Use source based routing if secondary interfaces specify different gateway.
[pyplnet.git] / sioc.py
1 # $Id$
2 # vim:set ts=4 sw=4 expandtab:
3 # (c) Copyright 2008 The Trustees of Princeton University
4
5 import os
6 import socket
7 import fcntl
8 import struct
9 import subprocess
10
11 SIOCGIFADDR = 0x8915
12 SIOCGIFADDR_struct = "16xH2xI8x"
13 SIOCGIFHWADDR = 0x8927
14 SIOCGIFHWADDR_struct = "16x2x6B8x"
15
16 def _format_ip(nip):
17     ip = socket.ntohl(nip)
18     return "%d.%d.%d.%d" % ((ip & 0xff000000) >> 24,
19                             (ip & 0x00ff0000) >> 16,
20                             (ip & 0x0000ff00) >> 8,
21                             (ip & 0x000000ff))
22
23 def gifaddr(interface):
24     s = None
25     try:
26         s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0)
27         ifreq = fcntl.ioctl(s.fileno(), SIOCGIFADDR, struct.pack("16s16x", interface))
28         (family, ip) = struct.unpack(SIOCGIFADDR_struct, ifreq)
29         if family == socket.AF_INET:
30             return _format_ip(ip)
31     finally:
32         if s is not None:
33             s.close()
34     return None
35
36 def gifconf():
37     ret = {}
38     ip = subprocess.Popen(["/sbin/ip", "-4", "addr", "ls"],
39                           stdin=subprocess.PIPE, stdout=subprocess.PIPE,
40                           stderr=subprocess.PIPE, close_fds=True)
41     (stdout, stderr) = ip.communicate()
42     # no wait is needed when using communicate
43     for line in stdout.split("\n"):
44         fields = [ field.strip() for field in line.split() ]
45         if fields and fields[0] == "inet":
46             # fields[-1] is the last column in fields, which has the interface name
47             # fields[1] has the IP address / netmask width 
48             ret[fields[-1]] = fields[1].split("/")[0]
49     return ret
50
51 def gifhwaddr(interface):
52     s = None
53     try:
54         s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0)
55         ifreq = fcntl.ioctl(s.fileno(), SIOCGIFHWADDR, struct.pack("16s16x", interface))
56         mac = struct.unpack(SIOCGIFHWADDR_struct, ifreq)
57         return "%02x:%02x:%02x:%02x:%02x:%02x" % mac
58     finally:
59         s.close()
60     return None