linux下ip层的一些概念

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


[img]/upload/attachment/117377/434dc733-af31-3c35-8163-2d0325b4f7a3.jpg[/img]

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

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

1 ip数据包的校验

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

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

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

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


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


[img]/upload/attachment/117380/d5b05484-9994-3cbd-ace2-d47785a43c2e.jpg[/img]


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种,一种是单字节的,一种是多字节的。下面我们就来看这两种的结构:

[img]/upload/attachment/117390/c40b6cf9-0852-3f22-9f31-4b181bb3fc58.jpg[/img]

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


[img]/upload/attachment/117395/c95328f7-7775-32fb-a2aa-3682952a7a4b.jpg[/img]


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


[img]/upload/attachment/117399/2d6bab5d-971c-306f-9ff7-a013f90a5131.jpg[/img]

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

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

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

[img]/upload/attachment/117401/9d3f74f0-b83a-3ce3-a8a5-c25009e226e2.jpg[/img]


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

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


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

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

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

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


[img]/upload/attachment/117407/409cfee7-5b16-392b-9bc3-13ff0d2ac771.jpg[/img]

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

先来看丢包的问题,首先我们要知道只有当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,这时就会出问题:


[img]/upload/attachment/117424/2f069ef1-982b-3a28-bbae-1fec2ba033c4.jpg[/img]

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

最后看一下packet ID,在linux中,是每个目的地址一个ip packet id,每个id是一个16位的整数。这样的话就降低了数据包的id有可能老的还没到,新的就要重新使用老的的id。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值