Нужна помощь в выводе номера порта источника и назначения пользователю, чтения из файла pcap с использованием Python и dpkt - PullRequest
1 голос
/ 25 апреля 2019

Привет всем, я впервые делаю программирование на PCAP, используя Python для языка программирования, это задача для университета, и у меня в основном есть все, что мне нужно для выполнения задачи, за исключением одной маленькой детали.

Мне просто нужно получить выходные данные номеров портов источника и назначения (например, HTTP-порт 80), связанных с IP-адресами.

Я рад, что ответ будет указателем в правильном направлении, чтобы помочь мне решить его для себя. В противном случае, если на него будет проще ответить, я хотел бы получить базовое объяснение того, что использовалось и как оно решает проблему, чтобы я мог лучше понять его, когда буду больше заниматься программированием на PCAP в своих исследованиях и исследованиях.

Используется в системе Unix, работающей под FreeBSD 10.3

.

Я пытался использовать библиотеки dpkt.tcp, dpkt.udp, dpkt.ip, а также некоторые библиотеки сокетов, чтобы посмотреть, смогу ли я достичь желаемого результата, но мне не повезло. Я буду честен, я не уверен, что мне нужно использовать.

РЕДАКТИРОВАТЬ: я пытался использовать tcp.sport и tcp.dport, все еще не повезло.

Основное внимание уделено тому, где я добавил комментарии.

import datetime
import time
import sys
import dpkt
import socket

def printPcap(pcap):
    for (ts,buf) in pcap:
        try:
            eth = dpkt.ethernet.Ethernet(buf)
            if eth.type == dpkt.ethernet.ETH_TYPE_IP:
                ip = eth.data
                ipsrc = socket.inet_ntoa(ip.src)        
                ipdst = socket.inet_ntoa(ip.dst)

                srcport = ??? ###Stuck here for source port
                dstport = ??? ###Stuck here for destination port

                if ip.p == dpkt.ip.IP_PROTO_TCP:        
                    TCP = ip.data
                    iptype = 'tcp'
                elif ip.p == dpkt.ip.IP_PROTO_UDP:   
                    UDP = ip.data
                    iptype = 'udp'
                len = str(ip.len)
                ttl = str(ip.ttl)

                ###My current output
                print '[' +str(datetime.datetime.utcfromtimestamp(ts))+ '] - ' \
                        +ipsrc+ ':' +srcport+ ' -> ' +ipdst+ ':' +dstport+ \
                        ' ('+iptype+', len='+len+', ttl='+ttl+')'

        except:
            pass

ОБРАЗЕЦ ОЖИДАЕМЫХ ВЫХОДОВ:

[2018-08-16 02:48:10.238506] - 172.16.11.2:61016 -> 172.16.10.2:80 (tcp, len=52, ttl=63)

Ответы [ 2 ]

0 голосов
/ 26 апреля 2019

Проблема в том, что ваше утверждение для печати является поддельным, но вы скрыли это с «голым исключением». Именно по этой причине использование голого кроме считается очень плохой практикой в ​​Python. См. Также ответы на этот вопрос: Должен ли я всегда указывать тип исключения в операторах `кроме`?

В частности, ваш оператор печати пытается объединить целое число со строкой, которая недопустима.

Итак, отремонтировано и с:

                if ip.p == dpkt.ip.IP_PROTO_TCP:
                    TCP = ip.data
                    iptype = 'tcp'
                    srcport = TCP.sport
                    dstport = TCP.dport
                elif ip.p == dpkt.ip.IP_PROTO_UDP:
                    UDP = ip.data
                    iptype = 'udp'
                    srcport = UDP.sport
                    dstport = UDP.dport

и это оператор печати, он работает:

                print("[{}] - {}:{} -> {}:{} ({}, len={}, ttl={})".format(
                      datetime.datetime.utcfromtimestamp(ts), ipsrc, srcport,
                      ipdst, dstport, iptype, len, ttl))

Наконец, по крайней мере, я бы изменил вашу фразу «исключение» на что-то вроде этого, чтобы обнаружить такие проблемы в будущем:

        except Exception as exc:
            print("Exception: {}".format(exc))

(Обратите внимание, что здесь я использовал синтаксис print , совместимый с python3 * , который также отлично работает с оператором печати python2 .)

EDIT:
Еще одна вещь произошла со мной. Если первый обнаруженный IP-пакет не является ни TCP, ни UDP, srcport и dstport не будут определены, что приведет к исключению AttributeError. Оставляя это для вас, чтобы убрать.

0 голосов
/ 25 апреля 2019

Возможно использовать ip.data для получения пакета TCP и sport и / или dport?

ip = eth.data

if ip.p == dpkt.ip.IP_PROTO_TCP:
    tcp = ip.data
    print('source port: {}, dest port: {}'.format(tcp.sport, tcp.dport))
...