2010-04-17 18:56:00 WXJWHQWY 阅读数 554
  • 从理论到实战:在园区网中部属IPv6

           本课程系统的介绍了IPv6的基本特点、地址结构、地址分类、报文格式、ICMPv6、常用的IPv6路由技术(静态路由和OSPFv3)、隧道技术等知识,实验部分通过华为ensp模拟器完成。最后通过工程项目案例使学员掌握如何在园区网中进行层次化的IPv6地址分配、路由设置优化、部署给予IPv6的应用、并掌握IPv6故障排除的基本技能,项目中主要使用华为厂商的网络设备。

    1269 人正在学习 去看看 马青

 

清华大学出版社

伍孝金

9787302223528

本书介绍IPv6技术的概念、基本原理及主要的理论知识,阐述IPv6技术的特点;同时在实践应用方面,依托于校园网组建的IPv6实验室进行一系列的实验,论述IPv6技术的一些具体应用的实现方法。

全书共分8章。内容包括IPv6概述、ICMPv6及邻居发现协议、IPv6路由技术和路由协议、套接字编程、IPv6过渡机制、IPv6的基本应用、IPv6安全机制和移动IPv6。特别要注意的是,每章都附有IPv6的实验和应用,这些实验和应用都是基于Linux平台的,具有开放性和扩展性,可以满足读者进一步学习和研究的需要。

本书不仅理论翔实,同时注重实践应用,适合从事计算机网络、IPv6网络技术的高校师生和工程技术人员阅读,对于正在从事IPv6相关研究和开发的工程技术人员,本书也具有较高的参考价值。

2017-07-03 16:58:48 qq_22530197 阅读数 296
  • 从理论到实战:在园区网中部属IPv6

           本课程系统的介绍了IPv6的基本特点、地址结构、地址分类、报文格式、ICMPv6、常用的IPv6路由技术(静态路由和OSPFv3)、隧道技术等知识,实验部分通过华为ensp模拟器完成。最后通过工程项目案例使学员掌握如何在园区网中进行层次化的IPv6地址分配、路由设置优化、部署给予IPv6的应用、并掌握IPv6故障排除的基本技能,项目中主要使用华为厂商的网络设备。

    1269 人正在学习 去看看 马青

1.IP协议簇
通常使用的是IPV4和IPV6,但是网络中还存在别的协议簇
unix域协议,路由套接字密匙套接字。
2.bind函数,就是绑定也就是说服务器端将端口和地址绑定到套接字上,事实上所谓的套接字编程就是说将将所有应用层一下的所需要的参数绑定到套接字上,然后我们操作的函数都是这个套接字
3.listen函数;监听
4.accept这个等待连接,也就是说等待客户端进行connet,一旦有客户端连接就进入三次握手阶段。

2.并发服务器
并发服务器的概念很简单,就是说我们创建一个服务器,并不是只给一个客户端使用的,会有很多客户端进行连接,然后获取服务器的数据的,最简单的办法就是使用fork传进一个子进程,子进程的责任就是负责收发,使用fork创建的子进程是父进程的一个副本,会享受创建之前父进程定义的所有变量。

#include <unistd.h>  
#include <stdio.h>   
int main ()   
{   
    pid_t fpid; //fpid表示fork函数返回的值  
    int count=0;  
    fpid=fork();   
    if (fpid < 0)   
        printf("error in fork!");   
    else if (fpid == 0) {  
        printf("i am the child process, my process id is %d/n",getpid());   
        printf("我是爹的儿子/n");//对某些人来说中文看着更直白。  
        count++;  
    }  
    else {  
        printf("i am the parent process, my process id is %d/n",getpid());   
        printf("我是孩子他爹/n");  
        count++;  
    }  
    printf("统计结果是: %d/n",count);  
    return 0;  
}

使用getsockname和geteername获取地址个地址长度

2018-11-11 15:17:48 shanggamo 阅读数 430
  • 从理论到实战:在园区网中部属IPv6

           本课程系统的介绍了IPv6的基本特点、地址结构、地址分类、报文格式、ICMPv6、常用的IPv6路由技术(静态路由和OSPFv3)、隧道技术等知识,实验部分通过华为ensp模拟器完成。最后通过工程项目案例使学员掌握如何在园区网中进行层次化的IPv6地址分配、路由设置优化、部署给予IPv6的应用、并掌握IPv6故障排除的基本技能,项目中主要使用华为厂商的网络设备。

    1269 人正在学习 去看看 马青

各函数原型:

int socket(int family, int type, int protocol);
/*
family:指定使用的协议族:AF_INET(IPv4) AF_INET6(IPv6) AF_LOCAL(UNIX协议) AF_ROUTE(路由套接字) AF_KEY(秘钥套接字)
type:指定使用的套接字的类型:SOCK_STREAM(字节流套接字) SOCK_DGRAM
protocol:如果套接字类型不是原始套接字,那么这个参数为0
*/

int bind(int sockfd, struct sockaddr *myaddr, int addrlen);
/*
sockfd:socket函数返回的套接字描述符
myaddr:指向本地IP地址的结构体指针
struct sockaddr{
     unsigned short sa_family; //通信协议类型族AF_xx
     char sa_data[14];  //14字节协议地址,包含该socket的IP地址和端口号
 };
struct sockaddr_in{
     short int sin_family; //通信协议类型族
     unsigned short int sin_port; //端口号
     struct in_addr sin_addr; //IP地址
     unsigned char si_zero[8];  //填充0以保持与sockaddr结构的长度相同
 };
myaddrlen:结构长度
*/

int connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen);
/*
sockfd:socket函数返回套接字描述符
serv_addr:服务器IP地址结构指针
addrlen:结构体指针的长度
*/

int listen(int sockfd, int backlog);
/*
sockfd:socket函数绑定bind后套接字描述符
46 backlog:设置可连接客户端的最大连接个数,当有多个客户端向服务器请求时,收到此值的影响。默认值20
*/
int accept(int sockfd, struct sockaddr *cliaddr, socklen_t *addrlen);
/*
sockfd:socket函数经过listen后套接字描述符
cliaddr:客户端套接字接口地址结构
addrlen:客户端地址结构长度
*/

int send(int sockfd, const void *msg, int len, int flags);
int recv(int sockfd, void *buf, int len, unsigned int flags);
/*
sockfd:socket函数的套接字描述符
msg:发送数据的指针
buf:存放接收数据的缓冲区
len:数据的长度,把flags设置为0
*/

服务器ser.c

#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<signal.h>
#include<unistd.h>
#include<stdlib.h>
#include<assert.h>
#include<stdio.h>
#include<string.h>

int main()
{
struct sockaddr_in ser, cli;
int fd, new_fd, struct_len, numbytes;
char buff[127] = {0};

ser.sin_family = AF_INET;
ser.sin_port = htons(6000);
ser.sin_addr.s_addr = INADDR_ANY;
bzero(&(ser.sin_zero), 8);
struct_len = sizeof(struct sockaddr_in);

fd = socket(AF_INET, SOCK_STREAM, 0);
bind(fd, (struct sockaddr*)&ser, struct_len);
listen(fd, 20);
new_fd = accept(fd, (struct sockaddr*)&cli, &struct_len);
numbytes = send(new_fd, "start writing\n", 14, 0);

while(1)
{
numbytes = recv(new_fd, buff, 127, 0);
if(strcmp(buff,"end")==0)
{
printf("one cli end\n");
break;
}
buff[numbytes] = '\0';
printf("%s\n", buff);
}
close(new_fd);
close(fd);
return 0;
}

客户端cli.c

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<arpa/inet.h>
int main()
{
	struct sockaddr_in their_addr;
	int sockfd, numbytes;
	char buff[127];
	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	their_addr.sin_family = AF_INET;
	their_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
	their_addr.sin_port = htons(6000);
	bzero(&(their_addr.sin_zero), 8);

	connect(sockfd, (struct sockaddr*)&their_addr, sizeof(struct sockaddr));
	numbytes = recv(sockfd, buff, 127, 0);
	buff[numbytes] = '\0';
	printf("%s", buff);
	while (1)
	{
		scanf("%s", buff);
		send(sockfd, buff, strlen(buff), 0);
		if (strcmp(buff, "end") == 0)
		{
			break;
		}
		printf("OK\n");
	}
	close(sockfd);
	return 0;
}
2013-05-23 12:27:00 Simba888888 阅读数 6509
  • 从理论到实战:在园区网中部属IPv6

           本课程系统的介绍了IPv6的基本特点、地址结构、地址分类、报文格式、ICMPv6、常用的IPv6路由技术(静态路由和OSPFv3)、隧道技术等知识,实验部分通过华为ensp模拟器完成。最后通过工程项目案例使学员掌握如何在园区网中进行层次化的IPv6地址分配、路由设置优化、部署给予IPv6的应用、并掌握IPv6故障排除的基本技能,项目中主要使用华为厂商的网络设备。

    1269 人正在学习 去看看 马青

一、IP数据报格式

IP数据报格式如下:


注:需要注意的是网络数据包以大端字节序传输,当然头部也得是大端字节序,也就是说:

The most significant bit is numbered 0 at the left, and the least significant bit of a 32-bit value is numbered 31 on the right.

The 4 bytes in the 32-bit value are transmitted in the order: bits 0-7 first, then bits 8-15, then 16-23, and bits 24-31 last. This is called big endian byte ordering, which is the byte ordering required for all binary integers in the TCP/IP headers as they traverse a network. This is called the network byte order. Machines that store binary integers in other formats, such as the little endian format, must convert the header values into the network byte order before transmitting the data.


版本
IP协议版本号,长度为4位,IPv4此字段值为4,IPv6此字段值为6


首部长度
以32位的字为单位,该字段长度为4位,最小值为5,即不带任何选项的IP首部20个字节;最大值为15,所以首部长度最大为60个字节


服务类型(TOS)
长度为8位。此字段包含3位的优先权(现已忽略),4位的服务类型子字段(只能有一位置1)和1位的保留位(必须置0)。4位的服务类型分别为最小延迟(D)、最大吞吐量(T)、最高可靠性(R)、最小费用(F),如下图。



总长度
该字段长度为16位,以字节为单位,该字段长度包含IP的头部和数据部分(payload)。IP数据报最大可达65535个字节。

The total length field is required in the IP header since some data links (e.g., Ethernet) pad small frames to be a minimum length.

when a datagram is fragmented the total length field of each fragment is changed to be the size of that fragment.


标识
16位标识,用来标识一个IP数据报,每发送一个此值会加1,可用于分片和重新组装成数据报。


标志与片偏移

3位标志其中第一位不使用, 每二位DF(Don’t Fragment),该位如果为1,如果传输的数据报超过最大传输单元,该数据报会被丢弃,并发送一个ICMP差错报文。第三位MF(More Fragment)表示是否有更多的片,该位为1,说明后续有分片。最后一片MF为0。


注:在这里稍微讲一下IP层分片的问题。假设一个IP数据报大于最大传输单元MTU,那么如果设置了分片标志位,将会被分片传输。

每一片都有自己的IP 头部,IP头部中的标识是一样的,但是片偏移不同(以8字节为单位)。除了最后一片,分片要求其他片除去IP头部的大小必须是8字节的整数倍。除了第一片有tcp/udp头部,其他片都没有。分片完成后,每一片独自成为一个数据包(跟数据报概念不同,参见这里),可以走不同的路由,最后到达目的地的时候IP层根据它们各自IP头部的信息重新组成一个IP数据报

分片是有风险的,因为一旦某一片丢失,就需要重传这个IP数据报,因为IP层本身并没有超时重传的机制,可靠性需要TCP层来保证(一些UDP协议的可靠性由应用程序保证),一旦一个TCP段中的某一片丢失,TCP协议层会超时重传。此外,分片可以发生在源主机或者中间的路由,如果发生在中间的路由,源主机根本不知道是怎样分片,所以要尽量避免分片。

应用数据的多个IP数据报由TCP层根据seq number 进行重组成原始数据,存放到TCP接收缓冲区。

Using sequence numbers, a receiving TCP discards duplicate segments and reorders segments that arrive out of order. Recall that any of these anomalies can happen because TCP uses IP to deliver its segments, and IP does not provide duplicate elimination or guarantee correct ordering. Because it is a byte stream protocol, however, TCP never delivers data to the receiving application out of order. Thus, the receiving TCP may be forced to hold on to data with larger sequence numbers before giving it to an application until a missing lower-sequence-numbered segment (a “hole”) is filled in.



实战经验:在使用tcpdump 并指定端口时,如果分片传输,除第一片外,其他片可能捕捉不到。



TTL
TTL(Time To Live)表示数据报最多可经过的路由器的数量。数据报每经过一个路由器,TTL减1,减为0时丢弃,并发送ICMP报文通知源主机。TTL可以避免数据报在路由器之间不断循环。


协议类型
表示IP层上承载的是哪个高级协议。在封装与分用的过程中,协议栈知道该交给哪个层的协议处理。1 ICMP 2 IGMP 6 TCP 17UDP


头部校验和
保证数据报头部的数据完整性,但校验不包括数据部分。这样做的目的有二:一是所有将数据封装在IP数据包中的高层协议均含有覆盖整个数据的校验和,因此IP数据报没有必要再对其所承载的数据部分进行校验。二是每经过一个路由器,IP数据报的头部要发生改变(如TTL),而数据部分不变,这样只对发生改变的头部进行校验,显然不会浪费太多的时间。为了减少计算时间,一般不用CRC校验码,而是采用更简单的网际校验和(Internet Checksum)。

Since a router often changes only the TTL field (decrementing it by 1), a router can incrementally update the checksum when it forwards a received datagram, instead of calculating the checksum over the entire IP header again.

The standard BSD implementation, however, does not use this incremental update feature when forwarding a datagram.


源IP地址
发送数据的主机IP地址


目的IP地址
接收数据的主机IP地址


选项与填充(选项为4字节整数倍,否则用0填充)
安全和处理限制
路径记录:记录所经历路由器的IP地址
时间戳:记录所经历路由器的IP地址和时间
宽松源站路由:指定数据报文必须经历的IP地址,可以经过没有指定的IP地址。
严格的源站路由:指定数据报文必须经历的IP地址,不能经过没有指定的IP地址。


二、IP地址与路由

IPv4的IP地址长度为4字节,通常采用点分十进制表示法(dotted decimal representation)例如0xc0a80002表示为192.168.0.2。Internet被各种路由器和网关设备分隔成很多网段,为了标识不同的网段,需要把32位的IP地址划分成网络号和主机号两部分,网络号相同的各主机位于同一网段,相互间可以直接通信,网络号不同的主机之间通信则需要通过路由器转发。


In our general scheme, IP can receive a datagram from TCP, UDP, ICMP, or IGMP (that is, a locally generated datagram) to send, or one that has been received from a network interface (a datagram to forward). The IP layer has a routing table in memory that it searches each time it receives a datagram to send. When a datagram is received from a network interface, IP first checks if the destination IP address is one of its own IP addresses or an IP broadcast address. If so, the datagram is delivered to the protocol module specified by the protocol field in the IP header. If the datagram is not destined for this IP layer, then (1) if the IP layer was configured to act as a router the packet is forwarded (that is, handled as an outgoing datagram as described below), else (2) the datagram is silently discarded.


假设某主机上的网络接口配置和路由表如下:


这台主机只有一个网络接口连到192.168.232.0/24网络。路由表的Destination是目的网络地址,Genmask是子网掩码,Gateway是下一跳地址,Iface是发送接口,Flags中的U标志表示此条目有效(可以禁用某些条目),G标志表示此条目的下一跳地址是某个路由器的地址,没有G标志的条目表示目的网络地址是与本机接口直接相连的网络,不必经路由器转发,因此下一跳地址处记为*号。
如果要发送的数据包的目的地址是192.168.232.1,跟第三行的子网掩码做与运算得到192.168.232.0,正是第三行的目的网络地址,因此从eth0接口发送出去,由于192.168.232.0/24正是与eth0接口直接相连的网络,因此可以直接发到目的主机,不需要经路由器转发。
如果要发送的数据包的目的地址是202.10.1.2,跟后两行路由表条目都不匹配,那么就要按缺省路由条目,从eth0接口发出去,首先发往192.168.232.2 路由器,再让路由器根据它的路由表决定下一跳地址。

A complete matching host address is searched for before a matching network ID. Only if both of these fail is a default route used.


路由的处理过程如下,ARP部分可以参考这里


参考:

《Linux C 编程一站式学习》

《TCP/IP详解 卷一》


2019-10-14 16:06:21 weixin_44367006 阅读数 36
  • 从理论到实战:在园区网中部属IPv6

           本课程系统的介绍了IPv6的基本特点、地址结构、地址分类、报文格式、ICMPv6、常用的IPv6路由技术(静态路由和OSPFv3)、隧道技术等知识,实验部分通过华为ensp模拟器完成。最后通过工程项目案例使学员掌握如何在园区网中进行层次化的IPv6地址分配、路由设置优化、部署给予IPv6的应用、并掌握IPv6故障排除的基本技能,项目中主要使用华为厂商的网络设备。

    1269 人正在学习 去看看 马青

目录

 

IP服务的特点

IPv4 头部结构

介绍

使用 tcpdump 观察 IPv4 头部结构

IP 分片

介绍

使用 tcpdump 观察 IP 分片

IP路由

IP 模块工作流程

路由机制

IP转发

重定向

ICPM 重定向报文

IPv6 头部结构

IPv6 固定头部结构

IPv6 扩展头部


IP服务的特点

IP协议是TCP/IP协议族的动力,它为上层协议提供无状态无连接不可靠的服务。

无状态(stateless)是指IP通信双方不同步传输数据的状态信息,因此所有IP数据报的发送、传输和接收都是相互独立、没有上下文关系的。
缺点:无法处理乱序重复的IP数据报。比如发送端发送出的第N个IP数据报可能比第N+1个IP数据报后到达接收端,而同一个IP数据报也可能经过不同的路径多次到达接收端。
接收端的IP模块只要收到了完整的IP数据报(如果是IP分片的话,IP模块将先执行重组),就将其数据部分上交给对应的上层协议。那么从上层协议来看,这些数据就可能是乱序的、重复的。面向连接的协议,比如TCP协议,则能够自己处理乱序的、重复的报文段,它递交给上层协议的内容绝对是有序的、正确的。
优点:简单、高效。我们无须为保持通信的状态而分配一些内核资源,也无须每次传输数据时都携带状态信息。

无连接(connectionless)是指 IP 通信双方都不长久地维持对方的任何信息。这样,上层协议每次发送数据的时候,都必须明确指定对方的IP地址。

不可靠是指IP协议不能保证IP数据报准确地到达接收端,它只是承诺尽最大努力(best effort)。
很多种情况都能导致IP数据报发送失败。比如,某个中转路由器发现IP数据报在网络上存活的时间太长,那么它将丢弃之,并返回一个ICMP错误消息(超时错误)给发送端。又比如,接收端发现收到的IP数据报不正确(通过校验机制),它也将丢弃之,并返回一个ICMP错误消息(IP头部参数错误)给发送端。无论哪种情况,发送端的IP模块一旦检测到IP数据报发送失败,就通知上层协议发送失败,而不会试图重传
因此,使用IP服务的上层协议(比如TCP协议)需要自己实现数据确认、超时重传等机制以达到可靠传输的目的。



IPv4 头部结构

介绍

IPv4的头部结构如图2-1所示。其长度通常为20字节,除非含有可变长的选项部分。

  • 4位版本号(version)指定IP协议的版本。对IPv4来说,其值是4。
  • 4位头部长度(header length)标识该IP头部有多少个32bit字(4字节,一行)。因为4位最大能表示15,所以IP头部最长是60字节。
  • 8位服务类型(Type Of Service,TOS)包括一个3位的优先权字段(现在已经被忽略),4位的TOS字段和1位保留字段(必须置0)。4位的TOS字段分别表示:最小延时,最大吞吐量,最高可靠性和最小费用。其中最多有一个能置为1,应用程序应该根据实际需要来设置它。比如像ssh和telnet这样的登录程序需要的是最小延时的服务,而文件传输程序ftp则需要最大吞吐量的服务。
  • 16位总长度(total length)是指整个IP数据报的长度,以字节为单位,因此IP数据报的最大长度为65535(2^{16} - 1)字节。但由于MTU(Maximum Transmission Unit,最大传输单元)的限制,长度超过MTU的数据报都将被分片传输,所以实际传输的IP数据报(或分片)的长度都远远没有达到最大值。接下来的3个字段则描述了如何实现分片
  • 16位标识(identification)唯一地标识主机发送的每一个数据报。其初始值由系统随机生成:每发送一个数据报,其值就加1。该值在数据报分片时被复制到每个分片中,因此同一个数据报的所有分片都具有相同的标识值
  • 3位标志字段的第一位保留。第二位(Don't Fragment,DF)表示“禁止分片”。如果设置了这个位,IP模块将不对数据报进行分片。在这种情况下,如果IP数据报长度超过MTU的话,IP模块将丢弃该数据报并返回一个ICMP差错报文。第三位(More Fragment,MF)表示“更多分片”。除了数据报的最后一个分片外,其他分片都要把它置1。
  • 13位分片偏移(fragmentation offset)是分片相对原始IP数据报开始处(仅指数据部分)的偏移。实际的偏移值是该值左移3位(乘8)后得到的。由于这个原因,除了最后一个IP分片外,每个IP分片的数据部分的长度必须是8的整数倍(这样才能保证后面的IP分片拥有一个合适的偏移值)。
  • 8位生存时间(Time To Live,TTL)是数据报到达目的地之前允许经过的路由器跳数。TTL值被发送端设置(常见的值是64)。数据报在转发过程中每经过一个路由,该值就被路由器减1。当TTL值减为0时,路由器将丢弃数据报,并向源端发送一个ICMP差错报文。TTL值可以防止数据报陷入路由循环。
  • 8位协议(protocol)用来区分上层协议。/etc/protocols 文件定义了所有上层协议对应的protocol字段的数值。其中,ICMP是1,TCP是6,UDP是17。
  • 16位头部校验和(header checksum)由发送端填充,接收端对其使用CRC算法以检验IP数据报头部(注意,仅检验头部)在传输过程中是否损坏。
  • 32位的源端IP地址目的端IP地址用来标识数据报的发送端和接收端。一般情况下,这两个地址在整个数据报的传递过程中保持不变,而不论它中间经过多少个中转路由器。
  • IPv4最后一个选项字段(option)是可变长的可选信息。这部分最多包含40字节。可用的IP选项包括:
    记录路由(record route),告诉数据报途经的所有路由器都将自己的IP地址填入IP头部的选项部分,这样我们就可以跟踪数据报的传递路径。
    时间戳(timestamp),告诉每个路由器都将数据报被转发的时间(或时间与IP地址对)填入IP头部的选项部分,这样就可以测量途经路由之间数据报传输的时间。
    松散源路由选择(loose source routing),指定一个路由器IP地址列表,数据报发送过程中必须经过其中所有的路由器。
    严格源路由选择(strict source routing),和松散源路由选择类似,不过数据报只能经过被指定的路由器。
    这些选项字段很少被使用,使用松散源路由选择和严格源路由选择选项的例子大概仅有 traceroute 程序。此外,作为记录路由IP选项的替代品,traceroute 程序使用UDP报文和ICMP报文实现了更可靠的记录路由功能。

使用 tcpdump 观察 IPv4 头部结构

会话A:tcpdump -ntx -i lo

用tcpdump抓取会话B中telnet客户端程序和telnet服务器程序之间交换的数据包

会话B:telnet 127.0.0.1

telent 登录本机

4位一个十六进制数,8位一个字节。上面的 4510 就是4个十六进制数,16位。
IP 首部20字节,也就是160位,要10个 4510 这种长度的数。从 4510 003c 到 7f00 0001 是 IP 首部。

对应图2-1,可知:

4510:IP 版本号4,头部长度5个32位(20字节),TOS 为十六进制10(二进制:0001 0000)最小延时服务;003c:总长度
71d2:标识 ;4000:0100 0000 0000 0000,前3位表示标志,第二位为1,禁止分片,片偏移0
4006:生存时间 4*16 + 0 = 64 次,协议 6,表示上层协议为 TCP 协议;cad7:头部校验和
7f00 0001:源端 IP 地址,7f:0111 1111 ,127
7f00 0001:目的端 IP 地址



IP 分片

介绍

当IP数据报的长度超过帧的MTU时,它将被分片传输。分片可能发生在发送端,也可能发生在中转路由器上,而且可能在传输过程中被多次分片,但只有在最终的目标机器上,这些分片才会被内核中的IP模块重新组装。

IP头部中的如下三个字段给IP的分片和重组提供了足够的信息:数据报标识、标志和片偏移。一个IP数据报的每个分片都具有自己的IP头部,它们具有相同的标识值,但具有不同的片偏移。并且除了最后一个分片外,其他分片都将设置MF标志。此外,每个分片的IP头部的总长度字段将被设置为该分片的长度

以太网帧的MTU是1500字节(可以通过ifconfig命令或者netstat命令查看),因此它携带的IP数据报的数据部分最多是1480字节(IP头部至少占用20字节)。


使用 tcpdump 观察 IP 分片

考虑用IP数据报封装一个长度为1481字节的ICMP报文(包括8字节的ICMP头部,所以其数据部分长度为1473字节),则该数据报在使用以太网帧传输时必须被分片,如图2-2所示。

会话A:

tcpdump -ntv -i ens33 icmp #只抓取ICMP报文

会话B:

ping 192.168.100.1 -s 1473 #指定每次发送1473字节数据,加ICMP首部1481,加IP首部1501

id 表示标识,都是51591表示是同一 IP 的分片;flags [+] 表示设置了 MF 标志,还有后续分片。



IP路由

IP协议的一个核心任务是数据报的路由,即决定发送数据报到目标机器的路径。

IP 模块工作流程

IP模块基本工作流程如图2-3所示,从右往左来分析。

当IP模块接收到来自数据链路层的IP数据报时:

1. 首先对该数据报的头部做CRC校验,确认无误之后就分析其头部的具体信息。
2. 如果该IP数据报的头部设置了源站选路选项(松散源路由选择或严格源路由选择),则IP模块调用数据报转发子模块来处理该数据报。
3. 如果该IP数据报的头部中目标IP地址是本机的某个IP地址,或者是广播地址,即该数据报是发送给本机的,则IP模块就根据数据报头部中的协议字段来决定将它派发给哪个上层应用(分用)。
4. 如果IP模块发现这个数据报不是发送给本机的,则也调用数据报转发子模块来处理该数据报。
5. 数据报转发子模块将首先检测系统是否允许转发。如果不允许,IP模块就将数据报丢弃。如果允许,数据报转发子模块将对该数据报执行一些操作,然后将它交给IP数据报输出子模块(图中的“路由表”、“计算下一跳路由”和“IP输出队列”
6. IP数据报应该发送至哪个下一跳路由(或者目标机器),以及经过哪个网卡来发送,就是IP路由过程,即图2-3中“计算下一跳路由”子模块。IP模块实现数据报路由的核心数据结构是路由表。这个表按照数据报的目标IP地址分类,同一类型的IP数据报将被发往相同的下一跳路由器(或者目标机器)。
7. IP输出队列中存放的是所有等待发送的IP数据报,其中除了需要转发的IP数据报外,还包括封装了本机上层数据(ICMP报文、TCP报文段和UDP数据报)的IP数据报。图2-3中的虚线箭头显示了路由表更新的过程。这一过程是指通过路由协议或者route命令调整路由表,使之更适应最新的网络拓扑结构,称为IP路由策略。


路由机制

要研究IP路由机制,需要先了解路由表的内容。我们可以使用route命令或netstat命令查看路由表。

那么路由表是如何按照IP地址分类的呢?或者说给定数据报的目标IP地址,它将匹配路由表中的哪一项呢?这就是IP的路由机制,分为3个步骤:
1)查找路由表中和数据报的目标IP地址完全匹配的主机IP地址。如果找到,就使用该路由项,没找到则转步骤2。
2)查找路由表中和数据报的目标IP地址具有相同网路ID的网络IP地址(169.254.0.*和192.168.100.*)。如果找到,就使用该路由项:没找到则转步骤3。
3)选择默认路由项,这通常意味着数据报的下一跳路由是网关。所有访问因特网的请求都将通过网关来转发(匹配默认路由项)。



IP转发

前文提到,不是发送给本机的IP数据报将由数据报转发子模块来处理。路由器都能执行数据报的转发操作,而主机一般只发送和接收数据报,这是因为主机上/proc/sys/net/ipv4/ip_forward内核参数默认被设置为0。

若要使本机具备转发功能:

echo 1 > /proc/sys/net/ipv4/ip_forward

对于允许IP数据报转发的系统(主机或路由器),数据报转发子模块将对期望转发的数据报执行如下操作:
1)检查数据报头部的TTL值。如果TTL值已经是0,则丢弃该数据报。
2)查看数据报头部的严格源路由选择选项。如果该选项被设置,则检测数据报的目标IP地址是否是本机的某个IP地址。如果不是,则发送一个ICMP源站选路失败报文给发送端。
3)如果有必要,则给源端发送一个ICMP重定向报文,以告诉它一个更合理的下一跳路由器。
4)将TTL值减1。
5)处理IP头部选项。
6)如果有必要,则执行IP分片操作。



重定向

ICPM 重定向报文也能更新路由表

ICPM 重定向报文

ICMP重定向报文的类型值是。代码字段有4个可选值,用来区分不同的重定向类型,主机重定向代码值为1。
ICMP重定向报文的数据部分含义很明确,它给接收方提供了如下两个信息:
1. 应该使用的路由器的IP地址
2. 引起重定向的IP数据报(即图2-4中的原始IP数据报)的源端IP地址
接收主机根据这两个信息就可以断定引起重定向的IP数据报应该使用哪个路由器来转发,并且以此来更新路由表(通常是更新路由表缓冲,而不是直接更改路由表)。

/proc/sys/net/ipv4/conf/all/send_redirects内核参数指定是否允许发送ICMP重定向报,而/proc/sys/net/ipv4/conf/all/accept_redirects内核参数则指定是否允许接收ICMP重定向报文。
一般来说,主机只能接收ICMP重定向报文,而路由器只能发送ICMP重定向报文。



IPv6 头部结构

IPv6协议是网络层技术发展的必然趋势。它不仅解决了IPv4地址不够用的问题,还做了很大的改进。比如,增加了多播和流的功能,为网络上多媒体内容的质量提供精细的控制;引入自动配置功能,使得局域网管理更方便;增加了专门的网络安全功能等。

IPv6头部由40字节的固定头部可变长的扩展头部组成。

IPv6 固定头部结构

  • 4位版本号(version)指定IP协议的版本。对IPv6来说,其值是6。
  • 8位通信类型(traffic class)指示数据流通信类型或优先级,和IPv4中的TOS类似。
  • 20位流标签(flow label)是IPv6新增加的字段,用于某些对连接的服务质量有特殊要求的通信,比如音频或视频等实时数据传输。
  • 16位净荷长度(payload length)指的是IPv6扩展头部和应用程序数据长度之和,不包括固定头部长度。
  • 8位下一个包头(next header)指出紧跟IPv6固定头部后的包头类型,如扩展头(如果有的话)或某个上层协议头(比如TCP,UDP或ICMP)。它类似于IPv4头部中的协议字段,且相同的取值有相同的含义。
  • 8位跳数限制(hop limit)和IPv4中的TTL含义相同。

IPV6用128位(16字节)来表示IP地址,使得IP地址的总量达到了2^{128}个。所以有人说,“IPv6使得地球上的每粒沙子都有一个IP地址”。

32位表示的IPv4地址一般用点分十进制来表示,而IPv6地址则用十六进制字符串表示,比如“FE80:0000:0000:0000:1234:5678:0000:0012”。可见,IPv6地址用“:”分割成8组,每组包含2字节。但这种表示方法过于麻烦,通常可以使用所谓的零压缩法来将其简写,也就是省略连续的、全零的组。比如,上面的例子使用零压缩法可表示为
“FE80::1234:5678:0000:0012”。不过零压缩法对一个IPv6地址只能使用一次,比如上面的例子中,字节组“5678”后面的全零组就不能再省略,否则我们就无法计算每个“:”之间省略了多少个全零组。


IPv6 扩展头部

可变长的扩展头部使得IPv6能支持更多的选项,并且很便于将来的扩展需要。它的长度可以是0,表示数据报没使用任何扩展头部。一个数据报可以包含多个扩展头部,每个扩展头部的类型由前一个头部(固定头部或扩展头部)中的下一个报头字段指定。目前可以使用的扩展头部如表2-3所示。

QtNetworkdemo

阅读数 24

没有更多推荐了,返回首页