This post is an extension to the broadcast example. In this, I am going to explain how a node can be entered into promiscuous mode so that it can overhear the packets sent, forward or received by neighboring nodes. It all require a class called Tap which is available in mac.h header file. Tap class offer a function called void tap(const Packet *p). To define the tap function, we need to inherit the class Tap. Usage of tap function and Tap class has shown with the broadcast example.
/* This Protocol perform Simple broad cast and overhear the packets of neighboring nodes
* sbcast.h
*
* Created on: 19-May-2013
* Author: P. RAGHU VAMSI
* @ JAYPEE INSTITUTE OF INFORMATION TECHNOLOGY UNIVERSITY, INDIA
* @ prvonline@yahoo.co.in
*/
#ifndef SBCAST_H_
#define SBCAST_H_
// Include mac header to overhear
#include
#define CURRENT_TIME Scheduler::instance().clock()
#define MAX_NODES 20
#define JITTER (Random::uniform()*0.5)
#define CURRENT_TIME Scheduler::instance().clock()
#define HDR_BEACON(p) (hdr_beacon *) hdr_beacon::access(p)
struct hdr_beacon {
nsaddr_t addr_;
u_int8_t seq_num_;
inline nsaddr_t & addr() { return addr_; }
inline u_int8_t & seq_num() { return seq_num_; }
static int offset_;
inline static int & offset() { return offset_; }
inline static hdr_beacon * access(const Packet *p) {
return (hdr_beacon*) p->access(offset_);
}
};
class SBAgent;
class BcastTimer : public TimerHandler {
protected:
SBAgent *agent_;
virtual void expire(Event *e);
public:
BcastTimer(SBAgent *agent):TimerHandler(),agent_(agent) { }
};
class SBAgent : public Tap,public Agent {
protected:
friend class BcastTimer;
private:
BcastTimer btimer_;
PortClassifier *dmux_;
Trace *logtarget_;
nsaddr_t my_addr_;
int seq_num_;
int node_count;
// for obtaining the mac of the node
Mac *mac_;
public:
static int pkt_received[MAX_NODES];
static int pkt_send[MAX_NODES];
static int no_of_nodes;
static int color_count;
SBAgent();
int command(int,const char*const*);
void recv(Packet *,Handler *);
void sendBeacon();
void resetBcastTimer();
inline nsaddr_t & my_addr() { return my_addr_;}
void changeColor();
//Tap to overhear the packets (or) to enter into promiscous mode
void tap(const Packet *);
};
#endif /* SBCAST_H_ */
sbcast.cc
/*
* sbcast.cc
* This Protocol perform Simple broad cast
* Created on: 19-May-2013
* Author: P. RAGHU VAMSI
* @ JAYPEE INSTITUTE OF INFORMATION TECHNOLOGY UNIVERSITY, INDIA
* @ prvonline@yahoo.co.in
*/
#include "sbcast.h"
#include "mobilenode.h"
// TCL Hooks
int hdr_beacon::offset_;
static class SBcastHeaderClass : public PacketHeaderClass {
public:
SBcastHeaderClass():PacketHeaderClass("PacketHeader/SB",sizeof(hdr_beacon)) {
bind_offset(&hdr_beacon::offset_);
}
}class_hdr_sbcast;
static class SBcastClass : public TclClass {
public:
SBcastClass():TclClass("Agent/SB") { }
TclObject *create(int argc,const char*const* argv) {
return (new SBAgent());
}
virtual void bind(); // for access of static variables
virtual int method(int argc, const char*const* argv);
}class_sbagent;
int SBAgent::pkt_received[MAX_NODES];
int SBAgent::pkt_send[MAX_NODES];
int SBAgent::no_of_nodes;
int SBAgent::color_count;
void SBcastClass::bind() {
TclClass::bind();
add_method("print-stats");
}
int SBcastClass::method(int ac, const char*const* av) {
int argc = ac - 2;
const char*const* argv = av + 2;
if (argc == 2) {
if(strcmp(argv[1],"print-stats")==0){
for(int i=0;
i printf("Packets Sent By Node %d : %d \n",i,SBAgent::pkt_send[i]);
printf("Packets Received By Node %d : %d \n",i,SBAgent::pkt_received[i]);
}
}
return TCL_OK;
}
}
SBAgent::SBAgent():Agent(PT_SB),btimer_(this) {
bind("node_count",&node_count);
no_of_nodes = node_count;
}
int SBAgent::command(int argc,const char*const* argv) {
if(argc==2){
if(strcmp(argv[1],"start")==0){
my_addr_ = addr();
return TCL_OK;
}
if(strcmp(argv[1],"base-station")==0){
btimer_.resched((double)0.1);
my_addr_ = addr();
return TCL_OK;
}
}else if (argc == 3) {
// Obtains corresponding dmux to carry packets to upper layers
if (strcmp(argv[1], "port-dmux") == 0) {
dmux_ = (PortClassifier*)TclObject::lookup(argv[2]);
if (dmux_ == 0) {
fprintf(stderr, "%s: %s lookup of %s failed\n",
__FILE__,
argv[1],
argv[2]);
return TCL_ERROR;
}
return TCL_OK;
}
if (strcmp(argv[1], "log-target") == 0 ||
strcmp(argv[1], "tracetarget") == 0) {
logtarget_ = (Trace*)TclObject::lookup(argv[2]);
if (logtarget_ == 0)
return TCL_ERROR;
return TCL_OK;
}
/* Add a command to install tap on a mac layer of a node */
if (strcmp(argv[1], "install-tap") == 0) {
mac_ = (Mac*) TclObject::lookup(argv[2]);
mac_->installTap(this);
return TCL_OK;
}
}
return (Agent::command(argc,argv));
}
void BcastTimer::expire(Event *e) {
agent_->sendBeacon();
agent_->changeColor();
agent_->resetBcastTimer();
}
void SBAgent::resetBcastTimer() {
btimer_.resched((double)0.5);
}
void SBAgent::sendBeacon() {
Packet* p = allocpkt();
struct hdr_cmn* ch = HDR_CMN(p);
struct hdr_ip* ih = HDR_IP(p);
struct hdr_beacon * ph = HDR_BEACON(p);
ph->addr() = my_addr();
ph->seq_num() = seq_num_++;
ch->ptype() = PT_SB;
ch->direction() = hdr_cmn::DOWN;
ch->size() = IP_HDR_LEN;
ch->error() = 0;
ch->next_hop() = IP_BROADCAST;
ch->addr_type() = NS_AF_INET;
ih->saddr() = my_addr();
ih->daddr() = IP_BROADCAST;
ih->sport() = RT_PORT;
ih->dport() = RT_PORT;
ih->ttl() = IP_DEF_TTL;
pkt_send[my_addr()]++;
send(p,0);
}
void SBAgent::recv(Packet *p,Handler *h) {
struct hdr_cmn *ch = HDR_CMN(p);
if(ch->ptype() == PT_SB) {
pkt_received[my_addr()]++;
}
}
void SBAgent::changeColor() {
char *color[5] = {"blue","brown","red","yellow","purple"};
Tcl& tcl = Tcl::instance();
tcl.evalf("%s set node_", name());
const char *node_object = tcl.result();
Tcl::instance().evalf("$ns at %f \"%s color %s\"",CURRENT_TIME,
node_object,color[color_count]);
if(color_count >= 4) color_count=0;
else color_count++;
}
/* Define the tap function to overhear the packets (or) to enter
* into promiscuos mode.
*/
void SBAgent::tap(const Packet *p) {
struct hdr_cmn* ch = HDR_CMN(p);
struct hdr_beacon * ph = HDR_BEACON(p);
printf("\n Node: %d IN TAP: from %d Seq Number: %d Packet Type: %d",my_addr(),ph->addr_,ph->seq_num_,ch->ptype());
}
/* This Protocol perform Simple broad cast and overhear the packets of neighboring nodes
* sbcast.h
*
* Created on: 19-May-2013
* Author: P. RAGHU VAMSI
* @ JAYPEE INSTITUTE OF INFORMATION TECHNOLOGY UNIVERSITY, INDIA
* @ prvonline@yahoo.co.in
*/
#ifndef SBCAST_H_
#define SBCAST_H_
// Include mac header to overhear
#include
#define CURRENT_TIME Scheduler::instance().clock()
#define MAX_NODES 20
#define JITTER (Random::uniform()*0.5)
#define CURRENT_TIME Scheduler::instance().clock()
#define HDR_BEACON(p) (hdr_beacon *) hdr_beacon::access(p)
struct hdr_beacon {
nsaddr_t addr_;
u_int8_t seq_num_;
inline nsaddr_t & addr() { return addr_; }
inline u_int8_t & seq_num() { return seq_num_; }
static int offset_;
inline static int & offset() { return offset_; }
inline static hdr_beacon * access(const Packet *p) {
return (hdr_beacon*) p->access(offset_);
}
};
class SBAgent;
class BcastTimer : public TimerHandler {
protected:
SBAgent *agent_;
virtual void expire(Event *e);
public:
BcastTimer(SBAgent *agent):TimerHandler(),agent_(agent) { }
};
class SBAgent : public Tap,public Agent {
protected:
friend class BcastTimer;
private:
BcastTimer btimer_;
PortClassifier *dmux_;
Trace *logtarget_;
nsaddr_t my_addr_;
int seq_num_;
int node_count;
// for obtaining the mac of the node
Mac *mac_;
public:
static int pkt_received[MAX_NODES];
static int pkt_send[MAX_NODES];
static int no_of_nodes;
static int color_count;
SBAgent();
int command(int,const char*const*);
void recv(Packet *,Handler *);
void sendBeacon();
void resetBcastTimer();
inline nsaddr_t & my_addr() { return my_addr_;}
void changeColor();
//Tap to overhear the packets (or) to enter into promiscous mode
void tap(const Packet *);
};
#endif /* SBCAST_H_ */
sbcast.cc
/*
* sbcast.cc
* This Protocol perform Simple broad cast
* Created on: 19-May-2013
* Author: P. RAGHU VAMSI
* @ JAYPEE INSTITUTE OF INFORMATION TECHNOLOGY UNIVERSITY, INDIA
* @ prvonline@yahoo.co.in
*/
#include "sbcast.h"
#include "mobilenode.h"
// TCL Hooks
int hdr_beacon::offset_;
static class SBcastHeaderClass : public PacketHeaderClass {
public:
SBcastHeaderClass():PacketHeaderClass("PacketHeader/SB",sizeof(hdr_beacon)) {
bind_offset(&hdr_beacon::offset_);
}
}class_hdr_sbcast;
static class SBcastClass : public TclClass {
public:
SBcastClass():TclClass("Agent/SB") { }
TclObject *create(int argc,const char*const* argv) {
return (new SBAgent());
}
virtual void bind(); // for access of static variables
virtual int method(int argc, const char*const* argv);
}class_sbagent;
int SBAgent::pkt_received[MAX_NODES];
int SBAgent::pkt_send[MAX_NODES];
int SBAgent::no_of_nodes;
int SBAgent::color_count;
void SBcastClass::bind() {
TclClass::bind();
add_method("print-stats");
}
int SBcastClass::method(int ac, const char*const* av) {
int argc = ac - 2;
const char*const* argv = av + 2;
if (argc == 2) {
if(strcmp(argv[1],"print-stats")==0){
for(int i=0;
i
printf("Packets Received By Node %d : %d \n",i,SBAgent::pkt_received[i]);
}
}
return TCL_OK;
}
}
SBAgent::SBAgent():Agent(PT_SB),btimer_(this) {
bind("node_count",&node_count);
no_of_nodes = node_count;
}
int SBAgent::command(int argc,const char*const* argv) {
if(argc==2){
if(strcmp(argv[1],"start")==0){
my_addr_ = addr();
return TCL_OK;
}
if(strcmp(argv[1],"base-station")==0){
btimer_.resched((double)0.1);
my_addr_ = addr();
return TCL_OK;
}
}else if (argc == 3) {
// Obtains corresponding dmux to carry packets to upper layers
if (strcmp(argv[1], "port-dmux") == 0) {
dmux_ = (PortClassifier*)TclObject::lookup(argv[2]);
if (dmux_ == 0) {
fprintf(stderr, "%s: %s lookup of %s failed\n",
__FILE__,
argv[1],
argv[2]);
return TCL_ERROR;
}
return TCL_OK;
}
if (strcmp(argv[1], "log-target") == 0 ||
strcmp(argv[1], "tracetarget") == 0) {
logtarget_ = (Trace*)TclObject::lookup(argv[2]);
if (logtarget_ == 0)
return TCL_ERROR;
return TCL_OK;
}
/* Add a command to install tap on a mac layer of a node */
if (strcmp(argv[1], "install-tap") == 0) {
mac_ = (Mac*) TclObject::lookup(argv[2]);
mac_->installTap(this);
return TCL_OK;
}
}
return (Agent::command(argc,argv));
}
void BcastTimer::expire(Event *e) {
agent_->sendBeacon();
agent_->changeColor();
agent_->resetBcastTimer();
}
void SBAgent::resetBcastTimer() {
btimer_.resched((double)0.5);
}
void SBAgent::sendBeacon() {
Packet* p = allocpkt();
struct hdr_cmn* ch = HDR_CMN(p);
struct hdr_ip* ih = HDR_IP(p);
struct hdr_beacon * ph = HDR_BEACON(p);
ph->addr() = my_addr();
ph->seq_num() = seq_num_++;
ch->ptype() = PT_SB;
ch->direction() = hdr_cmn::DOWN;
ch->size() = IP_HDR_LEN;
ch->error() = 0;
ch->next_hop() = IP_BROADCAST;
ch->addr_type() = NS_AF_INET;
ih->saddr() = my_addr();
ih->daddr() = IP_BROADCAST;
ih->sport() = RT_PORT;
ih->dport() = RT_PORT;
ih->ttl() = IP_DEF_TTL;
pkt_send[my_addr()]++;
send(p,0);
}
void SBAgent::recv(Packet *p,Handler *h) {
struct hdr_cmn *ch = HDR_CMN(p);
if(ch->ptype() == PT_SB) {
pkt_received[my_addr()]++;
}
}
void SBAgent::changeColor() {
char *color[5] = {"blue","brown","red","yellow","purple"};
Tcl& tcl = Tcl::instance();
tcl.evalf("%s set node_", name());
const char *node_object = tcl.result();
Tcl::instance().evalf("$ns at %f \"%s color %s\"",CURRENT_TIME,
node_object,color[color_count]);
if(color_count >= 4) color_count=0;
else color_count++;
}
/* Define the tap function to overhear the packets (or) to enter
* into promiscuos mode.
*/
void SBAgent::tap(const Packet *p) {
struct hdr_cmn* ch = HDR_CMN(p);
struct hdr_beacon * ph = HDR_BEACON(p);
printf("\n Node: %d IN TAP: from %d Seq Number: %d Packet Type: %d",my_addr(),ph->addr_,ph->seq_num_,ch->ptype());
}
bcast.tcl
#===================================
# Simulation parameters setup
#===================================
set val(chan) Channel/WirelessChannel ;# channel type
set val(prop) Propagation/TwoRayGround ;# radio-propagation model
set val(netif) Phy/WirelessPhy ;# network interface type
set val(mac) Mac/802_11 ;# MAC type
set val(ifq) Queue/DropTail/PriQueue ;# interface queue type
set val(ll) LL ;# link layer type
set val(ant) Antenna/OmniAntenna ;# antenna model
set val(ifqlen) 50 ;# max packet in ifq
set val(nn) 5 ;# number of mobilenodes
set val(rp) SB ;# routing protocol
set val(ie) 100 ; # initial energy of a node
set val(em) EnergyModel ; # Energy model
set val(x) 100 ;# X dimension of topography
set val(y) 100 ;# Y dimension of topography
set val(stop) 50
Agent/SB set node_count $val(nn)
#===================================
# Attaching selected headers
#===================================
remove-all-packet-headers
add-packet-header Mac LL IP ARP LL SB
#===================================
# Initialization
#===================================
#Create a ns simulator
set ns [new Simulator]
#Setup topography object
set topo [new Topography]
$topo load_flatgrid $val(x) $val(y)
create-god $val(nn)
#Open the NS trace file
set tracefile [open bcast.tr w]
$ns trace-all $tracefile
#Open the NAM trace file
set namfile [open bcast.nam w]
$ns namtrace-all $namfile
$ns namtrace-all-wireless $namfile $val(x) $val(y)
set chan [new $val(chan)];#Create wireless channel
Mac/802_11 set dataRate 512Kbps
#===================================
# Node parameter setup
#===================================
$ns node-config -adhocRouting $val(rp) \
-llType $val(ll) \
-macType $val(mac) \
-ifqType $val(ifq) \
-ifqLen $val(ifqlen) \
-antType $val(ant) \
-propType $val(prop) \
-phyType $val(netif) \
-channel $chan \
-topoInstance $topo \
-agentTrace ON \
-routerTrace ON \
-macTrace ON \
-movementTrace OFF \
-energyModel $val(em) \
-initialEnergy $val(ie) \
-rxPower 35.25e-23 \
-txPower 31.21e-23 \
-idlePower 712e-6 \
-sleepPower 144e-9
#===================================
# Nodes Definition
#===================================
for {set i 0} {$i < $val(nn)} {incr i} {
set node_($i) [$ns node]
$node_($i) color blue
}
for {set i 0} {$i < $val(nn)} {incr i} {
set u_($i) [new Agent/SB]
$ns attach-agent $node_($i) $u_($i)
}
$node_(0) set X_ 0.0
$node_(0) set Y_ 0.0
$node_(0) set Z_ 0
$node_(1) set X_ 40.0
$node_(1) set Y_ 0.0
$node_(1) set Z_ 0
$node_(2) set X_ 25.0
$node_(2) set Y_ 0.0
$node_(2) set Z_ 0
$node_(3) set X_ 0.0
$node_(3) set Y_ 75.0
$node_(3) set Z_ 0
$node_(4) set X_ 60.0
$node_(4) set Y_ 20.0
$node_(4) set Z_ 0
#$ns at 1.0 "$node_(0) setdest 99.0 99.0 15.0"
for {set i 0} {$i < $val(nn)} {incr i} {
$ns at 0.0 "[$node_($i) set ragent_] base-station"
}
for {set i 0} {$i < $val(nn)} {incr i} {
$ns initial_node_pos $node_($i) 10
}
for {set i 0} {$i < $val(nn)} {incr i} {
[$node_($i) set ragent_] install-tap [$node_($i) set mac_(0)]
}
proc finish {} {
global ns tracefile namfile
$ns flush-trace
close $tracefile
close $namfile
Agent/SB print-stats
exec nam bcast.nam &
exit 0
}
#===================================
# Reset the nodes
#===================================
for {set i 0} {$i < $val(nn) } { incr i } {
$ns at $val(stop) "$node_($i) reset"
}
#===================================
# Simulation start up
#===================================
$ns at $val(stop) "$ns nam-end-wireless $val(stop)"
$ns at $val(stop) "finish"
$ns at $val(stop) "puts \"done\" ; $ns halt"
puts "before sim run"
$ns run