ll.cc

Go to the documentation of this file.
00001 /* -*-  Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
00002 /*
00003  * Copyright (c) 1997 Regents of the University of California.
00004  * All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions
00008  * are met:
00009  * 1. Redistributions of source code must retain the above copyright
00010  *    notice, this list of conditions and the following disclaimer.
00011  * 2. Redistributions in binary form must reproduce the above copyright
00012  *    notice, this list of conditions and the following disclaimer in the
00013  *    documentation and/or other materials provided with the distribution.
00014  * 3. All advertising materials mentioning features or use of this software
00015  *    must display the following acknowledgement:
00016  *  This product includes software developed by the Daedalus Research
00017  *  Group at the University of California Berkeley.
00018  * 4. Neither the name of the University nor of the Laboratory may be used
00019  *    to endorse or promote products derived from this software without
00020  *    specific prior written permission.
00021  *
00022  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00023  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00024  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00025  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00026  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00027  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00028  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00029  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00031  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00032  * SUCH DAMAGE.
00033  *
00034  * Contributed by the Daedalus Research Group, http://daedalus.cs.berkeley.edu
00035  */
00036 
00037 #ifndef lint
00038 static const char rcsid[] =
00039     "@(#) $Header: /nfs/jade/vint/CVSROOT/ns-2/mac/ll.cc,v 1.46 2002/03/14 01:12:52 haldar Exp $ (UCB)";
00040 #endif
00041 
00042 #include <errmodel.h>
00043 #include <mac.h>
00044 #include <ll.h>
00045 #include <address.h>
00046 #include <dsr/hdr_sr.h>
00047 
00048 int hdr_ll::offset_;
00049 
00050 static class LLHeaderClass : public PacketHeaderClass {
00051 public:
00052     LLHeaderClass() : PacketHeaderClass("PacketHeader/LL",
00053                         sizeof(hdr_ll)) {
00054         bind_offset(&hdr_ll::offset_);
00055     }
00056 } class_hdr_ll;
00057 
00058 
00059 static class LLClass : public TclClass {
00060 public:
00061     LLClass() : TclClass("LL") {}
00062     TclObject* create(int, const char*const*) {
00063         return (new LL);
00064     }
00065 } class_ll;
00066 
00067 
00068 LL::LL() : LinkDelay(), seqno_(0), ackno_(0), macDA_(0), ifq_(0),
00069     mac_(0), lanrouter_(0), arptable_(0), varp_(0),
00070     downtarget_(0), uptarget_(0)
00071 {
00072     bind("macDA_", &macDA_);
00073 }
00074 
00075 int LL::command(int argc, const char*const* argv)
00076 {
00077     Tcl& tcl = Tcl::instance();
00078     if (argc == 3) {
00079         if (strcmp(argv[1], "ifq") == 0) {
00080             ifq_ = (Queue*) TclObject::lookup(argv[2]);
00081             return (TCL_OK);
00082         }
00083         if(strcmp(argv[1], "arptable") == 0) {
00084                         arptable_ = (ARPTable*)TclObject::lookup(argv[2]);
00085                         assert(arptable_);
00086                         return TCL_OK;
00087                 }
00088         if(strcmp(argv[1], "varp") == 0) {
00089                         varp_ = (VARPTable*)TclObject::lookup(argv[2]);
00090                         assert(varp_);
00091                         return TCL_OK;
00092                 }
00093         if (strcmp(argv[1], "mac") == 0) {
00094             mac_ = (Mac*) TclObject::lookup(argv[2]);
00095                         assert(mac_);
00096             return (TCL_OK);
00097         }
00098         if (strcmp(argv[1], "down-target") == 0) {
00099             downtarget_ = (NsObject*) TclObject::lookup(argv[2]);
00100             return (TCL_OK);
00101         }
00102         if (strcmp(argv[1], "up-target") == 0) {
00103             uptarget_ = (NsObject*) TclObject::lookup(argv[2]);
00104             return (TCL_OK);
00105         }
00106         if (strcmp(argv[1], "lanrouter") == 0) {
00107             lanrouter_ = (LanRouter*) TclObject::lookup(argv[2]);
00108             return (TCL_OK);
00109         }
00110 
00111     }
00112     else if (argc == 2) {
00113         if (strcmp(argv[1], "ifq") == 0) {
00114             tcl.resultf("%s", ifq_->name());
00115             return (TCL_OK);
00116         }
00117         if (strcmp(argv[1], "mac") == 0) {
00118             tcl.resultf("%s", mac_->name());
00119             return (TCL_OK);
00120         }
00121         if (strcmp(argv[1], "down-target") == 0) {
00122             tcl.resultf("%s", downtarget_->name());
00123             return (TCL_OK);
00124         }
00125         if (strcmp(argv[1], "up-target") == 0) {
00126             tcl.resultf("%s", uptarget_->name());
00127             return (TCL_OK);
00128         }
00129     }
00130     return LinkDelay::command(argc, argv);
00131 }
00132 
00133 
00134 
00135 void LL::recv(Packet* p, Handler* /*h*/)
00136 {
00137     hdr_cmn *ch = HDR_CMN(p);
00138     //char *mh = (char*) HDR_MAC(p);
00139     //struct hdr_sr *hsr = HDR_SR(p);
00140 
00141     /*
00142      * Sanity Check
00143      */
00144     assert(initialized());
00145 
00146     //if(p->incoming) {
00147     //p->incoming = 0;
00148     //}
00149     // XXXXX NOTE: use of incoming flag has been depracated; In order to track direction of pkt flow, direction_ in hdr_cmn is used instead. see packet.h for details.
00150 
00151     // If direction = UP, then pass it up the stack
00152     // Otherwise, set direction to DOWN and pass it down the stack
00153     if(ch->direction() == hdr_cmn::UP) {
00154         //if(mac_->hdr_type(mh) == ETHERTYPE_ARP)
00155         if(ch->ptype_ == PT_ARP)
00156             arptable_->arpinput(p, this);
00157         else
00158             uptarget_ ? sendUp(p) : drop(p);
00159         return;
00160     }
00161 
00162     ch->direction() = hdr_cmn::DOWN;
00163     sendDown(p);
00164 }
00165 
00166 
00167 void LL::sendDown(Packet* p)
00168 {   
00169     hdr_cmn *ch = HDR_CMN(p);
00170     hdr_ip *ih = HDR_IP(p);
00171 
00172     nsaddr_t dst = (nsaddr_t)Address::instance().get_nodeaddr(ih->daddr());
00173     //nsaddr_t dst = ih->dst();
00174     hdr_ll *llh = HDR_LL(p);
00175     char *mh = (char*)p->access(hdr_mac::offset_);
00176     
00177     llh->seqno_ = ++seqno_;
00178     llh->lltype() = LL_DATA;
00179 
00180     mac_->hdr_src(mh, mac_->addr());
00181     mac_->hdr_type(mh, ETHERTYPE_IP);
00182     int tx = 0;
00183     
00184     switch(ch->addr_type()) {
00185 
00186     case NS_AF_ILINK:
00187         mac_->hdr_dst((char*) HDR_MAC(p), ch->next_hop());
00188         break;
00189 
00190     case NS_AF_INET:
00191         dst = ch->next_hop();
00192         /* FALL THROUGH */
00193         
00194     case NS_AF_NONE:
00195         
00196         if (IP_BROADCAST == (u_int32_t) dst)
00197         {
00198             mac_->hdr_dst((char*) HDR_MAC(p), MAC_BROADCAST);
00199             break;
00200         }
00201         /* Assuming arptable is present, send query */
00202         if (arptable_) {
00203             tx = arptable_->arpresolve(dst, p, this);
00204             break;
00205         }
00206         //if (varp_) {
00207         //tx = varp_->arpresolve(dst, p);
00208         //break;
00209             
00210         //}         
00211         /* FALL THROUGH */
00212 
00213     default:
00214         
00215         int IPnh = (lanrouter_) ? lanrouter_->next_hop(p) : -1;
00216         if (IPnh < 0)
00217             mac_->hdr_dst((char*) HDR_MAC(p),macDA_);
00218         else if (varp_)
00219             tx = varp_->arpresolve(IPnh, p);
00220         else
00221             mac_->hdr_dst((char*) HDR_MAC(p), IPnh);
00222         break;
00223     }
00224     
00225     if (tx == 0) {
00226         Scheduler& s = Scheduler::instance();
00227     // let mac decide when to take a new packet from the queue.
00228         s.schedule(downtarget_, p, delay_);
00229     }
00230 }
00231 
00232 
00233 
00234 void LL::sendUp(Packet* p)
00235 {
00236 
00237     Scheduler& s = Scheduler::instance();
00238     if (hdr_cmn::access(p)->error() > 0)
00239         drop(p);
00240     else
00241         s.schedule(uptarget_, p, delay_);
00242 }
00243 
00244 

Generated on Tue Mar 6 16:47:46 2007 for ns2 Network Simulator 2.29 by  doxygen 1.4.6