📄 mip-reg.cc
字号:
/* * Copyright (c) Sun Microsystems, Inc. 1998 All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Sun Microsystems, Inc. * * 4. The name of the Sun Microsystems, Inc nor may not be used to endorse or * promote products derived from this software without specific prior * written permission. * * SUN MICROSYSTEMS MERCHANTABILITY OF THIS SOFTWARE OR THE SUITABILITY OF THIS * SOFTWARE FOR ANY PARTICULAR PURPOSE. The software is provided "as is" * without express or implied warranty of any kind. * * These notices must be retained in any copies of any part of this software. */// #ident "@(#)mip-reg.cc 1.4 98/08/30 SMI"// #ident "@(#)mip-reg.cc 1.4 00/10/30 SMI"#include <template.h>#include <mip.h>#include <random.h>#include <address.h>#include <mobilenode.h>#include <hawaii.h>#define AGENT_ADS_SIZE 48#define REG_REQUEST_SIZE 52static class MIPHeaderClass : public PacketHeaderClass {public: MIPHeaderClass() : PacketHeaderClass("PacketHeader/MIP", sizeof(hdr_mip)) { }} class_miphdr;static class MIPBSAgentClass : public TclClass {public: MIPBSAgentClass() : TclClass("Agent/MIPBS") {} TclObject* create(int, const char*const*) { return (new MIPBSAgent()); }} class_mipbsagent;MIPBSAgent::MIPBSAgent() : Agent(PT_UDP), beacon_(1.0), drr_addr_(-1), hawaii_msf_(0), bcast_target_(0), ragent_(0), timer_(this), adlftm_(~0){ bind("adSize_", &size_); bind("ad_lifetime_", &adlftm_); bind("off_mip_", &off_mip_); // Wan: Hawaii Specific bind("off_hawaii_", &off_hawaii_); bind("previous_coa_", &Pcoa_); bind("domain_root_router_", &drr_addr_); bind("HawaiiRoutingMSF", &hawaii_msf_); size_ = AGENT_ADS_SIZE; seqno_ = -1;}int not_Hawaii(){ int flag; Tcl::instance().evalf("set HawaiiRouting"); flag = atoi(Tcl::instance().result()); if (flag == 1) return 0; else return 1;}int is_HFA(){ int flag; Tcl::instance().evalf("set HFA_Routing"); flag = atoi(Tcl::instance().result()); if (flag == 1) return 1; else return 0;}/* Wan:Generate Hawaii specific messages, special for BS node */void MIPBSAgent::genHawaii(HwMsgType type, int homeAddr, int oldBS){ Node* mynode = 0 ; int myNodeId; int nodeaddr = MY_ADDR, nextHop; if(!not_Hawaii()) { Tcl::instance().evalf("%s myNodeID", name_); myNodeId = atoi(Tcl::instance().result()); } Packet *p = allocpkt(); hdr_ip *iph = (hdr_ip *)p->access(off_ip_); hdr_hawaii *h = (hdr_hawaii *)p->access(off_hawaii_); h->hawaiiTag_ = -127; if(!not_Hawaii()) { Tcl::instance().evalf("addrToString %d", oldBS); DEBUG(2) printf("\nThe address of %d is %s\n", oldBS, TCL_RESULT); nextHop = atoi(TCL_RESULT); if(nextHop >= 0) { /* if there exist old BS field in the MIP msg */ Tcl::instance().evalf("%s get-nexthop %s", name_, TCL_RESULT); nextHop = atoi(TCL_RESULT); DEBUG(2) printf("\nNext-Hop is %d \n", nextHop); } } switch (type) { case HW_Power_Up: /* (1) generate power up Hawaii msgs * (2) forward to DRR hop-by-hop */ if(nodeaddr == drr_addr_) { printf("I am Domain Root Router, ACK the message\n"); iph->daddr() = oldBS; iph->dport() = 0; h->type_ = HW_ACK; h->home_addr_ = homeAddr; h->old_base_station_ = -1; h->new_base_station_ = nodeaddr; h->route_lifetime_ = 2; h->previous_hop_ = myNodeId; } else { /* setup initial route entry for MH */ Tcl::instance().evalf("%s create-route %d", name_, homeAddr); /* forward to nexthop toward DRR */ Tcl::instance().evalf("addrToString %d", drr_addr_); Tcl::instance().evalf("%s get-nexthop %s", name_, TCL_RESULT); iph->daddr() = atoi(TCL_RESULT); iph->dport() = 0; h->type_ = HW_Power_Up; h->home_addr_ = homeAddr; h->old_base_station_ = -1; h->new_base_station_ = nodeaddr; h->route_lifetime_ = 2; h->previous_hop_ = myNodeId; send(p, 0); } break; case HW_Handoff: /* Generate Hawaii Handoff msg. */ iph->daddr() = nextHop; iph->dport() = 0; h->type_ = HW_Handoff; h->home_addr_ = homeAddr; h->old_base_station_ = oldBS; h->new_base_station_ = nodeaddr; h->route_lifetime_ = 2; h->previous_hop_ = myNodeId; send(p, 0); DEBUG(2) printf("Send Hawaii Msg to %d at %f\n", nextHop, CUR_TIME); fflush(stdout); break; case HW_ACK: /* (1) When receive hawaii Ack, if I am the BS/FA, I should generate * Reg Reply to MH. * When generating Hawaii ACK, send it back to the new BS. * (2) This message is generated by DRR or old BS, and send directly * from src to dst. not hop-by-hop. */ iph->daddr() = oldBS; iph->dport() = 0; h->type_ = HW_ACK; h->home_addr_ = homeAddr; h->old_base_station_ = nodeaddr; /* I should be old BS to ACK */ h->new_base_station_ = oldBS; /* oldBS contain New BS's addr */ h->route_lifetime_ = 2; h->previous_hop_ = myNodeId; send(p, 0); DEBUG(2) printf("Send Hawaii ACK to %d at %f\n", iph->daddr(), CUR_TIME); break; case HW_Refresh: break; case HW_MSF: iph->daddr() = oldBS; iph->dport() = 0; h->type_ = HW_MSF; h->home_addr_ = homeAddr; h->old_base_station_ = oldBS; h->new_base_station_ = nodeaddr; h->route_lifetime_ = 2; h->previous_hop_ = myNodeId; send(p, 0); DEBUG(2) printf("Send Hawaii MSF to %d at %f\n", oldBS, CUR_TIME); fflush(stdout); break; default: break; }}/* Wan:Generate MIP reg Reply, special for BS node */void MIPBSAgent::genMIPreply(int homeAddr, int COA) { Packet *newp = allocpkt(); hdr_ip *newiph = (hdr_ip *)newp->access(off_ip_); newiph->daddr() = homeAddr; newiph->dport() = 0; hdr_mip *newh = (hdr_mip *)newp->access(off_mip_); newh->haddr_ = homeAddr; newh->ha_ = COA; // MH only check to match COA, HA field does not matter newh->coa_ = COA; // since this must be the BS/FA to MIP-reply MH newh->type_ = MIPT_REG_REPLY; newh->lifetime_ = 2; newh->seqno_ = 2; send(newp, 0); DEBUG(3) printf("\n************************\n \ send MIP reply to MH[%d] at %f\n", newiph->daddr(), CUR_TIME); }/* Wan: Process both MIP and Hawaii Msgs */void MIPBSAgent::recv(Packet* p, Handler *){ Tcl& tcl = Tcl::instance(); char *objname = NULL; NsObject *obj = NULL; hdr_mip *miph = (hdr_mip *)p->access(off_mip_); hdr_ip *iph = (hdr_ip *)p->access(off_ip_); hdr_cmn *ch = (hdr_cmn*)p->access(off_cmn_); int nodeaddr = Address::instance().get_nodeaddr(addr()); hdr_hawaii *hwh = (hdr_hawaii *)p->access(off_hawaii_); int myNodeId; if (!not_Hawaii()) { Tcl::instance().evalf("%s myNodeID", name_); myNodeId = atoi(Tcl::instance().result()); } /* when getting a Hawaii Mesgs */ if(hwh->hawaiiTag_ == -127){ DEBUG(2) printf("BS[%d:%d]: Hawaii Msg at time %fs-> ", nodeaddr, myNodeId, CUR_TIME); switch(hwh->type_) { case HW_Power_Up: /* (1) generate power up Hawaii msgs * (2) forward to DRR hop-by-hop */ if(nodeaddr == drr_addr_) { printf("I am Domain Root Router, ACK the message\n"); } else { iph->daddr() = drr_addr_; send(p, 0); } break; case HW_Handoff: /* (1) When getting a Hawaii Handoff msg. * (2) If I am the old BS, reply ACK. Update routing table for MH. * (3) If I am not, forward it to old BS hop-by-hop. */ if(hwh->old_base_station_ == nodeaddr){ iph->daddr() = hwh->new_base_station_; iph->saddr() = addr(); hwh->type_ = HW_ACK; send(p,0); DEBUG(2) printf("Old BS[%d]: Change Route and ACK -> %d\n", addr(), iph->daddr()); } else { DEBUG(2) printf("Handoff-> Update Routing Table\n"); fflush(stdout); } break; case HW_ACK: /* (1) When receive hawaii Ack, if I am the BS/FA, I should generate * Reg Reply to MH. * (2) This message is generated by DRR or old BS, and send directly * from src to dst. not hop-by-hop. */ DEBUG(2) printf("Hawaii Ack[%d]->Generate MIP Reg Reply to MH[%d] \n", addr(), hwh->home_addr_); genMIPreply(hwh->home_addr_, nodeaddr); break; case HW_Refresh: break; case HW_MSF: int nextHop; /* if this is the old BS, then update route for MH * and forward the control messages hop-by-hop back * to the new base station in case of MSF */ if(hwh->old_base_station_ == nodeaddr){ cout << "\n old BS got Hawaii MSF \n"; Tcl::instance().evalf("addrToString %d", hwh->new_base_station_); DEBUG(2) printf("\nThe address of %d is %s\n", hwh->new_base_station_, TCL_RESULT); Tcl::instance().evalf("%s get-nexthop %s", name_, TCL_RESULT); nextHop = atoi(TCL_RESULT); DEBUG(2) printf("\nNext-Hop is %d \n", nextHop); iph->daddr() = nextHop; iph->saddr() = addr(); tcl.evalf("%s change-route %d %d", name_, hwh->home_addr_, nextHop); send(p, 0); DEBUG(2) printf("Old BS[%d]: Change Route and ACK -> %d\n", addr(), iph->daddr()); // buffer packet needed to be forwarded to new base station. tcl.evalf("%s block-packet %d", name_, miph->haddr_); tcl.evalf("%s dump-buffer", name_); } else { if(hwh->new_base_station_ == nodeaddr) { genMIPreply(hwh->home_addr_, nodeaddr); } else { DEBUG(2) printf("Handoff-> Update Routing Table\n"); fflush(stdout); } } break; default: break; } } else { switch (miph->type_) { case MIPT_REG_REQUEST: if (miph->ha_ == (Address::instance().get_nodeaddr(addr()))){ if (miph->ha_ == miph->coa_) { // back home if (not_Hawaii()) tcl.evalf("%s clear-reg %d", name_, miph->haddr_); } else { if (not_Hawaii()) tcl.evalf("%s encap-route %d %d %lf", name_, miph->haddr_, miph->coa_, miph->lifetime_); } iph->dst() = iph->src(); miph->type_ = MIPT_REG_REPLY; } else { iph->daddr() = miph->ha_; iph->dport() = 0; } iph->saddr() = addr(); iph->sport() = port(); // by now should be back to normal route // if dst is the mobile // also initialise forward counter to 0. otherwise routing // agent is going to think pkt is looping and drop it!! ch->num_forwards() = 0; /* Wan */ DEBUG(2) printf("BS[%d]:The previous COA is %d at time %fs\n", nodeaddr, miph->Pcoa_, CUR_TIME); if (not_Hawaii()) send(p, 0); if (not_Hawaii()) { if(is_HFA()) { if(miph->Pcoa_ < 0) { printf("power up ->forward Reg Messages to the GFA [%d:1]\n", miph->ha_); } else { if(miph->Pcoa_ != miph->coa_) { if(miph->coa_ == nodeaddr){ printf("BS[%d:%d]:Handoff\n", nodeaddr, myNodeId); printf("Create routing entry in Foreign BS for MH[%d]:", miph->haddr_); if( miph->ha_ != nodeaddr ) { Tcl::instance().evalf("%s create-route %d", name_, miph->haddr_); } DEBUG(3) printf("Handoff: oldBS[%d] HA[%d]", miph->Pcoa_, miph->ha_); if( miph->Pcoa_ != miph->ha_ ) { Tcl::instance().evalf("%s clear-route %d %d", name_, miph->haddr_, miph->Pcoa_); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -