Exemplo n.º 1
0
def nl_socket_alloc(cb=None):
    """Allocate new Netlink socket. Does not yet actually open a socket.

    https://github.com/thom311/libnl/blob/libnl3_2_25/lib/socket.c#L206

    Also has code for generating local port once.
    https://github.com/thom311/libnl/blob/libnl3_2_25/lib/nl.c#L123

    Keyword arguments:
    cb -- custom callback handler.

    Returns:
    Newly allocated Netlink socket (nl_sock class instance) or None.
    """
    # Allocate the callback.
    cb = cb or nl_cb_alloc(default_cb)
    if not cb:
        return None

    # Allocate the socket.
    sk = nl_sock()
    sk.s_cb = cb
    sk.s_local.nl_family = getattr(socket, 'AF_NETLINK', -1)
    sk.s_peer.nl_family = getattr(socket, 'AF_NETLINK', -1)
    sk.s_seq_expect = sk.s_seq_next = int(time.time())
    sk.s_flags = NL_OWN_PORT  # The port is 0 (unspecified), meaning NL_OWN_PORT.

    # Generate local port.
    nl_socket_get_local_port(sk)  # I didn't find this in the C source, but during testing I saw this behavior.

    return sk
Exemplo n.º 2
0
def nl_socket_alloc(cb=None):
    """Allocate new Netlink socket. Does not yet actually open a socket.

    https://github.com/thom311/libnl/blob/libnl3_2_25/lib/socket.c#L206

    Also has code for generating local port once.
    https://github.com/thom311/libnl/blob/libnl3_2_25/lib/nl.c#L123

    Keyword arguments:
    cb -- custom callback handler.

    Returns:
    Newly allocated Netlink socket (nl_sock class instance) or None.
    """
    # Allocate the callback.
    cb = cb or nl_cb_alloc(default_cb)
    if not cb:
        return None

    # Allocate the socket.
    sk = nl_sock()
    sk.s_cb = cb
    sk.s_local.nl_family = getattr(socket, 'AF_NETLINK', -1)
    sk.s_peer.nl_family = getattr(socket, 'AF_NETLINK', -1)
    sk.s_seq_expect = sk.s_seq_next = int(time.time())
    sk.s_flags = NL_OWN_PORT  # The port is 0 (unspecified), meaning NL_OWN_PORT.

    # Generate local port.
    nl_socket_get_local_port(
        sk
    )  # I didn't find this in the C source, but during testing I saw this behavior.

    return sk
Exemplo n.º 3
0
def test_nl_socket_alloc():
    r"""C code to test against.

    // gcc a.c $(pkg-config --cflags --libs libnl-genl-3.0) && ./a.out
    #include <netlink/msg.h>
    struct nl_cb {
        nl_recvmsg_msg_cb_t cb_set[NL_CB_TYPE_MAX+1]; void * cb_args[NL_CB_TYPE_MAX+1]; nl_recvmsg_err_cb_t cb_err;
        void * cb_err_arg; int (*cb_recvmsgs_ow)(struct nl_sock *, struct nl_cb *);
        int (*cb_recv_ow)(struct nl_sock *, struct sockaddr_nl *, unsigned char **, struct ucred **);
        int (*cb_send_ow)(struct nl_sock *, struct nl_msg *); int cb_refcnt; enum nl_cb_type cb_active;
    };
    struct nl_sock {
        struct sockaddr_nl s_local; struct sockaddr_nl s_peer; int s_fd; int s_proto; unsigned int s_seq_next;
        unsigned int s_seq_expect; int s_flags; struct nl_cb *s_cb; size_t s_bufsize;
    };
    void print(struct nl_sock *sk) {
        printf("sk.s_local.nl_family = %d\n", sk->s_local.nl_family);
        printf("sk.s_local.nl_pid = %d  # changes every process, remains same throughout proc.\n", sk->s_local.nl_pid);
        printf("sk.s_local.nl_groups = %d\n", sk->s_local.nl_groups);
        printf("sk.s_peer.nl_family = %d\n", sk->s_peer.nl_family);
        printf("sk.s_peer.nl_pid = %d\n", sk->s_peer.nl_pid);
        printf("sk.s_peer.nl_groups = %d\n", sk->s_peer.nl_groups);
        printf("sk.s_fd = %d\n", sk->s_fd);
        printf("sk.s_proto = %d\n", sk->s_proto);
        printf("sk.s_flags = %d\n", sk->s_flags);
        printf("sk.s_cb.cb_active = %d\n", sk->s_cb->cb_active);
        printf("addr: sk.s_cb.cb_err = %p\n", sk->s_cb->cb_err);
    }
    int main() {
        struct nl_sock *sk = nl_socket_alloc();
        print(sk);
        nl_socket_free(sk);
        printf("\n");
        struct nl_cb *cb = nl_cb_alloc(NL_CB_VERBOSE);
        sk = nl_socket_alloc_cb(cb);
        nl_cb_put(cb);
        print(sk);
        nl_socket_free(sk);
        return 0;
    }
    // Expected output:
    // sk.s_local.nl_family = 16
    // sk.s_local.nl_pid = 12309  # changes every process, remains same throughout proc.
    // sk.s_local.nl_groups = 0
    // sk.s_peer.nl_family = 16
    // sk.s_peer.nl_pid = 0
    // sk.s_peer.nl_groups = 0
    // sk.s_fd = -1
    // sk.s_proto = 0
    // sk.s_flags = 0
    // sk.s_cb.cb_active = 11
    // addr: sk.s_cb.cb_err = (nil)
    //
    // sk.s_local.nl_family = 16
    // sk.s_local.nl_pid = 12309  # changes every process, remains same throughout proc.
    // sk.s_local.nl_groups = 0
    // sk.s_peer.nl_family = 16
    // sk.s_peer.nl_pid = 0
    // sk.s_peer.nl_groups = 0
    // sk.s_fd = -1
    // sk.s_proto = 0
    // sk.s_flags = 0
    // sk.s_cb.cb_active = 11
    // addr: sk.s_cb.cb_err = 0xb6f6eb40
    """
    sk = nl_socket_alloc()
    assert 16 == sk.s_local.nl_family
    assert 0 < sk.s_local.nl_pid
    assert 0 == sk.s_local.nl_groups
    assert 16 == sk.s_peer.nl_family
    assert 0 == sk.s_peer.nl_pid
    assert 0 == sk.s_peer.nl_groups
    assert -1 == sk.s_fd
    assert 0 == sk.s_proto
    assert 0 == sk.s_flags
    assert 11 == sk.s_cb.cb_active
    assert sk.s_cb.cb_err is None
    nl_socket_free(sk)

    first_pid = int(sk.s_local.nl_pid)
    sk = nl_socket_alloc(nl_cb_alloc(NL_CB_VERBOSE))
    assert 16 == sk.s_local.nl_family
    assert first_pid == sk.s_local.nl_pid
    assert 0 == sk.s_local.nl_groups
    assert 16 == sk.s_peer.nl_family
    assert 0 == sk.s_peer.nl_pid
    assert 0 == sk.s_peer.nl_groups
    assert -1 == sk.s_fd
    assert 0 == sk.s_proto
    assert 0 == sk.s_flags
    assert 11 == sk.s_cb.cb_active
    assert sk.s_cb.cb_err is not None
    nl_socket_free(sk)
Exemplo n.º 4
0
def test_nl_socket_alloc():
    r"""C code to test against.

    // gcc a.c $(pkg-config --cflags --libs libnl-genl-3.0) && ./a.out
    #include <netlink/msg.h>
    struct nl_cb {
        nl_recvmsg_msg_cb_t cb_set[NL_CB_TYPE_MAX+1]; void * cb_args[NL_CB_TYPE_MAX+1]; nl_recvmsg_err_cb_t cb_err;
        void * cb_err_arg; int (*cb_recvmsgs_ow)(struct nl_sock *, struct nl_cb *);
        int (*cb_recv_ow)(struct nl_sock *, struct sockaddr_nl *, unsigned char **, struct ucred **);
        int (*cb_send_ow)(struct nl_sock *, struct nl_msg *); int cb_refcnt; enum nl_cb_type cb_active;
    };
    struct nl_sock {
        struct sockaddr_nl s_local; struct sockaddr_nl s_peer; int s_fd; int s_proto; unsigned int s_seq_next;
        unsigned int s_seq_expect; int s_flags; struct nl_cb *s_cb; size_t s_bufsize;
    };
    void print(struct nl_sock *sk) {
        printf("sk.s_local.nl_family = %d\n", sk->s_local.nl_family);
        printf("sk.s_local.nl_pid = %d  # changes every process, remains same throughout proc.\n", sk->s_local.nl_pid);
        printf("sk.s_local.nl_groups = %d\n", sk->s_local.nl_groups);
        printf("sk.s_peer.nl_family = %d\n", sk->s_peer.nl_family);
        printf("sk.s_peer.nl_pid = %d\n", sk->s_peer.nl_pid);
        printf("sk.s_peer.nl_groups = %d\n", sk->s_peer.nl_groups);
        printf("sk.s_fd = %d\n", sk->s_fd);
        printf("sk.s_proto = %d\n", sk->s_proto);
        printf("sk.s_flags = %d\n", sk->s_flags);
        printf("sk.s_cb.cb_active = %d\n", sk->s_cb->cb_active);
        printf("addr: sk.s_cb.cb_err = %p\n", sk->s_cb->cb_err);
    }
    int main() {
        struct nl_sock *sk = nl_socket_alloc();
        print(sk);
        nl_socket_free(sk);
        printf("\n");
        struct nl_cb *cb = nl_cb_alloc(NL_CB_VERBOSE);
        sk = nl_socket_alloc_cb(cb);
        nl_cb_put(cb);
        print(sk);
        nl_socket_free(sk);
        return 0;
    }
    // Expected output:
    // sk.s_local.nl_family = 16
    // sk.s_local.nl_pid = 12309  # changes every process, remains same throughout proc.
    // sk.s_local.nl_groups = 0
    // sk.s_peer.nl_family = 16
    // sk.s_peer.nl_pid = 0
    // sk.s_peer.nl_groups = 0
    // sk.s_fd = -1
    // sk.s_proto = 0
    // sk.s_flags = 0
    // sk.s_cb.cb_active = 11
    // addr: sk.s_cb.cb_err = (nil)
    //
    // sk.s_local.nl_family = 16
    // sk.s_local.nl_pid = 12309  # changes every process, remains same throughout proc.
    // sk.s_local.nl_groups = 0
    // sk.s_peer.nl_family = 16
    // sk.s_peer.nl_pid = 0
    // sk.s_peer.nl_groups = 0
    // sk.s_fd = -1
    // sk.s_proto = 0
    // sk.s_flags = 0
    // sk.s_cb.cb_active = 11
    // addr: sk.s_cb.cb_err = 0xb6f6eb40
    """
    sk = nl_socket_alloc()
    assert 16 == sk.s_local.nl_family
    assert 0 < sk.s_local.nl_pid
    assert 0 == sk.s_local.nl_groups
    assert 16 == sk.s_peer.nl_family
    assert 0 == sk.s_peer.nl_pid
    assert 0 == sk.s_peer.nl_groups
    assert -1 == sk.s_fd
    assert 0 == sk.s_proto
    assert 0 == sk.s_flags
    assert 11 == sk.s_cb.cb_active
    assert sk.s_cb.cb_err is None
    nl_socket_free(sk)

    first_pid = int(sk.s_local.nl_pid)
    sk = nl_socket_alloc(nl_cb_alloc(NL_CB_VERBOSE))
    assert 16 == sk.s_local.nl_family
    assert first_pid == sk.s_local.nl_pid
    assert 0 == sk.s_local.nl_groups
    assert 16 == sk.s_peer.nl_family
    assert 0 == sk.s_peer.nl_pid
    assert 0 == sk.s_peer.nl_groups
    assert -1 == sk.s_fd
    assert 0 == sk.s_proto
    assert 0 == sk.s_flags
    assert 11 == sk.s_cb.cb_active
    assert sk.s_cb.cb_err is not None
    nl_socket_free(sk)