Skip to content
Extraits de code Groupes Projets
Valider 4b2a25e1 rédigé par François De Keersmaeker's avatar François De Keersmaeker
Parcourir les fichiers

MAC: bugfix + unit tests

parent 5534d4cd
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
Anonymize MAC addresses. Anonymize MAC addresses.
""" """
import random
import secrets import secrets
from scapy.layers.l2 import Ether, ARP from scapy.layers.l2 import Ether, ARP
...@@ -14,6 +15,36 @@ special_macs = [ ...@@ -14,6 +15,36 @@ special_macs = [
] ]
def get_ig_bit(mac: str) -> int:
"""
Get the I/G bit of a given MAC address.
Args:
mac (str): MAC address to get the I/G bit from
Returns:
int: 8-bit integer with the I/G bit set to its corresponding value,
and all other bits set to 0
"""
first_byte = int(mac.split(":")[0], BASE_HEX)
ig_mask = 0b00000001
return first_byte & ig_mask
def get_ul_bit(mac: str) -> int:
"""
Get the U/L bit of a given MAC address.
Args:
mac (str): MAC address to get the U/L bit from
Returns:
int: 8-bit integer with the U/L bit set to its corresponding value,
and all other bits set to 0
"""
first_byte = int(mac.split(":")[0], BASE_HEX)
ul_mask = 0b00000010
return first_byte & ul_mask
def anonymize_mac(mac: str) -> str: def anonymize_mac(mac: str) -> str:
""" """
Anonymize a given MAC address. Anonymize a given MAC address.
...@@ -33,9 +64,7 @@ def anonymize_mac(mac: str) -> str: ...@@ -33,9 +64,7 @@ def anonymize_mac(mac: str) -> str:
## I/G bit: first byte, least-significant bit ## I/G bit: first byte, least-significant bit
# I/G bit = 0 ==> Unicast address # I/G bit = 0 ==> Unicast address
# I/G bit = 1 ==> Multicast address # I/G bit = 1 ==> Multicast address
first_byte = int(mac_split[0], BASE_HEX) ig_bit = get_ig_bit(mac)
ig_mask = 0b00000001
ig_bit = first_byte & ig_mask
is_multicast = bool(ig_bit) # True ==> Multicast, False ==> Unicast is_multicast = bool(ig_bit) # True ==> Multicast, False ==> Unicast
# Multicast address: # Multicast address:
...@@ -46,14 +75,14 @@ def anonymize_mac(mac: str) -> str: ...@@ -46,14 +75,14 @@ def anonymize_mac(mac: str) -> str:
## U/L bit: first byte, second least-significant bit ## U/L bit: first byte, second least-significant bit
# U/L bit = 0 ==> Universally administered address (UAA) # U/L bit = 0 ==> Universally administered address (UAA)
# U/L bit = 1 ==> Locally administered address (LAA) # U/L bit = 1 ==> Locally administered address (LAA)
ul_mask = 0b00000010 ul_bit = get_ul_bit(mac)
ul_bit = first_byte & ul_mask
is_local = bool(ul_bit) # True ==> LAA, False ==> UAA is_local = bool(ul_bit) # True ==> LAA, False ==> UAA
# Locally administered address # Locally administered address
if is_local: if is_local:
first_byte = (secrets.token_hex(1) & ig_bit) & ul_bit # Keep I/G and U/L bits bit_mask = ig_bit | ul_bit
return f"{first_byte:x}" + ':'.join(secrets.token_hex(1) for _ in range(5)) first_byte = (random.getrandbits(6) << 2) | bit_mask # Keep I/G and U/L bits
return f"{first_byte:02x}:" + ':'.join(secrets.token_hex(1) for _ in range(5))
# Universally administered address # Universally administered address
return ( return (
......
"""
Unit tests for the package `pcap-anonymize`.
"""
from pcap_anonymize.layers.mac import get_ig_bit, get_ul_bit, anonymize_mac
# Number of random MAC addresses to generate per unit test
N_TESTS = 5
### TEST FUNCTIONS ###
def test_get_ig_bit():
"""
Test the function `get_ig_bit`.
"""
assert get_ig_bit("00:00:00:00:00:00") == 0b00000000
assert get_ig_bit("01:00:00:00:00:00") == 0b00000001
assert get_ig_bit("12:34:56:78:9a:bc") == 0b00000000
def test_get_ul_bit():
"""
Test the function `get_ul_bit`.
"""
assert get_ul_bit("00:00:00:00:00:00") == 0b00000000
assert get_ul_bit("02:00:00:00:00:00") == 0b00000010
assert get_ul_bit("12:34:56:78:9a:bc") == 0b00000010
def test_anonymize_mac_multicast():
"""
Test the function `anonymize_mac`
with a multicast MAC address.
The MAC address should not be anonymized.
"""
mac_multicast = "01:00:00:00:00:00"
assert anonymize_mac(mac_multicast) == mac_multicast
def test_anonymize_mac_laa():
"""
Test the function `anonymize_mac`
with a locally administered MAC address.
All bits should be anonymized except the I/G and U/L bits.
"""
mac_laa = "02:00:00:00:00:00"
# Generate N anonymized MAC addresses,
# and verify they are correct
for _ in range(N_TESTS):
mac_laa_anon = anonymize_mac(mac_laa)
assert mac_laa_anon != mac_laa
# Verify I/G and U/L bits
assert get_ig_bit(mac_laa) == get_ig_bit(mac_laa_anon)
assert get_ul_bit(mac_laa) == get_ul_bit(mac_laa_anon)
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Terminez d'abord l'édition de ce message.
Veuillez vous inscrire ou vous pour commenter