Python 3.4: Unknown format code 'x'

2019-03-04 21:06发布

问题:

I have issue about packet sniffer in Python3.

version of python: 3.4

I followed some tutorial that works, but not on my computer. This code has to get mac address, convert it to string and in main() method should print to me destination mac, source mac and protocol.

code: sniffer_demo.py

import socket
import struct
import textwrap

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

    while True:
        raw_data, addr = conn.recvfrom(65536)
        # one's and zero's put to the method ehternet_frame
        dest_mac, src_mac, eth_proto, data = ethernet_frame(raw_data)
        print('\nEthernet Frame:')
        print('Destination: {}, Source: {}, Protocol: {}'.format(dest_mac, src_mac, eth_proto))


# Unpack ethernet frame
def ethernet_frame(data):
    dest_mac, src_mac, proto = struct.unpack('! 6s 6s H', data[:14])
    return get_mac_addr(dest_mac), get_mac_addr(src_mac), socket.htons(proto), data[14:]


# Return properly formatted MAC address: (ie AA:BB:CC:DD:EE:FF)
def get_mac_addr(bytes_addr):
    bytes_str = map('{:02x}'.format, bytes_addr)
    return ':'.join(bytes_str).upper()

main()

The error is:

Traceback (most recent call last):
  File "sniffer_demo.py", line 28, in <module>
    main()
  File "sniffer_demo.py", line 11, in main
    dest_mac, src_mac, eth_proto, data = ethernet_frame(raw_data)
  File "sniffer_demo.py", line 19, in ethernet_frame
    return get_mac_addr(dest_mac), get_mac_addr(src_mac), socket.htons(proto), data[14:]
  File "sniffer_demo.py", line 24, in get_mac_addr
    bytes_str = map('{:02x}'.format, bytes_addr)
ValueError: Unknown format code 'x' for object of type 'str'

How to fix that?

回答1:

While trying to reproduce, your code seems to work exactly as expected. I do not see any shebang-line. Are you sure you are executing using python3?

Sample output from # python3.4 snif2.py:

Ethernet Frame:
Destination: A4:17:31:xx:xx:xx, Source: 00:0C:F6:xx:xx:xx, Protocol: 8

Ethernet Frame:
Destination: 00:0C:F6:xx:xx:xx, Source: A4:17:31:xx:xx:xx, Protocol: 8
^CTraceback (most recent call last):
  File "snif2.py", line 27, in <module>
    main()
  File "snif2.py", line 9, in main
    raw_data, addr = conn.recvfrom(65536)
KeyboardInterrupt


回答2:

Update your Python to version 3.6.