📄 manual.cc
字号:
/* * Copyright (c) 2004, Stony Brook University * Contributors: Ashish Raniwala * All rights reserved. * * See copyright notice included in the distribution for details * */// raniwala: added for manual routing in wireless scenarioextern "C" {#include <stdarg.h>#include <float.h>};#include "manual.h"#include "priqueue.h"#include <random.h>#include <cmu-trace.h>#include <address.h>#include <mobilenode.h>#define DSDV_BROADCAST_JITTER 0.01 // jitter for all broadcast packetsextern int global_flowid;extern int flow_to_tag[];void Manual_Agent::trace (char *fmt,...){ va_list ap; if (!tracetarget) return; va_start (ap, fmt); vsprintf (tracetarget->pt_->buffer (), fmt, ap); tracetarget->pt_->dump (); va_end (ap);}void Manual_Agent::tracepkt (Packet * p, double now, int me, const char *type){ char buf[1024]; unsigned char *walk = p->accessdata (); int ct = *(walk++); int seq, dst, met; snprintf (buf, 1024, "V%s %.5f _%d_ [%d]:", type, now, me, ct); while (ct--) { dst = *(walk++); dst = dst << 8 | *(walk++); dst = dst << 8 | *(walk++); dst = dst << 8 | *(walk++); met = *(walk++); seq = *(walk++); seq = seq << 8 | *(walk++); seq = seq << 8 | *(walk++); seq = seq << 8 | *(walk++); snprintf (buf, 1024, "%s (%d,%d,%d)", buf, dst, met, seq); } // Now do trigger handling. //trace("VTU %.5f %d", now, me); if (verbose_) trace ("%s", buf);}// Prints out an rtable element.voidManual_Agent::output_rte(const char *prefix, fixed_rtable_ent * prte, Manual_Agent * a){ a->trace("DFU: deimplemented"); printf("DFU: deimplemented"); prte = 0; prefix = 0;#if 0 printf ("%s%d %d %d %d %f %f %f %f 0x%08x\n", prefix, prte->dst, prte->hop, prte->metric, prte->seqnum, prte->udtime, prte->new_seqnum_at, prte->wst, prte->changed_at, (unsigned int) prte->timeout_event); a->trace ("VTE %.5f %d %d %d %d %f %f %f %f 0x%08x", Scheduler::instance ().clock (), prte->dst, prte->hop, prte->metric, prte->seqnum, prte->udtime, prte->new_seqnum_at, prte->wst, prte->changed_at, prte->timeout_event);#endif}static void mac_callback (Packet * p, void *arg){ printf("mac_callback not implemented\n");}int Manual_Agent::diff_subnet(int dst) { char* dstnet = Address::instance().get_subnetaddr(dst); if (subnet_ != NULL) { if (dstnet != NULL) { if (strcmp(dstnet, subnet_) != 0) { delete [] dstnet; return 1; } delete [] dstnet; } } //assert(dstnet == NULL); return 0;}voidManual_Agent::forwardPacket (Packet * p){ hdr_ip *iph = HDR_IP(p); Scheduler & s = Scheduler::instance (); double now = s.clock (); hdr_cmn *hdrc = HDR_CMN (p); int dst; int tag; int flowid; fixed_rtable_ent *prte; printf("%d: MANUAL routing agent called to forward packet\n", myaddr_); // We should route it. //printf("(%d)-->forwardig pkt\n",myaddr_); // set direction of pkt to -1 , i.e downward hdrc->direction() = hdr_cmn::DOWN; // if the destination is outside mobilenode's domain // forward it to base_stn node // Note: pkt is not buffered if route to base_stn is unknown dst = Address::instance().get_nodeaddr(iph->daddr()); tag = hdrc->_tag_; flowid = hdrc->_flowid_; if (tag == -1) { // if tag does not exist in table#ifndef SPLIT_FLOWS if (flow_to_tag[flowid] == -1)#endif { tag_table_ent * tmp; // create a tag, and put into flow_to_tag[flowid] tmp = tagtable_->GetTag(dst); flow_to_tag[flowid] = tmp->tag;#ifndef SPLIT_FLOWS printf(">>>>>>>>>Flow %d assigned new tag %d\n", flowid, flow_to_tag[flowid]);#endif } // write tag on packet tag = hdrc->_tag_ = flow_to_tag[flowid]; } if (diff_subnet(iph->daddr())) { prte = table_->GetEntry (dst, tag); if (prte) goto send; //int dst = (node_->base_stn())->address(); dst = node_->base_stn(); printf(">>>PROBLEM - LOOKING FOR BASE STATION!\n"); prte = table_->GetEntry (dst, tag); if (prte) goto send; else { //drop pkt with warning fprintf(stderr, "warning: Route to base_stn not known: dropping pkt\n"); Packet::free(p); return; } } prte = table_->GetEntry (dst, tag); // trace("VDEBUG-RX %d %d->%d %d %d 0x%08x 0x%08x %d %d", // myaddr_, iph->src(), iph->dst(), hdrc->next_hop_, hdrc->addr_type_, // hdrc->xmit_failure_, hdrc->xmit_failure_data_, // hdrc->num_forwards_, hdrc->opt_num_forwards); if (prte) { //printf("(%d)-have route for dst\n",myaddr_); goto send; } else { /* must queue the packet */ //printf("(%d)-no route, queue pkt\n",myaddr_); if (!prte->q) { prte->q = new PacketQueue (); } prte->q->enque(p); if (verbose_) trace ("VBP %.5f _%d_ %d:%d -> %d:%d tag=%d", now, myaddr_, iph->saddr(), iph->sport(), iph->daddr(), iph->dport(), tag); while (prte->q->length () > MAX_QUEUE_LENGTH) drop (prte->q->deque (), DROP_RTR_QFULL); return; } send: printf(">>> Reached send label!\n"); hdrc->addr_type_ = NS_AF_INET; hdrc->xmit_failure_ = mac_callback; hdrc->xmit_failure_data_ = this; hdrc->next_hop_ = prte->hop; if (verbose_) trace ("Routing pkts outside domain: \VFP %.5f _%d_ %d:%d -> %d:%d", now, myaddr_, iph->saddr(), iph->sport(), iph->daddr(), iph->dport()); printf("DEST = %d, NEXTHOP = %d nic_id = %d\n", dst, prte->hop, prte->nic_id); assert (!HDR_CMN (p)->xmit_failure_ || HDR_CMN (p)->xmit_failure_ == mac_callback); if (prte->nic_id == 1) downtarget1_->recv(p, (Handler *)0); else if (prte->nic_id == 2) downtarget2_->recv(p, (Handler *)0); else if (prte->nic_id == 3) downtarget3_->recv(p, (Handler *)0); else if (prte->nic_id == 4) downtarget4_->recv(p, (Handler *)0); else if (prte->nic_id == 5) downtarget5_->recv(p, (Handler *)0); return;}void Manual_Agent::sendOutBCastPkt(Packet *p){ Scheduler & s = Scheduler::instance (); printf("Broadcast not implemented!!\n");}voidManual_Agent::recv (Packet * p, Handler *){ hdr_ip *iph = HDR_IP(p); hdr_cmn *cmh = HDR_CMN(p); int src = Address::instance().get_nodeaddr(iph->saddr()); int dst = cmh->next_hop(); /* * Must be a packet I'm originating... */ if(src == myaddr_ && cmh->num_forwards() == 0) { /* * Add the IP Header */ cmh->size() += IP_HDR_LEN; iph->ttl_ = IP_DEF_TTL; } /* * I received a packet that I sent. Probably * a routing loop. */ else if(src == myaddr_) { drop(p, DROP_RTR_ROUTE_LOOP); return; } /* * Packet I'm forwarding... */ else { /* * Check the TTL. If it is zero, then discard. */ if(--iph->ttl_ == 0) { drop(p, DROP_RTR_TTL); return; } } if ((src != myaddr_) && (iph->dport() == ROUTER_PORT)) { // XXX disable this feature for mobileIP where // the MH and FA (belonging to diff domains) // communicate with each other. // Drop pkt if rtg update from some other domain: // if (diff_subnet(iph->src())) // drop(p, DROP_OUTSIDE_SUBNET); //else printf("How come we got a route update ?? \n"); } else if ((u_int32_t) dst == IP_BROADCAST && (iph->dport() != ROUTER_PORT)) { if (src == myaddr_) { // handle brdcast pkt sendOutBCastPkt(p); } else { // hand it over to the port-demux port_dmux_->recv(p, (Handler*)0); } } else { forwardPacket(p); }}static class ManualClass:public TclClass{ public: ManualClass ():TclClass ("Agent/ManualRouting") { } TclObject *create (int, const char *const *) { return (new Manual_Agent ()); }} class_manualrouting;Manual_Agent::Manual_Agent (): Agent (PT_MESSAGE), ll_queue (0), myaddr_ (0), subnet_ (0), node_ (0), port_dmux_(0), use_mac_ (0), verbose_ (1), downtarget1_ (0), downtarget2_ (0), downtarget3_(0), downtarget4_(0), downtarget5_(0) // constants { int i; table_ = new FixedRoutingTable (); tagtable_ = new TagTable (); //bind ("use_mac_", &use_mac_); //bind ("verbose_", &verbose_); //DEBUG address = 0; }voidManual_Agent::startUp(){ Time now = Scheduler::instance().clock(); subnet_ = Address::instance().get_subnetaddr(myaddr_); //DEBUG address = Address::instance().print_nodeaddr(myaddr_); //printf("myaddress: %d -> %s\n",myaddr_,address); fixed_rtable_ent rte; bzero(&rte, sizeof(rte)); rte.dst = myaddr_; rte.hop = myaddr_; rte.tag = -1; rte.q = 0; // Don't buffer pkts for self! table_->AddEntry (rte); printf("Self address = %d\n", myaddr_);}int Manual_Agent::command (int argc, const char *const *argv){ if (argc == 2) { if (strcmp (argv[1], "start-manual-routing") == 0) { startUp(); return (TCL_OK); } else if (strcmp (argv[1], "dumprtab") == 0) { Packet *p2 = allocpkt (); hdr_ip *iph2 = HDR_IP(p2); fixed_rtable_ent *prte; printf ("Table Dump %d[%d]\n----------------------------------\n", iph2->saddr(), iph2->sport()); trace ("VTD %.5f %d:%d\n", Scheduler::instance ().clock (), iph2->saddr(), iph2->sport()); /* * Freeing a routing layer packet --> don't need to * call drop here. */ Packet::free (p2); for (table_->InitLoop (); (prte = table_->NextLoop ());) output_rte ("\t", prte, this); printf ("\n"); return (TCL_OK); } else if (strcasecmp (argv[1], "ll-queue") == 0) { if (!(ll_queue = (PriQueue *) TclObject::lookup (argv[2]))) { fprintf (stderr, "Manual_Agent: ll-queue lookup of %s failed\n", argv[2]); return TCL_ERROR; } return TCL_OK; } } else if (argc == 3) { if (strcasecmp (argv[1], "addr") == 0) { int temp; temp = Address::instance().str2addr(argv[2]); myaddr_ = temp; return TCL_OK; } TclObject *obj; if ((obj = TclObject::lookup (argv[2])) == 0) { fprintf (stderr, "%s: %s lookup of %s failed\n", __FILE__, argv[1], argv[2]); return TCL_ERROR; } if (strcasecmp (argv[1], "tracetarget") == 0) { tracetarget = (Trace *) obj; return TCL_OK; } else if (strcasecmp (argv[1], "node") == 0) { node_ = (MobileNode*) obj; return TCL_OK; } else if (strcasecmp (argv[1], "port-dmux") == 0) { port_dmux_ = (NsObject *) obj; return TCL_OK; } // raniwala: adding multiple down-targets else if (strcasecmp (argv[1], "down-target-1") == 0) { downtarget1_ = (NsObject *) obj; return TCL_OK; } else if (strcasecmp (argv[1], "down-target-2") == 0) { downtarget2_ = (NsObject *) obj; return TCL_OK; } else if (strcasecmp (argv[1], "down-target-3") == 0) { downtarget3_ = (NsObject *) obj; return TCL_OK; } else if (strcasecmp (argv[1], "down-target-4") == 0) { downtarget4_ = (NsObject *) obj; return TCL_OK; } else if (strcasecmp (argv[1], "down-target-5") == 0) { downtarget5_ = (NsObject *) obj; return TCL_OK; } } else if (argc==4) { if (strcasecmp (argv[1], "add-route-tag") == 0) { // format: add-next-hop dst hop tag_table_ent new_entry; new_entry.dst = atoi(argv[2]); new_entry.tag = atoi(argv[3]); tagtable_->AddTag(new_entry); return TCL_OK; } } else if (argc==6) { if (strcasecmp (argv[1], "add-next-hop") == 0) { // format: add-next-hop dst hop fixed_rtable_ent new_entry; new_entry.dst = atoi(argv[2]); new_entry.tag = atoi(argv[3]); new_entry.hop = atoi(argv[4]); new_entry.nic_id = atoi(argv[5]); new_entry.q = NULL; table_->AddEntry(new_entry); return TCL_OK; } } printf("Calling superclass Agent's command function!"); return (Agent::command (argc, argv));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -