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
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 #include <errno.h>
00049
00050 #include "delay.h"
00051
00052 #include "mac.h"
00053 #include "mrcl_arp.h"
00054 #include "topography.h"
00055 #include "cmu-trace.h"
00056 #include "mobilenode.h"
00057 #include "mrcl_ll.h"
00058 #include "packet.h"
00059 #include <address.h>
00060
00061
00062
00063 static class MrclMrclARPTableClass : public TclClass {
00064 public:
00065 MrclMrclARPTableClass() : TclClass("ARPTable/Mrcl") {}
00066 TclObject* create(int, const char*const* argv) {
00067 return (new MrclARPTable(argv[4], argv[5]));
00068 }
00069 } class_mrclarptable;
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 MrclARPTable_List MrclARPTable::athead_ = { 0 };
00087
00088 void
00089 MrclARPTable::Terminate()
00090 {
00091 MrclARPEntry *ll;
00092 for(ll = arphead_.lh_first; ll; ll = ll->arp_link_.le_next) {
00093 if(ll->hold_) {
00094 drop(ll->hold_, DROP_END_OF_SIMULATION);
00095 ll->hold_ = 0;
00096 }
00097 }
00098 }
00099
00100
00101 MrclARPTable::MrclARPTable(const char * IPaddr, const char *tclmac) : LinkDelay() {
00102 LIST_INIT(&arphead_);
00103
00104
00105
00106 IPaddress_ = atoi(IPaddr);
00107 mac_ = (Mac*) TclObject::lookup(tclmac);
00108 assert(mac_);
00109 LIST_INSERT_HEAD(&athead_, this, link_);
00110 }
00111
00112 int
00113 MrclARPTable::command(int argc, const char*const* argv)
00114 {
00115 if (argc == 2 && strcasecmp(argv[1], "reset") == 0) {
00116 Terminate();
00117
00118 }
00119 return LinkDelay::command(argc, argv);
00120 }
00121
00122 int
00123 MrclARPTable::arpresolve(nsaddr_t dst, Packet *p, MrclLL *ll)
00124 {
00125 MrclARPEntry *llinfo ;
00126 assert(initialized());
00127 llinfo = arplookup(dst);
00128
00129 #ifdef DEBUG
00130 fprintf(stderr, "%d - %s\n", IPaddress_, __FUNCTION__);
00131 #endif
00132
00133 if(llinfo && llinfo->up_) {
00134 mac_->hdr_dst((char*) HDR_MAC(p), llinfo->macaddr_);
00135 return 0;
00136 }
00137
00138 if(llinfo == 0) {
00139
00140
00141
00142 llinfo = new MrclARPEntry(&arphead_, dst);
00143 }
00144
00145 if(llinfo->count_ >= ARP_MAX_REQUEST_COUNT) {
00146
00147
00148
00149
00150
00151
00152
00153 Packet *t = llinfo->hold_;
00154
00155 llinfo->count_ = 0;
00156 llinfo->hold_ = 0;
00157 hdr_cmn* ch;
00158
00159 if(t) {
00160 ch = HDR_CMN(t);
00161
00162 if (ch->xmit_failure_) {
00163 ch->xmit_reason_ = 0;
00164 ch->xmit_failure_(t, ch->xmit_failure_data_);
00165 }
00166 else {
00167 drop(t, DROP_IFQ_ARP_FULL);
00168 }
00169 }
00170
00171 ch = HDR_CMN(p);
00172
00173 if (ch->xmit_failure_) {
00174 ch->xmit_reason_ = 0;
00175 ch->xmit_failure_(p, ch->xmit_failure_data_);
00176 }
00177 else {
00178 drop(p, DROP_IFQ_ARP_FULL);
00179 }
00180
00181 return EADDRNOTAVAIL;
00182 }
00183
00184 llinfo->count_++;
00185 if(llinfo->hold_)
00186 drop(llinfo->hold_, DROP_IFQ_ARP_FULL);
00187 llinfo->hold_ = p;
00188
00189
00190
00191
00192
00193
00194
00195 int src = IPaddress_;
00196 arprequest(src, dst, ll);
00197 return EADDRNOTAVAIL;
00198 }
00199
00200
00201 MrclARPEntry*
00202 MrclARPTable::arplookup(nsaddr_t dst)
00203 {
00204 MrclARPEntry *a;
00205
00206 for(a = arphead_.lh_first; a; a = a->nextarp()) {
00207 if(a->ipaddr_ == dst)
00208 return a;
00209 }
00210 return 0;
00211 }
00212
00213
00214 void
00215 MrclARPTable::arprequest(nsaddr_t src, nsaddr_t dst, MrclLL *ll)
00216 {
00217 Scheduler& s = Scheduler::instance();
00218 Packet *p = Packet::alloc();
00219
00220 hdr_cmn *ch = HDR_CMN(p);
00221 char *mh = (char*) HDR_MAC(p);
00222 hdr_ll *lh = HDR_LL(p);
00223 hdr_arp *ah = HDR_ARP(p);
00224
00225 ch->uid() = 0;
00226 ch->ptype() = PT_ARP;
00227 ch->size() = ARP_HDR_LEN;
00228 ch->iface() = -2;
00229 ch->error() = 0;
00230
00231 mac_->hdr_dst(mh, MAC_BROADCAST);
00232 mac_->hdr_src(mh, ll->mac_->addr());
00233 mac_->hdr_type(mh, ETHERTYPE_ARP);
00234
00235 lh->seqno() = 0;
00236 lh->lltype() = LL_DATA;
00237
00238 ch->direction() = hdr_cmn::DOWN;
00239 ah->arp_hrd = ARPHRD_ETHER;
00240 ah->arp_pro = ETHERTYPE_IP;
00241 ah->arp_hln = ETHER_ADDR_LEN;
00242 ah->arp_pln = sizeof(nsaddr_t);
00243 ah->arp_op = ARPOP_REQUEST;
00244 ah->arp_sha = ll->mac_->addr();
00245 ah->arp_spa = src;
00246 ah->arp_tha = 0;
00247 ah->arp_tpa = dst;
00248
00249 s.schedule(ll->downtarget_, p, delay_);
00250 }
00251
00252 void
00253 MrclARPTable::arpinput(Packet *p, MrclLL *ll)
00254 {
00255 Scheduler& s = Scheduler::instance();
00256 hdr_arp *ah = HDR_ARP(p);
00257 MrclARPEntry *llinfo;
00258
00259 assert(initialized());
00260
00261 #ifdef DEBUG
00262 fprintf(stderr,
00263 "%d - %s\n\top: %x, sha: %x, tha: %x, spa: %x, tpa: %x\n",
00264 IPaddress_, __FUNCTION__, ah->arp_op,
00265 ah->arp_sha, ah->arp_tha, ah->arp_spa, ah->arp_tpa);
00266 #endif
00267
00268 if((llinfo = arplookup(ah->arp_spa)) == 0) {
00269
00270
00271
00272
00273 llinfo = new MrclARPEntry(&arphead_, ah->arp_spa);
00274 }
00275 assert(llinfo);
00276
00277 llinfo->macaddr_ = ah->arp_sha;
00278 llinfo->up_ = 1;
00279
00280
00281
00282
00283 if(llinfo->hold_) {
00284 hdr_cmn *ch = HDR_CMN(llinfo->hold_);
00285 char *mh = (char*) HDR_MAC(llinfo->hold_);
00286 hdr_ip *ih = HDR_IP(llinfo->hold_);
00287
00288
00289
00290 int dst = Address::instance().get_nodeaddr(ih->daddr());
00291
00292 if((ch->addr_type() == NS_AF_NONE &&
00293 dst == ah->arp_spa) ||
00294 (NS_AF_INET == ch->addr_type() &&
00295 ch->next_hop() == ah->arp_spa)) {
00296 #ifdef DEBUG
00297 fprintf(stderr, "\tsending HELD packet.\n");
00298 #endif
00299 mac_->hdr_dst(mh, ah->arp_sha);
00300
00301
00302 s.schedule(ll->downtarget_, llinfo->hold_, delay_);
00303 llinfo->hold_ = 0;
00304 }
00305 else {
00306 fprintf(stderr, "\tfatal ARP error...\n");
00307 exit(1);
00308 }
00309 }
00310
00311 if(ah->arp_op == ARPOP_REQUEST &&
00312 ah->arp_tpa == IPaddress_) {
00313
00314 hdr_cmn *ch = HDR_CMN(p);
00315 char *mh = (char*)HDR_MAC(p);
00316 hdr_ll *lh = HDR_LL(p);
00317
00318 ch->size() = ARP_HDR_LEN;
00319 ch->error() = 0;
00320 ch->direction() = hdr_cmn::DOWN;
00321
00322 mac_->hdr_dst(mh, ah->arp_sha);
00323 mac_->hdr_src(mh, ll->mac_->addr());
00324 mac_->hdr_type(mh, ETHERTYPE_ARP);
00325
00326 lh->seqno() = 0;
00327 lh->lltype() = LL_DATA;
00328
00329
00330
00331
00332
00333
00334 ah->arp_op = ARPOP_REPLY;
00335 ah->arp_tha = ah->arp_sha;
00336 ah->arp_sha = ll->mac_->addr();
00337
00338 nsaddr_t t = ah->arp_spa;
00339 ah->arp_spa = ah->arp_tpa;
00340 ah->arp_tpa = t;
00341
00342 s.schedule(ll->downtarget_, p, delay_);
00343 return;
00344 }
00345 Packet::free(p);
00346 }
00347