11
11
12
12
def is_valid_interface (interface ):
13
13
"""Check if the interface name is valid."""
14
- valid_prefixes = ['eth' , 'wlan' ]
14
+ valid_prefixes = ['eth' , 'wlan' , 'ens' ]
15
15
return any (interface .startswith (prefix ) for prefix in valid_prefixes ) and all (c in string .ascii_letters + string .digits + ':-.' for c in interface )
16
16
17
17
def configure_logging (verbose ):
@@ -21,11 +21,25 @@ def configure_logging(verbose):
21
21
return logging .getLogger (__name__ )
22
22
23
23
def interface_exists (interface , logger ):
24
- """Check if the network interface exists."""
24
+ """Check if the network interface exists using ifconfig or ip."""
25
+ ifconfig_command = ["ifconfig" , interface ]
26
+ ip_command = ["ip" , "link" , "show" , interface ]
27
+
25
28
try :
29
+ # Check if ifconfig is available
26
30
logger .debug (f"Checking if interface { interface } exists using 'ifconfig'" )
27
- subprocess .check_output ([ "ifconfig" , interface ] , stderr = subprocess .STDOUT )
31
+ subprocess .check_output (ifconfig_command , stderr = subprocess .STDOUT )
28
32
return True
33
+ except FileNotFoundError :
34
+ logger .debug ("'ifconfig' command not found, falling back to 'ip'" )
35
+ # If ifconfig is not available, check with ip
36
+ try :
37
+ logger .debug (f"Checking if interface { interface } exists using 'ip link'" )
38
+ subprocess .check_output (ip_command , stderr = subprocess .STDOUT )
39
+ return True
40
+ except subprocess .CalledProcessError :
41
+ logger .debug (f"Interface { interface } does not exist." )
42
+ return False
29
43
except subprocess .CalledProcessError :
30
44
logger .debug (f"Interface { interface } does not exist." )
31
45
return False
@@ -47,12 +61,26 @@ def is_valid_mac(mac_address, logger):
47
61
48
62
def get_current_mac (interface , logger ):
49
63
"""Retrieve the current MAC address of the specified interface."""
64
+ ifconfig_command = ["ifconfig" , interface ]
65
+ ip_command = ["ip" , "link" , "show" , interface ]
66
+
50
67
try :
68
+ # Try to get MAC address using ifconfig
51
69
logger .debug (f"Getting current MAC address for { interface } using 'ifconfig'" )
52
- ifconfig_result = subprocess .check_output (["ifconfig" , interface ]).decode ('utf-8' )
53
- mac_address_search_result = re .search (r"(\w\w:\w\w:\w\w:\w\w:\w\w:\w\w)" , ifconfig_result )
70
+ ifconfig_result = subprocess .check_output (ifconfig_command ).decode ('utf-8' )
71
+ mac_address_search_result = re .search (r"([0-9a-fA-F]{2}[:-]){5}[0-9a-fA-F]{2}" , ifconfig_result )
72
+ except FileNotFoundError :
73
+ logger .debug ("'ifconfig' command not found, falling back to 'ip link'" )
74
+ try :
75
+ # If ifconfig is not available, use ip link
76
+ logger .debug (f"Getting current MAC address for { interface } using 'ip link'" )
77
+ ip_result = subprocess .check_output (ip_command ).decode ('utf-8' )
78
+ mac_address_search_result = re .search (r"link/ether ([0-9a-fA-F]{2}[:-]){5}[0-9a-fA-F]{2}" , ip_result )
79
+ except subprocess .CalledProcessError as e :
80
+ logger .error (f"Could not retrieve MAC address using 'ip link': { e } " )
81
+ return None
54
82
except subprocess .CalledProcessError :
55
- logger .error (f"Could not retrieve MAC address for { interface } " )
83
+ logger .error (f"Could not retrieve MAC address using 'ifconfig' " )
56
84
return None
57
85
58
86
if mac_address_search_result :
@@ -74,35 +102,37 @@ def execute_commands(commands, logger):
74
102
logger .error (f"Command failed with error: { e } " )
75
103
raise # Re-raise the exception to stop execution if a command fails
76
104
77
- def bring_interface_down_and_up (interface , new_mac , logger ):
78
- """Bring the interface down, change MAC address, and bring it up."""
79
- commands = [
80
- ["sudo" , "ifconfig" , interface , "down" ],
81
- ["sudo" , "ifconfig" , interface , "hw" , "ether" , new_mac ],
82
- ["sudo" , "ifconfig" , interface , "up" ]
83
- ]
84
- execute_commands (commands , logger )
85
-
86
- def bring_interface_down_and_up_ip (interface , new_mac , logger ):
87
- """Bring the interface down, change MAC address, and bring it up using 'ip link'."""
88
- commands = [
89
- ["sudo" , "ip" , "link" , "set" , "dev" , interface , "down" ],
90
- ["sudo" , "ip" , "link" , "set" , "dev" , interface , "address" , new_mac ],
91
- ["sudo" , "ip" , "link" , "set" , "dev" , interface , "up" ]
92
- ]
105
+ def bring_interface_down_and_up (interface , new_mac , logger , use_ip = False ):
106
+ """Bring the interface down, change MAC address, and bring it up using either 'ifconfig' or 'ip link'."""
107
+ if use_ip :
108
+ commands = [
109
+ ["sudo" , "ip" , "link" , "set" , "dev" , interface , "down" ],
110
+ ["sudo" , "ip" , "link" , "set" , "dev" , interface , "address" , new_mac ],
111
+ ["sudo" , "ip" , "link" , "set" , "dev" , interface , "up" ]
112
+ ]
113
+ else :
114
+ commands = [
115
+ ["sudo" , "ifconfig" , interface , "down" ],
116
+ ["sudo" , "ifconfig" , interface , "hw" , "ether" , new_mac ],
117
+ ["sudo" , "ifconfig" , interface , "up" ]
118
+ ]
119
+
93
120
execute_commands (commands , logger )
94
121
95
122
def change_mac (interface , new_mac , logger ):
96
123
"""Change the MAC address of the specified interface."""
97
124
try :
98
125
logger .debug (f"Attempting to change MAC address for { interface } to { new_mac } using 'ifconfig'" )
99
- bring_interface_down_and_up (interface , new_mac , logger )
100
- logger .info (f"MAC address successfully changed to { new_mac } using 'ifconfig'" )
101
- return True
102
- except Exception :
103
- logger .warning (f"Failed to change MAC address using 'ifconfig'. Trying 'ip link'..." )
126
+ if subprocess .call (["which" , "ifconfig" ], stdout = subprocess .DEVNULL ) == 0 :
127
+ bring_interface_down_and_up (interface , new_mac , logger , use_ip = False )
128
+ logger .info (f"MAC address successfully changed to { new_mac } using 'ifconfig'" )
129
+ return True
130
+ else :
131
+ raise FileNotFoundError ("ifconfig not found" )
132
+ except FileNotFoundError :
133
+ logger .debug (f"Failed to change MAC address using 'ifconfig'. Trying 'ip link'..." )
104
134
try :
105
- bring_interface_down_and_up_ip (interface , new_mac , logger )
135
+ bring_interface_down_and_up (interface , new_mac , logger , use_ip = True )
106
136
logger .info (f"MAC address successfully changed to { new_mac } using 'ip link'" )
107
137
return True
108
138
except Exception as e :
@@ -113,6 +143,8 @@ def save_primary_mac_to_file(interface, primary_mac, logger):
113
143
"""Save the primary MAC address to a file."""
114
144
filename = f"{ interface } _primary_mac.txt"
115
145
try :
146
+ # Remove any prefix like 'link/ether' if present
147
+ primary_mac = primary_mac .split ()[- 1 ] if ' ' in primary_mac else primary_mac
116
148
with open (filename , 'w' ) as file :
117
149
file .write (primary_mac )
118
150
logger .info (f"Primary MAC address saved to file for { interface } : { primary_mac } " )
@@ -128,6 +160,8 @@ def read_primary_mac_from_file(interface, logger):
128
160
try :
129
161
with open (filename , 'r' ) as file :
130
162
primary_mac = file .read ().strip ()
163
+ # Ensure no prefix like 'link/ether' is present
164
+ primary_mac = primary_mac .split ()[- 1 ] if ' ' in primary_mac else primary_mac
131
165
logger .info (f"Primary MAC address read from file for { interface } " )
132
166
return primary_mac
133
167
except FileNotFoundError :
@@ -203,20 +237,41 @@ def cleanup(interface, primary_mac, anonsurf_started, mac_changed, verbose, logg
203
237
# Bring the interface back up if it was down
204
238
try :
205
239
logger .debug (f"Checking if interface { interface } is up." )
206
- ifconfig_result = subprocess .check_output (["ifconfig" , interface ]).decode ('utf-8' )
207
- if "UP" not in ifconfig_result :
208
- logger .info (f"Interface { interface } is down. Bringing it back up." )
209
- subprocess .run (["sudo" , "ifconfig" , interface , "up" ], check = True )
210
-
211
- # Compare the current MAC address with the primary MAC address
212
- current_mac = get_current_mac (interface , logger )
213
- if current_mac != primary_mac :
214
- logger .info (f"Current MAC address ({ current_mac } ) does not match primary MAC address ({ primary_mac } ). Restoring primary MAC address." )
215
- if not set_primary_mac (interface , primary_mac , logger ):
216
- logger .error ("Failed to restore the primary MAC address." )
217
- else :
218
- logger .debug (f"Current MAC address matches the primary MAC address ({ primary_mac } )." )
240
+ ip_command = ["ip" , "link" , "show" , interface ]
241
+ ifconfig_command = ["ifconfig" , interface ]
242
+
243
+ try :
244
+ ifconfig_result = subprocess .check_output (ifconfig_command ).decode ('utf-8' )
245
+ if "UP" not in ifconfig_result :
246
+ logger .info (f"Interface { interface } is down. Bringing it back up." )
247
+ subprocess .run (["sudo" , "ifconfig" , interface , "up" ], check = True )
248
+ except FileNotFoundError :
249
+ logger .debug ("'ifconfig' command not found, falling back to 'ip link'" )
250
+ ip_result = subprocess .check_output (ip_command ).decode ('utf-8' )
251
+ if "state UP" not in ip_result :
252
+ logger .info (f"Interface { interface } is down. Bringing it back up." )
253
+ subprocess .run (["sudo" , "ip" , "link" , "set" , "dev" , interface , "up" ], check = True )
254
+
255
+ # Recheck if the primary MAC address file exists
256
+ primary_mac_file = f"{ interface } _primary_mac.txt"
257
+ if os .path .isfile (primary_mac_file ):
258
+ logger .info ("Primary MAC address file found. Attempting to restore MAC address." )
259
+
260
+ # Read the primary MAC address from the file
261
+ with open (primary_mac_file , 'r' ) as f :
262
+ primary_mac = f .read ().strip ()
219
263
264
+ # Compare the current MAC address with the primary MAC address
265
+ current_mac = get_current_mac (interface , logger )
266
+ if current_mac and current_mac != primary_mac :
267
+ logger .info (f"Current MAC address ({ current_mac } ) does not match primary MAC address ({ primary_mac } ). Restoring primary MAC address." )
268
+ if not set_primary_mac (interface , primary_mac , logger ):
269
+ logger .error ("Failed to restore the primary MAC address." )
270
+ else :
271
+ logger .info ("Current MAC address matches the primary MAC address or MAC address is not changed." )
272
+ else :
273
+ logger .error (f"Primary MAC address file not found for { interface } . Cannot restore the MAC address." )
274
+
220
275
except subprocess .CalledProcessError as e :
221
276
logger .error (f"Failed to check or bring up interface { interface } : { e } " )
222
277
0 commit comments