# coding=utf-8
import json
import time
import os
import dpkt
import socket
import datetime
import uuid
import traceback
from dpkt.ethernet import Ethernet
from scapy.layers.l2 import Ether
from scapy.sendrecv import sniff
from scapy.utils import wrpcap
from BigData.data_common.utils.file_util import FileUtil
def get_local_ip():
hostname = socket.gethostname()
# 获取本机内网ip
local_ips = socket.gethostbyname_ex(hostname)[-1]
return local_ips
def body_transfer(body):
str_body = body.decode()
body_ls = str_body.split("&")
d = {}
for item in body_ls:
key_, value_ = item.split("=")
d[key_.strip()] = value_.strip()
def analysis_pcap(timestamp, buf):
data = {}
if isinstance(buf, dpkt.ip.IP):
eth = buf
else:
eth = dpkt.ethernet.Ethernet(buf)
# print(eth.data.__dict__)
# print("ip layer:"+eth.data.__class__.__name__) #以太包的数据既是网络层包
# print("tcp layer:"+eth.data.data.__class__.__name__) #网络层包的数据既是传输层包
# print("http layer:" + eth.data.data.data.__class__.__name__) #传输层包的数据既是应用层包
# print('Timestamp: ',str(datetime.datetime.utcfromtimestamp(timestamp))) #打印出包的抓取时间
if isinstance(eth.data, dpkt.ip.IP) or isinstance(eth.data, dpkt.ip6.IP6):
# # print('%d Non IP Packet type not supported %s' % (int(timestamp), eth.data.__class__.__name__))
# print('ip.data type is {}'.format(eth.data.__class__.__name__))
# print(repr(eth.data))
# return data
ip = eth.data
if isinstance(eth.data, dpkt.ip.IP):
src_ip = socket.inet_ntoa(ip.src)
dst_ip = socket.inet_ntoa(ip.dst)
# do_not_fragment =bool(ip.off & dpkt.ip.IP_DF)
# more_fragments =bool(ip.off & dpkt.ip.IP_MF)
# fragment_offset = ip.off & dpkt.ip.IP_OFFMASK
# key = 'IPV4' if isinstance(eth.data, dpkt.ip.IP) else 'IPV6'
data.update({
'time': timestamp,
'IPV4': {'src': src_ip, 'dst': dst_ip}
})
else:
src_ip = ip.src
dst_ip = ip.dst
data.update({
'time': timestamp,
'IPV6': {'src': src_ip, 'dst': dst_ip}
})
print('ip.data type is {}'.format(ip.data.__class__.__name__))
if isinstance(ip.data, dpkt.tcp.TCP):
layer = ip.data
data.update(analysis_tcp(layer))
elif isinstance(ip.data, dpkt.udp.UDP):
layer = ip.data
data.update(analysis_udp(layer))
elif isinstance(ip.data, dpkt.icmp.ICMP) or isinstance(ip.data, dpkt.icmp6.ICMP6):
layer = ip.data
data.update(analysis_icmp(layer))
else:
print('analysis_pcap ip.data {}'.format(repr(ip.data)))
data = {'time': timestamp, eth.data.__class__.__name__: {}}
else:
print('analysis_pcap eth.data {}'.format(repr(eth.data)))
data = {'time': timestamp, eth.data.__class__.__name__: eth.data.__dict__}
return data
def analysis_udp(udp, key="UDP"):
try:
data_dict = {}
try:
data_str = udp.data.decode('utf-8')
if data_str.startswith('M-SEARCH'):
data_list = data_str.strip().split('\n')[1:]
for item in data_list:
k, v = item.split(':')[0], ':'.join(item.split(':')[1:])
data_dict[k.strip()] = v.strip()
else:
data_dict = data_str
except:
pass
return {
key: {
'sport': udp.sport,
'dport': udp.dport,
'ulen': udp.ulen,
'sum': udp.sum,
'data': data_dict
}
}
except:
pass
print('analysis_udp udp {}'.format(repr(udp)))
return {}
def analysis_tcp(tcp, key='TCP'):
data = {
key: {
'dport': tcp.dport,
'sport': tcp.sport,
'ack': tcp.ack,
'seq': tcp.seq
}
}
try:
request = dpkt.http.Request(tcp.data)
data['HTTP'] = {
'type': 'request',
'uri': request.uri,
'Method': request.method.upper(),
'Headers': dict(request.headers),
'Body': body_transfer(request.body),
'Data': body_transfer(request.data)
}
except:
pass
try:
response = dpkt.http.Response(tcp)
data['HTTP'] = {
'type': 'response',
'Headers': dict(response.headers),
'Body': body_transfer(response.body),
'Data': body_transfer(response.data)
}
except:
pass
try:
data_dict = {}
data_str = tcp.data.decode('utf-8')
if data_str.startswith('M-SEARCH'):
data_list = data_str.strip().split('\n')[1:]
for item in data_list:
k, v = item.split(':')[0], ':'.join(item.split(':')[1:])
data_dict[k.strip()] = v.strip()
else:
data_dict = data_str
if key in data and data_dict:
data[key]['Data'] = data_dict
except:
pass
if data:
return data
print('analysis_tcp tcp {}'.format(repr(tcp)))
return {}
def analysis_icmp(icmp, key='ICMP'):
try:
if isinstance(icmp, dpkt.icmp.ICMP):
return {
'ICMP': {
'type': icmp.type,
'sum': icmp.sum,
'Data': analysis_pcap(int(time.time()), icmp.data.data)
}
}
else:
data_str = ''
try:
data_str = icmp.data.decode('utf-8')
except:
pass
return {
'ICMP6': {
'type': icmp.type,
'sum': icmp.sum,
'Data': data_str
}
}
except:
pass
return {}
def analysis_pcap2(timestamp, buf):
e = Ether(buf)
e.show()
def get_dpkt():
# 这里是针对单网卡的机子, 多网卡的可以在参数中指定网卡, 例:iface=Qualcomm QCA9377 802.11ac Wireless Adapter
dpkt_ = sniff(count = 10)
_uuid = uuid.uuid1()
filename = f"{_uuid}.pcap"
wrpcap(filename, dpkt_)
return filename
def main():
while True:
filename = get_dpkt()
with open(filename, "rb") as f:
pcap = dpkt.pcap.Reader(f)
local_ips = get_local_ip()
for timestamp, buf in pcap:
res = analysis_pcap(timestamp, buf)
# analysis_pcap2(timestamp, buf)
print(res)
# FileUtil.write_lines('test.txt', json.dumps(res))
os.remove(filename)
# FileUtil.flush()
if __name__ =='__main__':
main()