@@ -434,6 +434,34 @@ def _find_mac_near_keyword(command, args, keywords, get_word_index):
434
434
return first_local_mac or None
435
435
436
436
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
+
437
465
def _find_mac_under_heading (command , args , heading ):
438
466
"""Looks for a MAC address under a heading in a command's output.
439
467
@@ -453,39 +481,21 @@ def _find_mac_under_heading(command, args, heading):
453
481
454
482
first_local_mac = None
455
483
for line in stdout :
484
+ words = line .rstrip ().split ()
456
485
try :
457
- words = line .rstrip ().split ()
458
486
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
489
499
490
500
491
501
# The following functions call external programs to 'get' a macaddr value to
0 commit comments