Skip to content

Instantly share code, notes, and snippets.

@sphaero
Last active January 1, 2016 23:39
Show Gist options
  • Save sphaero/8218025 to your computer and use it in GitHub Desktop.
Save sphaero/8218025 to your computer and use it in GitHub Desktop.
# Based on http://carnivore.it/2012/10/12/python3.3_sendmsg_and_recvmsg
# Example of using the new recvmsg() method of the sockets module
import ipaddress
import socket
import ctypes
# First, we have to tell the socket we want to receive this additional data.
# As the socket module lacks some constants, we need to define them too.
IP_PKTINFO = 8
IPV6_PKTINFO = 50
IPV6_RECVPKTINFO = 49
SOL_IPV6 = 41
uint32_t = ctypes.c_uint32
in_addr_t = uint32_t
class in_addr(ctypes.Structure):
_fields_ = [('s_addr', in_addr_t)]
class in_pktinfo(ctypes.Structure):
_fields_ = [
('ipi_ifindex', ctypes.c_int),
('ipi_spec_dst', in_addr),
('ipi_addr', in_addr),
]
print("Setting up a broadcast beacon on %s:%s" %('255.255.255.255', 1200))
udp_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
udp_sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
udp_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
if socket.SO_REUSEPORT in dir(socket):
udp_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
udp_sock.setsockopt(socket.SOL_IP, IP_PKTINFO, 1)
udp_sock.bind(('255.255.255.255', 1200))
while True:
data, ancdata, msg_flags, _from = udp_sock.recvmsg(5120, socket.CMSG_LEN(5120 * 5))
for anc in ancdata:
if anc[0] == socket.SOL_IP and anc[1] == IP_PKTINFO:
inf = in_pktinfo.from_buffer_copy(anc[2])
addr = ipaddress.IPv4Address(memoryview(inf.ipi_addr).tobytes())
daddr = ipaddress.IPv4Address(memoryview(inf.ipi_spec_dst).tobytes())
idx = inf.ipi_ifindex
print(data, addr, daddr, idx)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment