首页 > 代码库 > 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
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。