网络协议栈

目录

  • 网络协议
  • 网络每层做了什么事情
    • 传输层
    • 网络层
    • 链路层
  • 抓包工具
  • code
    • 头文件
    • UDP协议
    • 收发数据

网络协议

网络协议栈_第1张图片
这个七层协议或者五层协议相信大家都很清楚,那么每一层分别做了什么?

网络每层做了什么事情

网络协议栈_第2张图片

传输层

传输层添加下面这八个字节的数据内容(TCP协议)
网络协议栈_第3张图片

网络层

网络层添加下面指示的这20个字节的数据内容(IP协议)
网络协议栈_第4张图片

链路层

链路层添加下图开头的14个字节(以太网协议)
网络协议栈_第5张图片

抓包工具

  1. raw-socket
  2. netmap
  3. dpdk

code

头文件

#include 
#include 
#include 
#include 

#include 
#include 


#define NETMAP_WITH_LIBS

#include  

UDP协议

#pragma pack(1)
#define ETH_ALEN	6
struct ethhdr {
	unsigned char h_dest[ETH_ALEN];
	unsigned char h_source[ETH_ALEN];
	unsigned short h_proto;
};

struct iphdr {
	unsigned char version;
	unsigned char tos;
	unsigned short tot_len;
	unsigned short id;
	unsigned short flag_off;
	unsigned char ttl;
	unsigned char protocol;
	unsigned short check;
	unsigned int saddr;
	unsigned int daddr;
};

struct udphdr {
	unsigned short source;
	unsigned short dest;
	unsigned short len;
	unsigned short check;
};

struct udppkt {
	struct ethhdr eh;
	struct iphdr ip;
	struct udphdr udp;
	unsigned char body[0];
};

收发数据

void echo_udp_pkt(struct udppkt *udp, struct udppkt *udp_rt) {

	memcpy(udp_rt, udp, sizeof(struct udppkt));

	memcpy(udp_rt->eh.h_dest, udp->eh.h_source, ETH_ALEN);
	memcpy(udp_rt->eh.h_source, udp->eh.h_dest, ETH_ALEN);

	udp_rt->ip.saddr = udp->ip.daddr;
	udp_rt->ip.daddr = udp->ip.saddr;

	udp_rt->udp.source = udp->udp.dest;
	udp_rt->udp.dest = udp->udp.source;

}

int main() {
	
	struct ethhdr *eh;
	struct pollfd pfd = {0};
	struct nm_pkthdr h;
	unsigned char *stream = NULL;

	struct nm_desc *nmr = nm_open("netmap:eth0", NULL, 0, NULL);
	if (nmr == NULL) {
		return -1;
	}

	pfd.fd = nmr->fd;
	pfd.events = POLLIN;

	while (1) {
		int ret = poll(&pfd, 1, -1);
		if (ret < 0) continue;
		
		if (pfd.revents & POLLIN) {
			stream = nm_nextpkt(nmr, &h);
			eh = (struct ethhdr*)stream;

			if (ntohs(eh->h_proto) == PROTO_IP) {

				struct udppkt *udp = (struct udppkt*)stream;
				if (udp->ip.protocol == PROTO_UDP) {

					struct in_addr addr;
					addr.s_addr = udp->ip.saddr;

					int udp_length = ntohs(udp->udp.len);
					printf("%s:%d:length:%d, ip_len:%d --> ", inet_ntoa(addr), udp->udp.source, 
						udp_length, ntohs(udp->ip.tot_len));

					udp->body[udp_length-8] = '\0';
					printf("udp --> %s\n", udp->body);
#if 1
					struct udppkt udp_rt;
					echo_udp_pkt(udp, &udp_rt);
					nm_inject(nmr, &udp_rt, sizeof(struct udppkt));
#endif
				} else {
					printf("other ip packet");
				}
				
			}  
		} 
	}
}

你可能感兴趣的:(技术,日志,tcp/ip,c语言)