UDP用户态协议栈详细实现

  • 1 前言
  • 2 网络协议格式
    • 2.1 以太网协议
    • 2.2 IP协议
    • 2.3 UDP协议
    • 2.4 ARP协议
    • 2.5 ICMP协议
  • 3 UDP用户协议栈实现

1 前言

首先需要回答一个问题,为什么要学习实现用户态协议栈,从技术角度分析,主要是由于用户态的网络协议栈更高效,第二个是用户态协议栈可以实现定制。更高效主要是针对,网卡数据拷贝到协议栈这部分,如果采用用户态协议栈就可以进行一个零拷贝的过程,即利用mmap技术完成。这里实现UDP用户态协议主要是对于协议栈的理解的加深,了解内核协议栈的工作原理。

2 网络协议格式

2.1 以太网协议

以太网协议分为三个部分,协议头,数据和CRC校验。源地址和目的地址是指网卡的硬件地址(也叫MAC地址),类型主要包括IP协议,ARP协议和RARP协议。协议定义来自于RFC894,具体如下图。

头结构定义:

#define ETH_HDR_LEN             6#define IP_PROTO                0x0800
#define ARP_PROTO               0x0806
#define RARP_PROTO              0x0835typedef struct _eth_hdr {unsigned char src_mac[ETH_HDR_LEN];unsigned char dst_mac[ETH_HDR_LEN];unsigned short proto;
}eth_hdr;

2.2 IP协议

IP协议比较复杂,包括内容比较多,主要是定义了源ip地址和目的ip地址。默认是20字节的头部长度,当存在选项时头部长度将进行扩展。具体定义见RFC791:
头结构定义:

typedef struct  _ip_header
{#if __BYTE_ORDER == __LITTLE_ENDIANunsigned char hdr_len:4,version:4;
#elseunsigned char version:4,hdr_len:4;
#endifunsigned char tos_type;unsigned short pkt_len;unsigned short mark;unsigned short flag_offset;unsigned char ttl;unsigned char proto;unsigned short hdr_checksum;unsigned int src_ip;unsigned int dst_ip;unsigned int opt[0];
}ip_header;

2.3 UDP协议

udp协议是定义最为简单的协议,协议基本不提供什么保障,主要定义了源端口和目的端口,也使得UDP在用户层可以进行更为灵活的设计。详细见RFC768:

#define PROTO_UDP    17
typedef struct  _udp_header
{unsigned short src_port;unsigned short dst_port;unsigned short length;unsigned short checksum;
}udp_header;typedef struct  _udp_pkt
{eth_header eth;ip_header ip;udp_header udp;unsigned char data[0];
}udp_pkt;

2.4 ARP协议

ARP协议的作用是通过IP地址获取MAC地址,主要工作流程是ARP进程在本局域网上广播发送一个ARP请求分组,主要内容是A自己的IP地址、MAC地址,询问的IP地址。然后被询问对象既可以回复自身的ip和mac地址,建立一个arp表,后面可以直接查表。具体见RFC 826:

typedef struct  _arp_header
{unsigned short hw_type;unsigned short proto;unsigned char hw_len;unsigned char addr_len;unsigned short op;unsigned short src_mac[ETH_MAC_LEN];unsigned int src_ip;unsigned short dst_mac[ETH_MAC_LEN];unsigned int dst_ip;
}arp_header;typedef struct  _arp_pkt
{eth_header eth;arp_header arp;unsigned char data[0];
}arp_pkt;

注意:
这里存在一个arp攻击问题,就是对于arp欺骗,利用arp广播的原理,然后发送错误的ip和mac个对方造成arp表错乱整个网络无法使用。

2.5 ICMP协议

ICMP协议是一种面向无连接的协议,用于传输出错报告控制信息。具体见RFC792:

结构定义:

typedef struct  _icmp_header
{unsigned char type;unsigned char code;unsigned short checksum;unsigned short identifier;unsigned short seq;unsigned char data[32];
}icmp_header;typedef struct  _icmp_pkt
{eth_header eth;ip_header ip;icmp_header icmp;unsigned char data[0];
}icmp_pkt;

3 UDP用户协议栈实现

利用netmap实现一个简单的UDP协议的解析过程,用到netmap接口:nm_open打开网卡;nm_nextpkt获取网络数据;nm_inject发送网络数据。利用poll进行网络数据接收状态的获取,根据协议一层一层的强转,最终得到用户数据,数据发送也是一层层封装的过程。整体比较简单。网络编程需要考虑网络字节序和用户字节序,后续完善ARP查表和ICMP ping功能的实现。

#include<stdio.h>
#include <poll.h>
#include <arpa/inet.h>
#define NETMAP_WITH_LIBS
#include <net/netmap_user.h>
#pragma pack(1)int main()
{eth_header *eth = NULL;struct pollfd pfd = {0};struct nm_pkthdr nmh;unsigned char *buffer = NULL;//netmap:打开eth0网卡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) {buffer = nm_nextpkt(nmr, &nmh);eth = (eth_header *)buffer;if(ntohs(eth->proto) == PROTO_IP){udp_pkt *udp = (udp_pkt *)buffer;if(udp->ip.proto == PROTO_UDP){struct in_addr addr;addr.s_addr = udp->ip.src_ip;int udp_length = ntohs(udp->udp.length);printf("%s:%d:length:%d, ip_len:%d --> ", inet_ntoa(addr), udp->udp.src_port, udp_length, ntohs(udp->ip.pkt_len));udp->data[udp_length-8] = '\0';printf("udp buffer: %s\n", udp->data);udp_pkt udp_rt;echo_udp_pkt(udp, &udp_rt);nm_inject(nmr, &udp_rt, sizeof(udp_pkt));}}}}return 0;
}

注意点:
结构体会进行对齐,造成最后数据包的大小计算错误,这里需要指定#pragma pack(1)

UDP用户态协议栈详细实现相关推荐

  1. 100行源代码搞定用户态协议栈丨udp,icmp,arp协议的现实丨网络协议栈丨Linux服务器开发丨C++后端开发丨Linux后台开发

    100行源代码搞定用户态协议栈 视频讲解如下,点击观看: 100行源代码搞定用户态协议栈丨udp,icmp,arp协议的现实丨网络协议栈丨Linux服务器开发丨C++后端开发丨Linux后台开发丨网络 ...

  2. Linux网络设计之用户态协议栈与dpdk

    用户态协议栈设计与dpdk dpdk环境开启 Windowe下配置静态IP表 DPDK API介绍 struct rte_memzone结构体 struct rte_mempool结构体 struct ...

  3. 用户态协议栈之tcp/ip设计

    1 解决问题 对于服务器而言,正常的接受一帧Data的过程,客户端先通过网络发送一帧数据到网卡,再经过协议栈,最后通过系统调用叨叨应用程序.具体的流程图如下: 针对上面的两个流程,涉及到两次拷贝(网卡 ...

  4. 用户态协议栈tcp/ip设计

    1 解决问题 对于服务器而言,正常的接受一帧Data的过程,客户端先通过网络发送一帧数据到网卡,再经过协议栈,最后通过系统调用叨叨应用程序.具体的流程图如下: 针对上面的两个流程,涉及到两次拷贝(网卡 ...

  5. 深入浅出用户态协议栈

    一.前言 在讲网络协议栈前,先理解一个数据包在网络传输是一个怎么样的流程,如下图所示. 正常的流程是网卡接收到数据后,把数据copy到协议栈(sk_buff),协议栈把sk_buff数据解析完后再把数 ...

  6. 【高阶知识】用户态协议栈之Epoll实现原理

    Epoll 是 Linux IO 多路复用的管理机制.作为现在 Linux 平台高性能网络 IO 必要的组件.内核的实现可以参照:fs/eventpoll.c . 为什么需要自己实现 epoll 呢? ...

  7. 一文彻底掌握用户态协议栈,一看就懂的

    用户态协议栈 那我们先跟大家解释这个协议栈这个东西啊协议栈这个东西呢或多或少啊各个朋友应该都听过,我们站在一个设计者的角度,站在一个设计者的角度,站在tcpip的个人的角度,我们怎么去设计这个协议的? ...

  8. 【Linux服务器开发系列】手写用户态协议栈,udpipeth数据包的封装,零拷贝的实现,柔性数组

    视频教你手写网络协议栈,保证大家能学会,耐心看 1. 用户态协议栈 2. udp/ip/eth数据包的封装 3. 零拷贝的实现 4. 零长数组(柔性数组) [Linux服务器开发系列]手写用户态协议栈 ...

  9. 用户态协议栈设计实现

    目录 1. 网络模式 2. 获取原始数据 3. UDP数据帧格式 以太网协议头(数据链路层) -- 14byte IP数据头(网络层) -- 20byte UDP协议的数据格式(传输层) -- 8by ...

  10. FD.io VSAP(VPP Stack Acceleration Project),通过FD.io VSAP构建用户态协议栈

    目录 VSAP Scope-使用范围 Releases List of all subpages (used or unused) 通过FD.io VSAP构建用户态协议栈 VSAP https:// ...

最新文章

  1. 再见了!面试八股文。。。
  2. 扩增子图表解读8网络图:节点OTU或类Venn比较
  3. 50个photoshop网页设计教程-整体布局篇
  4. 函数(复习),闭包,DOM
  5. 深入理解javascript原型和闭包(13)-【作用域】和【上下文环境】
  6. SQL SERVER 查询表字段中是否有汉字
  7. 通过Blazor使用C#开发SPA单页面应用程序(2)
  8. js的匿名函数 和普通函数
  9. 重磅消息:F5收购Nginx!
  10. 虚拟机无法安装VMware Tools
  11. diadem2017注册机 ni_NI DIAdem2017下载
  12. 001-取整函数(ceil、floor、round)
  13. 嗅探(窃听网络上流经的数据包)
  14. 汉语拼音文件搜索项目
  15. pm2 使用教程: 管理你的 nodejs 后台项目
  16. 大数据治理工程师_大数据治理遇到的问题有哪些?大数据工程师必须认真应对...
  17. 年轻设计师如何做好商业设计
  18. RealView MDK开发工具
  19. iOS开发:关于UILabel、UIButton、UITextField文字下划线的设置方法(涉及到富文本的知识)
  20. RationalDMIS 7.1读取点自动测量圆 2020

热门文章

  1. 如何破解无线网络密码(无线网络密码破解)
  2. C# CommandName四个属性
  3. vue 局部回到顶部_VUE回到顶部功能
  4. 【高级检索】现在还有人不会用百度的搜索语法?
  5. nexus3私库环境搭建(maven,yum,apt,nodejs)
  6. 大蟒蛇Python平台相关知识
  7. linux动态鼠标光标,自定义鼠标光标---Linux Mint 18.2 Sonya系统
  8. IT行业都能干什么事?为什么要学习IT技能呢?
  9. 特效字幕(ass)简易制作教程
  10. 计算机服务器可以开游戏吗,想买台小服务器做个人电脑,玩游戏可以吗