1

Using PyShark, how can I get a string with the name of an IP protocol from the number on the packet proto field?

For example, converting 6 to 'TCP'.

Ortomala Lokni
  • 56,620
  • 24
  • 188
  • 240

2 Answers2

0

You can get a map of protocol numbers as defined by IANA from the socket module of the Python Standard Library with:

import socket
ip_proto={v:k[8:] for (k,v) in vars(socket).items() if k.startswith('IPPROTO')}

This dictionary comprehension extract IP protocols from the __dict__ attribute of the socket module using the vars built-in function.

And then use it as:

>>> ip_proto.get(1)
'ICMP'
>>> ip_proto.get(2)
'IGMP'
>>> ip_proto.get(6)
'TCP'
Ortomala Lokni
  • 56,620
  • 24
  • 188
  • 240
0

Here is one method to accomplish your use case using PyShark.

import pyshark
import re as regex

capture = pyshark.LiveCapture(interface='en0')
for packet in capture:
    if 'IPV6 Layer' in str(packet.layers):
        protocol = regex.search(r'(Next Header:)(.*)', str(packet.ipv6))
        protocol_type = protocol.group(2).strip().split(' ')[0]
        protocol_number = protocol.group(2).strip().split(' ')[1]
        print(f'(Internet Protocol: IPv6, '
              f'Protocol Type: {protocol_type}, '
              f'Protocol Number: {protocol_number}')
    elif 'IP Layer' in str(packet.layers):
        protocol = regex.search(r'(Protocol:)(.*)', str(packet.ip))
        protocol_type = protocol.group(2).strip().split(' ')[0]
        protocol_number = protocol.group(2).strip().split(' ')[1]
        print(f'(Internet Protocol: IPv4, '
              f'Protocol Type: {protocol_type}, '
              f'Protocol Number: {protocol_number}')

OUTPUT:

(Internet Protocol: IPv4, Protocol Type: TCP, Protocol Number: (6)
(Internet Protocol: IPv4, Protocol Type: UDP, Protocol Number: (17)
(Internet Protocol: IPv6, Protocol Type: ICMPv6, Protocol Number: (58)
truncated...

Here is another way to accomplish your use case using the Python module sockets and PyShark

import socket
import pyshark

prefix = "IPPROTO_"
protocol_table = {num:name[len(prefix):] for name,num in vars(socket).items() if name.startswith(prefix)}

capture = pyshark.LiveCapture(interface='en0')
for packet in capture:
    if 'IPV6 Layer' in str(packet.layers):
        protocol = [protocol_type for [protocol_number, protocol_type] in protocol_table.items()
                    if protocol_number == int(packet.ipv6.nxt)]
        print(protocol)
    elif 'IP Layer' in str(packet.layers):
        protocol = [protocol_type for [protocol_number, protocol_type] in protocol_table.items()
                    if protocol_number == int(packet.ip.proto)]
        print(protocol)

OUTPUT:

['TCP']
['UDP']
['ICMPV6']
truncated...
Life is complex
  • 15,374
  • 5
  • 29
  • 58