ns2.35-classifier.cc

line143:recv()

  1 /* -*-    Mode:C++; c-basic-offset:8; tab-8; indent-tabs-mode:t -*- */
  2 /*
  3  * Copyright (c) 1996 Regents of the University of California.
  4  * All rights reserved.
  5  * 
  6  * Redistribution and use in source and binary forms, with or without
  7  * modification, are permitted provided that the following conditions
  8  * are met:
  9  * 1. Redistributions of source code must retain the above copyright
 10  *    notice, this list of conditions and the following disclaimer.
 11  * 2. Redistributions in binary form must reproduce the above copyright
 12  *    notice, this list of conditions and the following disclaimer in the
 13  *    documentation and/or other materials provided with the distribution.
 14  * 3. All advertising materials mentioning features or use of this software
 15  *    must display the following acknowledgement:
 16  *     This product includes software developed by the MASH Research
 17  *     Group at the University of California Berkeley.
 18  * 4. Neither the name of the University nor of the Research Group may be
 19  *    used to endorse or promote products derived from this software without
 20  *    specific prior written permission.
 21  * 
 22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 32  * SUCH DAMAGE.
 33  */
 34 
 35 #ifndef lint
 36 static const char rcsid[] =
 37     "@(#) $Header: /cvsroot/nsnam/ns-2/classifier/classifier.cc,v 1.44 2010/03/08 05:54:49 tom_henderson Exp $";
 38 #endif
 39 
 40 #include <stdlib.h>
 41 #include "config.h"
 42 #include "classifier.h"
 43 #include "packet.h"
 44 #include "link/cell_header.h"
 45 
 46 static class ClassifierClass : public TclClass {
 47 public:
 48     ClassifierClass() : TclClass("Classifier") {}
 49     TclObject* create(int, const char*const*) {
 50         return (new Classifier());
 51     }
 52 } class_classifier;
 53 
 54 
 55 Classifier::Classifier() : 
 56     slot_(0), nslot_(0), maxslot_(-1), shift_(0), mask_(0xffffffff), nsize_(0)
 57 {
 58     default_target_ = 0;
 59 
 60     bind("offset_", &offset_);
 61     bind("shift_", &shift_);
 62     bind("mask_", &mask_);
 63 }
 64 
 65 int Classifier::classify(Packet *p)
 66 {
 67     return (mshift(*((int*) p->access(offset_))));
 68 }
 69 
 70 Classifier::~Classifier()
 71 {
 72     delete [] slot_;
 73 }
 74 
 75 void Classifier::set_table_size(int nn)
 76 {
 77     nsize_ = nn;
 78 }
 79 
 80 void Classifier::alloc(int slot)
 81 {
 82     NsObject** old = slot_;
 83     int n = nslot_;
 84     if (old == 0) 
 85         {    
 86         if (nsize_ != 0) {
 87             //printf("classifier %x set to %d....%dth visit
", this, nsize_, i++);
 88             nslot_ = nsize_;
 89         }
 90         else {
 91             //printf("classifier %x set to 32....%dth visit
", this, j++);
 92             nslot_ = 32;
 93         }
 94         }
 95     while (nslot_ <= slot) 
 96         nslot_ <<= 1;
 97     slot_ = new NsObject*[nslot_];
 98     memset(slot_, 0, nslot_ * sizeof(NsObject*));
 99     for (int i = 0; i < n; ++i)
100         slot_[i] = old[i];
101     delete [] old;
102 }
103 
104 
105 void Classifier::install(int slot, NsObject* p)
106 {
107     if (slot >= nslot_)
108         alloc(slot);
109     slot_[slot] = p;
110     if (slot >= maxslot_)
111         maxslot_ = slot;
112 }
113 
114 void Classifier::clear(int slot)
115 {
116     slot_[slot] = 0;
117     if (slot == maxslot_) {
118         while (--maxslot_ >= 0 && slot_[maxslot_] == 0)
119             ;
120     }
121 }
122 
123 int Classifier::allocPort (NsObject *nullagent)
124 {
125     return getnxt (nullagent);
126 }
127 
128 int Classifier::getnxt(NsObject *nullagent)
129 {
130     int i;
131     for (i=0; i < nslot_; i++)
132         if (slot_[i]==0 || slot_[i]==nullagent)
133             return i;
134     i=nslot_;
135     alloc(nslot_);
136     return i;
137 }
138 
139 /*
140  * objects only ever see "packet" events, which come either
141  * from an incoming link or a local agent (i.e., packet source).
142  */
143 void Classifier::recv(Packet* p, Handler*h)
144 {
145     NsObject* node = find(p);
146     if (node == NULL) {
147         /*
148          * XXX this should be "dropped" somehow.  Right now,
149          * these events aren't traced.
150          */
151         Packet::free(p);
152         return;
153     }
154     node->recv(p,h);
155 }
156 
157 /*
158  * perform the mapping from packet to object
159  * perform upcall if no mapping
160  */
161 
162 NsObject* Classifier::find(Packet* p)
163 {
164     NsObject* node = NULL;
165     int cl = classify(p);
166     if (cl < 0 || cl >= nslot_ || (node = slot_[cl]) == 0) { 
167         if (default_target_) 
168             return default_target_;
169         /*
170          * Sigh.  Can't pass the pkt out to tcl because it's
171          * not an object.
172          */
173         Tcl::instance().evalf("%s no-slot %ld", name(), cl);
174         if (cl == TWICE) {
175             /*
176              * Try again.  Maybe callback patched up the table.
177              */
178             cl = classify(p);
179             if (cl < 0 || cl >= nslot_ || (node = slot_[cl]) == 0)
180                 return (NULL);
181         }
182     }
183     return (node);
184 }
185 
186 int Classifier::install_next(NsObject *node) {
187     int slot = maxslot_ + 1;
188     install(slot, node);
189     return (slot);
190 }
191 
192 int Classifier::command(int argc, const char*const* argv)
193 {
194     Tcl& tcl = Tcl::instance();
195     if(argc == 2) {
196                 if (strcmp(argv[1], "defaulttarget") == 0) {
197                         if (default_target_ != 0)
198                                 tcl.result(default_target_->name());
199                         return (TCL_OK);
200                 }
201         } else if (argc == 3) {
202         /*
203          * $classifier alloc-port nullagent
204          */
205         if (strcmp(argv[1],"alloc-port") == 0) {
206             int slot;
207             NsObject* nullagent =
208                 (NsObject*)TclObject::lookup(argv[2]);
209             slot = getnxt(nullagent);
210             tcl.resultf("%u",slot);
211             return(TCL_OK);
212         }
213         /*
214          * $classifier clear $slot
215          */
216         if (strcmp(argv[1], "clear") == 0) {
217             int slot = atoi(argv[2]);
218             clear(slot);
219             return (TCL_OK);
220         }
221         /*
222          * $classifier installNext $node
223          */
224         if (strcmp(argv[1], "installNext") == 0) {
225             //int slot = maxslot_ + 1;
226             NsObject* node = (NsObject*)TclObject::lookup(argv[2]);
227             if (node == NULL) {
228                 tcl.resultf("Classifier::installNext attempt "
229             "to install non-object %s into classifier", argv[2]);
230                 return TCL_ERROR;
231             };
232             int slot = install_next(node);
233             tcl.resultf("%u", slot);
234             return TCL_OK;
235         }
236         /*
237          * $classifier slot snum
238          * returns the name of the object in slot # snum
239          */
240         if (strcmp(argv[1], "slot") == 0) {
241             int slot = atoi(argv[2]);
242             if (slot >= 0 && slot < nslot_ && slot_[slot] != NULL) {
243                 tcl.resultf("%s", slot_[slot]->name());
244                 return TCL_OK;
245             }
246             tcl.resultf("Classifier: no object at slot %d", slot);
247             return (TCL_ERROR);
248         }
249         /*
250          * $classifier findslot $node
251          * finds the slot containing $node
252          */
253         if (strcmp(argv[1], "findslot") == 0) {
254             int slot = 0;
255             NsObject* node = (NsObject*)TclObject::lookup(argv[2]);
256             if (node == NULL) {
257                 return (TCL_ERROR);
258             }
259             while (slot < nslot_) {
260                 // check if the slot is empty (xuanc, 1/14/02) 
261                 // fix contributed by Frank A. Zdarsky 
262                 // <frank.zdarsky@kom.tu-darmstadt.de>
263                 if (slot_[slot] && 
264                     strcmp(slot_[slot]->name(), argv[2]) == 0){
265                     tcl.resultf("%u", slot);
266                     return (TCL_OK);
267                 }
268                 slot++;
269             }
270             tcl.result("-1");
271             return (TCL_OK);
272         }
273         if (strcmp(argv[1], "defaulttarget") == 0) {
274             default_target_=(NsObject*)TclObject::lookup(argv[2]);
275             if (default_target_ == 0)
276                 return TCL_ERROR;
277             return TCL_OK;
278         }
279     } else if (argc == 4) {
280         /*
281          * $classifier install $slot $node
282          */
283         if (strcmp(argv[1], "install") == 0) {
284             int slot = atoi(argv[2]);
285             NsObject* node = (NsObject*)TclObject::lookup(argv[3]);
286             install(slot, node);
287             return (TCL_OK);
288         }
289     }
290     return (NsObject::command(argc, argv));
291 }
292 
293 void Classifier::set_table_size(int, int)
294 {}
原文地址:https://www.cnblogs.com/forcheryl/p/4198699.html