python发送以太网报文_python之分解以太帧
通过了解socket(int domain, int type, int protocol)接口,我们知道利用socket的AF_PACKET
或者PF_PACKET域,和类型SOCK_RAW再加上协议就可以监听获得指定协议的以太帧。
1.获得各个协议的头部
以太协议类型有很多,仅贴上一部分,如下图:
图一
本文仅介绍0x0800(IPV4)的监听与拆分。现在我们就可以利用:
s=socket.socket(socket.PF_PACKET,socket.SOCK_RAW,socket.htons(0x0800))
获得ipv4协议的以太帧。然后就是接收,并根据协议格式拆分了。先看以太帧格式部分,如下:
图二
我们接收的数据没有Preamble部分,此部分被以太网硬件过滤掉了。这里说一下,上图Type/Length
部分是Ethernet-II才有的type,在原始的IEEE 802.3帧此部分是负载的数据长度,怎样区分的呢,数值小于
1500表示帧负载数据长度,而>=1536(十六进制0x0600)表示Ethernet-II的type(见图一ethertype的值)。
另外提一下vlan类型大小是0x8100,此类型的协议现在使用比较广泛,格式如下:
图三
vlan tag中有12bit用来表示vlan id的。此处和本文没有多少关系,主要是应用广泛介绍一下。继续正文。
我们用pkt表示接受的数据,pkt为str类型,通过图二可知用pkt[:14]包含了目的mac(6 bytes)、
源mac(6 bytes)和Type(2 bytes)。ipv4数据包封装在以太帧中,下一步看ipv4头格式:
图四
从图四可以知道ipv4最小长度20bytes(每行四字节,共5行),所以通过pkt[14:34]得到其头部。
由于ipv4之上有Tcp、UDP等协议,这里介绍获取的TCP数据,在ipv4头部的protocol为6时即是tcp包。
TCP header如下:
图五
Tcp头部最小也是20bytes,所以tcp_header=pkt[34:54]。
2.获得每个协议的每个字段
在此之前,要说一个问题。比如要把4存进int型的低8位,在python中这个还好说,再去取来也
没什么难度。但是如果把4存进2bytes的数中或者从保存4的2bytes str类型中获得4,就没有c等语言
简单。这里介绍struct模块,有了它,一切就简单了!我们通过如下:
tcp_h=struct.unpack("
此方法就得到了tcp头部的个部分信息。
首先"'、'!'或者'='。H表示无符号16位,
I表示unsignedint,b表示signed char。所以HHII分别是source port(16bits)、Destination port(16bits)、
Sequence number(32bits)、Ack number(32bits)(看图五),bbHHH同理。
根据你设置的格式化字符串unpack()返回对应长度的数组,比如上面的“HHIIbbHHH”(9个字符)
就会返回长度为9的数组,并且每个元素都是int型。
同理,对于以太帧头部和ipv4头部处理与tcp header类似。
更详细的格式化字符对照如下:
3.代码实现
通过上面讲述实现主体代码如下:
1 ipv4=0x0800
2 udptype=0x11
3 tcptype=0x06
4 bufsize=1500
5 s=socket.socket(socket.PF_PACKET,socket.SOCK_RAW,socket.htons(ipv4))6
7 whileTrue:8 pkt=s.recv(bufsize)9 if len(pkt)<=0:10 break
11 elif len(pkt)>54:12 ether_header = pkt[0:14]13 ip_header = pkt[14:34]14 ether_h = struct.unpack("!6s6s2s",ether_header)15 ip_h = struct.unpack("'+ip.destinationip()+\22 ':'+str(tcp.dport)
16、17行用了两个类对ip和tcp头部解析,如下:
1 importos,socket2 importstruct3 classIPv4Parser:4 def __init__(self,ip):5 self.ip=ip6 @property7 defversion(self):8 v=self.ip[0]>>4
9 returnv10 @property11 defheaderLen(self):12 l=(self.ip[0]&0x000f)*4
13 returnl
@property
def protocol(self):
return self.ip[6]14 defsourceip(self):15 sip=self.__getstrip(self.ip[8])16 returnsip17 defdestinationip(self):18 dip=self.__getstrip(self.ip[9])19 returndip20 deftotalLen(self):21 return ((self.ip[2]&0xff)<<8)|((self.ip[2]>>8)&0xff)
22 defchecksum(self):23 pass
24 def __getstrip(self,intip):25 strip=str(intip&0xff)+'.'+str((intip>>8)&0xff)+'.'+\26 str((intip>>16)&0xff)+'.'+str((intip>>24)&0xff)27 returnstrip28 classTCPParser:29 def __init__(self,tcp):30 self.tcp=tcp31 @property32 defsport(self):33 sp=self.tcp[0]34 return((sp&0xff)<<8)|(sp>>8)35 @property36 defdport(self):37 return ((self.tcp[1]&0xff)<<8)|(self.tcp[1]>>8)
38 @property39 defheaderLen(self):40 return ((self.tcp[4]>>4)&0x0f)*4
上面并没有解析ip和tcp header的所有部分,当然你可以补全,解析头部注意字节序。
把上面两处代码放在一个文件中没意外就可以运行了,注意需要root权限。运行输出的
信息如下,当然也可以输出更详细的信息。
我们完全可以更进一步,对于tcp上层的协议比如http继续解包。
python发送以太网报文_python之分解以太帧相关推荐
- python发送soap报文_python用http发送soap报文进行webservice接口调用
最近学习了python用http发送soap报文进行webservice接口调用,从网上找了些资料,为了方便下次温习,在此留下代码片段,也望高手指点: #!/usr/bin/env python # ...
- python发送xml报文_python通过tcp发送xml报文的方法
如下所示: # -*- coding: utf-8 -*- import socket # 使用tcp发送请求报文 def tcpsend(ip, port, xmlbw): address = (i ...
- python发送arp报文_python发送arp欺骗攻击代码分析
代码如下: # -*- coding: cp936 -*- from scapy.all import * from threading import Thread,Lock,activeCount ...
- python发送qq邮件_python使用SMTP发送qq或sina邮件
python使用qq邮箱(个人邮箱)发送邮件需开启qq邮箱的SMTP服务 在设置中开启pop3/SMTP服务,返回的密码就是之后代码中登录使用账户密码(在完整代码中标识了出来) 之后出现如下错误 复制 ...
- python 生成pdf收据_python如何与以太坊交互并将区块链信息写入SQLite
关于区块链介绍性的研讨会通常以易于理解的点对点网络和银行分类账这类故事开头,然后直接跳到编写智能合约,这显得非常突兀.因此,想象自己走进丛林,想象以太坊区块链是一个你即将研究的奇怪生物.今天我们将观察 ...
- python发送excel文件_Python操作Excel, 开发和调用接口,发送邮件
接口开发: importflaskimporttoolsimportjson,redisimportrandom server= flask.Flask(__name__)#新建一个服务,把当前这个p ...
- python发送cookie请求_Python中实现带Cookie的Http的Post请求
已经实现了如何获得对应的cookie,具体参考: [已解决]Python中如何获得访问网页所返回的cookie 现在想要把已获得cookie,在http的提交post请求的时候,也同时发送过去. 即, ...
- python发送qq邮件_python基于SMTP发送邮件(qq邮箱)
在Python中, smtplib模块提供了丰富的邮件发送接口,只要设置smtp服务器和端口,输入账号密码登陆,就可以使用邮件发送的接口. 第一步:开启SMTP服务 (1)点击"开启&quo ...
- python发送soap报文_使用Python将带附件的XML发送到SOAP ws
在过去的几周里,我一直在学习Python,并尝试将自定义XML发送到公共测试WS . 现在我觉得我没有取得任何进展 . 所以我现在需要帮助或任何建议 . 如果你使用SoapUI或其他方法(我试过-mz ...
- python发送qq邮件_Python实现给qq邮箱发送邮件的方法
#-*-coding:utf-8-*- #========================================== # 导入smtplib和MIMEText #============== ...
最新文章
- Linux中history历史命令使用方法详解
- BZOJ3224普通平衡树
- vs2010项目属性配置
- SpringBoot使用@ServerEndpoint无法依赖注入问题解决 SpringBoot webSocket配置
- Android 源码编译过程
- 使用@Aspect切面进行让JDBC自动关闭(Spring AOP)
- 基于Modelica的船用大功率电推进系统建模仿真
- iOS13 微信消息不通知 打开微信才能看到消息
- 深度学习入门笔记(8)——什么是optim?
- BiTree T 和Bitree T
- Preparing transaction:done Verifying transaction:failed RemoveError:‘requests‘ is a dependency of **
- mysql的备份与还原步骤_MySQL备份与还原
- 如何演示扇形面积公式推导过程
- 2022-2028年中国安检设备行业市场全景调查及投资策略研究报告
- 人机验证 之 验证码插件
- 使用JavaScript使浏览器进入全屏或退出全屏
- SRE运维工程师笔记-文件查找和压缩
- android获取电池信息;android获取电池容量、技术、电压、电量、温度等信息
- 哈啰A80青春版体验:避繁就简,享受智慧骑行带来的乐趣
- html盒子移动动画代码,js实现盒子滚动动画效果