第12章 网络 (5)

news2024/11/15 4:15:19

目录

12.8 网络层

12.8.1 IPv4

12.8.2 接受分组

12.8.3 交付到本地传输层


本专栏文章将有70篇左右,欢迎+关注,查看后续文章。

12.8 网络层

12.8.1 IPv4

IPv4首部:

version:         值为4。

IHL:            IP header length。至少20字节。

Codepoint或Type of Service:ToS

Length:          首部 + 数据的总长度。

Fragment ID: 分片标识,一个分组的所有分片都相同,结合Fragment Offset来合并分片。

标志:            不同位代表不同特性。如:

        DF位:           不可分片。

        MF位:           有更多分片。

Fragment Offset:     该分片在分组的偏移。

TTL:                        最大跳数。

Protocol:                 传输层协议,如TCP or UDP。

IP头结构体

struct    iphdr    {

        __u8             version:4,

        __u8             ihl:4;

        __u8             tos;

        __be16         tot_len;

        __be16         id;

        __be16         frag_off;

        __u8             ttl;

        __u8             protocol;

        __sum16      check;

        __be32         saddr;

        __be32         daddr;

};

注册IP协议

inet_init()

        -> dev_add_pack( &ip_packet_type );

                将IP协议注册到ptype_base[ ] 数组中。

struct   packet_type     ip_packet_type    =    {

        .type        =       cpu_to_be16( ETH_P_IP ),

        .func        =       ip_rcv,         // 网络层入口

}

问:ip_rcv () 如何被调用?

答:1. 收包时,__netif_receive_skb_core () 中调用 deliver_ptype_list_skb ()

        2. deliver_ptype_list_skb:

                1. 遍历所有注册的网络层协议(packet_type)。

                2. 比较 packet_type->type与 skb->protocol 是否相等。

                3. 若相等,调用 packet_type->func(),即 ip_rcv。

12.8.2 接受分组

ip_rcv 收到分组后,流程:

struct    rtable   {         // IPv4 路由决策信息。

        struct    dst_entry    dst;

        unsigned int            rt_flags;

                //值有RTCF_LOCAL、RTCF_MULTICAST

        __u16                   rt_type;

                //表示路由类型。

                举例:

                        RTN_UNICAST:单播路由。

                        RTN_LOCAL:本地路由(直接交付)。

        int                         rt_genid;

                // 路由表变化时,rt_genid会递增。

        u32                      rt_pmtu;

                // pmtu值,即路径MTU。

        __be32                 rt_gateway;

                // 下一跳

        ........

};

IPv4

struct    rtable     *rt;

本地接收单播:

        rth->dst.input    =    ip_local_deliver;

转发单播:

        rth->dst.input    =    ip_forward;

接收组播

        rth->dst.input    =    ip_mr_input;

IPv6

struct    rt6_info    *rt;

本地接收:

        rt->dst.input    =    ip6_input;

转发:

        rt->dst.input    =    ip6_forward;

ip_rcv () 内容:

        1. 检测报文首部校验,其他字段检查。

        2. 调用 netfilter的 PRE_ROUTING钩子函数。

int    ip_rcv(struct   sk_buff    *skb,    struct net_device    *dev,    struct packet_type    *pt,    struct net_device    *orig_dev)

{

        // 1. 各种错误检查

        // 2. 执行netfilter的pre_route钩子函数

        NF_HOOK(NFPROTO_IPV4,    NF_INET_PRE_ROUTING,    skb,    dev,    NULL,

   ip_rcv_finish);

}

ip_rcv_finish:

        1. 根据 sk_buff 计算得到struct dst_entry *dst

        2. 执行dst->input() ,即:

                ip_local_deliver:本地接收。传给传输层协议。

                        或

                ip_forward:转发。

12.8.3 交付到本地传输层

对应函数:

        ip_local_deliver

int    ip_local_deliver(struct  sk_buff    *skb)

{

        if ( ip_is_fragment( ip_hdr(skb) ) ) {

                if (ip_defrag(skb,    IP_DEFRAG_LOCAL_DELIVER ))

                        return 0;         // 分片合并失败,如分片还没全部收到。

        }

        return    NF_HOOK(NFPROTO_IPV4,    NF_INET_LOCAL_IN,    skb,    skb->dev,    NULL,

   ip_local_deliver_finish);

}

1. 分片重组合并

ip_defrag

分片缓存:

        同一分组的各个分片缓存在一个独立的等待队列,直到所有分片到达。

ip_find ():

        对分片ID,源目IP,协议类型等进行hash,以检查是否为该分组创建了等待队列。

        1. 若没有,则创建新队列。

        2. 否则,通过 ip_frag_queue () 将分组置于队列中。

ip_frag_reasm ():

        实现合并分组动作。

若一个分组的分片没有全部到达,ip_defrag () 返回NULL,终止处理,等待分片到达。

2. 交付到传输层

ip_local_deliver () 分片合并后,调用:

        NF_HOOK(NFPROTO_IPV4,    NF_INET_LOCAL_IN,    skb, skb->dev,    NULL,    ip_local_deliver_finish);

每个传输层协议,定义一个 struct    net_protocol 实例

struct    net_protocol {

        void         (*early_demux)(struct sk_buff    *skb);

        int            (*handler)(struct sk_buff    *skb);

        void         (*err_handler)(struct sk_buff    *skb,    u32    info);

        unsigned int         no_policy:1,

        unsigned int         icmp_strict_tag_validation:1;

};

struct    net_protocol    tcp_protocol    =    {

        .handler    =    tcp_v4_rcv,

};

struct    net_protocol    udp_protocol    =    {

        .handler    =    udp_rcv,

};

struct    net_protocol    icmp_protocol    =    {

        .handler    =    icmp_rcv,

        .err_handler    =    icmp_err,         // 处理收到的ICMP差错消息。

}

注册传输层协议方法:

inet_add_protocol( &tcp_protocol,    IPPROTO_TCP);

        //添加到struct net_protocol *inet_protos[MAX_INET_PROTOS];

        //数组索引由hash得到。

所以最终由 udp_rcv () ,tcp_v4_rcv () 等函数接收分组。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AI模型:追求全能还是专精?详细阐述

AI模型:追求全能还是专精? 近日,OpenAI预计在秋季推出代号为“草莓”的新AI。从专注于数学问题到处理主观营销策略,"草莓"模型展现出惊人的多样性。而这种全能型 AI 是否代表了未来趋势?相比专攻于某一领域…

Python和MATLAB及R平均意见得分导图

🎯要点 文本转语音预测语音视频得分后验分布预测语音质量移动端语音质量测量英伟达GPU深度学习语音质量评估秩统计平均意见得分比较置信区间音频波形质量等分测评转换语音和自然语言相似性评估 JavaScript平均意见得分 平均意见得分是体验质量和电信工程领域中使用…

什么是Cursor?Cursor 是用于编码的 ChatGPT,现在任何人都能在几分钟内制作出应用程序

有时,一款人工智能工具会突然出现,并主导社交媒体上的话题。这款应用程序就是 Cursor,它是一款人工智能编码工具,使用 Claude 3.5 Sonnet 和 GPT-4o 等模型,让你比以往任何时候都更容易构建自己的应用程序。 Cursor 既…

3分钟千人被裁,IBM中国 “灭霸式“裁员背后原因?

2024年8月23日,IMB即有员工传出“无法访问系统”,“无法连接到公司网络”的消息,后续传出裁员的传闻。 图片来源网络 2024年8月26日周一,IBM召开3分钟的会议,宣布彻底关闭IBM中国研发部门,之后直接切断会议…

i.MX6裸机开发(12):eLCDIF——液晶显示

本章参考资料:《IMX6ULRM》(参考手册)Chapter 32: Enhanced LCD Interface (eLCDIF) 显示器介绍,显示器的分类和基本参数。 液晶控制原理,野火液晶屏介绍和控制原理讲解。 eLCDIF液晶显示实验,开发板预留…

安卓蓝牙技术的使用和场景

1.蓝牙协议应用领域 蓝牙协议是一种无线通信技术,广泛应用于短距离的数据和语音传输。以下是蓝牙协议的主要使用场景: 个人设备互联:蓝牙技术允许智能手机、平板电脑、笔记本电脑等设备之间进行数据传输和共享。例如,通过蓝牙将手…

“遥感+”集成技术的碳储量、碳排放、碳循环、温室气体等多领域监测与模拟

以全球变暖为主要特征的气候变化已成为全球性环境问题,对全球可持续发展带来严峻挑战。2015年多国在《巴黎协定》上明确提出缔约方应尽快实现碳达峰和碳中和目标。2019年第49届 IPCC全会明确增加了基于卫星遥感的排放清单校验方法。随着碳中和目标以及全球碳盘点的现…

DP2.0和HDMI2.1的计算

一、HDMI 8K60Hz,需要带宽64Gbps HDMI2.1支持48Gbps,不足以支持8K60Hz 增加HDMI2.1 FRL(Fixed Rate Link)模式,实现接口带宽的增加,满足8Kp60Hz需要。同时需要结合相应的YCbCr 4:2: 0编码和视频压缩技术。 1、变更内…

Redis高级----主从、哨兵、分片、脑裂原理

目前已更新系列: 当前:Redis高级----主从、哨兵、分片的原理 计算机网络--面试知识总结一 计算机网络-----面试知识总结二 计算机网络--面试总结三(Http与Https) 计算机网络--面试总结四(HTTP、RPC、WebSocket、S…

Android 11 ,Android Studio 三方APP调用系统 system/lib 目录下so库使用过程中的BUG(坑)。

背景介绍:最近在做文件管理器,需要把图库的功能集成到文件管理器中,实现在文件管理器中打开图片、切换图片的功能。在实现gif图片打开功能的时候,需要用到系统现成的gifplayer so库,导入Android studio的时候遇到了一堆…

游戏发行技术体系之SDK技术体系

在上篇文章中提现过,SDK主要分为充值、登录、合规、数据、聚合和后台管理。 下面是针对SDK技术体系进行拆分 这个地方没有写账号,是因为我会账号独立出来,这块会在后面的账号技术体系单独规划。

爆改YOLOv8|利用分层特征融合策略MSBlock改进yolov8,暴力涨点

1,本文介绍 MSBlock 是一种分层特征融合策略,用于改进卷积神经网络中的特征融合效果。它通过分层次地融合不同尺度的特征图来提高网络的表达能力和性能。MSBlock 采用多尺度特征融合的方法,确保网络能够有效地捕捉不同层次和尺度的信息&…

FPGA实现HDMI传输(二)

之前的文章简单介绍了HDMI接口、TMDS编码以及ADV611工作原理和寄存器配置,本篇博客将给出具体的代码以及板级验证结果,代码参考自米联客的教程。 一.ADV7611配置 1.i2c驱动模块 timescale 1ns / 1psmodule uii2c# (parameter WMEN_LEN …

Git使用教程(小白也能看懂)

git的使用教程(学习和工作中都能用到) 1、所需工具 git bash 1)安装git bash 官网:https://git-scm.com/download/win 2)在文件夹空白处鼠标右键 若出现 上图说明安装成功 2、使用 1)我们想要克隆一…

DHT11 实现温湿度传感器

DHT11 DHT11是一款含有已校准数字信号输出的温湿度复合传感器,它结合了电阻式感湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接。通过采用专用的数字模块采集技术和温湿度传感技术,DHT11确保了产品的高可靠性和长期稳定性 DHT11时序…

android studio 新建java工程, 安卓新建项目,android studio2024 如何新建java项目

主要解决,新增安卓工程,没有java选项 1. 点击左上角FIle -> New -> 2. 选择 no activity 选项, 然后next 3. langua 就可以选择java 了。name自己定义项目名称,项目存储地址,包名。 配置完成选择finish. 4. fin…

【C++】vector(下)--上篇

个人主页~ vector(上)~ vector 二、vector的模拟实现1、了解组成2、vector.h(1)为什么有了size_t参数的vector构造函数还要再写一个int参数的重载vector构造函数(2)为什么reserve不用memcpy(3&…

Mysql剖析(三)----MySql的事务详解

事务(Transaction):一般是指要做的或所做的事情。在计算机术语中是指访问并可能更新数据库中的各种数据项的一个程序执行单元(unit)。事务通常由高级数据库操纵语言或编程语言(如SQL、C或Java)书写的用户程序的执行所引…

Python脚本实现向飞书发送卡片消息

目录 1 先创建一个卡片消息2 Python脚本2.1 告警测试2.2 告警恢复 总结 1 先创建一个卡片消息 飞书卡片搭建工具 根据自己的需要创建一个消息卡片: 可以在 卡片源代码 中看到这个卡片的代码信息 2 Python脚本 2.1 告警测试 test.py 文件 ""&quo…

MacOS安装Docker Desktop

目录 安装Docker Desktop 1.下载 2.安装 3.验证 安装Docker Desktop 1.下载 访问Docker官方网站下载页面:https://www.docker.com/products/docker-desktop 选择自己所需的版本下载即可 2.安装 3.验证 1.查询版本号 docker --version 2.也可以运行一个简单的…