📄 noah.cc
字号:
extern "C" {#include <stdarg.h>#include <float.h>#include <string.h>#include <stdlib.h>#include <stdio.h>#include <assert.h>};#include <random.h>#include <address.h>#include <mobilenode.h>#include <cmu-trace.h>#include "noah.h"#define NOAH_BROADCAST_JITTER 0.01 // jitter for all broadcast packets//#define NOAH_DEBUG// Returns a random number between 0 and maxstatic inline double jitter (double max, int be_random_){ return (be_random_ ? Random::uniform(max) : 0);}voidNOAH_Agent::trace (char *fmt,...){ va_list ap; if (!tracetarget) return; va_start (ap, fmt); vsprintf (tracetarget->buffer (), fmt, ap); tracetarget->dump (); va_end (ap);}voidNOAH_Agent::lost_link (Packet *p){ hdr_cmn *ch = HDR_CMN (p); if(use_mac_ == 0) { drop(p, DROP_RTR_MAC_CALLBACK); return; } if (!use_mac_ || ch->addr_type_ != NS_AF_INET) return; // Queue these packets up... recv(p, 0);}static void mac_callback (Packet * p, void *arg){ ((NOAH_Agent *) arg)->lost_link (p);}voidNOAH_Agent::forwardPacket (Packet * p){ Scheduler & s = Scheduler::instance (); double now = s.clock (); hdr_cmn *ch = HDR_CMN (p); hdr_ip *iph = HDR_IP(p); if (node_->base_stn() == node_->address()) { // node is its own BS --> HA or FA ch->next_hop_ = Address::instance().get_nodeaddr(iph->daddr()); } else { // MH sends to BS // JCW set next hop in mip-reg.cc when sending request etc. // don't set when destination already set by MIPMH if (ch->next_hop_ <= -2) // see packet.h ch->next_hop_ = Address::instance().get_nodeaddr(node_->base_stn()); } ch->direction() = hdr_cmn::DOWN; ch->addr_type_ = NS_AF_INET; ch->xmit_failure_ = mac_callback; ch->xmit_failure_data_ = this; assert (!HDR_CMN (p)->xmit_failure_ || HDR_CMN (p)->xmit_failure_ == mac_callback);#ifdef NOAH_DEBUG printf("%f NOAH forward (node %s) to %s (via %s), packet %i\n", Scheduler::instance().clock(), Address::instance().print_nodeaddr(node_->address()), Address::instance().print_nodeaddr(iph->daddr()), Address::instance().print_nodeaddr(ch->next_hop_), ch->uid()); // JCW#endif target_->recv(p, (Handler *)0); return;}void NOAH_Agent::sendOutBCastPkt(Packet *p){ Scheduler & s = Scheduler::instance ();#ifdef NOAH_DEBUG hdr_ip *iph = HDR_IP(p); hdr_cmn *ch = HDR_CMN(p); printf("%f NOAH broadcast (node %s) to %s, packet %i\n", Scheduler::instance().clock(), Address::instance().print_nodeaddr(node_->address()), Address::instance().print_nodeaddr(iph->daddr()), ch->uid()); // JCW#endif s.schedule (target_, p, jitter(NOAH_BROADCAST_JITTER, be_random_));}voidNOAH_Agent::recv (Packet * p, Handler *){ hdr_ip *iph = HDR_IP(p); hdr_cmn *ch = HDR_CMN(p); int src = Address::instance().get_nodeaddr(iph->saddr()); int dst = ch->next_hop(); /* * Must be a packet I'm originating... */ if(src == myaddr_ && ch->num_forwards() == 0) { /* * Add the IP Header */ ch->size() += IP_HDR_LEN; iph->ttl_ = IP_DEF_TTL; } /* * I received a packet that I sent. Probably * a routing loop. */ else if(src == myaddr_) {#ifdef NOAH_DEBUG printf("%f NOAH dropped packet (routing loop)\n", Scheduler::instance().clock());#endif 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) {#ifdef NOAH_DEBUG printf("%f NOAH dropped packet (TTL)\n", Scheduler::instance().clock());#endif drop(p, DROP_RTR_TTL); return; } } 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#ifdef NOAH_DEBUG printf("%f NOAH receive (node %s) from %s, packet %i\n", Scheduler::instance().clock(), Address::instance().print_nodeaddr(node_->address()), Address::instance().print_nodeaddr(iph->daddr()), ch->uid()); // JCW#endif port_dmux_->recv(p, (Handler*)0); } } else { forwardPacket(p); }}static class NOAHClass:public TclClass{public: NOAHClass ():TclClass ("Agent/NOAH") {} TclObject *create (int, const char *const *) { return (new NOAH_Agent ()); }} class_noah;NOAH_Agent::NOAH_Agent (): Agent (PT_MESSAGE), myaddr_ (0), subnet_ (0), node_ (0), port_dmux_(0), be_random_ (1), use_mac_ (0){ bind ("use_mac_", &use_mac_); bind ("be_random_", &be_random_);}int NOAH_Agent::command (int argc, const char *const *argv){ if (argc == 3) { if (strcasecmp (argv[1], "addr") == 0) { myaddr_ = Address::instance().str2addr(argv[2]); subnet_ = Address::instance().get_subnetaddr(myaddr_); 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; } } return (Agent::command (argc, argv));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -