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