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 #include "mll-module.h"
00032 #include <mmac-clmsg.h>
00033 #include <ip-clmsg.h>
00034
00035 extern ClMessage_t IP_CLMSG_SEND_ADDR;
00036
00037 static class MLLModuleClass : public TclClass {
00038 public:
00039 MLLModuleClass() : TclClass("Module/MLL") {}
00040 TclObject* create(int, const char*const*) {
00041 return (new MLLModule());
00042 }
00043 } class_ll;
00044
00045 MLLModule::MLLModule() : seqno_(0), ackno_(0)
00046 {
00047 arptable_ = new MARPTable();
00048 }
00049
00050 MLLModule::~MLLModule()
00051 {
00052 }
00053
00054 int MLLModule::crLayCommand(ClMessage* m)
00055 {
00056 if(m->type() == IP_CLMSG_SEND_ADDR)
00057 {
00058 nsaddr_t tmp = ((IPClMsgSendAddr *)m)->getAddr();
00059 netAddr.push_back(tmp);
00060 delete m;
00061 return 1;
00062 }
00063 return Module::crLayCommand(m);
00064 }
00065
00066
00067 int MLLModule::recvAsyncClMsg(ClMessage* m)
00068 {
00069 if(m->type() == IP_CLMSG_SEND_ADDR)
00070 {
00071 nsaddr_t tmp = ((IPClMsgSendAddr *)m)->getAddr();
00072 netAddr.push_back(tmp);
00073 delete m;
00074 return 1;
00075 }
00076 return Module::crLayCommand(m);
00077 }
00078
00079
00080 int MLLModule::command(int argc, const char*const* argv)
00081 {
00082 if (argc == 2)
00083 {
00084 if (strcasecmp(argv[1], "reset") == 0) {
00085 arptable_->clear();
00086
00087 }
00088 }
00089 if (argc == 4)
00090 {
00091 if (strcasecmp(argv[1], "addentry") == 0)
00092 {
00093 nsaddr_t ipaddr = atoi(argv[2]);
00094 MARPEntry* e = new MARPEntry(ipaddr);
00095 e->macaddr_ = atoi(argv[3]);
00096 e->up_ = 1;
00097 arptable_->addEntry(e);
00098 return TCL_OK;
00099 }
00100 }
00101 return Module::command(argc, argv);
00102 }
00103
00104 void MLLModule::recv(Packet* p)
00105 {
00106 recv(p, -1);
00107 }
00108
00109 void MLLModule::recv(Packet *p, int idSrc)
00110 {
00111 hdr_cmn *ch = HDR_CMN(p);
00112 if(ch->direction() == hdr_cmn::UP)
00113 {
00114 if(ch->ptype_ == PT_ARP)
00115 processARP(p, idSrc);
00116 else
00117 sendUp(p);
00118 }
00119 else
00120 {
00121 ch->direction() = hdr_cmn::DOWN;
00122 sendDown(p);
00123 }
00124 }
00125
00126 void MLLModule::sendDown(Packet* p)
00127 {
00128 hdr_cmn *ch = HDR_CMN(p);
00129 hdr_ip *ih = HDR_IP(p);
00130 nsaddr_t dst = ih->daddr();
00131 hdr_ll *llh = HDR_LL(p);
00132 hdr_mac *mh = HDR_MAC(p);
00133
00134 llh->seqno_ = ++seqno_;
00135 llh->lltype() = LL_DATA;
00136
00137 mh->macSA() = getDownAddr();
00138 mh->hdr_type() = ETHERTYPE_IP;
00139 int tx = 0;
00140
00141 switch(ch->addr_type()) {
00142
00143 case NS_AF_ILINK:
00144
00145 mh->macDA() = ch->next_hop();
00146 break;
00147
00148 case NS_AF_INET:
00149 dst = ch->next_hop();
00150
00151
00152 case NS_AF_NONE:
00153
00154 if (IP_BROADCAST == (u_int32_t) dst)
00155 {
00156 mh->macDA() = MAC_BROADCAST;
00157 break;
00158 }
00159
00160
00161 tx = arpResolve(dst, p);
00162 break;
00163
00164 default:
00165 mh->macDA() = MAC_BROADCAST;
00166 break;
00167 }
00168
00169 if (tx == 0)
00170 {
00171 Module::sendDown(p);
00172 }
00173 }
00174
00175 void MLLModule::sendUp(Packet* p)
00176 {
00177 Module::sendUp(p);
00178 }
00179
00180 void MLLModule::processARP(Packet* p, int idSrc)
00181 {
00182 hdr_arp *ah = HDR_ARP(p);
00183 MARPEntry *llinfo;
00184
00185
00186 if((llinfo = arptable_->lookup(ah->arp_spa)) == 0) {
00187
00188
00189 llinfo = new MARPEntry(ah->arp_spa);
00190 arptable_->addEntry(llinfo);
00191 }
00192 llinfo->macaddr_ = ah->arp_sha;
00193 llinfo->up_ = 1;
00194
00195
00196 if(llinfo->hold_)
00197 {
00198 hdr_cmn *ch = HDR_CMN(llinfo->hold_);
00199 hdr_mac *mh = HDR_MAC(llinfo->hold_);
00200 hdr_ip *ih = HDR_IP(llinfo->hold_);
00201 nsaddr_t dst = ih->daddr();
00202
00203 if((ch->addr_type() == NS_AF_NONE &&
00204 dst == ah->arp_spa) ||
00205 (NS_AF_INET == ch->addr_type() &&
00206 ch->next_hop() == ah->arp_spa))
00207 {
00208 if(debug_ > 5)
00209 printf("\tsending HELD packet.\n");
00210
00211 mh->macDA() = ah->arp_sha;
00212
00213 Module::sendDown(llinfo->hold_);
00214 llinfo->hold_ = 0;
00215 }
00216 else
00217 {
00218 fprintf(stderr, "\tfatal ARP error...\n");
00219 exit(1);
00220 }
00221 }
00222
00223 if(ah->arp_op == ARPOP_REQUEST && netAddrPresent(ah->arp_tpa))
00224 {
00225 hdr_cmn *ch = HDR_CMN(p);
00226 hdr_mac *mh = HDR_MAC(p);
00227 hdr_ll *lh = HDR_LL(p);
00228
00229 ch->size() = ARP_HDR_LEN;
00230 ch->error() = 0;
00231 ch->direction() = hdr_cmn::DOWN;
00232
00233 int downAddr = getDownAddr(idSrc);
00234
00235 mh->macDA() = ah->arp_sha;
00236 mh->macSA() = downAddr;
00237 mh->hdr_type() = ETHERTYPE_ARP;
00238
00239 lh->seqno() = 0;
00240 lh->lltype() = LL_DATA;
00241
00242 ah->arp_op = ARPOP_REPLY;
00243 ah->arp_tha = ah->arp_sha;
00244 ah->arp_sha = downAddr;
00245
00246 nsaddr_t t = ah->arp_spa;
00247 ah->arp_spa = ah->arp_tpa;
00248 ah->arp_tpa = t;
00249
00250 Module::sendDown(p);
00251 return;
00252 }
00253 Packet::free(p);
00254 }
00255
00256 bool MLLModule::netAddrPresent(nsaddr_t addr)
00257 {
00258 fillNetAddrTable();
00259 vector<nsaddr_t>::iterator p = find(netAddr.begin(), netAddr.end(), addr);
00260 return (p != netAddr.end());
00261 }
00262
00263 void MLLModule::fillNetAddrTable()
00264 {
00265 netAddr.clear();
00266 IPClMsgReqAddr *c = new IPClMsgReqAddr(getId());
00267 c->setDest(CLBROADCASTADDR);
00268 sendSyncClMsgUp(c);
00269 delete c;
00270 }
00271
00272 int MLLModule::getDownAddr(int downId)
00273 {
00274 MacClMsgGetAddr *c;
00275 if(downId != -1)
00276 {
00277 c = new MacClMsgGetAddr(UNICAST, downId);
00278 sendSyncClMsgDown(c);
00279 }
00280 else
00281 {
00282 c = new MacClMsgGetAddr(BROADCAST, CLBROADCASTADDR);
00283 sendSyncClMsgDown(c);
00284 }
00285 int val = c->getAddr();
00286 delete c;
00287 return val;
00288 }
00289
00290 int MLLModule::arpResolve(nsaddr_t dst, Packet* p)
00291 {
00292 hdr_mac *mh = HDR_MAC(p);
00293 MARPEntry *llinfo;
00294 llinfo = arptable_->lookup(dst);
00295
00296
00297 if(llinfo && llinfo->up_)
00298 {
00299 mh->macDA() = llinfo->macaddr_;
00300 return 0;
00301 }
00302
00303 if(llinfo == 0) {
00304
00305 llinfo = new MARPEntry(dst);
00306 arptable_->addEntry(llinfo);
00307 }
00308
00309 if(llinfo->count_ >= ARP_MAX_REQUEST_COUNT) {
00310
00311
00312
00313
00314
00315
00316
00317 Packet *t = llinfo->hold_;
00318
00319 llinfo->count_ = 0;
00320 llinfo->hold_ = 0;
00321 hdr_cmn* ch;
00322
00323 if(t) {
00324 ch = HDR_CMN(t);
00325
00326 if (ch->xmit_failure_) {
00327 ch->xmit_reason_ = 0;
00328 ch->xmit_failure_(t, ch->xmit_failure_data_);
00329 }
00330 else {
00331 drop(t, 1, DROP_IFQ_ARP_FULL);
00332 }
00333 }
00334
00335 ch = HDR_CMN(p);
00336
00337 if (ch->xmit_failure_) {
00338 ch->xmit_reason_ = 0;
00339 ch->xmit_failure_(p, ch->xmit_failure_data_);
00340 }
00341 else {
00342 drop(p, 1, DROP_IFQ_ARP_FULL);
00343 }
00344
00345 return EADDRNOTAVAIL;
00346 }
00347
00348 llinfo->count_++;
00349 if(llinfo->hold_)
00350 drop(llinfo->hold_, 1, DROP_IFQ_ARP_FULL);
00351 llinfo->hold_ = p;
00352
00353
00354
00355
00356
00357
00358
00359 fillNetAddrTable();
00360 if(netAddr.size() > 0)
00361 arpRequest(netAddr[0], dst);
00362 else
00363 arpRequest(0, dst);
00364 return EADDRNOTAVAIL;
00365 }
00366
00367 void MLLModule::arpRequest(nsaddr_t src, nsaddr_t dst)
00368 {
00369 Packet *p = Packet::alloc();
00370
00371 hdr_cmn *ch = HDR_CMN(p);
00372 hdr_mac *mh = HDR_MAC(p);
00373 hdr_ll *lh = HDR_LL(p);
00374 hdr_arp *ah = HDR_ARP(p);
00375
00376 ch->uid() = 0;
00377 ch->ptype() = PT_ARP;
00378 ch->size() = ARP_HDR_LEN;
00379 ch->iface() = -2;
00380 ch->error() = 0;
00381
00382 mh->macDA() = MAC_BROADCAST;
00383 mh->macSA() = getDownAddr();
00384 mh->hdr_type() = ETHERTYPE_ARP;
00385
00386 lh->seqno() = 0;
00387 lh->lltype() = LL_DATA;
00388
00389 ch->direction() = hdr_cmn::DOWN;
00390 ah->arp_hrd = ARPHRD_ETHER;
00391 ah->arp_pro = ETHERTYPE_IP;
00392 ah->arp_hln = ETHER_ADDR_LEN;
00393 ah->arp_pln = sizeof(nsaddr_t);
00394 ah->arp_op = ARPOP_REQUEST;
00395 ah->arp_sha = mh->macSA();
00396 ah->arp_spa = src;
00397 ah->arp_tha = 0;
00398 ah->arp_tpa = dst;
00399
00400 Module::sendDown(p);
00401 }