首先来看这个ip层的结构:

这里看到非常多的netfilter hook,这是因为netfilter主要是针对ip层的。

ip层的主要任务有下面5个方面:

1 ip数据包的校验

2 防火墙的处理(也就是netfilter子系统)

3 处理options(这里的options包含了一些可选的信息。比如时间戳或者源路由option).

4 切包和组包(由于mtu的存在,因此我们需要切包和组包).

5 接收,输出和转发操作。

接下来我们来看ip头的结构:

struct iphdr {
#if defined(__LITTLE_ENDIAN_BITFIELD)  __u8    ihl:4,  version:4;
#elif defined (__BIG_ENDIAN_BITFIELD)  __u8    version:4,  ihl:4;
#else
#error  "Please fix <asm/byteorder.h>"
#endif  __u8    tos;  __be16  tot_len;  __be16  id;
//这里要注意DF,MF和Fragment offset表示为frag_off一个域.  __be16  frag_off;  __u8    ttl;  __u8    protocol;  __sum16 check;  __be32  saddr;  __be32  daddr;  /*The options start here. */
};

这里每个字段的意思也就没什么好解释得了,基本上对网络协议有些了解的都会知道。我下面会介绍几个主要的域。这里可以看到在

首先来看options域。

前面已经说过了,这个域也就是包含一些其他程序(比如路由)需要的信息。这个域的大小为0到40位,一般不会超过40个位,再大的options基本上很罕见。

options被分为2种,一种是单字节的,一种是多字节的。下面我们就来看这两种的结构:

先来看type字段,它的结构:

clas也就是这个options的类型了,copied如果被设置,则当数据包切片的时候,这个option必须被复制到每一个切好的包。而number则是类型所对应的值:下面这个图就是ip option的一些类型值:

主要的类型定义在linux/ip.h里面。

接下来length表示这个option的长度。poionter这个指针表示options的起始位移。option data存储一些需要的数据。

随便举个ip options的例子,比如record route option,这个option用来保存输出接口的ip地址,但它有大小限制,只能保存9个地址们如果超过九个就会忽略,接下来看下面的图,a主机发送包到b主机:

最后我们来看一下数据报的切片和组包。

首先来看相关的ip头里面的域:

DF,表示不切片,因为有时切片并组包耗时太长,影响性能。可是如何解决mtu等问题呢,这里linux采用了Path MTU Discovery算法,来取得所能传输的最大mtu,而不是根据输入帧的头来判断。

MF表示需要更多的切好的片。当一个包被切片之后,它设置mg为true,知道最后一个分片,而这个分片的MF会被设置为false(也就是0).当接收端接收到这最后一个切片时,就会开始组包,哪怕其他的切片还没到达。

Fragment offset表示这个分片的数据包在原来数据包中的位移,只有凭借这个才能正确组包。

ID,ip包的id,一个ip包的所有帧切片的id都是相同的。通过这个域,接受者能知道那些切片是属于同一个包的。

我们再来看切片和组包有可能会出现的问题。

先来看丢包的问题,首先我们要知道只有当ip包全部接收到(也就是被切片的包)之后,才会组包并将此数据包发送给高层。

丢包有3种情况:

1 有可能被路由器丢掉。

2 有可能由于crc校验不通过而被丢掉。

3 有可能被防火墙过滤掉。

解决方法就是,如果一些切片没有在给定的时间内到达的话,每一个路由器和主机都有一个定时器来清理发送过的ip包的切片。

这里要注意,ip层是没有重传机制的(ip协议是无连接的),因此必须等待高层来告诉它重传整个数据包。

重传的数据包不能重新使用未传输成功的数据报的id,也就是id不能相同。

由于kernel不能交换数据到硬盘,因此handling切片在内存中,会影响路由器的性能,因此linux对于切片的内存有了一个限制。

由于ip是一个无连接的协议,因此没有流量控制什么的,所以这些都交给上层去做。

标识每一个切片是属于哪一个数据包,在linux中使用4个域来确定:

源地址,目的地址,ip包id,l4协议类型。

可是这有一个问题,那就是有可能不同的包,这四个参数都是相同的,比如经过nat转发后的数据包。比如下面的例子,当pc1,pc2发出去的包被路由r修改掉源地址,并切片后,然后同时抵达S,这时就会出问题:

而ipv6就会更好的处理这个问题,他将只允许在原始的host进行切片。

最后看一下packet ID,在linux中,是每个目的地址一个ip packet id,每个id是一个16位的整数。这样的话就降低了数据包的id有可能老的还没到,新的就要重新使用老的的id。

linux下ip层的一些概念相关推荐

  1. Linux下ip route、ip rule、iptables的关系(转

    http://www.cnblogs.com/sammyliu/p/4713562.html(本文内容转自此篇博客) Linux下ip route.ip rule.iptables的关系(转) 1.基 ...

  2. linux系统下的ip分片程序,Linux下IP分片与重组

    Linux下IP――分片与重组 原理介绍 为一个数据包片再次分片 为数据包分片和为数据包片再次分片之间的细微差别就在于网关处理MF比特的不同.但一个网关为原来为分片的数据包分片时,除了末尾的数据包片, ...

  3. linux下ip冲突检测 arp

    linux下ip冲突检测 ARP协议具体解释之Gratuitous ARP(免费ARP)

  4. Linux下IP地址两种修改方式的总结(IP地址、子网掩码、网关、DNS简介)

    目录 一.IP地址.子网掩码.网关.DNS简介 1.IP地址 2.子网掩码 3.网关 4.DNS 二.Linux下IP地址修改两种方式介绍(Centos7.6) 1.查看IP地址 2.修改配置文件修改 ...

  5. linux下ip协议(V4)的实现(四)

    这次主要介绍的是ip层的切片与组包的实现. 首先来看一下分片好的帧的一些概念: 1 第一个帧的offset位非0并且MF位为1 2 所有的在第一个帧和最后一个帧之间的帧都拥有长度大于0的域 3 最后一 ...

  6. linux下ip协议(V4)的实现(三)

    这次我们来看数据包如何从4层传递到3层. 先看下面的图,这张图表示了4层和3层之间(也就是4层传输给3层)的传输所需要调用的主要的函数: 我们注意到3层最终会把帧用dst_output函数进行输出,而 ...

  7. linux下ip协议(V4)的实现(一)

    首先来看校验相关的一些结构: 1 net_device结构: 包含一个features的域,这个表示设备的一些特性(比如控制校验),下面的几个flag就是用来控制校验: #define NETIF_F ...

  8. linux协议栈ip层分析

    学习目标: 熟悉ip层的职责? 熟练数据包如何通过ip层? 熟练ip数据重组的设计思路? 熟悉ip路由的思路? 熟悉netfilter的钩子函数处理? 1数据流路径 2职责 ip层的主要任务有下面5个 ...

  9. linux+ip+路由设置,Linux下IP巧设置-网管专栏,防火墙和路由

    如何实现ip伪装?假设你现在有一台linux主机通过ddn专线连接到internet上,有自己的ip和域名,同时还与20台win95工作站通过hub连接,你现在完全可以通过ip伪装来实现这20台win ...

最新文章

  1. 没有云平台,又不会代码?MicrobiomeAnalyst:一款综合的可视化微生物组学数据分析网页工具
  2. 简洁好用的KDTree模板
  3. static的三种用法,定义静态变量,静态函数,静态代码块!
  4. vivadoRAM中初始化文件coe如何快速生成
  5. 由一个计数器出发:关于vue使用独立js文件的问题
  6. 公司新办公楼休息间能看到富士山了
  7. Python守护进程
  8. android 叠加视图 重启,android-后台应用程序以侦听拖动手势
  9. 同人游戏开发手记(三) - 第二章 守护者之剑系列 (2.1 ~ 2.2)
  10. 计算机毕业设计ssm基于SSM框架的人力资源管理系统89kq5系统+程序+源码+lw+远程部署
  11. 缺陷报告单写作准则(5C)
  12. 电脑的Windows图片查看器找不到怎么办
  13. 女朋友嘲笑我没有艺术气息,我不服!!一气之下我用python画素描人像
  14. 数据分析-kaggle泰坦尼克号生存率分析
  15. Latex页眉三种形式设置
  16. 樱道,空蝉,雨空,夏恋,雨道,彩月,幻昼,惊梦,白夜。这些纯音乐
  17. 简单好用的服务器压力测试小工具 ab
  18. C#实现Gauss完全主元消去法
  19. 传统图像去噪方法(一)
  20. Android Studio在项目文件夹/build/intermediates/下找不到bundles文件夹和packaged-classes文件夹

热门文章

  1. androidpn php,服务器推送消息到Android终端方法
  2. matlab错误使用builtin,MATLAB环境下运行MATLAB函数时发生异常
  3. em表示什么长度单位_使用相对长度单位em布局网页内容
  4. CentOS下Redis 2.2.14安装配置详解
  5. 11个不常被提及的JavaScript小技巧
  6. 如何让两个线程交替打印整数1-100?你的答案呢?
  7. Ajax基础知识梳理 1
  8. Django-用户认证组件
  9. git完全cli指南之详细思维导图整理分享
  10. 动态删除列表中的元素