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)
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)
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)