[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: fragmentation/reassembly functions at link layer
I'm forwarding Nguyen's modifications as an FYI to the original
authors and ns-users, since it's text.
Archive of the latest original code I could find is at:
http://www.ee.surrey.ac.uk/Personal/L.Wood/ns/sar_dist_oct2298.tar.gz
since it's not currently available at ftp://cc-lab.u-aizu.ac.jp/pub/
(Nguyen - that is later than what I previously found and sent you,
mostly with some minimal trace additions. You might want to stick
some comments in your code identifying your modifications, too...)
Comments, anyone?
cheers,
L.
<[email protected]>PGP<http://www.ee.surrey.ac.uk/Personal/L.Wood/>
---------- Forwarded message ----------
Date: Tue, 29 Jun 1999 13:08:56 +0100
From: Nguyen Huu Thanh <[email protected]>
To: Lloyd Wood <[email protected]>
Subject: Re: fragmentation/reassembly functions at link layer
Dear Lloyd,
Thank you very much for the code you shiped me. I find it very useful
and decided to use this model. However, I think that this code has some
following disadvantages:
- All header informations of original packets except hdr_cmn, hdr_ip and
hdr_rtp are lost due to the fact that the Agent/Pass and Agent/Sar must
allocate new packets each time they receive an original packet.
- Such performance as end-to-end delay cannot be traced, also due to the
above-mentioned matter.
- Agent/Pass can only classify CBR traffic.
I have modified the code to overcome these problems. At the segmentation
node, I send the original packet at the end of the cell period and
simply change the packet size and packet type. These informations are
restored at the reassembly node. The packet is then directed to the sink
by modifying its destination address in the ip header. I attache here
the modified code. Let me know if you have any comment (you can make a
test by running the original example.tcl).
Best regards,
Nguyen Huu Thanh
Lloyd Wood wrote:
> I thought fragmentation and reassembly was a done thing in third-party
> code - although this does it via an agent rather than at link level.
> Let me know if the attached code is of any use.
>
> ns2.1b2, segmentation and reassembly at link layer - may need to email
> Behcet Sarikaya
> ([email protected]) or Yukio Hashimoto ([email protected])
> previously available from ftp://cc-lab.u-aizu.ac.jp/pub/
>
> And then there's the ATM work you'll find mentioned on:
> http://www.ee.surrey.ac.uk/Personal/L.Wood/ns/
> for ns 1 though.
--
------------------------------------------------
Nguyen Huu Thanh
Universitaet der Bundeswehr Muenchen
Institut fuer informationstechnische Systeme
Werner-Heisenberg-Weg 39
85577 Neubiberg
Tel.: +49 89 6004-2279
Email: [email protected]
-------------------------------------------------
/*
* File: pass.cc
* date: July, 1998
* Author: Yukio Hashimoto
Thanks to Marc Greis ([email protected])
*
*/
#include "agent.h"
#include "tclcl.h"
#include "packet.h"
#include "ip.h"
#include "sar.h"
#include "rtp.h"
#include <iostream.h>
class PassAgent : public Agent {
public:
PassAgent();
int command(int argc, const char*const* argv);
void recv(Packet*, Handler*);
protected:
int off_sar_;
NsObject* dst;
int off_rtp_;
};
static class PassClass : public TclClass {
public:
PassClass() : TclClass("Agent/Pass") {}
TclObject* create(int, const char*const*) {
return (new PassAgent());
}
} class_pass;
PassAgent::PassAgent() : Agent(PT_PASS)
{
bind("off_sar_", &off_sar_); // important to access sar packets
bind("off_rtp_", &off_rtp_);
}
int PassAgent::command(int argc, const char*const* argv)
{
if (argc == 3) {
if (strcmp(argv[1], "dst") == 0) {
Agent* a = (Agent*)TclObject::lookup(argv[2]);
dst=a;
// command has been processed */
return (TCL_OK);
}
}
// If the command hasn't been processed by PassAgent()::command,
// call the command() function for the base class
return (Agent::command(argc, argv));
}
void PassAgent::recv(Packet* pkt, Handler*)
{
// Access the IP header for the received packet:
hdr_cmn* hdrcmn = (hdr_cmn*)pkt->access(off_cmn_);
if(hdrcmn->ptype() != PT_SAR){ // to lower layer
dst->recv(pkt,(Handler*)0);
} else { // from lower layer
// Access the Pass header for the received packet:
hdr_sar* hdra = (hdr_sar*)pkt->access(off_sar_);
hdr_cmn* header_common_ = (hdr_cmn*)pkt->access(off_cmn_);
header_common_->ptype() = hdra->packet_type_; // return the original type
//Packet* p = allocpkt();
//hdr_cmn* hdrcmn2 = (hdr_cmn*)p->access(off_cmn_);
//hdrcmn2->size()=hdra->pkt_size;
//hdrcmn2->ptype() = hdra->packet_type_;
hdr_ip* hdrip = (hdr_ip*)pkt->access(off_ip_);
//*hdrip= hdra->IP;
//hdrip->src() = addr_;
hdrip->dst() = dst_; // modification of the ip destination
//hdrip->ttl() = defttl_;
//hdr_rtp* rh = (hdr_rtp*)p->access(off_rtp_);
//hdr_rtp* rh_from = (hdr_rtp*)pkt->access(off_rtp_);
//*rh = *rh_from; // copy rtp info
send(pkt,0);
//Packet::free(pkt);
}
}
/*
* File: Code for a 'Sar' Agent Class
* date: July, 1998
* Author: Yukio Hashimoto
* Thanks to Marc Greis ([email protected])
*
*/
#include <stdio.h>
#include <math.h>
#include "sar.h"
#include "rtp.h"
#include "tcp.h"
#include <iostream.h>
static class SarClass : public TclClass {
public:
SarClass() : TclClass("Agent/Sar") {}
TclObject* create(int, const char*const*) {
return (new SarAgent());
}
} class_sar;
SarAgent::SarAgent() : Agent(PT_SAR), sar_timer_(this), finish_seg(1)
{
bind("packetSize_", &size_);
bind("off_sar_", &off_sar_);
bind("off_rtp_", &off_rtp_);
bind("off_tcp_", &off_tcp_);
finish_seg=1;
}
int SarAgent::command(int argc, const char*const* argv)
{
if (argc == 3) {
if (strcmp(argv[1], "dst") == 0) {
Agent* a = (Agent*)TclObject::lookup(argv[2]);
dst=a;
/*
// Create a new packet
Packet* pkt = allocpkt();
// Access the Sar header for the new packet:
hdr_sar* hdr = (hdr_sar*)pkt->access(off_sar_);
// Set the 'ret' field to 0, so the receiving node knows
// that it has to generate an echo packet
hdr->ret = 0;
// Store the current time in the 'send_time' field
hdr->send_time = Scheduler::instance().clock();
// Send the packet
send(pkt, 0);
// 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 SarAgent()::command,
// call the command() function for the base class
return (Agent::command(argc, argv));
}
void SarAgent::recv(Packet* pkt, Handler*)
{
// Access the IP header for the received packet:
hdr_cmn* hdrcmn = (hdr_cmn*)pkt->access(off_cmn_);
hdr_ip* hdrip = (hdr_ip*)pkt->access(off_ip_);
hdr_rtp* rh_from = (hdr_rtp*)pkt->access(off_rtp_);
if(hdrcmn->ptype() == PT_SAR){// to upper layer
// reassembly
// Access the Sar header for the received packet:
hdr_sar* hdr = (hdr_sar*)pkt->access(off_sar_);
if(hdr->total_cell_num == hdr->cell_num) {
//Packet* p = allocpkt();
//hdr_sar* hdr3 = (hdr_sar*)p->access(off_sar_);
//hdr_cmn* header_common_ = (hdr_cmn*)p->access(off_cmn_);
//header_common_->size() = hdr->pkt_size; // restore the original size
hdrcmn->size() = hdr->pkt_size; // restore the original size
//hdr3->pkt_size=hdr->pkt_size;
//hdr3->packet_type_ = hdr->packet_type_;
// kokowa test
//hdr_rtp* rh = (hdr_rtp*)p->access(off_rtp_);
//*rh= *rh_from;
//dst->recv(p,(Handler*)0);
dst->recv(pkt,(Handler*)0);
}else {
//cout << "discard";
Packet::free(pkt);
}
//Packet::free(pkt);
} else { // from upper layer
// segmentation
sar_timer_.resched(0.2);
while (finish_seg == 0) {
cout << "wait "<< endl ;
} // do nothing
int psize=hdrcmn->size(); // read packet size
packet_t org_ptype_=hdrcmn->ptype();
int cell_num =(int)ceil((double)psize/58.0); // required num of 58 byte S cells (total 64 bytes)
for(int i=0; i< cell_num-1; i++) {
Packet* c = allocpkt();
hdr_sar* hdr_sar1 = (hdr_sar*)c->access(off_sar_);
hdr_sar1->total_cell_num=cell_num;
hdr_sar1->cell_num=i+1;
//cout << i << "th iteration" << endl;
send(c,0);
}
// last cell
//Packet* c=allocpkt();
hdr_sar* hdr2 = (hdr_sar*)pkt->access(off_sar_);
hdr2->total_cell_num=cell_num;
hdr2->cell_num=cell_num;
hdr2->IP = *hdrip;
//hdr_sar* hdr2 = (hdr_sar*)c->access(off_sar_);
//hdr2->total_cell_num=cell_num;
//hdr2->cell_num=cell_num;
//hdr2->IP = *hdrip;
// save the original size and type in sar header
hdr2->pkt_size=psize;
hdr2->packet_type_=org_ptype_;
//hdr2->pkt_size=psize; // put IP size info
//hdr2->packet_type_=org_ptype_; // save the original packet type
//hdr_rtp* rh = (hdr_rtp*)c->access(off_rtp_);
//*rh = *rh_from; // copy rtp info
// modify the packet size and type
hdrcmn->ptype() = type_;
hdrcmn->size() = size_;
// modify the ip destination
hdrip->dst() = dst_;
//send(c,0);
send(pkt,0);
//Packet::free(pkt);
}
}
void Sar_Timer::expire(Event *e) {
a_->timeout(0);
}
void SarAgent::timeout(int)
{
finish_seg=1;
}
/*
* File: sar.h
* date: July 1998
* Author: Yukio Hashimoto
Thanks to Marc Greis ([email protected])
*
*/
#ifndef ns_sar_h
#define ns_sar_h
#include "agent.h"
#include "tclcl.h"
#include "packet.h"
#include "ip.h"
class SarAgent;
class Sar_Timer : public TimerHandler {
public:
Sar_Timer(SarAgent *a) : TimerHandler() { a_ = a; }
virtual void expire(Event *e);
protected:
SarAgent *a_;
};
struct hdr_sar {
char ret;
double send_time;
int total_cell_num;
int cell_num;
int pkt_num;
int pkt_size;
struct hdr_ip IP;
int seqno_;
packet_t packet_type_;
int& seqno() {
return (seqno_);
}
};
class SarAgent : public Agent {
public:
SarAgent();
int command(int argc, const char*const* argv);
void recv(Packet*, Handler*);
void timeout(int);
protected:
Sar_Timer sar_timer_;
int off_sar_;
NsObject* dst;
int off_rtp_;
int off_tcp_;
int finish_seg;
};
static class SarHeaderClass : public PacketHeaderClass {
public:
SarHeaderClass() : PacketHeaderClass("PacketHeader/Sar",
sizeof(hdr_sar)) {}
} class_sarhdr;
#endif