4

Code I'm attempting to use in python 3.4:

#!/usr/bin/python3
 def get_mac_addr(ifname):
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    info = fcntl.ioctl(s.fileno(), 0x8927,  struct.pack('256s', ifname[:15]))
    return ''.join(['%02x:' % ord(char) for char in info[18:24]])[:-1]
 print (get_mac_addr('eth0'))

Error: struct.error: argument for 's' must be a bytes object

I see that this code does work when not using python3 but I need it in 3 for my project. I tried comparing to problem: Struct.Error, Must Be a Bytes Object? but I couldn't see how I can apply this to myself.

Community
  • 1
  • 1
Pam B
  • 43
  • 1
  • 3

1 Answers1

5

You need to convert the ifname string into bytes. You also don't need to call ord(), since ioctl returns bytes, not a string:

...
info = fcntl.ioctl(s.fileno(), 0x8927,  struct.pack('256s', bytes(ifname[:15], 'utf-8')))
return ''.join(['%02x:' % b for b in info[18:24]])[:-1]
...

See this SO question for more info about strings and bytes in python3

Community
  • 1
  • 1
pbkhrv
  • 647
  • 4
  • 11
  • Thanks! I think this(or something else?) may be causing another error. "TypeError: ord() expected string of length 1, but int found" I believe ord() is supposed to return an integer representing the Unicode code point of the string entered... anything you can direct me towards in this code specifically? – Pam B Dec 10 '14 at 01:08
  • Works perfectly! Been struggling with this for hours, thank you! I couldn't quite figure out the logic behind it. – Pam B Dec 10 '14 at 01:21