bat-serjo/PyIface

Can't read out IP address

Closed this issue · 3 comments

I can read out the interfaces but if I want to get the addr property I get an error message. Here is a minimal example in the python console:

>>> import pyiface
>>> pyiface.getIfaces()[0].addr
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/dist-packages/pyiface/iface.py", line 291, in addr
    ifr = self.__newIfreqWithName()
  File "/usr/local/lib/python2.7/dist-packages/pyiface/iface.py", line 181, in __newIfreqWithName
    ifr.ifr_name = self._name
TypeError: expected c_ubyte_Array_16 instance, got str

Any thoughts on what is going on? :)
Thanks!

petri commented

I can confirm this on Debian stable, Python 2.7.

petri commented

Easy fix. Just replace the:

 ifr.ifr_name = self._name

with:

ifr.ifr_name = (c_ubyte*IFNAMSIZ) (*bytearray(self._name))

That's how it's done elsewhere in the same module, anyway. For what it's worth, it might actually be better to use:

ifr.ifr_name = (c_ubyte*IFNAMSIZ).from_buffer_copy(self._name)

(assuming the interface name is always a regular string rather than unicode - I don't know if it always is)

For reasoning, see http://stackoverflow.com/questions/21483482/efficient-way-to-convert-string-to-ctypes-c-ubyte-array-in-python, especially the chosen answer by eryksun.

EDIT: the above second alternative does not work, the name has to be padded thus:

ifr.ifr_name = (c_ubyte*IFNAMSIZ).from_buffer_copy(self._name + (IFNAMSIZ-len(self._name))*'\0')

Which probably eats any performance benefits of the approach. Of course, we don't need to worry about performance here anyway, though.

petri commented

A PR submitted; @bat-serjo, think you can merge and make a release?