00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
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
00049
00050
00051
00052
00053
00054
00055
00056
00057
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* )
00137 {
00138 hdr_cmn *ch = HDR_CMN(p);
00139
00140
00141
00142
00143
00144
00145 assert(initialized());
00146
00147
00148
00149
00150
00151
00152
00153
00154 if(ch->direction() == hdr_cmn::UP) {
00155
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
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
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
00203 if (arptable_) {
00204 tx = arptable_->arpresolve(dst, p, this);
00205 break;
00206 }
00207
00208
00209
00210
00211
00212
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
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