示例#1
0
文件: test_attr.py 项目: ewa/libnl
def test_ints():
    """Test integer attributes."""
    msg = nlmsg_alloc()
    assert 0 == libnl.attr.nla_put_u8(msg, 2, 10)
    assert 0 == libnl.attr.nla_put_u16(msg, 3, 11)
    assert 0 == libnl.attr.nla_put_u32(msg, 4, 12)
    assert 0 == libnl.attr.nla_put_u64(msg, 5, 13195)

    attr = nlmsg_find_attr(nlmsg_hdr(msg), 0, 2)
    assert 2 == libnl.attr.nla_type(attr)
    assert 10 == libnl.attr.nla_get_u8(attr)
    assert 5 == attr.nla_len
    assert b"BQACAAo=" == base64.b64encode(buffer(attr.bytearray[: attr.nla_len]))

    attr = nlmsg_find_attr(nlmsg_hdr(msg), 0, 3)
    assert 3 == libnl.attr.nla_type(attr)
    assert 11 == libnl.attr.nla_get_u16(attr)
    assert 6 == attr.nla_len
    assert b"BgADAAsA" == base64.b64encode(buffer(attr.bytearray[: attr.nla_len]))

    attr = nlmsg_find_attr(nlmsg_hdr(msg), 0, 4)
    assert 4 == libnl.attr.nla_type(attr)
    assert 12 == libnl.attr.nla_get_u32(attr)
    assert 8 == attr.nla_len
    assert b"CAAEAAwAAAA=" == base64.b64encode(buffer(attr.bytearray[: attr.nla_len]))

    attr = nlmsg_find_attr(nlmsg_hdr(msg), 0, 5)
    assert 5 == libnl.attr.nla_type(attr)
    assert 13195 == libnl.attr.nla_get_u64(attr)  # printf("%llu\n", nla_get_u64(attr));
    assert 12 == attr.nla_len
    assert b"DAAFAIszAAAAAAAA" == base64.b64encode(buffer(attr.bytearray[: attr.nla_len]))
示例#2
0
def callback(msg, _):
    """Callback function called by libnl upon receiving messages from the kernel.

    Positional arguments:
    msg -- nl_msg class instance containing the data sent by the kernel.

    Returns:
    An integer, value of NL_OK. It tells libnl to proceed with processing the next kernel message.
    """
    # First convert `msg` into something more manageable.
    nlh = nlmsg_hdr(msg)
    iface = ifinfomsg(nlmsg_data(nlh))
    hdr = IFLA_RTA(iface)
    remaining = ctypes.c_int(nlh.nlmsg_len - NLMSG_LENGTH(iface.SIZEOF))

    # Now iterate through each rtattr stored in `iface`.
    while RTA_OK(hdr, remaining):
        # Each rtattr (which is what hdr is) instance is only one type. Looping through all of them until we run into
        # the ones we care about.
        if hdr.rta_type == IFLA_IFNAME:
            print('Found network interface {0}: {1}'.format(
                iface.ifi_index,
                get_string(RTA_DATA(hdr)).decode('ascii')))
        hdr = RTA_NEXT(hdr, remaining)
    return NL_OK
示例#3
0
def probe_response(msg, arg):
    """Process responses from from the query sent by genl_ctrl_probe_by_name().

    https://github.com/thom311/libnl/blob/libnl3_2_25/lib/genl/ctrl.c#L203

    Process returned messages, filling out the missing information in the genl_family structure.

    Positional arguments:
    msg -- returned message (nl_msg class instance).
    arg -- genl_family class instance to fill out.

    Returns:
    Indicator to keep processing frames or not (NL_SKIP or NL_STOP).
    """
    tb = dict((i, None) for i in range(CTRL_ATTR_MAX + 1))
    nlh = nlmsg_hdr(msg)
    ret = arg
    if genlmsg_parse(nlh, 0, tb, CTRL_ATTR_MAX, ctrl_policy):
        return NL_SKIP
    if tb[CTRL_ATTR_FAMILY_ID]:
        genl_family_set_id(ret, nla_get_u16(tb[CTRL_ATTR_FAMILY_ID]))
    if tb[CTRL_ATTR_MCAST_GROUPS] and parse_mcast_grps(
            ret, tb[CTRL_ATTR_MCAST_GROUPS]) < 0:
        return NL_SKIP
    return NL_STOP
示例#4
0
def callback_dump(msg, results):
    """Here is where SSIDs and their data is decoded from the binary data sent by the kernel.

    This function is called once per SSID. Everything in `msg` pertains to just one SSID.

    Positional arguments:
    msg -- nl_msg class instance containing the data sent by the kernel.
    results -- dictionary to populate with parsed data.
    """
    bss = dict()  # To be filled by nla_parse_nested().

    # First we must parse incoming data into manageable chunks and check for errors.
    gnlh = genlmsghdr(nlmsg_data(nlmsg_hdr(msg)))
    tb = dict((i, None) for i in range(nl80211.NL80211_ATTR_MAX + 1))
    nla_parse(tb, nl80211.NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), None)
    if not tb[nl80211.NL80211_ATTR_BSS]:
        print('WARNING: BSS info missing for an access point.')
        return libnl.handlers.NL_SKIP
    if nla_parse_nested(bss, nl80211.NL80211_BSS_MAX, tb[nl80211.NL80211_ATTR_BSS], bss_policy):
        print('WARNING: Failed to parse nested attributes for an access point!')
        return libnl.handlers.NL_SKIP
    if not bss[nl80211.NL80211_BSS_BSSID]:
        print('WARNING: No BSSID detected for an access point!')
        return libnl.handlers.NL_SKIP
    if not bss[nl80211.NL80211_BSS_INFORMATION_ELEMENTS]:
        print('WARNING: No additional information available for an access point!')
        return libnl.handlers.NL_SKIP

    # Further parse and then store. Overwrite existing data for BSSID if scan is run multiple times.
    bss_parsed = parse_bss(bss)
    results[bss_parsed['bssid']] = bss_parsed
    return libnl.handlers.NL_SKIP
示例#5
0
    def _callback_dump(self, msg, results):
        # Here is where SSIDs and their data is decoded from the binary data
        # sent by the kernel. This function is called once per SSID. Everything
        # in `msg` pertains to just one SSID.
        #
        # Positional arguments:
        # msg -- nl_msg class instance containing the data sent by the kernel.
        # results -- dictionary to populate with parsed data.
        bss = dict()  # To be filled by nla_parse_nested().

        # First we must parse incoming data into manageable chunks and check for errors.
        gnlh = genlmsghdr(nlmsg_data(nlmsg_hdr(msg)))
        tb = dict((i, None) for i in range(nl80211.NL80211_ATTR_MAX + 1))
        nla_parse(tb, nl80211.NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
                  genlmsg_attrlen(gnlh, 0), None)
        if not tb[nl80211.NL80211_ATTR_BSS]:
            logger.warning('BSS info missing for an access point.')
            return libnl.handlers.NL_SKIP
        if nla_parse_nested(bss, nl80211.NL80211_BSS_MAX,
                            tb[nl80211.NL80211_ATTR_BSS], bss_policy):
            logger.warning(
                'Failed to parse nested attributes for an access point!')
            return libnl.handlers.NL_SKIP
        if not bss[nl80211.NL80211_BSS_BSSID]:
            logger.warning('No BSSID detected for an access point!')
            return libnl.handlers.NL_SKIP
        if not bss[nl80211.NL80211_BSS_INFORMATION_ELEMENTS]:
            logger.warning(
                'No additional information available for an access point!')
            return libnl.handlers.NL_SKIP

        # Further parse and then store. Overwrite existing data for BSSID if scan is run multiple times.
        bss_parsed = parse_bss(bss)
        results[bss_parsed['bssid']] = bss_parsed
        return libnl.handlers.NL_SKIP
示例#6
0
文件: nl.py 项目: kimocoder/libnl-1
def nl_send(sk, msg):
    """Transmit Netlink message.

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

    Transmits the Netlink message `msg` over the Netlink socket using the `socket.sendmsg()`. This function is based on
    `nl_send_iovec()`.

    The message is addressed to the peer as specified in the socket by either the nl_socket_set_peer_port() or
    nl_socket_set_peer_groups() function. The peer address can be overwritten by specifying an address in the `msg`
    object using nlmsg_set_dst().

    If present in the `msg`, credentials set by the nlmsg_set_creds() function are added to the control buffer of the
    message.

    Calls to this function can be overwritten by providing an alternative using the nl_cb_overwrite_send() function.

    This function triggers the `NL_CB_MSG_OUT` callback.

    ATTENTION:  Unlike `nl_send_auto()`, this function does *not* finalize the message in terms of automatically adding
    needed flags or filling out port numbers.

    Positional arguments:
    sk -- Netlink socket (nl_sock class instance).
    msg -- Netlink message (nl_msg class instance).

    Returns:
    Number of bytes sent on success or a negative error code.
    """
    cb = sk.s_cb
    if cb.cb_send_ow:
        return cb.cb_send_ow(sk, msg)
    hdr = nlmsg_hdr(msg)
    iov = hdr.bytearray[:hdr.nlmsg_len]
    return nl_send_iovec(sk, msg, iov, 1)
示例#7
0
def test_nla_put_get_u32():
    r"""C code to test against.

    // gcc a.c $(pkg-config --cflags --libs libnl-genl-3.0) && ./a.out
    #include <netlink/msg.h>
    int main() {
        int rem, i, range[] = { 0, 1, 2, 19, 20, 50 };
        struct nl_msg *msg = nlmsg_alloc();
        struct nlmsghdr *nlh = nlmsg_hdr(msg);
        struct nlattr *nla;
        for (i = 0; i < (sizeof(range) / sizeof(int)); i++) nla_put_u32(msg, i, range[i]);
        nlmsg_for_each_attr(nla, nlh, 0, rem) printf("type: %d; nla_get_u32: %d\n", nla_type(nla), nla_get_u32(nla));
        nlmsg_free(msg);
        return 0;
    }
    // Expected output:
    // type: 0; nla_get_u32: 0
    // type: 1; nla_get_u32: 1
    // type: 2; nla_get_u32: 2
    // type: 3; nla_get_u32: 19
    // type: 4; nla_get_u32: 20
    // type: 5; nla_get_u32: 50
    """
    rem = c_int()
    range_ = (0, 1, 2, 19, 20, 50)
    msg = nlmsg_alloc()
    nlh = nlmsg_hdr(msg)
    for i in range(len(range_)):
        libnl.attr.nla_put_u32(msg, i, range_[i])
    i = 0
    for nla in nlmsg_for_each_attr(nlh, 0, rem):
        assert i == libnl.attr.nla_type(nla)
        assert range_[i] == libnl.attr.nla_get_u32(nla)
        i += 1
示例#8
0
文件: test_attr.py 项目: ewa/libnl
def test_nla_put_get_u32():
    r"""C code to test against.

    // gcc a.c $(pkg-config --cflags --libs libnl-genl-3.0) && ./a.out
    #include <netlink/msg.h>
    int main() {
        int rem, i, range[] = { 0, 1, 2, 19, 20, 50 };
        struct nl_msg *msg = nlmsg_alloc();
        struct nlmsghdr *nlh = nlmsg_hdr(msg);
        struct nlattr *nla;
        for (i = 0; i < (sizeof(range) / sizeof(int)); i++) nla_put_u32(msg, i, range[i]);
        nlmsg_for_each_attr(nla, nlh, 0, rem) printf("type: %d; nla_get_u32: %d\n", nla_type(nla), nla_get_u32(nla));
        nlmsg_free(msg);
        return 0;
    }
    // Expected output:
    // type: 0; nla_get_u32: 0
    // type: 1; nla_get_u32: 1
    // type: 2; nla_get_u32: 2
    // type: 3; nla_get_u32: 19
    // type: 4; nla_get_u32: 20
    // type: 5; nla_get_u32: 50
    """
    rem = c_int()
    range_ = (0, 1, 2, 19, 20, 50)
    msg = nlmsg_alloc()
    nlh = nlmsg_hdr(msg)
    for i in range(len(range_)):
        libnl.attr.nla_put_u32(msg, i, range_[i])
    i = 0
    for nla in nlmsg_for_each_attr(nlh, 0, rem):
        assert i == libnl.attr.nla_type(nla)
        assert range_[i] == libnl.attr.nla_get_u32(nla)
        i += 1
示例#9
0
文件: nl.py 项目: 0x90/libnl
def nl_send(sk, msg):
    """Transmit Netlink message.

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

    Transmits the Netlink message `msg` over the Netlink socket using the `socket.sendmsg()`. This function is based on
    `nl_send_iovec()`.

    The message is addressed to the peer as specified in the socket by either the nl_socket_set_peer_port() or
    nl_socket_set_peer_groups() function. The peer address can be overwritten by specifying an address in the `msg`
    object using nlmsg_set_dst().

    If present in the `msg`, credentials set by the nlmsg_set_creds() function are added to the control buffer of the
    message.

    Calls to this function can be overwritten by providing an alternative using the nl_cb_overwrite_send() function.

    This function triggers the `NL_CB_MSG_OUT` callback.

    ATTENTION:  Unlike `nl_send_auto()`, this function does *not* finalize the message in terms of automatically adding
    needed flags or filling out port numbers.

    Positional arguments:
    sk -- Netlink socket (nl_sock class instance).
    msg -- Netlink message (nl_msg class instance).

    Returns:
    Number of bytes sent on success or a negative error code.
    """
    cb = sk.s_cb
    if cb.cb_send_ow:
        return cb.cb_send_ow(sk, msg)
    hdr = nlmsg_hdr(msg)
    iov = hdr.bytearray[:hdr.nlmsg_len]
    return nl_send_iovec(sk, msg, iov, 1)
示例#10
0
def dump_callback(msg, _):

    gnlh = genlmsghdr(nlmsg_data(nlmsg_hdr(msg)))
    tb = dict((i, None) for i in range(NCSI_ATTR_MAX + 1))
    nla_parse(tb, NCSI_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
              genlmsg_attrlen(gnlh, 0), None)

    print(tb)
    return NL_SKIP
示例#11
0
文件: test_attr.py 项目: ewa/libnl
def test_msecs():
    """Test milliseconds."""
    msg = nlmsg_alloc()
    assert 0 == libnl.attr.nla_put_msecs(msg, 12, 99)

    attr = nlmsg_find_attr(nlmsg_hdr(msg), 0, 12)
    assert 12 == libnl.attr.nla_type(attr)
    assert 99 == libnl.attr.nla_get_msecs(attr)
    assert 12 == attr.nla_len
    assert b"DAAMAGMAAAAAAAAA" == base64.b64encode(buffer(attr.bytearray[: attr.nla_len]))
示例#12
0
    def callback_trigger(self, msg, arg):
        gnlh = genlmsghdr(nlmsg_data(nlmsg_hdr(msg)))

        tb = dict((i, None) for i in range(10 + 1))
        nla_parse(tb, nl80211.NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
                  genlmsg_attrlen(gnlh, 0), None)
        if tb.get(NL_CMD_RECOVERY_MSG):
            self.recovery = True

        return libnl.handlers.NL_STOP
示例#13
0
文件: test_attr.py 项目: ewa/libnl
def test_flag():
    """Test flags."""
    msg = nlmsg_alloc()
    assert 0 == libnl.attr.nla_put_flag(msg, 7)

    attr = nlmsg_find_attr(nlmsg_hdr(msg), 0, 7)
    assert 7 == libnl.attr.nla_type(attr)
    assert libnl.attr.nla_get_flag(attr) is True  # printf("%s\n", nla_get_flag(attr) ? "True" : "False");
    assert 4 == attr.nla_len
    assert b"BAAHAA==" == base64.b64encode(buffer(attr.bytearray[: attr.nla_len]))
def callback(msg, has_printed):
    """Callback function called by libnl upon receiving messages from the kernel.

    Positional arguments:
    msg -- nl_msg class instance containing the data sent by the kernel.
    has_printed -- simple pseudo boolean (if list is empty) to keep track of when to print emtpy lines.

    Returns:
    An integer, value of NL_SKIP. It tells libnl to stop calling other callbacks for this message and proceed with
    processing the next kernel message.
    """
    table = AsciiTable([['Data Type', 'Data Value']])
    # First convert `msg` into something more manageable.
    gnlh = genlmsghdr(nlmsg_data(nlmsg_hdr(msg)))

    # Partially parse the raw binary data and place them in the `tb` dictionary.
    tb = dict(
        (i, None)
        for i in range(nl80211.NL80211_ATTR_MAX +
                       1))  # Need to populate dict with all possible keys.
    nla_parse(tb, nl80211.NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
              genlmsg_attrlen(gnlh, 0), None)

    # Now it's time to grab the juicy data!
    if tb[nl80211.NL80211_ATTR_IFNAME]:
        table.title = nla_get_string(
            tb[nl80211.NL80211_ATTR_IFNAME]).decode('ascii')
    else:
        table.title = 'Unnamed Interface'

    if tb[nl80211.NL80211_ATTR_WIPHY]:
        wiphy_num = nla_get_u32(tb[nl80211.NL80211_ATTR_WIPHY])
        wiphy = ('wiphy {0}'
                 if OPTIONS['<interface>'] else 'phy#{0}').format(wiphy_num)
        table.table_data.append(['NL80211_ATTR_WIPHY', wiphy])

    if tb[nl80211.NL80211_ATTR_MAC]:
        mac_address = ':'.join(
            format(x, '02x')
            for x in nla_data(tb[nl80211.NL80211_ATTR_MAC])[:6])
        table.table_data.append(['NL80211_ATTR_MAC', mac_address])

    if tb[nl80211.NL80211_ATTR_IFINDEX]:
        table.table_data.append([
            'NL80211_ATTR_IFINDEX',
            str(nla_get_u32(tb[nl80211.NL80211_ATTR_IFINDEX]))
        ])

    # Print all data.
    if has_printed:
        print()
    else:
        has_printed.append(True)
    print(table.table)
    return NL_SKIP
示例#15
0
    def callback(msg, arg):
        nlh = nlmsg_hdr(msg)
        iface = ifinfomsg(nlmsg_data(nlh))
        hdr = IFLA_RTA(iface)
        remaining = c_int(nlh.nlmsg_len - NLMSG_LENGTH(iface.SIZEOF))

        while RTA_OK(hdr, remaining):
            if hdr.rta_type == IFLA_IFNAME:
                arg[int(iface.ifi_index)] = str(get_string(RTA_DATA(hdr)).decode('ascii'))
            hdr = RTA_NEXT(hdr, remaining)
        return NL_OK
示例#16
0
def test_msecs():
    """Test milliseconds."""
    msg = nlmsg_alloc()
    assert 0 == libnl.attr.nla_put_msecs(msg, 12, 99)

    attr = nlmsg_find_attr(nlmsg_hdr(msg), 0, 12)
    assert 12 == libnl.attr.nla_type(attr)
    assert 99 == libnl.attr.nla_get_msecs(attr)
    assert 12 == attr.nla_len
    assert b'DAAMAGMAAAAAAAAA' == base64.b64encode(
        buffer(attr.bytearray[:attr.nla_len]))
示例#17
0
文件: test_attr.py 项目: ewa/libnl
def test_string_short():
    """Test string attributes with a short string."""
    payload = bytes("test".encode("ascii"))
    msg = nlmsg_alloc()
    assert 0 == libnl.attr.nla_put_string(msg, 6, payload)

    attr = nlmsg_find_attr(nlmsg_hdr(msg), 0, 6)
    assert 6 == libnl.attr.nla_type(attr)
    assert payload == libnl.attr.nla_get_string(attr)
    assert 9 == attr.nla_len
    assert b"CQAGAHRlc3QA" == base64.b64encode(buffer(attr.bytearray[: attr.nla_len]))
示例#18
0
文件: test_attr.py 项目: ewa/libnl
def test_string_medium():
    """Test string attributes with a longer string."""
    payload = bytes("The quick br()wn f0x jumps over the l@zy dog!".encode("ascii"))
    msg = nlmsg_alloc()
    assert 0 == libnl.attr.nla_put_string(msg, 6, payload)

    attr = nlmsg_find_attr(nlmsg_hdr(msg), 0, 6)
    assert 6 == libnl.attr.nla_type(attr)
    assert payload == libnl.attr.nla_get_string(attr)
    assert 50 == attr.nla_len
    expected = b"MgAGAFRoZSBxdWljayBicigpd24gZjB4IGp1bXBzIG92ZXIgdGhlIGxAenkgZG9nIQA="
    assert expected == base64.b64encode(buffer(attr.bytearray[: attr.nla_len]))
示例#19
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)
示例#20
0
def test_string_short():
    """Test string attributes with a short string."""
    payload = bytes('test'.encode('ascii'))
    msg = nlmsg_alloc()
    assert 0 == libnl.attr.nla_put_string(msg, 6, payload)

    attr = nlmsg_find_attr(nlmsg_hdr(msg), 0, 6)
    assert 6 == libnl.attr.nla_type(attr)
    assert payload == libnl.attr.nla_get_string(attr)
    assert 9 == attr.nla_len
    assert b'CQAGAHRlc3QA' == base64.b64encode(
        buffer(attr.bytearray[:attr.nla_len]))
示例#21
0
def test_flag():
    """Test flags."""
    msg = nlmsg_alloc()
    assert 0 == libnl.attr.nla_put_flag(msg, 7)

    attr = nlmsg_find_attr(nlmsg_hdr(msg), 0, 7)
    assert 7 == libnl.attr.nla_type(attr)
    assert libnl.attr.nla_get_flag(
        attr) is True  # printf("%s\n", nla_get_flag(attr) ? "True" : "False");
    assert 4 == attr.nla_len
    assert b'BAAHAA==' == base64.b64encode(
        buffer(attr.bytearray[:attr.nla_len]))
示例#22
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)
示例#23
0
def test_string_medium():
    """Test string attributes with a longer string."""
    payload = bytes(
        'The quick br()wn f0x jumps over the l@zy dog!'.encode('ascii'))
    msg = nlmsg_alloc()
    assert 0 == libnl.attr.nla_put_string(msg, 6, payload)

    attr = nlmsg_find_attr(nlmsg_hdr(msg), 0, 6)
    assert 6 == libnl.attr.nla_type(attr)
    assert payload == libnl.attr.nla_get_string(attr)
    assert 50 == attr.nla_len
    expected = b'MgAGAFRoZSBxdWljayBicigpd24gZjB4IGp1bXBzIG92ZXIgdGhlIGxAenkgZG9nIQA='
    assert expected == base64.b64encode(buffer(attr.bytearray[:attr.nla_len]))
示例#24
0
def test_string_long():
    """Test string attributes with a long string."""
    payload = bytes(string.printable[:-2].encode('ascii'))
    msg = nlmsg_alloc()
    assert 0 == libnl.attr.nla_put_string(msg, 6, payload)

    attr = nlmsg_find_attr(nlmsg_hdr(msg), 0, 6)
    assert 6 == libnl.attr.nla_type(attr)
    assert payload == libnl.attr.nla_get_string(attr)
    assert 103 == attr.nla_len
    expected = (
        b'ZwAGADAxMjM0NTY3ODlhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ekFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaISIjJCUmJygp'
        b'KissLS4vOjs8PT4/QFtcXV5fYHt8fX4gCQoNAA==')
    assert expected == base64.b64encode(buffer(attr.bytearray[:attr.nla_len]))
示例#25
0
def test_ints():
    """Test integer attributes."""
    msg = nlmsg_alloc()
    assert 0 == libnl.attr.nla_put_u8(msg, 2, 10)
    assert 0 == libnl.attr.nla_put_u16(msg, 3, 11)
    assert 0 == libnl.attr.nla_put_u32(msg, 4, 12)
    assert 0 == libnl.attr.nla_put_u64(msg, 5, 13195)

    attr = nlmsg_find_attr(nlmsg_hdr(msg), 0, 2)
    assert 2 == libnl.attr.nla_type(attr)
    assert 10 == libnl.attr.nla_get_u8(attr)
    assert 5 == attr.nla_len
    assert b'BQACAAo=' == base64.b64encode(
        buffer(attr.bytearray[:attr.nla_len]))

    attr = nlmsg_find_attr(nlmsg_hdr(msg), 0, 3)
    assert 3 == libnl.attr.nla_type(attr)
    assert 11 == libnl.attr.nla_get_u16(attr)
    assert 6 == attr.nla_len
    assert b'BgADAAsA' == base64.b64encode(
        buffer(attr.bytearray[:attr.nla_len]))

    attr = nlmsg_find_attr(nlmsg_hdr(msg), 0, 4)
    assert 4 == libnl.attr.nla_type(attr)
    assert 12 == libnl.attr.nla_get_u32(attr)
    assert 8 == attr.nla_len
    assert b'CAAEAAwAAAA=' == base64.b64encode(
        buffer(attr.bytearray[:attr.nla_len]))

    attr = nlmsg_find_attr(nlmsg_hdr(msg), 0, 5)
    assert 5 == libnl.attr.nla_type(attr)
    assert 13195 == libnl.attr.nla_get_u64(
        attr)  # printf("%llu\n", nla_get_u64(attr));
    assert 12 == attr.nla_len
    assert b'DAAFAIszAAAAAAAA' == base64.b64encode(
        buffer(attr.bytearray[:attr.nla_len]))
示例#26
0
文件: test_attr.py 项目: ewa/libnl
def test_string_long():
    """Test string attributes with a long string."""
    payload = bytes(string.printable[:-2].encode("ascii"))
    msg = nlmsg_alloc()
    assert 0 == libnl.attr.nla_put_string(msg, 6, payload)

    attr = nlmsg_find_attr(nlmsg_hdr(msg), 0, 6)
    assert 6 == libnl.attr.nla_type(attr)
    assert payload == libnl.attr.nla_get_string(attr)
    assert 103 == attr.nla_len
    expected = (
        b"ZwAGADAxMjM0NTY3ODlhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ekFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaISIjJCUmJygp"
        b"KissLS4vOjs8PT4/QFtcXV5fYHt8fX4gCQoNAA=="
    )
    assert expected == base64.b64encode(buffer(attr.bytearray[: attr.nla_len]))
示例#27
0
def callback_trigger(msg, arg):
    """Called when the kernel is done scanning. Only signals if it was successful or if it failed. No other data.

    Positional arguments:
    msg -- nl_msg class instance containing the data sent by the kernel.
    arg -- mutable integer (ctypes.c_int()) to update with results.

    Returns:
    An integer, value of NL_SKIP. It tells libnl to stop calling other callbacks for this message and proceed with
    processing the next kernel message.
    """
    gnlh = genlmsghdr(nlmsg_data(nlmsg_hdr(msg)))
    if gnlh.cmd == nl80211.NL80211_CMD_SCAN_ABORTED:
        arg.value = 1  # The scan was aborted for some reason.
    elif gnlh.cmd == nl80211.NL80211_CMD_NEW_SCAN_RESULTS:
        arg.value = 0  # The scan completed successfully. `callback_dump` will collect the results later.
    return libnl.handlers.NL_SKIP
示例#28
0
def callback_trigger(msg, arg):
    """Called when the kernel is done scanning. Only signals if it was successful or if it failed. No other data.

    Positional arguments:
    msg -- nl_msg class instance containing the data sent by the kernel.
    arg -- mutable integer (ctypes.c_int()) to update with results.

    Returns:
    An integer, value of NL_SKIP. It tells libnl to stop calling other callbacks for this message and proceed with
    processing the next kernel message.
    """
    gnlh = genlmsghdr(nlmsg_data(nlmsg_hdr(msg)))
    if gnlh.cmd == nl80211.NL80211_CMD_SCAN_ABORTED:
        arg.value = 1  # The scan was aborted for some reason.
    elif gnlh.cmd == nl80211.NL80211_CMD_NEW_SCAN_RESULTS:
        arg.value = 0  # The scan completed successfully. `callback_dump` will collect the results later.
    return libnl.handlers.NL_SKIP
示例#29
0
 def callback_send(sk, msg):
     assert 16 == 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 msg.nm_creds is None
     assert 16 == msg.nm_nlh.nlmsg_type
     assert 5 == msg.nm_nlh.nlmsg_flags
     assert 100 < msg.nm_nlh.nlmsg_pid
     assert 1 == msg.nm_refcnt
     hdr = nlmsg_hdr(msg)
     iov = hdr.bytearray[:hdr.nlmsg_len]
     dump_hex(logging.getLogger().debug, iov, len(iov), 0)
     return nl_send_iovec(sk, msg, iov, 1)
示例#30
0
文件: test_ctrl.py 项目: 0x90/libnl
 def callback_send(sk, msg):
     assert 16 == 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 msg.nm_creds is None
     assert 16 == msg.nm_nlh.nlmsg_type
     assert 5 == msg.nm_nlh.nlmsg_flags
     assert 100 < msg.nm_nlh.nlmsg_pid
     assert 1 == msg.nm_refcnt
     hdr = nlmsg_hdr(msg)
     iov = hdr.bytearray[:hdr.nlmsg_len]
     dump_hex(logging.getLogger().debug, iov, len(iov), 0)
     return nl_send_iovec(sk, msg, iov, 1)
示例#31
0
def callback(msg, has_printed):
    """Callback function called by libnl upon receiving messages from the kernel.

    Positional arguments:
    msg -- nl_msg class instance containing the data sent by the kernel.
    has_printed -- simple pseudo boolean (if list is empty) to keep track of when to print emtpy lines.

    Returns:
    An integer, value of NL_SKIP. It tells libnl to stop calling other callbacks for this message and proceed with
    processing the next kernel message.
    """
    table = AsciiTable([['Data Type', 'Data Value']])
    # First convert `msg` into something more manageable.
    gnlh = genlmsghdr(nlmsg_data(nlmsg_hdr(msg)))

    # Partially parse the raw binary data and place them in the `tb` dictionary.
    tb = dict((i, None) for i in range(nl80211.NL80211_ATTR_MAX + 1))  # Need to populate dict with all possible keys.
    nla_parse(tb, nl80211.NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), None)

    # Now it's time to grab the juicy data!
    if tb[nl80211.NL80211_ATTR_IFNAME]:
        table.title = nla_get_string(tb[nl80211.NL80211_ATTR_IFNAME]).decode('ascii')
    else:
        table.title = 'Unnamed Interface'

    if tb[nl80211.NL80211_ATTR_WIPHY]:
        wiphy_num = nla_get_u32(tb[nl80211.NL80211_ATTR_WIPHY])
        wiphy = ('wiphy {0}' if OPTIONS['<interface>'] else 'phy#{0}').format(wiphy_num)
        table.table_data.append(['NL80211_ATTR_WIPHY', wiphy])

    if tb[nl80211.NL80211_ATTR_MAC]:
        mac_address = ':'.join(format(x, '02x') for x in nla_data(tb[nl80211.NL80211_ATTR_MAC])[:6])
        table.table_data.append(['NL80211_ATTR_MAC', mac_address])

    if tb[nl80211.NL80211_ATTR_IFINDEX]:
        table.table_data.append(['NL80211_ATTR_IFINDEX', str(nla_get_u32(tb[nl80211.NL80211_ATTR_IFINDEX]))])

    # Print all data.
    if has_printed:
        print()
    else:
        has_printed.append(True)
    print(table.table)
    return NL_SKIP
示例#32
0
 def callback(_, msg_):
     nlh = nlmsg_hdr(msg_)
     assert 20 == nlh.nlmsg_len
     assert 16 == nlh.nlmsg_type
     assert 5 == nlh.nlmsg_flags
     ops = nl_cache_ops_associate_safe(NETLINK_GENERIC, nlh.nlmsg_type)
     assert 'genl/family' == ops.co_name
     assert 4 == ops.co_hdrsize
     assert 16 == ops.co_protocol
     assert 0 == ops.co_hash_size
     assert 0 == ops.co_flags
     assert 'genl/family' == ops.co_obj_ops.oo_name
     assert 80 == ops.co_obj_ops.oo_size
     assert 1 == ops.co_obj_ops.oo_id_attrs
     assert 0 == nlmsg_attrlen(nlh, ops.co_hdrsize)
     mt = nl_msgtype_lookup(ops, nlh.nlmsg_type)
     assert 16 == mt.mt_id
     assert 0 == mt.mt_act
     assert 'nlctrl' == mt.mt_name
     called.append(True)
     return NL_STOP
示例#33
0
def test_seq():
    """Test sequences."""
    msg = nlmsg_alloc()
    nlh = nlmsg_hdr(msg)
    assert 16 == nlh.nlmsg_len
    assert 0 == nlh.nlmsg_type
    assert 0 == nlh.nlmsg_flags
    assert 0 == nlh.nlmsg_seq
    assert 0 == nlh.nlmsg_pid

    sk = nl_socket_alloc()
    nl_connect(sk, NETLINK_ROUTE)
    sk.socket_instance.close()
    sk.s_local.nl_pid = 0
    nl_complete_msg(sk, msg)
    assert 1423351063 <= nlh.nlmsg_seq
    nlh.nlmsg_seq = 1423350947
    assert 1423350947 == nlh.nlmsg_seq
    nlh.nlmsg_pid = 0  # sk.s_local.nl_pid is read-only in Python.

    assert b'EAAAAAAABQCjnNZUAAAAAA==' == base64.b64encode(buffer(nlh.bytearray[:nlh.nlmsg_len]))
示例#34
0
 def callback(_, msg_):
     nlh = nlmsg_hdr(msg_)
     assert 20 == nlh.nlmsg_len
     assert 16 == nlh.nlmsg_type
     assert 5 == nlh.nlmsg_flags
     ops = nl_cache_ops_associate_safe(NETLINK_GENERIC, nlh.nlmsg_type)
     assert 'genl/family' == ops.co_name
     assert 4 == ops.co_hdrsize
     assert 16 == ops.co_protocol
     assert 0 == ops.co_hash_size
     assert 0 == ops.co_flags
     assert 'genl/family' == ops.co_obj_ops.oo_name
     assert 80 == ops.co_obj_ops.oo_size
     assert 1 == ops.co_obj_ops.oo_id_attrs
     assert 0 == nlmsg_attrlen(nlh, ops.co_hdrsize)
     mt = nl_msgtype_lookup(ops, nlh.nlmsg_type)
     assert 16 == mt.mt_id
     assert 0 == mt.mt_act
     assert 'nlctrl' == mt.mt_name
     called.append(True)
     return NL_STOP
示例#35
0
def test_seq():
    """Test sequences."""
    msg = nlmsg_alloc()
    nlh = nlmsg_hdr(msg)
    assert 16 == nlh.nlmsg_len
    assert 0 == nlh.nlmsg_type
    assert 0 == nlh.nlmsg_flags
    assert 0 == nlh.nlmsg_seq
    assert 0 == nlh.nlmsg_pid

    sk = nl_socket_alloc()
    nl_connect(sk, NETLINK_ROUTE)
    sk.socket_instance.close()
    sk.s_local.nl_pid = 0
    nl_complete_msg(sk, msg)
    assert 1423351063 <= nlh.nlmsg_seq
    nlh.nlmsg_seq = 1423350947
    assert 1423350947 == nlh.nlmsg_seq
    nlh.nlmsg_pid = 0  # sk.s_local.nl_pid is read-only in Python.

    assert b'EAAAAAAABQCjnNZUAAAAAA==' == base64.b64encode(
        buffer(nlh.bytearray[:nlh.nlmsg_len]))
def callback(msg, _):
    """Callback function called by libnl upon receiving messages from the kernel.

    Positional arguments:
    msg -- nl_msg class instance containing the data sent by the kernel.

    Returns:
    An integer, value of NL_OK. It tells libnl to proceed with processing the next kernel message.
    """
    # First convert `msg` into something more manageable.
    nlh = nlmsg_hdr(msg)
    iface = ifinfomsg(nlmsg_data(nlh))
    hdr = IFLA_RTA(iface)
    remaining = ctypes.c_int(nlh.nlmsg_len - NLMSG_LENGTH(iface.SIZEOF))

    # Now iterate through each rtattr stored in `iface`.
    while RTA_OK(hdr, remaining):
        # Each rtattr (which is what hdr is) instance is only one type. Looping through all of them until we run into
        # the ones we care about.
        if hdr.rta_type == IFLA_IFNAME:
            print('Found network interface {0}: {1}'.format(iface.ifi_index, get_string(RTA_DATA(hdr)).decode('ascii')))
        hdr = RTA_NEXT(hdr, remaining)
    return NL_OK
示例#37
0
def test_two_attrs():
    """Test with two attributes."""
    msg = nlmsg_alloc()
    assert 0 == nla_put_u32(msg, 4, 8)
    nlh = nlmsg_hdr(msg)
    assert 24 == nlh.nlmsg_len
    assert 0 == nlh.nlmsg_type
    assert 0 == nlh.nlmsg_flags
    assert 0 == nlh.nlmsg_seq
    assert 0 == nlh.nlmsg_pid
    assert 0 == nla_put_u64(msg, 5, 17)
    assert 36 == nlh.nlmsg_len

    sk = nl_socket_alloc()
    nl_connect(sk, NETLINK_ROUTE)
    sk.socket_instance.close()
    sk.s_local.nl_pid = 0
    sk.s_seq_next = 0
    nl_complete_msg(sk, msg)
    assert 0 == nlh.nlmsg_seq
    nlh.nlmsg_pid = 0  # sk.s_local.nl_pid is read-only in Python.

    expected = b'JAAAAAAABQAAAAAAAAAAAAgABAAIAAAADAAFABEAAAAAAAAA'
    assert expected == base64.b64encode(buffer(nlh.bytearray[:nlh.nlmsg_len]))
示例#38
0
文件: ctrl.py 项目: 0x90/libnl
def probe_response(msg, arg):
    """Process responses from from the query sent by genl_ctrl_probe_by_name().

    https://github.com/thom311/libnl/blob/libnl3_2_25/lib/genl/ctrl.c#L203

    Process returned messages, filling out the missing information in the genl_family structure.

    Positional arguments:
    msg -- returned message (nl_msg class instance).
    arg -- genl_family class instance to fill out.

    Returns:
    Indicator to keep processing frames or not (NL_SKIP or NL_STOP).
    """
    tb = dict((i, None) for i in range(CTRL_ATTR_MAX + 1))
    nlh = nlmsg_hdr(msg)
    ret = arg
    if genlmsg_parse(nlh, 0, tb, CTRL_ATTR_MAX, ctrl_policy):
        return NL_SKIP
    if tb[CTRL_ATTR_FAMILY_ID]:
        genl_family_set_id(ret, nla_get_u16(tb[CTRL_ATTR_FAMILY_ID]))
    if tb[CTRL_ATTR_MCAST_GROUPS] and parse_mcast_grps(ret, tb[CTRL_ATTR_MCAST_GROUPS]) < 0:
        return NL_SKIP
    return NL_STOP
示例#39
0
def test_two_attrs():
    """Test with two attributes."""
    msg = nlmsg_alloc()
    assert 0 == nla_put_u32(msg, 4, 8)
    nlh = nlmsg_hdr(msg)
    assert 24 == nlh.nlmsg_len
    assert 0 == nlh.nlmsg_type
    assert 0 == nlh.nlmsg_flags
    assert 0 == nlh.nlmsg_seq
    assert 0 == nlh.nlmsg_pid
    assert 0 == nla_put_u64(msg, 5, 17)
    assert 36 == nlh.nlmsg_len

    sk = nl_socket_alloc()
    nl_connect(sk, NETLINK_ROUTE)
    sk.socket_instance.close()
    sk.s_local.nl_pid = 0
    sk.s_seq_next = 0
    nl_complete_msg(sk, msg)
    assert 0 == nlh.nlmsg_seq
    nlh.nlmsg_pid = 0  # sk.s_local.nl_pid is read-only in Python.

    expected = b'JAAAAAAABQAAAAAAAAAAAAgABAAIAAAADAAFABEAAAAAAAAA'
    assert expected == base64.b64encode(buffer(nlh.bytearray[:nlh.nlmsg_len]))
示例#40
0
文件: test_attr.py 项目: ewa/libnl
def test_socket(tcp_server):
    r"""C code to test against.

    // gcc a.c $(pkg-config --cflags --libs libnl-genl-3.0) && (nc -l 2000 |base64 &) && 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 nl_msg *msg = nlmsg_alloc();
        printf("%d == nla_put_u32()\n", nla_put_u32(msg, 4, 8));
        struct nlmsghdr *nlh = nlmsg_hdr(msg);
        struct nlattr *attr = nlmsg_find_attr(nlh, 0, 4);
        printf("%d == nla_type(attr)\n", nla_type(attr));
        printf("%d == nla_get_u32(attr)\n", nla_get_u32(attr));
        printf("%d == attr->nla_len\n", attr->nla_len);

        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();
        nl_connect(sk, NETLINK_ROUTE);
        sk->s_fd = fd;
        sk->s_local.nl_pid = 0;
        nl_complete_msg(sk, msg);

        struct iovec iov = { .iov_base = attr, .iov_len = attr->nla_len };
        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:
    // 0 == nla_put_u32()
    // 4 == nla_type(attr)
    // 8 == nla_get_u32(attr)
    // 8 == attr->nla_len
    // Bytes: 8
    // CAAEAAgAAAA=
    """
    msg = nlmsg_alloc()
    assert 0 == libnl.attr.nla_put_u32(msg, 4, 8)
    nlh = nlmsg_hdr(msg)
    attr = nlmsg_find_attr(nlh, 0, 4)
    assert 4 == libnl.attr.nla_type(attr)
    assert 8 == libnl.attr.nla_get_u32(attr)
    assert 8 == attr.nla_len

    sk = nl_socket_alloc()
    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)

    iov = attr.bytearray[: attr.nla_len]
    hdr = msghdr(msg_iov=iov)

    assert 8 == nl_sendmsg(sk, msg, hdr)
    assert 1 == len(tcp_server.data)
    assert b"CAAEAAgAAAA=" == base64.b64encode(buffer(iov))
    assert b"CAAEAAgAAAA=" == base64.b64encode(buffer(tcp_server.data[0]))
    nl_socket_free(sk)
示例#41
0
    def _iface_callback(self, msg, _):
        # Callback function called by libnl upon receiving messages from the
        # kernel.
        #
        # Positional arguments:
        # msg -- nl_msg class instance containing the data sent by the kernel.
        #
        # Returns:
        # An integer, value of NL_SKIP. It tells libnl to stop calling other
        # callbacks for this message and proceed with processing the next kernel
        # message.
        # First convert `msg` into something more manageable.
        gnlh = genlmsghdr(nlmsg_data(nlmsg_hdr(msg)))

        # Partially parse the raw binary data and place them in the `tb`
        # dictionary. Need to populate dict with all possible keys.
        tb = dict((i, None) for i in range(nl80211.NL80211_ATTR_MAX + 1))
        nla_parse(tb, nl80211.NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
                  genlmsg_attrlen(gnlh, 0), None)

        # Now it's time to grab the data, we start with the interface index as
        # universal identifier
        if tb[nl80211.NL80211_ATTR_IFINDEX]:
            if_index = nla_get_u32(tb[nl80211.NL80211_ATTR_IFINDEX])
        else:
            return NL_SKIP

        # Create new interface dict if this interface is not yet known
        if if_index in self.iface_data:
            iface_data = self.iface_data[if_index]
        else:
            iface_data = {}

        if tb[nl80211.NL80211_ATTR_IFNAME]:
            iface_data['name'] = nla_get_string(
                tb[nl80211.NL80211_ATTR_IFNAME]).decode('ascii')

        if tb[nl80211.NL80211_ATTR_IFTYPE]:
            iftype = nla_get_u32(tb[nl80211.NL80211_ATTR_IFTYPE])

            if iftype == nl80211.NL80211_IFTYPE_UNSPECIFIED:
                typestr = 'UNSPECIFIED'
            elif iftype == nl80211.NL80211_IFTYPE_ADHOC:
                typestr = 'ADHOC'
            elif iftype == nl80211.NL80211_IFTYPE_STATION:
                typestr = 'STATION'
            elif iftype == nl80211.NL80211_IFTYPE_AP:
                typestr = 'AP'
            elif iftype == nl80211.NL80211_IFTYPE_AP_VLAN:
                typestr = 'AP_VLAN'
            elif iftype == nl80211.NL80211_IFTYPE_WDS:
                typestr = 'WDS'
            elif iftype == nl80211.NL80211_IFTYPE_MONITOR:
                typestr = 'MONITOR'
            elif iftype == nl80211.NL80211_IFTYPE_MESH_POINT:
                typestr = 'MESH_POINT'
            elif iftype == nl80211.NL80211_IFTYPE_P2P_CLIENT:
                typestr = 'P2P_CLIENT'
            elif iftype == nl80211.NL80211_IFTYPE_P2P_GO:
                typestr = 'P2P_GO'
            elif iftype == nl80211.NL80211_IFTYPE_P2P_DEVICE:
                typestr = 'P2P_DEVICE'

            iface_data['type'] = typestr

        if tb[nl80211.NL80211_ATTR_WIPHY]:
            wiphy_num = nla_get_u32(tb[nl80211.NL80211_ATTR_WIPHY])
            iface_data['wiphy'] = 'phy#{0}'.format(wiphy_num)

        if tb[nl80211.NL80211_ATTR_MAC]:
            mac_raw = nla_data(tb[nl80211.NL80211_ATTR_MAC])[:6]
            mac_address = ':'.join(format(x, '02x') for x in mac_raw)
            iface_data['mac'] = mac_address
            if (gnlh.cmd == nl80211.NL80211_CMD_NEW_STATION
                    and if_index == self.if_idx):
                # This is the BSSID that we're currently associated to
                self.bssid = mac_address

        if tb[nl80211.NL80211_ATTR_GENERATION]:
            generation = nla_get_u32(tb[nl80211.NL80211_ATTR_GENERATION])
            # Do not overwrite the generation for excessively large values
            if generation < 100:
                iface_data['generation'] = generation

        if tb[nl80211.NL80211_ATTR_WIPHY_TX_POWER_LEVEL]:
            iface_data['tx_power'] = nla_get_u32(
                tb[nl80211.NL80211_ATTR_WIPHY_TX_POWER_LEVEL]) / 100  # mW

        if tb[nl80211.NL80211_ATTR_CHANNEL_WIDTH]:
            iface_data['ch_width'] = nla_get_u32(
                tb[nl80211.NL80211_ATTR_CHANNEL_WIDTH])

        if tb[nl80211.NL80211_ATTR_CENTER_FREQ1]:
            iface_data['frequency'] = nla_get_u32(
                tb[nl80211.NL80211_ATTR_CENTER_FREQ1])

        # Station infos
        if tb[nl80211.NL80211_ATTR_STA_INFO]:
            # Need to unpack the data
            sinfo = dict(
                (i, None) for i in range(nl80211.NL80211_STA_INFO_MAX))
            rinfo = dict(
                (i, None) for i in range(nl80211.NL80211_STA_INFO_TX_BITRATE))

            # Extract data
            nla_parse_nested(sinfo, nl80211.NL80211_STA_INFO_MAX,
                             tb[nl80211.NL80211_ATTR_STA_INFO], None)

            # Extract info about signal strength (= quality)
            if sinfo[nl80211.NL80211_STA_INFO_SIGNAL]:
                iface_data['signal'] = 100 + \
                    nla_get_u8(sinfo[nl80211.NL80211_STA_INFO_SIGNAL])
                # Compute quality (formula found in iwinfo_nl80211.c and largely
                # simplified)
                iface_data['quality'] = iface_data['signal'] + 110
                iface_data['quality_max'] = 70

            # Extract info about negotiated bitrate
            if sinfo[nl80211.NL80211_STA_INFO_TX_BITRATE]:
                nla_parse_nested(rinfo, nl80211.NL80211_RATE_INFO_MAX,
                                 sinfo[nl80211.NL80211_STA_INFO_TX_BITRATE],
                                 None)
                if rinfo[nl80211.NL80211_RATE_INFO_BITRATE]:
                    iface_data['bitrate'] = nla_get_u16(
                        rinfo[nl80211.NL80211_RATE_INFO_BITRATE]) / 10

        # BSS info
        if tb[nl80211.NL80211_ATTR_BSS]:
            # Need to unpack the data
            binfo = dict((i, None) for i in range(nl80211.NL80211_BSS_MAX))
            nla_parse_nested(binfo, nl80211.NL80211_BSS_MAX,
                             tb[nl80211.NL80211_ATTR_BSS], None)

            # Parse BSS section (if complete)
            try:
                bss = parse_bss(binfo)

                # Remove duplicated information blocks
                if 'beacon_ies' in bss:
                    del bss['beacon_ies']
                if 'information_elements' in bss:
                    del bss['information_elements']
                if 'supported_rates' in bss:
                    del bss['supported_rates']

                # Convert timedelta objects for later JSON encoding
                for prop in bss:
                    if isinstance(bss[prop], datetime.timedelta):
                        bss[prop] = int(bss[prop].microseconds) / 1000

                # Append BSS data to general object
                iface_data = {**iface_data, **bss}
            except Exception as e:
                logger.warning("Obtaining BSS data failed: {}".format(e))
                pass

        # Append data to global structure
        self.iface_data[if_index] = iface_data
        return NL_SKIP
示例#42
0
文件: handlers.py 项目: 0x90/libnl
def nl_finish_handler_debug(msg, arg):
    """https://github.com/thom311/libnl/blob/libnl3_2_25/lib/handlers.c#L103."""
    ofd = arg or _LOGGER.debug
    ofd('-- Debug: End of multipart message block: ' + print_header_content(nlmsg_hdr(msg)))
    return NL_STOP
示例#43
0
def nl_valid_handler_verbose(msg, arg):
    """https://github.com/thom311/libnl/blob/libnl3_2_25/lib/handlers.c#L45."""
    ofd = arg or _LOGGER.debug
    ofd('-- Warning: unhandled valid message: ' + print_header_content(nlmsg_hdr(msg)))
    return NL_OK
示例#44
0
def nl_invalid_handler_verbose(msg, arg):
    """https://github.com/thom311/libnl/blob/libnl3_2_25/lib/handlers.c#L56."""
    ofd = arg or _LOGGER.debug
    ofd('-- Error: Invalid message: ' + print_header_content(nlmsg_hdr(msg)))
    return NL_STOP
示例#45
0
def nl_valid_handler_debug(msg, arg):
    """https://github.com/thom311/libnl/blob/libnl3_2_25/lib/handlers.c#L92."""
    ofd = arg or _LOGGER.debug
    ofd('-- Debug: Unhandled Valid message: ' + print_header_content(nlmsg_hdr(msg)))
    return NL_OK
示例#46
0
def test_socket(tcp_server):
    r"""C code to test against.

    // gcc a.c $(pkg-config --cflags --libs libnl-genl-3.0) && (nc -l 2000 |base64 &) && 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 nl_msg *msg = nlmsg_alloc();
        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 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();
        nl_connect(sk, NETLINK_ROUTE);
        sk->s_fd = fd;
        sk->s_local.nl_pid = 0;
        sk->s_seq_next = 0;
        nl_complete_msg(sk, msg);
        printf("%d == nlh->nlmsg_seq\n", nlh->nlmsg_seq);

        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;
    }
    // Expected bash output:
    // 16 == nlh->nlmsg_len
    // 0 == nlh->nlmsg_type
    // 0 == nlh->nlmsg_flags
    // 0 == nlh->nlmsg_seq
    // 0 == nlh->nlmsg_pid
    // 0 == nlh->nlmsg_seq
    // Bytes: 16
    // EAAAAAAABQAAAAAAAAAAAA==
    """
    msg = nlmsg_alloc()
    nlh = nlmsg_hdr(msg)
    assert 16 == nlh.nlmsg_len
    assert 0 == nlh.nlmsg_type
    assert 0 == nlh.nlmsg_flags
    assert 0 == nlh.nlmsg_seq
    assert 0 == nlh.nlmsg_pid

    sk = nl_socket_alloc()
    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
    sk.s_seq_next = 0
    nl_complete_msg(sk, msg)
    assert 0 == nlh.nlmsg_seq
    nlh.nlmsg_pid = 0  # sk.s_local.nl_pid is read-only in Python.

    iov = nlh.bytearray[:nlh.nlmsg_len]
    hdr = msghdr(msg_iov=iov)

    assert 16 == nl_sendmsg(sk, msg, hdr)
    assert 1 == len(tcp_server.data)
    assert b'EAAAAAAABQAAAAAAAAAAAA==' == base64.b64encode(buffer(iov))
    assert b'EAAAAAAABQAAAAAAAAAAAA==' == base64.b64encode(buffer(tcp_server.data[0]))
    nl_socket_free(sk)
示例#47
0
文件: test_attr.py 项目: ewa/libnl
def test_nested():
    r"""C code to test against.

    // gcc a.c $(pkg-config --cflags --libs libnl-genl-3.0) && ./a.out
    #include <netlink/msg.h>
    int main() {
        int i, rem1, rem2;
        struct nlattr *nla;
        struct nl_msg *msg = nlmsg_alloc();
        struct nl_msg *sub = nlmsg_alloc();
        struct nlmsghdr *nlh = nlmsg_hdr(sub);
        unsigned char *buf = (unsigned char *) nlh;
        nla_put_string(sub, 0, "");
        nla_put_string(sub, 1, "Just tell me why!");
        nla_put_string(sub, 2, "Please read this 55-page warrant.");
        nla_put_string(sub, 3, "There must be robots worse than I!");
        nla_put_string(sub, 4, "We've checked around, there really aren't.");
        nlmsg_for_each_attr(nla, nlh, 0, rem1) {
            printf("type: %d len: %d; nla_get_string: %s\n", nla_type(nla), nla_len(nla), nla_get_string(nla));
        }
        for (i = 0; i < nlmsg_total_size(nlmsg_datalen(nlh)); i++) printf("%02x", buf[i]); printf("\n");
        nla_put_nested(msg, 5, sub);
        nlmsg_free(sub);

        sub = nlmsg_alloc();
        nlh = nlmsg_hdr(sub);
        buf = (unsigned char *) nlh;
        nla_put_string(sub, 6, "Aw, don't blame me,");
        nla_put_string(sub, 7, "Blame my upbringing!");
        nlmsg_for_each_attr(nla, nlh, 0, rem1) {
            printf("type: %d len: %d; nla_get_string: %s\n", nla_type(nla), nla_len(nla), nla_get_string(nla));
        }
        for (i = 0; i < nlmsg_total_size(nlmsg_datalen(nlh)); i++) printf("%02x", buf[i]); printf("\n");
        nla_put_nested(msg, 8, sub);
        nlmsg_free(sub);

        nlh = nlmsg_hdr(msg);
        buf = (unsigned char *) nlh;
        nla_put_u16(msg, 9, 666);
        for (i = 0; i < nlmsg_total_size(nlmsg_datalen(nlh)); i++) printf("%02x", buf[i]); printf("\n");

        struct nlattr *nla_outer;
        nlmsg_for_each_attr(nla_outer, nlh, 0, rem1) {
            if (nla_type(nla_outer) != 9) {
                printf("Outer type: %d len:%d\n", nla_type(nla_outer), nla_len(nla_outer));
                nla_for_each_nested(nla, nla_outer, rem2) {
                    printf("type: %d len: %d; nla_get_string: %s\n", nla_type(nla), nla_len(nla), nla_get_string(nla));
                }
            } else {
                printf("t: %d l:%d; get_u16: %d\n", nla_type(nla_outer), nla_len(nla_outer), nla_get_u16(nla_outer));
            }
        }

        nlmsg_free(msg);
        return 0;
    }
    // Expected output:
    // type: 0 len: 1; nla_get_string:
    // type: 1 len: 18; nla_get_string: Just tell me why!
    // type: 2 len: 34; nla_get_string: Please read this 55-page warrant.
    // type: 3 len: 35; nla_get_string: There must be robots worse than I!
    // type: 4 len: 43; nla_get_string: We've checked around, there really aren't.
    // b00000000000000000000000000000000500000000000000160001004a7573742074656c6c206d65207768792100000026000200506c65617
    365207265616420746869732035352d706167652077617272616e742e000000270003005468657265206d75737420626520726f626f747320776
    f727365207468616e20492100002f000400576527766520636865636b65642061726f756e642c207468657265207265616c6c79206172656e277
    42e0000
    // type: 6 len: 20; nla_get_string: Aw, don't blame me,
    // type: 7 len: 21; nla_get_string: Blame my upbringing!
    // 440000000000000000000000000000001800060041772c20646f6e277420626c616d65206d652c0019000700426c616d65206d79207570627
    2696e67696e672100000000
    // f4000000000000000000000000000000a40005000500000000000000160001004a7573742074656c6c206d652077687921000000260002005
    06c65617365207265616420746869732035352d706167652077617272616e742e000000270003005468657265206d75737420626520726f626f7
    47320776f727365207468616e20492100002f000400576527766520636865636b65642061726f756e642c207468657265207265616c6c7920617
    2656e27742e0000380008001800060041772c20646f6e277420626c616d65206d652c0019000700426c616d65206d792075706272696e67696e6
    72100000000060009009a020000
    // Outer type: 5 len:160
    // type: 0 len: 1; nla_get_string:
    // type: 1 len: 18; nla_get_string: Just tell me why!
    // type: 2 len: 34; nla_get_string: Please read this 55-page warrant.
    // type: 3 len: 35; nla_get_string: There must be robots worse than I!
    // type: 4 len: 43; nla_get_string: We've checked around, there really aren't.
    // Outer type: 8 len:52
    // type: 6 len: 20; nla_get_string: Aw, don't blame me,
    // type: 7 len: 21; nla_get_string: Blame my upbringing!
    // t: 9 l:2; get_u16: 666
    """
    rem1, rem2 = c_int(), c_int()
    msg = nlmsg_alloc()
    sub = nlmsg_alloc()
    nlh = nlmsg_hdr(sub)
    libnl.attr.nla_put_string(sub, 0, b"")
    libnl.attr.nla_put_string(sub, 1, b"Just tell me why!")
    libnl.attr.nla_put_string(sub, 2, b"Please read this 55-page warrant.")
    libnl.attr.nla_put_string(sub, 3, b"There must be robots worse than I!")
    libnl.attr.nla_put_string(sub, 4, b"We've checked around, there really aren't.")
    actual = list()
    for nla in nlmsg_for_each_attr(nlh, 0, rem1):
        actual.append((libnl.attr.nla_type(nla), libnl.attr.nla_len(nla), libnl.attr.nla_get_string(nla)))
    expected = [
        (0, 1, b""),
        (1, 18, b"Just tell me why!"),
        (2, 34, b"Please read this 55-page warrant."),
        (3, 35, b"There must be robots worse than I!"),
        (4, 43, b"We've checked around, there really aren't."),
    ]
    assert expected == actual
    expected = (
        "b00000000000000000000000000000000500000000000000160001004a7573742074656c6c206d652077687921000000260002"
        "00506c65617365207265616420746869732035352d706167652077617272616e742e000000270003005468657265206d757374"
        "20626520726f626f747320776f727365207468616e20492100002f000400576527766520636865636b65642061726f756e642c"
        "207468657265207265616c6c79206172656e27742e0000"
    )
    assert expected == "".join(format(c, "02x") for c in nlh.bytearray[: nlmsg_total_size(nlmsg_datalen(nlh))])
    libnl.attr.nla_put_nested(msg, 5, sub)

    sub = nlmsg_alloc()
    nlh = nlmsg_hdr(sub)
    libnl.attr.nla_put_string(sub, 6, b"Aw, don't blame me,")
    libnl.attr.nla_put_string(sub, 7, b"Blame my upbringing!")
    actual = list()
    for nla in nlmsg_for_each_attr(nlh, 0, rem1):
        actual.append((libnl.attr.nla_type(nla), libnl.attr.nla_len(nla), libnl.attr.nla_get_string(nla)))
    expected = [(6, 20, b"Aw, don't blame me,"), (7, 21, b"Blame my upbringing!")]
    assert expected == actual
    expected = (
        "440000000000000000000000000000001800060041772c20646f6e277420626c616d65206d652c0019000700426c616d65206d"
        "792075706272696e67696e672100000000"
    )
    assert expected == "".join(format(c, "02x") for c in nlh.bytearray[: nlmsg_total_size(nlmsg_datalen(nlh))])
    libnl.attr.nla_put_nested(msg, 8, sub)

    nlh = nlmsg_hdr(msg)
    libnl.attr.nla_put_u16(msg, 9, 666)
    expected = (
        "f4000000000000000000000000000000a40005000500000000000000160001004a7573742074656c6c206d6520776879210000"
        "0026000200506c65617365207265616420746869732035352d706167652077617272616e742e00000027000300546865726520"
        "6d75737420626520726f626f747320776f727365207468616e20492100002f000400576527766520636865636b65642061726f"
        "756e642c207468657265207265616c6c79206172656e27742e0000380008001800060041772c20646f6e277420626c616d6520"
        "6d652c0019000700426c616d65206d792075706272696e67696e672100000000060009009a020000"
    )
    assert expected == "".join(format(c, "02x") for c in nlh.bytearray[: nlmsg_total_size(nlmsg_datalen(nlh))])

    actual = list()
    for nla_outer in nlmsg_for_each_attr(nlh, 0, rem1):
        if libnl.attr.nla_type(nla_outer) != 9:
            actual.append((libnl.attr.nla_type(nla_outer), libnl.attr.nla_len(nla_outer), b"Outer"))
            for nla in libnl.attr.nla_for_each_nested(nla_outer, rem2):
                actual.append((libnl.attr.nla_type(nla), libnl.attr.nla_len(nla), libnl.attr.nla_get_string(nla)))
        else:
            actual.append(
                (libnl.attr.nla_type(nla_outer), libnl.attr.nla_len(nla_outer), libnl.attr.nla_get_u16(nla_outer))
            )
    expected = [
        (5, 160, b"Outer"),
        (0, 1, b""),
        (1, 18, b"Just tell me why!"),
        (2, 34, b"Please read this 55-page warrant."),
        (3, 35, b"There must be robots worse than I!"),
        (4, 43, b"We've checked around, there really aren't."),
        (8, 52, b"Outer"),
        (6, 20, b"Aw, don't blame me,"),
        (7, 21, b"Blame my upbringing!"),
        (9, 2, 666),
    ]
    assert expected == actual
示例#48
0
def nl_ack_handler_debug(msg, arg):
    """https://github.com/thom311/libnl/blob/libnl3_2_25/lib/handlers.c#L145."""
    ofd = arg or _LOGGER.debug
    ofd('-- Debug: ACK: ' + print_header_content(nlmsg_hdr(msg)))
    return NL_STOP
示例#49
0
def nl_overrun_handler_verbose(msg, arg):
    """https://github.com/thom311/libnl/blob/libnl3_2_25/lib/handlers.c#L67."""
    ofd = arg or _LOGGER.debug
    ofd('-- Error: Netlink Overrun: ' + print_header_content(nlmsg_hdr(msg)))
    return NL_STOP
示例#50
0
def test_socket(tcp_server):
    r"""C code to test against.

    // gcc a.c $(pkg-config --cflags --libs libnl-genl-3.0) && (nc -l 2000 |base64 &) && 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 nl_msg *msg = nlmsg_alloc();
        printf("%d == nla_put_u32()\n", nla_put_u32(msg, 4, 8));
        struct nlmsghdr *nlh = nlmsg_hdr(msg);
        struct nlattr *attr = nlmsg_find_attr(nlh, 0, 4);
        printf("%d == nla_type(attr)\n", nla_type(attr));
        printf("%d == nla_get_u32(attr)\n", nla_get_u32(attr));
        printf("%d == attr->nla_len\n", attr->nla_len);

        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();
        nl_connect(sk, NETLINK_ROUTE);
        sk->s_fd = fd;
        sk->s_local.nl_pid = 0;
        nl_complete_msg(sk, msg);

        struct iovec iov = { .iov_base = attr, .iov_len = attr->nla_len };
        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:
    // 0 == nla_put_u32()
    // 4 == nla_type(attr)
    // 8 == nla_get_u32(attr)
    // 8 == attr->nla_len
    // Bytes: 8
    // CAAEAAgAAAA=
    """
    msg = nlmsg_alloc()
    assert 0 == libnl.attr.nla_put_u32(msg, 4, 8)
    nlh = nlmsg_hdr(msg)
    attr = nlmsg_find_attr(nlh, 0, 4)
    assert 4 == libnl.attr.nla_type(attr)
    assert 8 == libnl.attr.nla_get_u32(attr)
    assert 8 == attr.nla_len

    sk = nl_socket_alloc()
    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)

    iov = attr.bytearray[:attr.nla_len]
    hdr = msghdr(msg_iov=iov)

    assert 8 == nl_sendmsg(sk, msg, hdr)
    assert 1 == len(tcp_server.data)
    assert b'CAAEAAgAAAA=' == base64.b64encode(buffer(iov))
    assert b'CAAEAAgAAAA=' == base64.b64encode(buffer(tcp_server.data[0]))
    nl_socket_free(sk)
示例#51
0
def test_nested():
    r"""C code to test against.

    // gcc a.c $(pkg-config --cflags --libs libnl-genl-3.0) && ./a.out
    #include <netlink/msg.h>
    int main() {
        int i, rem1, rem2;
        struct nlattr *nla;
        struct nl_msg *msg = nlmsg_alloc();
        struct nl_msg *sub = nlmsg_alloc();
        struct nlmsghdr *nlh = nlmsg_hdr(sub);
        unsigned char *buf = (unsigned char *) nlh;
        nla_put_string(sub, 0, "");
        nla_put_string(sub, 1, "Just tell me why!");
        nla_put_string(sub, 2, "Please read this 55-page warrant.");
        nla_put_string(sub, 3, "There must be robots worse than I!");
        nla_put_string(sub, 4, "We've checked around, there really aren't.");
        nlmsg_for_each_attr(nla, nlh, 0, rem1) {
            printf("type: %d len: %d; nla_get_string: %s\n", nla_type(nla), nla_len(nla), nla_get_string(nla));
        }
        for (i = 0; i < nlmsg_total_size(nlmsg_datalen(nlh)); i++) printf("%02x", buf[i]); printf("\n");
        nla_put_nested(msg, 5, sub);
        nlmsg_free(sub);

        sub = nlmsg_alloc();
        nlh = nlmsg_hdr(sub);
        buf = (unsigned char *) nlh;
        nla_put_string(sub, 6, "Aw, don't blame me,");
        nla_put_string(sub, 7, "Blame my upbringing!");
        nlmsg_for_each_attr(nla, nlh, 0, rem1) {
            printf("type: %d len: %d; nla_get_string: %s\n", nla_type(nla), nla_len(nla), nla_get_string(nla));
        }
        for (i = 0; i < nlmsg_total_size(nlmsg_datalen(nlh)); i++) printf("%02x", buf[i]); printf("\n");
        nla_put_nested(msg, 8, sub);
        nlmsg_free(sub);

        nlh = nlmsg_hdr(msg);
        buf = (unsigned char *) nlh;
        nla_put_u16(msg, 9, 666);
        for (i = 0; i < nlmsg_total_size(nlmsg_datalen(nlh)); i++) printf("%02x", buf[i]); printf("\n");

        struct nlattr *nla_outer;
        nlmsg_for_each_attr(nla_outer, nlh, 0, rem1) {
            if (nla_type(nla_outer) != 9) {
                printf("Outer type: %d len:%d\n", nla_type(nla_outer), nla_len(nla_outer));
                nla_for_each_nested(nla, nla_outer, rem2) {
                    printf("type: %d len: %d; nla_get_string: %s\n", nla_type(nla), nla_len(nla), nla_get_string(nla));
                }
            } else {
                printf("t: %d l:%d; get_u16: %d\n", nla_type(nla_outer), nla_len(nla_outer), nla_get_u16(nla_outer));
            }
        }

        nlmsg_free(msg);
        return 0;
    }
    // Expected output:
    // type: 0 len: 1; nla_get_string:
    // type: 1 len: 18; nla_get_string: Just tell me why!
    // type: 2 len: 34; nla_get_string: Please read this 55-page warrant.
    // type: 3 len: 35; nla_get_string: There must be robots worse than I!
    // type: 4 len: 43; nla_get_string: We've checked around, there really aren't.
    // b00000000000000000000000000000000500000000000000160001004a7573742074656c6c206d65207768792100000026000200506c65617
    365207265616420746869732035352d706167652077617272616e742e000000270003005468657265206d75737420626520726f626f747320776
    f727365207468616e20492100002f000400576527766520636865636b65642061726f756e642c207468657265207265616c6c79206172656e277
    42e0000
    // type: 6 len: 20; nla_get_string: Aw, don't blame me,
    // type: 7 len: 21; nla_get_string: Blame my upbringing!
    // 440000000000000000000000000000001800060041772c20646f6e277420626c616d65206d652c0019000700426c616d65206d79207570627
    2696e67696e672100000000
    // f4000000000000000000000000000000a40005000500000000000000160001004a7573742074656c6c206d652077687921000000260002005
    06c65617365207265616420746869732035352d706167652077617272616e742e000000270003005468657265206d75737420626520726f626f7
    47320776f727365207468616e20492100002f000400576527766520636865636b65642061726f756e642c207468657265207265616c6c7920617
    2656e27742e0000380008001800060041772c20646f6e277420626c616d65206d652c0019000700426c616d65206d792075706272696e67696e6
    72100000000060009009a020000
    // Outer type: 5 len:160
    // type: 0 len: 1; nla_get_string:
    // type: 1 len: 18; nla_get_string: Just tell me why!
    // type: 2 len: 34; nla_get_string: Please read this 55-page warrant.
    // type: 3 len: 35; nla_get_string: There must be robots worse than I!
    // type: 4 len: 43; nla_get_string: We've checked around, there really aren't.
    // Outer type: 8 len:52
    // type: 6 len: 20; nla_get_string: Aw, don't blame me,
    // type: 7 len: 21; nla_get_string: Blame my upbringing!
    // t: 9 l:2; get_u16: 666
    """
    rem1, rem2 = c_int(), c_int()
    msg = nlmsg_alloc()
    sub = nlmsg_alloc()
    nlh = nlmsg_hdr(sub)
    libnl.attr.nla_put_string(sub, 0, b'')
    libnl.attr.nla_put_string(sub, 1, b'Just tell me why!')
    libnl.attr.nla_put_string(sub, 2, b'Please read this 55-page warrant.')
    libnl.attr.nla_put_string(sub, 3, b'There must be robots worse than I!')
    libnl.attr.nla_put_string(sub, 4,
                              b"We've checked around, there really aren't.")
    actual = list()
    for nla in nlmsg_for_each_attr(nlh, 0, rem1):
        actual.append((libnl.attr.nla_type(nla), libnl.attr.nla_len(nla),
                       libnl.attr.nla_get_string(nla)))
    expected = [
        (0, 1, b''),
        (1, 18, b'Just tell me why!'),
        (2, 34, b'Please read this 55-page warrant.'),
        (3, 35, b'There must be robots worse than I!'),
        (4, 43, b"We've checked around, there really aren't."),
    ]
    assert expected == actual
    expected = (
        'b00000000000000000000000000000000500000000000000160001004a7573742074656c6c206d652077687921000000260002'
        '00506c65617365207265616420746869732035352d706167652077617272616e742e000000270003005468657265206d757374'
        '20626520726f626f747320776f727365207468616e20492100002f000400576527766520636865636b65642061726f756e642c'
        '207468657265207265616c6c79206172656e27742e0000')
    assert expected == ''.join(
        format(c, '02x')
        for c in nlh.bytearray[:nlmsg_total_size(nlmsg_datalen(nlh))])
    libnl.attr.nla_put_nested(msg, 5, sub)

    sub = nlmsg_alloc()
    nlh = nlmsg_hdr(sub)
    libnl.attr.nla_put_string(sub, 6, b"Aw, don't blame me,")
    libnl.attr.nla_put_string(sub, 7, b'Blame my upbringing!')
    actual = list()
    for nla in nlmsg_for_each_attr(nlh, 0, rem1):
        actual.append((libnl.attr.nla_type(nla), libnl.attr.nla_len(nla),
                       libnl.attr.nla_get_string(nla)))
    expected = [
        (6, 20, b"Aw, don't blame me,"),
        (7, 21, b'Blame my upbringing!'),
    ]
    assert expected == actual
    expected = (
        '440000000000000000000000000000001800060041772c20646f6e277420626c616d65206d652c0019000700426c616d65206d'
        '792075706272696e67696e672100000000')
    assert expected == ''.join(
        format(c, '02x')
        for c in nlh.bytearray[:nlmsg_total_size(nlmsg_datalen(nlh))])
    libnl.attr.nla_put_nested(msg, 8, sub)

    nlh = nlmsg_hdr(msg)
    libnl.attr.nla_put_u16(msg, 9, 666)
    expected = (
        'f4000000000000000000000000000000a40005000500000000000000160001004a7573742074656c6c206d6520776879210000'
        '0026000200506c65617365207265616420746869732035352d706167652077617272616e742e00000027000300546865726520'
        '6d75737420626520726f626f747320776f727365207468616e20492100002f000400576527766520636865636b65642061726f'
        '756e642c207468657265207265616c6c79206172656e27742e0000380008001800060041772c20646f6e277420626c616d6520'
        '6d652c0019000700426c616d65206d792075706272696e67696e672100000000060009009a020000'
    )
    assert expected == ''.join(
        format(c, '02x')
        for c in nlh.bytearray[:nlmsg_total_size(nlmsg_datalen(nlh))])

    actual = list()
    for nla_outer in nlmsg_for_each_attr(nlh, 0, rem1):
        if libnl.attr.nla_type(nla_outer) != 9:
            actual.append((libnl.attr.nla_type(nla_outer),
                           libnl.attr.nla_len(nla_outer), b'Outer'))
            for nla in libnl.attr.nla_for_each_nested(nla_outer, rem2):
                actual.append(
                    (libnl.attr.nla_type(nla), libnl.attr.nla_len(nla),
                     libnl.attr.nla_get_string(nla)))
        else:
            actual.append(
                (libnl.attr.nla_type(nla_outer), libnl.attr.nla_len(nla_outer),
                 libnl.attr.nla_get_u16(nla_outer)))
    expected = [
        (5, 160, b'Outer'),
        (0, 1, b''),
        (1, 18, b'Just tell me why!'),
        (2, 34, b'Please read this 55-page warrant.'),
        (3, 35, b'There must be robots worse than I!'),
        (4, 43, b"We've checked around, there really aren't."),
        (8, 52, b'Outer'),
        (6, 20, b"Aw, don't blame me,"),
        (7, 21, b'Blame my upbringing!'),
        (9, 2, 666),
    ]
    assert expected == actual
示例#52
0
def nl_skipped_handler_debug(msg, arg):
    """https://github.com/thom311/libnl/blob/libnl3_2_25/lib/handlers.c#L134."""
    ofd = arg or _LOGGER.debug
    ofd('-- Debug: Skipped message: ' + print_header_content(nlmsg_hdr(msg)))
    return NL_SKIP