📄 ll.cc
字号:
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- *//* * Copyright (c) 1997 Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the Daedalus Research * Group at the University of California Berkeley. * 4. Neither the name of the University nor of the Laboratory may be used * to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * Contributed by the Daedalus Research Group, http://daedalus.cs.berkeley.edu */#ifndef lintstatic const char rcsid[] = "@(#) $Header: /usr/src/mash/repository/vint/ns-2/ll.cc,v 1.35 1999/03/13 03:52:50 haoboy Exp $ (UCB)";#endif#include <errmodel.h>#include <mac.h>#include <ll.h>#include <address.h>int hdr_ll::offset_;static class LLHeaderClass : public PacketHeaderClass {public: LLHeaderClass() : PacketHeaderClass("PacketHeader/LL", sizeof(hdr_ll)) { bind_offset(&hdr_ll::offset_); }} class_hdr_ll;static class LLClass : public TclClass {public: LLClass() : TclClass("LL") {} TclObject* create(int, const char*const*) { return (new LL); }} class_ll;LL::LL() : LinkDelay(), seqno_(0), ackno_(0), macDA_(0), ifq_(0), mac_(0), lanrouter_(0), arptable_(0), varp_(0), downtarget_(0), uptarget_(0){ bind("macDA_", &macDA_);#ifdef SPIN bind_time("mindelay_", &mindelay_);#endif}int LL::command(int argc, const char*const* argv){ Tcl& tcl = Tcl::instance(); if (argc == 3) { if (strcmp(argv[1], "ifq") == 0) { ifq_ = (Queue*) TclObject::lookup(argv[2]); return (TCL_OK); } if(strcmp(argv[1], "arptable") == 0) { arptable_ = (ARPTable*)TclObject::lookup(argv[2]); assert(arptable_); return TCL_OK; } if(strcmp(argv[1], "varp") == 0) { varp_ = (VARPTable*)TclObject::lookup(argv[2]); assert(varp_); return TCL_OK; } if (strcmp(argv[1], "mac") == 0) { mac_ = (Mac*) TclObject::lookup(argv[2]); assert(mac_); return (TCL_OK); } if (strcmp(argv[1], "down-target") == 0) { downtarget_ = (NsObject*) TclObject::lookup(argv[2]); return (TCL_OK); } if (strcmp(argv[1], "up-target") == 0) { uptarget_ = (NsObject*) TclObject::lookup(argv[2]); return (TCL_OK); } if (strcmp(argv[1], "lanrouter") == 0) { lanrouter_ = (LanRouter*) TclObject::lookup(argv[2]); return (TCL_OK); } } else if (argc == 2) { if (strcmp(argv[1], "ifq") == 0) { tcl.resultf("%s", ifq_->name()); return (TCL_OK); } if (strcmp(argv[1], "mac") == 0) { tcl.resultf("%s", mac_->name()); return (TCL_OK); } if (strcmp(argv[1], "down-target") == 0) { tcl.resultf("%s", downtarget_->name()); return (TCL_OK); } if (strcmp(argv[1], "up-target") == 0) { tcl.resultf("%s", uptarget_->name()); return (TCL_OK); } } return LinkDelay::command(argc, argv);}void LL::recv(Packet* p, Handler* /*h*/){ char *mh = (char*) HDR_MAC(p); hdr_cmn *ch = HDR_CMN(p); /* * Sanity Check */ assert(initialized()); // If direction = 1, then pass it up the stack // Otherwise, set direction to -1 and pass it down the stack if(ch->direction() == 1) { if(mac_->hdr_type(mh) == ETHERTYPE_ARP) arptable_->arpinput(p, this); else uptarget_ ? sendUp(p) : drop(p); return; } ch->direction() = -1; sendDown(p);}void LL::sendDown(Packet* p){ hdr_cmn *ch = HDR_CMN(p); hdr_ip *ih = HDR_IP(p); nsaddr_t dst = ih->dst(); hdr_ll *llh = HDR_LL(p); char *mh = (char*)p->access(hdr_mac::offset_); llh->seqno_ = ++seqno_; llh->lltype() = LL_DATA; mac_->hdr_src(mh, mac_->addr()); mac_->hdr_type(mh, ETHERTYPE_IP); int tx = 0; switch(ch->addr_type()) { case AF_ILINK: mac_->hdr_dst((char*) HDR_MAC(p), ch->next_hop()); break; case AF_INET: dst = ch->next_hop(); /* FALL THROUGH */ case AF_NONE: if (IP_BROADCAST == (u_int32_t) dst) { mac_->hdr_dst((char*) HDR_MAC(p), MAC_BROADCAST); break; } /* Assuming arptable is present, send query */ if (arptable_) { tx = arptable_->arpresolve(dst, p, this); break; } /* FALL THROUGH */ default: int IPnh = (lanrouter_) ? lanrouter_->next_hop(p) : -1; if (IPnh < 0) mac_->hdr_dst((char*) HDR_MAC(p),macDA_); else if (varp_) tx = varp_->arpresolve(IPnh, p); else mac_->hdr_dst((char*) HDR_MAC(p), IPnh); break; } if (tx == 0) { Scheduler& s = Scheduler::instance(); // let mac decide when to take a new packet from the queue. s.schedule(downtarget_, p, delay_); }}void LL::sendUp(Packet* p){ Scheduler& s = Scheduler::instance(); if (hdr_cmn::access(p)->error() > 0) drop(p); else s.schedule(uptarget_, p, delay_);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -