summaryrefslogtreecommitdiff
path: root/tap-mac/tuntap/test/tuntap/interface_harness.py
diff options
context:
space:
mode:
Diffstat (limited to 'tap-mac/tuntap/test/tuntap/interface_harness.py')
-rw-r--r--tap-mac/tuntap/test/tuntap/interface_harness.py279
1 files changed, 0 insertions, 279 deletions
diff --git a/tap-mac/tuntap/test/tuntap/interface_harness.py b/tap-mac/tuntap/test/tuntap/interface_harness.py
deleted file mode 100644
index fe4f1fc5..00000000
--- a/tap-mac/tuntap/test/tuntap/interface_harness.py
+++ /dev/null
@@ -1,279 +0,0 @@
-# Copyright (c) 2011 Mattias Nissler <mattias.nissler@gmx.de>
-#
-# Redistribution and use in source and binary forms, with or without modification, are permitted
-# provided that the following conditions are met:
-#
-# 1. Redistributions of source code must retain the above copyright notice, this list of
-# conditions and the following disclaimer.
-# 2. Redistributions in binary form must reproduce the above copyright notice, this list of
-# conditions and the following disclaimer in the documentation and/or other materials provided
-# with the distribution.
-# 3. The name of the author may not be used to endorse or promote products derived from this
-# software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
-# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
-# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-import ctypes
-import ctypes.util
-import errno
-import fcntl
-import socket
-import struct
-
-from tuntap import ioctl
-from tuntap.sockaddr import SockaddrDl, SockaddrIn, SockaddrIn6
-
-libc = ctypes.CDLL(ctypes.util.find_library('c'))
-
-class struct_sockaddr(ctypes.Structure):
- _fields_ = [ ('sa_len', ctypes.c_uint8),
- ('sa_family', ctypes.c_uint8) ]
-
-class struct_ifaddrs(ctypes.Structure):
- pass
-
-struct_ifaddrs._fields_ = [ ('ifa_next', ctypes.POINTER(struct_ifaddrs)),
- ('ifa_name', ctypes.c_char_p),
- ('ifa_flags', ctypes.c_uint),
- ('ifa_addr', ctypes.POINTER(struct_sockaddr)),
- ('ifa_netmask', ctypes.POINTER(struct_sockaddr)),
- ('ifa_dstaddr', ctypes.POINTER(struct_sockaddr)),
- ('ifa_data', ctypes.c_void_p) ]
-
-def decodeSockaddr(sockaddr):
- if not sockaddr:
- return None
-
- data = ctypes.string_at(sockaddr, max(sockaddr.contents.sa_len, 16))
- if sockaddr.contents.sa_family == SockaddrDl.AF_LINK:
- return SockaddrDl.decode(data)
- elif sockaddr.contents.sa_family == socket.AF_INET:
- return SockaddrIn.decode(data)
- elif sockaddr.contents.sa_family == socket.AF_INET6:
- return SockaddrIn6.decode(data)
-
- return None
-
-def getIfAddrs(ifname):
- ifaddrs = (ctypes.POINTER(struct_ifaddrs))()
- assert not libc.getifaddrs(ctypes.byref(ifaddrs))
-
- addrs = []
- try:
- entry = ifaddrs
- while entry:
- ia = entry.contents
- entry = ia.ifa_next
- if ia.ifa_name != ifname:
- continue
-
- addrs.append((decodeSockaddr(ia.ifa_addr),
- decodeSockaddr(ia.ifa_netmask),
- decodeSockaddr(ia.ifa_dstaddr)))
- return addrs
- finally:
- libc.freeifaddrs(ifaddrs)
-
-
-def ifNameToIndex(ifname):
- libc.if_nametoindex.restype = ctypes.c_uint
- index = libc.if_nametoindex(ifname)
- if not index:
- raise OSError(ctypes.get_errno)
- return index
-
-
-class Address(object):
- """
- Wraps address parameters for an interface.
- """
-
- def __init__(self, af, local, remote, dst, mask):
- self.af = af
- self.local = local
- self.remote = remote
- self.dst = dst
- self.mask = mask
-
- def __makeSaProperty(name):
- def get(self):
- addrmap = { socket.AF_INET: SockaddrIn,
- socket.AF_INET6: SockaddrIn6 }
- addr = getattr(self, name)
- if self.af not in addrmap:
- return None
- if addr == None:
- return addrmap[self.af](af = 0, addr = None)
- return addrmap[self.af](af = self.af, addr = addr)
-
- return property(get)
-
- sa_local = __makeSaProperty('local')
- sa_remote = __makeSaProperty('remote')
- sa_dst = __makeSaProperty('dst')
- sa_mask = __makeSaProperty('mask')
-
-
-class InterfaceHarness(object):
- """
- Base class for network interface harnesses. Provides helpers to configure the interface.
- """
-
- SIOCSIFFLAGS = ioctl.IOC(ioctl.OUT, 'i', 16, '16s16s')
- SIOCGIFFLAGS = ioctl.IOC(ioctl.INOUT, 'i', 17, '16s16s')
-
- SIOCAIFADDR = ioctl.IOC(ioctl.OUT, 'i', 26, '16s16s16s16s')
- SIOCAIFADDR_IN6 = ioctl.IOC(ioctl.OUT, 'i', 26, '16s28s28s28sIiiII')
- SIOCSIFLLADDR = ioctl.IOC(ioctl.OUT, 'i', 60, '16s16s')
-
- IFF_UP = 0x1
- IFF_BROADCAST = 0x2
- IFF_DEBUG = 0x4
- IFF_LOOPBACK = 0x8
- IFF_POINTOPOINT = 0x10
- IFF_NOTRAILERS = 0x20
- IFF_RUNNING = 0x40
- IFF_NOARP = 0x80
- IFF_PROMISC = 0x100
- IFF_ALLMULTI = 0x200
- IFF_OACTIVE = 0x400
- IFF_SIMPLEX = 0x800
- IFF_LINK0 = 0x1000
- IFF_LINK1 = 0x2000
- IFF_LINK2 = 0x4000
- IFF_MULTICAST = 0x8000
-
- def __init__(self, class_name, unit):
- """
- Initializes the harness.
-
- Args:
- class_name: Interface class name.
- unit: The interface number.
- """
- self._class_name = class_name
- self._unit = unit
-
- def _ioctl(self, af, cmd, format, arg):
- """
- Performs a socket ioctl.
-
- Args:
- af: address family.
- cmd: the ioctl cmd.
- format: argument format description.
- arg: argument data tuple.
-
- Returns:
- Output data tuple.
- """
- s = socket.socket(af, socket.SOCK_DGRAM)
- try:
- return struct.unpack(format, fcntl.ioctl(s, cmd, struct.pack(format, *arg)))
- finally:
- s.close()
-
- @property
- def flags(self):
- """
- Retrieves the interface flags.
-
- Returns:
- The interface flags.
- """
- return self._ioctl(socket.AF_INET, InterfaceHarness.SIOCGIFFLAGS,
- '16sH', (self.name, 0))[1]
-
- @flags.setter
- def flags(self, flags):
- """
- Sets new interface flags.
-
- Args:
- flags: new interface flags.
- """
- self._ioctl(socket.AF_INET, InterfaceHarness.SIOCSIFFLAGS,
- '16sH', (self.name, flags))
-
- @property
- def name(self):
- """
- Gets the interface name.
-
- Returns:
- Full interface name.
- """
- return "%s%d" % (self._class_name, self._unit)
-
- @property
- def index(self):
- """
- Gets the interface index.
-
- Returns:
- Interface index.
- """
- return ifNameToIndex(self.name)
-
- def getAddrs(self, af = None):
- def check(addr):
- if addr and addr.af == af:
- return addr
- else:
- return None
- return filter(lambda (a, n, d): a != None,
- map(lambda (a, n, d): (check(a), check(n), check(d)), getIfAddrs(self.name)))
-
- @property
- def lladdr(self):
- entry = self.getAddrs(SockaddrDl.AF_LINK)
- if entry:
- return entry[0][0]
- return None
-
- @lladdr.setter
- def lladdr(self, addr):
- self._ioctl(socket.AF_INET, InterfaceHarness.SIOCSIFLLADDR,
- '16sBB14s', (self.name, len(addr.addr), addr.af, addr.addr))
-
- def addIfAddr(self, local, dst, mask):
- """
- Set an interface address.
-
- Args:
- local: local address.
- dst: broadcast address or destination address, respectively.
- mask: the netmask.
- """
- self._ioctl(socket.AF_INET, InterfaceHarness.SIOCAIFADDR,
- '16s16s16s16s', (self.name, local.encode(), dst.encode(), mask.encode()))
-
- def addIfAddr6(self, local, dst, mask):
- """
- Set an INET6 address for the interface.
-
- Args:
- local: local address.
- dst: destination address.
- mask: the netmask.
- """
- # This sometimes fails on Tiger with ENOBUFS. Just retry...
- ntries = 0
- while True:
- try:
- self._ioctl(socket.AF_INET6, InterfaceHarness.SIOCAIFADDR_IN6,
- '16s28s28s28sIiiII',
- (self.name, local.encode(), dst.encode(), mask.encode(),
- 0, 0, 0, 0xffffffff, 0xffffffff))
- break
- except IOError as e:
- if e.errno != errno.ENOBUFS or ntries > 10:
- raise e
- ntries += 1