ns2之包结构解析

最近在做ns2的“反移植”工作,深入研究了一下NS2中包的结构,其定义主要在packet.h/cc中实现的,但是有许多代码是为了与TCL接口而设计的。其定义如下:

class Packet : public Event {
private:

 unsigned char* bits_; // header bits
 AppData* data_;  // variable size buffer for 'data'
....

};

 

不得不说,上面两个字段域是Packet最重要的动动,其中bits_存储包头结构,而data_存储用户自定义的数据。但是,NS2其实是一个大而全的仿真平台,它在仿真时其实是将所有或者大多数数据包放在一个包里面,即使当前用不到。比如我们建立一个仿真环境,用来测试两个节点的通过TCP建立连接,然后发送数据,理论上这个仿真中只涉及到TCP/IP的基本存储功能,即应该包括hdr_mac, hdr_ll, hdr_ip, hdr_cmn, hdr_tcp,但是实际得到的包应该如下:

hdr_iphdr_llhdr_cmnhdr_tcphdr_XCP........            data_         

那如何访问数据包中相应的子包呢,可以查看packet.h开始,发现定义了许多宏,如:

#define HDR_CMN(p)      (hdr_cmn::access(p))
#define HDR_ARP(p)      (hdr_arp::access(p))
#define HDR_MAC(p)      (hdr_mac::access(p))
#define HDR_MAC802_11(p) ((hdr_mac802_11 *)hdr_mac::access(p))
#define HDR_MAC_TDMA(p) ((hdr_mac_tdma *)hdr_mac::access(p))
#define HDR_SMAC(p)     ((hdr_smac *)hdr_mac::access(p))
#define HDR_LL(p)       (hdr_ll::access(p))
#define HDR_HDLC(p)     ((hdr_hdlc *)hdr_ll::access(p))
#define HDR_IP(p)       (hdr_ip::access(p))
#define HDR_RTP(p)      (hdr_rtp::access(p))
#define HDR_TCP(p)      (hdr_tcp::access(p))
#define HDR_SCTP(p)     (hdr_sctp::access(p))
#define HDR_SR(p)       (hdr_sr::access(p))
#define HDR_TFRC(p)     (hdr_tfrc::access(p))
#define HDR_TORA(p)     (hdr_tora::access(p))

就是用来访问相应的字段,比如HDR_MAC(p),即可以取得对应的域。而具体如何取则由hdr_***::access来实现。access是每一种包头都包含的,比如hdr_cmn:

 inline static hdr_cmn* access(const Packet* p) {
  return (hdr_cmn*) p->access(offset_);
 }
再看看包Packet的access函数,如下:

 inline unsigned char* access(int off) const {
       if (off < 0)     abort();
       return (&bits_[off]);
 }

到此,基本明白了,offset其实是每个包相对于packet开始的偏移值,通过这个偏移值即可确定其在整个包中的地址。

 

现在问题是,在哪个地方设置这个offset值,搜索了所有的C++代码也没看到对每个包的offset的初始化。经过仔细比较,发现在tcl/lib/ns-lib.tcl中的Simulator初始化init过程中有一个调用:

 $self create_packetformat
接着在ns-packet.tcl中找到了这个函数:

Simulator instproc create_packetformat { } {
 PacketHeaderManager instvar tab_
 set pm [new PacketHeaderManager]
 foreach cl [PacketHeader info subclass] {
  if [info exists tab_($cl)] {
   set off [$pm allochdr $cl]
   $cl offset $off
  }
 }
 $self set packetManager_ $pm
}

 应该是在这个地方实现了offset的初始化,换句话说,是在这个地方指定每个包的offset。设置断点并打印,证实了我的猜想:

PacketHeader/PBC has offset 0
PacketHeader/LRWPAN has offset 8
PacketHeader/XCP has offset 216
PacketHeader/PGM has offset 272
PacketHeader/PGM_SPM has offset 288
PacketHeader/PGM_NAK has offset 296
PacketHeader/Pushback has offset 312
PacketHeader/NV has offset 320
PacketHeader/LDP has offset 328
PacketHeader/MPLS has offset 368
PacketHeader/rtProtoLS has offset 392
PacketHeader/Ping has offset 400
PacketHeader/TFRC has offset 424
PacketHeader/TFRC_ACK has offset 480
PacketHeader/Diffusion has offset 544
PacketHeader/RAP has offset 736
PacketHeader/AOMDV has offset 760
PacketHeader/AODV has offset 1568
PacketHeader/SR has offset 2376
PacketHeader/TORA has offset 3088
PacketHeader/IMEP has offset 3120
PacketHeader/ARP has offset 3632
PacketHeader/MIP has offset 3664
PacketHeader/IPinIP has offset 3696
PacketHeader/LL has offset 3704
PacketHeader/Mac has offset 3736
PacketHeader/Encap has offset 3776
PacketHeader/HttpInval has offset 3784
PacketHeader/SRMEXT has offset 3792
PacketHeader/SRM has offset 3800
PacketHeader/aSRM has offset 3816
PacketHeader/mcastCtrl has offset 3824
PacketHeader/CtrMcast has offset 3848
PacketHeader/rtProtoDV has offset 3864
PacketHeader/GAF has offset 3872
PacketHeader/Snoop has offset 3880
PacketHeader/SCTP has offset 3904
PacketHeader/TCPA has offset 3912
PacketHeader/TCP has offset 3928
PacketHeader/IVS has offset 4008
PacketHeader/RTP has offset 4040
PacketHeader/Message has offset 4056
PacketHeader/Resv has offset 4120
PacketHeader/QS has offset 4136
PacketHeader/UMP has offset 4152
PacketHeader/Src_rt has offset 4168
PacketHeader/IP has offset 4248
PacketHeader/Common has offset 4280
PacketHeader/Flags has offset 4384

实际上,每个包的offset应该为sizeof(hdr_***)。为了验证,写了一个程序测试。比如hdr_ip,

typedef int32_t nsaddr_t;
typedef int32_t nsmask_t;

/* 32-bit addressing support */
struct ns_addr_t {
 int32_t addr_;
 int32_t port_;
};

struct hdr_ip {
 /* common to IPv{4,6} */
 ns_addr_t src_;
 ns_addr_t dst_;
 int  ttl_;

 /* Monarch extn */
  u_int16_t sport_;
  u_int16_t dport_;
 
 /* IPv6 */
 int  fid_; /* flow id */
 int  prio_;

 static int offset_;
 inline static int& offset() { return offset_; }

 /* per-field member acces functions */
 ns_addr_t& src() { return (src_); }
 nsaddr_t& saddr() { return (src_.addr_); }
        int32_t& sport() { return src_.port_;}

 ns_addr_t& dst() { return (dst_); }
 nsaddr_t& daddr() { return (dst_.addr_); }
        int32_t& dport() { return dst_.port_;}
 int& ttl() { return (ttl_); }
 /* ipv6 fields */
 int& flowid() { return (fid_); }
 int& prio() { return (prio_); }
};

int main(int argc, char* argv[])
{

    printf("ip: %d\n", sizeof(hdr_ip));
    printf("tora: %d\n", sizeof(hdr_tora));

    getch();
     return 0;

}
程序的输出验证我的猜想。

packet.h的下面定义则实现了两者间的绑定:

class PacketHeaderClass : public TclClass {
protected:
 PacketHeaderClass(const char* classname, int hdrsize);
 virtual int method(int argc, const char*const* argv);
 void field_offset(const char* fieldname, int offset);
 inline void bind_offset(int* off) { offset_ = off; }
 inline void offset(int* off) {offset_= off;}
 int hdrlen_;  // # of bytes for this header
 int* offset_;  // offset for this header
public:
 virtual void bind();
 virtual void export_offsets();
 TclObject* create(int argc, const char*const* argv);
};

GAL游戏解包工具,含C++源码。 包含181个工具: alb2png amp2bmp ar2bugfix arkcmp2bmp brs2png d3dslide decrbrads decrddns2 decrkansa erisacvt ex1uparc ex4ag exafa exah3pac exakbdat exald exanepak exaos exaqugsp exar2 exarc2 exarc4 exarcw exatuworks exavk exbbbin exbelarc exbelldat_nosrc exbelldat1.02_nosrc exbkarc exbrdat_nosrc exbrpak exbsa exbszdat excandydat excatcab excdt excfarc exchpac excrxb exdaf2 exddp exdebopak exdieslib exdosnpac exdpk exdpmx exdxa exedendp5 exeiarc exescarc exfavbin exfigdat exfleurdat exfp3 exgce3 exgr2 exgsp4 exgxp exhappyend exhdcpak exhecdat exhud exhxp exiar exifdypf exiga exihkcap exisa exk5 exkactive exkhwag exkifint exkiss6dat exkizpak exkkesui exkleinpak exkoigdat exl4osa_nosrc exl5enj_nosrc exl6ren_nosrc exlac exlfa exlfar21 exlibiarc exlnk4 exlrlpk_nosrc exm2lib exmaiarc exmaotarc exmarupac_nosrc exmaspaz exmed exmespac exmhpac exmk2 exmnvdat exmoepack exmornpak exmpf2 exmpk exmpsaf exmugibin exmwpak exnfcel exnllpk_nosrc exnnkarc exnosdat_nosrc exnp4x exnpa exnpf exns2 exoozoarc expatbin expcf expdfpk expf2 expimg expkd expzdat exrlarc_nosrc exrrdat_nosrc exs4alf exscharc_nosrc exsec exsenarc_nosrc exsgnpa exshikidat exsholib exsteldat exsui2rom exszs extafarc extapak extarc extcd3 extensho extk2fpk extmmpck extricgf_nosrc extropak extskfdat exttd extttdpk extvkarc_nosrc exuni2 exunity exutsudat exvcpak exvff exvfs exwatfopck exwhaledat exwlcs exxusegd exyatpkg exykc exyox exzwarc_nosrc gax2png gyu2bmp junk_atled junk_monobeno kamiparadeck lpx2bmp mag2bmp miscbss misceri miscmja nimg2bmp pmchar2bmp ps2force480p spc2bmp sz2png tig2png tits2deck tox2deck toxtweak tpw2bmp_nosrc VisualMemory0.9.5
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值