python开发的网络调试助手_用python来调试网络程序

需要联调的程序,沟通联调起来总是各种麻烦,如果自己能写个简单一点的“测试机”,事情就很easy了;或者有时候想做“中间人”,看看网路上到底传些什么。前面写了串口的测试机,今天尝试了一下UDP的。

importsocketfrom struct import *s=socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_UDP)whileTrue:

packet= s.recvfrom(65565)

packet=packet[0]

ip_header= packet[0:20]

iph= unpack('!BBHHHBBH4s4s', ip_header)

version_ihl=iph[0]

version= version_ihl >> 4ihl= version_ihl & 0xfttl= iph[5]

protocol= iph[6]

s_addr= socket.inet_ntoa(iph[8])

d_addr= socket.inet_ntoa(iph[9])print '---> src_addr:'+s_addr+',dst_addr:'+d_addr

udp_header= packet[20:28]

udph= unpack('!HHHH', udp_header)

s_port=udph[0]

d_port= udph[1]

data_length= udph[3]print 'src_port:'+str(s_port)+',dst_port:'+str(d_port)

简单做一下注释:

1. raw_socket,字面理解是“裸”套接字,这个“裸”对应用编程人员来说就是,未经过解析的。

2. recvfrom(length),注意,这里的参数是缓存区的大小,并不是port。因为我们在这里recvfrom()到的,是本机所有的UDP datagram(tcp使用IPPROTO_TCP,ICMP使用IPPROTO_ICMP)。

3. recvfrom的返回是一个tuple,类似下面:

("E \x00x\xcc\xfc\x00\x000\x06j%J}G\x13\xc0\xa8\x01\x06\x01\xbb\xa3\xdc\x0b\xbeI\xbf\x1aF[\x83P\x18\xff\xff\x88\xf6\x00\x00\x17\x03\x01\x00\x1c\xbbT\xb3\x07}\xb0\xedqE\x1e\xe7;-\x03\x9bU\xb7\xb1r\xd2\x9e]\xa1\xb8\xac\xa4V\x9a\x17\x03\x01\x00*\xed\x1f\xda\xa4##Qe\x9a\xe9\xd6\xadN\xf4\x9b\xc4\xf0C'\x01\xc4\x82\xdb\xb2\x8d(\xa5\xd0\x06\x95\x13WO\x0f\x8e\x1c\xa6f\x1d\xdf\xe1x", ('74.125.71.19', 0))

4. unpack是struct包中的函数,format字符串的含义在这里有解释。如:‘!’表示big-endian,也可以使用‘>’代替;‘H’表示unsigned short。

另一个,截取TCP包的代码,IP头部分与上面udp解析一样:

tcp_header = packet[20:40]#now unpack them :)

tcph = unpack('!HHLLBBHHH', tcp_header)

source_port=tcph[0]

dest_port= tcph[1]

sequence= tcph[2]

acknowledgement= tcph[3]

doff_reserved= tcph[4]

tcph_length= doff_reserved >> 4

print 'Source Port :' + str(source_port) + 'Dest Port :' + str(dest_port) + 'Sequence Number :' + str(sequence) + 'Acknowledgement :' + str(acknowledgement) + 'TCP header length :' +str(tcph_length)

h_size= ihl * 4 + tcph_length * 4data_size= len(packet) -h_size#get data from the packet

data =packet[data_size:]print 'Data :' + data

另外,此方法还支持PF_PACKET,所以可以直接用来抓取以太网数据(只有x-nix系统支持PF_PACKET,所以,windows系统还得使用wpcap)。

想要抓取经过自己网卡的所有数据包,需要网卡进入“promiscuous mode”。有两种方法:手动“ifconfig eth0 promisc”打开;使用ioctl,修改socket的配置"ifr.ifr_flags |= IFF_PROMISC"。

data.encode("hex")

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值