Skip to content

Instantly share code, notes, and snippets.

@subzer0iq
Last active March 28, 2024 10:35
Show Gist options
  • Save subzer0iq/889f6ea71c2fe490270ef1f5fc5a70af to your computer and use it in GitHub Desktop.
Save subzer0iq/889f6ea71c2fe490270ef1f5fc5a70af to your computer and use it in GitHub Desktop.
Python: List all default gateways on host
#!/usr/bin/env python3
"""
Determine IPv4/IPv6 default gateway(s) on a Linux machine via the socket interface.
"""
import socket
import struct
### Base netlink constants. See include/uapi/linux/netlink.h
NLM_F_REQUEST = 1
NLM_F_DUMP = 768
NLMSG_DONE = 3
### rtnetlink constants. See include/uapi/linux/rtnetlink.h
RTM_NEWROUTE = 24
RTM_GETROUTE = 26
RTN_UNICAST = 1
RTPROT_STATIC = 4
RTPROT_UNSPEC = 0
RT_SCOPE_UNIVERSE = 0
RT_TABLE_UNSPEC = 0
RTA_OIF = 4
RTA_GATEWAY = 5
flags = 0
flags |= NLM_F_REQUEST
flags |= NLM_F_DUMP
seq = 0
brk = 0
sock = socket.socket(socket.AF_NETLINK, socket.SOCK_RAW, socket.NETLINK_ROUTE)
pid = sock.getsockname()[1]
sock.bind((0,0))
rtnlpack_len = 28
nlpack_len = 16
nlmsg = struct.pack("=LHHLL", rtnlpack_len, RTM_GETROUTE, flags, seq, pid)
rtmsg = struct.pack("=BBBBBBBBI", 0, 0, 0, 0, RT_TABLE_UNSPEC, RTPROT_STATIC, RT_SCOPE_UNIVERSE, RTN_UNICAST, 0)
sock.send(nlmsg + rtmsg)
while data := sock.recv(65536):
nlmsg_step = 0
data_len = len(data)
while nlmsg_step < data_len:
nlmsg_len, nlmsg_type, *_ = struct.unpack("=LHHLL", data[nlmsg_step:nlmsg_step+nlpack_len])
if nlmsg_type == NLMSG_DONE:
brk = 1
break
if nlmsg_type == RTM_NEWROUTE:
rtm_family, rtm_dst_len = struct.unpack("=BB", data[nlpack_len+nlmsg_step:nlpack_len+nlmsg_step+2])
nla_step = 0
while nla_step < nlmsg_len - (rtnlpack_len + 4):
idx = rtnlpack_len + nlmsg_step + nla_step
nla_len, nla_type = struct.unpack("=HH", data[idx:idx+4])
if nla_type == RTA_GATEWAY and rtm_dst_len == 0:
print("default via {} dev {} metric {}".format(socket.inet_ntop(rtm_family, data[idx+4:idx+nla_len]),
socket.if_indextoname(data[idx+nla_len+4]),
struct.unpack("=H", data[idx-4:idx-2])[0]))
nla_step += nla_len
nlmsg_step += nlmsg_len
if brk == 1:
break
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment