mrcl_ll.cc

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 <mrcl_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 //              bind();
00056 //      }
00057 // } class_hdr_ll;
00058 
00059 
00060 static class MrclLLClass : public TclClass {
00061 public:
00062         MrclLLClass() : TclClass("LL/Mrcl") {}
00063         TclObject* create(int, const char*const*) {
00064                 return (new MrclLL);
00065         }
00066 } class_mrcl_ll;
00067 
00068 
00069 MrclLL::MrclLL() : LinkDelay(), seqno_(0), ackno_(0), macDA_(0), ifq_(0),
00070         mac_(0), lanrouter_(0), arptable_(0), varp_(0),
00071         downtarget_(0), uptarget_(0)
00072 {
00073         bind("macDA_", &macDA_);
00074 }
00075 
00076 int MrclLL::command(int argc, const char*const* argv)
00077 {
00078         Tcl& tcl = Tcl::instance();
00079         if (argc == 3) {
00080                 if (strcmp(argv[1], "ifq") == 0) {
00081                         ifq_ = (Queue*) TclObject::lookup(argv[2]);
00082                         return (TCL_OK);
00083                 }
00084                 if(strcmp(argv[1], "arptable") == 0) {
00085                         arptable_ = (MrclARPTable*)TclObject::lookup(argv[2]);
00086                         assert(arptable_);
00087                         return TCL_OK;
00088                 }
00089                 if(strcmp(argv[1], "varp") == 0) {
00090                         varp_ = (VARPTable*)TclObject::lookup(argv[2]);
00091                         assert(varp_);
00092                         return TCL_OK;
00093                 }
00094                 if (strcmp(argv[1], "mac") == 0) {
00095                         mac_ = (Mac*) TclObject::lookup(argv[2]);
00096                         assert(mac_);
00097                         return (TCL_OK);
00098                 }
00099                 if (strcmp(argv[1], "down-target") == 0) {
00100                         downtarget_ = (NsObject*) TclObject::lookup(argv[2]);
00101                         return (TCL_OK);
00102                 }
00103                 if (strcmp(argv[1], "up-target") == 0) {
00104                         uptarget_ = (NsObject*) TclObject::lookup(argv[2]);
00105                         return (TCL_OK);
00106                 }
00107                 if (strcmp(argv[1], "lanrouter") == 0) {
00108                         lanrouter_ = (LanRouter*) TclObject::lookup(argv[2]);
00109                         return (TCL_OK);
00110                 }
00111 
00112         }
00113         else if (argc == 2) {
00114                 if (strcmp(argv[1], "ifq") == 0) {
00115                         tcl.resultf("%s", ifq_->name());
00116                         return (TCL_OK);
00117                 }
00118                 if (strcmp(argv[1], "mac") == 0) {
00119                         tcl.resultf("%s", mac_->name());
00120                         return (TCL_OK);
00121                 }
00122                 if (strcmp(argv[1], "down-target") == 0) {
00123                         tcl.resultf("%s", downtarget_->name());
00124                         return (TCL_OK);
00125                 }
00126                 if (strcmp(argv[1], "up-target") == 0) {
00127                         tcl.resultf("%s", uptarget_->name());
00128                         return (TCL_OK);
00129                 }
00130         }
00131         return LinkDelay::command(argc, argv);
00132 }
00133 
00134 
00135 
00136 void MrclLL::recv(Packet* p, Handler* /*h*/)
00137 {
00138         hdr_cmn *ch = HDR_CMN(p);
00139         //char *mh = (char*) HDR_MAC(p);
00140         //struct hdr_sr *hsr = HDR_SR(p);
00141 
00142         /*
00143          * Sanity Check
00144          */
00145         assert(initialized());
00146 
00147         //if(p->incoming) {
00148         //p->incoming = 0;
00149         //}
00150         // 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.
00151 
00152         // If direction = UP, then pass it up the stack
00153         // Otherwise, set direction to DOWN and pass it down the stack
00154         if(ch->direction() == hdr_cmn::UP) {
00155                 //if(mac_->hdr_type(mh) == ETHERTYPE_ARP)
00156                 if(ch->ptype_ == PT_ARP)
00157                         arptable_->arpinput(p, this);
00158                 else
00159                         uptarget_ ? sendUp(p) : drop(p);
00160                 return;
00161         }
00162 
00163         ch->direction() = hdr_cmn::DOWN;
00164         sendDown(p);
00165 }
00166 
00167 
00168 void MrclLL::sendDown(Packet* p)
00169 {       
00170         hdr_cmn *ch = HDR_CMN(p);
00171         hdr_ip *ih = HDR_IP(p);
00172 
00173         nsaddr_t dst = (nsaddr_t)Address::instance().get_nodeaddr(ih->daddr());
00174         //nsaddr_t dst = ih->dst();
00175         hdr_ll *llh = HDR_LL(p);
00176         char *mh = (char*)p->access(hdr_mac::offset_);
00177         
00178         llh->seqno_ = ++seqno_;
00179         llh->lltype() = LL_DATA;
00180 
00181         mac_->hdr_src(mh, mac_->addr());
00182         mac_->hdr_type(mh, ETHERTYPE_IP);
00183         int tx = 0;
00184         
00185         switch(ch->addr_type()) {
00186 
00187         case NS_AF_ILINK:
00188                 mac_->hdr_dst((char*) HDR_MAC(p), ch->next_hop());
00189                 break;
00190 
00191         case NS_AF_INET:
00192                 dst = ch->next_hop();
00193                 /* FALL THROUGH */
00194                 
00195         case NS_AF_NONE:
00196                 
00197                 if (IP_BROADCAST == (u_int32_t) dst)
00198                 {
00199                         mac_->hdr_dst((char*) HDR_MAC(p), MAC_BROADCAST);
00200                         break;
00201                 }
00202                 /* Assuming arptable is present, send query */
00203                 if (arptable_) {
00204                         tx = arptable_->arpresolve(dst, p, this);
00205                         break;
00206                 }
00207                 //if (varp_) {
00208                 //tx = varp_->arpresolve(dst, p);
00209                 //break;
00210                         
00211                 //}                     
00212                 /* FALL THROUGH */
00213 
00214         default:
00215                 
00216                 int IPnh = (lanrouter_) ? lanrouter_->next_hop(p) : -1;
00217                 if (IPnh < 0)
00218                         mac_->hdr_dst((char*) HDR_MAC(p),macDA_);
00219                 else if (varp_)
00220                         tx = varp_->arpresolve(IPnh, p);
00221                 else
00222                         mac_->hdr_dst((char*) HDR_MAC(p), IPnh);
00223                 break;
00224         }
00225         
00226         if (tx == 0) {
00227                 Scheduler& s = Scheduler::instance();
00228         // let mac decide when to take a new packet from the queue.
00229                 s.schedule(downtarget_, p, delay_);
00230         }
00231 }
00232 
00233 
00234 
00235 void MrclLL::sendUp(Packet* p)
00236 {
00237 
00238         Scheduler& s = Scheduler::instance();
00239         if (hdr_cmn::access(p)->error() > 0)
00240                 drop(p);
00241         else
00242                 s.schedule(uptarget_, p, delay_);
00243 }
00244 
00245 

Generated on Wed Nov 26 15:47:28 2008 for NS-MIRACLE library by  doxygen 1.5.2