2017-06-20 24 views
1

我正在写一个从DHCP数据包中提取数据的Python脚本。目前,我的输出的一部分只是来自DHCP选项的列表:从DHCP选项列表中提取数据

[('message-type',3),('param_req_list',b'\ x01y \ x01 \ x01 \ x011 \ aaa_ '',''max_dhcp_size',1500),('client_id',b'\ x01(\ aaa \ aa1A \ aa1O'),('requested_addr','192.168.1.4'),('server_id',' 192.168.1.1'),('hostname',b'HOSTNAME')]

我只希望打印消息类型,主机名和请求地址,从哪里开始将它转换为元组,我可以滤除元件

编辑: 我的输出高于 我的代码是:

from scapy.all import * 
from scapy.layers import dhcp 
import logging 
logging.getLogger("scapy.runtime").setLevel(logging.ERROR) 
runtime = logging.getLogger('scapy.runtime') 
runtime.setLevel(logging.ERROR) 
loading = logging.getLogger('scapy.loading') 
loading.setLevel(logging.ERROR) 
from scapy.layers.l2 import Ether 
from scapy.layers.all import BOOTP 
from scapy.layers.all import DHCP, DHCPTypes, DHCPOptions, DHCPRevOptions 
from scapy import route 

s=socket.socket(socket.PF_PACKET, socket.SOCK_RAW, socket.ntohs(0x0800)) 

print("Input network interface") 
interface = input() 


def pkt_data(pkt): 
    src_mac = pkt.getlayer(Ether).fields['src'] 
    dhcp_options = filter(lambda o: type(o) is tuple, 
     pkt.getlayer(DHCP).fields['options']) 


    print(src_mac) 
    print(list(dhcp_options)) 

sniff(iface=interface, prn=pkt_data, filter='udp port (67 or 68)', store=0) 
+0

你能读一下吗?看起来像它的有效Python格式。 (编辑:所以我不知道如何,但我觉得Python的REPL必须是一个简单的解决方案) –

+0

这是终端的输出。我只需要输出只是我想要的价值,而不是全部。然后我可以将其存储到数据库中。 – dcode1

+0

我已经向您展示了如何将该字符串转换为元组列表。将现在的输出捕获为字符串,然后使用exec将其转换为您可以解析的元组列表。 –

回答

0
#At this point it is not clear to me if this exec is needed. 
exec("vals = [('message-type', 3), ('param_req_list', b'\x01y\x01\x01\x011\aaa_,.'), ('max_dhcp_size', 1500), ('client_id', b'\x01(\aaa\aa1A\aa1O'), ('requested_addr', '192.168.1.4'), ('server_id', '192.168.1.1'), ('hostname', b'HOSTNAME')]") 

ans = [] 
for v in vals: 
    if v[0] in ['message-type', 'hostname', 'requested_addr']: 
    ans += (v,) 

print (ans) 
+0

谢谢,我已经准备好了输出。我需要从输出中提取上面指定的选项。输出是来自数据包的原始数据,所以我需要对其进行过滤。 – dcode1

+0

我误解了你的问题。你的问题不是把它转换成一个元组,你的问题是解析一个列表。 –

+0

是的,抱歉写了一个坏问题。这是我的输出。我有一个名字和一个价值。我只是想提取某些值屁股涂上一个名字。 – dcode1

0

也许,这不是一个最好的过滤解决方案,真的,但它会起作用。下面的代码将你的列表转换成字典(直接,谢谢@Slam提醒)并为字典取值。

>>> x=[('message-type', 3), ('param_req_list', b'\x01y\x01\x01\x011\aaa_,.'), ('max_dhcp_size', 1500), ('client_id', b'\x01(\aaa\aa1A\aa1O'), ('requested_addr', '192.168.1.4'), ('server_id', '192.168.1.1'), ('hostname', b'HOSTNAME')] 
>>> y=dict(x) 
>>> y['requested_addr'] 
'192.168.1.4'                                                     
>>> y['hostname']                                                    
'HOSTNAME'                                                      
>>> 

这段代码根本不是最优的,但可能会给你一些想法。

+0

只是从python一侧 - 'dict'构造函数实际上采用完全相同的格式,因为你在这里。所以'y = dict(x)'可以正常工作,不需要手动迭代。 – Slam

+0

@Slam你是对的。谢谢,我忘记了,我可以直接将列表转换为字典。我已经更新了答案。 – rth

1

假设你的字符串进行解析的外观(并期待),如有效的Python数据严格,可以用python的内部工具

from ast import literal_eval 
lst = literal_eval(msg) 
data = dict(lst) 
... 

literal_eval解析它来解析字符串转换Python数据结构(及其安全即eval)。 dict从中构建便捷的字典。