3

I have a simple python script, that creates a socket AF_PACKET, which parses all IPv4 packets and retrieves the source and destination IP addresses:

import socket
import struct

def get_ip(s):
    return '.'.join([str(ord(symbol)) for symbol in s])

def main():
    conn = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.ntohs(3))

    while True:
    pkt, addr = conn.recvfrom(65536)

    proto = struct.unpack('! H', pkt[12:14])
    eth_proto = socket.htons(proto[0])

    print('eth_proto = ', eth_proto)
    if eth_proto == 8:
        src, target = struct.unpack('! 4s 4s', pkt[26:34])
        source_ip = get_ip(src)
        destination_ip = get_ip(target)

        print('Source IP = ', source_ip)
        print('Destination IP = ', destination_ip)

main()

Is it possible to refactor getting the IP address, so it will look better and doesn't use this loop:

'.'.join([str(ord(symbol)) for symbol in s])

Format characters is described here: https://docs.python.org/2/library/struct.html

2
  • Please show example input for the get_ip function and the desired output for that. Commented Jan 9, 2019 at 14:28
  • @ruohola output for the function get_ip is the string with ip address (e.g. 172.15.75.12) input is array of bytes. maybe I can read in different ways this bytes ? Commented Jan 9, 2019 at 15:07

1 Answer 1

1

If you are using Python 2 (as you have linked to the Python 2 docs), you can use a bytearray and a format string to remove the explicit loop.

>>> s = '\n\x0b\xfa\x01'
>>> '{}.{}.{}.{}'.format(*bytearray(s))
'10.11.250.1'

If you are using Python 3.3+, you can use the standard library's ipaddress module.

>> ipa2 = ipaddress.ip_address(b'\n\x0b\xfa\x01')
>>> ipa2
IPv4Address('10.11.250.1')
>>> str(ipa2)
'10.11.250.1'
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.