IPV4 header 格式 + 驱动层手动发包

头部介绍转自 https://ccie.lol/knowledge-base/ipv4-and-ipv6-packet-header/

IPv4 报文头格式及各字段功能

IPv4报头格式

IPv4 报头格式

各字段功能:

1、版本号(Version):长度 4 bit 。标识目前采用的 IP 协议的版本号。一般的值为 0100(IPv4),0110(IPv6)

版本号 版本 RFC 文档
0 保留
1~3 未分配
4 Internet 协议版本 4(IPv4) RFC791
5 ST 数据报(Datagram) RFC1190
6 简单 Internet 协议(SIP)
6 IPv6 RFC1883
7 TP / IX RFC1475
8 P Internet 协议(PIP) RFC1621
9 使用更大地址的 TCP 和 UDP(TUBA) RFC1347
10~14 未分配
15 保留

2、IP 报头长度(Header Length):长度 4 bit 。这个字段的作用是为了描述 IP 报头的长度,因为在 IP 报头中有变长的可选部分。该部分占 4 个 bit,长度单位为 4 个字节,即本区域值 = IP 头部长度(单位为字节)/ 长度单位(4 个字节)。因此,一个 IP 报头的长度最长为 “ 1111 ”,即 15 x 4 个字节 = 60 个字节。IP 报头最小长度为 20 字节。

Header Length Header Length 所代表的实际的 IP 报头长度
0101 20 字节
0110 24 字节
0111 28 字节
1101 52 字节
1110 56 字节
1111 60 字节

3、服务类型(Type of Service):长度 8 bit 。8 位按位被如下定义:PPP DTRC0(更多详细信息可以参见 RFC1340 和 RFC1349)

  • PPP:前 3 位,定义包的优先级,取值越大数据越重要
    • 000 普通(Routine)
    • 001 优先的(Priority)
    • 010 立即的发送(Immediate)
    • 011 闪电式的(Flash)
    • 100 比闪电还闪电式的(Flash Override)
    • 101 CRI / TIC / ECP(找不到这个词的翻译)
    • 110 网间控制(Internetwork Control)
    • 111 网络控制(Network Control)
  • DTRCO:后 5 位
    • D 时延:0:普通,1:延迟尽量小
    • T 吞吐量:0:普通,1:流量尽量大
    • R 可靠性:0:普通,1:可靠性尽量大
    • M 传输成本:0:普通,1:成本尽量小
    • 0 最后一位被保留,恒定为 0

4、IP 包总长度(Total Length):长度 16 bit 。以字节为单位计算的 IP 包的长度(包括头部和数据),所以 IP 包最大长度 65 535 字节。所以,数据包有效载荷的大小 = IP 包总长度(Total Length)- IP 报头长度(Header Length)。

5、标识符(Identifier):长度 16 bit 。该字段和 Flags 和 Fragment Offest 字段联合使用,对较大的上层数据包进行分段(fragment)操作。路由器将一个包拆分后,所有拆分开的小包被标记相同的值,以便目的端设备能够区分哪个包属于被拆分开的包的一部分。

6、标记(Flags):长度 3 bit 。

  • 该字段第一位不使用。
  • 第二位是 DF(Don’t Fragment)位,DF 位设为 1 时表明路由器不能对该上层数据包分段。如果一个上层数据包无法在不分段的情况下进行转发,则路由器会丢弃该上层数据包并返回一个错误信息。
  • 第三位是 MF(More Fragments)位,当路由器对一个上层数据包分段,则路由器会在除了最后一个分段的 IP 包的报头中将 MF 位设为 1 。

IPv4报头格式(中文解释)

IPv4 报头格式(中文解释)

7、片偏移(Fragment Offset):长度 13 bit,以 8 个八位组为单位。表示该 IP 包在该组分片包中位置,接收端靠此来组装还原 IP 包。

8、生存时间(TTL):长度 8 bit,设计之初是以秒(s)为单位的,但实际以跳数为单位,建议的缺省值为 64 。当 IP 包进行传送时,先会对该字段赋予某个特定的值。当 IP 包经过每一个沿途的路由器的时候,每个沿途的路由器会将 IP 包的 TTL 值减少 1 。如果 TTL 减少为 0,则该 IP 包会被丢弃。这个字段可以防止由于路由环路而导致 IP 包在网络中不停被转发。

9、协议(Protocol):长度 8 bit 。标识了上层所使用的协议。以下是比较常用的协议号:1 ICMP;2 IGMP;6 TCP;17 UDP;88 IGRP;89 OSPF 。(更多协议号请点击这里:IP协议号汇总)

10、头部校验(Header Checksum):长度 16 bit 。用来做 IP 头部的正确性检测,但不包含数据部分。 因为每个路由器要改变 TTL 的值,所以路由器会为每个通过的数据包重新计算这个值(RFC1141 讨论了一些简化计算的策略)。

11、起源和目标地址(Source and Destination Addresses):这两个地址都是 32 bit 。标识了这个 IP 包的起源和目标地址。要注意除非使用 NAT,否则整个传输的过程中,这两个地址不会改变。

12、可选项(Options):这是一个可变长的字段。该字段属于可选项,主要用于测试,由起源设备根据需要改写。可选项目包含以下内容:

  • 松散源路由(Loose source routing):给出一连串路由器接口的 IP 地址。IP 包必须沿着这些 IP 地址传送,但是允许在相继的两个 IP 地址之间跳过多个路由器。
  • 严格源路由(Strict source routing):给出一连串路由器接口的 IP 地址。IP 包必须沿着这些 IP 地址传送,如果下一跳不在 IP 地址表中则表示发生错误。
  • 路由记录(Record route):当 IP 包离开每个路由器的时候记录路由器的出站接口的 IP 地址。
  • 时间戳(Timestamps):当 IP 包离开每个路由器的时候记录时间。
  • 填充(Padding):因为 IP 报头长度(Header Length)部分的单位为 32 bit,所以 IP 报头的长度必须为 32 bit 的整数倍。因此,在可选项后面,IP 协议会填充若干个 0,以达到 32 bit 的整数倍。

实际抓包:

char buf[256] = { 0xd4,0x62,0xea,0x26,0x75,0xe7,0x00,0x00,0xca,0x00,0x72,0x2b,0x08,0x00,0x45,0x00, 0x00,0x54,0x04,0xa4,0x40,0x00,0x40,0x01,0x5e,0x40,0xc0,0xa8,0x2b,0x73,0xc0,0xa8, 0x2b,0x01,0x08,0x00,0x2e,0xd4,0x00,0x01,0x00,0x02,0x78,0xd6,0x7e,0x5f,0xd9,0xef, 0x0d,0x00,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15, 0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25, 0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35, 0x36,0x37 };

s32 send _testpkt(struct net_device *ndev, u32 level

{
dhd_info_t *dhd = DHD_DEV_INFO(ndev);
int ret;
struct sk_buff *skb_p;

skb_p = netdev_alloc_skb(ndev, 256);

memcpy(skb_p->data, buf, 256);
WL_ERR(("cyx skb_p->len=%d datalen=%d\n", skb_p->len,skb_p->data_len));
if (skb_p->len == 0)
skb_p->len = 256;

skb_p->data_len = 0;

WL_ERR(("cyx wl_cfg80211_set_dbg_verbose 1"));
ret = __dhd_sendpkt(&dhd->pub, 0, skb_p );

return BCME_OK;
}

[ 289.367074@1] cyx dhd_dump_pkt ether_type =0x800
[ 289.372059@1] cyx pktbuf buf=ffffffc02572fd00
[ 289.376088@1] [dhd-wlan0] cyx PING REQUEST [TX] : 192.168.43.115(00:00:ca:00:72:2b) -> 192.168.43.1(d4:62:ea:26:75:e7) SEQNUM=2 TX_PKTHASH:0x0 TX_PKT_FATE:TX_PKT_FATE_ACKED
[ 289.391529@1] DHD IP::
[ 289.393883@1] 0000: d4 62 ea 26 75 e7 00 00 ca 00 72 2b 08 00 45 00
[ 289.400339@1] 0010: 00 54 04 a4 40 00 40 01 5e 40 c0 a8 2b 73 c0 a8
[ 289.406844@1] 0020: 2b 01 08 00 2e d4 00 01 00 02 78 d6 7e 5f d9 ef
[ 289.413346@1] 0030: 0d 00 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15
[ 289.419841@1] 0040: 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25
[ 289.426339@1] 0050: 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35
[ 289.432839@1] 0060: 36 37 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 289.439356@1] 0070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 289.445857@1] 0080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 289.452350@1] 0090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 289.458873@1] 00a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 289.465348@1] 00b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 289.471840@1] 00c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 289.478339@1] 00d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 289.484839@1] 00e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 289.491342@1] 00f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00