You are on page 1of 62

NS Tutorial

PMIPv6 Implementation in NS HyonYoung Choi (commani@gmail.com)


NS PMIPv6 Implementation

Tcl C++
Tcl Object C++ Object Tcl Object C++ Object TclClass Tcl C++ object
set mag [new Agent/PMIPv6/MAG]

TclClass class MAGAgentClass : public TclClass { static Tcl Object


public: MAGAgentClass() : TclClass("Agent/PMIPv6/MAG") {} TclObject* create(int, const char*const*) { return (new MAGAgent()); } } class_magagent; class MAGAgent : public PMIPv6Agent { public: MAGAgent(); };

NS (1/4)
Tcl: instproc
Classifier/Addr/PMIPv6Dest instproc install {dst target} { $self instvar classifier_ $classifier_ install $dst $target }

C++: TclObject class command overriding if-else-if string match


int MAGAgent::command(int argc, const char*const* argv) { if(argc==3) { if(strcmp(argv[1], "new-mn") == 0) { return TCL_OK; } else if(strcmp(argv[1], "set-lmaa") == 0) { return (PMIPv6Agent::command(argc, argv)); }

NS (2/4)
Tcl C++
Tcl Type , , C++ Object .

C++ Object Tcl

NS (3/4)
Tcl C++ : Tcl > C++
Tcl C++ command Tcl : C++ : cmd

Tcl C++

Classifier/Addr/PMIPv6Dest instproc clear { dst } { $self instvar classifier_ $classifier_ clear $dst } Classifier/Addr/PMIPv6Dest instproc clear-by-dest { addr } { $self cmd clear $addr }

NS (4/4)
Tcl C++ (contd)
C++ Tcl
Tcl::eval, Tcl::evalf
Tcl& tcl = Tcl::instance(); tcl.evalf("%s setup-route %ld %ld", name(), bule->mn_prefix(), bule->lmaa());

C++ Tcl
Tcl::result
tcl.evalf ("%s getRXThresh",netif_->name()); RXThreshold_ = atof (tcl.result());

C++ Tcl (return)


Tcl::resultf
if (strcmp(argv[1], "ifq") == 0) { tcl.resultf("%s", ifq_->name()); return (TCL_OK); }

packet type (1/4)


1. Packet offset_, offset(), access(Packet *p) ( ) HDR_XXX define ( ) offset_ static C++
#define HDR_PMIPv6((p) ((struct hdr_pmipv6*)(p)->access(hdr_pmipv6::offset_)) struct hdr_pmipv6 { ( ) static int offset_; inline static int& offset() { return offset_; } inline static hdr_pmipv6* access(Packet* p) { return (hdr_pmipv6*) p->access(offset_); } }; int hdr_pmipv6::offset_;

packet type (2/4)


2. PacketHeaderClass Packet Manager class
static class PMIPv6HeaderClass : public PacketHeaderClass { public: PMIPv6HeaderClass() : PacketHeaderClass("PacketHeader/PMIPv6", sizeof(hdr_pmipv6)) { bind_offset(&hdr_pmipv6::offset_); } } class_pmipv6hdr;

3. ns-packet.tcl (ns-2.29/tcl/lib/) PacketHeaderClass


foreach prot { PMIPv6 }{ add-packet-header $prot }

packet type (3/4)


4. packet.h (ns-2.29/common/)
enum packet_t PT_NTYPE
enum packet_t { //PMIP6: type PT_PBU, PT_PBACK, PT_NTYPE // This MUST be the LAST one };

name_ : trace type


p_info() { name_[PT_PBU]="pbu"; name_[PT_PBACK]="pba"; name_[PT_NTYPE]= "undefined"; }

packet type (4/4)


allockpkt hdr_cmn

size: ptype: packet type

Packet *p = allocpkt(); hdr_cmn *hdrc = HDR_CMN(p); hdr_ip *iph = HDR_IP(p); hdr_pmipv6 *h = HDR_PMIPv6(p); hdrc->size() = IPv6_HEADER_SIZE; hdrc->ptype() = PT_PBU; hdrc->size() += PBU_SIZE; iph->saddr() = proxy_coa; iph->sport() = port();

List Tcl (1/2)


(index ) 1. List

info exists
Node instproc listadd {index value} { $self instvar List_ if { ! [info exists List_($index)] || $List_($index)==} { set List_($index) $value } }

List Tcl (2/2)


2. List
unset
Node instproc listdel {index} { $self instvar List_ if { [info exists List_($index)] && $List_($index)!=} { set List_($index) unset List_($index) } }

List - C++ (1/2)


List 1. LIST_HEAD head 2. entry insert_entry. next_entry, remove_entry, link
class BULEntry { public: inline void insert_entry(struct bulEntry *head) { LIST_INSERT_HEAD(head, this, link); } BULEntry* next_entry(void) const { return link.le_next; } inline void remove_entry() { LIST_REMOVE(this, link); } protected: LIST_ENTRY(BULEntry) link; }; class BULEntry; LIST_HEAD(bulEntry, BULEntry);

List - C++ (2/2)


3. List
class MAGAgent : public PMIPv6Agent { struct bulEntry bul_list_;

List List

void MAGAgent::process_new_mn(int32_t mn_id) { bule->insert_entry(&bul_list_);

List

BULEntry *MAGAgent::find_bule(int32_t mn_id) { for(BULEntry *bule=bul_list_.lh_first; bule; bule=bule->next_entry()) { if(bule->mn_id() == mn_id) return bule; } return NULL; }

Timer - Tcl
ns simulator at 1. timeout
Node instproc record {} { set ns [Simulator instance] .. }

2. Timer

Node instproc start { mnaddr } { $self instvar RTimer_ set ns [Simulator instance] set now [$ns now] if {![info exists RTimer_($mnaddr)] || $RTimer_($mnaddr) == ""} { $ns at [expr $now + 1.0] $self record } }

Node instproc stop { mnaddr } { $self instvar RTimer_ set ns [Simulator instance] if {[info exists RTimer_($mnaddr)] && $RTimer_($mnaddr) != ""} { $ns cancel $RTimer_($mnaddr) set Rtimer_($mnaddr) } }

Timer C++ (1/2)


TimerHandler 1. TimerHandler
expire overriding
class BindingTimer : public TimerHandler { public: BindingTimer(PMIPv6Agent *pagent, void *data): TimerHandler() { pagent_ = pagent; data_ = data; } protected: PMIPv6Agent *pagent_; void *data_; void expire(Event *); };

Timer C++ (2/2)


2. expire
Timer
void BindingTimer::expire(Event *) { pagent_->BindingTimeout(data_); }

3. timer
resched cancel
bule->BULTimer_.resched(1.0); bule->BULTimer_.cancel ();

PMIPv6 Objects (1/2)


PacketHeader/PMIPv6 (struct hdr_pmipv6)
PBU, PBACK

PacketHeader/IP6Encap (struct hdr_ip6encap)


IPv6-in-IPv6

Agent/PMIPv6 (class PMIPv6Agent)


LMA MAG

Agent/PMIPv6/LMA (class LMAAgent)


LMA Agent

Agent/PMIPv6/MAG (class MAGAgent)


MAG Agent

PMIPv6 Objects (2/2)


PMIPv6Encapsulator (class PMIPv6Encapsulator) IPv6-in-IPv6 Encapsulator Classifier/Addr/PMIPv6Src (class PMIPv6Src) Source address based routing Classifier/Addr/PMIPv6Dest (class PMIPv6Dest) Destination address routing Classifier/Addr/PMIPv6Decapsulator (class PMIPv6Decapsulator) IPv6-in-IPv6 Decapsulator

PMIPv6 example script

General Initialization
Hierarchical routing MN LMA routing
# set up for hierarchical routing (needed for routing over a basestation) $ns node-config -addressType hierarchical AddrParams set domain_num_ 5 ;# domain number AddrParams set cluster_num_ {1 1 1 1 1} AddrParams set nodes_num_ {1 2 1 1 1}

Wireless configuration
# Parameter for wireless nodes set opt(chan) Channel/WirelessChannel ;# channel type set opt(prop) Propagation/TwoRayGround ;# radio-propagation model set opt(netif) Phy/WirelessPhy ;# network interface type set opt(mac) Mac/802_11 ;# MAC type set opt(ifq) Queue/DropTail/PriQueue ;# interface queue type set opt(ll) LL ;# link layer type set opt(ant) Antenna/OmniAntenna ;# antenna model set opt(ifqlen) 50 ;# max packet in ifq set opt(adhocRouting) DSDV ;# routing protocol

PMIPv6 Initialization (1/8)


LMA
LMA Node install-lma
: duplex-link install-lma

set lma [$ns node 1.0.0] #attach Agent/PMIPv6/LMA to the LMA set lma_pm [$lma install-lma] #BE CAREFUL!. PMIPv6 agent must be installed before connecting link(duplex-link) $ns duplex-link $lma $router 100Mb $opt(dfLinkDelay) DropTail

PMIPv6 Initialization (2/8)


LMA (contd)
install-lma

PMIPv6 Initialization (3/8)


install-lma
Node instproc install-lma {} { $self instvar classifier_ decap_ dmux_ agents_ $self instvar pmip6_agent_ $self instvar dst_classifier_ old_classifier_ #attach pmip6 agent set lma [new Agent/PMIPv6/LMA] $self attach $lma [$lma set default_port_] set pmip6_agent_ $lma #attach dest classifier set old_classifier_ $classifier_ set dst_classifier_ [new Classifier/Addr/PMIPv6Dest] $dst_classifier_ set mask_ 0xffffffff $dst_classifier_ set shift_ 0 $dst_classifier_ defaulttarget $old_classifier_

PMIPv6 Initialization (4/8)


install-lma (contd)
set nodetype [[Simulator instance] get-nodetype] $self insert-entry [$self get-module $nodetype] $dst_classifier_ $dst_classifier_ install-by-dest 0 $old_classifier_ #attach decapsulator set decap_ [new Classifier/Addr/PMIPv6Decapsulator] $decap_ set mask_ 0xffffffff $decap_ set shift_ 0 $decap_ defaulttarget $dst_classifier_ lappend $agents_ $decap_ $dmux_ install [Simulator set PMIPv6_TUNNEL_PORT] $decap_ return $lma }

PMIPv6 Initialization (5/8)


MAG NIST settings: bssid, channel, beacon install-mag set-lmaa : LMA Address 802.11 MAC trigger
set mag1 [$ns node 3.0.0] $mag1 random-motion 0 $mag1 set X_ 100.0 $mag1 set Y_ 200.0 $mag1 set Z_ 0.0 #NIST settings set mag1_mac [$mag1 getMac 0] set mag1_addr [$mag1_mac id] $mag1_mac bss_id $mag1_addr $mag1_mac set-channel 1 $mag1_mac enable-beacon #install PMIPv6/MAG agent to the MAG1 set mag1_pm [$mag1 install-mag] set lmaa [$lma node-addr] $mag1_pm set-lmaa [AddrParams addr2id $lmaa] #setup 802.11 MAC to support MN ATTACH Event $mag1_mac set use_pmip6_ext_ 1 $mag1_mac pmip6-agent $mag1_pm $ns duplex-link $mag1 $router 100Mb $opt(dfLinkDelay) DropTail

PMIPv6 Initialization (6/8)


MAG (contd)

PMIPv6 Initialization (7/8)


install-mag
Node instproc install-mag {} { $self instvar classifier_ dmux_ agents_ ll_ $self instvar pmip6_agent_ $self instvar src_classifier_ old_classifier_ $self instvar decap_ set mag [new Agent/PMIPv6/MAG] $self attach $mag [$mag set default_port_] set pmip6_agent_ $mag #attach src classifier set old_classifier_ $classifier_ set src_classifier_ [new Classifier/Addr/PMIPv6Src] $src_classifier_ set mask_ 0xffffffff $src_classifier_ set shift_ 0 $src_classifier_ defaulttarget $old_classifier_

PMIPv6 Initialization (8/8)


install-mag (contd)
set nodetype [[Simulator instance] get-nodetype] $self insert-entry [$self get-module $nodetype] $src_classifier_ $src_classifier_ install-by-src 0 $old_classifier_ #attach decap_ set decap_ [new Classifier/Addr/PMIPv6Decapsulator] $decap_ set mask_ 0xffffffff $decap_ set shift_ 0 lappend $agents_ $decap_ $dmux_ install [Simulator set PMIPv6_TUNNEL_PORT] $decap_ # LL points previous hier_classifier as up-target # we should change this to our classifier if {[info exists ll_(0)] && $ll_(0) != ""} { $ll_(0) up-target $src_classifier_ } return $mag }

Binding Update Process (1/3)


Sending PBU
Mac802_11 MAGAgent PMIPv6Agent new-mn/TCL command()

process_new_mn() -find_bule

send_pbu() create_pbu()

send()

Binding Update Process (2/3)


Receiving PBU/Sending PBACK
PMIPv6Agent LMAAgent recv() process_packet() process_pbu() -find_bce()

setup_route()

setup-route/TCL -get-pmip6-encap/TCL send_pback() create_pback() send()

Binding Update Process (3/3)


Receiving PBACK
PMIPv6Agent MAGAgent recv() process_packet() process_pback() -find_bule()

bule_state: BUL_S_SETUP

setup_route()

setup-route/TCL -get-pmip6-encap/TCL clear_route()

bule_state: BUL_S_DELETE

clear-route/TCL

Data Process (1/2)


LMA MAG
PMIPv6Dest recv() classify() recv() target_->recv() recv() find() PMIPv6Encapsulator PMIPv6Decapsulator

link->recv()

Data Process (2/2)


MAG LMA
PMIPv6Src recv() classify() recv() target_->recv() recv() find() PMIPv6Encapsulator PMIPv6Decapsulator

link->recv()

802.11 MAC Operation (1/5)


802.11 MAC Layer 2 Trigger
Mac802_11 MAGAgent PMIPv6Agent new-mn/TCL command()

process_new_mn() -find_bule

send_pbu() create_pbu()

send()

802.11 MAC Operation (2/5)


802.11 MAC class Mac802_11 (ns-2.29/mac/mac-802_11.h)
use_pmip6_ext_: PMIPv6 L2 trigger pmip6_agent_: L2 trigger PMIPv6 agent
class Mac802_11 : public Mac { //PMIPv6 int use_pmip6_ext_; Agent* pmip6_agent_; //End PMIPv6

pmip6-agent
int Mac802_11::command(int argc, const char*const* argv) { else if (strcmp(argv[1], "pmip6-agent") == 0) { if(use_pmip6_ext_==0) return TCL_ERROR; pmip6_agent_ = (Agent *)TclObject::lookup(argv[2]); return TCL_OK; }

802.11 MAC Operation (3/5)


802.11 MAC (contd) 802.11 MAC AP address
inline int Mac802_11::hdr_dst(char* hdr, int dst ) { //PMIPv6 if(dst != bss_id_) STORE4BYTE(&bss_id_, (dh->dh_3a)); //end PMIPv6

Link
void Mac802_11::link_disconnect (link_down_reason_t reason) { //PMIPv6 if(!mih_) { //If disconnected, it automatically starts scanning Tcl& tcl = Tcl::instance(); tcl.evalf ("%s autoscan", name()); } //PMIPv6 end

802.11 MAC Operation (4/5)


802.11 MAC (contd) AP
void Mac802_11::nextScan () { //PMIPv6 if(!mih_) { BSSDescription *n; n=scan_status_.resp->bssDesc_head.lh_first; //store structure scan bssid/channel Vincent Gauthier channelIDAfterScan_[n->bss_id()] = n->channel(); link_connect(n->bss_id()); } //PMIPv6 end

802.11 MAC Operation (5/5)


Layer 2 Trigger AssocRes PMIPv6 agent new-mn
void Mac802_11::recvACK(Packet *p) { //PMIPv6 if(use_pmip6_ext_) { if(pmip6_agent_) { Tcl& tcl = Tcl::instance(); tcl.evalf("%s new-mn %d", pmip6_agent_->name(), n->id()); } } //end PMIPv6

MAG Operation #1 (1/5)


MAG L2 Trigger PBU
Mac802_11 MAGAgent PMIPv6Agent new-mn/TCL command()

process_new_mn() -find_bule

send_pbu() create_pbu()

send()

MAG Operation #1 (1/4)


new-mn process_new_mn
int MAGAgent::command(int argc, const char*const* argv) { else if(argc==3) { if(strcmp(argv[1], "new-mn") == 0) { uint32_t id; id = atoi(argv[2]); process_new_mn(id); return TCL_OK; }

process_new_mn

Binding Update List BUL entry (bule)

PBU retransmission timer PBU (pktPBU_)

MAG Operation #1 (2/4)


process_new_mn (contd)
void MAGAgent::process_new_mn(int32_t mn_id) { BULEntry *bule; bule = find_bule(mn_id); if(!bule) { bule = create_bule(mn_id); bule->lmaa() = lma_addr_; bule->proxy_coa() = addr(); bule->lifetime() = binding_lifetime_; bule->insert_entry(&bul_list_); } else { bule->BULTimer_.cancel(); if(bule->pktPBU_) { Packet::free(bule->pktPBU_); bule->pktPBU_ = 0; } } bule->set_state(BUL_S_SETUP); bule->retry_count_ = 0; send_pbu(bule); }

MAG Operation #1 (3/4)


send_pbu
PMIPv6Agent create_pbu PBU bule PBU Retransmission timer
void MAGAgent::send_pbu(BULEntry *bule) { if(!bule->pktPBU_) { bule->pktPBU_ = create_pbu(bule->lmaa(), bule->mn_id(), bule->lifetime(), bule->proxy_coa()); } send(bule->pktPBU_->copy(), 0); //FIXME: adjust retransmit timeout (Random backoff??) bule->BULTimer_.resched(1.0); }

MAG Operation #1 (4/4)


create_pbu
Packet *PMIPv6Agent::create_pbu( int32_t dst, int32_t mn_id, uint32_t lifetime, int32_t proxy_coa) { Packet *p = allocpkt(); hdr_cmn *hdrc = HDR_CMN(p); hdr_ip *iph = HDR_IP(p); hdr_pmipv6 *h = HDR_PMIPv6(p); hdrc->size() = IPv6_HEADER_SIZE; hdrc->ptype() = PT_PBU; hdrc->size() += PBU_SIZE; iph->saddr() = proxy_coa; iph->sport() = port(); iph->daddr() = dst; iph->dport() = port(); h->H() = 1; h->A() = 1; h->P() = 1; h->type() = PBU; h->seqno() = 0; h->lifetime() = lifetime; h->mn_id() = mn_id; h->coa() = proxy_coa; h->haddr() = -1; h->status() = 0; return p; }

LMA Operation (1/7)


Receiving PBU/Sending PBACK
PMIPv6Agent LMAAgent recv() process_packet() process_pbu() -find_bce()

setup_route()

setup-route/TCL -get-pmip6-encap/TCL send_pback() create_pback() send()

LMA Operation (2/7)


PMIPv6Agent recv
PBU IP dest port recv void PMIPv6Agent::recv(Packet* p, Handler *) { hdr_cmn *hdrc = HDR_CMN(p);
int ptype; ptype = hdrc->ptype(); if((ptype==PT_PBU && strcmp(node_info_, "LMA")==0) || (ptype==PT_PBACK && strcmp(node_info_, "MAG")==0)) { process_packet(p); } else { fprintf(stderr, "%s received packet with wrong type %d\n", node_info_, ptype); Packet::free(p); } }

LMA Operation (3/7)


process_packet virtual , LMAAgent MAGAgent override void LMAAgent::process_packet(Packet *p) { process_pbu
hdr_cmn *ch = HDR_CMN(p); if(ch->ptype() == PT_PBU) { process_pbu(p); } Packet::free(p); }

process_pbu Binding cache , lifetime Lifetime Routing PBACK

LMA Operation (4/7)


process_pbu (contd)
void LMAAgent::process_pbu(Packet *p) { hdr_ip *iph = hdr_ip::access(p); hdr_pmipv6 *h = hdr_pmipv6::access(p); int mn_id, mnaddr; BCacheEntry *bce; if(h->lifetime()==0 && bce->proxy_coa()!=iph->saddr()) { send_pback(p, 0); return; } bce->lifetime() = h->lifetime(); if(bce->lifetime()>0) setup_route(bce); else clear_route(bce); send_pback(bce, 0); bce->BCacheTimer_.resched( (double)bce->lifetime()); }

mn_id = h->mn_id(); bce = find_bce(mn_id); if(!bce) { if(h->lifetime()==0) { send_pback(p, 0); return; } if((mnaddr=find_mn_prefix(mn_id))==-1) { send_pback(p, 1); return; } bce = create_bce(mn_id); bce->proxy_coa() = iph->saddr(); bce->mn_prefix() = mnaddr; bce->insert_entry(&bcache_list_); }

LMA Operation (5/7)


setup_route : tcl setup-route setup-route (TCL) MN PMIPv6Encapsulator PMIPv6Dest classifier
Agent/PMIPv6/LMA instproc setup-route { mnaddr te } { $self instvar node_ #encap settings set clsfr_dst [$node_ set dst_classifier_] set encap [$node_ get-pmip6-encap $te] $clsfr_dst install-by-dest $mnaddr $encap }

LMA Operation (6/7)


get-pmip6-encap (TCL) Tunneling endpoint(te) PMIPv6Encapsulator TE ,
Node instproc get-pmip6-encap { te } { $self instvar address_ Encaps_ if {[info exists Encaps_($te)] && $Encaps_($te) != ""} { return $Encaps_($te) } set Encaps_($te) [new PMIPv6Encapsulator] $Encaps_($te) set addr_ [AddrParams addr2id $address_] $Encaps_($te) set port_ [Simulator set PMIPv6_TUNNEL_PORT] $Encaps_($te) set dest_addr_ $te $Encaps_($te) set dest_port_ [Simulator set PMIPv6_TUNNEL_PORT] $Encaps_($te) target [$self entry] $Encaps_($te) set node_ $self return $Encaps_($te) }

LMA Operation (7/7)

MAG Operation #2 (1/5)


Receiving PBACK
PMIPv6Agent MAGAgent recv() process_packet() process_pback() -find_bule()

bule_state: BUL_S_SETUP

setup_route()

setup-route/TCL -get-pmip6-encap/TCL clear_route()

bule_state: BUL_S_DELETE

clear-route/TCL

MAG Operation #2 (2/5)


process_pback
bule , routing
void MAGAgent::process_pback(Packet* p) { hdr_pmipv6 *h = hdr_pmipv6::access(p); BULEntry *bule; bule = find_bule(h->mn_id()); //Stop retransmit timer bule->BULTimer_.cancel(); bule->mn_prefix() = h->haddr(); bule->lifetime() = h->lifetime(); switch(bule->get_state()) { case BUL_S_SETUP: setup_route(bule); //fall through case BUL_S_REFRESH: //Update lifetime for binding refresh bule->BULTimer_.resched( (double)bule->lifetime()*.9); if(bule->pktPBU_) { Packet::free(bule->pktPBU_); bule->pktPBU_ = 0; } bule->set_state(BUL_S_ESTABLISHED); break; case BUL_S_DELETE: clear_route(bule); bule->remove_entry(); delete bule; break; } }

MAG Operation #2 (3/5)


setup-route (TCL) PMIPv6Decapsulator MN link
MN adhoc routing protocol target MN link target

MN PMIPv6Encapsulator PMIPv6Src classifier

MAG Operation #2 (4/5)


setup-route (TCL) (contd)
Agent/PMIPv6/MAG instproc setup-route { mnaddr te} { $self instvar node_ set ns [Simulator instance] set decap_ [$node_ set decap_] if {[$node_ info class] == "MobileNode/MIPBS" || [$node_ info class] =="Node/MobileNode" } { set target [$node_ set ragent_] } else { set target [[$ns link $node_ [$ns get-node-by-addr $mnaddr]] head] if {$target==""} { puts "cannot find target } } $decap_ install $mnaddr $target set clsfr_src [$node_ set src_classifier_] set encap [$node_ get-pmip6-encap $te] $clsfr_src install-by-src $mnaddr $encap }

MAG Operation #2 (5/5)

Encap/Decap Operation (1/3)


PMIPv6Src Classifier IP source address hash classify PMIPv6Dest
int PMIPv6Src::classify(Packet *p) { hdr_ip* iph = hdr_ip::access(p); return mshift(iph->saddr()); }

address classifier

Encap/Decap Operation (2/3)


PMIPv6Encapsulator recv
MAG LMA setup-route(TCL) MN data packet PMIPv6Encapsulator recv
void PMIPv6Encapsulator::recv(Packet* p, Handler *h) { hdr_cmn* ch = hdr_cmn::access(p); hdr_ip* hdr = hdr_ip::access(p); hdr_ip6encap *enh = HDR_IP6ENCAP(p); if (--hdr->ttl_ <= 0) { Packet::free(p); return; } enh->hdr_ = *hdr; enh->ptype_ = ch->ptype(); hdr->saddr() = here_.addr_; hdr->sport() = here_.port_; hdr->daddr() = dest_.addr_; hdr->dport() = dest_.port_; hdr->ttl() = defttl_; ch->size() += IPv6_HEADER_SIZE; target_->recv(p,h); }

Encap/Decap Operation (3/3)


PMIPv6Decapsulator recv

void PMIPv6Decapsulator::recv(Packet* p, Handler *h) { hdr_cmn* ch = hdr_cmn::access(p); hdr_ip *hdr = hdr_ip::access(p); hdr_ip6encap *enh = HDR_IP6ENCAP(p); hdr_ip tmph; tmph = *hdr; *hdr = enh->hdr_; enh->hdr_ = tmph; NsObject* link = find(p); if (link == NULL || hdr->ttl_ <= 0) { printf("Link not found\n"); Packet::free(p); return; } ch->size() -= IPv6_HEADER_SIZE; link->recv(p,h); }

You might also like