2017-06-20 76 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從中構建便捷的字典。