00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef lint
00022 static const char rcsid[] =
00023 "@(#) $Header: /usr/src/mash/repository/vint/ns-2/filter.cc ";
00024 #endif
00025
00026 #include "packet.h"
00027 #include "filter.h"
00028
00029 static class FilterClass : public TclClass {
00030 public:
00031 FilterClass() : TclClass("Filter") {}
00032 TclObject* create(int, const char*const*) {
00033 return (new Filter);
00034 }
00035 } class_filter;
00036
00037 Filter::Filter() : filter_target_(0)
00038 {
00039 }
00040 Filter::filter_e Filter::filter(Packet* )
00041 {
00042 return PASS;
00043 }
00044 void Filter::recv(Packet* p, Handler* h)
00045 {
00046 switch(filter(p)) {
00047 case DROP :
00048 if (h) h->handle(p);
00049 drop(p);
00050 break;
00051 case DUPLIC :
00052 if (filter_target_)
00053 filter_target_->recv(p->copy(), h);
00054
00055 case PASS :
00056 send(p, h);
00057 break;
00058 case FILTER :
00059 if (filter_target_)
00060 filter_target_->recv(p, h);
00061 break;
00062 }
00063 }
00064 int Filter::command(int argc, const char*const* argv)
00065 {
00066 Tcl& tcl = Tcl::instance();
00067 if (argc == 2) {
00068 if (strcmp(argv[1], "filter-target") == 0) {
00069 if (filter_target_ != 0)
00070 tcl.result(target_->name());
00071 return TCL_OK;
00072 }
00073 }
00074 else if (argc == 3) {
00075 if (strcmp(argv[1], "filter-target") == 0) {
00076 filter_target_ = (NsObject*)TclObject::lookup(argv[2]);
00077 return TCL_OK;
00078 }
00079 }
00080 return Connector::command(argc, argv);
00081 }
00082
00083 static class FieldFilterClass : public TclClass {
00084 public:
00085 FieldFilterClass() : TclClass("Filter/Field") {}
00086 TclObject* create(int, const char*const*) {
00087 return (new FieldFilter);
00088 }
00089 } class_filter_field;
00090
00091 FieldFilter::FieldFilter()
00092 {
00093 bind("offset_", &offset_);
00094 bind("match_", &match_);
00095 }
00096 Filter::filter_e FieldFilter::filter(Packet *p)
00097 {
00098 return (*(int *)p->access(offset_) == match_) ? FILTER : PASS;
00099 }
00100
00101
00102 static class MultiFieldFilterClass : public TclClass {
00103 public:
00104 MultiFieldFilterClass() : TclClass("Filter/MultiField") {}
00105 TclObject* create(int, const char*const*) {
00106 return (new MultiFieldFilter);
00107 }
00108 } class_filter_multifield;
00109
00110 MultiFieldFilter::MultiFieldFilter() : field_list_(0)
00111 {
00112
00113 }
00114
00115 void MultiFieldFilter::add_field(fieldobj *p)
00116 {
00117 p->next = field_list_;
00118 field_list_ = p;
00119 }
00120
00121 MultiFieldFilter::filter_e MultiFieldFilter::filter(Packet *p)
00122 {
00123 fieldobj* tmpfield;
00124
00125 tmpfield = field_list_;
00126 while (tmpfield != 0) {
00127 if (*(int *)p->access(tmpfield->offset) == tmpfield->match)
00128 tmpfield = tmpfield->next;
00129 else
00130 return (PASS);
00131 }
00132 return(FILTER);
00133 }
00134
00135
00136 int MultiFieldFilter::command(int argc, const char*const* argv)
00137 {
00138 Tcl& tcl = Tcl::instance();
00139 if (argc == 2) {
00140 if (strcmp(argv[1], "filter-target") == 0) {
00141 if (filter_target_ != 0)
00142 tcl.result(target_->name());
00143 return TCL_OK;
00144 }
00145 }
00146 else if (argc == 3) {
00147 if (strcmp(argv[1], "filter-target") == 0) {
00148 filter_target_ = (NsObject*)TclObject::lookup(argv[2]);
00149 return TCL_OK;
00150 }
00151 }
00152 else if (argc == 4) {
00153 if (strcmp(argv[1], "filter-field") == 0) {
00154 fieldobj *tmp = new fieldobj;
00155 tmp->offset = atoi(argv[2]);
00156 tmp->match = atoi(argv[3]);
00157 add_field(tmp);
00158 return TCL_OK;
00159 }
00160 }
00161 return Connector::command(argc, argv);
00162 }