IP协议

IPV4协议头固定部分20字节


IPV6协议头固定大小部分为40个字节


通过一个抓包,分析IP头部的校验和如何计算


1-1:version 4位

1-2:头长 4位   此四位表示的是有多少个32位,即有多少个4字节。

第一个字节45,二进制是0100 0101,即可看到前四位表示版本是4,后5位表示头部长度是20个字节,5*4=20.

计算校验和的方法,是将校验和置0,即图中的91 2a, 然后将头部数据每两个字节为一组,进行相加运算,如果结果大于两个字节,再将结果中每两个字节为一组进行加运算,最后得到两个字节的和,将这个和取反,即为IP头部校验和。这个例子相加结果是26ed3, 分两部分加后为6ed5, 取反(即用15去减每一位)得到912a.

TCP/IP详解一书中提到的是所有双字节先取反,再求和,计算结果是一样的,79123 -> 912a.


------------------------------------------------------------------

下面看下编程时用到的地址结构,及其转化。

表示地址的结构体,IPV4的sockaddr_in 是16个字节,其中后8个字节是填充位。

struct sockaddr_in {
  sa_family_t                sin_family;        /* Address family             2字节   */
  unsigned short int        sin_port;        /* Port number                   2字节     */
  struct in_addr        sin_addr;        /* Internet address               4字节 */

  /* Pad to size of `struct sockaddr'.  8字节*/
  unsigned char                __pad[__SOCK_SIZE__ - sizeof(short int) -
                        sizeof(unsigned short int) - sizeof(struct in_addr)];
};

其中sin_addr是一个联合体。

IPV6的sockaddr_in6为28字节

struct sockaddr_in6 {
unsigned short intsin6_family;    /* AF_INET6  2字节*/
__be16 sin6_port;      /* Transport layer port # 2字节 */
__be32 sin6_flowinfo;  /* IPv6 flow information  4字节*/
struct in6_addrsin6_addr;      /* IPv6 address  16字节*/ 
__u32 sin6_scope_id;  /* scope id (new in RFC2553) 4字节 */
};

它们最终要转化的sockaddr为16字节,

struct sockaddr {
sa_family_t sa_family; /* address family, AF_xxx*/
char sa_data[14];/* 14 bytes of protocol address
*/
};

所以IPV4地址结构在转换后会有溢出的部分,但用指针访问依然可以。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值