1import socket 2import struct 3from ctypes import c_int 4from ctypes import c_ubyte 5from ctypes import c_uint 6from ctypes import c_ushort 7from ctypes import sizeof 8from ctypes import Structure 9from enum import auto 10from enum import Enum 11 12from atf_python.sys.netlink.attrs import NlAttr 13from atf_python.sys.netlink.attrs import NlAttrIp 14from atf_python.sys.netlink.attrs import NlAttrNested 15from atf_python.sys.netlink.attrs import NlAttrStr 16from atf_python.sys.netlink.attrs import NlAttrU32 17from atf_python.sys.netlink.attrs import NlAttrU8 18from atf_python.sys.netlink.message import StdNetlinkMessage 19from atf_python.sys.netlink.message import NlMsgProps 20from atf_python.sys.netlink.message import NlMsgCategory 21from atf_python.sys.netlink.utils import AttrDescr 22from atf_python.sys.netlink.utils import get_bitmask_str 23from atf_python.sys.netlink.utils import prepare_attrs_map 24 25 26class RtattrType(Enum): 27 RTA_UNSPEC = 0 28 RTA_DST = 1 29 RTA_SRC = 2 30 RTA_IIF = 3 31 RTA_OIF = 4 32 RTA_GATEWAY = 5 33 RTA_PRIORITY = 6 34 RTA_PREFSRC = 7 35 RTA_METRICS = 8 36 RTA_MULTIPATH = 9 37 # RTA_PROTOINFO = 10 38 RTA_KNH_ID = 10 39 RTA_FLOW = 11 40 RTA_CACHEINFO = 12 41 RTA_SESSION = 13 42 # RTA_MP_ALGO = 14 43 RTA_RTFLAGS = 14 44 RTA_TABLE = 15 45 RTA_MARK = 16 46 RTA_MFC_STATS = 17 47 RTA_VIA = 18 48 RTA_NEWDST = 19 49 RTA_PREF = 20 50 RTA_ENCAP_TYPE = 21 51 RTA_ENCAP = 22 52 RTA_EXPIRES = 23 53 RTA_PAD = 24 54 RTA_UID = 25 55 RTA_TTL_PROPAGATE = 26 56 RTA_IP_PROTO = 27 57 RTA_SPORT = 28 58 RTA_DPORT = 29 59 RTA_NH_ID = 30 60 61 62class NlRtMsgType(Enum): 63 RTM_NEWLINK = 16 64 RTM_DELLINK = 17 65 RTM_GETLINK = 18 66 RTM_SETLINK = 19 67 RTM_NEWADDR = 20 68 RTM_DELADDR = 21 69 RTM_GETADDR = 22 70 RTM_NEWROUTE = 24 71 RTM_DELROUTE = 25 72 RTM_GETROUTE = 26 73 RTM_NEWNEIGH = 28 74 RTM_DELNEIGH = 29 75 RTM_GETNEIGH = 30 76 RTM_NEWRULE = 32 77 RTM_DELRULE = 33 78 RTM_GETRULE = 34 79 RTM_NEWQDISC = 36 80 RTM_DELQDISC = 37 81 RTM_GETQDISC = 38 82 RTM_NEWTCLASS = 40 83 RTM_DELTCLASS = 41 84 RTM_GETTCLASS = 42 85 RTM_NEWTFILTER = 44 86 RTM_DELTFILTER = 45 87 RTM_GETTFILTER = 46 88 RTM_NEWACTION = 48 89 RTM_DELACTION = 49 90 RTM_GETACTION = 50 91 RTM_NEWPREFIX = 52 92 RTM_GETMULTICAST = 58 93 RTM_GETANYCAST = 62 94 RTM_NEWNEIGHTBL = 64 95 RTM_GETNEIGHTBL = 66 96 RTM_SETNEIGHTBL = 67 97 RTM_NEWNDUSEROPT = 68 98 RTM_NEWADDRLABEL = 72 99 RTM_DELADDRLABEL = 73 100 RTM_GETADDRLABEL = 74 101 RTM_GETDCB = 78 102 RTM_SETDCB = 79 103 RTM_NEWNETCONF = 80 104 RTM_GETNETCONF = 82 105 RTM_NEWMDB = 84 106 RTM_DELMDB = 85 107 RTM_GETMDB = 86 108 RTM_NEWNSID = 88 109 RTM_DELNSID = 89 110 RTM_GETNSID = 90 111 RTM_NEWSTATS = 92 112 RTM_GETSTATS = 94 113 114 115class RtAttr(Structure): 116 _fields_ = [ 117 ("rta_len", c_ushort), 118 ("rta_type", c_ushort), 119 ] 120 121 122class RtMsgHdr(Structure): 123 _fields_ = [ 124 ("rtm_family", c_ubyte), 125 ("rtm_dst_len", c_ubyte), 126 ("rtm_src_len", c_ubyte), 127 ("rtm_tos", c_ubyte), 128 ("rtm_table", c_ubyte), 129 ("rtm_protocol", c_ubyte), 130 ("rtm_scope", c_ubyte), 131 ("rtm_type", c_ubyte), 132 ("rtm_flags", c_uint), 133 ] 134 135 136class RtMsgFlags(Enum): 137 RTM_F_NOTIFY = 0x100 138 RTM_F_CLONED = 0x200 139 RTM_F_EQUALIZE = 0x400 140 RTM_F_PREFIX = 0x800 141 RTM_F_LOOKUP_TABLE = 0x1000 142 RTM_F_FIB_MATCH = 0x2000 143 RTM_F_OFFLOAD = 0x4000 144 RTM_F_TRAP = 0x8000 145 RTM_F_OFFLOAD_FAILED = 0x20000000 146 147 148class RtScope(Enum): 149 RT_SCOPE_UNIVERSE = 0 150 RT_SCOPE_SITE = 200 151 RT_SCOPE_LINK = 253 152 RT_SCOPE_HOST = 254 153 RT_SCOPE_NOWHERE = 255 154 155 156class RtType(Enum): 157 RTN_UNSPEC = 0 158 RTN_UNICAST = auto() 159 RTN_LOCAL = auto() 160 RTN_BROADCAST = auto() 161 RTN_ANYCAST = auto() 162 RTN_MULTICAST = auto() 163 RTN_BLACKHOLE = auto() 164 RTN_UNREACHABLE = auto() 165 RTN_PROHIBIT = auto() 166 RTN_THROW = auto() 167 RTN_NAT = auto() 168 RTN_XRESOLVE = auto() 169 170 171class RtProto(Enum): 172 RTPROT_UNSPEC = 0 173 RTPROT_REDIRECT = 1 174 RTPROT_KERNEL = 2 175 RTPROT_BOOT = 3 176 RTPROT_STATIC = 4 177 RTPROT_GATED = 8 178 RTPROT_RA = 9 179 RTPROT_MRT = 10 180 RTPROT_ZEBRA = 11 181 RTPROT_BIRD = 12 182 RTPROT_DNROUTED = 13 183 RTPROT_XORP = 14 184 RTPROT_NTK = 15 185 RTPROT_DHCP = 16 186 RTPROT_MROUTED = 17 187 RTPROT_KEEPALIVED = 18 188 RTPROT_BABEL = 42 189 RTPROT_OPENR = 99 190 RTPROT_BGP = 186 191 RTPROT_ISIS = 187 192 RTPROT_OSPF = 188 193 RTPROT_RIP = 189 194 RTPROT_EIGRP = 192 195 196 197class NlRtaxType(Enum): 198 RTAX_UNSPEC = 0 199 RTAX_LOCK = auto() 200 RTAX_MTU = auto() 201 RTAX_WINDOW = auto() 202 RTAX_RTT = auto() 203 RTAX_RTTVAR = auto() 204 RTAX_SSTHRESH = auto() 205 RTAX_CWND = auto() 206 RTAX_ADVMSS = auto() 207 RTAX_REORDERING = auto() 208 RTAX_HOPLIMIT = auto() 209 RTAX_INITCWND = auto() 210 RTAX_FEATURES = auto() 211 RTAX_RTO_MIN = auto() 212 RTAX_INITRWND = auto() 213 RTAX_QUICKACK = auto() 214 RTAX_CC_ALGO = auto() 215 RTAX_FASTOPEN_NO_COOKIE = auto() 216 217 218class RtFlagsBSD(Enum): 219 RTF_UP = 0x1 220 RTF_GATEWAY = 0x2 221 RTF_HOST = 0x4 222 RTF_REJECT = 0x8 223 RTF_DYNAMIC = 0x10 224 RTF_MODIFIED = 0x20 225 RTF_DONE = 0x40 226 RTF_XRESOLVE = 0x200 227 RTF_LLINFO = 0x400 228 RTF_LLDATA = 0x400 229 RTF_STATIC = 0x800 230 RTF_BLACKHOLE = 0x1000 231 RTF_PROTO2 = 0x4000 232 RTF_PROTO1 = 0x8000 233 RTF_PROTO3 = 0x40000 234 RTF_FIXEDMTU = 0x80000 235 RTF_PINNED = 0x100000 236 RTF_LOCAL = 0x200000 237 RTF_BROADCAST = 0x400000 238 RTF_MULTICAST = 0x800000 239 RTF_STICKY = 0x10000000 240 RTF_RNH_LOCKED = 0x40000000 241 RTF_GWFLAG_COMPAT = 0x80000000 242 243 244class NlRtGroup(Enum): 245 RTNLGRP_NONE = 0 246 RTNLGRP_LINK = auto() 247 RTNLGRP_NOTIFY = auto() 248 RTNLGRP_NEIGH = auto() 249 RTNLGRP_TC = auto() 250 RTNLGRP_IPV4_IFADDR = auto() 251 RTNLGRP_IPV4_MROUTE = auto() 252 RTNLGRP_IPV4_ROUTE = auto() 253 RTNLGRP_IPV4_RULE = auto() 254 RTNLGRP_IPV6_IFADDR = auto() 255 RTNLGRP_IPV6_MROUTE = auto() 256 RTNLGRP_IPV6_ROUTE = auto() 257 RTNLGRP_IPV6_IFINFO = auto() 258 RTNLGRP_DECnet_IFADDR = auto() 259 RTNLGRP_NOP2 = auto() 260 RTNLGRP_DECnet_ROUTE = auto() 261 RTNLGRP_DECnet_RULE = auto() 262 RTNLGRP_NOP4 = auto() 263 RTNLGRP_IPV6_PREFIX = auto() 264 RTNLGRP_IPV6_RULE = auto() 265 RTNLGRP_ND_USEROPT = auto() 266 RTNLGRP_PHONET_IFADDR = auto() 267 RTNLGRP_PHONET_ROUTE = auto() 268 RTNLGRP_DCB = auto() 269 RTNLGRP_IPV4_NETCONF = auto() 270 RTNLGRP_IPV6_NETCONF = auto() 271 RTNLGRP_MDB = auto() 272 RTNLGRP_MPLS_ROUTE = auto() 273 RTNLGRP_NSID = auto() 274 RTNLGRP_MPLS_NETCONF = auto() 275 RTNLGRP_IPV4_MROUTE_R = auto() 276 RTNLGRP_IPV6_MROUTE_R = auto() 277 RTNLGRP_NEXTHOP = auto() 278 RTNLGRP_BRVLAN = auto() 279 280 281class IfinfoMsg(Structure): 282 _fields_ = [ 283 ("ifi_family", c_ubyte), 284 ("__ifi_pad", c_ubyte), 285 ("ifi_type", c_ushort), 286 ("ifi_index", c_int), 287 ("ifi_flags", c_uint), 288 ("ifi_change", c_uint), 289 ] 290 291 292class IflattrType(Enum): 293 IFLA_UNSPEC = 0 294 IFLA_ADDRESS = 1 295 IFLA_BROADCAST = 2 296 IFLA_IFNAME = 3 297 IFLA_MTU = 4 298 IFLA_LINK = 5 299 IFLA_QDISC = 6 300 IFLA_STATS = 7 301 IFLA_COST = 8 302 IFLA_PRIORITY = 9 303 IFLA_MASTER = 10 304 IFLA_WIRELESS = 11 305 IFLA_PROTINFO = 12 306 IFLA_TXQLEN = 13 307 IFLA_MAP = 14 308 IFLA_WEIGHT = 15 309 IFLA_OPERSTATE = 16 310 IFLA_LINKMODE = 17 311 IFLA_LINKINFO = 18 312 IFLA_NET_NS_PID = 19 313 IFLA_IFALIAS = 20 314 IFLA_NUM_VF = 21 315 IFLA_VFINFO_LIST = 22 316 IFLA_STATS64 = 23 317 IFLA_VF_PORTS = 24 318 IFLA_PORT_SELF = 25 319 IFLA_AF_SPEC = 26 320 IFLA_GROUP = 27 321 IFLA_NET_NS_FD = 28 322 IFLA_EXT_MASK = 29 323 IFLA_PROMISCUITY = 30 324 IFLA_NUM_TX_QUEUES = 31 325 IFLA_NUM_RX_QUEUES = 32 326 IFLA_CARRIER = 33 327 IFLA_PHYS_PORT_ID = 34 328 IFLA_CARRIER_CHANGES = 35 329 IFLA_PHYS_SWITCH_ID = 36 330 IFLA_LINK_NETNSID = 37 331 IFLA_PHYS_PORT_NAME = 38 332 IFLA_PROTO_DOWN = 39 333 IFLA_GSO_MAX_SEGS = 40 334 IFLA_GSO_MAX_SIZE = 41 335 IFLA_PAD = 42 336 IFLA_XDP = 43 337 IFLA_EVENT = 44 338 IFLA_NEW_NETNSID = 45 339 IFLA_IF_NETNSID = 46 340 IFLA_CARRIER_UP_COUNT = 47 341 IFLA_CARRIER_DOWN_COUNT = 48 342 IFLA_NEW_IFINDEX = 49 343 IFLA_MIN_MTU = 50 344 IFLA_MAX_MTU = 51 345 IFLA_PROP_LIST = 52 346 IFLA_ALT_IFNAME = 53 347 IFLA_PERM_ADDRESS = 54 348 IFLA_PROTO_DOWN_REASON = 55 349 IFLA_PARENT_DEV_NAME = 56 350 IFLA_PARENT_DEV_BUS_NAME = 57 351 IFLA_GRO_MAX_SIZE = 58 352 IFLA_TSO_MAX_SEGS = 59 353 IFLA_ALLMULTI = 60 354 IFLA_DEVLINK_PORT = 61 355 IFLA_GSO_IPV4_MAX_SIZE = 62 356 IFLA_GRO_IPV4_MAX_SIZE = 63 357 IFLA_FREEBSD = 64 358 359 360class IflafAttrType(Enum): 361 IFLAF_UNSPEC = 0 362 IFLAF_ORIG_IFNAME = 1 363 IFLAF_ORIG_HWADDR = 2 364 365 366class IflinkInfo(Enum): 367 IFLA_INFO_UNSPEC = 0 368 IFLA_INFO_KIND = auto() 369 IFLA_INFO_DATA = auto() 370 IFLA_INFO_XSTATS = auto() 371 IFLA_INFO_SLAVE_KIND = auto() 372 IFLA_INFO_SLAVE_DATA = auto() 373 374 375class IfLinkInfoDataVlan(Enum): 376 IFLA_VLAN_UNSPEC = 0 377 IFLA_VLAN_ID = auto() 378 IFLA_VLAN_FLAGS = auto() 379 IFLA_VLAN_EGRESS_QOS = auto() 380 IFLA_VLAN_INGRESS_QOS = auto() 381 IFLA_VLAN_PROTOCOL = auto() 382 383 384class IfaddrMsg(Structure): 385 _fields_ = [ 386 ("ifa_family", c_ubyte), 387 ("ifa_prefixlen", c_ubyte), 388 ("ifa_flags", c_ubyte), 389 ("ifa_scope", c_ubyte), 390 ("ifa_index", c_uint), 391 ] 392 393 394class IfaAttrType(Enum): 395 IFA_UNSPEC = 0 396 IFA_ADDRESS = 1 397 IFA_LOCAL = 2 398 IFA_LABEL = 3 399 IFA_BROADCAST = 4 400 IFA_ANYCAST = 5 401 IFA_CACHEINFO = 6 402 IFA_MULTICAST = 7 403 IFA_FLAGS = 8 404 IFA_RT_PRIORITY = 9 405 IFA_TARGET_NETNSID = 10 406 IFA_FREEBSD = 11 407 408 409class IfafAttrType(Enum): 410 IFAF_UNSPEC = 0 411 IFAF_VHID = 1 412 IFAF_FLAGS = 2 413 414 415class IfaCacheInfo(Structure): 416 _fields_ = [ 417 ("ifa_prefered", c_uint), # seconds till the end of the prefix considered preferred 418 ("ifa_valid", c_uint), # seconds till the end of the prefix considered valid 419 ("cstamp", c_uint), # creation time in 1ms intervals from the boot time 420 ("tstamp", c_uint), # update time in 1ms intervals from the boot time 421 ] 422 423 424class IfaFlags(Enum): 425 IFA_F_TEMPORARY = 0x01 426 IFA_F_NODAD = 0x02 427 IFA_F_OPTIMISTIC = 0x04 428 IFA_F_DADFAILED = 0x08 429 IFA_F_HOMEADDRESS = 0x10 430 IFA_F_DEPRECATED = 0x20 431 IFA_F_TENTATIVE = 0x40 432 IFA_F_PERMANENT = 0x80 433 IFA_F_MANAGETEMPADDR = 0x100 434 IFA_F_NOPREFIXROUTE = 0x200 435 IFA_F_MCAUTOJOIN = 0x400 436 IFA_F_STABLE_PRIVACY = 0x800 437 438 439class IfafFlags6(Enum): 440 IN6_IFF_ANYCAST = 0x01 441 IN6_IFF_TENTATIVE = 0x02 442 IN6_IFF_DUPLICATED = 0x04 443 IN6_IFF_DETACHED = 0x08 444 IN6_IFF_DEPRECATED = 0x10 445 IN6_IFF_NODAD = 0x20 446 IN6_IFF_AUTOCONF = 0x40 447 IN6_IFF_TEMPORARY = 0x80 448 IN6_IFF_PREFER_SOURCE = 0x100 449 450 451class NdMsg(Structure): 452 _fields_ = [ 453 ("ndm_family", c_ubyte), 454 ("ndm_pad1", c_ubyte), 455 ("ndm_pad2", c_ubyte), 456 ("ndm_ifindex", c_uint), 457 ("ndm_state", c_ushort), 458 ("ndm_flags", c_ubyte), 459 ("ndm_type", c_ubyte), 460 ] 461 462 463class NdAttrType(Enum): 464 NDA_UNSPEC = 0 465 NDA_DST = 1 466 NDA_LLADDR = 2 467 NDA_CACHEINFO = 3 468 NDA_PROBES = 4 469 NDA_VLAN = 5 470 NDA_PORT = 6 471 NDA_VNI = 7 472 NDA_IFINDEX = 8 473 NDA_MASTER = 9 474 NDA_LINK_NETNSID = 10 475 NDA_SRC_VNI = 11 476 NDA_PROTOCOL = 12 477 NDA_NH_ID = 13 478 NDA_FDB_EXT_ATTRS = 14 479 NDA_FLAGS_EXT = 15 480 NDA_NDM_STATE_MASK = 16 481 NDA_NDM_FLAGS_MASK = 17 482 483 484class NlAttrRtFlags(NlAttrU32): 485 def _print_attr_value(self): 486 s = get_bitmask_str(RtFlagsBSD, self.u32) 487 return " rtflags={}".format(s) 488 489 490class NlAttrIfindex(NlAttrU32): 491 def _print_attr_value(self): 492 try: 493 ifname = socket.if_indextoname(self.u32) 494 return " iface={}(#{})".format(ifname, self.u32) 495 except OSError: 496 pass 497 return " iface=if#{}".format(self.u32) 498 499 500class NlAttrTable(NlAttrU32): 501 def _print_attr_value(self): 502 return " rtable={}".format(self.u32) 503 504 505class NlAttrNhId(NlAttrU32): 506 def _print_attr_value(self): 507 return " nh_id={}".format(self.u32) 508 509 510class NlAttrKNhId(NlAttrU32): 511 def _print_attr_value(self): 512 return " knh_id={}".format(self.u32) 513 514 515class NlAttrMac(NlAttr): 516 def _print_attr_value(self): 517 return ' mac="' + ":".join(["{:02X}".format(b) for b in self._data]) + '"' 518 519 520class NlAttrIfStats(NlAttr): 521 def _print_attr_value(self): 522 return " stats={...}" 523 524 525class NlAttrCacheInfo(NlAttr): 526 def __init__(self, nla_type, data): 527 super().__init__(nla_type, data) 528 self.ci = IfaCacheInfo.from_buffer_copy(data) 529 530 @staticmethod 531 def _validate(data): 532 nla_len, nla_type = struct.unpack("@HH", data[:4]) 533 data_len = nla_len - 4 534 if data_len != sizeof(IfaCacheInfo): 535 raise ValueError( 536 "Error validating attr {}: wrong size".format(nla_type) 537 ) # noqa: E501 538 539 def _print_attr_value(self): 540 return " ifa_prefered={} ifa_valid={} cstamp={} tstamp={}".format( 541 self.ci.ifa_prefered, self.ci.ifa_valid, self.ci.cstamp, self.ci.tstamp) 542 543 544class NlAttrVia(NlAttr): 545 def __init__(self, nla_type, family, addr: str): 546 super().__init__(nla_type, b"") 547 self.addr = addr 548 self.family = family 549 550 @staticmethod 551 def _validate(data): 552 nla_len, nla_type = struct.unpack("@HH", data[:4]) 553 data_len = nla_len - 4 554 if data_len == 0: 555 raise ValueError( 556 "Error validating attr {}: empty data".format(nla_type) 557 ) # noqa: E501 558 family = int(data_len[0]) 559 if family not in (socket.AF_INET, socket.AF_INET6): 560 raise ValueError( 561 "Error validating attr {}: unsupported AF {}".format( # noqa: E501 562 nla_type, family 563 ) 564 ) 565 if family == socket.AF_INET: 566 expected_len = 1 + 4 567 else: 568 expected_len = 1 + 16 569 if data_len != expected_len: 570 raise ValueError( 571 "Error validating attr {}: expected len {} got {}".format( # noqa: E501 572 nla_type, expected_len, data_len 573 ) 574 ) 575 576 @property 577 def nla_len(self): 578 if self.family == socket.AF_INET6: 579 return 21 580 else: 581 return 9 582 583 @classmethod 584 def _parse(cls, data): 585 nla_len, nla_type, family = struct.unpack("@HHB", data[:5]) 586 off = 5 587 if family == socket.AF_INET: 588 addr = socket.inet_ntop(family, data[off:off + 4]) 589 else: 590 addr = socket.inet_ntop(family, data[off:off + 16]) 591 return cls(nla_type, family, addr) 592 593 def __bytes__(self): 594 addr = socket.inet_pton(self.family, self.addr) 595 return self._to_bytes(struct.pack("@B", self.family) + addr) 596 597 def _print_attr_value(self): 598 return " via={}".format(self.addr) 599 600 601rtnl_route_attrs = prepare_attrs_map( 602 [ 603 AttrDescr(RtattrType.RTA_DST, NlAttrIp), 604 AttrDescr(RtattrType.RTA_SRC, NlAttrIp), 605 AttrDescr(RtattrType.RTA_IIF, NlAttrIfindex), 606 AttrDescr(RtattrType.RTA_OIF, NlAttrIfindex), 607 AttrDescr(RtattrType.RTA_GATEWAY, NlAttrIp), 608 AttrDescr(RtattrType.RTA_TABLE, NlAttrTable), 609 AttrDescr(RtattrType.RTA_PRIORITY, NlAttrU32), 610 AttrDescr(RtattrType.RTA_VIA, NlAttrVia), 611 AttrDescr(RtattrType.RTA_NH_ID, NlAttrNhId), 612 AttrDescr(RtattrType.RTA_KNH_ID, NlAttrKNhId), 613 AttrDescr(RtattrType.RTA_RTFLAGS, NlAttrRtFlags), 614 AttrDescr( 615 RtattrType.RTA_METRICS, 616 NlAttrNested, 617 [ 618 AttrDescr(NlRtaxType.RTAX_MTU, NlAttrU32), 619 ], 620 ), 621 ] 622) 623 624rtnl_ifla_attrs = prepare_attrs_map( 625 [ 626 AttrDescr(IflattrType.IFLA_ADDRESS, NlAttrMac), 627 AttrDescr(IflattrType.IFLA_BROADCAST, NlAttrMac), 628 AttrDescr(IflattrType.IFLA_IFNAME, NlAttrStr), 629 AttrDescr(IflattrType.IFLA_MTU, NlAttrU32), 630 AttrDescr(IflattrType.IFLA_LINK, NlAttrU32), 631 AttrDescr(IflattrType.IFLA_PROMISCUITY, NlAttrU32), 632 AttrDescr(IflattrType.IFLA_OPERSTATE, NlAttrU8), 633 AttrDescr(IflattrType.IFLA_CARRIER, NlAttrU8), 634 AttrDescr(IflattrType.IFLA_IFALIAS, NlAttrStr), 635 AttrDescr(IflattrType.IFLA_STATS64, NlAttrIfStats), 636 AttrDescr(IflattrType.IFLA_NEW_IFINDEX, NlAttrU32), 637 AttrDescr( 638 IflattrType.IFLA_LINKINFO, 639 NlAttrNested, 640 [ 641 AttrDescr(IflinkInfo.IFLA_INFO_KIND, NlAttrStr), 642 AttrDescr(IflinkInfo.IFLA_INFO_DATA, NlAttr), 643 ], 644 ), 645 AttrDescr( 646 IflattrType.IFLA_FREEBSD, 647 NlAttrNested, 648 [ 649 AttrDescr(IflafAttrType.IFLAF_ORIG_HWADDR, NlAttrMac), 650 ], 651 ), 652 ] 653) 654 655rtnl_ifa_attrs = prepare_attrs_map( 656 [ 657 AttrDescr(IfaAttrType.IFA_ADDRESS, NlAttrIp), 658 AttrDescr(IfaAttrType.IFA_LOCAL, NlAttrIp), 659 AttrDescr(IfaAttrType.IFA_LABEL, NlAttrStr), 660 AttrDescr(IfaAttrType.IFA_BROADCAST, NlAttrIp), 661 AttrDescr(IfaAttrType.IFA_ANYCAST, NlAttrIp), 662 AttrDescr(IfaAttrType.IFA_FLAGS, NlAttrU32), 663 AttrDescr(IfaAttrType.IFA_CACHEINFO, NlAttrCacheInfo), 664 AttrDescr( 665 IfaAttrType.IFA_FREEBSD, 666 NlAttrNested, 667 [ 668 AttrDescr(IfafAttrType.IFAF_VHID, NlAttrU32), 669 AttrDescr(IfafAttrType.IFAF_FLAGS, NlAttrU32), 670 ], 671 ), 672 ] 673) 674 675 676rtnl_nd_attrs = prepare_attrs_map( 677 [ 678 AttrDescr(NdAttrType.NDA_DST, NlAttrIp), 679 AttrDescr(NdAttrType.NDA_IFINDEX, NlAttrIfindex), 680 AttrDescr(NdAttrType.NDA_FLAGS_EXT, NlAttrU32), 681 AttrDescr(NdAttrType.NDA_LLADDR, NlAttrMac), 682 ] 683) 684 685 686class BaseNetlinkRtMessage(StdNetlinkMessage): 687 pass 688 689 690class NetlinkRtMessage(BaseNetlinkRtMessage): 691 messages = [ 692 NlMsgProps(NlRtMsgType.RTM_NEWROUTE, NlMsgCategory.NEW), 693 NlMsgProps(NlRtMsgType.RTM_DELROUTE, NlMsgCategory.DELETE), 694 NlMsgProps(NlRtMsgType.RTM_GETROUTE, NlMsgCategory.GET), 695 ] 696 nl_attrs_map = rtnl_route_attrs 697 698 def __init__(self, helper, nlm_type): 699 super().__init__(helper, nlm_type) 700 self.base_hdr = RtMsgHdr() 701 702 def parse_base_header(self, data): 703 if len(data) < sizeof(RtMsgHdr): 704 raise ValueError("length less than rtmsg header") 705 rtm_hdr = RtMsgHdr.from_buffer_copy(data) 706 return (rtm_hdr, sizeof(RtMsgHdr)) 707 708 def print_base_header(self, hdr, prepend=""): 709 family = self.helper.get_af_name(hdr.rtm_family) 710 print( 711 "{}family={}, dst_len={}, src_len={}, tos={}, table={}, protocol={}({}), scope={}({}), type={}({}), flags={}({})".format( # noqa: E501 712 prepend, 713 family, 714 hdr.rtm_dst_len, 715 hdr.rtm_src_len, 716 hdr.rtm_tos, 717 hdr.rtm_table, 718 self.helper.get_attr_byval(RtProto, hdr.rtm_protocol), 719 hdr.rtm_protocol, 720 self.helper.get_attr_byval(RtScope, hdr.rtm_scope), 721 hdr.rtm_scope, 722 self.helper.get_attr_byval(RtType, hdr.rtm_type), 723 hdr.rtm_type, 724 self.helper.get_bitmask_str(RtMsgFlags, hdr.rtm_flags), 725 hdr.rtm_flags, 726 ) 727 ) 728 729 730class NetlinkIflaMessage(BaseNetlinkRtMessage): 731 messages = [ 732 NlMsgProps(NlRtMsgType.RTM_NEWLINK, NlMsgCategory.NEW), 733 NlMsgProps(NlRtMsgType.RTM_DELLINK, NlMsgCategory.DELETE), 734 NlMsgProps(NlRtMsgType.RTM_GETLINK, NlMsgCategory.GET), 735 ] 736 nl_attrs_map = rtnl_ifla_attrs 737 738 def __init__(self, helper, nlm_type): 739 super().__init__(helper, nlm_type) 740 self.base_hdr = IfinfoMsg() 741 742 def parse_base_header(self, data): 743 if len(data) < sizeof(IfinfoMsg): 744 raise ValueError("length less than IfinfoMsg header") 745 rtm_hdr = IfinfoMsg.from_buffer_copy(data) 746 return (rtm_hdr, sizeof(IfinfoMsg)) 747 748 def print_base_header(self, hdr, prepend=""): 749 family = self.helper.get_af_name(hdr.ifi_family) 750 print( 751 "{}family={}, ifi_type={}, ifi_index={}, ifi_flags={}, ifi_change={}".format( # noqa: E501 752 prepend, 753 family, 754 hdr.ifi_type, 755 hdr.ifi_index, 756 hdr.ifi_flags, 757 hdr.ifi_change, 758 ) 759 ) 760 761 762class NetlinkIfaMessage(BaseNetlinkRtMessage): 763 messages = [ 764 NlMsgProps(NlRtMsgType.RTM_NEWADDR, NlMsgCategory.NEW), 765 NlMsgProps(NlRtMsgType.RTM_DELADDR, NlMsgCategory.DELETE), 766 NlMsgProps(NlRtMsgType.RTM_GETADDR, NlMsgCategory.GET), 767 ] 768 nl_attrs_map = rtnl_ifa_attrs 769 770 def __init__(self, helper, nlm_type): 771 super().__init__(helper, nlm_type) 772 self.base_hdr = IfaddrMsg() 773 774 def parse_base_header(self, data): 775 if len(data) < sizeof(IfaddrMsg): 776 raise ValueError("length less than IfaddrMsg header") 777 rtm_hdr = IfaddrMsg.from_buffer_copy(data) 778 return (rtm_hdr, sizeof(IfaddrMsg)) 779 780 def print_base_header(self, hdr, prepend=""): 781 family = self.helper.get_af_name(hdr.ifa_family) 782 print( 783 "{}family={}, ifa_prefixlen={}, ifa_flags={}, ifa_scope={}, ifa_index={}".format( # noqa: E501 784 prepend, 785 family, 786 hdr.ifa_prefixlen, 787 hdr.ifa_flags, 788 hdr.ifa_scope, 789 hdr.ifa_index, 790 ) 791 ) 792 793 794class NetlinkNdMessage(BaseNetlinkRtMessage): 795 messages = [ 796 NlMsgProps(NlRtMsgType.RTM_NEWNEIGH, NlMsgCategory.NEW), 797 NlMsgProps(NlRtMsgType.RTM_DELNEIGH, NlMsgCategory.DELETE), 798 NlMsgProps(NlRtMsgType.RTM_GETNEIGH, NlMsgCategory.GET), 799 ] 800 nl_attrs_map = rtnl_nd_attrs 801 802 def __init__(self, helper, nlm_type): 803 super().__init__(helper, nlm_type) 804 self.base_hdr = NdMsg() 805 806 def parse_base_header(self, data): 807 if len(data) < sizeof(NdMsg): 808 raise ValueError("length less than NdMsg header") 809 nd_hdr = NdMsg.from_buffer_copy(data) 810 return (nd_hdr, sizeof(NdMsg)) 811 812 def print_base_header(self, hdr, prepend=""): 813 family = self.helper.get_af_name(hdr.ndm_family) 814 print( 815 "{}family={}, ndm_ifindex={}, ndm_state={}, ndm_flags={}".format( # noqa: E501 816 prepend, 817 family, 818 hdr.ndm_ifindex, 819 hdr.ndm_state, 820 hdr.ndm_flags, 821 ) 822 ) 823 824 825handler_classes = { 826 "netlink_route": [ 827 NetlinkRtMessage, 828 NetlinkIflaMessage, 829 NetlinkIfaMessage, 830 NetlinkNdMessage, 831 ], 832} 833