级别:初级。我目前正在使用原始套接字使用 python 来开发嗅探器。
我有一个关于 struct 模块提供的 unpack() 中使用的格式说明符的一般性问题。当我们使用此方法根据指定的格式说明符解包数据时。我见过很多嗅探器程序使用 unpack() 从十六进制形式解码数据包信息。
例如,为了提取以太网标头信息,可以使用以下代码:
ethHeader = struct.unpack("!6s6s2s", ethernetHeader)
这里的 ethernetHeader 是变量,包含之前从原始套接字捕获的实际以太网标头数据。现在我的问题是如何知道标题使用哪种格式说明符?我如何提前知道以太网地址是字符串格式还是其他格式?是否也有这方面的文档。我阅读了与 unpack() 相关的 python 文档,但没有找到任何信息。类似地,对于 IP 地址,代码如下:
ipAddresses = struct.unpack("!12s4s4s", IPAddresses)
这里的 IPAddresses 是变量,包含之前从原始套接字捕获的实际 IP 地址信息。我怎么知道我必须使用字符串作为格式说明符(!12s4s4s)。
谢谢。
感谢 J.F. Sebastian 的提示。我终于弄清楚了,并将花一些时间在这里解释它。通常,我们必须在每个标头的结构中查找 C 类型,以了解数据包的不同标头中的每个字段使用什么 C 类型。那么稍后我们就可以使用这个table http://docs.python.org/2/library/struct.html#format-characters了解哪个格式说明符将代表哪种 C 类型。例如,对于 IP 标头,结构如下所示:
struct ipheader {
unsigned char ip_hl:4, ip_v:4; /* this means that each member is 4 bits */
unsigned char ip_tos;
unsigned short int ip_len;
unsigned short int ip_id;
unsigned short int ip_off;
unsigned char ip_ttl;
unsigned char ip_p;
unsigned short int ip_sum;
unsigned int ip_src;
unsigned int ip_dst;
};
例如:unsigned char 表示为“B”,unsigned int 表示为“I”。现在我们可以使用此方法来了解 struct.unpack() 中应使用什么格式说明符来获取 IP 标头的字段值。如果是 IP 标头,则如下所示:
struct.unpack('!BBHHHBBHII')
但你会注意到大多数程序都使用struct.unpack('!BBHHHBBH4s4s')
.
那么问题来了,为什么在这种情况下unsigned int ip_src;
& unsigned int ip_dst;
使用“s”代替“I”作为格式说明符struct.unpack()
。原因是如果“I”用作格式说明符,则unpack()
方法以整数形式返回 IP 地址(例如:3232267778)。然后你必须将其转换为实际的IP地址形式(例如:10.0.0.1)。通常在互联网上可用的嗅探器程序中只需使用socket.inet_ntoa()
用于获取实际的IP地址。此方法接受字符串类型而不是整数类型。这就是为什么在 unsigned int ip_src 的情况下; & 无符号 int ip_dst;在 struct.unpack() 中使用“s”代替“I”作为格式说明符,以便稍后可以将结果提供给 socket.inet_ntoa() 以获取实际 IP 地址格式的 IP 地址。以太网标头的情况也是如此。我们在 struct.unpack() 中使用“s”而不是“B”,因为我们需要一个可以稍后输入的字符串binascii.hexlify()
以获取实际 MAC 地址格式的 MAC。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)