2013年2月16日 星期六

IP Header其實很多平台不一樣


IP header format defined in RFC 791:
 
   0                   1                   2                   3   
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |Version|  IHL  |Type of Service|          Total Length         |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |         Identification        |Flags|      Fragment Offset    |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |  Time to Live |    Protocol   |         Header Checksum       |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                       Source Address                          |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                    Destination Address                        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                    Options                    |    Padding    |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+


IP header data sturcture in Linux:
/*  /usr/include/netinet/ip.h  */


struct iphdr
  {
#if __BYTE_ORDER == __LITTLE_ENDIAN
    unsigned int ihl:4;
    unsigned int version:4;
#elif __BYTE_ORDER == __BIG_ENDIAN
    unsigned int version:4;
    unsigned int ihl:4;
#else
# error "Please fix <bits/endian.h>"
#endif
    u_int8_t tos;
    u_int16_t tot_len;
    u_int16_t id;
    u_int16_t frag_off;
    u_int8_t ttl;
    u_int8_t protocol;
    u_int16_t check;
    u_int32_t saddr;
    u_int32_t daddr;
    /*The options start here. */
  };


IP header data structure in ns2:
/*    src/ns-<ver>/common/ip.h  */

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_; }
    inline static hdr_ip* access(const Packet* p) {
        return (hdr_ip*) p->access(offset_);
    }



IP header data structure in GloMoSim:
typedef struct ip {
    unsigned int ip_v:3,        /* version */
                 ip_hl:5,       /* header length */
                 ip_tos:8,      /* type of service */
                 ip_len:16;     /* total length */
    
    unsigned int ip_id:16,
                 ip_reserved:1,
                 ip_dont_fragment:1,
                 ip_more_fragments:1,
                 ip_fragment_offset:13;
                 
    unsigned char  ip_ttl;      /* time to live */
    unsigned char  ip_p;        /* protocol */
    unsigned short ip_sum;      /* checksum */
    long    ip_src,ip_dst;      /* source and dest address */
    
} IpHeaderType;


IP header data structure in OPNET:

/*  Data structure for fields in the */
/*  ip datagram.     */
typedef struct
    {
 OpT_Packet_Size  orig_len;
 int    ident;
 OpT_Packet_Size  frag_len; /* payload_length for IPv6 */
        /* For IPv6 pkts this does not include the length */
        /* of the fragmentation header.     */
 int    ttl;  /* hop_limit for IPv6  */
 InetT_Address    src_addr;
 InetT_Address    dest_addr;
 int    protocol; /* next_hdr for IPv6  */
 int    tos;  /* traffic_class for IPv6 */
 int    offset;  /* The offset of this fragment */


 /* The following two fields are for ECN - RFC#3168. */
 /* The ECT field is set in the datagram only if the */
 /* transport protocol is capable of handling the */
 /* explicit congestion notification.  The CE bit */
 /* actually contains information about congestion. */ 
 int     CE;
 int     ECT;

 /* The remaining fields are for  */
 /* simulation efficiency, and are  */
 /* not actual fields in a packet. */
 int    frag;
 int    connection_class;
 int    src_internal_addr;
 int    dest_internal_addr;
 IpT_Compression_Method  compression_method;
 OpT_Packet_Size    original_size;
 OpT_uInt8    options_field_set; /* Boolean field, uint8 is being used to conserve memory. */
 OpT_uInt8    tunnel_pkt_at_src; /* Boolean set to true in outer pkt at src of tunnel  */
 double    decompression_delay;
 InetT_Address  next_addr;

 /* The tunnel destination ip address*/
 /* is used to tunnel an ip datagram */
 /* in ip in the case of voluntary   */
 /* tunneling. It is NOT a standard  */
 /* field in ip.                     */
 InetT_Address    tunnel_end_addr;
 InetT_Address    net_addr_tunneled;
 void*    tunnel_ptr;
 double     tunnel_start_time;

 /* VPN Stamp time to hold the time when packet enters a VPN */
 double    vpn_stamp_time;
 
 /* Mobile IP related fields */
 int     icmp_type;
 int     encap_count;

 /* IPv6 extension headers container. */ 
 IpT_Ipv6_Extension_Headers_Data* ipv6_extension_hdr_info_ptr; 

    /* Field to store source stat handle, Number of Hops */
    Stathandle*    src_num_hops_stat_hndl_ptr;

 /* This field tells whether the packet has already been decrypted */
 /* by a HAIPE device and is being "re-recieved" on the same interface */
 Boolean    haipe_processing_performed;
 } IpT_Dgram_Fields;





Linux data structure defines fields in bits while simulators define them in common C data types other than bits. Since Linux, which directly runs on hardware, benefits from bit operation. But simulators cannot. So there's no need to bother fields in bits.

Comparing the structures in ns2 and OPNET, we find OPNET struture much more complex, since it supports many technologies in its IP module, including IP tunneling, MPLS, VPN, etc.

參考資料:
http://my.opera.com/Illidan/blog/ip-header-data-structure

沒有留言:

張貼留言