macOS Sonoma 14.4 broke macchanger, and ifconfig!? wtfh
I already submitted Feedback to Apple, but figured I would report things here too in case someone may discover a workaround.
macchanger worked without issues on macOS 14.3.1.
After updating to 14.4:
% sudo macchanger -r en0
Password:
INFO: Type of interface is Wi-Fi. Will disassociate from any network.
WARNING: The airport command line tool is deprecated and will be removed in a future release.
For diagnosing Wi-Fi related issues, use the Wireless Diagnostics app or wdutil command line tool.
ERROR: This device / interface has no MAC address to set.
Worse, this doesn't seem to be unique to macchanger; ifconfig seems broken on macOS 14.4 Sonoma as well:
sudo ifconfig en0 ether 10:93:e8:37:38:39
ifconfig: ioctl (SIOCAIFADDR): Can't assign requested address
adomino@MBAm2starhikari ~ % sudo ifconfig en0 ether de:ad:be:ef:de:ad
ifconfig: ioctl (SIOCAIFADDR): Can't assign requested address
Tested as broken on two Apple Silicon devices which previously functioned OK with macchanger on 14.3.1.
Thanks for reporting this issue! I just upgraded to Sonoma 14.4.1 and can confirm the issue.
This appears to be a problem with the airport command line tool as it doesn't disassociate from the network. You can manually disconnect from the Wi-Fi network and then run macchanger which works.
I tried to find an alternative to the airport command and came up with the following snippet that imitates IO80211.framework. Some information can also be found here.
It would be great if you could test if this code correctly performs disassociation from Wi-Fi. If you have access to older versions of macOS it would also be great to have a positive sign that they are working there.
The below code can be compiled using clang -o disassoc ./disassoc.c.
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
int main(int argc, char** argv) {
int fd = socket(AF_INET, SOCK_DGRAM, 0);
struct io80211_ioctl {
char ifname[16];
uint64_t type;
uint32_t length;
void* data;
} ioc;
strcpy(ioc.ifname, "en0");
ioc.type = 22;
ioc.length = 0;
ioc.data = NULL;
int res = ioctl(fd, 0x802869c8, &ioc);
if(res == -1) {
perror("ioctl");
return res;
}
return 0;
}
Genius, how did you even pull this? Works now !
Genius, how did you even pull this? Works now !
Great to hear that, @DarkNero69. Do you have the possibility to test the code on an older system?
Genius, how did you even pull this? Works now !
Great to hear that, @DarkNero69. Do you have the possibility to test the code on an older system?
Hey, sorry for the delayed reply. Unfortunately i don't have another computer or any other system. I only got macbook air m1 :/ but this can easily be tested in public computers, though i don't have the time to hit up library at the moment haha
@shilch The fix is tested to be working on my MBP 13-inch, 2020 running i5.
Be sure to run it with sudo though.
Thanks @aaronleetw, @DarkNero69!
I developed a new version that supports macOS Sonoma 14.4+ on branch v0.2-draft.
Please let me know if the new version does the job:
git clone -b v0.2-draft https://github.com/shilch/macchanger
cd macchanger
make
./macchanger
@shilch Works on my end! Thank you for your work.
@shilch It works for me too! I'm not very experienced with the terminal, but I managed to get it working hehe. Amazing work, thank you! It's much simpler and faster to use now =)
Thanks @aaronleetw, @DarkNero69!
I developed a new version that supports macOS Sonoma 14.4+ on branch
v0.2-draft.Please let me know if the new version does the job:
git clone -b v0.2-draft https://github.com/shilch/macchanger cd macchanger make ./macchanger
Thank you!
I've tested the new v0.2-draft branch on 14.3.1, 14.4 and 14.4.1 and it is functioning OK.
Attempting to build on OS X El Capitan 10.11.6 yields the following errors:
make macchanger.c:39:51: error: unknown type name 'ether_addr_t'; did you mean 'user_addr_t'? void interface_get_ether(const interface_t iface, ether_addr_t* ether); ^~~~~~~~~~~~ user_addr_t /usr/include/i386/types.h:97:20: note: 'user_addr_t' declared here typedef u_int64_t user_addr_t; ^ macchanger.c:40:51: error: unknown type name 'ether_addr_t'; did you mean 'user_addr_t'? void interface_set_ether(interface_t iface, const ether_addr_t* ether); ^~~~~~~~~~~~ user_addr_t /usr/include/i386/types.h:97:20: note: 'user_addr_t' declared here typedef u_int64_t user_addr_t; ^ macchanger.c:41:61: error: unknown type name 'ether_addr_t'; did you mean 'user_addr_t'? void interface_get_permanent_ether(const interface_t iface, ether_addr_t* eth... ^~~~~~~~~~~~ user_addr_t /usr/include/i386/types.h:97:20: note: 'user_addr_t' declared here typedef u_int64_t user_addr_t; ^ macchanger.c:48:42: error: unknown type name 'ether_addr_t'; did you mean 'user_addr_t'? void change_mac(interface_t iface, const ether_addr_t* ether); ^~~~~~~~~~~~ user_addr_t /usr/include/i386/types.h:97:20: note: 'user_addr_t' declared here typedef u_int64_t user_addr_t; ^ macchanger.c:50:19: error: unknown type name 'ether_addr_t'; did you mean 'user_addr_t'? void random_ether(ether_addr_t* ether); ^~~~~~~~~~~~ user_addr_t /usr/include/i386/types.h:97:20: note: 'user_addr_t' declared here typedef u_int64_t user_addr_t; ^ macchanger.c:51:34: error: unknown type name 'ether_addr_t'; did you mean 'user_addr_t'? int ether_parse(const char* str, ether_addr_t* ether); ^~~~~~~~~~~~ user_addr_t /usr/include/i386/types.h:97:20: note: 'user_addr_t' declared here typedef u_int64_t user_addr_t; ^ macchanger.c:52:35: error: unknown type name 'ether_addr_t'; did you mean 'user_addr_t'? const char* ether_to_string(const ether_addr_t* ether); ^~~~~~~~~~~~ user_addr_t /usr/include/i386/types.h:97:20: note: 'user_addr_t' declared here typedef u_int64_t user_addr_t; ^ macchanger.c:65:5: error: unknown type name 'ether_addr_t'; did you mean 'user_addr_t'? ether_addr_t ether; ^~~~~~~~~~~~ user_addr_t /usr/include/i386/types.h:97:20: note: 'user_addr_t' declared here typedef u_int64_t user_addr_t; ^ macchanger.c:155:5: error: unknown type name 'ether_addr_t'; did you mean 'user_addr_t'? ether_addr_t ether, permanent_ether; ^~~~~~~~~~~~ user_addr_t /usr/include/i386/types.h:97:20: note: 'user_addr_t' declared here typedef u_int64_t user_addr_t; ^ macchanger.c:164:48: error: unknown type name 'ether_addr_t'; did you mean 'user_addr_t'? void change_mac(const interface_t iface, const ether_addr_t* new_ether) { ^~~~~~~~~~~~ user_addr_t /usr/include/i386/types.h:97:20: note: 'user_addr_t' declared here typedef u_int64_t user_addr_t; ^ macchanger.c:165:5: error: unknown type name 'ether_addr_t'; did you mean 'user_addr_t'? ether_addr_t permanent_ether, old_ether, current_ether; ^~~~~~~~~~~~ user_addr_t /usr/include/i386/types.h:97:20: note: 'user_addr_t' declared here typedef u_int64_t user_addr_t; ^ macchanger.c:167:18: error: member reference base type 'const user_addr_t' (aka 'const unsigned long long') is not a structure or union if (new_ether->octet[0] & 1) { ~~~~~~~~~^ ~~~~~ macchanger.c:194:19: error: unknown type name 'ether_addr_t'; did you mean 'user_addr_t'? void random_ether(ether_addr_t* ether) { ^~~~~~~~~~~~ user_addr_t /usr/include/i386/types.h:97:20: note: 'user_addr_t' declared here typedef u_int64_t user_addr_t; ^ macchanger.c:204:35: error: member reference base type 'user_addr_t' (aka 'unsigned long long') is not a structure or union ssize_t n = read(fd, ether->octet + (ETHER_ADDR_LEN - to_read), ... ~~~~~^ ~~~~~ macchanger.c:213:10: error: member reference base type 'user_addr_t' (aka 'unsigned long long') is not a structure or union ether->octet[0] &= 0xFE; ~~~~~^ ~~~~~ macchanger.c:219:34: error: unknown type name 'ether_addr_t'; did you mean 'user_addr_t'? int ether_parse(const char* str, ether_addr_t* ether) { ^~~~~~~~~~~~ user_addr_t /usr/include/i386/types.h:97:20: note: 'user_addr_t' declared here typedef u_int64_t user_addr_t; ^ macchanger.c:226:14: error: member reference base type 'user_addr_t' (aka 'unsigned long long') is not a structure or union ether->octet[i] = 0; ~~~~~^ ~~~~~ macchanger.c:228:18: error: member reference base type 'user_addr_t' (aka 'unsigned long long') is not a structure or union ether->octet[i] <<= 4; ~~~~~^ ~~~~~ macchanger.c:230:45: error: member reference base type 'user_addr_t' (aka 'unsigned long long') is not a structure or union if(ch >= '0' && ch <= '9') ether->octet[i] |= (ch - '0'); ~~~~~^ ~~~~~ fatal error: too many errors emitted, stopping now [-ferror-limit=] 20 errors generated. make: *** [macchanger] Error 1
However, the previous macchanger.sh functions OK on El Capitan 10.11.6.
I also noticed that on macOS versions with the v0.2-draft branch, when invoked without root privileges, it will fail to change the MAC address (expected behavior) but it will still disassociate from WiFi (I am not sure if this is desirable?).
@shilch Hi there, the branch v0.2-draft didn't work on my macOS(Sonoma 14.4.1).
sudo ./macchanger -r en0
INFO: Type of interface is Wi-Fi. Will disassociate from any network.
interface_set_ether: Can't assign requested address
Thank you for this. It works with the wifi adapter on my M2 Macbook Air, Sonoma 14.5. But, it does not work with my Belkin USB-C ethernet adapter, i get the error message "interface_set_ether: Can't assign requested address". Any leads?
Hello. Sorry i haven't been replied to anything yet. First of all, thank you so much for developing such an amazing thing!
I haven't changed my mac address lately, but i just tested it by typing "sudo macchanger" to terminal. It seems like it works, managed to change to some random mac address. Thanks!
Sorry for not responding in a while.
@artkiver The compilation error occurs because the ether_addr_t did not exist in El Capitan. That should be an easy fix which I will add.
@geek4what Which device are you using? Is the en0 an Airport device?
@nilssonalex The tool uses the interface APIs provided by the operating system. If the network driver for this 3rd party device does not implement the possibility to change the mac address, there's nothing that macchanger can do. You would need a driver which has this feature.
The v0.2-draft is also working for me, thanks!
Sorry for not responding in a while.
@geek4what Which device are you using? Is the en0 an Airport device?
wifi en0. By the way, after upgrade to 14.5, it's work like a charm.
For wifi this works great. However, if I try to change the mac address of a wired network, I still get the following error: sh-3.2# ./macchanger -m [mac] en17 interface_set_ether: Can't assign requested address
I use 14.5. The interface is listed as a USB 10/100/1000 device.
@shilch Hi there, the branch v0.2-draft didn't work on my macOS(Sonoma 14.4.1).
sudo ./macchanger -r en0 INFO: Type of interface is Wi-Fi. Will disassociate from any network. interface_set_ether: Can't assign requested address
It's because macchanger can't disassociate from the wifi network. Disconnect from wifi yourself, then run macchanger and it will work. Tested on M1 Max MBP running macOS 15 Sequoia beta
I tried to find an alternative to the
airportcommand and came up with the following snippet that imitatesIO80211.framework. Some information can also be found here.It would be great if you could test if this code correctly performs disassociation from Wi-Fi. If you have access to older versions of macOS it would also be great to have a positive sign that they are working there.
The below code can be compiled using
clang -o disassoc ./disassoc.c.#include <stdint.h> #include <stdio.h> #include <string.h> #include <sys/ioctl.h> #include <sys/socket.h> int main(int argc, char** argv) { int fd = socket(AF_INET, SOCK_DGRAM, 0); struct io80211_ioctl { char ifname[16]; uint64_t type; uint32_t length; void* data; } ioc; strcpy(ioc.ifname, "en0"); ioc.type = 22; ioc.length = 0; ioc.data = NULL; int res = ioctl(fd, 0x802869c8, &ioc); if(res == -1) { perror("ioctl"); return res; } return 0; }
Sadly this didn't work for me in macOS 15 beta (I never tried on macOS 14)
v0.2-draft, Macbook Pro 16 2021 M1 Pro
works fine for wifi en0, but for en4
sudo ./macchanger -r en4
interface_set_ether: Can't assign requested address
USB 10/100/1000 LAN:
Bus: USB Vendor Name: Realtek Product Name: USB 10/100/1000 LAN Vendor ID: 0x0bda Product ID: 0x8153 USB Link Speed: Up to 5 Gb/s Driver: com.apple.DriverKit.AppleUserECM BSD Device Name: en4 MAC Address: 00:e0:4c:cc:3f:7d AVB Support: No
Just so I can understand correctly, with nothing plugged into your Mac (no hardwire internet connections, or network adapters), you can run sudo./macchanger -r en0 while the MacBook is connected to a wireless network? Meaning it disassociates, changes the MAC address, and then reconnects?
Thanks
Just so I can understand correctly, with nothing plugged into your Mac (no hardwire internet connections, or network adapters), you can run
sudo./macchanger -r en0while the MacBook is connected to a wireless network? Meaning it disassociates, changes the MAC address, and then reconnects?Thanks
Meaning, I just reconnected my wifi using new mac address. But it doesn't work for my type-c ethernet adapter :(
Were you connected to wifi on en0 before you ran the command? And what does it show you when you run en4?
@johndekroon @dennis777 @ASolod82 Thanks for your tests!
Can you please check if it works / there are errors for the following cases:
- Using the v0.2-draft version
- Using the master version but disassociating using this snippet
- Using the master version but disassociating using the macOS UI
Certainly! Here are the results tested on my 21 MacBook Pro M1 Max macOS 15.0 beta (shouldn't be any different for 14 as airport is deprecated there as well)
Using the v0.2-draft version
Result: Does not disassociate from wifi, thus not changing the Mac address
Manually disassociating, works just fine
Using the master version but disassociating using this snippet
Result: does not disassociate but prints a message
ioctl: Operation not supported on socket
So then as expected, the macchanger doesn't work because it doesn't disassociate using that snippet
seems like ioctl() call isn't working in disassoc.c
Using the master version but disassociating using the macOS UI
Result: Works perfectly fine
Hope this helps! Let me know if theres anything else I can test @shilch
Thanks @dennis777, I guess that Apple changed the interface to disassociate WiFi in one of the recent versions ("Operation not supported on socket" hints at an API change).
I am currently using 14.4.1 on M1 Pro and v0.2-draft works for me. User @geek4what had issues on 14.4.1 but upgrading to 14.5 fixed it, apparently. I assume that issue affects macOS 15.0+.
The solution could be to implement the disassociation using IOKit instead of ioctl. The headers have been leaked here. Once I'm less busy with university, I'll have a look at it.
Ah okay I didn't know about this tool until after I updated to the beta.
I will play around with those dumped headers and see if I can come up with anything in the meantime. But my experience with C is extremely limited. I wish I understood it better 😅 Thank you
The v0.2-draft version worked fine. I am on 14.5 (Macbook Air)
Is it possible to make it installable by brew?
Also the git clone https://github.com/shilch/macchanger command in the readme does not clone the v0.2-draft.. You should adjust it to git clone -b v0.2-draft https://github.com/shilch/macchanger
The
v0.2-draftversion worked fine.
Which model of Mac do you use and what version of macOS?