9.3.12 源IP字段占用32 bit 。
为源主机的IP地址 。
9.3.13 目标IP字段占用32 bit 。
为目标主机的IP地址 。
9.3.14 选项字段0到40字节 。
对于IP数据报首部来说,其大小必须为4字节的整数倍 。
如果选项字段长度不为4的倍数,则需要用0进行填充 。
在 LwIP 中只识别选项字段,不会处理选项字段的内容 。
该字段在IPv6报文中已经被移除了 。
9.3.15 数据区字段IP 数据报的最后的一个字段,装载着当前IP数据报的数据,是上层协议的数据报 。
9.3.16 对应wireshark包分析
文章插图
9.4 IP首部数据结构注意:网络字节序是大端的 。
ipv4的IP首部数据结构:对应IP首部报文图 。
/* The IPv4 header */struct ip_hdr {/* version / header length */PACK_STRUCT_FLD_8(u8_t _v_hl); /* 版本号字段(4)+首部长度字段(4)单位字 *//* type of service */PACK_STRUCT_FLD_8(u8_t _tos); /* 服务类型TOS字段(8) *//* total length */PACK_STRUCT_FIELD(u16_t _len); /* 总长度字段(16)单位字节 *//* identification */PACK_STRUCT_FIELD(u16_t _id); /* 标识字段字段(16) *//* fragment offset field */PACK_STRUCT_FIELD(u16_t _offset); /* 标志字段(3)+分片偏移量字段(13)单位两字 */#define IP_RF 0x8000U/* 标志字段第一位:字段保留 */#define IP_DF 0x4000U/* 标志字段第二位:不发片掩码 */#define IP_MF 0x2000U/* 标志字段第三位:更多分片掩码 */#define IP_OFFMASK 0x1fffU/* 分片偏移量字段的掩码 *//* time to live */PACK_STRUCT_FLD_8(u8_t _ttl); /* TTL字段(8) *//* protocol*/PACK_STRUCT_FLD_8(u8_t _proto); /* 上层协议类型字段(8) *//* checksum */PACK_STRUCT_FIELD(u16_t _chksum); /* 首部校验和字段(16) *//* source and destination IP addresses */PACK_STRUCT_FLD_S(ip4_addr_p_t src); /* 源IP字段(32) */PACK_STRUCT_FLD_S(ip4_addr_p_t dest); /* 目的IP字段(32) */} PACK_STRUCT_STRUCT;
由于IP首部部分字段的操作涉及到bit,所以lwip也封装出对应的宏操作 。/* 均为网络字节序 *//* Macros to get struct ip_hdr fields: */#define IPH_V(hdr)((hdr)->_v_hl >> 4) /* 获取版本号 */#define IPH_HL(hdr) ((hdr)->_v_hl & 0x0f) /* 获取首部长度字段值 */#define IPH_HL_BYTES(hdr) ((u8_t)(IPH_HL(hdr) * 4)) /* 获取首部长度,单位字节 */#define IPH_TOS(hdr) ((hdr)->_tos) /* 获取服务类型TOS */#define IPH_LEN(hdr) ((hdr)->_len) /* 获取IP数据报总长度 */#define IPH_ID(hdr) ((hdr)->_id) /* 获取标识字段 */#define IPH_OFFSET(hdr) ((hdr)->_offset) /* 获取标志字段+分片偏移量字段 */#define IPH_OFFSET_BYTES(hdr) ((u16_t)((lwip_ntohs(IPH_OFFSET(hdr)) & IP_OFFMASK) * 8U)) /* 获取分片偏移量,单位字节 */#define IPH_TTL(hdr) ((hdr)->_ttl) /* 获取TTL */#define IPH_PROTO(hdr) ((hdr)->_proto) /* 获取协议类型 */#define IPH_CHKSUM(hdr) ((hdr)->_chksum) /* 获取首部校验和字段 *//* Macros to set struct ip_hdr fields: */#define IPH_VHL_SET(hdr, v, hl) (hdr)->_v_hl = (u8_t)((((v) << 4) | (hl))) /* 设置版本号 */#define IPH_TOS_SET(hdr, tos) (hdr)->_tos = (tos) /* 设置服务类型TOS */#define IPH_LEN_SET(hdr, len) (hdr)->_len = (len) /* 设置总长度字段值 */#define IPH_ID_SET(hdr, id) (hdr)->_id = (id) /* 设置标识 */#define IPH_OFFSET_SET(hdr, off) (hdr)->_offset = (off) /* 设置标志字段+分片偏移量字段 */#define IPH_TTL_SET(hdr, ttl) (hdr)->_ttl = (u8_t)(ttl) /* 设置TTL */#define IPH_PROTO_SET(hdr, proto) (hdr)->_proto = (u8_t)(proto) /* 设置协议类型 */#define IPH_CHKSUM_SET(hdr, chksum) (hdr)->_chksum = (chksum) /* 设置首部校验和 */
9.5 网卡路由9.5.1 路由网卡匹配从官方源码看 , 匹配网卡的流程:ip4_route_src()
:- 先函数
LWIP_HOOK_IP4_ROUTE_SRC()
匹配 。 - 然后到
ip4_route()
基函数匹配 。
ip4_route()
:- 多播IP优先匹配多播专用网卡
ip4_default_multicast_netif
。
- 遍历网卡:
- 有效网卡先匹配子网;
- 子网匹配失败就匹配网关,网卡不能有广播能力 。
- 环回IP:如果开启了各个网卡的环回功能,且没有创建环回网卡:
- 说明:因为创建了环回网卡,在遍历链表时,就会把环回IP 127.x.x.x都会匹配到环回网卡 。
- 对于环回IP,优先匹配默认网卡
netif_default
。 - 再遍历网卡,第一个协议栈有效的网卡即可 。
- 钩子匹配:(由用户实现)
- 先
LWIP_HOOK_IP4_ROUTE_SRC(src, dest);
- 再
LWIP_HOOK_IP4_ROUTE(dest);
- 先
- 【第5篇】AI语音简介
- 原神3.0陵薮市朝什么时间开启
- 【Azure 环境】把OpenSSL生产的自签名证书导入到Azure Key Vault Certificate中报错
- 常用类.String类
- cf如何跳上高箱子(cf开什么箱子赚cf点)
- macos monterey描述文件下载_macos monterey描述文件下载地址
- 浏览器怎样清除缓存(浏览器历史清空了怎么恢复)
- 我的世界豹猫怎么驯服,为什么给豹猫喂鱼之后不变成猫
- 支付宝蚂蚁庄园每日答题答案
- 原神90级提纳里毕业面板数值怎么样