filter.cc
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:5k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /* -*-  Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
  2. /*
  3.  * Copyright (C) 1998 by the University of Southern California
  4.  * $Id: filter.cc,v 1.8 2005/08/25 18:58:02 johnh Exp $
  5.  *
  6.  * This program is free software; you can redistribute it and/or
  7.  * modify it under the terms of the GNU General Public License,
  8.  * version 2, as published by the Free Software Foundation.
  9.  *
  10.  * This program is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License along
  16.  * with this program; if not, write to the Free Software Foundation, Inc.,
  17.  * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  18.  *
  19.  *
  20.  * The copyright of this module includes the following
  21.  * linking-with-specific-other-licenses addition:
  22.  *
  23.  * In addition, as a special exception, the copyright holders of
  24.  * this module give you permission to combine (via static or
  25.  * dynamic linking) this module with free software programs or
  26.  * libraries that are released under the GNU LGPL and with code
  27.  * included in the standard release of ns-2 under the Apache 2.0
  28.  * license or under otherwise-compatible licenses with advertising
  29.  * requirements (or modified versions of such code, with unchanged
  30.  * license).  You may copy and distribute such a system following the
  31.  * terms of the GNU GPL for this module and the licenses of the
  32.  * other code concerned, provided that you include the source code of
  33.  * that other code when and as the GNU GPL requires distribution of
  34.  * source code.
  35.  *
  36.  * Note that people who make modified versions of this module
  37.  * are not obligated to grant this special exception for their
  38.  * modified versions; it is their choice whether to do so.  The GNU
  39.  * General Public License gives permission to release a modified
  40.  * version without this exception; this exception also makes it
  41.  * possible to release a modified version which carries forward this
  42.  * exception.
  43.  *
  44.  */
  45. #ifndef lint
  46. static const char rcsid[] =
  47.     "@(#) $Header: /usr/src/mash/repository/vint/ns-2/filter.cc ";
  48. #endif
  49. #include "packet.h"
  50. #include "filter.h"
  51. static class FilterClass : public TclClass {
  52. public:
  53. FilterClass() : TclClass("Filter") {}
  54. TclObject* create(int, const char*const*) {
  55. return (new Filter);
  56. }
  57. } class_filter;
  58. Filter::Filter() : filter_target_(0) 
  59. {
  60. }
  61. Filter::filter_e Filter::filter(Packet* /*p*/) 
  62. {
  63. return PASS;  // As simple connector
  64. }
  65. void Filter::recv(Packet* p, Handler* h)
  66. {
  67. switch(filter(p)) {
  68. case DROP : 
  69. if (h) h->handle(p);
  70. drop(p);
  71. break;
  72. case DUPLIC :
  73. if (filter_target_)
  74. filter_target_->recv(p->copy(), h);
  75. /* fallthrough */
  76. case PASS :
  77. send(p, h);
  78. break;
  79. case FILTER :
  80. if (filter_target_)
  81. filter_target_->recv(p, h);
  82. break;
  83. }
  84. }
  85. int Filter::command(int argc, const char*const* argv)
  86. {
  87. Tcl& tcl = Tcl::instance();
  88. if (argc == 2) {
  89. if (strcmp(argv[1], "filter-target") == 0) {
  90. if (filter_target_ != 0)
  91. tcl.result(target_->name());
  92. return TCL_OK;
  93. }
  94. }
  95. else if (argc == 3) {
  96. if (strcmp(argv[1], "filter-target") == 0) {
  97. filter_target_ = (NsObject*)TclObject::lookup(argv[2]);
  98. return TCL_OK;
  99. }
  100. }
  101. return Connector::command(argc, argv);
  102. }
  103. static class FieldFilterClass : public TclClass {
  104. public:
  105. FieldFilterClass() : TclClass("Filter/Field") {}
  106. TclObject* create(int, const char*const*) {
  107. return (new FieldFilter);
  108. }
  109. } class_filter_field;
  110. FieldFilter::FieldFilter() 
  111. {
  112. bind("offset_", &offset_);
  113. bind("match_", &match_);
  114. }
  115. Filter::filter_e FieldFilter::filter(Packet *p) 
  116. {
  117. return (*(int *)p->access(offset_) == match_) ? FILTER : PASS;
  118. }
  119. /* 10-5-98, Polly Huang, Filters that filter on multiple fields */
  120. static class MultiFieldFilterClass : public TclClass {
  121. public:
  122. MultiFieldFilterClass() : TclClass("Filter/MultiField") {}
  123. TclObject* create(int, const char*const*) {
  124. return (new MultiFieldFilter);
  125. }
  126. } class_filter_multifield;
  127. MultiFieldFilter::MultiFieldFilter() : field_list_(0)
  128. {
  129. }
  130. void MultiFieldFilter::add_field(fieldobj *p) 
  131. {
  132. p->next = field_list_;
  133. field_list_ = p;
  134. }
  135. MultiFieldFilter::filter_e MultiFieldFilter::filter(Packet *p) 
  136. {
  137. fieldobj* tmpfield;
  138. tmpfield = field_list_;
  139. while (tmpfield != 0) {
  140. if (*(int *)p->access(tmpfield->offset) == tmpfield->match)
  141. tmpfield = tmpfield->next;
  142. else 
  143. return (PASS);
  144. }
  145. return(FILTER);
  146. }
  147. int MultiFieldFilter::command(int argc, const char*const* argv)
  148. {
  149. Tcl& tcl = Tcl::instance();
  150. if (argc == 2) {
  151. if (strcmp(argv[1], "filter-target") == 0) {
  152. if (filter_target_ != 0)
  153. tcl.result(target_->name());
  154. return TCL_OK;
  155. }
  156. }
  157. else if (argc == 3) {
  158. if (strcmp(argv[1], "filter-target") == 0) {
  159. filter_target_ = (NsObject*)TclObject::lookup(argv[2]);
  160. return TCL_OK;
  161. }
  162. }
  163.        else if (argc == 4) {
  164. if (strcmp(argv[1], "filter-field") == 0) {
  165. fieldobj *tmp = new fieldobj;
  166. tmp->offset = atoi(argv[2]);
  167. tmp->match = atoi(argv[3]);
  168. add_field(tmp);
  169. return TCL_OK;
  170. }
  171. }
  172. return Connector::command(argc, argv);
  173. }