1#!/usr/local/bin/python3 2from enum import Enum 3from typing import Any 4from typing import Dict 5from typing import List 6from typing import NamedTuple 7 8 9class NlConst: 10 AF_NETLINK = 38 11 NETLINK_ROUTE = 0 12 NETLINK_GENERIC = 16 13 GENL_ID_CTRL = 16 14 15 16def roundup2(val: int, num: int) -> int: 17 if val % num: 18 return (val | (num - 1)) + 1 19 else: 20 return val 21 22 23def align4(val: int) -> int: 24 return roundup2(val, 4) 25 26 27def enum_or_int(val) -> int: 28 if isinstance(val, Enum): 29 return val.value 30 return val 31 32 33class AttrDescr(NamedTuple): 34 val: Enum 35 cls: "NlAttr" 36 child_map: Any = None 37 38 39def prepare_attrs_map(attrs: List[AttrDescr]) -> Dict[str, Dict]: 40 ret = {} 41 for ad in attrs: 42 ret[ad.val.value] = {"ad": ad} 43 if ad.child_map: 44 ret[ad.val.value]["child"] = prepare_attrs_map(ad.child_map) 45 return ret 46 47 48def build_propmap(cls): 49 ret = {} 50 for prop in dir(cls): 51 if not prop.startswith("_"): 52 ret[getattr(cls, prop).value] = prop 53 return ret 54 55 56def get_bitmask_map(propmap, val): 57 v = 1 58 ret = {} 59 while val: 60 if v & val: 61 if v in propmap: 62 ret[v] = propmap[v] 63 else: 64 ret[v] = hex(v) 65 val -= v 66 v *= 2 67 return ret 68 69 70def get_bitmask_str(cls, val): 71 if isinstance(cls, type): 72 pmap = build_propmap(cls) 73 else: 74 pmap = {} 75 for _cls in cls: 76 pmap.update(build_propmap(_cls)) 77 bmap = get_bitmask_map(pmap, val) 78 return ",".join([v for k, v in bmap.items()]) 79