文章目录
- LWIP主进程工作
- 链路层
- LWIP数据包收发函数框架
- ARP(地址解析协议)表
- ARP表查询
- IP层
- ICMP处理(Internet 控制报文协议)
- TCPIP_Thread线程启动流程
- **tcpip_thread主线程处理**
LWIP主进程工作
当数据在各层之间传递时,LWIP极力禁止数据的拷贝工作,因为会耗费大量的时间和内存
struct pbuf{
struct pbuf *next;
void *payload;
u16_t tot_len;
u16_t len;
u8_t type;
u8_t flags;
u16_t ref;
};
LWIP没有在各层之间进行严格的划分,各层协议之间有交叉存取。
链路层
netif描述一个硬件网络接口
struct netif{
struct netif *next;
struct ip_addr ip_addr;
struct ip_addr netmask;
struct ip_addr gw;
err_t (*input)(struct pbuf *p, struct netif *inp);
err_t (*output)(struct netif *netif, struct pbuf* p, struct ip_addr *ipaddr);
err_t (*linkoutput)(struct netif *netif, struct pbuf *p);
void *state;
u8_t hwaddr_len;
u8_t hwaddr[NETIF_MAX_HWADDR_LEN];
u16_t mtu;
u8_t flags;
char name[2];
u8_t num;
};
LWIP数据包收发函数框架
low_level_input low_level_output
LWIP应用系统包括三个进程:
- 上层应用程序进程
- LWIP协议栈进程
- 底层硬件数据包接收进程
目标MAC地址 | 源MAC地址 | 类型/长度 | 数据 | 校验 |
---|
6字节 | 6字节 | 2字节(IP:0x0800/ARP:0x0806) | 46-1500字节 | 4字节 |
ps: 最大帧长1518字节,最小64字节
eth_hdr描述以太网数据包包头14个字节
PACK_STRUCT_BEGIN
struct eth_hdr{
PACK_STRUCT_FIELD(struct eth_addr dest);
PACK_STRUCT_FIELD(struct eth_addr src);
PACK_STRUCT_FIELD(u16_t type);
}PACK_STRUCT_STRUCT;
PACK_STRUCT_END
大端模式:某个半字或字数据的高位字节存在内存的低地址端,低位字节存放在内存的高地址端
小端模式:某个半字或字数据的 高位字节存在内存的高地址端,低位字节存放在内存的低地址端
ARM处理器使用的是小端模式;;网络字节数据用的大端模式
ARP(地址解析协议)表
动态映射:将32位的IP地址转换为对应48位的MAC地址
核心:ARP缓存表;对缓存表的建立、更新、查询等操作
struct etharp_entry{
#if ARP_QUEUEING
struct etharp_q_entry *q;
#endif
struct ip_addr ipaddr;
struct eth_addr ethaddr;
enum etharp_state state;
u8_t ctime;
struct netif *netif;
};
enum etharp_state{
ETHARP_STATE_EMPTY = 0,
ETHARP_STATE_PENDING,
ETHARP_STATE_STABLE
};
static struct etharp_entry arp_table[ARP_TABLE_SIZE];
两个字节长的以太网帧类型表示后面数据的类型。对于 ARP 请求或应答数据包来说,
该字段的值为 0x0806,对于 IP 数据包来说,该字段的值为 0x0800。
struct etharp_hdr{
PACK_STRUCT_FIELD(struct eth_hdr ethhdr);
PACK_STRUCT_FIELD(u16_t hwtype);
PACK_STRUCT_FIELD(u16_t proto);
PACK_STRUCT_FIELD(u16_t _hwlen_protolen);
PACK_STRUCT_FIELD(u16_t opcode);
PACK_STRUCT_FIELD(struct eth_addr shwaddr);
PACK_STRUCT_FIELD(struct ip_addr2 sipaddr);
PACK_STRUCT_FIELD(struct eth_addr dhwaddr);
PACK_STRUCT_FIELD(struct ip_addr2 dipaddr);
}PACK_STRUCT_STRUCT;
ARP表查询
ARP攻击,针对是针对以太网地址解析协议( ARP)的一种攻击技术。在局域网中, ARP
病毒收到广播的 ARP 请求包,能够解析出其它节点的 (IP, MAC) 地址, 然后病毒伪装为目
的主机,告诉源主机一个假 MAC 地址,这样就使得源主机发送给目的主机的所有数据包都
被病毒软件截取,而源主机和目的主机却浑然不知。 ARP 攻击通过伪造 IP 地址和 MAC 地
址实现 ARP 欺骗,能够在网络中产生大量的 ARP 通信量使网络阻塞,攻击者只要持续不断
的发出伪造的 ARP 响应包就能更改目标主机 ARP 缓存中的 IP-MAC 条目。 ARP 协议在设
计时未考虑网络安全方面的特性,这就注定了其很容易遭受 ARP 攻击。黑客只要在局域网
内阅读送上门来的广播 ARP 请求数据包,就能偷听到网内所有的 (IP, MAC)地址。而源节
点收到 ARP 响应时,它也不会质疑,这样黑客很容易冒充他人。
static s8_t find_entry(struct ip_addr *ipaddr, u8_t flags)
lwip 有一个比较巧妙的地方 ,LWIP 中有个全局的变量 etharp_cached_entry,它始终保存着上次用到的索引号,如
果这个索引恰好就是我们要找的内容,且索引的表项已经处于 stable 状态,那就直接返回这个索引号就完成了 。
err_t etharp_query(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
static err_t update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *ethaddr, u8_t flags)
IP层
IP 数据报头
struct ip_hdr {
PACK_STRUCT_FIELD(u8_t _v_hl);
PACK_STRUCT_FIELD(u8_t _tos);
PACK_STRUCT_FIELD(u16_t _len);
PACK_STRUCT_FIELD(u16_t _id);
PACK_STRUCT_FIELD(u16_t _offset);
#define IP_RF 0x8000
#define IP_DF 0x4000
#define IP_MF 0x2000
#define IP_OFFMASK 0x1fff
PACK_STRUCT_FIELD(u8_t _ttl);
PACK_STRUCT_FIELD(u8_t _proto);
PACK_STRUCT_FIELD(u16_t _chksum);
PACK_STRUCT_FIELD(struct ip_addr src);
PACK_STRUCT_FIELD(struct ip_addr dest);
} PACK_STRUCT_STRUCT;
ICMP处理(Internet 控制报文协议)
控制消息是指网络通不通、主机是否可达、路由是否可用等网络本身的消息。
TCPIP_Thread线程启动流程
源码文件tcpip.c tcpip.h
tcpip_thread主线程处理
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)