Извлечение данных из списка параметров 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 '), (' required_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)

3 ответа

Предполагая, что ваша строка для анализа выглядит (и будет выглядеть) строго как допустимые данные Python, вы можете проанализировать ее с помощью pythonвнутренние инструменты

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

literal_eval для разбора строки в структуру данных Python (и это безопаснее, eval). dict построить удобный словарь из этого.

#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) 

Возможно, это НЕ лучшее решение для фильтрации, на самом деле, но оно будет работать. Код ниже преобразует ваш список в словарь (напрямую, спасибо @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'                                                                                                                                                                                                                      
>>>

Этот код не является оптимальным, но может дать вам некоторые идеи.

Другие вопросы по тегам