用户态协议栈TCP/IP的实现

在上一篇文章中,知道了为什么要有用户态协议栈,它具备什么功能。

今天来讲述,如何实现一个用户态协议栈。
它的原理就是, 将TCP/UDP到达网卡经解析后的数据,存储起来, 然后存储的位置通过映射的方法,直接到达应用程序处理。

在这里插入图片描述

网络协议栈

在这里插入图片描述
请问,网卡是属于哪一层协议栈?
先解释一下,
物理层 传输的是 物理信号, 即 光电信号。
数据链路层 , 对应的是 数字信号。

而从物理层的 光电信号 转化为 数据链路层的 数字信号, 靠的是 网卡。

网卡, 也可将 数字信号转为 光电信号。

所以,网卡并不属于网络协议栈里的任何一层。

UDP数据包的结构图

在这里插入图片描述
它是一层一层的,往外包的。

以太网协议

在这里插入图片描述
mac地址是以太网产物
mac地址有什么用?
mac地址,在局域网内有用。出了局域网之后,mac的地址就无效了。

//定义一个以太网的协议头
struct ethhdr {
   
	unsigned char h_dest[ETH_ALEN];    // mac 目的地址,固定6个字节
	unsigned char h_source[ETH_ALEN];  // 源地址, 固定6个字节
	unsigned short h_proto;            // 类型 
};

这个以太网协议头这个结构体,大小为14字节。

IP协议

在这里插入图片描述
IP地址是网络层产物

// IP协议头
struct iphdr {
   
	unsigned char version;   // 版本号  ipv4 /ipv6
	unsigned char tos;		 // 8bit 的 服务类型
	unsigned short tot_len;  
	unsigned short id;       // 标识, 每个包都有自己的id,identidy
	unsigned short flag_off; // 3bit的标志, 13bit的偏移量
	unsigned char ttl;		 // 生命周期
	unsigned char protocol;	 // 协议
	unsigned short check;	 // 校验和
	unsigned int saddr;		 // 源ip地址
	unsigned int daddr;      // 目的地址
};

什么时候选择有符号的char,啥时候选择无符号char.
如果有用来计算的话,就选择有符号的char型。
如果没有,只是单纯的表示值。那么就选择无符号的char。

ARP协议

在这里插入图片描述

// 28字节的 ARP请求/应答  ARP协议头
struct arphdr {
   
	unsigned short h_type;			// 硬件类型
	unsigned short h_proto;	        // 协议类型
	unsigned char h_addrlen;        // 硬件地址长度
	unsigned char protolen;			// 协议地址长度
	unsigned short oper;			// op 操作
	unsigned char smac[ETH_ALEN];  // 发送端以太网地址
	unsigned int sip;			   // 发送端IP地址
	unsigned char dmac[ETH_ALEN];  // 目的以太网地址
	unsigned int dip;			   // 目的IP地址
};

// 一个ARP的数据包
struct arppkt {
   
	struct ethhdr eh;  	// 以太网头
	struct arphdr arp;  // ARP请求/应答 ARP协议头
};

ICMP协议

在这里插入图片描述

// ICMP协议头
struct icmphdr {
   
	unsigned char type;
	unsigned char code;
	unsigned short check;
	unsigned short identifier;
	unsigned short seq;
	unsigned char data[32];
};

//一个ICMP的数据包
struct icmppkt {
   
	struct ethhdr eh;  // 以太网
	struct iphdr ip;   // IP头
	struct icmphdr icmp;  // ICMP协议头
};

用户态协议栈的实现

以下是使用了netmap 框架来实现的一个,用户态协议栈



#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>

#include <sys/poll.h>
#include <arpa/inet.h>


#define NETMAP_WITH_LIBS
#include <net/netmap_user.h> 
#pragma pack(1)


#define ETH_ALEN	6
#define PROTO_IP	0x0800
#define PROTO_ARP	0x0806

#define PROTO_UDP	17
#define PROTO_ICMP	1
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值