原始套接字

1. 前言

原始套接字是一种较为底层的套接字,使用它可以直接发送或接收IP层数据包,因此具有较大的灵活性。通常被用于抓包、测试等领域。

2. IP数据包协议格式

现在最常见的是IPv4协议,格式定义如下:

ipv4

2.1. IP字段解释

版本: ipv4中固定为4

首部长度: ip头的长度,ipv4中包头长度固定为20,该字段的值为520/4

服务类型: 一般设为0

总长度: IP数据包的总长度(包含包头)

标识: 用来标识IP数据包,当IP包分片时,所有分片需要使用相同的标识

标志: 共3位

  • 第1位为保留位
  • 第2位为DF(Don't Fragment)位,为1表示不允许分片
  • 第3位为MF(More Fragment)位,为1表示后面还有分片,为0表示是最后一个分片

片偏移: 当IP包分片的时候,当前分片在原IP包中的偏移值。片偏移以8字节为偏移单元

生存时间: TTL(Time To Live) 每经过一个路由器,TTL值减一,如果该值为0,则丢弃该数据包

协议: 传输层使用的协议

常见协议定义如下:

协议号 协议类型
1 ICMP
2 IGMP
6 TCP
17 UDP
47 GRE
136 UDPLITE

首部校验和: 只对IP头计算校验和,以减少计算量

源IP地址: 发送IP数据包的主机地址。请求包经过NAT设备时,该值会发生变化

目的IP地址: IP数据包要发送的目的地址。返回包经过NAT设备时,该值会发生变化

选项: 目前IP数据包都没有该字段,因此IP数据包固定长度为20

3. 使用原始套接字

3.1. 创建socket对象

s = socket.socket(socket.AF_INET, socket.SOCK_RAW, protocol)

与创建TCPUDP socket对象不同,这里传入的typesocket.SOCK_RAW,表示是原始套接字。

protocol字段传入的值与IP协议中的协议字段的值是一致的。

3.2. 绑定地址

s.bind(('127.0.0.1', 0))

绑定的ip地址必须是某一网卡的ip地址,这样才能抓取该网卡收发的数据包。

3.3. 接收数据包

buff, addr = s.recvfrom(4096)

3.4. 发送数据包

s.sendto(buff, (ip, port))

可以看到,原始套接字与UDP通信还是挺像的。

4. 使用原始套接字实现ping程序

ping是一个用来检测网络连通性的常用工具,使用ICMP协议进行通信。

4.1. ICMP协议格式

icmp

ICMP字段解释

ICMP包头共8个字节,前4个字节定义如下:

类型: ICMP数据包类型,常见类型定义如下:

TYPE Description 描述
0 Echo Reply 回显应答(Ping应答)
3 Destination Unreachable 目标不可达
4 Source Quench 源端被关闭(基本流控制)
5 Redirect 重定向
8 Echo Request 回显请求(Ping请求)

ping主要就是用的80这两个类型。

代码: 部分类型还会有子类型,使用代码表示,如:类型3、类型5

校验和: ICMP包头和包体一起计算校验和,算法与IP协议相同

后面4个字节的内容与具体类型有关,在ping请求和应答中,这4个字节是由2字节的ID和2字节的序号组成。并且请求包和应答包思维这两个字段必须一致。

数据包示例

下面是一个ping请求包的示例(每行4个字节)

+---+---+-------+---------------+------
| 4 | 5 |   0   |      60       |  ^
+---+---+-----------------------+  |
|    0x6f18     |      0        |  |
+-------+-----------------------+  |  IP协议头
|  64   |   1   |    0x09c0     |  |
+-------+-------+---------------+  |
|         10.0.0.101            |  |
+-------------------------------+  |
|         10.0.0.102            |  v
+-------+-------+----------------------
|   8   |   0   |    0x2070     |  ^
+-------+-----------------------+  |  ICMP协议头
|       1       |    12345      |  v
+---------------+----------------------
|              abcd             |  ^
+-------------------------------+  |
|              efgh             |  |
+-------------------------------+  |
|              ijkl             |  |
+-------------------------------+  |  ICMP数据
|              mnop             |  |
+-------------------------------+  |
|              qrst             |  |
+-------------------------------+  |
|              uvwx             |  |  
+-------------------------------+  |
|              yzAB             |  |
+-------------------------------+  |
|              CDEF             |  v
+-------------------------------+------

该IP包共有60个字节,其中包含20个字节的IP头,8个字节的ICMP头,以及32个字节的ICMP数据。

4.2. 使用原始套接字发送ping请求包

drunkdream.cn 版权所有 粤ICP备17153329号 all right reserved,powered by Gitbook该文件修订时间: 2021-01-07 18:27:03

results matching ""

    No results matching ""