Esempio n. 1
0
def nl_send_simple(sk, type_, flags, buf=None, size=0):
    """Construct and transmit a Netlink message.

    https://github.com/thom311/libnl/blob/libnl3_2_25/lib/nl.c#L549

    Allocates a new Netlink message based on `type_` and `flags`. If `buf` points to payload of length `size` that
    payload will be appended to the message.

    Sends out the message using `nl_send_auto()`.

    Positional arguments:
    sk -- Netlink socket (nl_sock class instance).
    type_ -- Netlink message type (integer).
    flags -- Netlink message flags (integer).

    Keyword arguments:
    buf -- payload data.
    size -- size of `data` (integer).

    Returns:
    Number of characters sent on success or a negative error code.
    """
    msg = nlmsg_alloc_simple(type_, flags)
    if buf is not None and size:
        err = nlmsg_append(msg, buf, size, NLMSG_ALIGNTO)
        if err < 0:
            return err
    return nl_send_auto(sk, msg)
Esempio n. 2
0
File: nl.py Progetto: 0x90/libnl
def nl_send_simple(sk, type_, flags, buf=None, size=0):
    """Construct and transmit a Netlink message.

    https://github.com/thom311/libnl/blob/libnl3_2_25/lib/nl.c#L549

    Allocates a new Netlink message based on `type_` and `flags`. If `buf` points to payload of length `size` that
    payload will be appended to the message.

    Sends out the message using `nl_send_auto()`.

    Positional arguments:
    sk -- Netlink socket (nl_sock class instance).
    type_ -- Netlink message type (integer).
    flags -- Netlink message flags (integer).

    Keyword arguments:
    buf -- payload data.
    size -- size of `data` (integer).

    Returns:
    Number of characters sent on success or a negative error code.
    """
    msg = nlmsg_alloc_simple(type_, flags)
    if buf is not None and size:
        err = nlmsg_append(msg, buf, size, NLMSG_ALIGNTO)
        if err < 0:
            return err
    return nl_send_auto(sk, msg)
Esempio n. 3
0
def test_s_proto():
    """Test socket protocol."""
    sk = nl_socket_alloc()
    nl_connect(sk, NETLINK_ROUTE)
    msg = nlmsg_alloc_simple(0, 0)
    assert -1 == msg.nm_protocol

    nl_complete_msg(sk, msg)
    assert NETLINK_ROUTE == msg.nm_protocol
    nl_socket_free(sk)
Esempio n. 4
0
def test_nm_protocol():
    """Test protocol."""
    sk = nl_socket_alloc()
    msg = nlmsg_alloc_simple(0, 0)
    assert -1 == msg.nm_protocol

    msg.nm_protocol = 10
    nl_complete_msg(sk, msg)
    assert 10 == msg.nm_protocol
    nl_socket_free(sk)
Esempio n. 5
0
def test_nlmsg_pid():
    """Test pid."""
    sk = nl_socket_alloc()
    msg = nlmsg_alloc_simple(0, 0)
    assert 0 == msg.nm_nlh.nlmsg_pid

    msg.nm_nlh.nlmsg_pid = 10
    nl_complete_msg(sk, msg)
    assert 10 == msg.nm_nlh.nlmsg_pid
    nl_socket_free(sk)
Esempio n. 6
0
def test_dissect(monkeypatch):
    r"""Diff of C code (from test_bare()) to test against.

    --- test_bare.c	2015-02-08 12:43:15.543135855 -0800
    +++ test_dissect.c	2015-02-08 13:25:31.375715668 -0800
    @@ -16,8 +16,22 @@
             sk->s_local.nl_pid = 0;
             sk->s_seq_next = 0;

    -        int ret = nl_send_simple(sk, RTM_GETLINK, 0, NULL, 0);
    +        struct rtgenmsg rt_hdr = { .rtgen_family = AF_PACKET, };
    +        struct nl_msg *msg = nlmsg_alloc_simple(RTM_GETLINK, NLM_F_REQUEST | NLM_F_DUMP);
    +        nlmsg_append(msg, &rt_hdr, sizeof(rt_hdr), NLMSG_ALIGNTO);
    +        nl_complete_msg(sk, msg);
    +        struct nlmsghdr *nlh = nlmsg_hdr(msg);

    +        printf("%d == nlh->nlmsg_len\n", nlh->nlmsg_len);
    +        printf("%d == nlh->nlmsg_type\n", nlh->nlmsg_type);
    +        printf("%d == nlh->nlmsg_flags\n", nlh->nlmsg_flags);
    +        printf("%d == nlh->nlmsg_seq\n", nlh->nlmsg_seq);
    +        printf("%d == nlh->nlmsg_pid\n", nlh->nlmsg_pid);
    +
    +        struct iovec iov = { .iov_base = nlh, .iov_len = nlh->nlmsg_len };
    +        struct msghdr hdr = { .msg_iov = &iov, .msg_iovlen = 1, };
    +
    +        int ret = nl_sendmsg(sk, msg, &hdr);
             printf("Bytes: %d\n", ret);
             return 0;
         }
    """
    monkeypatch.setattr(libnl.socket_, 'generate_local_port', lambda: 0)

    sk = nl_socket_alloc()
    nl_connect(sk, NETLINK_ROUTE)
    sk.socket_instance.close()
    sk.s_local.nl_pid = 0
    sk.s_seq_next = 0

    rt_hdr = rtgenmsg(rtgen_family=socket.AF_PACKET)
    msg = nlmsg_alloc_simple(RTM_GETLINK, NLM_F_REQUEST | NLM_F_DUMP)
    nlmsg_append(msg, rt_hdr, rt_hdr.SIZEOF, NLMSG_ALIGNTO)
    nl_complete_msg(sk, msg)
    nlh = nlmsg_hdr(msg)

    assert 20 == nlh.nlmsg_len
    assert 18 == nlh.nlmsg_type
    assert 773 == nlh.nlmsg_flags
    assert 0 == nlh.nlmsg_seq
    assert 0 == nlh.nlmsg_pid

    assert b'FAAAABIABQMAAAAAAAAAABEAAAA=' == base64.b64encode(
        buffer(nlh.bytearray[:nlh.nlmsg_len]))
    nl_socket_free(sk)
Esempio n. 7
0
def test_dissect(monkeypatch):
    r"""Diff of C code (from test_bare()) to test against.

    --- test_bare.c	2015-02-08 12:43:15.543135855 -0800
    +++ test_dissect.c	2015-02-08 13:25:31.375715668 -0800
    @@ -16,8 +16,22 @@
             sk->s_local.nl_pid = 0;
             sk->s_seq_next = 0;

    -        int ret = nl_send_simple(sk, RTM_GETLINK, 0, NULL, 0);
    +        struct rtgenmsg rt_hdr = { .rtgen_family = AF_PACKET, };
    +        struct nl_msg *msg = nlmsg_alloc_simple(RTM_GETLINK, NLM_F_REQUEST | NLM_F_DUMP);
    +        nlmsg_append(msg, &rt_hdr, sizeof(rt_hdr), NLMSG_ALIGNTO);
    +        nl_complete_msg(sk, msg);
    +        struct nlmsghdr *nlh = nlmsg_hdr(msg);

    +        printf("%d == nlh->nlmsg_len\n", nlh->nlmsg_len);
    +        printf("%d == nlh->nlmsg_type\n", nlh->nlmsg_type);
    +        printf("%d == nlh->nlmsg_flags\n", nlh->nlmsg_flags);
    +        printf("%d == nlh->nlmsg_seq\n", nlh->nlmsg_seq);
    +        printf("%d == nlh->nlmsg_pid\n", nlh->nlmsg_pid);
    +
    +        struct iovec iov = { .iov_base = nlh, .iov_len = nlh->nlmsg_len };
    +        struct msghdr hdr = { .msg_iov = &iov, .msg_iovlen = 1, };
    +
    +        int ret = nl_sendmsg(sk, msg, &hdr);
             printf("Bytes: %d\n", ret);
             return 0;
         }
    """
    monkeypatch.setattr(libnl.socket_, 'generate_local_port', lambda: 0)

    sk = nl_socket_alloc()
    nl_connect(sk, NETLINK_ROUTE)
    sk.socket_instance.close()
    sk.s_local.nl_pid = 0
    sk.s_seq_next = 0

    rt_hdr = rtgenmsg(rtgen_family=socket.AF_PACKET)
    msg = nlmsg_alloc_simple(RTM_GETLINK, NLM_F_REQUEST | NLM_F_DUMP)
    nlmsg_append(msg, rt_hdr, rt_hdr.SIZEOF, NLMSG_ALIGNTO)
    nl_complete_msg(sk, msg)
    nlh = nlmsg_hdr(msg)

    assert 20 == nlh.nlmsg_len
    assert 18 == nlh.nlmsg_type
    assert 773 == nlh.nlmsg_flags
    assert 0 == nlh.nlmsg_seq
    assert 0 == nlh.nlmsg_pid

    assert b'FAAAABIABQMAAAAAAAAAABEAAAA=' == base64.b64encode(buffer(nlh.bytearray[:nlh.nlmsg_len]))
    nl_socket_free(sk)
Esempio n. 8
0
def test_error_nle_bad_sock():
    """Test for NLE_BAD_SOCK."""
    sk = nl_socket_alloc()
    msg = nlmsg_alloc_simple(0, 0)
    nl_connect(sk, NETLINK_ROUTE)
    sk.socket_instance.close()
    nl_complete_msg(sk, msg)

    message = 'Hello World!\n'
    iov = bytes(message.encode('ascii'))
    hdr = msghdr(msg_iov=iov)

    assert -3 == nl_sendmsg(sk, msg, hdr)
Esempio n. 9
0
def test_default(tcp_server):
    r"""C code to test against.

    // gcc a.c $(pkg-config --cflags --libs libnl-genl-3.0)
    // (nc -l 2000 &); sleep 0.1; ./a.out
    #include <netlink/msg.h>
    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;
    };
    int main() {
        struct sockaddr_in sin = { .sin_port = htons(2000), .sin_family = AF_INET, };
        sin.sin_addr.s_addr = inet_addr("127.0.0.1");
        int fd = socket(AF_INET, SOCK_STREAM, 0);
        connect(fd, (struct sockaddr *) &sin, sizeof(sin));

        struct nl_sock *sk = nl_socket_alloc();
        struct nl_msg *msg = nlmsg_alloc_simple(0, 0);
        nl_connect(sk, NETLINK_ROUTE);
        sk->s_fd = fd;
        sk->s_local.nl_pid = 0;
        nl_complete_msg(sk, msg);

        char message[] = "Hello World!\n";
        struct iovec iov = { .iov_base = message, .iov_len = sizeof(message), };
        struct msghdr hdr = { .msg_iov = &iov, .msg_iovlen = 1, };

        int ret = nl_sendmsg(sk, msg, &hdr);
        printf("Bytes: %d\n", ret);  // 14
        return 0;
    }
    // Expected bash output:
    // Hello World!
    // Bytes: 14
    """
    sk = nl_socket_alloc()
    msg = nlmsg_alloc_simple(0, 0)
    nl_connect(sk, NETLINK_ROUTE)
    sk.socket_instance.close()
    sk.socket_instance = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sk.socket_instance.connect(tcp_server.server.server_address)
    sk.s_local.nl_pid = 0
    nl_complete_msg(sk, msg)

    message = 'Hello World!\n\0'
    iov = bytes(message.encode('ascii'))
    hdr = msghdr(msg_iov=iov)

    assert 14 == nl_sendmsg(sk, msg, hdr)
    assert [iov] == tcp_server.data
    nl_socket_free(sk)
Esempio n. 10
0
def test_defaults(log):
    r"""C code to test against.

    // gcc a.c $(pkg-config --cflags --libs libnl-genl-3.0) && NLDBG=4 ./a.out
    #include <netlink/msg.h>
    struct ucred { __u32 pid; __u32 uid; __u32 gid; };
    struct nl_msg {
        int nm_protocol; int nm_flags; struct sockaddr_nl nm_src; struct sockaddr_nl nm_dst; struct ucred nm_creds;
        struct nlmsghdr *nm_nlh; size_t nm_size; int nm_refcnt;
    };
    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_msg *msg) {
        printf("%d == msg.nm_protocol\n", msg->nm_protocol);
        printf("%d == msg.nm_flags\n", msg->nm_flags);
        printf("%d == msg.nm_src.nl_family\n", msg->nm_src.nl_family);
        printf("%d == msg.nm_src.nl_pid\n", msg->nm_src.nl_pid);
        printf("%d == msg.nm_src.nl_groups\n", msg->nm_src.nl_groups);
        printf("%d == msg.nm_dst.nl_family\n", msg->nm_dst.nl_family);
        printf("%d == msg.nm_dst.nl_pid\n", msg->nm_dst.nl_pid);
        printf("%d == msg.nm_dst.nl_groups\n", msg->nm_dst.nl_groups);
        printf("%d == msg.nm_nlh.nlmsg_type\n", msg->nm_nlh->nlmsg_type);
        printf("%d == msg.nm_nlh.nlmsg_flags\n", msg->nm_nlh->nlmsg_flags);
        printf("%d == msg.nm_nlh.nlmsg_pid\n", msg->nm_nlh->nlmsg_pid);
    }
    int main() {
        printf("Begin main()\n");
        struct nl_sock *sk = nl_socket_alloc();
        printf("Allocated socket.\n");
        struct nl_msg *msg = nlmsg_alloc_simple(0, 0);
        printf("Allocated message.\n");
        printf("%d == nl_socket_get_local_port(sk)\n", nl_socket_get_local_port(sk));
        printf("%d == sk.s_proto\n", sk->s_proto);
        printf("\n");
        print(msg);
        printf("\n");
        nl_complete_msg(sk, msg);
        print(msg);
        return 0;
    }
    // Expected output (trimmed):
    // nl_cache_mngt_register: Registered cache operations genl/family
    // Begin main()
    // Allocated socket.
    // __nlmsg_alloc: msg 0x1e9c0b8: Allocated new message, maxlen=4096
    // nlmsg_alloc_simple: msg 0x1e9c0b8: Allocated new simple message
    // Allocated message.
    // 10083 == nl_socket_get_local_port(sk)
    // 0 == sk.s_proto
    //
    // -1 == msg.nm_protocol
    // 0 == msg.nm_flags
    // 0 == msg.nm_src.nl_family
    // 0 == msg.nm_src.nl_pid
    // 0 == msg.nm_src.nl_groups
    // 0 == msg.nm_dst.nl_family
    // 0 == msg.nm_dst.nl_pid
    // 0 == msg.nm_dst.nl_groups
    // 0 == msg.nm_nlh.nlmsg_type
    // 0 == msg.nm_nlh.nlmsg_flags
    // 0 == msg.nm_nlh.nlmsg_pid
    //
    // 0 == msg.nm_protocol
    // 0 == msg.nm_flags
    // 0 == msg.nm_src.nl_family
    // 0 == msg.nm_src.nl_pid
    // 0 == msg.nm_src.nl_groups
    // 0 == msg.nm_dst.nl_family
    // 0 == msg.nm_dst.nl_pid
    // 0 == msg.nm_dst.nl_groups
    // 0 == msg.nm_nlh.nlmsg_type
    // 5 == msg.nm_nlh.nlmsg_flags
    // 10083 == msg.nm_nlh.nlmsg_pid
    // nl_cache_mngt_unregister: Unregistered cache operations genl/family
    """
    del log[:]
    sk = nl_socket_alloc()
    msg = nlmsg_alloc_simple(0, 0)
    assert re.match('nlmsg_alloc: msg 0x[a-f0-9]+: Allocated new message', log.pop(0))
    assert re.match('nlmsg_alloc_simple: msg 0x[a-f0-9]+: Allocated new simple message', log.pop(0))
    local_port = int(nl_socket_get_local_port(sk))
    proto = int(sk.s_proto)

    assert 0 < local_port
    assert 0 == proto

    assert -1 == msg.nm_protocol
    assert 0 == msg.nm_flags
    assert 0 == msg.nm_src.nl_family
    assert 0 == msg.nm_src.nl_pid
    assert 0 == msg.nm_src.nl_groups
    assert 0 == msg.nm_dst.nl_family
    assert 0 == msg.nm_dst.nl_pid
    assert 0 == msg.nm_dst.nl_groups
    assert 0 == msg.nm_nlh.nlmsg_type
    assert 0 == msg.nm_nlh.nlmsg_flags
    assert 0 == msg.nm_nlh.nlmsg_pid

    nl_complete_msg(sk, msg)
    assert proto == msg.nm_protocol
    assert 0 == msg.nm_flags
    assert 0 == msg.nm_src.nl_family
    assert 0 == msg.nm_src.nl_pid
    assert 0 == msg.nm_src.nl_groups
    assert 0 == msg.nm_dst.nl_family
    assert 0 == msg.nm_dst.nl_pid
    assert 0 == msg.nm_dst.nl_groups
    assert 0 == msg.nm_nlh.nlmsg_type
    assert 5 == msg.nm_nlh.nlmsg_flags
    assert local_port == msg.nm_nlh.nlmsg_pid

    assert not log
    nl_socket_free(sk)