用户态协议栈的设计实现
一 计算机网络各层的数据结构
计算机网络层次为:
计算机网络结构 |
---|
应用层 |
传输层 |
网络层 |
数据链路层 |
物理层 |
以太网(数据链路层)数据帧的结构:
其中数据段的长度为46到1500字节。
以太网数据帧并没有表示长度的字段。主机确定以太网数据帧接收完毕依靠的是主机接收器感受不到电压变换。当接收器感受不到电压的变化时,表明这一帧数据已经接收完成。
IP数据报(网络层)的格式:
UDP协议的数据格式:
ARP协议格式:
将以上数据包的头文件的格式用数据结构的方式表现出来:
#pragma pack(1) //
#define ETH_ADDR_LENGTH 6
struct ethhdr {
unsigned char h_dst[ETH_ADDR_LENGTH];
unsigned char h_src[ETH_ADDR_LENGTH];
unsigned short h_proto; //表示上一层用什么协议
};
struct iphdr {
unsigned char hdrlen:4,//低位
version:4;//高位
unsigned char tos;
unsigned short totlen;
unsigned short id;
unsigned short flag_offset;
unsigned char ttl;//time to live 默认是64
unsigned char type;
unsigned short check;
unsigned int sip;
unsigned int dip;
};
struct udphdr {
unsigned short sport;
unsigned short dport;
unsigned short length;
unsigned short check;
};
struct udppkt {
struct ethhdr eh;
struct iphdr ip;
struct udphdr udp;
unsigned char data[0];//零长数组,柔性数组 1.不关心它的长度;2.它的内存一开始是被分配好的;3。可以计算出它的长度。
};//sizeof(struct udppkt) == 42
struct arphdr {
unsigned short h_type;
unsigned short h_proto;
unsigned char h_addrlen;
unsigned char h_protolen;
unsigned short oper; //请求/响应
unsigned char smac[ETH_ADDR_LEN];
unsigned int sip;
unsigned char dmac[ETH_ADDR_LEN];
unsigned int dip;
}
#pragma pack(1)是用来进行一字节对齐的。字节对齐是指为了使计算器存取变量更快,往往会将变量存储到地址能够整除长度的地址。在结构体内部,为了字节对齐,往往会自动填充空白字节。一字节对齐指的是设置结构体内变量的边界对齐是1字节,即所有数据在内存中是连续存储的,不进行填充。
unsigned char data[0];这是零长数组,也叫做柔性数组。使用柔性数组由三个条件:
1.不关心它的长度;
2.它的内存一开始是被分配好的;
3.可以从程序的其他地方计算出它的长度。
二 net_map介绍
netmap是一个高效的收发报文的I/O框架,需要在Linux下编译使用。运行netmap时,此框架会接管主机的显卡,使显卡的数据发送给内核协议栈处理,转而发送给netmap框架处理。
当netmap框架启动后,显卡中的数据被通过mmap映射到内存中。mmap的映射过程由DMA控制。映射后,用户就能直接操作内存中的网络数据了。
关键函数分析:
nm_open:创建一个指向网卡的文件描述符。
nm_nextpkt:接收网卡中的数据,返回一个指向数据头的指针。
内存接收网卡数据的数据结构:ringbuffer(环形队列)
程序响应网卡新数据的到来靠的是轮询。响应数据的方式有两种,一是轮询,二是事件驱动。轮询的方式适合对大量数据的响应。事件驱动适合对稀疏数据的响应。
三 ARP协议及ARP攻击
ARP协议是将ip地址和mac地址一一对应。在局域网外中,主机相互识别依靠的是ip地址,在局域网中,主机相互识别靠的是mac地址。当外来的数据包通过ip地址找到目的主机所在的局域网后,就需要依靠mac地址在局域网中找到目的主机。
当主机打算将数据发送到局域网中的另一台主机时,主机需要通过目的IP在ARP高速缓存队列中找到对应的目的mac。如果没有相匹配的目的mac地址,主机会自动运行ARP。ARP的步骤如下:
1.ARP进程在本局域网中广播发送一个ARP请求分组,此分组包含本机IP和MAC,以及目的IP;
2.在本局域网上的所有主机上运行的ARP进程都收到此ARP请求分组;
3.如果某主机的IP地址和ARP请求分组中的地址一样,就收下ARP请求分组,并回发一个ARP响应分组,此响应分组中包含本机的MAC。对于与ARP请求分组中的目的IP不一致的主机,则忽略此请求;
4.当本机收到ARP响应分组后,就将目的IP和目的MAC写入ARP高速缓存队列中。
ARP攻击是指在局域网中,有某个主机,会回复任何ARP请求,回复的MAC地址也是错误的,导致本局域网中的主机的ARP高速缓存队列中数据的错误和局域网中充斥大量的ARP请求,使本局域网瘫痪。