Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Compound Members | File Members

filter.cc

Go to the documentation of this file.
00001 /* -*-  Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
00002 /*
00003  * filter.cc
00004  * Copyright (C) 1998 by USC/ISI
00005  * All rights reserved.                                            
00006  *                                                                
00007  * Redistribution and use in source and binary forms are permitted
00008  * provided that the above copyright notice and this paragraph are
00009  * duplicated in all such forms and that any documentation, advertising
00010  * materials, and other materials related to such distribution and use
00011  * acknowledge that the software was developed by the University of
00012  * Southern California, Information Sciences Institute.  The name of the
00013  * University may not be used to endorse or promote products derived from
00014  * this software without specific prior written permission.
00015  * 
00016  * THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
00017  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
00018  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
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* /*p*/) 
00041 {
00042         return PASS;  // As simple connector
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                 /* fallthrough */
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 /* 10-5-98, Polly Huang, Filters that filter on multiple fields */
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 }

Generated on Tue Apr 20 12:14:16 2004 for NS2.26SourcesOriginal by doxygen 1.3.3