返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C/C++详解实现二层转发
  • 591
分享到

C/C++详解实现二层转发

2024-04-02 19:04:59 591人浏览 八月长安
摘要

目录OSI第2层什么是Mac地址表二层转发C/C++代码实现总结OSI第2层 前两个字段分别是目的地址和源地址字段。第3个字段是2字节的类型字段,用来标识上一层是什么协议。 数据

OSI第2层

前两个字段分别是目的地址和源地址字段。第3个字段是2字节的类型字段,用来标识上一层是什么协议。

数据链路层有两个子层:逻辑链路控制 (LLC) 子层和媒体访问控制 (MAC) 子层。

媒体访问控制 (MAC):MAC 子层处理硬件标识号的分配,称为 MAC 地址,它唯一地标识网络上的每个设备。 任何两个设备都不应具有相同的 MAC 地址。 MAC 地址是在制造时分配的。 大多数网络都会自动识别它。 MAC 地址位于网卡 上。

交换机跟踪网络上的所有 MAC 地址。

逻辑链路控制 (LLC):LLC 子层处理成帧寻址和流量控制。 速度取决于节点之间的链接,例如以太网或 Wifi。

第 2 层上的数据单元是一个帧。每个帧都包含一个帧头、正文和一个帧尾:

Header:通常包括源节点和目标节点的 MAC 地址。

Body:由正在传输的位组成。

Trailer:包括错误检测信息。 当检测到错误时,根据网络或协议的实现或配置,帧可能会被丢弃,或者可能会将错误报告给更高层以进行进一步的纠错。

error detection mechanisms::循环冗余校验 (CRC) 和帧校验序列 (FCS)。

通常有一个最大帧大小限制,称为最大传输单元,MTU。 巨型帧超过标准 MTU.

通过ARP解析出目标 MAC 地址?

传统交换在 OSI 模型的第 2 层运行,其中数据包根据目标 MAC 地址发送到特定的交换机端口。第 2 层网段中的设备不需要路由即可到达本地对等点。 然而,需要的是可以通过地址解析协议 (ARP) 解析的目标 MAC 地址,如下所示:

在这里,PC A 想要将流量发送到 IP 地址为 192.168.1.6 的 PC B。 然而,它不知道唯一的 MAC 地址,直到它通过 ARP 发现它,该 ARP 在整个第 2 层网段中广播。

然后将数据包发送到适当的目标 MAC 地址,交换机将根据其 MAC 地址表将正确的端口转发出去。

什么是MAC地址表

MAC地址表是在交换机中记录局域网主机和对应接口关系的表,交换机就是根据这张表负责将数据帧传输到指定的主机上的。

MAC地址表可以动态的学习数据帧中的原MAC地址。在MAC地址表中,交换机的一个接口可以对应多个MAC地址。一个MAC地址只能对应在一个接口上。下面是MAC地址表形成的具体过程,如下:

二层转发C/c++代码实现

cethping:

void ethping(char *destination, char* interface){
    //创建原始套接字。 指定接口名称
    struct RawSocket* rawsocket = new_RawSocket(interface);
    //数据包数据缓冲区
    unsigned char buf[1024];
    //定义数据包。 投射以匹配以太网帧的格式
    struct ethhdr_frame* eth_packet = (struct ethhdr_frame*)buf;
    //存储发送方和接收方的 MAC 地址。 协议类型是可选的,并且指定了 0x0806。
    //根据指定的接口名称获取发送者的MAC地址
    memset(buf, 0x0, sizeof(eth_packet));
    set_macaddr_from_string(destination, eth_packet->h_dest);
    set_macaddr_from_ifname(interface, eth_packet->h_source);
	eth_packet->h_proto = 0x0806;
    //在payload中设置字符串“Hello”
    char* data = "Hello";
    memcpy(eth_packet->payload, data, sizeof(data)); 
    //绑定指定接口上的socket
    rawsocket->bind_rawsocket(rawsocket);
    int send_size = send(rawsocket->socket, &buf, sizeof(buf), 0);
    printf("%dbyte send.\n", send_size);
    //关闭原始套接字
    rawsocket->close_rawsocket(rawsocket);
}
int main(int arGC, char *argv[]){
    if(argc != 3){
        printf("usage: %s <destination> <interface>", argv[0]);
        exit(0);
    }
    char *destination = argv[1];
    char *if_name = argv[2];
    ethping(destination, if_name);
    return 0;
}

cethpingd:

void start_daemon(char *interface){
    //创建原始套接字(指定接收器接口名称)
    struct RawSocket* rawsocket = new_RawSocket(interface);
    int len;
    //使用 bind 绑定到接口
    rawsocket->bind_rawsocket(rawsocket);
    while(1){
        int len = rawsocket->recv_rawsocket(rawsocket);
        struct ethhdr_frame *data = (struct ethhdr_frame*)(rawsocket->buf);
        fflush(stdout);
        //显示接收到的数据包的内容
        if(len > 0){
            printf("src: ");
            print_macaddr(data->h_source);
            printf(", ");
            printf("dst: ");
            print_macaddr(data->h_dest);
            printf(", ");
            printf("type: ");
            printf("%02x", (uint16_t)data->h_proto);
            printf(", ");
            printf("payload: ");
            printf("%s", data->payload);
            printf("\n");
        }
    }
}
int main(int argc, char *argv[]){
    if(argc != 2){
        printf("usage: %s <interface>", argv[0]);
        exit(0);
    }
    char *if_name = argv[1];
    start_daemon(if_name);
    return 0;
}

编译:

增加两个虚拟网卡:

运行:

总结

转发是将连接到网络交换机一个端口的设备的网络流量传递到连接到交换机上另一个端口的另一个设备的过程。

当第 2 层以太网帧到达网络交换机上的端口时,交换机会读取以太网帧的源 MAC 地址作为学习功能的一部分,它还会读取目标 MAC 地址作为转发功能的一部分。目标 MAC 地址对于确定连接目标设备的端口号很重要。如果在 MAC 地址表中找到目的 MAC 地址,则交换机通过 MAC 地址对应的端口转发以太网帧。

参考:

tcp IP详解卷一》

到此这篇关于C/C++详解实现二层转发的文章就介绍到这了,更多相关C语言二层转发内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: C/C++详解实现二层转发

本文链接: https://lsjlt.com/news/149519.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • C/C++详解实现二层转发
    目录OSI第2层什么是MAC地址表二层转发C/C++代码实现总结OSI第2层 前两个字段分别是目的地址和源地址字段。第3个字段是2字节的类型字段,用来标识上一层是什么协议。 数据...
    99+
    2024-04-02
  • 用C++实现二叉树层序遍历
    这篇文章主要讲解了“用C++实现二叉树层序遍历”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“用C++实现二叉树层序遍历”吧!二叉树层序遍历从底部层序遍历其实还是从顶部开始遍历,只不过最后存储...
    99+
    2023-06-20
  • C++实现LeetCode(107.二叉树层序遍历之二)
    [LeetCode] 107. Binary Tree Level Order Traversal II 二叉树层序遍历之二 Given the root of ...
    99+
    2024-04-02
  • C++入门之vector的底层实现详解
    目录前言定义初始结构声明构造函数容量有关操作获取有效数据大小size()获取数据容量capacity()增加容量reserve()重置大小resize()迭代器数据操作尾插push_...
    99+
    2024-04-02
  • C++实现LeetCode(102.二叉树层序遍历)
    [LeetCode] 102. Binary Tree Level Order Traversal 二叉树层序遍历 Given a binary tree, return the&#...
    99+
    2024-04-02
  • C++怎么实现二叉树层序遍历
    本篇内容主要讲解“C++怎么实现二叉树层序遍历”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C++怎么实现二叉树层序遍历”吧!二叉树层序遍历Given a binary tree, return...
    99+
    2023-06-20
  • C++ 二叉树的实现超详细解析
    目录1、树的概念及结构(了解)1.1树的概念:1.2树的表示法:2、二叉树的概念及结构2.1二叉树的概念:2.2特殊的二叉树:2.3二叉树的性质:2.4二叉树的顺序存储:2.5二叉树...
    99+
    2024-04-02
  • C++实现二叉树层序遍历的方法
    今天小编给大家分享一下C++实现二叉树层序遍历的方法的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。二叉树层序遍历Given ...
    99+
    2023-06-19
  • C语言实例实现二叉搜索树详解
    目录有些算法题里有了这个概念,因为不知道这是什么蒙圈了很久。 先序遍历: root——>left——>right 中序遍历...
    99+
    2024-04-02
  • C语言实现二叉树层次遍历介绍
    目录什么是层次遍历?那我们如何来实现这个算法呢?主体代码:总结什么是层次遍历? 对于一颗二叉树来说,从根节点开始,按从上到下、从左到右的顺序访问每一个结点。 注:每一个结点有且访问一...
    99+
    2024-04-02
  • 详解如何用c++实现平衡二叉树
    目录一、概述二、平衡二叉树不平衡的情形三、调整措施3.1、单旋转3.2、双旋转四、AVL树的删除操作五、代码实现一、概述 平衡二叉树具有以下性质:它是一 棵空树或它的左右两个子树的高...
    99+
    2024-04-02
  • 详解C/C++实现各种字符转换方法合集
    目录一、std::string 和 std::wstring 互转1、直接声明std::wstring2、wstring_convert3、WideCharToMultiByte和M...
    99+
    2024-04-02
  • C#实现Word转换TXT的方法详解
    目录实践过程效果代码实践过程 效果 代码 public partial class Form1 : Form { public Form1() { ...
    99+
    2022-12-22
    C# Word转TXT C# Word TXT
  • 用C++实现二叉树的之字形层序遍历
    这篇文章主要介绍“用C++实现二叉树的之字形层序遍历”,在日常操作中,相信很多人在用C++实现二叉树的之字形层序遍历问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”用C++实现二叉树的之字形层序遍历”的疑惑有所...
    99+
    2023-06-20
  • C++怎么实现二叉树的字形层序遍历
    今天小编给大家分享一下C++怎么实现二叉树的字形层序遍历的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。二叉树的之字形层序遍历...
    99+
    2023-06-19
  • C#实现将PDF转为Excel的方法详解
    目录dll引用方法方法1方法2PDF转ExcelC#VB.NET通常,PDF格式的文档能支持的编辑功能不如office文档多,针对PDF文档里面有表格数据的,如果想要编辑表格里面的数...
    99+
    2024-04-02
  • 详解C#如何实现隐式类型转换
    目录预期效果static using 与 global using隐式类型转换实现 Result 类型Result 类型是许多编程语言中处理错误的常用方式,包括 C# 的 dotNe...
    99+
    2023-01-05
    C#实现隐式类型转换 C#隐式类型转换 C# 类型转换
  • C++实现中缀转后缀的示例详解
    单位数加减乘除 例如:2+3*(4-9) 定义一个栈内优先级 运算符号优先级+、-3*、/5(1)6#0 定义一个栈外优先级 运算符号优先级+、-4*、/2(6)1#0 整个过程如下...
    99+
    2024-04-02
  • C++二叉树层序遍历实例分析
    今天小编给大家分享一下C++二叉树层序遍历实例分析的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。二叉树层序遍历Example...
    99+
    2023-06-19
  • C++实现LeetCode(103.二叉树的之字形层序遍历)
    [LeetCode] 103. Binary Tree Zigzag Level Order Traversal 二叉树的之字形层序遍历 Given a binary tree, r...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作