第二章 IP协议详解


2.1 IP服务的特点

它为上层协议提供了无状态,无连接,不可靠的服务

名称 简介 优点 缺点 对付缺点的方法
无状态 IP通信双方不同步传输数据的状态信息 无须为保持通信的状态台而分配一些内核资源 无法自己处理乱序和重复的IP数据报 把接受到的数据交给上层服务,由它们来处理乱序的,重复的报文段
无连接 IP通信双方都不长久地维持任何信息
不可靠 不能保证IP数据报准确地到达接收端,只承诺尽最大的努力 若是发送失败不会尝试重传,只会通知上层协议发送失败 若使用诸如TCP的上层服务需要自己实现数据确认/超时重传等机制,以达到可靠传输的目的

可以看出IP协议的目标很明确,只是负责发送和接收数据,具体的处理不归它管.


2.2 IPv4的头部结构

IPv4的头部结构通常为20字节(除非可变长的选项部分)

  • 4位版本号(Version):指定IP协议版本. 对IPv4来说其值是4

  • 4位头部长度(Internet Header Length,IHL):该IP头部有多少个32bit字 , 因为四位最大为15,所以IP头部最大为15*(32/8) = 60字节

  • 16位总长度(Total Length): 整个IP数据报的长度,以字节为单位 , 故IP数据报的最大长度为65535字节.

  • 16位标识符(Identification):唯一标识主机发送的每一个数据报.其初始值由系统随机生成.

  • 3位标志字段(Flags):是否禁止分片,第一位保留,第二位表示禁止分片,若设置了此位,IP模块将不对数据进行分片

  • 13位分片偏移(Fragment Offset):是分片相对原始IP数据报开始处的偏移.

  • 8位生存时间(Time to Live,TTL):数据报到达目的地之前允许经过的路由跳数.通常设置为64,每经过一个路由,该值就会被路由减1,当TTL值减为0时,路由器将丢弃该数据报,并向源端发送一个ICMP差错报文.

  • 8位协议(Protocol):用来区分上层协议.可以通过"cat /etc/protocols"查看所有上层协议对应的protocol字段的数值.

  • 32位的源端IP地址(Source Address)和目的端IP地址(Destination Address)用来标识数据报的发送端和接收端.

  • 最后一个选项字段(Options):包括松散源路由选择(loose source routing)即指定一个路由器IP地址列表,数据报发送过程中必须经过其中所有的路由器;严格源路由选择(strict source routing),和前者类似,不过数据报只能经过被指定的路由器,还有其他许多选项.

一. 使用tcpdump观察IPv4头部结构

pi@happyPi:~ $ sudo tcpdump -ntx -i lo &
pi@happyPi:~ $ ping 127.0.0.1 -c 1
IP 127.0.0.1 > 127.0.0.1: ICMP echo request, id 1603, seq 1, length 64
0x0000: 4500 0054 68d8 4000 4001 d3ce 7f00 0001
0x0010: 7f00 0001 0800 28b8 0643 0001 3bc1 7d58
0x0020: 16e7 0e00 0809 0a0b 0c0d 0e0f 1011 1213
0x0030: 1415 1617 1819 1a1b 1c1d 1e1f 2021 2223
0x0040: 2425 2627 2829 2a2b 2c2d 2e2f 3031 3233
0x0050: 3435 3637

可以看出:

  • Version 为 4 , IPv4

  • IHL 为 5 , 即头部分长度为5*(32/8) = 20字节

  • Total Legnth 为 0054 , 即84,但是上面显示的length是64,我估计64是内容长度,不包括头部数据长度

  • Flag 为 010,可看出禁止分片

  • TTL 为 40 , 即被设置为了64

  • Protocol 为 01 , 由"cat /etc/protocols" 可查出01对应着ICMP服务,这与ping请求服务对应上了

  • ...

IP头部信息出现在每一个IP数据报中,用于指定IP通信的端源IP和目的端IP地址,指导IP分片和重组,以及其他通信行为.

二. 使用tcpdump观察IP数据报的分片

IP数据报若太长超过帧的MTU(Maximum Transmission Unit,最大传输单元)的话,将会被分片传输.

  • 分片发生的地点不唯一,可能在发送端,也可能在中转路由器上甚至在传输过程中被多次分片.

  • 但是只有在最终的目标机器上这些分片才会被内核中的IP模块重新组装.

One. 查看MTU大小

pi@happyPi:~ $ ifconfig -a eth0
...
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
...

我的MTU是1500,这就意味发送的IP数据报最大长度为1472字节(IP头部占用20字节,ICMP头部占用8字节).

Second. 尝试分片

pi@happyPi:~ $ sudo tcpdump -ntv -i eth0 icmp &
pi@happyPi:~ $ ping 192.168.1.104 -s 1473 -c 1
PING 192.168.1.104 (192.168.1.104) 1473(1501) bytes of data.
IP (tos 0x0, ttl 64, id 32317, offset 0, flags [+], proto ICMP (1), length 1500)
192.168.1.108 > 192.168.1.104: ICMP echo request, id 1660, seq 1, length 1480
IP (tos 0x0, ttl 64, id 32317, offset 1480, flags [none], proto ICMP (1), length 21)
192.168.1.108 > 192.168.1.104: ip-proto-1

第一条:ttl 64, id 32317, offset 0, flags [+], proto ICMP (1), length 1500

第二条:ttl 64, id 32317, offset 1480, flags [none], proto ICMP (1), length 21

综上可以简单的看出:

  • 两片id是一样的,都是32317

  • 第一片位移是0,第二片则是1480

  • 第一片设置了MF(flags[+]),最后一片也就是第二片并没有设置(flags[none])

  • 这两个分片共用一个IP头部,但是ICMP内容只在第一片被复制了

在IP头部中的ID,标志和片偏移为IP的分片和重组提供了足够的信息.


2.4 IP路由

在IP数据报经过判断进入转发子模块后(其它的则是发给本机的),IP数据报应该发送至哪个下一跳路由,以及哪个网卡来发送,这就是路由过程.

实现数据报路由的核心数据结构是路由表.

此表按照数据报的目标地址分类,同一类型的IP数据报将被发往相同的下一跳路由器或者目标机器.

一. 查看路由表

pi@happyPi:~ $ route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
default 192.168.1.1 0.0.0.0 UG 0 0 0 eth0
192.168.1.0 * 255.255.255.0 U 1 0 0 eth0
字段 含义
Destination 目标网络或主机
Gateway 网关地址,*表示目标和本机在同一个网络,不需要路由
Genmask 网络掩码
Flags 路由项标志
U:该路由项是活动的;
H:该路由项的目标是一台主机;
G:该路由项的目标是网关;
D:该路由项是由重定向生成的;
M:该路由被重定向修改过;
Metric 路由距离,到达指定网络所需的中转数
Ref 路由项被应用次数
Use 路由项被使用次数
Iface 路由项对应的输出网卡接口

IP的路由机制如下:

  1. 查找路由表中和数据报的目标完全匹配的主机IP地址,若找到,就使用该路由表;否则转步骤(2)

  2. 查找路由表中和数据报的目标IP地址具有相同网络段的网络IP地址,若找到,就使用该路由表;否则转步骤(3)

  3. 选择默认路由项,这通常意味着数据报的下一跳是网关

对于我的这台机器来说,所有发送到IP地址为192.168.1.*的机器的IP数据报都可以直接发送到目标机器(匹配路由表第2项,步骤2)

而所有访问因特网的请求都将通过网关来转发(匹配默认路由项,步骤3)

二.更新路由

通过route命令或其他手动修改路由项的方式为静态路由更新方式.

对于大型路由器,它们通常用其他协议以发现路径并更新自己的路由表,而且这个过程是动态的,自动的.


2.5 IP转发

路由器都能执行数据报的转发操作,而主机一般只能发送和接受数据报(但是可以通过修改主机参数使其支持IP数据报转发).


2.6 重定向

用于更新路由项的方式有很多种,ICMP也是其中一种.

可以使用ping功能(因为它会发送ICMP数据报)对非路由器设备发起请求.接着收到回复(下次应访问哪个路由设备)并更新到路由表缓冲区(通过route -Cn查看).

一般来说主机只能接收ICMP重定向报文,而路由器只能发送ICMP重定向报文(可以通过修改主机参数使其支持接收/发送ICMP重定向报文)


2.7 IPv6头部结构

IPv6不仅解决了IPv4地址不够用的问题,还做了很大改进.

例如增加了多播和流的功能,为网络上多媒体内容的质量提供精细的控制;引入自动配置功能,使得局域网管理更方便;增加了专门的网络安全功能等等.

  • IPv6的头部结构由40字节的固定头部和可变长的扩展头部组成.

  • IPv6用了128位来表示IP地址,使得IP地址的总量达到了2128个.

  • IPv6地址用":"分割成8组,每组包含2个字节,不同于IPv4的使用点分十进制来表示.

  • IPv6并不是IPv4的简单扩展,而是完全独立的协议.IPv4数据报的以太网帧封装类型值是0x800,而IPv6是0x86dd.


关于第二章的总结

  • IP协议提供了一个无状态,无连接,不可靠的服务.

  • 主要了解了IP的头部结构,为报文的分片和重组提供帮组并指定源端与目的端IP地址.

  • IP数据报的路由和转发生在除目标机器之外的所有主机和路由器上.

  • 路由最核心的是路由表,它提供给据数据报一条最佳的传输路径,更新方法有通过协议自动更新和手动修改或者重定向.


From

Linux 高性能服务器编程 游双著 机械工业出版社

MarkdownPad2

2017/1/18 13:22:28

第二章 IP协议详解的更多相关文章

  1. linux高性能服务器编程 (二) --IP协议详解

    第二章 IP协议详解 什么是IP协议:IP 协议是TCP/IP协议族的动力,它为上层提供了无状态.无连接.不可靠的服务. IP 头部信息:头部信息会出现在每一个IP数据报上,便于记录IP通信的源端IP ...

  2. 【转载】TCP /IP协议详解

    首先,TCP/IP不是一个协议,而是一个协议族的统称. 里面包括了IP协议,IMCP协议,TCP协议,以及http.ftp.pop3协议等等. TCP/IP协议分层 提到协议分层,我们很容易联想到IS ...

  3. Cobalt Strike系列教程第二章:Beacon详解

    上周更新了Cobalt Strike系列教程第一章:简介与安装,文章发布后,深受大家的喜爱,遂将该系列教程的其他章节与大家分享,提升更多实用技能! 第二章:Beacon详解 一.Beacon命令 大家 ...

  4. TCP /IP协议详解【转】

    转自:https://www.jianshu.com/p/0cf648510bce?utm_campaign=maleskine&utm_content=note&utm_medium ...

  5. TCP/IP协议详解概述

    TCP/IP协议详解卷1--第一章概述--读书笔记 作者:vpoet 日期:2015/06/25 注:本系列的文章只是作者对TCP/IP协议的理解,难免会出现纰漏或者不完整,当然也有可能很肤浅,希望大 ...

  6. 第3章 TCP协议详解

    第3章 TCP协议详解 3.1 TCP服务的特点 传输协议主要有两个:TCP协议和UDP协议,TCP协议相对于UDP协议的特点是 面向连接使用TCP协议通信的双方必须先建立连接,完成数据交换后,通信双 ...

  7. IP协议详解(转)

    本文转载自博文协议森林05 我尽力 (IP协议详解).这篇博文写的很有趣味,特转载! IPv4与IPv6头部的对比 我们已经在IP接力中介绍过,一个IP包分为头部(header)和数据(payload ...

  8. TCP/IP协议详解---概述

        工作之后,才发现以前在学校里学的东西忘得太快太干净了,现在需要一点点地捡起来了,要不然写几行程序会闹很多笑话会出现很多bug的.从今天开始,翻一翻<TCP/IP协议详解 卷1>这本 ...

  9. (转)协议森林05 我尽力 (IP协议详解)

    协议森林05 我尽力 (IP协议详解) 作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! IPv4与IPv6头部的对比 我们已经在I ...

随机推荐

  1. Java中Class类及用法

    Java中Class类及用法 Java程序在运行时,Java运行时系统一直对所有的对象进行所谓的运行时类型标识,即所谓的RTTI.这项信息纪录了每个对象所属的类.虚拟机通常使用运行时类型信息选准正确方 ...

  2. easyui分页的使用方法

    使用: $("#tt").datagrid("getPager").pagination(option); 例子: $("#tb").dat ...

  3. 【luogu P2279 [HNOI2003]消防局的设立】 题解

    题目链接:https://www.luogu.org/problemnew/show/P2279 想怎么贪怎么贪 #include <queue> #include <cstdio& ...

  4. c++中如 <类名 类名::对象> 是什么意思

    CComplex CComplex::add(CComplex &x) (这一句 不懂为何 类名 类名::对象) { CComplex y(real+x.real,image+x.image) ...

  5. 阿里云修改主机名(以centOS为例)

    需要更改配置文件生效,修/etc/sysconfig/network里的 HOSTNAME=主机名(可自定义),重启生效. 如何修改? 1.[root@aliyunbaike ~]# cd /etc/ ...

  6. Office365完整离线安装包下载及自定义安装教程

    Office 365是微软打造的一款适用于教育机构使用的office办公软件,这里为大家提供了一个Office 365离线安装包下载工具,让office 365离线包下载到本地再安装,而不是联网下载安 ...

  7. NodeJ Koa2 安装使用 reeber

    介绍 Koa 是由 Express 原班人马打造的,致力于成为一个更小.更富有表现力.更健壮的 Web 框架. 使用 koa 编写 web 应用,通过组合不同的 generator,可以免除重复繁琐的 ...

  8. 转:30分钟了解Springboot整合Shiro

    引自:30分钟了解Springboot整合Shiro 前言:06年7月的某日,不才创作了一篇题为<30分钟学会如何使用Shiro>的文章.不在意之间居然斩获了22万的阅读量,许多人因此加了 ...

  9. TinyMCE插件:Filemanager [4.x-6.x] 图片自动添加水印

    上传图片程序(filemanager/upload.php) 在if (!empty($_FILES) && $upload_files)有一个move_uploaded_file() ...

  10. Android简单的编写一个txt阅读器(没有处理字符编码),适用于新手学习

    本程序只是使用了一些基本的知识点编写了一个比较简单粗陋的txt文本阅读器,效率不高,只适合新手练习.所以大神勿喷. 其实想到编写这种程序源自本人之前喜欢看小说,而很多小说更新太慢,所以本人就只能找一个 ...