#!/bin/python

from ctypes import (CDLL, CFUNCTYPE, c_char, c_char_p, c_int, c_void_p, c_size_t, get_errno, sizeof, c_uint32)
import ctypes
import errno
import os

NETLINK_ROUTE = 0
LIBNL = CDLL('libnl-3.so', use_errno=True)

c = CDLL("libc.so.6")
c.__errno_location.restype = ctypes.POINTER(ctypes.c_int)

def get_errno():
    return c.__errno_location().contents.value;

_nl_connect = CFUNCTYPE(c_int, c_void_p, c_int)(('nl_connect', LIBNL))
_nl_socket_alloc = CFUNCTYPE(c_void_p)(('nl_socket_alloc', LIBNL))
_nl_socket_set_local_port = CFUNCTYPE(None, c_void_p, c_uint32)(('nl_socket_set_local_port', LIBNL))
_nl_socket_get_local_port = CFUNCTYPE(c_uint32, c_void_p)(('nl_socket_get_local_port', LIBNL))
_nl_geterror = CFUNCTYPE(c_char_p, c_int)(('nl_geterror', LIBNL))


parallel_handles = []

for i in range(0,1023):
    handle = _nl_socket_alloc()
    port = _nl_socket_get_local_port(handle)
    #_nl_socket_set_local_port (handle, port);
    print("create handle[%d]: %r - %u" % (i, handle, port))

    err = _nl_connect(handle, NETLINK_ROUTE)
    if err:
        n = get_errno()
        print("connect handle[%d] failed: %d - %d - %s" % (i, err, n, os.strerror(n)))
        raise IOError(-err, _nl_geterror(err))
    parallel_handles.append(handle)

for handle in parallel_handles:
    _nl_socket_set_local_port(handle, _nl_socket_get_local_port(handle))


for i in range(0,1):
    handle = _nl_socket_alloc()
    print("test handle[%d]: %r" % (i, handle))

    err = _nl_connect(handle, NETLINK_ROUTE)
    if err:
        print("connect handle failed: %d" % (err))
        raise IOError(-err, _nl_geterror(err))
    print("test handle[%d]: %r - connected to port %d" % (i, handle, _nl_socket_get_local_port(handle)))

