text: #!/usr/bin/python
  # -*- coding: utf-8 -*-
  #
  # Copyright (C) 2005, TUBITAK/UEKAE
  #
  # This program is free software; you can redistribute it and/or modify it
  # under the terms of the GNU General Public License as published by the
  # Free Software Foundation; either version 2 of the License, or (at your
  # option) any later version. Please read the COPYING file.
  #
  
  import os
  import array
  import fcntl
  import struct
  import socket
  
  class interface:
      """ ioctl stuff """
  
      IFNAMSIZ = 16               # interface name size
  
      # From <bits/ioctls.h>
  
      SIOCGIFADDR = 0x8915        # get PA address
      SIOCGIFBRDADDR  = 0x8919    # get broadcast PA address
      SIOCGIFCONF = 0x8912        # get iface list
      SIOCGIFFLAGS = 0x8913       # get flags
      SIOCGIFMTU = 0x8921         # get MTU size
      SIOCGIFNETMASK  = 0x891b    # get network PA mask
      SIOCSIFADDR = 0x8916        # set PA address
      SIOCSIFBRDADDR  = 0x891a    # set broadcast PA address
      SIOCSIFFLAGS = 0x8914       # set flags
      SIOCSIFMTU = 0x8922         # set MTU size
      SIOCSIFNETMASK  = 0x891c    # set network PA mask
  
      # From <net/if.h>    
  
      IFF_UP = 0x1           # Interface is up.
      IFF_BROADCAST = 0x2    # Broadcast address valid.
      IFF_DEBUG = 0x4        # Turn on debugging.
      IFF_LOOPBACK = 0x8     # Is a loopback net.
      IFF_POINTOPOINT = 0x10 # Interface is point-to-point link.
      IFF_NOTRAILERS = 0x20  # Avoid use of trailers.
      IFF_RUNNING = 0x40     # Resources allocated.
      IFF_NOARP = 0x80       # No address resolution protocol.
      IFF_PROMISC = 0x100    # Receive all packets.
      IFF_ALLMULTI = 0x200   # Receive all multicast packets.
      IFF_MASTER = 0x400     # Master of a load balancer.
      IFF_SLAVE = 0x800      # Slave of a load balancer.
      IFF_MULTICAST = 0x1000 # Supports multicast.
      IFF_PORTSEL = 0x2000   # Can set media type.
      IFF_AUTOMEDIA = 0x4000 # Auto media select active.
  
  
      def __init__(self):
          # create a socket to communicate with system
          self.sockfd = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  
      def _ioctl(self, func, args):
          return fcntl.ioctl(self.sockfd.fileno(), func, args)
  
      def _call(self, ifname, func, ip = None):
  
          if ip is None:
              data = (ifname + '\0'*32)[:32]
          else:
              ifreq = (ifname + '\0' * self.IFNAMSIZ)[:self.IFNAMSIZ]
              data = struct.pack("16si4s10x", ifreq, socket.AF_INET, socket.inet_aton(ip))
  
          try:
              result = self._ioctl(func, data)
          except IOError:
              return None
  
          return result
  
      def getInterfaceList(self):
          """ Get all interface names in a list """
          # get interface list
          buffer = array.array('c', '\0' * 1024)
          ifconf = struct.pack("iP", buffer.buffer_info()[1], buffer.buffer_info()[0])
          result = self._ioctl(self.SIOCGIFCONF, ifconf)
  
          # loop over interface names
          iflist = []
          size, ptr = struct.unpack("iP", result)
          for idx in range(0, size, 32):
              ifconf = buffer.tostring()[idx:idx+32]
              name, dummy = struct.unpack("16s16s", ifconf)
              name, dummy = name.split('\0', 1)
              iflist.append(name)
  
          return iflist
  
      def getAddr(self, ifname):
          """ Get the inet addr for an interface """
          result = self._call(ifname, self.SIOCGIFADDR)
          return socket.inet_ntoa(result[20:24])
  
      def getNetmask(self, ifname):
          """ Get the netmask for an interface """
          result = self._call(ifname, self.SIOCGIFNETMASK)
          return socket.inet_ntoa(result[20:24])
  
      def getBroadcast(self, ifname):
          """ Get the broadcast addr for an interface """
          result = self._call(ifname, self.SIOCGIFBRDADDR)
          return socket.inet_ntoa(result[20:24])
  
      def getStatus(self, ifname):
          """ Check whether interface is UP """
          result = self._call(ifname, self.SIOCGIFFLAGS)
          flags, = struct.unpack('H', result[16:18])
          return (flags & self.IFF_UP) != 0
  
      def getMTU(self, ifname):
          """ Get the MTU size of an interface """
          data = self._call(ifname, self.SIOCGIFMTU)
          mtu = struct.unpack("16si12x", data)[1]
          return mtu
  
      def setAddr(self, ifname, ip):
          """ Set the inet addr for an interface """
          result = self._call(ifname, self.SIOCSIFADDR, ip)
  
          if result and socket.inet_ntoa(result[20:24]) is ip:
              return True
          else:
              return None
  
      def setNetmask(self, ifname, ip):
          """ Set the netmask for an interface """
          result = self._call(ifname, self.SIOCSIFNETMASK, ip)
  
          if result and socket.inet_ntoa(result[20:24]) is ip:
              return True
          else:
              return None
  
      def setBroadcast(self, ifname, ip):
          """ Set the broadcast addr for an interface """
          result = self._call(ifname, self.SIOCSIFBRDADDR, ip)
  
          if socket.inet_ntoa(result[20:24]) is ip:
              return True
          else:
              return None
  
      def setStatusDown(self, ifname):
          """ Set interface status (UP/DOWN) """
          ifreq = (ifname + '\0' * self.IFNAMSIZ)[:self.IFNAMSIZ]
  
          result = self._call(ifname, self.SIOCGIFFLAGS)
          flags, = struct.unpack('H', result[16:18])
          flags &= ~self.IFF_UP
  
          data = struct.pack("16sh", ifreq, flags)
          result = self._ioctl(self.SIOCSIFFLAGS, data)
  
          return result
  
      def setStatusUp(self, ifname):
          """ Set interface status (UP/DOWN) """
          ifreq = (ifname + '\0' * self.IFNAMSIZ)[:self.IFNAMSIZ]
  
          flags = self.IFF_UP
          flags |= self.IFF_RUNNING
          flags |= self.IFF_BROADCAST
          flags |= self.IFF_MULTICAST
          flags &= ~self.IFF_NOARP
          flags &= ~self.IFF_PROMISC
  
          data = struct.pack("16sh", ifreq, flags)
          result = self._ioctl(self.SIOCSIFFLAGS, data)
  
          return result
  
      def setMTU(self, ifname, mtu):
          """ Set the MTU size of an interface """
          ifreq = (ifname + '\0' * self.IFNAMSIZ)[:self.IFNAMSIZ]
  
          data = struct.pack("16si", ifreq, mtu)
          result = self._ioctl(self.SIOCSIFMTU, data)
  
          if struct.unpack("16si", result)[1] is mtu:
              return True
          else:
              return None
  
  