@@ -434,6 +434,34 @@ def _find_mac_near_keyword(command, args, keywords, get_word_index):
434434 return first_local_mac or None
435435
436436
437+ def _parse_mac (word ):
438+ # Accept 'HH:HH:HH:HH:HH:HH' MAC address (ex: '52:54:00:9d:0e:67'),
439+ # but reject IPv6 address (ex: 'fe80::5054:ff:fe9' or '123:2:3:4:5:6:7:8').
440+ #
441+ # Virtual interfaces, such as those provided by VPNs, do not have a
442+ # colon-delimited MAC address as expected, but a 16-byte HWAddr separated
443+ # by dashes. These should be ignored in favor of a real MAC address
444+ parts = word .split (_MAC_DELIM )
445+ if len (parts ) != 6 :
446+ return
447+ if _MAC_OMITS_LEADING_ZEROES :
448+ # (Only) on AIX the macaddr value given is not prefixed by 0, e.g.
449+ # en0 1500 link#2 fa.bc.de.f7.62.4 110854824 0 160133733 0 0
450+ # not
451+ # en0 1500 link#2 fa.bc.de.f7.62.04 110854824 0 160133733 0 0
452+ if not all (1 <= len (part ) <= 2 for part in parts ):
453+ return
454+ hexstr = b'' .join (part .rjust (2 , b'0' ) for part in parts )
455+ else :
456+ if not all (len (part ) == 2 for part in parts ):
457+ return
458+ hexstr = b'' .join (parts )
459+ try :
460+ return int (hexstr , 16 )
461+ except ValueError :
462+ return
463+
464+
437465def _find_mac_under_heading (command , args , heading ):
438466 """Looks for a MAC address under a heading in a command's output.
439467
@@ -453,39 +481,21 @@ def _find_mac_under_heading(command, args, heading):
453481
454482 first_local_mac = None
455483 for line in stdout :
484+ words = line .rstrip ().split ()
456485 try :
457- words = line .rstrip ().split ()
458486 word = words [column_index ]
459- # Accept 'HH:HH:HH:HH:HH:HH' MAC address (ex: '52:54:00:9d:0e:67'),
460- # but reject IPv6 address (ex: 'fe80::5054:ff:fe9') detected
461- # by '::' pattern.
462- if len (word ) == 17 and b'::' not in word :
463- mac = int (word .replace (_MAC_DELIM , b'' ), 16 )
464- elif _MAC_OMITS_LEADING_ZEROES :
465- # (Only) on AIX the macaddr value given is not prefixed by 0, e.g.
466- # en0 1500 link#2 fa.bc.de.f7.62.4 110854824 0 160133733 0 0
467- # not
468- # en0 1500 link#2 fa.bc.de.f7.62.04 110854824 0 160133733 0 0
469- parts = word .split (_MAC_DELIM )
470- if len (parts ) == 6 and all (0 < len (p ) <= 2 for p in parts ):
471- hexstr = b'' .join (p .rjust (2 , b'0' ) for p in parts )
472- mac = int (hexstr , 16 )
473- else :
474- continue
475- else :
476- continue
477- except (ValueError , IndexError ):
478- # Virtual interfaces, such as those provided by
479- # VPNs, do not have a colon-delimited MAC address
480- # as expected, but a 16-byte HWAddr separated by
481- # dashes. These should be ignored in favor of a
482- # real MAC address
483- pass
484- else :
485- if _is_universal (mac ):
486- return mac
487- first_local_mac = first_local_mac or mac
488- return first_local_mac or None
487+ except IndexError :
488+ continue
489+
490+ mac = _parse_mac (word )
491+ if mac is None :
492+ continue
493+ if _is_universal (mac ):
494+ return mac
495+ if first_local_mac is None :
496+ first_local_mac = mac
497+
498+ return first_local_mac
489499
490500
491501# The following functions call external programs to 'get' a macaddr value to
0 commit comments