get_interfaces.py
Go to the documentation of this file.
00001 #!/usr/bin/python
00002  
00003 # Based on getifaddrs.py from pydlnadms [http://code.google.com/p/pydlnadms/].
00004 # Only tested on Linux!
00005  
00006 from socket import AF_INET, AF_INET6, inet_ntop
00007 from ctypes import (
00008 Structure, Union, POINTER,
00009 pointer, get_errno, cast,
00010 c_ushort, c_byte, c_void_p, c_char_p, c_uint, c_int, c_uint16, c_uint32
00011 )
00012 import ctypes.util
00013 import ctypes
00014  
00015 class struct_sockaddr(Structure):
00016         _fields_ = [
00017                 ('sa_family', c_ushort),
00018                 ('sa_data', c_byte * 14),]
00019  
00020 class struct_sockaddr_in(Structure):
00021         _fields_ = [
00022                 ('sin_family', c_ushort),
00023                 ('sin_port', c_uint16),
00024                 ('sin_addr', c_byte * 4)]
00025  
00026 class struct_sockaddr_in6(Structure):
00027         _fields_ = [
00028                 ('sin6_family', c_ushort),
00029                 ('sin6_port', c_uint16),
00030                 ('sin6_flowinfo', c_uint32),
00031                 ('sin6_addr', c_byte * 16),
00032                 ('sin6_scope_id', c_uint32)]
00033  
00034 class union_ifa_ifu(Union):
00035         _fields_ = [
00036                 ('ifu_broadaddr', POINTER(struct_sockaddr)),
00037                 ('ifu_dstaddr', POINTER(struct_sockaddr)),]
00038  
00039 class struct_ifaddrs(Structure):
00040         pass
00041 struct_ifaddrs._fields_ = [
00042         ('ifa_next', POINTER(struct_ifaddrs)),
00043         ('ifa_name', c_char_p),
00044         ('ifa_flags', c_uint),
00045         ('ifa_addr', POINTER(struct_sockaddr)),
00046         ('ifa_netmask', POINTER(struct_sockaddr)),
00047         ('ifa_ifu', union_ifa_ifu),
00048         ('ifa_data', c_void_p),]
00049  
00050 libc = ctypes.CDLL(ctypes.util.find_library('c'))
00051  
00052 def ifap_iter(ifap):
00053         ifa = ifap.contents
00054         while True:
00055                 yield ifa
00056                 if not ifa.ifa_next:
00057                         break
00058                 ifa = ifa.ifa_next.contents
00059  
00060 def getfamaddr(sa):
00061         family = sa.sa_family
00062         addr = None
00063         if family == AF_INET:
00064                 sa = cast(pointer(sa), POINTER(struct_sockaddr_in)).contents
00065                 addr = inet_ntop(family, sa.sin_addr)
00066         elif family == AF_INET6:
00067                 sa = cast(pointer(sa), POINTER(struct_sockaddr_in6)).contents
00068                 addr = inet_ntop(family, sa.sin6_addr)
00069         return family, addr
00070  
00071 class NetworkInterface(object):
00072         def __init__(self, name):
00073                 self.name = name
00074                 self.index = libc.if_nametoindex(name)
00075                 self.addresses = {}
00076  
00077         def __str__(self):
00078                 return "%s [index=%d, IPv4=%s, IPv6=%s]" % (
00079                         self.name, self.index,
00080                         self.addresses.get(AF_INET),
00081                         self.addresses.get(AF_INET6))
00082         
00083         def name(self):
00084                 return self.name,
00085          
00086 def get_network_interfaces():
00087         ifap = POINTER(struct_ifaddrs)()
00088         result = libc.getifaddrs(pointer(ifap))
00089         if result != 0:
00090                 raise OSError(get_errno())
00091         del result
00092         try:
00093                 retval = {}
00094                 for ifa in ifap_iter(ifap):
00095                         name = ifa.ifa_name
00096                         i = retval.get(name)
00097                         if not i:
00098                                 i = retval[name] = NetworkInterface(name)
00099                         family, addr = getfamaddr(ifa.ifa_addr.contents)
00100                         if addr:
00101                                 i.addresses[family] = addr
00102                 return retval.values()
00103         finally:
00104                 libc.freeifaddrs(ifap)
00105  
00106 if __name__ == '__main__':
00107         print [str(ni) for ni in get_network_interfaces()]


explorer
Author(s): Daniel Neuhold , Torsten Andre
autogenerated on Thu Aug 27 2015 11:56:52