• C/C++ Linux 用户态协议栈的实现


    一、前言

      在讲网络协议栈前,先理解一个数据包在网络传输是一个怎么样的流程,如下图所示。

      正常的流程是网卡接收到数据后,把数据copy到协议栈(sk_buff),协议栈把sk_buff数据解析完后再把数据放到recv_buff,此时应用程序调用recv把数据从协议栈copy到应用程序;发送数据包,则与之相反,应用程序调用send把数据包copy到send_buff,协议栈从send_buff取数据放到sk_buff,交给网卡发送出去。这个过程有多次拷贝,为避免多次拷贝,使用dma的方式(零拷贝),把网卡的数据直接映射到内存,再由应用程序访问内存。


    二、数据包分析

      从网卡接收到一帧完整的数据包,可以使用原生的socket、netmap、dpdk等,完整的一帧数据由以太网头、IP头、tcp/udp头、用户数据构成,这些层级涉及到7层网络模型OSI,如udp协议分布到7层OSI如下图所示。

      由上图可知,以太网头属于链路层、IP头属于网络层、UDP头属于传输层,而实际的用户数据在应用层。

      (1)以太网头

        以太网头分布如下图所示。

        对应结构体如下,由此可知MAC地址存在以太网头。

    1. #define ETH_LEN 6
    2. //14字节以太网头---->链路层---->MAC地址,
    3. struct ethhdr{
    4. unsigned char dst[ETH_LEN];//6字节 目的地址即MAC地址
    5. unsigned char src[ETH_LEN];//6字节 源地址
    6. unsigned short proto;//2字节 协议类型,形容网络层使用的协议
    7. }
    8. //在计算上没有那个固件叫MAC地址,IP地址、端口
    9. //所谓的MAC地址,IP地址、端口只不过是协议栈里面一个字段名而已,不要与固件捆绑

      (2)IP头

        IP头结构如下图所示。

        其数据结构如下所示,IP地址在IP头中,属于网络层。

    1. //iphdr(ip头)---->网络层--->IP地址
    2. struct iphdr{
    3. unsigned char version:4,//4位版本
    4. hdrlen:4;//4位首部长度
    5. unsigned char tos;//8位服务类型
    6. unsigned short totlen
  • 相关阅读:
    2. 线性表的基本概念 + 基本操作
    【firewalld防火墙】
    criu简单例子
    Docker的初级使用
    外包干了2个月,技术退步明显.......
    金仓数据库KingbaseES物理备份恢复最佳实践(概述)
    UE5 虚幻引擎 详解蓝图通信 必备的知识技能之一!!!
    聊一聊安全且正确使用缓存的那些事 —— 关于缓存可靠性、关乎数据一致性
    十五届蓝桥杯第三期模拟赛题单(C++、java、Python)
    证券行业超融合架构方案设计
  • 原文地址:https://blog.csdn.net/m0_58687318/article/details/126587602