1、第六讲原始套接字与数据链路访问任立勇电子科技大学计算机学院* 1目 录nTCP/IP协议族结构nIP数据报格式n原始套接字n一个简单的 DOS攻击程序nPing协议的 ICMP版本nTraceroute程序n数据链路层访问技术n一个数据链路访问的例子Date 2TCP/IP协议族结构应用层应用层IPv4, IPv6网络介质层网络介质层TCP UDPtcpdump mrouted ping traceroute Appl. Appl. Appl. Appl.TCP UDPICMPIGMPIPv4BPFDLPI 数据链路数据链路ARPRARPDate 3IPv4数据报格式n几点说明几点说明 : 首
2、部长度是以 32位(即 4字节)为单位; 16位的标识用于分片和重组; DF位(不分片); MF(还有片段);协议字段表示封装在 IP报文中的上层协议,典型的有: ICMP( 1)、IGMP( 2)、 TCP( 6)、 UDP( 17);头部校验和只对 IP头部(包括选项)计算,校验算法是标准的因特网校验和算法,即简单的16位反码求和。版本 总长度(字节长度)标识 片段偏移首部长度 服务类型0 DFMF存活时间( TTL) 头部校验和协议32位源地址32位目的地址选项(如果有的话)数据首部数据0 3 7 15 31Date 4IP数据报分片例子nIP数据报是指 I P 层端到端的传输单元(在分
3、片之前和重新组装之后),分组是指在 I P 层和链路层之间传送的数据单元。n需要重申的是,任何传输层首部只出现在第 1 片数据中。Date 5原始套接字(概述)n原始套接字提供了一些使用 tcp和 udp协议不能实现的功能,如:l使用原始套接字可以读写 ICMPv4、 IGMPv4分组。如Ping程序, mroute程序等;l使用原始套接字可以读些特殊的 IPv4数据包,内核不处理这些数据报的 IPv4协议字段。如大多数内核只处理ICMP、 IGMP、 TCP、 UDP的数据报。但协议字段还可以为其他值,如 OSPF直接使用 IP协议,将 IP数据报的协议字段设为 89,此时,就必须有专门的程
4、序通过原始套接字来处理它们;l利用原始套接字还可以创建自定义的 IP数据报首部,编写基于 IP协议的高层网络协议。Date 6原始套接字创建#include #include int socket(AF_INET, SOCK_RAW, int protocol);n protocol参数一般不能为 0,如: IPPROTO_ICMP。另外,只有超级用户才能创建原始套接字。n 用户可以通过设置 IP_HDRINCL选项来编写自己的 IP数据报首部:const int on = 1;setsockopt(sockfd, IPPROTO_IP, IP_HDRINCL, n 可以调用 bind函数绑定
5、原始套接字的本地 IP地址,此时,所有输出的数据报将用到源 IP地址(仅当 IP_HDRINCL未设置时);如果不调用bind函数,由内核将源 IP地址设成外出接口的主 IP地址;n 可以调用 connect函数设置数据报的目的地址(注意并不需要真正的连接)。此后,可直接调用 write或 send。n 注意: bind和 connect时,端口已经没有意义了 。Date 7通过原始套接字发送数据报n原始套接字的输出遵循以下规则:l 如果套接字已经连接,可以调用 write、 writev、 send来发送数据,否则需要调用 sendto或 sendmsg;l 如果 IP_HDRINCL选项未
6、设置,则内核写的数据起始地址指 IP头部之后的第一个字节。因为这种情况下,内核构造 IP头部,并将它安在来自进程的数据之前。内核将 IPv4头部的协议字段设置成用户在调用 socket函数所给的第三个参数;l 如果设置了 IP_HDRINCL,则内核写的数据起始地址指 IP头部的第一个字节。用户所提供的数据大小值必须包括头部的字节数。此时进程构造除了以下两项外的整个 IP头部;( a) IPv4标识字段可以设为 0,要求内核设置该值;( b) IPv4头部校验和由内核来计算和存储。 IPv4数据报首部各个字段的内容均是网络字节序(对 linux而言)l 对于超出外出接口的 MTU的分组,内核将
7、其分片。Date 8通过原始套接字接收数据报n内核通过原始套接字接收数据报,遵循以下规则:l接收到的 tcp和 udp分组决不会传递给原始套接字,如果一个进程希望读取包含 tcp或 udp分组的 IP数据报,那么它们必须在数据链路层读入;l当内核处理完 ICMP消息后,绝大部分 ICMP分组将传递给原始套接字。对源自 Berkeley的实现,除了回射请求、时间戳请求和地址掩码请求将完全由内核处理以外,所有收到的 ICMP分组将传递给某个原始套接口;l当内核处理完 IGMP消息后,所有 IGMP分组都将传递给某个原始套接字;l所有带有内核不能识别的协议字段的 IP数据报都将传递给某个原始套接字。
8、l如果数据报以分片形式到达,则该分组将在所有片段到达并重组后才传给原始套接字。Date 9通过原始套接字接收数据报(续)n 在将一个 IP数据报传递给某个套接字之前,内核需要选择匹配的原始套接字:l 如果在创建原始套接字时,所指定的 protocol参数不为 0,则接收到的数据包的协议字段应与该值匹配,否则该数据报将不传递给该套接字;l 如果此原始套接字之上绑定了一个本地 IP地址,那么接收到的数据报的目的 IP地址应与该绑定地址相匹配,否则该数据报将不传递给该套接字;l 如果此原始套接字通过调用 connect指定了一个对方的 IP地址,那么接收到的数据报的源 IP地址应与该已连接地址相匹配,否则该数据报将不传递给该套接字。l 如果一个原始套接字以 protocol参数为 0的方式创建,而且未调用bind或 connect,那么对于内核传递给原始套接字的每一个原始数据报,该套接字都会收到一份拷贝;l 当接收到的数据报传递给当接收到的数据报传递给 IPv4原始套接字时,整个数据报(包括原始套接字时,整个数据报(包括 IP头部)都将传递给进程头部)都将传递给进程 。而对于 IPv6,则将去除扩展头部。Date 10