You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Raw Socket数据包头部解析:Python嗅探器源IP/端口及字段疑问

嗨,我来帮你解决这两个问题——之前我自己写Socket嗅探器的时候也踩过这些坑,太懂这种摸不着头脑的感觉了!

一、如何找到发送方IP和端口号

首先得明确你捕获的是IPv4数据包(从你给的头部元组来看是IPv4),咱们一步步来:

  • 发送方IP地址:其实就在你拿到的IP头部里!IPv4头的结构里,源IP位于第13-16字节(也就是从data索引12开始的4个字节),而你已经能获取的接收方IP(目的IP)在它后面的4个字节(索引16-19)。比如你可以直接把这四个字节转成点分十进制:

    source_ip = '.'.join(map(str, data[12:16]))
    
  • 发送方端口号:端口属于传输层(TCP/UDP)内容,得先跳过IP头部才能拿到。IP头的长度由data[0]的后4位决定:比如data[0]是69(二进制01000101),后4位是0101,代表IP头长度是5×4=20字节。所以传输层头部从data[20]开始:

    • 如果是UDP协议(协议号17),源端口是传输层头的前两个字节,用struct模块解析:
      import struct
      ip_header_len = (data[0] & 0x0F) * 4
      source_port = struct.unpack('!H', data[ip_header_len:ip_header_len+2])[0]
      
    • 如果是TCP协议(协议号6),解析方式完全一样,因为TCP头的前两个字节也是源端口。

二、解析你给出的IP头部元组字段

先说明:你的元组看起来是把IP头的字段拆成了十进制值,但其中有些元素(比如1541)明显超过了单字节的范围(0-255),应该是拆分时的小错误,但结合已知的协议字段(header[6]=17),咱们对应标准IPv4头的字段来解释:

元组:(69, 0, 61, 1541, 0, 128, 17, 0, 192, 168, 56, 1, 255, 255, 255, 255)

  • 索引0: 69:二进制是01000101,前4位0100表示IPv4版本,后4位0101表示IP头部长度(5个32位字,也就是20字节,这是IPv4的最小头部长度)
  • 索引1: 0:服务类型(ToS),值0代表使用默认服务质量,无特殊优先级或延迟要求
  • 索引2-3: 61, 1541:这应该是**总长度(Total Length)**字段(原本是2字节,0-65535),但拆分出错了——正确的做法是从原始data中取2字节用struct.unpack('!H', data[2:4])获取,它代表整个数据包(IP头+数据)的字节数
  • 索引4-5: 0, 128:对应**标识(Identification)**字段(2字节),值为0×0080=128,用于分片重组时标识同一个数据包的分片
  • 索引6: 17:你已经知道的协议(Protocol),17对应UDP协议,6对应TCP,1对应ICMP
  • 索引7: 0:头部校验和(Header Checksum),值0通常是因为网卡硬件已经完成校验,或者捕获的数据包还没计算校验和
  • 索引8-11: 192,168,56,1:源IP地址,组合起来就是192.168.56.1——这就是你要找的发送方IP!
  • 索引12-15:255,255,255,255:目的IP地址,也就是你已经获取的接收方IP,这是一个广播地址

内容的提问来源于stack exchange,提问作者user9321739

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:44:09