--- ns-2.26.orig/Makefile.in 2003-02-27 17:51:25.000000000 -0700 +++ ns-2.26.nsclickcvs/Makefile.in 2003-04-30 16:27:18.000000000 -0600 @@ -57,7 +57,7 @@ LDFLAGS = $(STATIC) LDOUT = -o $(BLANK) -DEFINE = -DTCP_DELAY_BIND_ALL -DNO_TK @V_DEFINE@ @V_DEFINES@ @DEFS@ -DNS_DIFFUSION -DSMAC_NO_SYNC -DSTL_NAMESPACE=@STL_NAMESPACE@ -DUSE_SINGLE_ADDRESS_SPACE +DEFINE = -DTCP_DELAY_BIND_ALL -DNO_TK @V_DEFINE@ @V_DEFINES@ @DEFS@ -DNS_DIFFUSION -DSMAC_NO_SYNC -DSTL_NAMESPACE=@STL_NAMESPACE@ -DUSE_SINGLE_ADDRESS_SPACE -DALLOW_RANDOM INCLUDES = \ -I. @V_INCLUDE_X11@ \ @@ -140,7 +140,7 @@ OBJ_CC = \ tools/random.o tools/rng.o tools/ranvar.o common/misc.o common/timer-handler.o \ - common/scheduler.o common/object.o common/packet.o \ + common/scheduler.o common/object.o common/packet.o common/rawpacket.o \ common/ip.o routing/route.o common/connector.o common/ttl.o \ trace/trace.o trace/trace-ip.o \ classifier/classifier.o classifier/classifier-addr.o \ @@ -152,6 +152,7 @@ classifier/classifier-mac.o \ classifier/classifier-qs.o \ classifier/classifier-port.o src_rtg/classifier-sr.o \ + classifier/classifier-ext.o classifier/classifier-click.o \ src_rtg/sragent.o src_rtg/hdr_src.o adc/ump.o \ qs/qsagent.o qs/hdr_qs.o \ apps/app.o apps/telnet.o tcp/tcplib-telnet.o \ @@ -178,7 +179,7 @@ tcp/nilist.o \ tools/integrator.o tools/queue-monitor.o \ tools/flowmon.o tools/loss-monitor.o \ - queue/queue.o queue/drop-tail.o \ + queue/queue.o queue/drop-tail.o queue/clickqueue.o \ adc/simple-intserv-sched.o queue/red.o \ queue/semantic-packetqueue.o queue/semantic-red.o \ tcp/ack-recons.o \ @@ -208,14 +209,15 @@ common/pkt-counter.o \ common/Decapsulator.o common/Encapsulator.o \ common/encap.o \ - mac/channel.o mac/mac.o mac/ll.o mac/mac-802_11.o \ + mac/channel.o mac/mac.o mac/ll.o mac/ll-ext.o mac/mac-802_11.o \ mac/mac-802_3.o mac/mac-tdma.o mac/smac.o \ mobile/mip.o mobile/mip-reg.o mobile/gridkeeper.o \ mobile/propagation.o mobile/tworayground.o \ - mobile/antenna.o mobile/omni-antenna.o \ + mobile/antenna.o mobile/omni-antenna.o mobile/uni-antenna.o \ + mobile/pattern-antenna.o \ mobile/shadowing.o mobile/shadowing-vis.o mobile/dumb-agent.o \ common/bi-connector.o common/node.o \ - common/mobilenode.o \ + common/mobilenode.o common/clicknode.o \ mac/arp.o mobile/god.o mobile/dem.o \ mobile/topography.o mobile/modulation.o \ queue/priqueue.o queue/dsr-priqueue.o \ @@ -274,6 +276,7 @@ pgm/pgm-receiver.o mcast/rcvbuf.o \ mcast/classifier-lms.o mcast/lms-agent.o mcast/lms-receiver.o \ mcast/lms-sender.o \ + routing/extrouter.o routing/extclickrouter.o \ @V_STLOBJ@ @@ -432,6 +435,7 @@ tcl/lib/ns-srcrt.tcl \ tcl/mcast/ns-lms.tcl \ tcl/lib/ns-qsnode.tcl \ + tcl/lib/ns-clicknode.tcl \ @V_NS_TCL_LIB_STL@ $(GEN_DIR)ns_tcl.cc: $(NS_TCL_LIB) --- ns-2.26.orig/configure.in 2003-02-26 15:07:56.000000000 -0700 +++ ns-2.26.nsclickcvs/configure.in 2003-04-10 10:54:08.000000000 -0600 @@ -23,6 +23,8 @@ builtin(include, ./conf/configure.in.x11) builtin(include, ./conf/configure.in.tcldebug) builtin(include, ./conf/configure.in.dmalloc) +builtin(include, ./conf/configure.in.click) +builtin(include, ./conf/configure.in.libnet) default_classinstvar=yes builtin(include, ./conf/configure.in.debugopts) --- ns-2.26.orig/apps/udp.cc 2003-02-26 15:07:16.000000000 -0700 +++ ns-2.26.nsclickcvs/apps/udp.cc 2003-04-21 22:22:56.000000000 -0600 @@ -18,7 +18,7 @@ #ifndef lint static const char rcsid[] = - "@(#) $Header: /nfs/jade/vint/CVSROOT/ns-2/apps/udp.cc,v 1.19 2001/11/16 22:29:59 buchheim Exp $ (Xerox)"; + "@(#) $Header: /srl/dirkcvs/nsclick/ns/apps/udp.cc,v 1.2 2003/04/16 05:42:49 neufeldm Exp $ (Xerox)"; #endif #include "udp.h" @@ -82,7 +82,8 @@ if (flags && (0 ==strcmp(flags, "NEW_BURST"))) rh->flags() |= RTP_M; p->setdata(data); - target_->recv(p); + //target_->recv(p); + Agent::send(p,0); } n = nbytes % size_; if (n > 0) { @@ -97,7 +98,8 @@ if (flags && (0 == strcmp(flags, "NEW_BURST"))) rh->flags() |= RTP_M; p->setdata(data); - target_->recv(p); + //target_->recv(p); + Agent::send(p,0); } idle(); } --- ns-2.26.orig/classifier/classifier-click.cc 1969-12-31 17:00:00.000000000 -0700 +++ ns-2.26.nsclickcvs/classifier/classifier-click.cc 2003-04-30 16:27:19.000000000 -0600 @@ -0,0 +1,604 @@ +/* + * classifier-click classifier file for nsclick + * $Header: /srl/dirkcvs/nsclick/ns/classifier/classifier-click.cc,v 1.13 2003/04/25 00:45:37 neufeldm Exp $ + */ + +/***************************************************************************** + * Copyright 2002, Univerity of Colorado at Boulder. * + * * + * All Rights Reserved * + * * + * Permission to use, copy, modify, and distribute this software and its * + * documentation for any purpose other than its incorporation into a * + * commercial product is hereby granted without fee, provided that the * + * above copyright notice appear in all copies and that both that * + * copyright notice and this permission notice appear in supporting * + * documentation, and that the name of the University not be used in * + * advertising or publicity pertaining to distribution of the software * + * without specific, written prior permission. * + * * + * UNIVERSITY OF COLORADO DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS * + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND * + * FITNESS FOR ANY PARTICULAR PURPOSE. IN NO EVENT SHALL THE UNIVERSITY * + * OF COLORADO BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL * + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA * + * OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * + * PERFORMANCE OF THIS SOFTWARE. * + * * + ****************************************************************************/ + +#include "config.h" +#include +#include +#include +#include +//#include +//#include +#include +#include + +#include "agent.h" +#include "packet.h" +#include "rawpacket.h" +#include "ip.h" +#include "extrouter.h" +#include "classifier.h" +#include "classifier-ext.h" +#include "mobilenode.h" +#include "clicknode.h" +#include "address.h" +#include +#include "scheduler.h" +#include "classifier-click.h" +#include "ll-ext.h" +#include "clickqueue.h" + +static class ClickClassifierClass : public TclClass { +public: + ClickClassifierClass() : TclClass("Classifier/Ext/Click") {} + TclObject* create(int, const char*const*) { + return (new ClickClassifier()); + } +} class_click_classifier; + + +void +ClickEventHandler::handle(Event* event) { + // XXX dangerous downcast - should use RTTI + ClickEvent* cevent = (ClickEvent*) event; + simclick_simstate esimstate; + esimstate.curtime = cevent->when_; + //fprintf(stderr,"Should be calling simclick_click_run: %lf\n",event->time_); + + simclick_click_run(cevent->clickinst_,&esimstate); + delete cevent; +} + +map ClickClassifier::global_mactonodemap_; +map ClickClassifier::global_mactonsmacmap_; +map ClickClassifier::global_ipmap_; + +ClickClassifier::ClickClassifier() { + extrouter_ = this; + clickinst_ = NULL; +} + +int +ClickClassifier::command(int argc, const char*const* argv) +{ + Tcl& tcl = Tcl::instance(); + if (2 == argc) { + if (strcmp(argv[1], "getnodename") == 0) { + // getnodename + tcl.resultf(nodename_.c_str()); + return TCL_OK; + } + if (strcmp(argv[1], "runclick") == 0) { + // runclick + if (clickinst_) { + simclick_simstate simstate; + simstate.curtime = GetSimTime(); + simclick_click_run(clickinst_,&simstate); + } + return TCL_OK; + } + } + else if (3 == argc) { + if(strcmp(argv[1], "loadclick") == 0) { + simclick_simstate simstate; + simstate.curtime = GetSimTime(); + clickinst_ = simclick_click_create((simclick_sim)this,argv[2],&simstate); + simclick_click_run(clickinst_,&simstate); + + return TCL_OK; + } + if (strcmp(argv[1], "getip") == 0) { + // getip + int theif = simclick_sim_ifid_from_name((simclick_sim)this,argv[2]); + //fprintf(stderr,"get ipaddr is %s\n",ifipaddrs_[theif].c_str()); + tcl.resultf(ifipaddrs_[theif].c_str()); + return TCL_OK; + } + if (strcmp(argv[1], "getmac") == 0) { + // getmac + int theif = simclick_sim_ifid_from_name((simclick_sim)this,argv[2]); + //fprintf(stderr,"get macaddr is %s\n",ifmacaddrs_[theif].c_str()); + tcl.resultf(ifmacaddrs_[theif].c_str()); + return TCL_OK; + } + if (strcmp(argv[1], "setnodename") == 0) { + // setnodename + nodename_ = argv[2]; + return TCL_OK; + } + if (strcmp(argv[1], "setnodeaddr") == 0) { + // setnodeaddr + nodeaddr_ = Address::instance().str2addr(argv[2]); + return TCL_OK; + } + } + else if (4 == argc) { + if(strcmp(argv[1], "setip") == 0) { + // setip + int theif = simclick_sim_ifid_from_name((simclick_sim)this,argv[2]); + ifipaddrs_[theif] = string(argv[3]); + //fprintf(stderr,"ipaddr is %s\n",ifipaddrs_[theif].c_str()); + // Also save the binary form of this IP address in a static + // (i.e. simulator global) hash map of IP addresses to ns-2 + // addresses. This lets us track map IP to ns-2 address when + // we might need it. + global_ipmap_[inet_addr(argv[3])] = nodeaddr_; + return TCL_OK; + } + else if(strcmp(argv[1], "setmac") == 0) { + // setmac + int theif = simclick_sim_ifid_from_name((simclick_sim)this,argv[2]); + ifmacaddrs_[theif] = string(argv[3]); + + //fprintf(stderr,"macaddr is %s\n",ifmacaddrs_[theif].c_str()); + + // Also save the binary form of this MAC address in a static + // (i.e. simulator global) hash map of MAC addresses to ns-2 + // addresses. This lets us set the destination address in the + // ns-2 packet header. + MACAddr thismacaddr = MACAddr(string(argv[3])); + global_mactonodemap_[thismacaddr] = nodeaddr_; + LL* mylink = (LL*) slot_[theif]; + global_mactonsmacmap_[thismacaddr] = mylink->macDA(); + return TCL_OK; + } + else if (strcmp(argv[1], "readhandler") == 0) { + char* readreturn = 0; + readreturn = simclick_click_read_handler(clickinst_,argv[2],argv[3],0,0); + //fprintf(stderr, "readhandler: %s\n",clickretc); + if (readreturn) { + tcl.resultf("%s", readreturn); + free(readreturn); + readreturn = 0; + } + else { + tcl.resultf(""); + } + return TCL_OK; + } + } else if (argc == 5) { + if (strcmp(argv[1], "writehandler") == 0) { + int clickret; + clickret = simclick_click_write_handler(clickinst_, argv[2], argv[3], + argv[4]); + //fprintf(stderr, "writehandler: %i\n",clickret); + tcl.resultf("%i", clickret); + return TCL_OK; + } + } + + return ExtClassifier::command(argc, argv); +} + + +ClickClassifier::~ClickClassifier() { +} + +int +ClickClassifier::route(Packet* p) { + int result = 0; + if (clickinst_) { + unsigned char* data = NULL; + int len = ((PacketData*)(p->userdata()))->size(); + simclick_simpacketinfo simpinfo; + hdr_cmn* chdr = HDR_CMN(p); + int ifid = chdr->iface_; + hdr_ip* iphdr = hdr_ip::access(p); + simpinfo.id = chdr->uid(); + simpinfo.fid = iphdr->flowid(); + hdr_raw* rhdr = hdr_raw::access(p); + int nssubtype = rhdr->subtype; + int clicktype = GetClickPacketType(nssubtype); + simpinfo.simtype = rhdr->ns_type; + unsigned char* pdat = p->accessdata(); + data = new unsigned char[len]; + memcpy(data,pdat,len); + /* + * XXX Destroy packet for now. This may change if we wind + * up having to track and reuse ns packets after they've gone through + * click. + */ + Packet::free(p); + p = NULL; + + simclick_simstate simstate; + simstate.curtime = GetSimTime(); + //fprintf(stderr,"Sending packet up to click...\n"); + simclick_click_send(clickinst_,&simstate,ifid,clicktype,data,len,&simpinfo); + delete[] data; + data = 0; + } + else { + fprintf(stderr,"No click upcall set!\n"); + } + return result; +} + +string +ClickClassifier::GetIPAddr(int ifid) { + return ifipaddrs_[ifid]; +} + +string +ClickClassifier::GetMACAddr(int ifid) { + return ifmacaddrs_[ifid]; +} + +string +ClickClassifier::GetNodeName() { + return nodename_; +} + +/* + * Click service methods + */ +int simclick_sim_ifid_from_name(simclick_sim simid, const char* ifname) { + int ifid = -1; + char* devname = NULL; + + /* + * Provide a mapping between a textual interface name + * and the id numbers used. This is mostly for the + * benefit of click scripts, i.e. you can still refer to + * an interface as, say, /dev/eth0. + */ + if (strstr(ifname,"tap") || strstr(ifname,"tun")) { + /* + * A tapX or tunX interface goes to and from the kernel - + * always IFID_KERNELTAP + */ + ifid = ExtRouter::IFID_KERNELTAP; + } + else if ((devname = strstr(ifname,"eth"))) { + /* + * Anything with an "eth" followed by a number is + * a regular interface. Add the number to IFID_FIRSTIF + * to get the handle. + */ + while (*devname && !isdigit(*devname)) { + devname++; + } + if (*devname) { + ifid = atoi(devname) + ExtRouter::IFID_FIRSTIF; + } + } + else if ((devname = strstr(ifname,"drop"))) { + /* + * Anything with an "drop" followed by a number is + * a special interface on which we place packets that + * get dropped due to MAC layer feedback. Add the number to + * IFID_FIRSTIFDROP to get the handle. + */ + while (*devname && !isdigit(*devname)) { + devname++; + } + if (*devname) { + ifid = atoi(devname) + ExtRouter::IFID_FIRSTIFDROP; + } + } + return ifid; +} + +int +simclick_sim_send_to_if(simclick_sim siminst,simclick_click clickinst, + int ifid,int type, const unsigned char* data,int len, + simclick_simpacketinfo* pinfo) { + + if (NULL == siminst) { + return -1; + } + + /* + * Bail out if we get a bad ifid + */ + if (ExtRouter::IFID_LASTIF < ifid) { + return -1; + } + /* + * XXX should probably use RTTI typesafe casts if they are now + * reliably implemented across the compilers/platforms we want + * to run on. + */ + ClickClassifier* theclassifier = (ClickClassifier*)siminst; + + return theclassifier->send_to_if(ifid,type,data,len,pinfo); +} + +int +simclick_sim_schedule(simclick_sim siminst,simclick_click clickinst, + struct timeval* when) { + + int result = 0; + double simtime = when->tv_sec + (when->tv_usec/1.0e6); + double simdelay = simtime - Scheduler::instance().clock(); + ClickClassifier* theclassifier = (ClickClassifier*)siminst; + ClickEvent* ev = new ClickEvent(); + ev->clickinst_ = clickinst; + ev->when_ = *when; + Scheduler::instance().schedule(&(theclassifier->cevhandler_),ev,simdelay); + //fprintf(stderr,"Event scheduled in %f seconds\n",simdelay); + + return result; +} + +void +simclick_sim_ipaddr_from_name(simclick_sim siminst,const char* ifname, + char* buf,int len) { + ClickClassifier* theclassifier = (ClickClassifier*)siminst; + int theif = simclick_sim_ifid_from_name(siminst,ifname); + string ipaddr = theclassifier->GetIPAddr(theif); + memset(buf,0,len); + ipaddr.copy(buf,len-1); +} + +void +simclick_sim_macaddr_from_name(simclick_sim siminst,const char* ifname, + char* buf,int len) { + ClickClassifier* theclassifier = (ClickClassifier*)siminst; + int theif = simclick_sim_ifid_from_name(siminst,ifname); + string macaddr = theclassifier->GetMACAddr(theif); + memset(buf,0,len); + macaddr.copy(buf,len-1); +} + +void +simclick_sim_get_node_name(simclick_sim siminst,char* buf,int len) { + ClickClassifier* theclassifier = (ClickClassifier*)siminst; + string nodename = theclassifier->GetNodeName(); + memset(buf,0,len); + nodename.copy(buf,len-1); +} + +int +ClickClassifier::send_to_if(int ifid,int type,const unsigned char* data, + int len,simclick_simpacketinfo* pinfo) { + int result = 0; + Tcl& tcl = Tcl::instance(); + + /* + * Package raw data into an ns-2 format raw packet, then send + * it on down the line. + */ + + Packet* pkt = MakeRawPacket(type,ifid,data,len,pinfo); + //fprintf(stderr,"simclickid == %d\n",simclickid); + recv(pkt,0); + + return result; +} + +int +ClickClassifier::IFReady(int ifid) { + NsObject* target = NULL; + int ready = 0; + + // XXX assumes direct ifid->slot mapping + if (ExtRouter::IFID_KERNELTAP == ifid) { + return 1; + } + + target = slot_[ifid]; + if (target) { + LLExt* llext = (LLExt*) target; + ready = llext->ready(); + } + else { + ready = 0; + fprintf(stderr,"ERROR: network interface does not exist\n"); + } + + return ready; +} + +int +simclick_sim_if_ready(simclick_sim siminst,simclick_click clickinst,int ifid) { + int result = 0; + ClickClassifier* theclassifier = (ClickClassifier*)siminst; + result = theclassifier->IFReady(ifid); + return result; +} + +int +ClickClassifier::GetNSSubtype(int type) { + switch (type) { + case SIMCLICK_PTYPE_ETHER: + return hdr_raw::ETHERNET; + + case SIMCLICK_PTYPE_IP: + return hdr_raw::IP; + + default: + return hdr_raw::NONE; + } + + return hdr_raw::NONE; +} + +int +ClickClassifier::GetClickPacketType(int nssubtype) { + switch (nssubtype) { + case hdr_raw::ETHERNET: + return SIMCLICK_PTYPE_ETHER; + + case hdr_raw::IP: + return SIMCLICK_PTYPE_IP; + + default: + return SIMCLICK_PTYPE_UNKNOWN; + } + + return SIMCLICK_PTYPE_UNKNOWN; +} + +// XXX +// Normally I'd bitterly complain about code like this. However, +// I don't really want to worry about annoying differences +// between IP header files across different platforms, and I +// want to get this code up and running ASAP. So... I'm defining +// a few things here to handle the minimal packet cracking I +// need to do to create raw packets. If more complicated +// packet munging is called for, something better should be created. +#define NS_ETHER_OFFSET_DADDR 0 +#define NS_ETHER_OFFSET_SADDR 6 +#define NS_ETHER_HEADER_SIZE 14 + + +void +ClickClassifier::LinkLayerFailedCallback(Packet* p, void* arg) { + // Hit the callback and then free the packet + ((ClickClassifier*)arg)->LinkLayerFailed(p); + Packet::free(p); +} + +void +ClickClassifier::LinkLayerFailed(Packet* p) { + //fprintf(stderr,"XXX Lost a packet!!!\n"); + if (clickinst_) { + unsigned char* data = NULL; + int len = ((PacketData*)(p->userdata()))->size(); + simclick_simpacketinfo simpinfo; + hdr_cmn* chdr = HDR_CMN(p); + int ifid = chdr->iface_ + IFID_LASTIF; + hdr_ip* iphdr = hdr_ip::access(p); + simpinfo.id = chdr->uid(); + simpinfo.fid = iphdr->flowid(); + hdr_raw* rhdr = hdr_raw::access(p); + int nssubtype = rhdr->subtype; + int clicktype = GetClickPacketType(nssubtype); + unsigned char* pdat = p->accessdata(); + data = new unsigned char[len]; + memcpy(data,pdat,len); + simclick_simstate simstate; + simstate.curtime = GetSimTime(); + //fprintf(stderr,"Sending packet up to click...\n"); + simclick_click_send(clickinst_,&simstate,ifid,clicktype,data,len,&simpinfo); + delete data; + data = 0; + } + else { + fprintf(stderr,"No click upcall set!\n"); + } +} + +Packet* +ClickClassifier::MakeRawPacket(int type,int ifid,const unsigned char* data, + int len,simclick_simpacketinfo* pinfo){ + Packet* pkt = Packet::alloc(len); + /* + * Shovel raw data into packet + */ + hdr_raw* rhdr = hdr_raw::access(pkt); + rhdr->subtype = GetNSSubtype(type); + unsigned char* pdat = pkt->accessdata(); + memcpy(pdat,data,len); + + /* + * Set some of the packet header stuff ns-2 wants + */ + struct hdr_cmn* chdr = HDR_CMN(pkt); + chdr->iface() = ifid; + chdr->ptype() = PT_RAW; + chdr->size() = len; + if (pinfo->id >= 0) { + chdr->uid() = pinfo->id; + } + else { + chdr->uid() = Agent::getnextuid(); + } + rhdr->ns_type = (-1 == pinfo->simtype) ? PT_RAW : pinfo->simtype; + chdr->xmit_failure_ = LinkLayerFailedCallback; + chdr->xmit_failure_data_ = (void*)this; + + hdr_ip* iphdr = hdr_ip::access(pkt); + iphdr->flowid() = 0; + if (pinfo->fid >= 0) { + iphdr->flowid() = pinfo->fid; + } + + /* + * A packet coming in from click on the kernel tap device is + * considered to be going up into the node, on any other device + * going down out of it. + */ + if (ExtRouter::IFID_KERNELTAP == ifid) { + chdr->direction() = hdr_cmn::UP; + } + else { + chdr->direction() = hdr_cmn::DOWN; + // Going out to a network adapter, and we're already + // ethernet encapsulated. The ns-2 interface code will + // tack on ethernet header overhead as well, so we subtract + // it out of our simulated size here to avoid actual packet + // size inflation + if (hdr_raw::ETHERNET == rhdr->subtype) { + chdr->size() -= NS_ETHER_HEADER_SIZE; + } + } + + // If we've got ethernet encapsulation, translate mac address + // to ns address. Otherwise we're SOL. + struct hdr_mac* mhdr = HDR_MAC(pkt); + if (hdr_raw::ETHERNET == rhdr->subtype) { + MACAddr dmac(data + NS_ETHER_OFFSET_DADDR); + MACAddr smac(data + NS_ETHER_OFFSET_SADDR); + if (dmac.is_broadcast()) { + mhdr->macDA_ = MAC_BROADCAST; + } + else { + mhdr->macDA_ = global_mactonsmacmap_[dmac]; + //fprintf(stderr,"XXX using real MAC: %s -> %d\n",dmac.to_string().c_str(),mhdr->macDA_); + } + mhdr->macSA_ = global_mactonsmacmap_[smac]; + chdr->next_hop_ = global_mactonodemap_[dmac]; + chdr->prev_hop_ = global_mactonodemap_[smac]; + } + else { + //fprintf(stderr,"XXX using broadcast mac XXX\n"); + mhdr->macDA_ = MAC_BROADCAST; + } + + // Got an IP packet? Must have come from click, and therefore + // the next hop is us. + if ((ExtRouter::IFID_KERNELTAP == ifid) && (hdr_raw::IP == rhdr->subtype)) { + chdr->next_hop() = nodeaddr_; + } + + return pkt; +} + +struct timeval +ClickClassifier::GetSimTime() { + struct timeval curtime; + double ns2time = Scheduler::instance().clock(); + double fracp,intp; + fracp = modf(ns2time,&intp); + curtime.tv_sec = intp; + curtime.tv_usec = (fracp * 1.0e6 + 0.5); + return curtime; +} --- ns-2.26.orig/classifier/classifier-click.h 1969-12-31 17:00:00.000000000 -0700 +++ ns-2.26.nsclickcvs/classifier/classifier-click.h 2003-04-30 16:27:19.000000000 -0600 @@ -0,0 +1,158 @@ +/* + * + * This might not seem like a regular classifier, and it isn't. + * It essentially has a fixed interface ID which it sends along + * with its packet to the ClickNode it lives on, the idea being + * that the Click subsystem will be the thing which actually + * does the classifying, not the classifier. + * + * $Header: /srl/dirkcvs/nsclick/ns/classifier/classifier-click.h,v 1.6 2003/04/25 00:45:37 neufeldm Exp $ + */ + +/***************************************************************************** + * Copyright 2002, Univerity of Colorado at Boulder. * + * * + * All Rights Reserved * + * * + * Permission to use, copy, modify, and distribute this software and its * + * documentation for any purpose other than its incorporation into a * + * commercial product is hereby granted without fee, provided that the * + * above copyright notice appear in all copies and that both that * + * copyright notice and this permission notice appear in supporting * + * documentation, and that the name of the University not be used in * + * advertising or publicity pertaining to distribution of the software * + * without specific, written prior permission. * + * * + * UNIVERSITY OF COLORADO DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS * + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND * + * FITNESS FOR ANY PARTICULAR PURPOSE. IN NO EVENT SHALL THE UNIVERSITY * + * OF COLORADO BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL * + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA * + * OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * + * PERFORMANCE OF THIS SOFTWARE. * + * * + ****************************************************************************/ + +#ifndef ns_classifier_click_h +#define ns_classifier_click_h + +#include "object.h" + +class Packet; + + +class ClickEvent : public Event { + public: + simclick_click clickinst_; + // Store an extra copy of the call time in sec/usec format. + // This is to sidestep some roundoff errors which occured + // when going back and forth between sec/usec and doubles. + struct timeval when_; +}; + +class ClickEventHandler : public Handler { + public: + virtual void handle(Event* event); +}; + +class MACAddr { + public: + MACAddr() { + memset(macaddr_,0,6); + } + explicit MACAddr(const string straddr) { + sscanf(straddr.c_str(), "%02X:%02X:%02X:%02X:%02X:%02X", &macaddr_[0], + &macaddr_[1], &macaddr_[2], &macaddr_[3], &macaddr_[4], + &macaddr_[5]); + } + explicit MACAddr(const unsigned char* rawaddr) { + memcpy(macaddr_,rawaddr,6); + } + bool operator==(const MACAddr& rhs) const { + return(0 == memcmp(macaddr_,rhs.macaddr_,6)); + } + + bool is_broadcast() { + for (int i=0;i<6;i++) { + if (macaddr_[i] != 0xff) { + return false; + } + } + return true; + } + + string to_string() { + char tmp[64]; + sprintf(tmp, "%02X:%02X:%02X:%02X:%02X:%02X", macaddr_[0], + macaddr_[1], macaddr_[2], macaddr_[3], macaddr_[4], + macaddr_[5]); + + return string(tmp); + } + unsigned char macaddr_[6]; +}; + +namespace std { +struct less { + bool operator()(const MACAddr& l, const MACAddr& r) const { + // Treat MAC as a big old integer... + uint32_t leftu = *((uint32_t*)(l.macaddr_)); + uint32_t rightu = *((uint32_t*)(r.macaddr_)); + uint16_t leftl = *((uint16_t*)(l.macaddr_+4)); + uint16_t rightl = *((uint16_t*)(r.macaddr_+4)); + + // Check the upper bytes first, if those are equal check lower + if (leftu < rightu) { + return true; + } + else if (leftu == rightu) { + return (leftl < rightl); + } + return false; + } +}; +} + +class ClickClassifier : public ExtClassifier,public ExtRouter { + public: + ClickClassifier(); + virtual ~ClickClassifier(); + virtual int command(int argc, const char*const* argv); + + /* + * Stuff to handle click requests + */ + public: + virtual int send_to_if(int ifid,int type,const unsigned char* data, + int len,simclick_simpacketinfo* pinfo); + ClickEventHandler cevhandler_; + + // ExtRouter method + virtual int route(Packet* p); + + string GetIPAddr(int ifid); + string GetMACAddr(int ifid); + string GetNodeName(); + int IFReady(int ifid); + simclick_click GetClickinst() { return clickinst_; } + static void LinkLayerFailedCallback(Packet* p, void* arg); + void LinkLayerFailed(Packet* p); + protected: + int GetNSSubtype(int clicktype); + int GetClickPacketType(int nssubtype); + struct timeval GetSimTime(); + Packet* MakeRawPacket(int type,int ifid,const unsigned char* data,int len, + simclick_simpacketinfo* pinfo); + simclick_click clickinst_; + typedef map STRmap; + map ifipaddrs_; + map ifmacaddrs_; + static map global_mactonodemap_; + static map global_mactonsmacmap_; + static map global_ipmap_; + string nodename_; + int nodeaddr_; +}; + +#endif --- ns-2.26.orig/classifier/classifier-ext.cc 1969-12-31 17:00:00.000000000 -0700 +++ ns-2.26.nsclickcvs/classifier/classifier-ext.cc 2002-06-10 13:22:59.000000000 -0600 @@ -0,0 +1,162 @@ +/* + * classifier-ext.cc + * Base external router classifier + * + * $Header: /srl/dirkcvs/nsclick/ns/classifier/classifier-ext.cc,v 1.1 2002/06/10 19:22:59 neufeldm Exp $ + */ + +/***************************************************************************** + * Copyright 2002, Univerity of Colorado at Boulder. * + * * + * All Rights Reserved * + * * + * Permission to use, copy, modify, and distribute this software and its * + * documentation for any purpose other than its incorporation into a * + * commercial product is hereby granted without fee, provided that the * + * above copyright notice appear in all copies and that both that * + * copyright notice and this permission notice appear in supporting * + * documentation, and that the name of the University not be used in * + * advertising or publicity pertaining to distribution of the software * + * without specific, written prior permission. * + * * + * UNIVERSITY OF COLORADO DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS * + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND * + * FITNESS FOR ANY PARTICULAR PURPOSE. IN NO EVENT SHALL THE UNIVERSITY * + * OF COLORADO BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL * + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA * + * OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * + * PERFORMANCE OF THIS SOFTWARE. * + * * + ****************************************************************************/ + +#include +#include "config.h" +#include "packet.h" +#include "ip.h" +#include "extrouter.h" +#include "classifier.h" +#include "classifier-hash.h" +#include "classifier-ext.h" + + +static class ExtClassifierClass : public TclClass { +public: + ExtClassifierClass() : TclClass("Classifier/Ext") {} + TclObject* create(int, const char*const*) { + return (new ExtClassifier()); + } +} class_ext_classifier; + + +ExtClassifier::ExtClassifier() { + extrouter_ = NULL; +} + +ExtClassifier::~ExtClassifier() { +} + +int ExtClassifier::command(int argc, const char*const* argv) { + int result = TCL_OK; + Tcl& tcl = Tcl::instance(); + + result = Classifier::command(argc,argv); + return result; +} + +void ExtClassifier::recv(Packet* p, Handler* h) { + /* + * Use the interface and direction to decide what to do. If the + * packet is going down and came from an agent, it needs to + * go to the external router for processing. If coming up + * from the external router it needs to be sent to the appropriate + * local agent for processing. Otherwise, it just goes either down + * to the ns network interface or up to the external router. + */ + struct hdr_cmn* hdr = HDR_CMN(p); + int extid = hdr->iface(); + if (hdr_cmn::DOWN == hdr->direction()) { + if (ExtRouter::IFID_KERNELTAP == extid) { + /* + * Packet came from an agent - needs to go to the external router + */ + //fprintf(stderr,"To external router\n"); + if (NULL != extrouter_) { + extrouter_->route(p); + } + else { + fprintf(stderr,"No external router set!\n"); + } + } + else { + /* + * Packet came from the external router - needs to go to the net + */ + int cl = classify(p); + if ((cl >= 0) && (cl <= maxslot_)) { + NsObject* target = NULL; + target = slot_[cl]; + if (NULL == target) { + /* + * "Drop" the packet + */ + //puts("Dropping the packet"); + Packet::free(p); + } + else { + //puts("Sending packet out!!!"); + target->recv(p,h); + } + } + else { + fprintf(stderr,"Invalid slot: %d maxslot is %d\n",cl,maxslot_); + } + } + } + else if (hdr_cmn::UP == hdr->direction()) { + if (ExtRouter::IFID_KERNELTAP == extid) { + /* + * Packet came from the external router - needs to go to an agent. + */ + NsObject* target = NULL; + target = slot_[0]; + if (NULL == target) { + /* + * "Drop" the packet + */ + //fprintf(stderr,"Dropping the packet\n"); + Packet::free(p); + } + else { + //fprintf(stderr,"Packet going to agent\n"); + target->recv(p,h); + } + + //fprintf(stderr,"Hey! Send packets to agents!\n"); + } + else { + /* + * Packet came from the net - needs to go to the external router + */ + if (NULL != extrouter_) { + extrouter_->route(p); + } + } + } + else { + fprintf(stderr,"No packet direction set..."); + } +} + +int +ExtClassifier::classify(Packet* p) { + struct hdr_cmn* hdr = HDR_CMN(p); + int extid = hdr->iface(); + + /* + * Simple mapping between extid and slot number. + * No real reason to make things more complicated right now. + */ + int slot = extid; + return slot; +} --- ns-2.26.orig/classifier/classifier-ext.h 1969-12-31 17:00:00.000000000 -0700 +++ ns-2.26.nsclickcvs/classifier/classifier-ext.h 2002-06-10 13:22:59.000000000 -0600 @@ -0,0 +1,59 @@ +/* + * + * This classifier is intended for use with external routers bolted + * on to ns-2, e.g. Click. It uses a combination of the packet direction + * and interface ID to decide where to send stuff. + * + * $Header: /srl/dirkcvs/nsclick/ns/classifier/classifier-ext.h,v 1.1 2002/06/10 19:22:59 neufeldm Exp $ + */ + +/***************************************************************************** + * Copyright 2002, Univerity of Colorado at Boulder. * + * * + * All Rights Reserved * + * * + * Permission to use, copy, modify, and distribute this software and its * + * documentation for any purpose other than its incorporation into a * + * commercial product is hereby granted without fee, provided that the * + * above copyright notice appear in all copies and that both that * + * copyright notice and this permission notice appear in supporting * + * documentation, and that the name of the University not be used in * + * advertising or publicity pertaining to distribution of the software * + * without specific, written prior permission. * + * * + * UNIVERSITY OF COLORADO DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS * + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND * + * FITNESS FOR ANY PARTICULAR PURPOSE. IN NO EVENT SHALL THE UNIVERSITY * + * OF COLORADO BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL * + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA * + * OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * + * PERFORMANCE OF THIS SOFTWARE. * + * * + ****************************************************************************/ + +#ifndef ns_classifier_ext_h +#define ns_classifier_ext_h + +#include "object.h" + +class Packet; + +class ExtClassifier : public Classifier { + public: + ExtClassifier(); + virtual ~ExtClassifier(); + + virtual void recv(Packet* p, Handler* h); + + void setExtRouter(ExtRouter* ext) {extrouter_ = ext;} + ExtRouter* getExtRouter() {return extrouter_;} + + virtual int classify(Packet*); + + protected: + virtual int command(int argc, const char*const* argv); + ExtRouter* extrouter_; +}; + +#endif --- ns-2.26.orig/common/agent.cc 2003-02-26 15:07:38.000000000 -0700 +++ ns-2.26.nsclickcvs/common/agent.cc 2003-04-21 22:22:56.000000000 -0600 @@ -34,7 +34,7 @@ #ifndef lint static const char rcsid[] = - "@(#) $Header: /nfs/jade/vint/CVSROOT/ns-2/common/agent.cc,v 1.74 2002/06/14 23:15:02 yuri Exp $ (LBL)"; + "@(#) $Header: /srl/dirkcvs/nsclick/ns/common/agent.cc,v 1.5 2003/04/15 23:23:50 neufeldm Exp $ (LBL)"; #endif #include @@ -43,6 +43,7 @@ #include "config.h" #include "agent.h" #include "ip.h" +#include "tcp.h" #include "flags.h" #include "address.h" #include "app.h" @@ -51,6 +52,8 @@ #include "nix/nixnode.h" #endif //HAVE_STL +#include "rawpacket.h" +#include "extrouter.h" #ifndef min @@ -67,11 +70,23 @@ int Agent::uidcnt_; /* running unique id */ +#ifdef USE_LIBNET_1_1_X +// Stuff for libnet 1.1.X +libnet_t* Agent::libnet_context_; +char libnet_errbuf_[LIBNET_ERRBUF_SIZE]; +#endif + Agent::Agent(packet_t pkttype) : size_(0), type_(pkttype), channel_(0), traceName_(NULL), - oldValueList_(NULL), app_(0), et_(0) + oldValueList_(NULL), app_(0), et_(0), rawcvt_(false) { +#ifdef USE_LIBNET_1_1_X + if (0 == libnet_context_) { + libnet_context_ = libnet_init(,,libnet_errbuf_); + } +#endif + } void @@ -170,6 +185,22 @@ } else if (strcmp(argv[1], "set_pkttype") == 0) { set_pkttype(packet_t(atoi(argv[2]))); return (TCL_OK); + } else if (strcmp(argv[1], "set-srcip") == 0) { + srcip_ = libnet_name_resolve((unsigned char*)argv[2],0); + return (TCL_OK); + } else if (strcmp(argv[1], "set-srcport") == 0) { + srcport_ = atoi(argv[2]); + return (TCL_OK); + } + else if (strcmp(argv[1], "set-destip") == 0) { + destip_ = libnet_name_resolve((unsigned char*)argv[2],0); + return (TCL_OK); + } else if (strcmp(argv[1], "set-destport") == 0) { + destport_ = atoi(argv[2]); + return (TCL_OK); + } else if (strcmp(argv[1],"rawconvert") == 0) { + rawcvt_ = atoi(argv[2]); + return(TCL_OK); } } else if (argc == 4) { @@ -428,10 +459,128 @@ */ } +bool +Agent::toraw(Packet* p) { + // XXX What about AppData and other such junk? Need to + // figure out if anyone actually sends payloads. + // XXX What about TCP option headers? Won't work with SACK right now + bool result = false; + struct hdr_tcp* htcp = HDR_TCP(p); + struct hdr_ip* hip = HDR_IP(p); + struct hdr_cmn* hcmn = HDR_CMN(p); + struct hdr_raw* hraw = hdr_raw::access(p); + int packetlen = LIBNET_IP_H + hcmn->size_; + int paylen = hcmn->size_; + unsigned char* pdat = 0; + unsigned char* payload = 0; + unsigned char sflgs = 0; + if (0 < paylen) { + payload = new unsigned char[paylen]; + memset(payload,'A',paylen); + } + + switch (hcmn->ptype_) { + case PT_ACK: + sflgs = TH_ACK; + case PT_TCP: + packetlen += LIBNET_TCP_H; + p->allocdata(packetlen); + pdat = p->accessdata(); + memset(pdat,0,packetlen); + libnet_build_ip(packetlen-LIBNET_IP_H,IPTOS_LOWDELAY,ipseq_, + 0,hip->ttl_,IPPROTO_TCP,srcip_,destip_,NULL, + 0,pdat); + sflgs |= htcp->tcp_flags_; + libnet_build_tcp(srcport_,destport_,htcp->seqno_,htcp->ackno_, + sflgs,0,0,(unsigned char*)payload, + paylen,pdat+LIBNET_IP_H); + libnet_do_checksum(pdat,IPPROTO_TCP,packetlen); + libnet_do_checksum(pdat,IPPROTO_IP,LIBNET_IP_H); + result = true; + break; + + case PT_CBR: + packetlen += LIBNET_UDP_H; + p->allocdata(packetlen); + pdat = p->accessdata(); + memset(pdat,0,packetlen); + libnet_build_ip(packetlen-LIBNET_IP_H,IPTOS_LOWDELAY,ipseq_, + 0,hip->ttl_,IPPROTO_UDP,srcip_,destip_,NULL, + 0,pdat); + libnet_build_udp(srcport_,destport_,(unsigned char*)payload, + paylen,pdat+LIBNET_IP_H); + libnet_do_checksum(pdat,IPPROTO_UDP,packetlen); + libnet_do_checksum(pdat,IPPROTO_IP,LIBNET_IP_H); + result = true; + break; + default: + result = false; + break; + } + + + if (result) { + hcmn->direction() = hdr_cmn::DOWN; + hcmn->iface() = ExtRouter::IFID_KERNELTAP; + hraw->subtype = hdr_raw::IP; + hraw->ns_type = hcmn->ptype(); + hcmn->ptype() = PT_RAW; + hcmn->size() = packetlen; + ipseq_++; + } + + if (payload) { + delete[] payload; + payload = 0; + } + return result; +} + +bool +Agent::fromraw(Packet* p) { + struct hdr_tcp* htcp = HDR_TCP(p); + struct hdr_ip* hip = HDR_IP(p); + struct hdr_cmn* hcmn = HDR_CMN(p); + struct hdr_flags* hflg = hdr_flags::access(p); + struct libnet_ip_hdr* ip = 0; + struct libnet_tcp_hdr* tcp = 0; + struct libnet_udp_hdr* udp = 0; + unsigned char* pdat = 0; + bool result = false; + + if (PT_RAW != hcmn->ptype()) return false; + + pdat = p->accessdata(); + ip = (struct libnet_ip_hdr*)pdat; + + switch (ip->ip_p) { + case IPPROTO_TCP: + tcp = (struct libnet_tcp_hdr*)(pdat+LIBNET_IP_H); + htcp->seqno_ = ntohl(tcp->th_seq); + htcp->ackno_ = ntohl(tcp->th_ack); + htcp->tcp_flags_ = tcp->th_flags; + htcp->hlen_ = LIBNET_IP_H + LIBNET_TCP_H; + hcmn->ptype_ = (tcp->th_flags & TH_ACK) ? PT_ACK : PT_TCP; + result = true; + break; + case IPPROTO_UDP: + hcmn->ptype_ = PT_CBR; + result = true; + break; + default: + result = false; + break; + } + + return result; +} + void Agent::recv(Packet* p, Handler*) { - if (app_) + if (app_) { + if (rawcvt_) fromraw(p); app_->recv(hdr_cmn::access(p)->size()); + } /* * didn't expect packet (or we're a null agent?) */ --- ns-2.26.orig/common/agent.h 2003-02-26 15:07:38.000000000 -0700 +++ ns-2.26.nsclickcvs/common/agent.h 2003-04-21 22:22:56.000000000 -0600 @@ -31,7 +31,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#) $Header: /nfs/jade/vint/CVSROOT/ns-2/common/agent.h,v 1.35 2002/12/22 16:43:24 sfloyd Exp $ (LBL) + * @(#) $Header: /srl/dirkcvs/nsclick/ns/common/agent.h,v 1.5 2003/04/15 23:23:50 neufeldm Exp $ (LBL) */ #ifndef ns_agent_h @@ -43,6 +43,10 @@ #include "ns-process.h" #include "app.h" //#include "basetrace.h" +extern "C" { +#include +} + #define TIME_FORMAT "%.15g" // TIME_FORMAT is in basetrace.h, but including that header leads to problems @@ -77,7 +81,14 @@ //added for edrop tracing - ratul void recvOnly(Packet *) {}; - void send(Packet* p, Handler* h) { target_->recv(p, h); } + void send(Packet* p, Handler* h) { + if (rawcvt_) toraw(p); + target_->recv(p, h); + } + + bool toraw(Packet* p); + bool fromraw(Packet* p); + virtual void timeout(int tno); virtual void sendmsg(int sz, AppData*, const char* flags = 0); @@ -99,6 +110,7 @@ inline nsaddr_t& dport() { return dst_.port_; } void set_pkttype(packet_t pkttype) { type_ = pkttype; } inline packet_t get_pkttype() { return type_; } + static int getnextuid() { return uidcnt_++; } protected: int command(int argc, const char*const* argv); @@ -132,6 +144,24 @@ OldValue *oldValueList_; Application *app_; // ptr to application for callback + + // If this is set to "true" convert packets to and from + // raw format as they go to and from attached applications. + bool rawcvt_; + + // We also need to keep src and dest ip and port addresses + // around if we're going to use raw packets. + u_int16_t ipseq_; + u_long srcip_; + u_short srcport_; + u_long destip_; + u_short destport_; + +#ifdef USE_LIBNET_1_1_X + // Raw packet construction needs to have a libnet context + libnet_t* libnet_context_; + char libnet_errbuf_[LIBNET_ERRBUF_SIZE]; +#endif virtual void trace(TracedVar *v); void deleteAgentTrace(); --- ns-2.26.orig/common/clicknode.cc 1969-12-31 17:00:00.000000000 -0700 +++ ns-2.26.nsclickcvs/common/clicknode.cc 2002-06-10 13:23:01.000000000 -0600 @@ -0,0 +1,134 @@ +/* + * clicknode.cc + * Base class for nsclick nodes. + * + * XXX Should probably move a bunch of the functionality in this + * class to a superclass, i.e. something called ExtNode, since a lot + * of this should work with most Ext routing stuff, not just click. + * + * $Header: /srl/dirkcvs/nsclick/ns/common/clicknode.cc,v 1.1 2002/06/10 19:23:01 neufeldm Exp $ + * + */ + +/***************************************************************************** + * Copyright 2002, Univerity of Colorado at Boulder. * + * * + * All Rights Reserved * + * * + * Permission to use, copy, modify, and distribute this software and its * + * documentation for any purpose other than its incorporation into a * + * commercial product is hereby granted without fee, provided that the * + * above copyright notice appear in all copies and that both that * + * copyright notice and this permission notice appear in supporting * + * documentation, and that the name of the University not be used in * + * advertising or publicity pertaining to distribution of the software * + * without specific, written prior permission. * + * * + * UNIVERSITY OF COLORADO DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS * + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND * + * FITNESS FOR ANY PARTICULAR PURPOSE. IN NO EVENT SHALL THE UNIVERSITY * + * OF COLORADO BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL * + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA * + * OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * + * PERFORMANCE OF THIS SOFTWARE. * + * * + ****************************************************************************/ + +#include +#include +#include +#include + +#include "connector.h" +#include "delay.h" +#include "packet.h" +#include "agent.h" +#include "rawpacket.h" +#include "random.h" +#include "trace.h" +#include "address.h" + +#include "arp.h" +#include "topography.h" +#include "ll.h" +#include "mac.h" +#include "propagation.h" +#include "mobilenode.h" +#include "phy.h" +#include "wired-phy.h" +#include "god.h" +#include "extrouter.h" +#include "extclickrouter.h" +#include +#include +#include "clicknode.h" + + +static class ClickNodeClass : public TclClass { +public: + ClickNodeClass() : TclClass("Node/MobileNode/ClickNode") {} + TclObject* create(int, const char*const*) { + ClickNode* thenode = new ClickNode; + if (!thenode) { + return NULL; + } + + /* + * Do post-constructor initialization. + */ + int result = thenode->cinit(); + if (0 > result) { + delete thenode; + thenode = NULL; + } + + return thenode; + } +} class_clicknode; + + +ClickNode::ClickNode(void) { +} + +int +ClickNode::cinit() { + int result = 0; + return result; +} + +int +ClickNode::command(int argc, const char*const* argv) +{ + Tcl& tcl = Tcl::instance(); + if (2 == argc) { + } + else if (3 == argc) { + if(strcmp(argv[1], "addif") == 0) { + Phy* phyp = (Phy*)TclObject::lookup(argv[2]); + if(phyp == 0) { + return TCL_ERROR; + } + phyp->insertnode(&ifhead_); + phyp->setnode(this); + return TCL_OK; + } + } + else if (4 == argc) { + } + else if (5 == argc) { + } + + return MobileNode::command(argc, argv); +} + + +/* ====================================================================== + Other class functions + ====================================================================== */ +void +ClickNode::dump(void) { + printf("Dumping a clicknode...\n"); +} + + --- ns-2.26.orig/common/clicknode.h 1969-12-31 17:00:00.000000000 -0700 +++ ns-2.26.nsclickcvs/common/clicknode.h 2002-06-10 13:23:01.000000000 -0600 @@ -0,0 +1,66 @@ +/* + * clicknode.h + * + * $Header: /srl/dirkcvs/nsclick/ns/common/clicknode.h,v 1.1 2002/06/10 19:23:01 neufeldm Exp $ + * + */ + +/***************************************************************************** + * Copyright 2002, Univerity of Colorado at Boulder. * + * * + * All Rights Reserved * + * * + * Permission to use, copy, modify, and distribute this software and its * + * documentation for any purpose other than its incorporation into a * + * commercial product is hereby granted without fee, provided that the * + * above copyright notice appear in all copies and that both that * + * copyright notice and this permission notice appear in supporting * + * documentation, and that the name of the University not be used in * + * advertising or publicity pertaining to distribution of the software * + * without specific, written prior permission. * + * * + * UNIVERSITY OF COLORADO DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS * + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND * + * FITNESS FOR ANY PARTICULAR PURPOSE. IN NO EVENT SHALL THE UNIVERSITY * + * OF COLORADO BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL * + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA * + * OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * + * PERFORMANCE OF THIS SOFTWARE. * + * * + ****************************************************************************/ + +#ifndef __ns_clicknode_h__ +#define __ns_clicknode_h__ + +#include "object.h" +#include "trace.h" +#include "lib/bsd-list.h" +#include "node.h" + +class ClickNode : public MobileNode +{ + +public: + ClickNode(); + virtual int cinit(); + virtual int command(int argc, const char*const* argv); + inline ClickNode* nextnode() { return link_.le_next; } + + void dump(void); + +private: + + /* + * A global list of click nodes + */ + LIST_ENTRY(ClickNode) link_; + + /* + * Trace Target + */ + Trace* log_target_; + +}; + +#endif --- ns-2.26.orig/common/packet-stamp.h 2003-02-26 15:07:40.000000000 -0700 +++ ns-2.26.nsclickcvs/common/packet-stamp.h 2003-04-09 10:36:51.000000000 -0600 @@ -1,6 +1,6 @@ /* -*- c++ -*- packet-stamp.h - $Id: packet-stamp.h,v 1.3 1999/03/13 03:52:58 haoboy Exp $ + $Id: packet-stamp.h,v 1.2 2003/04/09 16:36:51 neufeldm Exp $ Information carried by a packet to allow a receive to decide if it will recieve the packet or not. @@ -23,6 +23,7 @@ public: PacketStamp() : ant(0), node(0), Pr(-1), lambda(-1) { } + void clear() { ant = 0; node = 0; Pr = -1; lambda = -1; } void init(const PacketStamp *s) { Antenna* ant; --- ns-2.26.orig/common/packet.cc 2003-02-26 15:07:40.000000000 -0700 +++ ns-2.26.nsclickcvs/common/packet.cc 2003-01-29 08:58:16.000000000 -0700 @@ -34,7 +34,7 @@ #ifndef lint static const char rcsid[] = - "@(#) $Header: /nfs/jade/vint/CVSROOT/ns-2/common/packet.cc,v 1.18 2000/09/15 20:32:57 haoboy Exp $ (LBL)"; + "@(#) $Header: /srl/dirkcvs/nsclick/ns/common/packet.cc,v 1.3 2003/01/29 15:58:16 neufeldm Exp $ (LBL)"; #endif #include "packet.h" @@ -145,3 +145,120 @@ return (new PacketHeaderManager); } } class_packethdr_mgr; + +#if 0 +bool +Packet::toraw() { + // XXX What about AppData and other such junk? Need to + // figure out if anyone actually sends payloads. + // XXX What about TCP option headers? Won't work with SACK right now + bool result = false; + struct hdr_tcp* htcp = HDR_TCP(this); + struct hdr_ip* hip = HDR_IP(this); + struct hdr_cmn* hcmn = HDR_CMN(this); + struct hdr_raw* hraw = hdr_raw::access(this); + int packetlen = LIBNET_IP_H + hcmn->size_; + int paylen = hcmn->size_; + unsigned char* pdat = 0; + unsigned char* payload = 0; + unsigned char sflgs = 0; + if (0 < paylen) { + payload = new unsigned char[paylen]; + memset(payload,'A',paylen); + } + + switch (hcmn->ptype_) { + case PT_ACK: + sflgs = TH_ACK; + case PT_TCP: + packetlen += LIBNET_TCP_H; + allocdata(packetlen); + pdat = accessdata(); + memset(pdat,0,packetlen); + libnet_build_ip(packetlen-LIBNET_IP_H,IPTOS_LOWDELAY,ipseq_, + 0,hip->ttl_,IPPROTO_TCP,srcip_,destip_,NULL, + 0,pdat); + sflgs |= htcp->tcp_flags_; + libnet_build_tcp(srcport_,destport_,htcp->seqno_,htcp->ackno_, + sflgs,0,0,(unsigned char*)payload, + paylen,pdat+LIBNET_IP_H); + libnet_do_checksum(pdat,IPPROTO_TCP,packetlen); + libnet_do_checksum(pdat,IPPROTO_IP,LIBNET_IP_H); + result = true; + break; + + case PT_CBR: + packetlen += LIBNET_UDP_H; + allocdata(packetlen); + pdat = accessdata(); + memset(pdat,0,packetlen); + libnet_build_ip(packetlen-LIBNET_IP_H,IPTOS_LOWDELAY,ipseq_, + 0,hip->ttl_,IPPROTO_UDP,srcip_,destip_,NULL, + 0,pdat); + libnet_build_udp(srcport_,destport_,(unsigned char*)payload, + paylen,pdat+LIBNET_IP_H); + libnet_do_checksum(pdat,IPPROTO_UDP,packetlen); + libnet_do_checksum(pdat,IPPROTO_IP,LIBNET_IP_H); + result = true; + break; + default: + result = false; + break; + } + + + if (result) { + hcmn->direction() = hdr_cmn::DOWN; + hcmn->iface() = ExtRouter::IFID_KERNELTAP; + hraw->subtype = hdr_raw::IP; + hcmn->ptype() = PT_RAW; + hcmn->size() = packetlen; + ipseq_++; + } + + if (payload) { + delete[] payload; + payload = 0; + } + return result; +} + +bool +Packet::fromraw() { + struct hdr_tcp* htcp = HDR_TCP(this); + struct hdr_ip* hip = HDR_IP(this); + struct hdr_cmn* hcmn = HDR_CMN(this); + struct hdr_flags* hflg = hdr_flags::access(this); + struct libnet_ip_hdr* ip = 0; + struct libnet_tcp_hdr* tcp = 0; + struct libnet_udp_hdr* udp = 0; + unsigned char* pdat = 0; + bool result = false; + + if (PT_RAW != hcmn->ptype()) return false; + + pdat = accessdata(); + ip = (struct libnet_ip_hdr*)pdat; + + switch (ip->ip_p) { + case IPPROTO_TCP: + tcp = (struct libnet_tcp_hdr*)(pdat+LIBNET_IP_H); + htcp->seqno_ = ntohl(tcp->th_seq); + htcp->ackno_ = ntohl(tcp->th_ack); + htcp->tcp_flags_ = tcp->th_flags; + htcp->hlen_ = LIBNET_IP_H + LIBNET_TCP_H; + hcmn->ptype_ = (tcp->th_flags & TH_ACK) ? PT_ACK : PT_TCP; + result = true; + break; + case IPPROTO_UDP: + hcmn->ptype_ = PT_CBR; + result = true; + break; + default: + result = false; + break; + } + + return result; +} +#endif --- ns-2.26.orig/common/packet.h 2003-02-26 15:07:40.000000000 -0700 +++ ns-2.26.nsclickcvs/common/packet.h 2003-04-10 10:54:08.000000000 -0600 @@ -31,7 +31,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#) $Header: /nfs/jade/vint/CVSROOT/ns-2/common/packet.h,v 1.93 2003/02/02 22:33:53 xuanc Exp $ (LBL) + * @(#) $Header: /srl/dirkcvs/nsclick/ns/common/packet.h,v 1.6 2003/04/10 16:51:34 neufeldm Exp $ (LBL) */ #ifndef ns_packet_h @@ -153,6 +153,9 @@ PT_LMS, PT_LMS_SETUP, + // nsclick RAW packet + PT_RAW, + // insert new packet types here PT_NTYPE // This MUST be the LAST one }; @@ -237,6 +240,9 @@ name_[PT_LMS]="LMS"; name_[PT_LMS_SETUP]="LMS_SETUP"; + // Raw packets + name_[PT_RAW] = "raw"; + name_[PT_NTYPE]= "undefined"; } const char* name(packet_t p) const { @@ -374,6 +380,12 @@ u_int8_t incoming; //monarch extns end; + +#if 0 + bool toraw(); + bool fromraw(); +#endif + }; /* @@ -501,6 +513,7 @@ inline void Packet::init(Packet* p) { bzero(p->bits_, hdrlen_); + p->txinfo_.clear(); } inline Packet* Packet::alloc() --- ns-2.26.orig/common/rawpacket.cc 1969-12-31 17:00:00.000000000 -0700 +++ ns-2.26.nsclickcvs/common/rawpacket.cc 2003-03-17 23:29:46.000000000 -0700 @@ -0,0 +1,173 @@ +/* + * rawpacket.cc + * Main file for the raw packet type + * + * $Header: /srl/dirkcvs/nsclick/ns/common/rawpacket.cc,v 1.2 2003/03/18 06:29:46 neufeldm Exp $ + * + */ + +/***************************************************************************** + * Copyright 2002, Univerity of Colorado at Boulder. * + * * + * All Rights Reserved * + * * + * Permission to use, copy, modify, and distribute this software and its * + * documentation for any purpose other than its incorporation into a * + * commercial product is hereby granted without fee, provided that the * + * above copyright notice appear in all copies and that both that * + * copyright notice and this permission notice appear in supporting * + * documentation, and that the name of the University not be used in * + * advertising or publicity pertaining to distribution of the software * + * without specific, written prior permission. * + * * + * UNIVERSITY OF COLORADO DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS * + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND * + * FITNESS FOR ANY PARTICULAR PURPOSE. IN NO EVENT SHALL THE UNIVERSITY * + * OF COLORADO BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL * + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA * + * OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * + * PERFORMANCE OF THIS SOFTWARE. * + * * + ****************************************************************************/ + +#include +#include "agent.h" +#include "packet.h" +#include "rawpacket.h" +#include "extrouter.h" +extern "C" { +#include +} +int hdr_raw::offset_; + +/* + * RawHeaderClass based on the ping example in the ns-2 tutorial. + */ +static class RawHeaderClass : public PacketHeaderClass { +public: + RawHeaderClass() : PacketHeaderClass("PacketHeader/Raw",sizeof(hdr_raw)){ + bind_offset(&hdr_raw::offset_); + } +} class_rawhdr; + +static class RawClass : public TclClass { +public: + RawClass() : TclClass("Agent/Raw") {} + TclObject* create(int,const char*const*) { + return (new RawAgent()); + } +} class_raw; + + +RawAgent::RawAgent() : Agent(PT_RAW) { + ipseq_ = 0; +} + +int RawAgent::command(int argc,const char*const* argv) { + if (argc == 2) { + if (strcmp(argv[1], "send") == 0) { + char* testmsg = "Howdy Howdy Howdy\n"; + send_udp_str(srcip_,srcport_,destip_,destport_,testmsg); + return (TCL_OK); + } + } + else if (argc == 3) { + if (strcmp(argv[1], "send") == 0) { + const char* testmsg = argv[2]; + send_udp_str(srcip_,srcport_,destip_,destport_,testmsg); + return (TCL_OK); + } + if (strcmp(argv[1], "set-srcip") == 0) { + srcip_ = libnet_name_resolve((unsigned char*)argv[2],0); + return (TCL_OK); + } + if (strcmp(argv[1], "set-srcport") == 0) { + srcport_ = atoi(argv[2]); + return (TCL_OK); + } + if (strcmp(argv[1], "set-destip") == 0) { + destip_ = libnet_name_resolve((unsigned char*)argv[2],0); + return (TCL_OK); + } + if (strcmp(argv[1], "set-destport") == 0) { + destport_ = atoi(argv[2]); + return (TCL_OK); + } + } + else if (argc == 7) { + if (strcmp(argv[1],"send-udp") == 0) { + // saddr,sport,daddr,dport,payload + // For right now only text strings can be sent + // as payload. + u_long saddr = libnet_name_resolve((unsigned char*)argv[2],0); + u_short sport = atoi(argv[3]); + u_long daddr = libnet_name_resolve((unsigned char*)argv[4],0); + u_short dport = atoi(argv[5]); + send_udp_str(saddr,sport,daddr,dport,argv[6]); + // return TCL_OK, so the calling function knows that the + // command has been processed + return (TCL_OK); + } + } + + // If the command hasn't been processed by RawAgent()::command, + // call the command() function for the base class + return (Agent::command(argc, argv)); +} + +void +RawAgent::sendmsg(int nbytes, const char *flags) { + // Make a string full of 'A's and use it for the payload + char* stuff = new char[nbytes]; + memset(stuff,'A',nbytes); + send_udp(srcip_,srcport_,destip_,destport_,stuff,nbytes); + delete[] stuff; + stuff = 0; +} + +void +RawAgent::send_udp_str(u_long saddr,u_short sport,u_long daddr,u_short dport, + const char* payload) { + send_udp(saddr,sport,daddr,dport,payload,strlen(payload)); +} + +void +RawAgent::send_udp(u_long saddr,u_short sport,u_long daddr,u_short dport, + const char* payload,int paylen) { + int packetlen = paylen + LIBNET_IP_H + LIBNET_UDP_H; + Packet* pkt = allocpkt(packetlen); + hdr_cmn* hcmn = HDR_CMN(pkt); + hcmn->direction() = hdr_cmn::DOWN; + hcmn->iface() = ExtRouter::IFID_KERNELTAP; + hcmn->ptype() = PT_RAW; + hcmn->size() = packetlen; + // Access the raw header for the new packet: + hdr_raw* hdr = hdr_raw::access(pkt); + hdr->subtype = hdr_raw::IP; + hdr->ns_type = PT_RAW; + unsigned char* pdat = pkt->accessdata(); + memset(pdat,0,packetlen); + libnet_build_ip(packetlen-LIBNET_IP_H,IPTOS_LOWDELAY,ipseq_,0,255, + IPPROTO_UDP,saddr,daddr,NULL,0,pdat); + libnet_build_udp(sport,dport,(unsigned char*)payload,paylen,pdat+LIBNET_IP_H); + libnet_do_checksum(pdat,IPPROTO_UDP,LIBNET_UDP_H+paylen); + libnet_do_checksum(pdat,IPPROTO_IP,LIBNET_IP_H); + // Send the packet + send(pkt, 0); + ipseq_++; +} + +void RawAgent::recv(Packet* pkt, Handler*) +{ + // Access the raw header for the received packet + hdr_raw* hdr = hdr_raw::access(pkt); + + if (hdr_raw::PSTRING == hdr->subtype) { + unsigned char* pdat = pkt->accessdata(); + unsigned int len = pdat[0]; + + // Shovel the string to the screen... + fwrite(pdat+1,sizeof(char),len,stdout); + } +} --- ns-2.26.orig/common/rawpacket.h 1969-12-31 17:00:00.000000000 -0700 +++ ns-2.26.nsclickcvs/common/rawpacket.h 2003-01-29 08:44:13.000000000 -0700 @@ -0,0 +1,92 @@ +/* + * rawpacket.h + * + * $Header: /srl/dirkcvs/nsclick/ns/common/rawpacket.h,v 1.2 2003/01/29 15:44:13 neufeldm Exp $ + * + */ + +/***************************************************************************** + * Copyright 2002, Univerity of Colorado at Boulder. * + * * + * All Rights Reserved * + * * + * Permission to use, copy, modify, and distribute this software and its * + * documentation for any purpose other than its incorporation into a * + * commercial product is hereby granted without fee, provided that the * + * above copyright notice appear in all copies and that both that * + * copyright notice and this permission notice appear in supporting * + * documentation, and that the name of the University not be used in * + * advertising or publicity pertaining to distribution of the software * + * without specific, written prior permission. * + * * + * UNIVERSITY OF COLORADO DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS * + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND * + * FITNESS FOR ANY PARTICULAR PURPOSE. IN NO EVENT SHALL THE UNIVERSITY * + * OF COLORADO BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL * + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA * + * OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * + * PERFORMANCE OF THIS SOFTWARE. * + * * + ****************************************************************************/ + +/* + * Raw packet type. + */ +struct hdr_raw { + /* + * This indicates the actual type of the stuff in the + * packet. The actual packet stuff is pointed to by + * the data thing. + */ + int subtype; + + /* + * Not many raw subtypes defined so far. + */ + enum { + NONE, + PSTRING, + IP, + ETHERNET, + }; + + /* + * This is the equivalent packet type in ns-2. Sometimes we + * want to maintain the raw packet data _and_ the ns-2 headers + * for that particular type in parallel, e.g. so we can use + * the existing ns-2 trace printing routines. However, we + * still want to keep the packet type as PT_RAW, so we store + * the ns-2 type in this field. + */ + int ns_type; + + /* Packet header access functions */ + static int offset_; + inline static int& offset() { return offset_; } + inline static hdr_raw* access(const Packet* p) { + return (hdr_raw*) p->access(offset_); + } +}; + +/* + * The base RawAgent class + */ +class RawAgent : public Agent { + public: + RawAgent(); + int command(int argc,const char*const* argv); + void recv(Packet*, Handler*); + virtual void sendmsg(int nbytes, const char *flags = 0); + protected: + void send_udp_str(u_long saddr,u_short sport,u_long daddr,u_short dport, + const char* payload); + void send_udp(u_long saddr,u_short sport,u_long daddr,u_short dport, + const char* payload,int paylen); + + u_int16_t ipseq_; + u_long srcip_; + u_short srcport_; + u_long destip_; + u_short destport_; +}; --- ns-2.26.orig/conf/configure.in.click 1969-12-31 17:00:00.000000000 -0700 +++ ns-2.26.nsclickcvs/conf/configure.in.click 2003-03-22 20:50:11.000000000 -0700 @@ -0,0 +1,31 @@ +dnl autoconf rules to find click - copied from dmalloc example +dnl $Header: /srl/dirkcvs/nsclick/ns/conf/configure.in.click,v 1.2 2003/03/23 03:50:11 neufeldm Exp $ + +AC_ARG_WITH(click, --with-click=path specify a pathname for the click modular router, d="$withval", d="") + +CLICK_VERS=1.3 + +CLICK_PATH="$PWD/../click \ + $PWD/../../click \ + $PWD/../click-$CLICK_VERS \ + $PWD/../../click-$CLICK_VERS \ + $PWD/../click/include/click \ + $PWD/../../click/include/click \ + $PWD/../click-$CLICK_VERS/include/click \ + $PWD/../../click-$CLICK_VERS/include/click \ + $PWD/../click/ns \ + $PWD/../../click/ns \ + $PWD/../click-$CLICK_VERS/ns \ + $PWD/../../click-$CLICK_VERS/ns \ + " +CLICK_PATH_D="$d \ + $d/ns \ + $d/include/click \ + " + +NS_BEGIN_PACKAGE(click) +NS_CHECK_HEADER_PATH(simclick.h,$CLICK_PATH,$d,$CLICK_PATH_D,V_HEADER_CLICK,click) +NS_CHECK_LIB_PATH(nsclick,$CLICK_PATH,$d,$CLICK_PATH_D,V_LIB_CLICK,click) +NS_END_PACKAGE(click,yes) + + --- ns-2.26.orig/conf/configure.in.libnet 1969-12-31 17:00:00.000000000 -0700 +++ ns-2.26.nsclickcvs/conf/configure.in.libnet 2002-06-12 19:33:48.000000000 -0600 @@ -0,0 +1,33 @@ +dnl autoconf rules to find libnet - copied from dmalloc example +dnl $Header: /srl/dirkcvs/nsclick/ns/conf/configure.in.libnet,v 1.1 2002/06/13 01:33:48 neufeldm Exp $ + +AC_ARG_WITH(libnet, --with-libnet=path specify a pathname for libnet, d="$withval", d="") + +LIBNET_VERS=1.0.2a + +LIBNET_PATH="$PWD/../libnet \ + $PWD/../../libnet \ + $PWD/../Libnet-$LIBNET_VERS \ + $PWD/../../Libnet-$LIBNET_VERS \ + $PWD/../libnet/include \ + $PWD/../../libnet/include \ + $PWD/../Libnet-$LIBNET_VERS/include \ + $PWD/../../Libnet-$LIBNET_VERS/include \ + $PWD/../libnet/lib \ + $PWD/../../libnet/lib \ + $PWD/../Libnet-$LIBNET_VERS/lib \ + $PWD/../../Libnet-$LIBNET_VERS/lib \ + " +LIBNET_PATH_D="$d \ + $d/include \ + $d/lib \ + " + +NS_BEGIN_PACKAGE(libnet) +NS_CHECK_HEADER_PATH(libnet.h,$LIBNET_PATH,$d,$LIBNET_PATH_D,V_HEADER_LIBNET,libnet) +NS_CHECK_LIB_PATH(net,$LIBNET_PATH,$d,$LIBNET_PATH_D,V_LIB_LIBNET,libnet) +NS_CHECK_ANY_PATH(libnet-config,$LIBNET_PATH,$d,$LIBNET_PATH_D,LIBNETCONFIG,libnet) +V_DEFINES="`$LIBNETCONFIG/libnet-config --defines` $V_DEFINES" +NS_END_PACKAGE(libnet,yes) + + --- ns-2.26.orig/mac/channel.cc 2003-02-26 15:08:55.000000000 -0700 +++ ns-2.26.nsclickcvs/mac/channel.cc 2003-04-21 22:22:56.000000000 -0600 @@ -37,7 +37,7 @@ #ifndef lint static const char rcsid[] = - "@(#) $Header: /nfs/jade/vint/CVSROOT/ns-2/mac/channel.cc,v 1.39 2002/07/03 20:45:22 yuri Exp $ (UCB)"; + "@(#) $Header: /srl/dirkcvs/nsclick/ns/mac/channel.cc,v 1.2 2003/04/15 23:22:01 neufeldm Exp $ (UCB)"; #endif //#include "template.h" @@ -113,6 +113,12 @@ ((Phy*) obj)->setchnl(this); return TCL_OK; } + else if(strcmp(argv[1], "delif") == 0) { + // Remove phy from channel + ((Phy*) obj)->setchnl(0); + ((Phy*) obj)->removechnl(); + return TCL_OK; + } // add interface for grid_keeper_ /*else if(strncasecmp(argv[1], "grid_keeper", 5) == 0) { grid_keeper_ = (GridKeeper*)obj; --- ns-2.26.orig/mac/ll-ext.cc 1969-12-31 17:00:00.000000000 -0700 +++ ns-2.26.nsclickcvs/mac/ll-ext.cc 2003-04-30 16:27:20.000000000 -0600 @@ -0,0 +1,175 @@ +/* + * ll-ext.cc + * This is a special link layer which explicitly notifies the attached + * queue when it becomes free. + * + * $Header: /srl/dirkcvs/nsclick/ns/mac/ll-ext.cc,v 1.4 2003/04/27 06:55:22 neufeldm Exp $ + */ + +/***************************************************************************** + * Copyright 2002, Univerity of Colorado at Boulder. * + * * + * All Rights Reserved * + * * + * Permission to use, copy, modify, and distribute this software and its * + * documentation for any purpose other than its incorporation into a * + * commercial product is hereby granted without fee, provided that the * + * above copyright notice appear in all copies and that both that * + * copyright notice and this permission notice appear in supporting * + * documentation, and that the name of the University not be used in * + * advertising or publicity pertaining to distribution of the software * + * without specific, written prior permission. * + * * + * UNIVERSITY OF COLORADO DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS * + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND * + * FITNESS FOR ANY PARTICULAR PURPOSE. IN NO EVENT SHALL THE UNIVERSITY * + * OF COLORADO BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL * + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA * + * OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * + * PERFORMANCE OF THIS SOFTWARE. * + * * + ****************************************************************************/ + +// XXX This is really a click link layer now - not just ext... + +#include "config.h" +#include +#include +#include +#include +//#include +//#include +#include +#include +#include +#include "packet.h" +#include "ip.h" +#include "mac.h" +#include "classifier.h" +//#include "classifier-hash.h" +#include "scheduler.h" +#include "ll.h" +#include +#include "ll-ext.h" +#include "packet.h" +#include "extrouter.h" +#include "classifier.h" +#include "classifier-ext.h" +#include "classifier-click.h" +#include "clickqueue.h" + +static class LLExtClass : public TclClass { +public: + LLExtClass() : TclClass("LL/Ext") {} + TclObject* create(int, const char*const*) { + return (new LLExt()); + } +} class_ll_ext; + +void +LLExtEventHandler::handle(Event* event) { + // XXX dangerous downcast - should use RTTI + LLExtEvent* myevent = (LLExtEvent*) event; + myevent->llext->setpending(0); + delete myevent; +} + + +LLExt::LLExt() { + extid_ = -1; + macDA_ = -1; + packetpending_ = 0; +} + +LLExt::~LLExt() { +} + +int LLExt::command(int argc, const char*const* argv) { + Tcl& tcl = Tcl::instance(); + if(argc == 2) { + } + else if (argc == 3) { + if (strcmp("setid",argv[1]) == 0) { + extid_ = atoi(argv[2]); + return TCL_OK; + } + else if (strcmp("setpromiscuous",argv[1]) == 0) { + bool promisc = (atoi(argv[2]) != 0); + setpromiscuous(promisc); + return TCL_OK; + } + } + else if (argc == 4) { + } + + return LL::command(argc,argv); +} + +void LLExt::recv(Packet* p, Handler* h) { + /* + * Tag the packet and then defer to standard link layer handling. + */ + struct hdr_cmn* hdr = HDR_CMN(p); + hdr->iface() = extid_; + // printf("ll = %d, ifid = %d\n",(int)this,hdr->iface()); + LL::recv(p,h); +} + +void LLExt::sendDown(Packet* p) { + // Someone decided that it would be A Good Thing to overlay + // the 802.11 MAC packet info on top of the regular MAC packet info. + // We need to fix the source and destination addresses here by accessing the + // MAC object itself. + struct hdr_mac* mhdr = HDR_MAC(p); + int macdst = mhdr->macDA(); + int macsrc = mhdr->macSA(); + memset(mhdr,0,sizeof(struct hdr_mac)); + mac_->hdr_dst((char*)mhdr,macdst); + mac_->hdr_src((char*)mhdr,macsrc); + + // Bleah. Send the packet down, mark ourself as being busy, and then + // schedule an event to mark ourselves unbusy. + packetpending_ = 1; + LL::sendDown(p); + LLExtEvent* llev = new LLExtEvent(); + llev->llext = this; + Scheduler& s = Scheduler::instance(); + s.schedule(&evhandle_,llev,delay_); +} + +int LLExt::ready() { + ClickQueue* pcq = (ClickQueue*) ifq_; + if (pcq) { + return (!packetpending_ && pcq->ready()); + } + + // No ClickQueue? Then we're always ready. + return 1; +} + +void +LLExt::setpromiscuous(bool promisc) { + if (!mac_) { + return; + } + + if (promisc) { + mac_->installTap(this,true); + } + else { + mac_->installTap(0,true); + } +} + +void +LLExt::tap(const Packet *packet) + /* process packets that are promiscously listened to from the MAC layer tap + *** do not change or free packet *** */ +{ + // XXX send a copy of packets received here up to the next layer. + // This code assumes that the tap is being used with the "filterown" + // option set, otherwise duplicate packets will get sent up the pipe. + Packet* newp = packet->copy(); + recv(newp,0); +} --- ns-2.26.orig/mac/ll-ext.h 1969-12-31 17:00:00.000000000 -0700 +++ ns-2.26.nsclickcvs/mac/ll-ext.h 2003-04-30 16:27:20.000000000 -0600 @@ -0,0 +1,80 @@ +/* + * ll-ext.h + * + * Much like the multicast routing system, ext routers needs to know what + * interface packets come in from. However, the multicast interface + * thing doesn't quite do what we need it to, so you get what + * we've got here. + * + * $Header: /srl/dirkcvs/nsclick/ns/mac/ll-ext.h,v 1.2 2003/04/27 06:55:22 neufeldm Exp $ + */ + +/***************************************************************************** + * Copyright 2002, Univerity of Colorado at Boulder. * + * * + * All Rights Reserved * + * * + * Permission to use, copy, modify, and distribute this software and its * + * documentation for any purpose other than its incorporation into a * + * commercial product is hereby granted without fee, provided that the * + * above copyright notice appear in all copies and that both that * + * copyright notice and this permission notice appear in supporting * + * documentation, and that the name of the University not be used in * + * advertising or publicity pertaining to distribution of the software * + * without specific, written prior permission. * + * * + * UNIVERSITY OF COLORADO DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS * + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND * + * FITNESS FOR ANY PARTICULAR PURPOSE. IN NO EVENT SHALL THE UNIVERSITY * + * OF COLORADO BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL * + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA * + * OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * + * PERFORMANCE OF THIS SOFTWARE. * + * * + ****************************************************************************/ + +#ifndef ns_ll_ext_h +#define ns_ll_ext_h + +#include "object.h" + +class Packet; +class LLExt; + +class LLExtEvent : public Event { + public: + LLExt* llext; +}; + +class LLExtEventHandler : public Handler { + public: + virtual void handle(Event* event); +}; + +class LLExt : public LL, public Tap { + public: + LLExt(); + virtual ~LLExt(); + + virtual void recv(Packet* p, Handler* h); + virtual void sendDown(Packet* p); + + // Allow us to do promiscuous mode by acting as a tap. + void tap(const Packet *p); + + void setExtID(int newid) {extid_ = newid;} + int getExtID() {return extid_;} + int ready(); + int getpending() { return packetpending_; } + void setpending(int newpend) { packetpending_ = newpend; }; + void setpromiscuous(bool promisc); + + protected: + virtual int command(int argc, const char*const* argv); + int extid_; + int packetpending_; + LLExtEventHandler evhandle_; +}; + +#endif --- ns-2.26.orig/mac/ll.cc 2003-02-26 15:08:56.000000000 -0700 +++ ns-2.26.nsclickcvs/mac/ll.cc 2002-09-06 21:19:28.000000000 -0600 @@ -36,7 +36,7 @@ #ifndef lint static const char rcsid[] = - "@(#) $Header: /nfs/jade/vint/CVSROOT/ns-2/mac/ll.cc,v 1.46 2002/03/14 01:12:52 haldar Exp $ (UCB)"; + "@(#) $Header: /srl/dirkcvs/nsclick/ns/mac/ll.cc,v 1.2 2002/09/07 03:19:28 neufeldm Exp $ (UCB)"; #endif #include @@ -203,6 +203,9 @@ tx = arptable_->arpresolve(dst, p, this); break; } + if (PT_RAW == ch->ptype()) { + break; + } //if (varp_) { //tx = varp_->arpresolve(dst, p); //break; --- ns-2.26.orig/mac/mac-802_11.cc 2003-02-26 15:08:56.000000000 -0700 +++ ns-2.26.nsclickcvs/mac/mac-802_11.cc 2003-04-30 16:27:20.000000000 -0600 @@ -31,7 +31,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Header: /nfs/jade/vint/CVSROOT/ns-2/mac/mac-802_11.cc,v 1.41 2003/02/21 00:40:22 haldar Exp $ + * $Header: /srl/dirkcvs/nsclick/ns/mac/mac-802_11.cc,v 1.3 2003/04/28 06:13:49 neufeldm Exp $ * * Ported from CMU/Monarch's code, nov'98 -Padma. */ @@ -1202,8 +1202,12 @@ /* tap out - */ if (tap_ && type == MAC_Type_Data && - MAC_Subtype_Data == subtype ) - tap_->tap(pktRx_); + MAC_Subtype_Data == subtype ) { + if (!tap_filterown_ || + ((dst != (u_int32_t)index_) && (dst != MAC_BROADCAST))) { + tap_->tap(pktRx_); + } + } /* * Adaptive Fidelity Algorithm Support - neighborhood infomation * collection --- ns-2.26.orig/mac/mac.h 2003-02-26 15:08:56.000000000 -0700 +++ ns-2.26.nsclickcvs/mac/mac.h 2003-04-30 16:27:20.000000000 -0600 @@ -33,7 +33,7 @@ * * Contributed by Giao Nguyen, http://daedalus.cs.berkeley.edu/~gnguyen * - * @(#) $Header: /nfs/jade/vint/CVSROOT/ns-2/mac/mac.h,v 1.35 2000/12/20 10:11:36 alefiyah Exp $ (UCB) + * @(#) $Header: /srl/dirkcvs/nsclick/ns/mac/mac.h,v 1.2 2003/04/27 06:55:22 neufeldm Exp $ (UCB) */ #ifndef ns_mac_h @@ -176,7 +176,10 @@ virtual void sendUp(Packet *p); virtual void resume(Packet* p = 0); - virtual void installTap(Tap *t) { tap_ = t; } + virtual void installTap(Tap *t,bool filterown = false) { + tap_ = t; + tap_filterown_ = filterown; + } inline double txtime(int bytes) { return (8. * bytes / bandwidth_); @@ -230,6 +233,7 @@ Phy *netif_; // network interface Tap *tap_; // tap agent + bool tap_filterown_; // filter tap packets destined for use anyhow LL *ll_; // LL this MAC is connected to Channel *channel_; // channel this MAC is connected to --- ns-2.26.orig/mac/phy.cc 2003-02-26 15:08:56.000000000 -0700 +++ ns-2.26.nsclickcvs/mac/phy.cc 2003-04-21 22:22:56.000000000 -0600 @@ -68,6 +68,16 @@ tcl.resultf("%d", index_); return TCL_OK; } + + if (strcmp(argv[1],"getchannel") == 0) { + if (channel_) { + tcl.resultf("%s",channel_->name()); + } + else { + tcl.resultf("%s",""); + } + return TCL_OK; + } } else if(argc == 3) { --- ns-2.26.orig/mac/wireless-phy.cc 2003-02-26 15:08:57.000000000 -0700 +++ ns-2.26.nsclickcvs/mac/wireless-phy.cc 2003-04-10 10:54:08.000000000 -0600 @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Header: /nfs/jade/vint/CVSROOT/ns-2/mac/wireless-phy.cc,v 1.19 2002/12/11 01:22:52 difa Exp $ + * $Header: /srl/dirkcvs/nsclick/ns/mac/wireless-phy.cc,v 1.3 2003/04/10 16:52:36 neufeldm Exp $ * * Ported from CMU/Monarch's code, nov'98 -Padma Haldar. * wireless-phy.cc @@ -130,6 +130,7 @@ WirelessPhy::command(int argc, const char*const* argv) { TclObject *obj; + Tcl& tcl = Tcl::instance(); if (argc==2) { if (strcasecmp(argv[1], "NodeOn") == 0) { @@ -148,7 +149,11 @@ update_energy_time_ = NOW; } return TCL_OK; + } else if (strcasecmp(argv[1], "getantenna") == 0) { + tcl.result(ant_->name()); + return TCL_OK; } + } else if(argc == 3) { if (strcasecmp(argv[1], "setTxPower") == 0) { Pt_consume_ = atof(argv[2]); --- ns-2.26.orig/mobile/pattern-antenna.cc 1969-12-31 17:00:00.000000000 -0700 +++ ns-2.26.nsclickcvs/mobile/pattern-antenna.cc 2003-04-26 22:59:55.000000000 -0600 @@ -0,0 +1,238 @@ + +/* + * Copyright (c) 2003 University of Colorado, Boulder + * All rights reserved. + * + */ + +#include +#include +#include +#include +#include +#include + +static class PatternAntennaClass : public TclClass { +public: + PatternAntennaClass() : TclClass("Antenna/PatternAntenna") {} + TclObject* create(int, const char*const*) { + return (new PatternAntenna); + } +} class_PatternAntenna; + +PatternAntenna::PatternAntenna() { + Dir_ = 0.0; + bind("Dir_", &Dir_); +} + +double +PatternAntenna::normalize(double deg) { + while (360.0 <= deg) { + deg -= 360.0; + } + + while (0.0 > deg) { + deg += 360.0; + } + + return deg; +} + +double +PatternAntenna::get_angle(double dX, double dY) { + double angle; + + // First take care of dX or both == 0 + if ((0.0 == dY) && (0.0 == dX)) { + angle = 0.0; + } + else if (0.0 == dX) { + angle = M_PI/2.0; + } + else { + angle = atan2(dY,dX); + if (0.0 > angle) { + angle += 2*M_PI; + } + } + + angle = (180.0/M_PI) * angle; + + return angle; +} + +PatternAntenna::gain_pattern::gain_pattern() { + samplecount_ = 0; + samples_ = 0; +} + +PatternAntenna::gain_pattern::~gain_pattern() { + if (samples_) { + free(samples_); + samples_ = 0; + } +} + +void +PatternAntenna::gain_pattern::set_gain_pattern(int samplecount,double* samples) +{ + if (samples_) { + free(samples_); + samples_ = 0; + samplecount = 0; + } + samples_ = (double*)malloc(samplecount*sizeof(double)); + samplecount_ = samplecount; + sample_quantum_ = 360.0/samplecount_; + memcpy(samples_,samples,samplecount*sizeof(double)); +} + +double +PatternAntenna::gain_pattern::get_gain(double angle) { + // Find closest sample to angle. + // XXX Maybe interpolate between samples at some point? + int whichsamp = ( (int)((angle/sample_quantum_) + 0.5) ) % samplecount_; + return samples_[whichsamp]; +} + +void +PatternAntenna::gain_pattern::copy_pattern(gain_pattern& pat) { + set_gain_pattern(pat.samplecount_,pat.samples_); +} + +// return the gain for a signal to a node at vector dX, dY, dZ +// from the transmitter at wavelength lambda +double +PatternAntenna::getTxGain(double dX, double dY, double dZ, double l) { + double angle = get_angle(dX,dY); + return horiz_tx_gain_.get_gain(angle); +} + +// return the gain for a signal from a node at vector dX, dY, dZ +// from the receiver at wavelength lambda +double +PatternAntenna::getRxGain(double dX, double dY, double dZ, double l) { + double angle = get_angle(dX,dY); + return horiz_rx_gain_.get_gain(angle); +} + +void +PatternAntenna::setHorizRxGainPattern(int samplecount, double* samples) { + horiz_rx_gain_.set_gain_pattern(samplecount,samples); +} + + +void +PatternAntenna::setHorizTxGainPattern(int samplecount, double* samples) { + horiz_tx_gain_.set_gain_pattern(samplecount,samples); +} + + +// return a pointer to a copy of this antenna that will return the +// same thing for get{Rx,Tx}Gain that this one would at this point +// in time. This is needed b/c if a pkt is sent with a directable +// antenna, this antenna may be have been redirected by the time we +// call getTxGain on the copy to determine if the pkt is received. +Antenna* +PatternAntenna::copy() { + PatternAntenna* antcopy = + (PatternAntenna*)TclObject::New("Antenna/PatternAntenna"); + antcopy->horiz_rx_gain_.copy_pattern(horiz_rx_gain_); + antcopy->horiz_tx_gain_.copy_pattern(horiz_tx_gain_); + return antcopy; +} + +void +PatternAntenna::release() { + TclObject::Delete((TclObject*)this); +} + +int +PatternAntenna::read_pattern_from_msi(const char* msifile) { + // XXX This code is by no means great. It is simplistic + // and fragile, but I think it'll work well enough for the + // simplistic kinds of tasks we'll give it. + double gain; + double* hpoints = 0; + int hpointcount = 0; + string units; + string nxttok; + int i = 0; + int result = 0; + int finalresult = 0; + ifstream msistrm(msifile); + // MSI uses 0 deg as due north, we have 0 deg as due east (and 90 as N). + // Add 90 deg to MSI numbers to fix this. + int hoffset = 90; + // MSI can use either dBd or dBi. I believe that ns-2 uses dBi. + // We'll set this appropriately when we get the units. + double gainoffset = 0.0; + + if (!msistrm) { + return -1; + } + + while (!msistrm.eof()) { + msistrm >> nxttok; + + if (msistrm.eof()) { + continue; + } + else if ("GAIN" == nxttok) { + msistrm >> gain; + msistrm >> units; + //cout << "GAIN " << gain << " " << units << endl; + gainoffset = 0.0; + if ("dBd" == units) { + gainoffset = 2.15; + } + } + else if ("HORIZONTAL" == nxttok) { + msistrm >> hpointcount; + //cout << "Horizontal pointcount: " << hpointcount << endl; + hpoints = (double*) malloc(hpointcount*sizeof(double)); + for (i=0;i> index; + msistrm >> curpoint; + //cout << "POINTS: " << index << " " << curpoint << endl; + int hindx = (i + hoffset) % 360; + if (0 > hindx) hindx += 360; + hpoints[hindx] = gain - curpoint + gainoffset; + } + } + } + + if (hpoints) { + if (hpointcount) { + // Assume same gain for Tx and Rx + setHorizRxGainPattern(hpointcount,hpoints); + setHorizTxGainPattern(hpointcount,hpoints); + } + free(hpoints); + hpoints = 0; + hpointcount = 0; + } + return finalresult; +} + +int +PatternAntenna::command(int argc, const char*const* argv) +{ + Tcl& tcl = Tcl::instance(); + if (2 == argc) { + } + else if (3 == argc) { + if(strcmp(argv[1], "loadmsi") == 0) { + int result = read_pattern_from_msi(argv[2]); + tcl.resultf("%d",result); + return TCL_OK; + } + } + else if (4 == argc) { + } else if (argc == 5) { + } + + return Antenna::command(argc, argv); +} --- ns-2.26.orig/mobile/pattern-antenna.h 1969-12-31 17:00:00.000000000 -0700 +++ ns-2.26.nsclickcvs/mobile/pattern-antenna.h 2003-04-26 22:21:40.000000000 -0600 @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2003 University of Colorado, Boulder + * All rights reserved. + * + */ + +#ifndef ns_patternantenna_h +#define ns_patternantenna_h + +#include + +class PatternAntenna : public Antenna { + +public: + PatternAntenna(); + virtual int command(int argc, const char*const* argv); + // return the gain for a signal to a node at vector dX, dY, dZ + // from the transmitter at wavelength lambda + virtual double getTxGain(double, double, double, double); + + // return the gain for a signal from a node at vector dX, dY, dZ + // from the receiver at wavelength lambda + virtual double getRxGain(double, double, double, double); + + // return a pointer to a copy of this antenna that will return the + // same thing for get{Rx,Tx}Gain that this one would at this point + // in time. This is needed b/c if a pkt is sent with a directable + // antenna, this antenna may be have been redirected by the time we + // call getTxGain on the copy to determine if the pkt is received. + virtual Antenna* copy(); + virtual void release(); + + void setDir(double newdir) { Dir_ = newdir; } + double getDir() { return Dir_; } + + void setHorizRxGainPattern(int samplecount, double* samples); + void setHorizTxGainPattern(int samplecount, double* samples); + + static double get_angle(double dX, double dY); + static double normalize(double deg); + + int read_pattern_from_msi(const char* msifile); + +protected: + double Dir_; + typedef class gain_pattern { + public: + gain_pattern(); + ~gain_pattern(); + void set_gain_pattern(int samplecount, double* samples); + double get_gain(double angle); + void copy_pattern(gain_pattern& pat); + + protected: + int samplecount_; + double* samples_; + double sample_quantum_; + }; + + gain_pattern horiz_tx_gain_; + gain_pattern horiz_rx_gain_; +}; + + +#endif // ns_uniantenna_h --- ns-2.26.orig/mobile/uni-antenna.cc 1969-12-31 17:00:00.000000000 -0700 +++ ns-2.26.nsclickcvs/mobile/uni-antenna.cc 2003-04-21 22:22:56.000000000 -0600 @@ -0,0 +1,198 @@ + +/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */ +/* + * Copyright (c) 1997 Regents of the University of California. + * 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 the Daedalus Research + * Group at the University of California Berkeley. + * 4. Neither the name of the University nor of the Laboratory may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + + * Ported from CMU/Monarch's code, nov'98 -Padma. + omni-antenna.cc + $Id: uni-antenna.cc,v 1.6 2003/04/16 05:43:36 neufeldm Exp $ + */ + +#include +#include +#include + +static class UniAntennaClass : public TclClass { +public: + UniAntennaClass() : TclClass("Antenna/UniAntenna") {} + TclObject* create(int, const char*const*) { + return (new UniAntenna); + } +} class_UniAntenna; + +UniAntenna::UniAntenna() : is_copy_(false) { + Gt_ = 1.0; + Gr_ = 1.0; + GtOmni_ = 0.0; + GrOmni_ = 0.0; + Dir_ = 0.0; + Width_ = 360.0; + bind("Gt_", &Gt_); + bind("Gr_", &Gr_); + bind("GtOmni_", &GtOmni_); + bind("GrOmni_", &GrOmni_); + bind("Dir_", &Dir_); + bind("Width_", &Width_); +} + +double +UniAntenna::normalize(double deg) { + while (360.0 <= deg) { + deg -= 360.0; + } + + while (0.0 > deg) { + deg += 360.0; + } + + return deg; +} + +double +UniAntenna::get_angle(double dX, double dY) { + double angle; + + // First take care of dX or both == 0 + if ((0.0 == dY) && (0.0 == dX)) { + angle = 0.0; + } + else if (0.0 == dX) { + angle = M_PI/2.0; + } + else { + angle = atan2(dY,dX); + if (0.0 > angle) { + angle += 2*M_PI; + } + } + + angle = (180.0/M_PI) * angle; + + return angle; +} + +void +UniAntenna::get_cone(double& lb, double& ub) { + lb = Dir_ - (Width_/2.0); + ub = Dir_ + (Width_/2.0); + lb = normalize(lb); + ub = normalize(ub); +} + +bool +UniAntenna::is_in_cone(double dX, double dY) { + bool result = false; + double angle = get_angle(dX,dY); + double lb, ub; + get_cone(lb,ub); + + // If lb and ub are swapped, we had a wraparound. In this + // case, the specified range is the inverse of the cone + // we want to check for. + if (lb > ub) { + result = ! ((ub <= angle) && (angle <= lb)); + } + else if (lb == ub) { + result = true; + } + else { + result = (lb <= angle) && (angle <= ub); + } + + return result; +} + +// return the gain for a signal to a node at vector dX, dY, dZ +// from the transmitter at wavelength lambda +double +UniAntenna::getTxGain(double dX, double dY, double dZ, double l) { + // XXX for now ignore dZ, just do 2 dimensions, and ignore lambda, too + double gain = Gt_; + + // XXX very stupid model. Gt_ gain within cone, GtOmni_ outside. + // Hopefully good enough for what we need initially... + if (is_in_cone(dX,dY)) { + gain = Gt_; + } + else { + gain = GtOmni_; + } + + return gain; +} + +// return the gain for a signal from a node at vector dX, dY, dZ +// from the receiver at wavelength lambda +double +UniAntenna::getRxGain(double dX, double dY, double dZ, double l) { + // XXX for now ignore dZ, just do 2 dimensions, and ignore lambda, too. + double gain = Gr_; + + // XXX very stupid model. Gr_ gain within cone, GrOmni_ outside. + // Hopefully good enough for what we need initially... + if (is_in_cone(dX,dY)) { + gain = Gr_; + } + else { + gain = GrOmni_; + } + + return gain; +} + +// return a pointer to a copy of this antenna that will return the +// same thing for get{Rx,Tx}Gain that this one would at this point +// in time. This is needed b/c if a pkt is sent with a directable +// antenna, this antenna may be have been redirected by the time we +// call getTxGain on the copy to determine if the pkt is received. +Antenna* +UniAntenna::copy() { + UniAntenna* antcopy = (UniAntenna*)TclObject::New("Antenna/UniAntenna"); + antcopy->X_ = X_; + antcopy->Y_ = Y_; + antcopy->Z_ = Z_; + antcopy->Gt_ = Gt_; + antcopy->Gr_ = Gr_; + antcopy->Dir_ = Dir_; + antcopy->Width_ = Width_; + antcopy->is_copy_ = true; + return antcopy; +} + +void +UniAntenna::release() { + if (is_copy_) { + TclObject::Delete((TclObject*)this); + } +} + + --- ns-2.26.orig/mobile/uni-antenna.h 1969-12-31 17:00:00.000000000 -0700 +++ ns-2.26.nsclickcvs/mobile/uni-antenna.h 2003-04-21 22:22:56.000000000 -0600 @@ -0,0 +1,82 @@ +/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */ +/* + * Copyright (c) 1997 Regents of the University of California. + * 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 the Computer Systems + * Engineering Group at Lawrence Berkeley Laboratory. + * 4. Neither the name of the University nor of the Laboratory may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +/* Ported from CMU/Monarch's code, nov'98 -Padma. + omni-antenna.h + omni-directional antenna + +*/ + +#ifndef ns_uniantenna_h +#define ns_uniantenna_h + +#include + +class UniAntenna : public Antenna { + +public: + UniAntenna(); + + // return the gain for a signal to a node at vector dX, dY, dZ + // from the transmitter at wavelength lambda + virtual double getTxGain(double, double, double, double); + + // return the gain for a signal from a node at vector dX, dY, dZ + // from the receiver at wavelength lambda + virtual double getRxGain(double, double, double, double); + + // return a pointer to a copy of this antenna that will return the + // same thing for get{Rx,Tx}Gain that this one would at this point + // in time. This is needed b/c if a pkt is sent with a directable + // antenna, this antenna may be have been redirected by the time we + // call getTxGain on the copy to determine if the pkt is received. + virtual Antenna* copy(); + virtual void release(); + + static double get_angle(double dX, double dY); + static double normalize(double deg); + bool is_in_cone(double dX, double dY); + void get_cone(double& lb,double& ub); + +protected: + double Gt_; // gain of transmitter (db) + double Gr_; // gain of receiver (db) + double GtOmni_; // Tx gain outside of cone + double GrOmni_; // Rx gain outside of cone + double Dir_; + double Width_; + bool is_copy_; +}; + + +#endif // ns_uniantenna_h --- ns-2.26.orig/queue/clickqueue.cc 1969-12-31 17:00:00.000000000 -0700 +++ ns-2.26.nsclickcvs/queue/clickqueue.cc 2003-04-10 10:54:09.000000000 -0600 @@ -0,0 +1,152 @@ +/* + * clickqueue.cc + * Special queue which runs the external Click router when it unblocks + * + */ + +/***************************************************************************** + * Copyright 2002, Univerity of Colorado at Boulder. * + * * + * All Rights Reserved * + * * + * Permission to use, copy, modify, and distribute this software and its * + * documentation for any purpose other than its incorporation into a * + * commercial product is hereby granted without fee, provided that the * + * above copyright notice appear in all copies and that both that * + * copyright notice and this permission notice appear in supporting * + * documentation, and that the name of the University not be used in * + * advertising or publicity pertaining to distribution of the software * + * without specific, written prior permission. * + * * + * UNIVERSITY OF COLORADO DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS * + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND * + * FITNESS FOR ANY PARTICULAR PURPOSE. IN NO EVENT SHALL THE UNIVERSITY * + * OF COLORADO BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL * + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA * + * OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * + * PERFORMANCE OF THIS SOFTWARE. * + * * + ****************************************************************************/ + +#ifndef lint +static const char rcsid[] = + "$Header: /srl/dirkcvs/nsclick/ns/queue/clickqueue.cc,v 1.2 2003/04/10 16:52:46 neufeldm Exp $"; +#endif + +#include +#include +#include +#include +//#include +//#include +#include +#include +#include +#include +#include "packet.h" +#include "extrouter.h" +#include "classifier.h" +#include "classifier-ext.h" +#include "classifier-click.h" +#include "clickqueue.h" + +static class ClickQueueClass : public TclClass { +public: + ClickQueueClass() : TclClass("Queue/ClickQueue") {} + TclObject* create(int, const char*const*) { + return (new ClickQueue); + } +} class_click_queue; + +int +ClickQueue::command(int argc, const char*const* argv) { + if (3 == argc) { + if (!strcmp(argv[1],"setclickclassifier")) { + cc_ = (ClickClassifier*)TclObject::lookup(argv[2]); + return TCL_OK; + } + } + return Queue::command(argc, argv); +} +/* + * drop-tail + */ +ClickQueue::ClickQueue() { + pq_ = new PacketQueue; + qlim_ = 1; + cc_ = 0; +} + +ClickQueue::~ClickQueue() { + delete pq_; +} + +int +ClickQueue::is_full() { + return (pq_->length() >= qlim_); +} + +int +ClickQueue::ready() { + return (!is_full() && !blocked()); +} + +void ClickQueue::enque(Packet* p) +{ + pq_->enque(p); + if (pq_->length() > qlim_) { + fprintf(stderr,"Hey!!! IFQ Overflow!!!\n"); + Packet *pp = pq_->deque(); + drop(pp); + } +} + +Packet* ClickQueue::deque() +{ + Packet* retval = pq_->deque(); + return retval; +} + +void ClickQueue::on_unblock() { + // + // Queue has space - run the external router + // and give it a chance to fill things up. + // + if (cc_) { + simclick_click clickinst = cc_->GetClickinst(); + Scheduler& s = Scheduler::instance(); + double dcurtime = s.clock(); + simclick_simstate curstate; + memset(&curstate,0,sizeof(curstate)); + double fracp, intp; + fracp = modf(dcurtime,&intp); + curstate.curtime.tv_sec = intp; + curstate.curtime.tv_usec = (fracp*1.0e6+0.5); + simclick_click_run(clickinst,&curstate); + } +} + +#if 0 +void ClickQueue::runclick() { + if (is_full()) { + return; + } + // + // Queue has space - run the external router + // and give it a chance to fill things up. + // + if (cc_) { + simclick_click clickinst = cc_->GetClickinst(); + Scheduler& s = Scheduler::instance(); + double dcurtime = s.clock(); + simclick_simstate curstate; + memset(&curstate,0,sizeof(curstate)); + double fracp, intp; + fracp = modf(dcurtime,&intp); + curstate.curtime.tv_sec = intp; + curstate.curtime.tv_usec = (fracp*1.0e6+0.5); + simclick_click_run(clickinst,&curstate); + } +} +#endif --- ns-2.26.orig/queue/clickqueue.h 1969-12-31 17:00:00.000000000 -0700 +++ ns-2.26.nsclickcvs/queue/clickqueue.h 2002-06-10 13:23:05.000000000 -0600 @@ -0,0 +1,61 @@ +/* + * clickqueue.h + * Special queue which runs the external Click router when it unblocks + * + */ + +/***************************************************************************** + * Copyright 2002, Univerity of Colorado at Boulder. * + * * + * All Rights Reserved * + * * + * Permission to use, copy, modify, and distribute this software and its * + * documentation for any purpose other than its incorporation into a * + * commercial product is hereby granted without fee, provided that the * + * above copyright notice appear in all copies and that both that * + * copyright notice and this permission notice appear in supporting * + * documentation, and that the name of the University not be used in * + * advertising or publicity pertaining to distribution of the software * + * without specific, written prior permission. * + * * + * UNIVERSITY OF COLORADO DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS * + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND * + * FITNESS FOR ANY PARTICULAR PURPOSE. IN NO EVENT SHALL THE UNIVERSITY * + * OF COLORADO BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL * + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA * + * OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * + * PERFORMANCE OF THIS SOFTWARE. * + * * + ****************************************************************************/ + +#ifndef ns_clickqueue_h +#define ns_clickqueue_h + +#include +#include "queue.h" +#include "config.h" + +/* + * A degenerate queue designed to work with Click routers. Should only + * have 1 packet ever sitting in it since the queueing should be handled + * by Click. Also makes sure that simclick gets run whenever the queue + * empties and unblocks so that the polling simulated network driver + * will insert packets when it has them. + */ +class ClickQueue : public Queue { + public: + ClickQueue(); + ~ClickQueue(); + void enque(Packet*); + Packet* deque(); + + int is_full(); + int ready(); + protected: + int command(int argc, const char*const* argv); + ClickClassifier* cc_; + virtual void on_unblock(); +}; + +#endif --- ns-2.26.orig/queue/queue.cc 2003-02-26 15:09:12.000000000 -0700 +++ ns-2.26.nsclickcvs/queue/queue.cc 2003-04-10 10:54:09.000000000 -0600 @@ -34,7 +34,7 @@ #ifndef lint static const char rcsid[] = - "@(#) $Header: /nfs/jade/vint/CVSROOT/ns-2/queue/queue.cc,v 1.27 2003/01/28 23:31:03 sfloyd Exp $ (LBL)"; + "@(#) $Header: /srl/dirkcvs/nsclick/ns/queue/queue.cc,v 1.3 2003/04/10 16:52:46 neufeldm Exp $ (LBL)"; #endif #include "queue.h" @@ -162,6 +162,7 @@ utilUpdate(last_change_, now, blocked_); last_change_ = now; blocked_ = 0; + on_unblock(); } else { utilUpdate(last_change_, now, blocked_); @@ -171,6 +172,10 @@ } } +void Queue::on_unblock() { + // Do nothing in base class +} + void Queue::reset() { Packet* p; --- ns-2.26.orig/queue/queue.h 2003-02-26 15:09:12.000000000 -0700 +++ ns-2.26.nsclickcvs/queue/queue.h 2003-04-10 10:54:09.000000000 -0600 @@ -31,7 +31,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#) $Header: /nfs/jade/vint/CVSROOT/ns-2/queue/queue.h,v 1.31 2002/12/18 03:36:37 sundarra Exp $ (LBL) + * @(#) $Header: /srl/dirkcvs/nsclick/ns/queue/queue.h,v 1.3 2003/04/10 16:52:46 neufeldm Exp $ (LBL) */ #ifndef ns_queue_h @@ -154,6 +154,7 @@ double last_change_; /* time at which state changed/utilization measured */ double old_util_; /* current utilization */ double util_weight_; /* decay factor for measuring the link utilization */ + virtual void on_unblock(); }; #endif --- ns-2.26.orig/routing/extclickrouter.cc 1969-12-31 17:00:00.000000000 -0700 +++ ns-2.26.nsclickcvs/routing/extclickrouter.cc 2002-06-10 13:23:06.000000000 -0600 @@ -0,0 +1,22 @@ +/* + * XXX Insert CU copyright stuff here... + * + * $Header: /srl/dirkcvs/nsclick/ns/routing/extclickrouter.cc,v 1.1 2002/06/10 19:23:06 neufeldm Exp $ + * + */ + +#include "packet.h" +#include "extrouter.h" +#include "extclickrouter.h" + +ExtClickRouter::ExtClickRouter() { +} + +ExtClickRouter::~ExtClickRouter() { +} + +int ExtClickRouter::recv(Packet* p) { + int result = 0; + + return result; +} --- ns-2.26.orig/routing/extclickrouter.h 1969-12-31 17:00:00.000000000 -0700 +++ ns-2.26.nsclickcvs/routing/extclickrouter.h 2002-06-10 13:23:06.000000000 -0600 @@ -0,0 +1,29 @@ +/* + * XXX Insert CU copyright stuff here... + * + * $Header: /srl/dirkcvs/nsclick/ns/routing/extclickrouter.h,v 1.1 2002/06/10 19:23:06 neufeldm Exp $ + * + * This defines the interface used by all external raw packet routing + * modules bolted on to ns. + * + */ + +#ifndef __ns_extclickrouter_h__ +#define __ns_extclickrouter_h__ + +class ExtClickRouter +{ + + public: + ExtClickRouter(); + virtual ~ExtClickRouter(); + virtual int recv(Packet* p); + + void* SetClickRouterPtr(void* crtptr); + + private: + void* clickrouter_; + +}; + +#endif --- ns-2.26.orig/routing/extrouter.cc 1969-12-31 17:00:00.000000000 -0700 +++ ns-2.26.nsclickcvs/routing/extrouter.cc 2002-06-10 13:23:07.000000000 -0600 @@ -0,0 +1,17 @@ +/* + * XXX Insert CU copyright stuff here... + * + * $Header: /srl/dirkcvs/nsclick/ns/routing/extrouter.cc,v 1.1 2002/06/10 19:23:07 neufeldm Exp $ + * + * This defines the interface used by all external raw packet routing + * modules bolted on to ns. + * + */ + +#include "packet.h" +#include "extrouter.h" + +// Just here so we get virtual destructors +ExtRouter::~ExtRouter() { +} + --- ns-2.26.orig/routing/extrouter.h 1969-12-31 17:00:00.000000000 -0700 +++ ns-2.26.nsclickcvs/routing/extrouter.h 2002-09-07 01:34:19.000000000 -0600 @@ -0,0 +1,31 @@ +/* + * XXX Insert CU copyright stuff here... + * + * $Header: /srl/dirkcvs/nsclick/ns/routing/extrouter.h,v 1.2 2002/09/07 07:34:19 neufeldm Exp $ + * + * This defines the interface used by all external raw packet routing + * modules bolted on to ns. + * + */ + +#ifndef __ns_extrouter_h__ +#define __ns_extrouter_h__ + +class ExtRouter +{ + +public: + enum { + IFID_NONE = -1, + IFID_KERNELTAP = 0, + IFID_FIRSTIF = 1, + IFID_LASTIF = 32, + IFID_FIRSTIFDROP = 33, + IFID_LASTIFDROP = 64 + }; + virtual ~ExtRouter(); + virtual int route(Packet* p) = 0; + +}; + +#endif --- ns-2.26.orig/routing/rtmodule.cc 2003-02-26 15:09:15.000000000 -0700 +++ ns-2.26.nsclickcvs/routing/rtmodule.cc 2003-04-10 10:54:09.000000000 -0600 @@ -16,7 +16,7 @@ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Header: /nfs/jade/vint/CVSROOT/ns-2/routing/rtmodule.cc,v 1.15 2002/12/18 03:36:37 sundarra Exp $ + * $Header: /srl/dirkcvs/nsclick/ns/routing/rtmodule.cc,v 1.3 2003/04/10 16:52:50 neufeldm Exp $ */ #include "rtmodule.h" @@ -109,6 +109,14 @@ } } class_lms_routing_module; +static class ClickRoutingModuleClass : public TclClass { +public: + ClickRoutingModuleClass() : TclClass("RtModule/Click") {} + TclObject* create(int, const char*const*) { + return (new ClickRoutingModule); + } +} class_click_routing_module; + RoutingModule::RoutingModule() : next_rtm_(NULL), n_(NULL), classifier_(NULL) { bind("classifier_", (TclObject**)&classifier_); @@ -480,4 +488,3 @@ if (next_rtm_ != NULL) next_rtm_->add_route(dst, target); } - --- ns-2.26.orig/routing/rtmodule.h 2003-02-26 15:09:15.000000000 -0700 +++ ns-2.26.nsclickcvs/routing/rtmodule.h 2003-04-10 10:54:09.000000000 -0600 @@ -16,7 +16,7 @@ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Header: /nfs/jade/vint/CVSROOT/ns-2/routing/rtmodule.h,v 1.14 2002/12/18 03:36:37 sundarra Exp $ + * $Header: /srl/dirkcvs/nsclick/ns/routing/rtmodule.h,v 1.3 2003/04/10 16:52:50 neufeldm Exp $ * * Definition of RoutingModule, base class for all extensions to routing * functionality in a Node. These modules are meant to be "plugin", and @@ -149,4 +149,10 @@ virtual void add_route(char *dst, NsObject *target){} }; +class ClickRoutingModule : public RoutingModule { +public: + ClickRoutingModule() : RoutingModule() {} + virtual const char* module_name() const { return "Click"; } +}; + #endif // ns_rtmodule_h --- ns-2.26.orig/tcl/ex/nsclick-simple-bridge.click 1969-12-31 17:00:00.000000000 -0700 +++ ns-2.26.nsclickcvs/tcl/ex/nsclick-simple-bridge.click 2002-06-10 13:23:08.000000000 -0600 @@ -0,0 +1,40 @@ +// +// Copyright 2002, Univerity of Colorado at Boulder. +// +// All Rights Reserved +// +// Permission to use, copy, modify, and distribute this software and its +// documentation for any purpose other than its incorporation into a +// commercial product is hereby granted without fee, provided that the +// above copyright notice appear in all copies and that both that +// copyright notice and this permission notice appear in supporting +// documentation, and that the name of the University not be used in +// advertising or publicity pertaining to distribution of the software +// without specific, written prior permission. +// +// UNIVERSITY OF COLORADO DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS +// SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +// FITNESS FOR ANY PARTICULAR PURPOSE. IN NO EVENT SHALL THE UNIVERSITY +// OF COLORADO BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL +// DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA +// OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. +// + +// nsclick-simple-bridge.click +// +// This is a simple and stupid network "bridge." Packets coming +// in off of eth0 are pumped out on eth1, and packets coming +// in off of eth1 are pumped out on eth0. +// + +FromSimDevice(eth0,4096) + -> Queue + -> ToSimDevice(eth1); + +FromSimDevice(eth1,4096) + -> Queue + -> ToSimDevice(eth0); + + --- ns-2.26.orig/tcl/ex/nsclick-simple-hybrid.tcl 1969-12-31 17:00:00.000000000 -0700 +++ ns-2.26.nsclickcvs/tcl/ex/nsclick-simple-hybrid.tcl 2002-06-12 20:34:34.000000000 -0600 @@ -0,0 +1,389 @@ +# +# Copyright 2002, Univerity of Colorado at Boulder. +# +# All Rights Reserved +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose other than its incorporation into a +# commercial product is hereby granted without fee, provided that the +# above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of the University not be used in +# advertising or publicity pertaining to distribution of the software +# without specific, written prior permission. +# +# UNIVERSITY OF COLORADO DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS +# SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +# FITNESS FOR ANY PARTICULAR PURPOSE. IN NO EVENT SHALL THE UNIVERSITY +# OF COLORADO BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL +# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA +# OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. +# +# nsclick-simple-hybrid.tcl +# @(#) $Header: /srl/dirkcvs/nsclick/ns/tcl/ex/nsclick-simple-hybrid.tcl,v 1.2 2002/06/13 02:34:34 neufeldm Exp $ +# +# A sample nsclick script simulating a small hybrid wired/wireless +# + +# +# Set some general simulation parameters +# + +# +# Unity gain, omnidirectional antennas, centered 1.5m above each node. +# These values are lifted from the ns-2 sample files. +# +Antenna/OmniAntenna set X_ 0 +Antenna/OmniAntenna set Y_ 0 +Antenna/OmniAntenna set Z_ 1.5 +Antenna/OmniAntenna set Gt_ 1.0 +Antenna/OmniAntenna set Gr_ 1.0 + +# +# Initialize the SharedMedia interface with parameters to make +# it work like the 914MHz Lucent WaveLAN DSSS radio interface +# These are taken directly from the ns-2 sample files. +# +Phy/WirelessPhy set CPThresh_ 10.0 +Phy/WirelessPhy set CSThresh_ 1.559e-11 +Phy/WirelessPhy set RXThresh_ 3.652e-10 +Phy/WirelessPhy set Rb_ 2*1e6 +Phy/WirelessPhy set Pt_ 0.2818 +Phy/WirelessPhy set freq_ 914e+6 +Phy/WirelessPhy set L_ 1.0 + +# +# Set the size of the playing field and the topography. +# +set xsize 100 +set ysize 100 +set wtopo [new Topography] +$wtopo load_flatgrid $xsize $ysize + +# +# The network channel, physical layer, MAC, propagation model, +# and antenna model are all standard ns-2. +# +set wirelesschan Channel/WirelessChannel +set wiredchan Channel + +set wirelessphy Phy/WirelessPhy +set wiredphy Phy/WiredPhy + +set wirelessmac Mac/802_11 +set wiredmac Mac/802_3 + +set netprop Propagation/TwoRayGround +set antenna Antenna/OmniAntenna + +# +# We have to use a special queue and link layer. This is so that +# Click can have control over the network interface packet queue, +# which is vital if we want to play with, e.g. QoS algorithms. +# +set netifq Queue/ClickQueue +set netll LL/Ext +LL set delay_ 1ms + +# +# These are pretty self-explanatory, just the number of nodes +# and when we'll stop. +# +set wirednodecount 3 +set wirelessnodecount 3 +set bridgenodecount 1 +set nodecount 7 +set stoptime 10.0 + +# +# With nsclick, we have to worry about details like which network +# port to use for communication. This sets the default ports to 5000. +# +Agent/Null set sport_ 5000 +Agent/Null set dport_ 5000 + +Agent/CBR set sport_ 5000 +Agent/CBR set dport_ 5000 + +# +# Standard ns-2 stuff here - create the simulator object. +# +set ns_ [new Simulator] + +# +# Create and activate trace files. +# +set tracefd [open "nsclick-simple-hybrid.tr" w] +set namtrace [open "nsclick-simple-hybrid.nam" w] +$ns_ trace-all $tracefd +$ns_ namtrace-all-wireless $namtrace $xsize $ysize +$ns_ use-newtrace + + +# +# Create the "god" object. This is another artifact of using +# the mobile node type. We have to have this even though +# we never use it. +# +set god_ [create-god $nodecount] + +# +# Tell the simulator to create Click nodes. +# +Simulator set node_factory_ Node/MobileNode/ClickNode + +# +# Create a network Channel for the nodes to use. One channel +# per LAN. Also set the propagation model to be used. +# +set wired_chan_ [new $wiredchan] +set wireless_chan_ [new $wirelesschan] +set prop_ [new $netprop] + +# +# In nsclick we have to worry about assigning IP and MAC addresses +# to out network interfaces. Here we generate a list of IP and MAC +# addresses, one per node since we've only got one network interface +# per node in this case. Also note that this scheme only works for +# fewer than 255 nodes, and we aren't worrying about subnet masks. +# +set iptemplate "192.168.1.%d" +set mactemplate "00:03:47:70:89:%0x" +for {set i 0} {$i < $wirednodecount} {incr i} { + set wired_node_ip($i) [format $iptemplate [expr $i+1]] + set wired_node_mac($i) [format $mactemplate [expr $i+1]] +} + +set iptemplate "192.168.2.%d" +set mactemplate "00:03:47:70:8A:%0x" +for {set i 0} {$i < $wirelessnodecount} {incr i} { + set wireless_node_ip($i) [format $iptemplate [expr $i+1]] + set wireless_node_mac($i) [format $mactemplate [expr $i+1]] +} + + +# +# We set the routing protocol to "Empty" so that ns-2 doesn't do +# any packet routing. All of the routing will be done by the +# Click script. +# +$ns_ rtproto Empty + +# +# Here is where we actually create all of the nodes. +# We'll create the wired, wireless, and the bridge node +# separately. +# + +# +# Start with the wireless nodes +# +for {set i 0} {$i < $wirelessnodecount } {incr i} { + set wireless_node_($i) [$ns_ node] + + # + # After creating the node, we add one wireless network interface to + # it. By default, this interface will be named "eth0". If we + # added a second interface it would be named "eth1", a third + # "eth2" and so on. + # + $wireless_node_($i) add-interface $wireless_chan_ $prop_ $netll \ + $wirelessmac $netifq 1 $wirelessphy $antenna + + # + # Now configure the interface eth0 + # + $wireless_node_($i) setip "eth0" $wireless_node_ip($i) + $wireless_node_($i) setmac "eth0" $wireless_node_mac($i) + + # + # Set some node properties + # + $wireless_node_($i) random-motion 0 + $wireless_node_($i) topography $wtopo + $wireless_node_($i) nodetrace $tracefd + + # + # The node name is used by Click to distinguish information + # coming from different nodes. For example, a "Print" element + # prepends this to the printed string so it's clear exactly + # which node is doing the printing. + # + [$wireless_node_($i) set classifier_] setnodename "wirelessnode$i-hybrid" + + # + # Load the appropriate Click router script for the node. + # + [$wireless_node_($i) entry] loadclick "nsclick-simple-lan.click" +} + +# +# Now create the wired nodes +# +for {set i 0} {$i < $wirednodecount } {incr i} { + set wired_node_($i) [$ns_ node] + + # + # After creating the node, we add one wired network interface to + # it. By default, this interface will be named "eth0". If we + # added a second interface it would be named "eth1", a third + # "eth2" and so on. + # + $wired_node_($i) add-wired-interface $wired_chan_ $netll $wiredmac \ + $netifq 1 $wiredphy + + # + # Now configure the interface eth0 + # + $wired_node_($i) setip "eth0" $wired_node_ip($i) + $wired_node_($i) setmac "eth0" $wired_node_mac($i) + + # + # Set some node properties + # + $wired_node_($i) random-motion 0 + $wired_node_($i) topography $wtopo + $wired_node_($i) nodetrace $tracefd + + # + # The node name is used by Click to distinguish information + # coming from different nodes. For example, a "Print" element + # prepends this to the printed string so it's clear exactly + # which node is doing the printing. + # + [$wired_node_($i) set classifier_] setnodename "wirednode$i-hybrid" + + # + # Load the appropriate Click router script for the node. + # All nodes in this simulation are using the same script, + # but there's no reason why each node couldn't use a different + # script. + # + [$wired_node_($i) entry] loadclick "nsclick-simple-lan.click" +} + +# +# Finally make the bridge node +# +set bridge_node_ [$ns_ node] +$bridge_node_ add-wired-interface $wired_chan_ $netll $wiredmac \ + $netifq 1 $wiredphy +$bridge_node_ add-interface $wireless_chan_ $prop_ $netll \ + $wirelessmac $netifq 1 $wirelessphy $antenna + +$bridge_node_ random-motion 0 +$bridge_node_ topography $wtopo +$bridge_node_ nodetrace $tracefd + +[$bridge_node_ entry] loadclick "nsclick-simple-bridge.click" +[$bridge_node_ set classifier_] setnodename "bridgenode-hybrid" + +# +# Define node network traffic. There isn't a whole lot going on +# in this simple test case, we're just going to have the first wireless node +# send packets to the first wired node, starting at 1 second, and ending at 10. +# There are Perl scripts available to automatically generate network +# traffic. +# + + +# +# Start transmitting at $startxmittime, $xmitrate packets per second. +# +set startxmittime 1 +set xmitrate 4 +set xmitinterval 0.25 +set packetsize 64 + +# +# We use the "raw" packet type, which sends real packet data +# down the pipe. +# +set raw_(0) [new Agent/Raw] +$ns_ attach-agent $wireless_node_(0) $raw_(0) + +set null_(0) [new Agent/Null] +$ns_ attach-agent $wired_node_(0) $null_(0) + +# +# The CBR object is just the default ns-2 CBR object, so +# no change in the meaning of the parameters. +# +set cbr_(0) [new Application/Traffic/CBR] +$cbr_(0) set packetSize_ $packetsize +$cbr_(0) set interval_ $xmitinterval +$cbr_(0) set random_ 0 +$cbr_(0) set maxpkts_ [expr ($stoptime - $startxmittime)*$xmitrate] +$cbr_(0) attach-agent $raw_(0) + +# +# The Raw agent creates real UDP packets, so it has to know +# the source and destination IP addresses and port numberes. +# +$raw_(0) set-srcip [$wireless_node_(0) getip eth0] +$raw_(0) set-srcport 5000 +$raw_(0) set-destport 5000 +$raw_(0) set-destip [$wired_node_(0) getip eth0] + +$ns_ at $startxmittime "$cbr_(0) start" + + +$wireless_node_(0) set X_ 10 +$wireless_node_(0) set Y_ 50 +$wireless_node_(0) set Z_ 0 + +$wireless_node_(1) set X_ 50 +$wireless_node_(1) set Y_ 50 +$wireless_node_(1) set Z_ 0 + +$wireless_node_(2) set X_ 90 +$wireless_node_(2) set Y_ 50 +$wireless_node_(2) set Z_ 0 + +$bridge_node_ set X_ 50 +$bridge_node_ set Y_ 10 +$bridge_node_ set Z_ 0 + +$wired_node_(0) set X_ 10 +$wired_node_(0) set Y_ 0 +$wired_node_(0) set Z_ 0 + +$wired_node_(1) set X_ 50 +$wired_node_(1) set Y_ 0 +$wired_node_(1) set Z_ 0 + +$wired_node_(2) set X_ 90 +$wired_node_(2) set Y_ 0 +$wired_node_(2) set Z_ 0 +# +# This sizes the nodes for use in nam. +# +for {set i 0} {$i < $wirelessnodecount} {incr i} { + $ns_ initial_node_pos $wireless_node_($i) 10 +} + +for {set i 0} {$i < $wirednodecount} {incr i} { + $ns_ initial_node_pos $wired_node_($i) 10 +} + +$ns_ initial_node_pos $bridge_node_ 10 + +# +# Stop the simulation +# +$ns_ at $stoptime.000000001 "puts \"NS EXITING...\" ; $ns_ halt" + +# +# Let nam know that the simulation is done. +# +$ns_ at $stoptime "$ns_ nam-end-wireless $stoptime" + + +puts "Starting Simulation..." +$ns_ run + + + + --- ns-2.26.orig/tcl/ex/nsclick-simple-lan.click 1969-12-31 17:00:00.000000000 -0700 +++ ns-2.26.nsclickcvs/tcl/ex/nsclick-simple-lan.click 2003-04-21 22:22:56.000000000 -0600 @@ -0,0 +1,101 @@ +// +// Copyright 2002, Univerity of Colorado at Boulder. +// +// All Rights Reserved +// +// Permission to use, copy, modify, and distribute this software and its +// documentation for any purpose other than its incorporation into a +// commercial product is hereby granted without fee, provided that the +// above copyright notice appear in all copies and that both that +// copyright notice and