Beispiel #1
0
def test_repr():
    """Test repr() of instances."""
    assert 'c_byte(123)' == repr(c_byte(123))
    if sys.maxsize > 2 ** 32:  # 64-bit.
        assert 'c_int(1234567890)' == repr(c_int(1234567890))
    else:
        assert 'c_long(1234567890)' == repr(c_int(1234567890)).replace('L)', ')')
    assert 'c_byte(123)' == repr(c_int8(123))
    assert 'c_long(1234567890)' == repr(c_long(1234567890)).replace('L)', ')')
    if sys.maxsize > 2 ** 32:  # 64-bit.
        assert 'c_long(1234567890123456789)' == repr(c_longlong(1234567890123456789)).replace('L)', ')')
    else:
        assert 'c_longlong(1234567890123456789)' == repr(c_longlong(1234567890123456789)).replace('L)', ')')
    assert 'c_ushort(12345)' == repr(c_uint16(12345))
    if sys.maxsize > 2 ** 32:  # 64-bit.
        assert 'c_uint(1234567890)' == repr(c_uint32(1234567890)).replace('L)', ')')
    else:
        assert 'c_ulong(1234567890)' == repr(c_uint32(1234567890)).replace('L)', ')')
    if sys.maxsize > 2 ** 32:  # 64-bit.
        assert 'c_ulong(12345678901234567890)' == repr(c_uint64(12345678901234567890)).replace('L)', ')')
    else:
        assert 'c_ulonglong(12345678901234567890)' == repr(c_uint64(12345678901234567890)).replace('L)', ')')
    assert 'c_ubyte(123)' == repr(c_uint8(123))
    assert 'c_ubyte(123)' == repr(c_ubyte(123))
    if sys.maxsize > 2 ** 32:  # 64-bit.
        assert 'c_uint(1234567890)' == repr(c_uint(1234567890)).replace('L)', ')')
    else:
        assert 'c_ulong(1234567890)' == repr(c_uint(1234567890)).replace('L)', ')')
    assert 'c_ulong(1234567890)' == repr(c_ulong(1234567890)).replace('L)', ')')
    if sys.maxsize > 2 ** 32:  # 64-bit.
        assert 'c_ulong(12345678901234567890)' == repr(c_ulonglong(12345678901234567890)).replace('L)', ')')
    else:
        assert 'c_ulonglong(12345678901234567890)' == repr(c_ulonglong(12345678901234567890)).replace('L)', ')')
    assert 'c_ushort(12345)' == repr(c_ushort(12345))
Beispiel #2
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
Beispiel #3
0
def test_maximum():
    """Test maximum valid integer value."""
    assert 127 == c_byte.from_buffer(bytearray(c_byte(127))).value
    assert 2147483647 == c_int.from_buffer(bytearray(c_int(2147483647))).value
    assert 127 == c_int8.from_buffer(bytearray(c_int8(127))).value
    if sys.maxsize > 2**32:  # 64-bit.
        assert 9223372036854775807 == c_long.from_buffer(
            bytearray(c_long(9223372036854775807))).value
    else:
        assert 2147483647 == c_long.from_buffer(bytearray(
            c_long(2147483647))).value
    assert 9223372036854775807 == c_longlong.from_buffer(
        bytearray(c_longlong(9223372036854775807))).value
    assert 65535 == c_uint16.from_buffer(bytearray(c_uint16(65535))).value
    assert 4294967295 == c_uint32.from_buffer(bytearray(
        c_uint32(4294967295))).value
    assert 18446744073709551615 == c_uint64.from_buffer(
        bytearray(c_uint64(18446744073709551615))).value
    assert 255 == c_uint8.from_buffer(bytearray(c_uint8(255))).value
    assert 255 == c_ubyte.from_buffer(bytearray(c_ubyte(255))).value
    assert 4294967295 == c_uint.from_buffer(bytearray(
        c_uint(4294967295))).value
    if sys.maxsize > 2**32:  # 64-bit.
        assert 18446744073709551615 == c_ulong.from_buffer(
            bytearray(c_ulong(18446744073709551615))).value
    else:
        assert 4294967295 == c_ulong.from_buffer(bytearray(
            c_ulong(4294967295))).value
    assert 18446744073709551615 == c_ulonglong.from_buffer(
        bytearray(c_ulonglong(18446744073709551615))).value
    assert 65535 == c_ushort.from_buffer(bytearray(c_ushort(65535))).value
Beispiel #4
0
Datei: msg.py Projekt: 0x90/libnl
def dump_attrs(ofd, attrs, attrlen, prefix=0):
    """https://github.com/thom311/libnl/blob/libnl3_2_25/lib/msg.c#L869.

    Positional arguments:
    ofd -- function to call with arguments similar to `logging.debug`.
    attrs -- nlattr class instance.
    attrlen -- length of payload (integer).

    Keyword arguments:
    prefix -- additional number of whitespace pairs to prefix each log statement with.
    """
    prefix_whitespaces = '  ' * prefix
    rem = c_int()
    for nla in nla_for_each_attr(attrs, attrlen, rem):
        alen = nla_len(nla)
        if nla.nla_type == 0:
            ofd('%s  [ATTR PADDING] %d octets', prefix_whitespaces, alen)
        else:
            is_nested = ' NESTED' if nla_is_nested(nla) else ''
            ofd('%s  [ATTR %02d%s] %d octets', prefix_whitespaces, nla.nla_type, is_nested, alen)

        if nla_is_nested(nla):
            dump_attrs(ofd, nla_data(nla), alen, prefix + 1)
        else:
            dump_attr(ofd, nla, prefix)

        padlen = nla_padlen(alen)
        if padlen > 0:
            ofd('%s  [PADDING] %d octets', prefix_whitespaces, padlen)
            dump_hex(ofd, bytearray_ptr(nla_data(nla), alen), padlen, prefix)

    if rem.value:
        ofd('%s  [LEFTOVER] %d octets', prefix_whitespaces, rem)
Beispiel #5
0
def parse_mcast_grps(family, grp_attr):
    """https://github.com/thom311/libnl/blob/libnl3_2_25/lib/genl/ctrl.c#L64.

    Positional arguments:
    family -- genl_family class instance.
    grp_attr -- nlattr class instance.

    Returns:
    0 on success or a negative error code.
    """
    remaining = c_int()
    if not grp_attr:
        raise BUG

    for nla in nla_for_each_nested(grp_attr, remaining):
        tb = dict()
        err = nla_parse_nested(tb, CTRL_ATTR_MCAST_GRP_MAX, nla, family_grp_policy)
        if err < 0:
            return err
        if not tb[CTRL_ATTR_MCAST_GRP_ID] or not tb[CTRL_ATTR_MCAST_GRP_NAME]:
            return -NLE_MISSING_ATTR

        id_ = nla_get_u32(tb[CTRL_ATTR_MCAST_GRP_ID])
        name = nla_get_string(tb[CTRL_ATTR_MCAST_GRP_NAME])

        err = genl_family_add_grp(family, id_, name)
        if err < 0:
            return err

    return 0
Beispiel #6
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
Beispiel #7
0
def parse_mcast_grps(family, grp_attr):
    """https://github.com/thom311/libnl/blob/libnl3_2_25/lib/genl/ctrl.c#L64.

    Positional arguments:
    family -- genl_family class instance.
    grp_attr -- nlattr class instance.

    Returns:
    0 on success or a negative error code.
    """
    remaining = c_int()
    if not grp_attr:
        raise BUG

    for nla in nla_for_each_nested(grp_attr, remaining):
        tb = dict()
        err = nla_parse_nested(tb, CTRL_ATTR_MCAST_GRP_MAX, nla,
                               family_grp_policy)
        if err < 0:
            return err
        if not tb[CTRL_ATTR_MCAST_GRP_ID] or not tb[CTRL_ATTR_MCAST_GRP_NAME]:
            return -NLE_MISSING_ATTR

        id_ = nla_get_u32(tb[CTRL_ATTR_MCAST_GRP_ID])
        name = nla_get_string(tb[CTRL_ATTR_MCAST_GRP_NAME])

        err = genl_family_add_grp(family, id_, name)
        if err < 0:
            return err

    return 0
Beispiel #8
0
def test_repr():
    """Test repr() of instances."""
    assert 'c_byte(123)' == repr(c_byte(123))
    if sys.maxsize > 2**32:  # 64-bit.
        assert 'c_int(1234567890)' == repr(c_int(1234567890))
    else:
        assert 'c_long(1234567890)' == repr(c_int(1234567890)).replace(
            'L)', ')')
    assert 'c_byte(123)' == repr(c_int8(123))
    assert 'c_long(1234567890)' == repr(c_long(1234567890)).replace('L)', ')')
    if sys.maxsize > 2**32:  # 64-bit.
        assert 'c_long(1234567890123456789)' == repr(
            c_longlong(1234567890123456789)).replace('L)', ')')
    else:
        assert 'c_longlong(1234567890123456789)' == repr(
            c_longlong(1234567890123456789)).replace('L)', ')')
    assert 'c_ushort(12345)' == repr(c_uint16(12345))
    if sys.maxsize > 2**32:  # 64-bit.
        assert 'c_uint(1234567890)' == repr(c_uint32(1234567890)).replace(
            'L)', ')')
    else:
        assert 'c_ulong(1234567890)' == repr(c_uint32(1234567890)).replace(
            'L)', ')')
    if sys.maxsize > 2**32:  # 64-bit.
        assert 'c_ulong(12345678901234567890)' == repr(
            c_uint64(12345678901234567890)).replace('L)', ')')
    else:
        assert 'c_ulonglong(12345678901234567890)' == repr(
            c_uint64(12345678901234567890)).replace('L)', ')')
    assert 'c_ubyte(123)' == repr(c_uint8(123))
    assert 'c_ubyte(123)' == repr(c_ubyte(123))
    if sys.maxsize > 2**32:  # 64-bit.
        assert 'c_uint(1234567890)' == repr(c_uint(1234567890)).replace(
            'L)', ')')
    else:
        assert 'c_ulong(1234567890)' == repr(c_uint(1234567890)).replace(
            'L)', ')')
    assert 'c_ulong(1234567890)' == repr(c_ulong(1234567890)).replace(
        'L)', ')')
    if sys.maxsize > 2**32:  # 64-bit.
        assert 'c_ulong(12345678901234567890)' == repr(
            c_ulonglong(12345678901234567890)).replace('L)', ')')
    else:
        assert 'c_ulonglong(12345678901234567890)' == repr(
            c_ulonglong(12345678901234567890)).replace('L)', ')')
    assert 'c_ushort(12345)' == repr(c_ushort(12345))
Beispiel #9
0
def test_minimum():
    """Test minimum valid integer value."""
    assert -128 == c_byte.from_buffer(bytearray(c_byte(-128))).value
    assert -2147483648 == c_int.from_buffer(bytearray(c_int(-2147483648))).value
    assert -128 == c_int8.from_buffer(bytearray(c_int8(-128))).value
    if sys.maxsize > 2 ** 32:  # 64-bit.
        assert -9223372036854775808 == c_long.from_buffer(bytearray(c_long(-9223372036854775808))).value
    else:
        assert -2147483648 == c_long.from_buffer(bytearray(c_long(-2147483648))).value
    assert -9223372036854775808 == c_longlong.from_buffer(bytearray(c_longlong(-9223372036854775808))).value
Beispiel #10
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
Beispiel #11
0
def test_minimum():
    """Test minimum valid integer value."""
    assert -128 == c_byte.from_buffer(bytearray(c_byte(-128))).value
    assert -2147483648 == c_int.from_buffer(bytearray(
        c_int(-2147483648))).value
    assert -128 == c_int8.from_buffer(bytearray(c_int8(-128))).value
    if sys.maxsize > 2**32:  # 64-bit.
        assert -9223372036854775808 == c_long.from_buffer(
            bytearray(c_long(-9223372036854775808))).value
    else:
        assert -2147483648 == c_long.from_buffer(bytearray(
            c_long(-2147483648))).value
    assert -9223372036854775808 == c_longlong.from_buffer(
        bytearray(c_longlong(-9223372036854775808))).value
Beispiel #12
0
def test_zero():
    """Test zero integer value."""
    assert 0 == c_byte.from_buffer(bytearray(c_byte())).value
    assert 0 == c_int.from_buffer(bytearray(c_int())).value
    assert 0 == c_int8.from_buffer(bytearray(c_int8())).value
    assert 0 == c_long.from_buffer(bytearray(c_long())).value
    assert 0 == c_longlong.from_buffer(bytearray(c_longlong())).value
    assert 0 == c_uint16.from_buffer(bytearray(c_uint16())).value
    assert 0 == c_uint32.from_buffer(bytearray(c_uint32())).value
    assert 0 == c_uint64.from_buffer(bytearray(c_uint64())).value
    assert 0 == c_uint8.from_buffer(bytearray(c_uint8())).value
    assert 0 == c_ubyte.from_buffer(bytearray(c_ubyte())).value
    assert 0 == c_uint.from_buffer(bytearray(c_uint())).value
    assert 0 == c_ulong.from_buffer(bytearray(c_ulong())).value
    assert 0 == c_ulonglong.from_buffer(bytearray(c_ulonglong())).value
    assert 0 == c_ushort.from_buffer(bytearray(c_ushort())).value
Beispiel #13
0
def test_middle():
    """Test with arbitrary positive value."""
    assert 123 == c_byte.from_buffer(bytearray(c_byte(123))).value
    assert 1234567890 == c_int.from_buffer(bytearray(c_int(1234567890))).value
    assert 123 == c_int8.from_buffer(bytearray(c_int8(123))).value
    assert 1234567890 == c_long.from_buffer(bytearray(c_long(1234567890))).value
    assert 1234567890123456789 == c_longlong.from_buffer(bytearray(c_longlong(1234567890123456789))).value
    assert 12345 == c_uint16.from_buffer(bytearray(c_uint16(12345))).value
    assert 1234567890 == c_uint32.from_buffer(bytearray(c_uint32(1234567890))).value
    assert 12345678901234567890 == c_uint64.from_buffer(bytearray(c_uint64(12345678901234567890))).value
    assert 123 == c_uint8.from_buffer(bytearray(c_uint8(123))).value
    assert 123 == c_ubyte.from_buffer(bytearray(c_ubyte(123))).value
    assert 1234567890 == c_uint.from_buffer(bytearray(c_uint(1234567890))).value
    assert 1234567890 == c_ulong.from_buffer(bytearray(c_ulong(1234567890))).value
    assert 12345678901234567890 == c_ulonglong.from_buffer(bytearray(c_ulonglong(12345678901234567890))).value
    assert 12345 == c_ushort.from_buffer(bytearray(c_ushort(12345))).value
Beispiel #14
0
def test_zero():
    """Test zero integer value."""
    assert 0 == c_byte.from_buffer(bytearray(c_byte())).value
    assert 0 == c_int.from_buffer(bytearray(c_int())).value
    assert 0 == c_int8.from_buffer(bytearray(c_int8())).value
    assert 0 == c_long.from_buffer(bytearray(c_long())).value
    assert 0 == c_longlong.from_buffer(bytearray(c_longlong())).value
    assert 0 == c_uint16.from_buffer(bytearray(c_uint16())).value
    assert 0 == c_uint32.from_buffer(bytearray(c_uint32())).value
    assert 0 == c_uint64.from_buffer(bytearray(c_uint64())).value
    assert 0 == c_uint8.from_buffer(bytearray(c_uint8())).value
    assert 0 == c_ubyte.from_buffer(bytearray(c_ubyte())).value
    assert 0 == c_uint.from_buffer(bytearray(c_uint())).value
    assert 0 == c_ulong.from_buffer(bytearray(c_ulong())).value
    assert 0 == c_ulonglong.from_buffer(bytearray(c_ulonglong())).value
    assert 0 == c_ushort.from_buffer(bytearray(c_ushort())).value
Beispiel #15
0
def nla_parse(tb, maxtype, head, len_, policy):
    """Create attribute index based on a stream of attributes.

    https://github.com/thom311/libnl/blob/libnl3_2_25/lib/attr.c#L242

    Iterates over the stream of attributes and stores a pointer to each attribute in the index array using the attribute
    type as index to the array. Attribute with a type greater than the maximum type specified will be silently ignored
    in order to maintain backwards compatibility. If `policy` is not None, the attribute will be validated using the
    specified policy.

    Positional arguments:
    tb -- dictionary to be filled (maxtype+1 elements).
    maxtype -- maximum attribute type expected and accepted (integer).
    head -- first nlattr with more in its bytearray payload (nlattr class instance).
    len_ -- length of attribute stream (integer).
    policy -- dictionary of nla_policy class instances as values, with nla types as keys.

    Returns:
    0 on success or a negative error code.
    """
    rem = c_int()
    for nla in nla_for_each_attr(head, len_, rem):
        type_ = nla_type(nla)
        if type_ > maxtype:
            continue

        if policy:
            err = validate_nla(nla, maxtype, policy)
            if err < 0:
                return err

        if type_ in tb and tb[type_]:
            _LOGGER.debug(
                'Attribute of type %d found multiple times in message, previous attribute is being ignored.',
                type_)
        tb[type_] = nla

    if rem.value > 0:
        _LOGGER.debug('netlink: %d bytes leftover after parsing attributes.',
                      rem.value)

    return 0
Beispiel #16
0
def nla_find(head, len_, attrtype):
    """Find a single attribute in a stream of attributes.

    https://github.com/thom311/libnl/blob/libnl3_2_25/lib/attr.c#L323

    Iterates over the stream of attributes and compares each type with the type specified. Returns the first attribute
    which matches the type.

    Positional arguments:
    head -- first nlattr with more in its bytearray payload (nlattr class instance).
    len_ -- length of attributes stream (integer).
    attrtype -- attribute type to look for (integer).

    Returns:
    Attribute found (nlattr class instance) or None.
    """
    rem = c_int()
    for nla in nla_for_each_attr(head, len_, rem):
        if nla_type(nla) == attrtype:
            return nla
    return None
Beispiel #17
0
def nla_find(head, len_, attrtype):
    """Find a single attribute in a stream of attributes.

    https://github.com/thom311/libnl/blob/libnl3_2_25/lib/attr.c#L323

    Iterates over the stream of attributes and compares each type with the type specified. Returns the first attribute
    which matches the type.

    Positional arguments:
    head -- first nlattr with more in its bytearray payload (nlattr class instance).
    len_ -- length of attributes stream (integer).
    attrtype -- attribute type to look for (integer).

    Returns:
    Attribute found (nlattr class instance) or None.
    """
    rem = c_int()
    for nla in nla_for_each_attr(head, len_, rem):
        if nla_type(nla) == attrtype:
            return nla
    return None
Beispiel #18
0
def nla_parse(tb, maxtype, head, len_, policy):
    """Create attribute index based on a stream of attributes.

    https://github.com/thom311/libnl/blob/libnl3_2_25/lib/attr.c#L242

    Iterates over the stream of attributes and stores a pointer to each attribute in the index array using the attribute
    type as index to the array. Attribute with a type greater than the maximum type specified will be silently ignored
    in order to maintain backwards compatibility. If `policy` is not None, the attribute will be validated using the
    specified policy.

    Positional arguments:
    tb -- dictionary to be filled (maxtype+1 elements).
    maxtype -- maximum attribute type expected and accepted (integer).
    head -- first nlattr with more in its bytearray payload (nlattr class instance).
    len_ -- length of attribute stream (integer).
    policy -- dictionary of nla_policy class instances as values, with nla types as keys.

    Returns:
    0 on success or a negative error code.
    """
    rem = c_int()
    for nla in nla_for_each_attr(head, len_, rem):
        type_ = nla_type(nla)
        if type_ > maxtype:
            continue

        if policy:
            err = validate_nla(nla, maxtype, policy)
            if err < 0:
                return err

        if type_ in tb and tb[type_]:
            _LOGGER.debug('Attribute of type %d found multiple times in message, previous attribute is being ignored.',
                          type_)
        tb[type_] = nla

    if rem.value > 0:
        _LOGGER.debug('netlink: %d bytes leftover after parsing attributes.', rem.value)

    return 0
Beispiel #19
0
def test_maximum_overflow():
    """Test positive overflow value."""
    assert -128 == c_byte(128).value
    assert -2147483648 == c_int(2147483648).value
    assert -128 == c_int8(128).value
    if sys.maxsize > 2 ** 32:  # 64-bit.
        assert -9223372036854775808 == c_long(9223372036854775808).value
    else:
        assert -2147483648 == c_long(2147483648).value
    assert -9223372036854775808 == c_longlong(9223372036854775808).value
    assert 0 == c_uint16(65536).value
    assert 0 == c_uint32(4294967296).value
    assert 0 == c_uint64(18446744073709551616).value
    assert 0 == c_uint8(256).value
    assert 0 == c_ubyte(256).value
    assert 0 == c_uint(4294967296).value
    if sys.maxsize > 2 ** 32:  # 64-bit.
        assert 0 == c_ulong(18446744073709551616).value
    else:
        assert 0 == c_ulong(4294967296).value
    assert 0 == c_ulonglong(18446744073709551616).value
    assert 0 == c_ushort(65536).value
Beispiel #20
0
def test_minimum_overflow_more():
    """Test negative overflow value with even lower numbers."""
    assert 27 == c_byte(-229).value
    assert 2147383647 == c_int(-2147583649).value
    assert 117 == c_int8(-139).value
    if sys.maxsize > 2 ** 32:  # 64-bit.
        assert 9223372036814775807 == c_long(-9223372036894775809).value
    else:
        assert 2147483647 == c_long(-2147483649).value
    assert 9223372033854775807 == c_longlong(-9223372039854775809).value
    assert 65524 == c_uint16(-12).value
    assert 4294967283 == c_uint32(-13).value
    assert 18446744073709551602 == c_uint64(-14).value
    assert 241 == c_uint8(-15).value
    assert 240 == c_ubyte(-16).value
    assert 4294967279 == c_uint(-17).value
    if sys.maxsize > 2 ** 32:  # 64-bit.
        assert 18446744073709551598 == c_ulong(-18).value
    else:
        assert 4294967277 == c_ulong(-19).value
    assert 18446744073709551598 == c_ulonglong(-18).value
    assert 65515 == c_ushort(-21).value
Beispiel #21
0
def test_maximum():
    """Test maximum valid integer value."""
    assert 127 == c_byte.from_buffer(bytearray(c_byte(127))).value
    assert 2147483647 == c_int.from_buffer(bytearray(c_int(2147483647))).value
    assert 127 == c_int8.from_buffer(bytearray(c_int8(127))).value
    if sys.maxsize > 2 ** 32:  # 64-bit.
        assert 9223372036854775807 == c_long.from_buffer(bytearray(c_long(9223372036854775807))).value
    else:
        assert 2147483647 == c_long.from_buffer(bytearray(c_long(2147483647))).value
    assert 9223372036854775807 == c_longlong.from_buffer(bytearray(c_longlong(9223372036854775807))).value
    assert 65535 == c_uint16.from_buffer(bytearray(c_uint16(65535))).value
    assert 4294967295 == c_uint32.from_buffer(bytearray(c_uint32(4294967295))).value
    assert 18446744073709551615 == c_uint64.from_buffer(bytearray(c_uint64(18446744073709551615))).value
    assert 255 == c_uint8.from_buffer(bytearray(c_uint8(255))).value
    assert 255 == c_ubyte.from_buffer(bytearray(c_ubyte(255))).value
    assert 4294967295 == c_uint.from_buffer(bytearray(c_uint(4294967295))).value
    if sys.maxsize > 2 ** 32:  # 64-bit.
        assert 18446744073709551615 == c_ulong.from_buffer(bytearray(c_ulong(18446744073709551615))).value
    else:
        assert 4294967295 == c_ulong.from_buffer(bytearray(c_ulong(4294967295))).value
    assert 18446744073709551615 == c_ulonglong.from_buffer(bytearray(c_ulonglong(18446744073709551615))).value
    assert 65535 == c_ushort.from_buffer(bytearray(c_ushort(65535))).value
Beispiel #22
0
def test_maximum_overflow_more():
    """Test positive overflow value with even greater numbers."""
    assert -118 == c_byte(138).value
    assert -2147482548 == c_int(2147484748).value
    assert -118 == c_int8(138).value
    if sys.maxsize > 2 ** 32:  # 64-bit.
        assert -9223372036854775708 == c_long(9223372036854775908).value
    else:
        assert -2147483548 == c_long(2147483748).value
    assert -9223372036854775708 == c_longlong(9223372036854775908).value
    assert 100 == c_uint16(65636).value
    assert 100 == c_uint32(4294967396).value
    assert 100 == c_uint64(18446744073709551716).value
    assert 100 == c_uint8(356).value
    assert 90 == c_ubyte(346).value
    assert 100 == c_uint(4294967396).value
    if sys.maxsize > 2 ** 32:  # 64-bit.
        assert 200 == c_ulong(18446744073709551816).value
    else:
        assert 1000 == c_ulong(4294968296).value
    assert 200 == c_ulonglong(18446744073709551816).value
    assert 10 == c_ushort(65546).value
Beispiel #23
0
def test_maximum_overflow():
    """Test positive overflow value."""
    assert -128 == c_byte(128).value
    assert -2147483648 == c_int(2147483648).value
    assert -128 == c_int8(128).value
    if sys.maxsize > 2**32:  # 64-bit.
        assert -9223372036854775808 == c_long(9223372036854775808).value
    else:
        assert -2147483648 == c_long(2147483648).value
    assert -9223372036854775808 == c_longlong(9223372036854775808).value
    assert 0 == c_uint16(65536).value
    assert 0 == c_uint32(4294967296).value
    assert 0 == c_uint64(18446744073709551616).value
    assert 0 == c_uint8(256).value
    assert 0 == c_ubyte(256).value
    assert 0 == c_uint(4294967296).value
    if sys.maxsize > 2**32:  # 64-bit.
        assert 0 == c_ulong(18446744073709551616).value
    else:
        assert 0 == c_ulong(4294967296).value
    assert 0 == c_ulonglong(18446744073709551616).value
    assert 0 == c_ushort(65536).value
Beispiel #24
0
def test_maximum_overflow_more():
    """Test positive overflow value with even greater numbers."""
    assert -118 == c_byte(138).value
    assert -2147482548 == c_int(2147484748).value
    assert -118 == c_int8(138).value
    if sys.maxsize > 2**32:  # 64-bit.
        assert -9223372036854775708 == c_long(9223372036854775908).value
    else:
        assert -2147483548 == c_long(2147483748).value
    assert -9223372036854775708 == c_longlong(9223372036854775908).value
    assert 100 == c_uint16(65636).value
    assert 100 == c_uint32(4294967396).value
    assert 100 == c_uint64(18446744073709551716).value
    assert 100 == c_uint8(356).value
    assert 90 == c_ubyte(346).value
    assert 100 == c_uint(4294967396).value
    if sys.maxsize > 2**32:  # 64-bit.
        assert 200 == c_ulong(18446744073709551816).value
    else:
        assert 1000 == c_ulong(4294968296).value
    assert 200 == c_ulonglong(18446744073709551816).value
    assert 10 == c_ushort(65546).value
Beispiel #25
0
def test_minimum_overflow():
    """Test negative overflow value."""
    assert 127 == c_byte(-129).value
    assert 2147483647 == c_int(-2147483649).value
    assert 127 == c_int8(-129).value
    if sys.maxsize > 2**32:  # 64-bit.
        assert 9223372036854775807 == c_long(-9223372036854775809).value
    else:
        assert 2147483647 == c_long(-2147483649).value
    assert 9223372036854775807 == c_longlong(-9223372036854775809).value
    assert 65535 == c_uint16(-1).value
    assert 4294967295 == c_uint32(-1).value
    assert 18446744073709551615 == c_uint64(-1).value
    assert 255 == c_uint8(-1).value
    assert 255 == c_ubyte(-1).value
    assert 4294967295 == c_uint(-1).value
    if sys.maxsize > 2**32:  # 64-bit.
        assert 18446744073709551615 == c_ulong(-1).value
    else:
        assert 4294967295 == c_ulong(-1).value
    assert 18446744073709551615 == c_ulonglong(-1).value
    assert 65535 == c_ushort(-1).value
Beispiel #26
0
def test_minimum_overflow_more():
    """Test negative overflow value with even lower numbers."""
    assert 27 == c_byte(-229).value
    assert 2147383647 == c_int(-2147583649).value
    assert 117 == c_int8(-139).value
    if sys.maxsize > 2**32:  # 64-bit.
        assert 9223372036814775807 == c_long(-9223372036894775809).value
    else:
        assert 2147483647 == c_long(-2147483649).value
    assert 9223372033854775807 == c_longlong(-9223372039854775809).value
    assert 65524 == c_uint16(-12).value
    assert 4294967283 == c_uint32(-13).value
    assert 18446744073709551602 == c_uint64(-14).value
    assert 241 == c_uint8(-15).value
    assert 240 == c_ubyte(-16).value
    assert 4294967279 == c_uint(-17).value
    if sys.maxsize > 2**32:  # 64-bit.
        assert 18446744073709551598 == c_ulong(-18).value
    else:
        assert 4294967277 == c_ulong(-19).value
    assert 18446744073709551598 == c_ulonglong(-18).value
    assert 65515 == c_ushort(-21).value
Beispiel #27
0
def test_minimum_overflow():
    """Test negative overflow value."""
    assert 127 == c_byte(-129).value
    assert 2147483647 == c_int(-2147483649).value
    assert 127 == c_int8(-129).value
    if sys.maxsize > 2 ** 32:  # 64-bit.
        assert 9223372036854775807 == c_long(-9223372036854775809).value
    else:
        assert 2147483647 == c_long(-2147483649).value
    assert 9223372036854775807 == c_longlong(-9223372036854775809).value
    assert 65535 == c_uint16(-1).value
    assert 4294967295 == c_uint32(-1).value
    assert 18446744073709551615 == c_uint64(-1).value
    assert 255 == c_uint8(-1).value
    assert 255 == c_ubyte(-1).value
    assert 4294967295 == c_uint(-1).value
    if sys.maxsize > 2 ** 32:  # 64-bit.
        assert 18446744073709551615 == c_ulong(-1).value
    else:
        assert 4294967295 == c_ulong(-1).value
    assert 18446744073709551615 == c_ulonglong(-1).value
    assert 65535 == c_ushort(-1).value
Beispiel #28
0
def test_middle():
    """Test with arbitrary positive value."""
    assert 123 == c_byte.from_buffer(bytearray(c_byte(123))).value
    assert 1234567890 == c_int.from_buffer(bytearray(c_int(1234567890))).value
    assert 123 == c_int8.from_buffer(bytearray(c_int8(123))).value
    assert 1234567890 == c_long.from_buffer(bytearray(
        c_long(1234567890))).value
    assert 1234567890123456789 == c_longlong.from_buffer(
        bytearray(c_longlong(1234567890123456789))).value
    assert 12345 == c_uint16.from_buffer(bytearray(c_uint16(12345))).value
    assert 1234567890 == c_uint32.from_buffer(bytearray(
        c_uint32(1234567890))).value
    assert 12345678901234567890 == c_uint64.from_buffer(
        bytearray(c_uint64(12345678901234567890))).value
    assert 123 == c_uint8.from_buffer(bytearray(c_uint8(123))).value
    assert 123 == c_ubyte.from_buffer(bytearray(c_ubyte(123))).value
    assert 1234567890 == c_uint.from_buffer(bytearray(
        c_uint(1234567890))).value
    assert 1234567890 == c_ulong.from_buffer(bytearray(
        c_ulong(1234567890))).value
    assert 12345678901234567890 == c_ulonglong.from_buffer(
        bytearray(c_ulonglong(12345678901234567890))).value
    assert 12345 == c_ushort.from_buffer(bytearray(c_ushort(12345))).value
Beispiel #29
0
Datei: msg.py Projekt: 0x90/libnl
def print_msg(msg, ofd, hdr):
    """https://github.com/thom311/libnl/blob/libnl3_2_25/lib/msg.c#L929.

    Positional arguments:
    msg -- Netlink message (nl_msg class instance).
    ofd -- function to call with arguments similar to `logging.debug`.
    hdr -- Netlink message header (nlmsghdr class instance).
    """
    payloadlen = c_int(nlmsg_len(hdr))
    attrlen = 0
    data = nlmsg_data(hdr)
    ops = nl_cache_ops_associate_safe(msg.nm_protocol, hdr.nlmsg_type)
    if ops:
        attrlen = nlmsg_attrlen(hdr, ops.co_hdrsize)
        payloadlen.value -= attrlen
    if msg.nm_protocol == libnl.linux_private.netlink.NETLINK_GENERIC:
        data = print_genl_msg(msg, ofd, hdr, ops, payloadlen)
    if payloadlen.value:
        ofd('  [PAYLOAD] %d octets', payloadlen.value)
        dump_hex(ofd, data, payloadlen.value, 0)
    if attrlen:
        attrs = nlmsg_attrdata(hdr, ops.co_hdrsize)
        attrlen = nlmsg_attrlen(hdr, ops.co_hdrsize)
        dump_attrs(ofd, attrs, attrlen, 0)
Beispiel #30
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
Beispiel #31
0
Datei: nl.py Projekt: 0x90/libnl
def recvmsgs(sk, cb):
    """https://github.com/thom311/libnl/blob/libnl3_2_25/lib/nl.c#L775.

    This is where callbacks are called.

    Positional arguments:
    sk -- Netlink socket (nl_sock class instance).
    cb -- callbacks (nl_cb class instance).

    Returns:
    Number of bytes received or a negative error code.
    """
    multipart = 0
    interrupted = 0
    nrecv = 0
    buf = bytearray()

    # nla is passed on to not only to nl_recv() but may also be passed to a function pointer provided by the caller
    # which may or may not initialize the variable. Thomas Graf.
    nla = sockaddr_nl()
    creds = ucred()

    while True:  # This is the `goto continue_reading` implementation.
        _LOGGER.debug('Attempting to read from 0x%x', id(sk))
        n = c_int(cb.cb_recv_ow(sk, nla, buf, creds) if cb.cb_recv_ow else nl_recv(sk, nla, buf, creds))
        if n.value <= 0:
            return n.value

        _LOGGER.debug('recvmsgs(0x%x): Read %d bytes', id(sk), n.value)

        hdr = nlmsghdr(bytearray_ptr(buf))
        while nlmsg_ok(hdr, n):
            _LOGGER.debug('recvmsgs(0x%x): Processing valid message...', id(sk))
            msg = nlmsg_convert(hdr)
            nlmsg_set_proto(msg, sk.s_proto)
            nlmsg_set_src(msg, nla)
            if creds:
                raise NotImplementedError  # nlmsg_set_creds(msg, creds)
            nrecv += 1

            # Raw callback is the first, it gives the most control to the user and he can do his very own parsing.
            if cb.cb_set[NL_CB_MSG_IN]:
                err = nl_cb_call(cb, NL_CB_MSG_IN, msg)  # NL_CB_CALL(cb, NL_CB_MSG_IN, msg)
                if err == NL_OK:
                    pass
                elif err == NL_SKIP:
                    hdr = nlmsg_next(hdr, n)
                    continue
                elif err == NL_STOP:
                    return -NLE_DUMP_INTR if interrupted else nrecv
                else:
                    return -NLE_DUMP_INTR if interrupted else (err or nrecv)

            if cb.cb_set[NL_CB_SEQ_CHECK]:
                # Sequence number checking. The check may be done by the user, otherwise a very simple check is applied
                # enforcing strict ordering.
                err = nl_cb_call(cb, NL_CB_SEQ_CHECK, msg)  # NL_CB_CALL(cb, NL_CB_SEQ_CHECK, msg)
                if err == NL_OK:
                    pass
                elif err == NL_SKIP:
                    hdr = nlmsg_next(hdr, n)
                    continue
                elif err == NL_STOP:
                    return -NLE_DUMP_INTR if interrupted else nrecv
                else:
                    return -NLE_DUMP_INTR if interrupted else (err or nrecv)
            elif not sk.s_flags & NL_NO_AUTO_ACK:
                # Only do sequence checking if auto-ack mode is enabled.
                if hdr.nlmsg_seq != sk.s_seq_expect:
                    if cb.cb_set[NL_CB_INVALID]:
                        err = nl_cb_call(cb, NL_CB_INVALID, msg)  # NL_CB_CALL(cb, NL_CB_INVALID, msg)
                        if err == NL_OK:
                            pass
                        elif err == NL_SKIP:
                            hdr = nlmsg_next(hdr, n)
                            continue
                        elif err == NL_STOP:
                            return -NLE_DUMP_INTR if interrupted else nrecv
                        else:
                            return -NLE_DUMP_INTR if interrupted else (err or nrecv)
                    else:
                        return -NLE_SEQ_MISMATCH

            if hdr.nlmsg_type in (NLMSG_DONE, NLMSG_ERROR, NLMSG_NOOP, NLMSG_OVERRUN):
                # We can't check for !NLM_F_MULTI since some Netlink users in the kernel are broken.
                sk.s_seq_expect += 1
                _LOGGER.debug('recvmsgs(0x%x): Increased expected sequence number to %d', id(sk), sk.s_seq_expect)

            if hdr.nlmsg_flags & NLM_F_MULTI:
                multipart = 1

            if hdr.nlmsg_flags & NLM_F_DUMP_INTR:
                if cb.cb_set[NL_CB_DUMP_INTR]:
                    err = nl_cb_call(cb, NL_CB_DUMP_INTR, msg)  # NL_CB_CALL(cb, NL_CB_DUMP_INTR, msg)
                    if err == NL_OK:
                        pass
                    elif err == NL_SKIP:
                        hdr = nlmsg_next(hdr, n)
                        continue
                    elif err == NL_STOP:
                        return -NLE_DUMP_INTR if interrupted else nrecv
                    else:
                        return -NLE_DUMP_INTR if interrupted else (err or nrecv)
                else:
                    # We have to continue reading to clear all messages until a NLMSG_DONE is received and report the
                    # inconsistency.
                    interrupted = 1

            if hdr.nlmsg_flags & NLM_F_ACK:
                # Other side wishes to see an ack for this message.
                if cb.cb_set[NL_CB_SEND_ACK]:
                    err = nl_cb_call(cb, NL_CB_SEND_ACK, msg)  # NL_CB_CALL(cb, NL_CB_SEND_ACK, msg)
                    if err == NL_OK:
                        pass
                    elif err == NL_SKIP:
                        hdr = nlmsg_next(hdr, n)
                        continue
                    elif err == NL_STOP:
                        return -NLE_DUMP_INTR if interrupted else nrecv
                    else:
                        return -NLE_DUMP_INTR if interrupted else (err or nrecv)

            if hdr.nlmsg_type == NLMSG_DONE:
                # Messages terminates a multipart message, this is usually the end of a message and therefore we slip
                # out of the loop by default. the user may overrule this action by skipping this packet.
                multipart = 0
                if cb.cb_set[NL_CB_FINISH]:
                    err = nl_cb_call(cb, NL_CB_FINISH, msg)  # NL_CB_CALL(cb, NL_CB_FINISH, msg)
                    if err == NL_OK:
                        pass
                    elif err == NL_SKIP:
                        hdr = nlmsg_next(hdr, n)
                        continue
                    elif err == NL_STOP:
                        return -NLE_DUMP_INTR if interrupted else nrecv
                    else:
                        return -NLE_DUMP_INTR if interrupted else (err or nrecv)
            elif hdr.nlmsg_type == NLMSG_NOOP:
                # Message to be ignored, the default action is to skip this message if no callback is specified. The
                # user may overrule this action by returning NL_PROCEED.
                if cb.cb_set[NL_CB_SKIPPED]:
                    err = nl_cb_call(cb, NL_CB_SKIPPED, msg)  # NL_CB_CALL(cb, NL_CB_SKIPPED, msg)
                    if err == NL_OK:
                        pass
                    elif err == NL_SKIP:
                        hdr = nlmsg_next(hdr, n)
                        continue
                    elif err == NL_STOP:
                        return -NLE_DUMP_INTR if interrupted else nrecv
                    else:
                        return -NLE_DUMP_INTR if interrupted else (err or nrecv)
                else:
                    hdr = nlmsg_next(hdr, n)
                    continue
            elif hdr.nlmsg_type == NLMSG_OVERRUN:
                # Data got lost, report back to user. The default action is to quit parsing. The user may overrule this
                # action by retuning NL_SKIP or NL_PROCEED (dangerous).
                if cb.cb_set[NL_CB_OVERRUN]:
                    err = nl_cb_call(cb, NL_CB_OVERRUN, msg)  # NL_CB_CALL(cb, NL_CB_OVERRUN, msg)
                    if err == NL_OK:
                        pass
                    elif err == NL_SKIP:
                        hdr = nlmsg_next(hdr, n)
                        continue
                    elif err == NL_STOP:
                        return -NLE_DUMP_INTR if interrupted else nrecv
                    else:
                        return -NLE_DUMP_INTR if interrupted else (err or nrecv)
                else:
                    return -NLE_DUMP_INTR if interrupted else -NLE_MSG_OVERFLOW
            elif hdr.nlmsg_type == NLMSG_ERROR:
                # Message carries a nlmsgerr.
                e = nlmsgerr(nlmsg_data(hdr))
                if hdr.nlmsg_len < nlmsg_size(e.SIZEOF):
                    # Truncated error message, the default action is to stop parsing. The user may overrule this action
                    # by returning NL_SKIP or NL_PROCEED (dangerous).
                    if cb.cb_set[NL_CB_INVALID]:
                        err = nl_cb_call(cb, NL_CB_INVALID, msg)  # NL_CB_CALL(cb, NL_CB_INVALID, msg)
                        if err == NL_OK:
                            pass
                        elif err == NL_SKIP:
                            hdr = nlmsg_next(hdr, n)
                            continue
                        elif err == NL_STOP:
                            return -NLE_DUMP_INTR if interrupted else nrecv
                        else:
                            return -NLE_DUMP_INTR if interrupted else (err or nrecv)
                    else:
                        return -NLE_DUMP_INTR if interrupted else -NLE_MSG_TRUNC
                elif e.error:
                    # Error message reported back from kernel.
                    if cb.cb_err:
                        err = cb.cb_err(nla, e, cb.cb_err_arg)
                        if err < 0:
                            return -NLE_DUMP_INTR if interrupted else err
                        elif err == NL_SKIP:
                            hdr = nlmsg_next(hdr, n)
                            continue
                        elif err == NL_STOP:
                            return -NLE_DUMP_INTR if interrupted else -nl_syserr2nlerr(e.error)
                    else:
                        return -NLE_DUMP_INTR if interrupted else -nl_syserr2nlerr(e.error)
                elif cb.cb_set[NL_CB_ACK]:
                    err = nl_cb_call(cb, NL_CB_ACK, msg)  # NL_CB_CALL(cb, NL_CB_ACK, msg)
                    if err == NL_OK:
                        pass
                    elif err == NL_SKIP:
                        hdr = nlmsg_next(hdr, n)
                        continue
                    elif err == NL_STOP:
                        return -NLE_DUMP_INTR if interrupted else nrecv
                    else:
                        return -NLE_DUMP_INTR if interrupted else (err or nrecv)
            else:
                # Valid message (not checking for MULTIPART bit to get along with broken kernels. NL_SKIP has no effect
                # on this.
                if cb.cb_set[NL_CB_VALID]:
                    err = nl_cb_call(cb, NL_CB_VALID, msg)  # NL_CB_CALL(cb, NL_CB_VALID, msg)
                    if err == NL_OK:
                        pass
                    elif err == NL_SKIP:
                        hdr = nlmsg_next(hdr, n)
                        continue
                    elif err == NL_STOP:
                        return -NLE_DUMP_INTR if interrupted else nrecv
                    else:
                        return -NLE_DUMP_INTR if interrupted else (err or nrecv)

            hdr = nlmsg_next(hdr, n)

        del buf[:]
        creds = None

        if multipart:
            # Multipart message not yet complete, continue reading.
            continue

        err = 0
        if interrupted:
            return -NLE_DUMP_INTR
        if not err:
            err = nrecv
        return err
Beispiel #32
0
def recvmsgs(sk, cb):
    """https://github.com/thom311/libnl/blob/libnl3_2_25/lib/nl.c#L775.

    This is where callbacks are called.

    Positional arguments:
    sk -- Netlink socket (nl_sock class instance).
    cb -- callbacks (nl_cb class instance).

    Returns:
    Number of bytes received or a negative error code.
    """
    multipart = 0
    interrupted = 0
    nrecv = 0
    buf = bytearray()

    # nla is passed on to not only to nl_recv() but may also be passed to a function pointer provided by the caller
    # which may or may not initialize the variable. Thomas Graf.
    nla = sockaddr_nl()
    creds = ucred()

    while True:  # This is the `goto continue_reading` implementation.
        _LOGGER.debug('Attempting to read from 0x%x', id(sk))
        n = c_int(
            cb.cb_recv_ow(sk, nla, buf, creds) if cb.
            cb_recv_ow else nl_recv(sk, nla, buf, creds))
        if n.value <= 0:
            return n.value

        _LOGGER.debug('recvmsgs(0x%x): Read %d bytes', id(sk), n.value)

        hdr = nlmsghdr(bytearray_ptr(buf))
        while nlmsg_ok(hdr, n):
            _LOGGER.debug('recvmsgs(0x%x): Processing valid message...',
                          id(sk))
            msg = nlmsg_convert(hdr)
            nlmsg_set_proto(msg, sk.s_proto)
            nlmsg_set_src(msg, nla)
            if creds:
                raise NotImplementedError  # nlmsg_set_creds(msg, creds)
            nrecv += 1

            # Raw callback is the first, it gives the most control to the user and he can do his very own parsing.
            if cb.cb_set[NL_CB_MSG_IN]:
                err = nl_cb_call(cb, NL_CB_MSG_IN,
                                 msg)  # NL_CB_CALL(cb, NL_CB_MSG_IN, msg)
                if err == NL_OK:
                    pass
                elif err == NL_SKIP:
                    hdr = nlmsg_next(hdr, n)
                    continue
                elif err == NL_STOP:
                    return -NLE_DUMP_INTR if interrupted else nrecv
                else:
                    return -NLE_DUMP_INTR if interrupted else (err or nrecv)

            if cb.cb_set[NL_CB_SEQ_CHECK]:
                # Sequence number checking. The check may be done by the user, otherwise a very simple check is applied
                # enforcing strict ordering.
                err = nl_cb_call(cb, NL_CB_SEQ_CHECK,
                                 msg)  # NL_CB_CALL(cb, NL_CB_SEQ_CHECK, msg)
                if err == NL_OK:
                    pass
                elif err == NL_SKIP:
                    hdr = nlmsg_next(hdr, n)
                    continue
                elif err == NL_STOP:
                    return -NLE_DUMP_INTR if interrupted else nrecv
                else:
                    return -NLE_DUMP_INTR if interrupted else (err or nrecv)
            elif not sk.s_flags & NL_NO_AUTO_ACK:
                # Only do sequence checking if auto-ack mode is enabled.
                if hdr.nlmsg_seq != sk.s_seq_expect:
                    if cb.cb_set[NL_CB_INVALID]:
                        err = nl_cb_call(
                            cb, NL_CB_INVALID,
                            msg)  # NL_CB_CALL(cb, NL_CB_INVALID, msg)
                        if err == NL_OK:
                            pass
                        elif err == NL_SKIP:
                            hdr = nlmsg_next(hdr, n)
                            continue
                        elif err == NL_STOP:
                            return -NLE_DUMP_INTR if interrupted else nrecv
                        else:
                            return -NLE_DUMP_INTR if interrupted else (
                                err or nrecv)
                    else:
                        return -NLE_SEQ_MISMATCH

            if hdr.nlmsg_type in (NLMSG_DONE, NLMSG_ERROR, NLMSG_NOOP,
                                  NLMSG_OVERRUN):
                # We can't check for !NLM_F_MULTI since some Netlink users in the kernel are broken.
                sk.s_seq_expect += 1
                _LOGGER.debug(
                    'recvmsgs(0x%x): Increased expected sequence number to %d',
                    id(sk), sk.s_seq_expect)

            if hdr.nlmsg_flags & NLM_F_MULTI:
                multipart = 1

            if hdr.nlmsg_flags & NLM_F_DUMP_INTR:
                if cb.cb_set[NL_CB_DUMP_INTR]:
                    err = nl_cb_call(
                        cb, NL_CB_DUMP_INTR,
                        msg)  # NL_CB_CALL(cb, NL_CB_DUMP_INTR, msg)
                    if err == NL_OK:
                        pass
                    elif err == NL_SKIP:
                        hdr = nlmsg_next(hdr, n)
                        continue
                    elif err == NL_STOP:
                        return -NLE_DUMP_INTR if interrupted else nrecv
                    else:
                        return -NLE_DUMP_INTR if interrupted else (err
                                                                   or nrecv)
                else:
                    # We have to continue reading to clear all messages until a NLMSG_DONE is received and report the
                    # inconsistency.
                    interrupted = 1

            if hdr.nlmsg_flags & NLM_F_ACK:
                # Other side wishes to see an ack for this message.
                if cb.cb_set[NL_CB_SEND_ACK]:
                    err = nl_cb_call(
                        cb, NL_CB_SEND_ACK,
                        msg)  # NL_CB_CALL(cb, NL_CB_SEND_ACK, msg)
                    if err == NL_OK:
                        pass
                    elif err == NL_SKIP:
                        hdr = nlmsg_next(hdr, n)
                        continue
                    elif err == NL_STOP:
                        return -NLE_DUMP_INTR if interrupted else nrecv
                    else:
                        return -NLE_DUMP_INTR if interrupted else (err
                                                                   or nrecv)

            if hdr.nlmsg_type == NLMSG_DONE:
                # Messages terminates a multipart message, this is usually the end of a message and therefore we slip
                # out of the loop by default. the user may overrule this action by skipping this packet.
                multipart = 0
                if cb.cb_set[NL_CB_FINISH]:
                    err = nl_cb_call(cb, NL_CB_FINISH,
                                     msg)  # NL_CB_CALL(cb, NL_CB_FINISH, msg)
                    if err == NL_OK:
                        pass
                    elif err == NL_SKIP:
                        hdr = nlmsg_next(hdr, n)
                        continue
                    elif err == NL_STOP:
                        return -NLE_DUMP_INTR if interrupted else nrecv
                    else:
                        return -NLE_DUMP_INTR if interrupted else (err
                                                                   or nrecv)
            elif hdr.nlmsg_type == NLMSG_NOOP:
                # Message to be ignored, the default action is to skip this message if no callback is specified. The
                # user may overrule this action by returning NL_PROCEED.
                if cb.cb_set[NL_CB_SKIPPED]:
                    err = nl_cb_call(cb, NL_CB_SKIPPED,
                                     msg)  # NL_CB_CALL(cb, NL_CB_SKIPPED, msg)
                    if err == NL_OK:
                        pass
                    elif err == NL_SKIP:
                        hdr = nlmsg_next(hdr, n)
                        continue
                    elif err == NL_STOP:
                        return -NLE_DUMP_INTR if interrupted else nrecv
                    else:
                        return -NLE_DUMP_INTR if interrupted else (err
                                                                   or nrecv)
                else:
                    hdr = nlmsg_next(hdr, n)
                    continue
            elif hdr.nlmsg_type == NLMSG_OVERRUN:
                # Data got lost, report back to user. The default action is to quit parsing. The user may overrule this
                # action by retuning NL_SKIP or NL_PROCEED (dangerous).
                if cb.cb_set[NL_CB_OVERRUN]:
                    err = nl_cb_call(cb, NL_CB_OVERRUN,
                                     msg)  # NL_CB_CALL(cb, NL_CB_OVERRUN, msg)
                    if err == NL_OK:
                        pass
                    elif err == NL_SKIP:
                        hdr = nlmsg_next(hdr, n)
                        continue
                    elif err == NL_STOP:
                        return -NLE_DUMP_INTR if interrupted else nrecv
                    else:
                        return -NLE_DUMP_INTR if interrupted else (err
                                                                   or nrecv)
                else:
                    return -NLE_DUMP_INTR if interrupted else -NLE_MSG_OVERFLOW
            elif hdr.nlmsg_type == NLMSG_ERROR:
                # Message carries a nlmsgerr.
                e = nlmsgerr(nlmsg_data(hdr))
                if hdr.nlmsg_len < nlmsg_size(e.SIZEOF):
                    # Truncated error message, the default action is to stop parsing. The user may overrule this action
                    # by returning NL_SKIP or NL_PROCEED (dangerous).
                    if cb.cb_set[NL_CB_INVALID]:
                        err = nl_cb_call(
                            cb, NL_CB_INVALID,
                            msg)  # NL_CB_CALL(cb, NL_CB_INVALID, msg)
                        if err == NL_OK:
                            pass
                        elif err == NL_SKIP:
                            hdr = nlmsg_next(hdr, n)
                            continue
                        elif err == NL_STOP:
                            return -NLE_DUMP_INTR if interrupted else nrecv
                        else:
                            return -NLE_DUMP_INTR if interrupted else (
                                err or nrecv)
                    else:
                        return -NLE_DUMP_INTR if interrupted else -NLE_MSG_TRUNC
                elif e.error:
                    # Error message reported back from kernel.
                    if cb.cb_err:
                        err = cb.cb_err(nla, e, cb.cb_err_arg)
                        if err < 0:
                            return -NLE_DUMP_INTR if interrupted else err
                        elif err == NL_SKIP:
                            hdr = nlmsg_next(hdr, n)
                            continue
                        elif err == NL_STOP:
                            return -NLE_DUMP_INTR if interrupted else -nl_syserr2nlerr(
                                e.error)
                    else:
                        return -NLE_DUMP_INTR if interrupted else -nl_syserr2nlerr(
                            e.error)
                elif cb.cb_set[NL_CB_ACK]:
                    err = nl_cb_call(cb, NL_CB_ACK,
                                     msg)  # NL_CB_CALL(cb, NL_CB_ACK, msg)
                    if err == NL_OK:
                        pass
                    elif err == NL_SKIP:
                        hdr = nlmsg_next(hdr, n)
                        continue
                    elif err == NL_STOP:
                        return -NLE_DUMP_INTR if interrupted else nrecv
                    else:
                        return -NLE_DUMP_INTR if interrupted else (err
                                                                   or nrecv)
            else:
                # Valid message (not checking for MULTIPART bit to get along with broken kernels. NL_SKIP has no effect
                # on this.
                if cb.cb_set[NL_CB_VALID]:
                    err = nl_cb_call(cb, NL_CB_VALID,
                                     msg)  # NL_CB_CALL(cb, NL_CB_VALID, msg)
                    if err == NL_OK:
                        pass
                    elif err == NL_SKIP:
                        hdr = nlmsg_next(hdr, n)
                        continue
                    elif err == NL_STOP:
                        return -NLE_DUMP_INTR if interrupted else nrecv
                    else:
                        return -NLE_DUMP_INTR if interrupted else (err
                                                                   or nrecv)

            hdr = nlmsg_next(hdr, n)

        del buf[:]
        creds = None

        if multipart:
            # Multipart message not yet complete, continue reading.
            continue

        err = 0
        if interrupted:
            return -NLE_DUMP_INTR
        if not err:
            err = nrecv
        return err
Beispiel #33
0
 def ifi_index(self, value):
     """Index setter."""
     self.bytearray[self._get_slicers(3)] = bytearray(c_int(value or 0))
Beispiel #34
0
def info_callback(msg, _):

    nlh = nlmsg_hdr(msg)
    gnlh = genlmsghdr(nlmsg_data(nlh))
    tb = dict((i, None) for i in range(NCSI_ATTR_MAX + 1))

    ret = genlmsg_parse(nlh, 0, tb, NCSI_ATTR_MAX, ncsi_policy)
    if ret != 0:
        reason = errmsg[abs(ret)]
        print("genlmsg_parse returned {}, {}".format(ret, reason))
        return ret

    if not NCSI_ATTR_PACKAGE_LIST in tb:
        print('No packages!')
        return -1

    rem = c_int()
    for nla in nla_for_each_nested(tb[NCSI_ATTR_PACKAGE_LIST], rem):
        ptb = dict()
        ret = nla_parse_nested(ptb, NCSI_PKG_ATTR_MAX, nla,
                               ncsi_package_policy)
        if ret < 0:
            print('Failed to parse package nest')
            return ret
        if NCSI_PKG_ATTR_ID in ptb:
            print('package {}'.format(nla_get_u32(ptb[NCSI_PKG_ATTR_ID])))
        else:
            print('package (with no id?)')
        if NCSI_PKG_ATTR_FORCED in ptb:
            print('this package is forced')
        print('----------')

        crem = c_int()
        for cnla in nla_for_each_nested(ptb[NCSI_PKG_ATTR_CHANNEL_LIST], crem):
            ctb = dict()
            ret = nla_parse_nested(ctb, NCSI_CHANNEL_ATTR_MAX, cnla,
                                   ncsi_channel_policy)
            if ret < 0:
                print('Failed to parse channel nest')
                return ret
            if NCSI_CHANNEL_ATTR_ID in ctb:
                channel = nla_get_u32(ctb[NCSI_CHANNEL_ATTR_ID])
                if NCSI_CHANNEL_ATTR_ACTIVE in ctb:
                    print('channel {} - active!'.format(channel))
                else:
                    print('channel {}'.format(channel))
                if NCSI_CHANNEL_ATTR_FORCED in ctb:
                    print('\tthis channel is forced')
            else:
                print('channel (with no id?)')
            if NCSI_CHANNEL_ATTR_VERSION_MAJOR in ctb:
                print('\tmajor version {}'.format(
                    nla_get_u32(ctb[NCSI_CHANNEL_ATTR_VERSION_MAJOR])))
            if NCSI_CHANNEL_ATTR_VERSION_MINOR in ctb:
                print('\tminor version {}'.format(
                    nla_get_u32(ctb[NCSI_CHANNEL_ATTR_VERSION_MINOR])))
            if NCSI_CHANNEL_ATTR_VERSION_STR in ctb:
                print('\tversion string {}'.format(
                    nla_get_string(ctb[NCSI_CHANNEL_ATTR_VERSION_STR])))
            if NCSI_CHANNEL_ATTR_LINK_STATE in ctb:
                print('\tlink state {}'.format(
                    nla_get_u32(ctb[NCSI_CHANNEL_ATTR_LINK_STATE])))
            if NCSI_CHANNEL_ATTR_VLAN_LIST in ctb:
                print('\tactive vlan ids:')
                rrem = c_int()
                vids = ctb[NCSI_CHANNEL_ATTR_VLAN_LIST]
                vid = nlattr(nla_data(vids))
                rrem.value = nla_len(vids)
                while nla_ok(vid, rrem):
                    print('\t\t{}'.format(nla_get_u16(vid)))
                    vid = nla_next(vid, rrem)

    return NL_SKIP
Beispiel #35
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
Beispiel #36
0
 def ifi_index(self, value):
     """Index setter."""
     self.bytearray[self._get_slicers(3)] = bytearray(c_int(value or 0))