Created
February 11, 2018 15:43
-
-
Save H0neyBadger/20df070881fe7786ed91755a4d89dfc4 to your computer and use it in GitHub Desktop.
Python udp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# coding: utf-8 | |
import socket | |
import IN | |
from ctypes import * | |
from threading import Thread | |
from time import sleep | |
# TODO import these value | |
MSG_ERRQUEUE = 0x2000 | |
MSG_WAITALL = 0x100 | |
MSG_WAITFORONE = 0x10000 | |
hosts = [ | |
# "localhost", | |
"192.168.0.10", | |
"192.168.0.11", | |
# "192.168.0.12", | |
# "1.1.1.1", | |
] | |
port = 15555 | |
#port = 22 | |
# https://github.com/floodlight/oftest/blob/master/src/python/oftest/afpacket.py | |
class struct_iovec(Structure): | |
_fields_ = [ | |
("iov_base", c_void_p), | |
("iov_len", c_size_t), | |
] | |
class struct_msghdr(Structure): | |
_fields_ = [ | |
("msg_name", c_void_p), | |
("msg_namelen", c_uint32), | |
("msg_iov", POINTER(struct_iovec)), | |
("msg_iovlen", c_size_t), | |
("msg_control", c_void_p), | |
("msg_controllen", c_size_t), | |
("msg_flags", c_int), | |
] | |
class struct_cmsghdr(Structure): | |
_fields_ = [ | |
("cmsg_len", c_size_t), | |
("cmsg_level", c_int), | |
("cmsg_type", c_int), | |
] | |
class sock_extended_err(Structure): | |
""" | |
{ | |
uint32_t ee_errno; /* error number */ | |
uint8_t ee_origin; /* where the error originated */ | |
uint8_t ee_type; /* type */ | |
uint8_t ee_code; /* code */ | |
uint8_t ee_pad; /* padding */ | |
uint32_t ee_info; /* additional information */ | |
uint32_t ee_data; /* other data */ | |
/* More data may follow */ | |
}; | |
""" | |
_fields_= [ | |
("ee_errno", c_uint32), | |
("ee_origin", c_uint8), | |
("ee_type", c_uint8), | |
("ee_code", c_uint8), | |
("ee_pad", c_uint8), | |
("ee_info", c_uint32), | |
("ee_data", c_uint32), | |
] | |
def getdict(self): | |
return dict((field, getattr(self, field)) for field, _ in self._fields_) | |
libc = CDLL("libc.so.6") | |
recvmsg = libc.recvmsg | |
recvmsg.argtypes = [c_int, POINTER(struct_msghdr), c_int] | |
recvmsg.retype = c_int | |
class ErrorReader(Thread): | |
def __init__(self, socket): | |
Thread.__init__(self) | |
self.s = socket | |
def run(self): | |
s = self.s | |
struct_msghdr | |
sfd = s.fileno() | |
c = 0 | |
bufsize = 2048 | |
buf = create_string_buffer(bufsize) | |
ctrl_bufsize = sizeof(struct_cmsghdr) + sizeof(sock_extended_err) + sizeof(c_size_t) | |
ctrl_buf = create_string_buffer(ctrl_bufsize) | |
iov = struct_iovec() | |
iov.iov_base = cast(buf, c_void_p) | |
iov.iov_len = bufsize | |
msghdr = struct_msghdr() | |
msghdr.msg_name = None | |
msghdr.msg_namelen = 0 | |
msghdr.msg_iov = pointer(iov) | |
msghdr.msg_iovlen = 1 | |
msghdr.msg_control = cast(ctrl_buf, c_void_p) | |
msghdr.msg_controllen = ctrl_bufsize | |
msghdr.msg_flags = 0 | |
while True: | |
c = c + 1 | |
a = recvmsg(sfd, byref(msghdr), MSG_ERRQUEUE | MSG_WAITFORONE) | |
sleep(0.01) | |
if a >= 0: | |
assert msghdr.msg_controllen >= sizeof(struct_cmsghdr) | |
cmsghdr = struct_cmsghdr.from_buffer(ctrl_buf) | |
#print(cmsghdr.cmsg_type) | |
if cmsghdr.cmsg_type == IN.IP_RECVERR: | |
ser = sock_extended_err.from_buffer(ctrl_buf, sizeof(struct_cmsghdr)) | |
print(a, c) | |
print(ser.getdict()) | |
return None | |
for host in hosts: | |
s = socket.socket(socket.AF_INET, | |
#socket.SOCK_STREAM) | |
socket.SOCK_DGRAM) | |
s.setsockopt( socket.IPPROTO_IP, IN.IP_RECVERR, 1 ) | |
error_reader = ErrorReader(s) | |
error_reader.start() | |
try: | |
#s.connect((host, port)) | |
print "Connection to {} {}".format(host, port) | |
#s.send(u"Hello") | |
s.sendto("hello",(host, port)) | |
except Exception as e: | |
print("Exception: {} {} {}".format(host, port, e)) | |
error_reader.join(1) | |
s.close() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment