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)
def dump_attr(ofd, attr, prefix=0): """https://github.com/thom311/libnl/blob/libnl3_2_25/lib/msg.c#L862. Positional arguments: ofd -- function to call with arguments similar to `logging.debug`. attr -- nlattr class instance. Keyword arguments: prefix -- additional number of whitespace pairs to prefix each log statement with. """ dump_hex(ofd, nla_data(attr), nla_len(attr), prefix)
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