Skip to content

Instantly share code, notes, and snippets.

@cwyang
Created February 25, 2021 02:40
Show Gist options
  • Save cwyang/1efae10e13f33f4b8427383a6db0a695 to your computer and use it in GitHub Desktop.
Save cwyang/1efae10e13f33f4b8427383a6db0a695 to your computer and use it in GitHub Desktop.
import os
import socket
import struct
# These constants map to constants in the Linux kernel. This is a crappy
# way to get at them, but it'll do for now.
RTMGRP_LINK = 1
NLMSG_NOOP = 1
NLMSG_ERROR = 2
RTM_NEWLINK = 16
RTM_DELLINK = 17
IFLA_IFNAME = 3
# Create the netlink socket and bind to RTMGRP_LINK,
s = socket.socket(socket.AF_NETLINK, socket.SOCK_RAW, socket.NETLINK_ROUTE)
s.bind((os.getpid(), RTMGRP_LINK))
while True:
data = s.recv(65535)
msg_len, msg_type, flags, seq, pid = struct.unpack("=LHHLL", data[:16])
if msg_type == NLMSG_NOOP:
print("SKIP: no-op")
continue
elif msg_type == NLMSG_ERROR:
print("ERROR, exit")
break
# We fundamentally only care about NEWLINK messages in this version.
if msg_type == RTM_NEWLINK:
print("NEWLINK")
elif msg_type == RTM_DELLINK:
print("DELLINK")
else:
print("SKIP: msg-type " + hex(msg_type))
continue
data = data[16:]
family, _, if_type, index, flags, change = struct.unpack("=BBHiII", data[:16])
remaining = msg_len - 32
data = data[16:]
while remaining:
rta_len, rta_type = struct.unpack("=HH", data[:4])
# This check comes from RTA_OK, and terminates a string of routing
# attributes.
if rta_len < 4:
break
rta_data = data[4:rta_len]
align = (rta_len + 4 - 1) & ~(4 - 1) # align to 4 byte
data = data[align:]
remaining -= align
# Hoorah, a link is up!
if rta_type == IFLA_IFNAME:
print("IF %d: %s FLAG:%s" % (index, rta_data, hex(flags)))
@cwyang
Copy link
Author

cwyang commented Feb 25, 2021

host if의 change이벤트는 위와 같이 받을 수 있습니다.

다음과 같이 해서 foo device를 만들고 up하고 down하고 지우면

root@vagrant:/home/vagrant/work# ip link add name foo type dummy
root@vagrant:/home/vagrant/work# ip link set dev foo up
root@vagrant:/home/vagrant/work# ip link set dev foo down
root@vagrant:/home/vagrant/work# ip link del dev foo

아래와 같이 감지해요

vagrant@vagrant:~/work$ /usr/bin/python3 monif.py 
NEWLINK
IF 6: b'foo\x00' FLAG:0x82
NEWLINK
IF 6: b'foo\x00' FLAG:0x100c3
NEWLINK
IF 6: b'foo\x00' FLAG:0x82
DELLINK
IF 6: b'foo\x00' FLAG:0x82
11:44 AM

플래그는 net/if.h에 있습니다. up=0x1, run=0x40 등등

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment