首页 > 代码库 > ns2.35-classifier.cc

ns2.35-classifier.cc

line143:recv()

  1 /* -*-    Mode:C++; c-basic-offset:8; tab-width: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\n", this, nsize_, i++); 88             nslot_ = nsize_; 89         } 90         else { 91             //printf("classifier %x set to 32....%dth visit\n", 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 either141  * 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 object159  * perform upcall if no mapping160  */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‘s171          * 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 nullagent204          */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 $slot215          */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 $node223          */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 snum238          * returns the name of the object in slot # snum239          */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 $node251          * finds the slot containing $node252          */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 $node282          */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 {}

 

ns2.35-classifier.cc