python原始数据是什么_python使用原始套接字 解析原始ip头数据

使用底层套接字解码底层流量,是这次做的重点工作。

首先来捕获第一个包

#coding:utf-8importsocket#监听的主机IP

host = "192.168.1.100"

socket_protocol=socket.IPPROTO_ICMP

sniffer=socket.socket(socket.AF_INET, socket.SOCK_RAW, socket_protocol)

sniffer.bind((host, 0))

sniffer.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL,1)

raw_buffer= sniffer.recvfrom(65535)print raw_buffer

下面一行一行解释上面代码的意思。

1. 导入socket包

2. 需要监听的本机ip地址

3. 给socket_protocol变量赋值icmp变量

4. 为sniffer变量创建一个soket对象,该对象为ipv4 原始套接字并指定其协议为icmp

5. 绑定到指定地址和端口进行监听

6. 为sniffer套接字设置选项参数,使其携带ip头

7. 将监听端口的套接字收到的原始数据赋值给raw_buffer

8. 打印raw_buffer的值

这个时候,我们使用root权限运行这个脚本,并且开启另外一个terminal对任意一个地址发送icmp包,我们监听的接口的recvfrom 会收到回监听回包到指定地址。recvfrom与recv不同的是 recvfrom会同时接收回包地址。(string, address)的格式

这个时候我们可以看到打印出来的值,是一堆完全看不懂的东西,因为是没有解码的状态,下面我们将对ip头进行解码。

使用python的struct和ctypes两个库实现这一点。

#coding:utf-8importsocketimportstructfrom ctypes import *

#监听的主机IPhost = "192.168.1.100"

#IP头定义

classIP(Structure):

_fields_=[

("ihl", c_ubyte, 4),

("version", c_ubyte, 4),

("tos", c_ubyte),

("len", c_ushort),

("id", c_ushort),

("offset", c_ushort),

("ttl", c_ubyte),

("protocol_num", c_ubyte),

("sum", c_ushort),

("src", c_uint),

("dst", c_uint),

]def __new__(self, socket_buffer=None):returnself.from_buffer_copy(socket_buffer)def __init__(self, socket_buffer=None):

self.protocol_map= {1: "ICMP", 6: "TCP", 17: "UDP"}#readable ip addressself.src_address= socket.inet_ntoa(struct.pack("

self.dst_address= socket.inet_ntoa(struct.pack("

try:

self.protocol=self.protocol_map[self.protocol_num]except:

self.protocol=str(self.protocol_num)socket_protocol=socket.IPPROTO_ICMP

sniffer=socket.socket(socket.AF_INET, socket.SOCK_RAW, socket_protocol)

sniffer.bind((host, 0))

sniffer.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL,1)try:whileTrue:

raw_buffer= sniffer.recvfrom(65535)[0]

ip_header= IP(raw_buffer[:20])print "Protocol: %s %s -> %s" %(ip_header.protocol, ip_header.src_address, ip_header.dst_address)exceptKeyboardInterrupt:pass

1. 导入各模块

2. 监听的本机ip地址

3. 使用ctypes 构造一个解析ip头的结构体(structure) IP

4. 使用from_buffer_copy方法在__new__方法将收到的数据生成一个IP class的实例

5. __init__方法初始化一部分数据保存到对应的实例属性值中。

6. 特别说明下面代码, 使用了python struct库的pack方法 用指定的格式化参数将src 和dst的long型数值转换为字符串,然后使用socket.inet_ntoa方法将字符串的一串数字转换为对应的ip格式。最后赋值给对应的src或者dst变量

#readable ip address

self.src_address = socket.inet_ntoa(struct.pack("

self.dst_address= socket.inet_ntoa(struct.pack("

7. 一个接收icmp包的服务器,没什么说的。

8. 无限循环监听指定端口,将recvfrom收到的数据的第一部分 也就是不要ip地址的部分传递给raw_buffer

9. ip头raw_buffer的前20个字节传递给结构体进行解码。

10. 然后打印。

可以看到大致思路就是,将原型socket数据拿过来,然后通过模拟c语言的结构体,使用python的库对这个格式的包进行一一对应的解码,将解码之后的数据打印出来。

到此为止可以看到,在ip层已经可以解析出数据包从哪儿去哪儿的信息。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值