【C语言】socket 层到网络接口的驱动程序之间的函数调用过程

一、socket 层到网络接口的驱动程序之间的函数调用过程概述

在 Linux 操作系统中,socket 层到网络接口的驱动程序之间的函数调用过程相对复杂,涉及多个层次的交互。以下是一个简化的概述,描述数据从 socket 传递到硬件驱动,再到硬件设备的基本调用过程:
1. 用户空间到内核空间
    用户程序通过 socket API 发起网络操作。当用户空间要发送数据时,它会调用如 sendto 或 write 等系统调用,这些调用将数据从用户空间传递到内核空间。
2. Socket 层处理
    根据 socket 类型(例如 TCP、UDP 或者其他协议),内核将调用相应的协议族处理函数。例如对于一个 TCP socket,传输控制协议 (TCP) 相关的函数将被使用。
3. 协议栈
    数据通过网络协议栈传递,进行必要的处理,如 IP 分段、TCP 分段、添加头部等。每一层协议栈都对数据进行加工,直到形成可以在网络上传输的包。
4. 路由决策
    内核根据 IP 层的路由表进行路由决策,确定用于发送数据的 net_device 结构体。此结构体代表了相应的网络接口,并包含了用于发送数据的接口函数。
5. 队列与传输
    数据包被放入到对应网络设备的发送队列中等待传输。这通常涉及到内核中的排队机制,如 Qdisc(排队规则)层。
6. 网络设备驱动程序的发送函数
    被排队的数据包最终将被网络设备驱动程序的发送函数处理。这一函数通常被称为 hard_start_xmit 或类似的名称。驱动程序将数据包转换成适合该网络设备的形式,并通过硬件接口发送出去。
7. 硬件传输
    最后,数据被传递到网卡的硬件,由网卡负责将电子信号或光信号发送到网络中。
这个过程可能会因为具体的配置和使用的协议栈而不同。在某些情况下,例如使用虚拟化技术或软件定义网络(SDN),过程中的某些步骤可能被跳过或者是在不同的层次上执行。此外,接收数据的过程也会涉及类似但相反的步骤,以将数据从硬件传输上来,经过内核处理,然后递送到用户态的应用程序中。

二、路由子系统将 IP 数据发送到正确的网络接口过程

在 Linux 内核中,IP层路由决策主要是由内核的路由子系统来完成的。路由子系统负责将 IP 数据包根据目的地址发送到正确的网络接口。这个过程大体上可以分为几个步骤:
1. 查找路由表
   当一个 IP 数据包需要被发送的时候,内核会根据这个数据包的目的 IP 地址在路由表中查找最匹配的路由项。Linux 中的路由表可以通过 ip route show 命令查看。
2. 路由表条目
   每一条路由表项包含了几个重要的信息字段,例如目的网络、子网掩码、网关、接口名称等。这些信息用来决定数据包的转发路径。
3. 选择最合适的路由
   如果路由表中有多条路由都可以匹配到一个目的地址,那么将根据优先级和其他标准选择最合适的一条。通常,最具体(最长前缀匹配)的路由将被选择用来转发数据包。
4. 确定 net_device
   一旦选择了一条路由,内核将使用与之相关联的 net_device 结构体。`net_device` 结构体代表了一个网络接口设备,包含了很多网络设备的信息,包括设备名称、接口状态、传输队列、以及用于发送和接收数据的函数指针等。
5. 处理网关(如果必要)
   如果数据包需要通过网关(跳)来到达目标,那么路由表项中也会包含网关的信息。在这种情况下,数据包的实际目的硬件地址将会是网关设备的地址,而不是最终目的地的地址。
6. 引用程序
   在最终确定了`net_device`结构体和下一跳信息(next hop—not necessarily the final destination)之后,数据包将被送到网络接口的发送队列准备发送(例如通过调用`dev_queue_xmit`函数)。
7. Neighbor Subsystem (ARP)
   如果还没有目的地的 MAC 地址,则需要进行地址解析(例如使用 ARP 协议解析 IPv4 地址)。这是在发送前必须完成的,除非目的地就是本地网络接口。
路由决策是一个动态的过程,可以被多种因素影响,例如路由协议、策略路由规则、网络接口的状态更改等。管理员或者网络管理系统可以修改路由表来更改路由决策的结果,以适应不断变化的网络环境。在进行网络通信时,确保高性能和正确的路由决策是很重要的,这是由内核的路由子系统来保证的。

三、选择路由的过程中涉及的步骤

当 Linux 内核需要发送一个网络数据包时,它会通过路由子系统来确定该往哪个方向发送数据包。选择路由之后,内核会使用与这条路由相关联的 net_device 结构体来处理接下来的数据包发送。`net_device` 结构体是 Linux 内核网络子系统的一个基础结构,代表一个网络接口,包含了与该网络设备相关的所有信息。
在选择路由的过程中,以下步骤通常会涉及:
1. 路由查找
   内核使用数据包的目的 IP 地址,通过路由查找函数(如 ip_route_output())在路由表中查找匹配的路由项。路由表包含了多个条目,每一个条目都包含目的网络、掩码、网关、接口等信息。
2. 选择路由项
   如果找到了匹配的路由项,内核就会获取相应的路由决策,这包括了数据包应该从哪个网络接口发送,以及是否需要通过网关来转发等信息。
3. 关联 net_device
   路由项包含了一个指向相关 net_device 结构体的指针。`net_device` 结构体定义在 <linux/netdevice.h> 头文件中,包含了网络接口的诸多信息和操作函数指针,如设备名(`name` 字段)、接口索引(`ifindex` 字段)、操作函数(`netdev_ops` 字段)等。
4. 数据包的处理
   一旦确定了 net_device,内核就会将数据包传递给这个结构体中的操作函数进行处理。`net_device_ops` 结构体中包含了多个操作数据包的函数指针,例如 ndo_start_xmit 用于发送数据包,`ndo_open` 和 ndo_stop 用于打开和关闭设备等。
5. 发送数据包
   ndo_start_xmit 函数(通常对应该网卡驱动的 hard_start_xmit 函数)被调用并且被传入待发送的 sk_buff(包含网络数据包的结构体)以及 net_device 结构体。该函数负责将数据包加入到传输队列,并触发数据包的传输流程,这可能会直接向硬件发送数据包,或者向硬件排队以便于稍后发送。
这个过程中的一个重要概念是 sk_buff,它是内核中用于存储和控制数据包的主要数据结构。当内核层的各种网络子系统处理数据包时,`sk_buff` 结构会随数据包传递,最终到达用于实际发送数据的网络设备驱动程序。

四、 IP 层数据包映射到相应的 net_device 结构体的过程

在 Linux 内核中,路由决策是基于路由表来进行的,其将 IP 层数据包映射到相应的 net_device 结构体的过程通常如下:
1. 网络接口注册
    当网络接口(或称为网络设备)如以太网卡在系统启动或者后来被加载时,它的驱动会通过调用 register_netdev() 函数将该设备注册到内核网络子系统中。在注册过程中,`net_device` 结构体会被初始化和填充,它包含了用于操作该网络设备的信息,包括发送和接收函数指针、设备名、以及设备的硬件地址等。
2. 路由表的初始化和更新
    路由表是内核中用于存储路由信息的数据结构,它包含了多个路由项,每个路由项包含了网络目的地址、网络掩码、网关地址、标志等信息。路由表可以手动通过例如 ip route add 命令配置,也可以自动通过 DHCP、路由协议如 OSPF、BGP 或其他机制来更新。
    当路由项被创建或更新时,每个路由项也会关联到一个 net_device 结构体。例如,如果一个路由项指定了通过特定的网关(也就是下一跳)来达到目的网络,则该路由项将包含指向该网关对应的网络接口(`net_device` 结构)的指针。
3. 路由选择
    当内核需要转发或发送数据包时,它会根据数据包的目的 IP 地址执行路由选择(路由查找)。这通常涉及查询路由表并且找到最合适的路由项。路由选择的算法会考虑多个因素,例如目的地址、子网掩码和度量值(metric)。
4. 结构体关联
    当路由选择过程确定了合适的路由项后,它会使用该路由项中指向 net_device 结构体的指针来确定数据包应该通过哪个网络接口发送。这个指针在路由项被添加到路由表时就已经建立起了。
路由表和网络设备通常是可以动态管理的,管理员可以使用包括 ifconfig、`ip` 等命令来配置网络接口和路由表,内核也会使用诸如 rtnetlink 接口来进行这些信息的更新和同步。

五、`net_device` 结构体中的设备名

`net_device` 结构体确实包含网络接口的名称,它在 Linux 内核网络子系统中表示一个网络接口。在 net_device 结构体中,通常有一个名为 name 的成员用于存储设备的名称。这个名称通常与在用户空间看到的设备名称(如 eth0, wlan0, ens33 等)相对应。
下面是一个简化版的 net_device 结构体的例子,展示了包含设备名称的部分:

struct net_device {
    char                name[IFNAMSIZ]; // 网络设备名称
    // ... 其他很多网络设备相关的成员变量和函数指针 ...

    // 这里仅展示了名称部分,并省略了大量其它细节
};

在这个结构体中,`IFNAMSIZ` 是一个定义在 <linux/if.h> 中的宏,它规定了接口名的最大长度,便于内核和用户空间的统一。
net_device 结构提供了内核中对网络接口的抽象,包含了很多网络操作的接口函数、统计信息、队列状态,以及一些特定于设备类型和配置的参数。
当网络接口注册到网络子系统时,例如在网卡驱动初始化的时候,这个结构会被填充并加入到内核的网络设备列表中。用户可以通过指令如 ifconfig 或 ip link show 在用户空间查看网络接口的详细信息。

六、IP 地址

在 Linux 内核中,`net_device` 结构体代表一个网络接口,它主要包含了与网络设备相关的信息,如设备状态、硬件地址(如 MAC 地址),以及指向设备驱动函数的指针等。`net_device` 结构体本身不直接保存 IP 地址信息。
IP 地址(无论是 IPv4 还是 IPv6)是在网络层管理的,具体而言,在 Linux 内核中,IP 地址是与网络接口相关联的,但存储在不同于 net_device 的结构体中。对于 IPv4,地址信息通常存储在 in_device 结构体中;对于 IPv6,地址信息通常存储在 inet6_dev 结构体中。
这两个结构体(`in_device` 和 inet6_dev)包含了与 IP 层相关的配置和状态信息,包括分配给接口的 IP 地址列表、子网掩码、任播和广播地址等。这些结构通过指针与对应的 net_device 实例相连。这样的设计允许网络接口能够同时配置和管理 IPv4 和 IPv6 地址。
网络接口的 IP 地址通常是通过系统调用(如 ioctl 或 socket 操作)和网络配置工具(如 ifconfig、`ip` 命令行工具等)来设置和管理的。在内核层面,此类操作会通过各种内核函数来修改和查看与 in_device 以及 inet6_dev 相关联的 IP 地址信息。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/403252.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

新书推荐:《分布式商业生态战略:未来数字商业新逻辑与企业数字化转型新策略》

近两年&#xff0c;商业经济环境的不确定性越来越明显&#xff0c;市场经济受到疫情、技术、政策等多方因素影响越来越难以预测&#xff0c;黑天鹅事件时有发生。在国内外经济方面&#xff0c;国际的地缘政治对商业经济产生着重大的影响&#xff0c;例如供应链中断&#xff0c;…

PostgreSQL 实体化视图的使用

上周的教程中&#xff0c;通过 DVD Rental Database 示例&#xff0c;让我们了解了在 PostgreSQL 中创建实体化视图的过程。正如我们所了解的&#xff0c;PostgreSQL 实体化视图提供了一种强大的机制&#xff0c;通过预计算和存储查询结果集为物理表来提高查询性能。接下来的内…

C#_扩展方法

简述&#xff1a; 扩展方法所属类必需是静态类&#xff08;类名依据规范通常为XXXExtension&#xff0c;XXX为被扩展类&#xff09;扩展方法必需是公有的静态方法扩展方法的首个参数由this修饰&#xff0c;参数类型为被扩展类型 示例&#xff1a; static class DoubleExtens…

vue实现拖拽(vuedraggable)

实现效果: 左侧往右侧拖动&#xff0c;右侧列表可以进行拖拽排序。 安装引用&#xff1a; npm install vuedraggable import draggable from vuedraggable 使用&#xff1a; data数据&#xff1a; componentList: [{groupName: 考试题型,children: [{componentType: danxua…

【基础】提高前端的增益

低噪声&#xff0c;低偏移电压&#xff0c;低漂移-当你把信号链前端的增益提高后&#xff0c;所有的这些精密小信号处理的目标变得很简单。 这是一个很简单的概念。如图1所示&#xff0c;第二级的误差将除以第一级的增益。比如&#xff0c;第一级增益适度&#xff0c;值为10&a…

制造业客户数据安全解决方案(终端安全/文件加密/介质管理等)

针对前文制造业客户数据安全解决方案&#xff08;数据防泄密需求分析&#xff09;提到的泄密风险&#xff0c;本文详细介绍一套完整、合理的解决方案&#xff0c;通过该方案构建公司数据安全防护边界&#xff0c;自动加密、全方位保护数据安全。 PC端&#xff1a;https://isite…

Qt开发:MAC安装qt、qtcreate(配置桌面应用开发环境)

安装qt-creator brew install qt-creator安装qt brew install qt查看qt安装路径 brew info qtzhbbindembp ~ % brew info qt > qt: stable 6.6.1 (bottled), HEAD Cross-platform application and UI framework https://www.qt.io/ /opt/homebrew/Cellar/qt/6…

创建一个基于Node.js的实时聊天应用

在当今数字化社会&#xff0c;实时通讯已成为人们生活中不可或缺的一部分。无论是在社交媒体平台上与朋友交流&#xff0c;还是在工作场合中与同事协作&#xff0c;实时聊天应用都扮演着重要角色。与此同时&#xff0c;Node.js作为一种流行的后端技术&#xff0c;为开发者提供了…

10大数据恢复软件可以帮助您恢复电脑数据

您可能会非常紧张&#xff0c;因为知道有人意外地从您的硬盘驱动器中删除了您的宝贵数据&#xff08;甚至使用 ShiftDelete 从回收站中删除&#xff09;&#xff0c;并且您确实需要这些数据&#xff0c;并且没有其他备份源可以在其中找到这些数据。不要担心&#xff0c;保持冷静…

B² NETWORK空投

空投要点 众多大机构支持&#xff0c;是为数不多的有 Bitcoin 主网验证 Rollup 解决方案的 BTC Layer2&#xff0c;提前埋伏其实是普通人抢早期筹码最好的方式&#xff0c;参加 B Buzz 就是手握金铲子&#xff0c;对标eth二层网络的繁荣程度你就能想象这个前景明牌空投5%给早期…

Kotlin 进阶 学习 委托

1.接口委托 package com.jmj.jetpackcomposecompositionlocal.byStudy/*** 接口委托*/ interface HomeDao{fun getAllData():List<String> }interface ADao{fun getById(id:Int):String }class HomeDaoImpl:HomeDao{override fun getAllData(): List<String> {ret…

useRef有什么用?

看一下官网定义 useRef是一个React Hook&#xff0c;它能帮助引用一个不需要渲染的值 这句话透露出一个信息&#xff0c;不需要渲染的值可以用useRef引用&#xff0c;那需要渲染的值用什么引用呢&#xff1f;当然是useState了&#xff0c;需要渲染的值指的就是状态嘛&#xff0…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的玉米病虫害检测系统(Python+PySide6界面+训练代码)

摘要&#xff1a;本文介绍了一种基于深度学习的玉米病虫害检测系统系统的代码&#xff0c;采用最先进的YOLOv8算法并对比YOLOv7、YOLOv6、YOLOv5等算法的结果&#xff0c;能够准确识别图像、视频、实时视频流以及批量文件中的玉米病虫害。文章详细解释了YOLOv8算法的原理&#…

防御保护--防病毒网关AV

目录 病毒 防病毒处理流量 防病毒的配置 防病毒&#xff08;AV&#xff09; --- 传统的AV防病毒的方式是对文件进行查杀。 传统的防病毒的方式是通过将文件缓存之后&#xff0c;再进行特征库的比对&#xff0c;完成检测。但是&#xff0c;因为需 要缓存文件&#xff0c;则将…

Swift Combine 使用调试器调试管道 从入门到精通二十六

Combine 系列 Swift Combine 从入门到精通一Swift Combine 发布者订阅者操作者 从入门到精通二Swift Combine 管道 从入门到精通三Swift Combine 发布者publisher的生命周期 从入门到精通四Swift Combine 操作符operations和Subjects发布者的生命周期 从入门到精通五Swift Com…

【数据结构初阶 6】二叉树:堆的基本操作 + 堆排序的实现

文章目录 &#x1f308; Ⅰ 二叉树的顺序结构&#x1f308; Ⅱ 堆的概念与性质&#x1f308; Ⅲ 堆的基本操作01. 堆的定义02. 初始化堆03. 堆的销毁04. 堆的插入05. 向上调整堆06. 堆的创建07. 获取堆顶数据08. 堆的删除09. 向下调整堆10. 判断堆空 &#x1f308; Ⅳ 堆的基本…

Spring之AOP源码解析(上)

Aop相关注解 EnableTransactionManagementEnableAspectJAutoProxyEnableAsync... 从注解切入来看看这些注解都干了什么 Import注解作用简述 注入的类一般继承ImportSelector或者ImportBeanDefinitionRegistrar接口 继承ImportSelector接口&#xff1a;selectImports方法返回…

2.22学习总结

1.营救 2.租用游艇 3.砍树 4.买礼物 5.刷题统计 砍树https://www.dotcpp.com/oj/problem3157.html 题目描述 给定一棵由 n 个结点组成的树以及 m 个不重复的无序数对 (a1, b1), (a2, b2), . . . , (am, bm)&#xff0c;其中 ai 互不相同&#xff0c;bi 互不相同&#xff0c;ai…

MYSQL-入门

一.安装和连接 1.1 安装 mysql安装教程&#xff1a; 2021MySql-8.0.26安装详细教程&#xff08;保姆级&#xff09;_2021mysql-8.0.26安装详细教程(保姆级)_mysql8.0.26_ylb呀的博客-cs-CSDN博客 workbench安装&#xff1a; MySQL Workbench 安装及使用-CSDN博客 1.2 配…

戏曲文化苑|戏曲文化苑小程序|基于微信小程序的戏曲文化苑系统设计与实现(源码+数据库+文档)

戏曲文化苑小程序目录 目录 基于微信小程序的戏曲文化苑系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、微信小程序前台 2、管理员后台 &#xff08;1&#xff09;戏曲管理 &#xff08;2&#xff09;公告信息管理 &#xff08;3&#xff09;公告类型管理…