1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
| import struct import socket import os
nlmsghdr_format = "=IHHII" ifinfomsg_format = "=BBHiII" ifaddrmsg_format = "=BBBBI" rtattr_format = "=HH" nlmsghdr_size = 16 ifinfomsg_size = 16 ifaddrmsg_size = 8 rtattr_size = 4
RTM_NEWROUTE = 24 RTM_DELROUTE = 25 IFA_LOCAL = 2 IFLA_IFNAME = 3 IFLA_MAX = 51 RTMGRP_LINK = 1 RTMGRP_IPV4_IFADDR = 0x10 RTMGRP_IPV4_ROUTE = 0x40 IFF_UP = 0x1 IFF_RUNNING = 0x40 RTM_DELADDR = 21 RTM_DELLINK = 17 RTM_NEWLINK = 16 RTM_NEWADDR = 20
sock = socket.socket(socket.AF_NETLINK, socket.SOCK_RAW, socket.NETLINK_ROUTE) sock.bind((os.getpid(), RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV4_ROUTE))
def parseRtattr(rta, msg_len, ifla_rta_ix): RTA_ALIGNTO = 4 RTA_ALIGN = lambda Length : (Length + RTA_ALIGNTO - 1) & ~(RTA_ALIGNTO - 1) tb = [None for _ in range(IFLA_MAX + 1)] point, size = 0, len(rta) rta_len, rta_type = struct.unpack(rtattr_format, rta[point : rtattr_size]) while msg_len >= rtattr_size and rtattr_size <= rta_len <= msg_len and point + rtattr_size <= size: rta_len, rta_type = struct.unpack(rtattr_format, rta[point : point + rtattr_size]) print("point is {}".format(point)) if rta_type <= IFLA_MAX: print("rta_type is {}, rta_len is {}, rta is {}".format(rta_type, rta_len, ifla_rta_ix + point)) tb[rta_type] = ifla_rta_ix + point + rtattr_size point += RTA_ALIGN(rta_len) msg_len -= RTA_ALIGN(rta_len)
return tb
while True: data = sock.recv(8192) nlmsghdr = data[0:nlmsghdr_size]
msg_len, msg_type, flags, seq, pid = struct.unpack(nlmsghdr_format, nlmsghdr) if msg_type == RTM_NEWROUTE or msg_type == RTM_DELROUTE: print("Routing table was changed") continue ifinfomsg = data[nlmsghdr_size : nlmsghdr_size + ifinfomsg_size] ifi_family, __ifi_pad, ifi_type, ifi_index, ifi_flags, ifi_change = struct.unpack(ifinfomsg_format, ifinfomsg) ifla_rta = data[nlmsghdr_size + ifinfomsg_size :] tb = parseRtattr(ifla_rta, msg_len, nlmsghdr_size + ifinfomsg_size)
if tb[IFLA_IFNAME]: for ix in range(tb[IFLA_IFNAME], len(data)): if data[ix] == '\x00': break ifName_format = "=" + "c" * (ix - tb[IFLA_IFNAME]) ifName = ''.join(struct.unpack(ifName_format, data[tb[IFLA_IFNAME] : ix])) print("ifName is {}".format(ifName)) if ifi_flags & IFF_UP: ifUpp = "UP" else: ifUpp = "DOWN" print(ifUpp) if ifi_flags & IFF_RUNNING: ifRunn = "RUNNING" else: ifRunn = "NOT RUNNING" print(ifRunn) ifaddrmsg = data[nlmsghdr_size : nlmsghdr_size + ifaddrmsg_size] ifa_family, ifa_prefixlen, ifa_flags, ifa_scope, ifa_index = struct.unpack(ifaddrmsg_format, ifaddrmsg) ifa = data[nlmsghdr_size + ifaddrmsg_size :] tba = parseRtattr(ifa, msg_len, nlmsghdr_size + ifaddrmsg_size) if tba[IFA_LOCAL]: for i in data[tba[IFA_LOCAL] : tba[IFA_LOCAL] + 4]: print(ord(i)) ifAddress = '.'.join(str(i) for i in struct.unpack('=BBBB', data[tba[IFA_LOCAL] : tba[IFA_LOCAL] + 4 ])) if msg_type == RTM_DELADDR: print("Interface {}: address was removed".format(ifName)) pass elif msg_type == RTM_DELLINK: print("Network interface {} was removed".format(ifName)) pass elif msg_type == RTM_NEWLINK: print("New network interface {}, state: {} {}".format(ifName, ifUpp, ifRunn)) pass elif msg_type == RTM_NEWADDR: print("Interface {}: new address was assigned: {}".format(ifName, ifAddress)) pass
close(sock)
|