Hi I made bash script to put down my interface, change MAC address and get it up again.
#!/bin/bash
INTERFACE_STATUS=$( cat /sys/class/net/eth0/operstate )
echo "$INTERFACE_STATUS"
if [ "$INTERFACE_STATUS" == "up" ]
then
echo "Putting down eth0"
sudo ifconfig eth0 down
# putting down eth0 works only when I sleep 10 seconds after using command
#sleep 10
echo "$( cat /sys/class/net/eth0/operstate )"
# TRIES=0
# while [ "$( cat /sys/class/net/eth0/operstate )" == "up" ]
# do
# sleep 1
# TRIES=$(($TRIES + 1))
# if [ "$TRIES" == "7" ]
# then
# echo Could not put down eth0
# exit 1
# fi
# done
fi
sudo ifconfig eth0 hw ether "91:91:91:91:91:91"
sudo ifconfig eth0 up
The problem is that it does not work. Immediately after putting down eth0 /sys/class/net/eth0/operstate
changes to down
but it seems like it isn't down yet. I takes like 10 seconds to put down interface eth0 so only way to make it work is to add sleep 10
after putting down eth0.
So my question is how to check if eht0 is really down?
//EDIT
It's like command ifconfig eth0 up
is used to early because it never gets up with new MAC address. I need to put it down, wait 10 s, change MAC and put it back again. I suspect that putting down eth0 takes few seconds and putting it up again too early does not work.
//EDIT 2
I checked MAC address again and it seems that it's changed, so now I think that it could be something with DNS because when I'm using ping on google I get unknown host. But same method with sleep 10
does work.
// EDIT 3
After using script without sleep 10
I tried using ping:
piotrek@piotrek-Vostro-2520:~$ ping 212.77.100.101
connect: Network is unreachable
piotrek@piotrek-Vostro-2520:~$ ping -n 212.77.100.101
connect: Network is unreachable
piotrek@piotrek-Vostro-2520:~$ ifconfig
eth0 Link encap:Ethernet HWaddr 08:3e:8e:2d:36:55
inet addr:10.36.253.122 Bcast:10.36.253.255 Mask:255.255.255.0
inet6 addr: fe80::a3e:8eff:fe2d:3655/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:74297 errors:0 dropped:0 overruns:0 frame:0
TX packets:38597 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:32417366 (32.4 MB) TX bytes:5201537 (5.2 MB)0
collisions:0 txqueuelen:1000
RX bytes:32417366 (32.4 MB) TX bytes:5201537 (5.2 MB)
//EDIT 4 SUM UP
piotrek@piotrek-Vostro-2520:~$ sudo ifconfig eth0 down; sudo ifconfig eth0 hw ether 08:3e:8e:2d:36:55 ; sudo ifconfig eth0 up
piotrek@piotrek-Vostro-2520:~$ ping -n 212.77.100.101
connect: Network is unreachable
piotrek@piotrek-Vostro-2520:~$ sudo ifconfig eth0 down; sleep 10; sudo ifconfig eth0 hw ether 08:3e:8e:2d:36:55 ; sudo ifconfig eth0 up
piotrek@piotrek-Vostro-2520:~$ ping -n 212.77.100.101
PING 212.77.100.101 (212.77.100.101) 56(84) bytes of data.
64 bytes from 212.77.100.101: icmp_req=1 ttl=246 time=8.91 ms
64 bytes from 212.77.100.101: icmp_req=2 ttl=246 time=8.76 ms
64 bytes from 212.77.100.101: icmp_req=3 ttl=246 time=8.52 ms
^C
--- 212.77.100.101 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 8.523/8.734/8.917/0.194 ms
Why sleep 10
matters?
// EDIT 5
Its getting quite weird. When I use sleep
it works fine. When I try without sleep
it looks like IP is ok, interface is up, but network does not work. When I try put down eth0
with sudo ifconfig eth0 down
after few seconds my OS (ubuntu 12.10) reconects me automaticly with my old MAC address and I get new IP. With second use of sudo ifconfig eth0 down
I'm able to fully put down eth0
.
piotrek@piotrek-Vostro-2520:~$ sudo ifconfig eth0 down; sleep 10; sudo ifconfig eth0 hw ether 08:3e:8e:2d:36:55 ; sudo ifconfig eth0 up
piotrek@piotrek-Vostro-2520:~$ sudo ifconfig
eth0 Link encap:Ethernet HWaddr 08:3e:8e:2d:36:55
inet addr:10.36.253.241 Bcast:10.36.253.255 Mask:255.255.255.0
inet6 addr: fe80::a3e:8eff:fe2d:3655/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:439341 errors:0 dropped:0 overruns:0 frame:0
TX packets:224187 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:400718780 (400.7 MB) TX bytes:26246307 (26.2 MB)
piotrek@piotrek-Vostro-2520:~$ sudo ifconfig eth0 down; sudo ifconfig eth0 hw ether 08:3e:8e:2d:36:55 ; sudo ifconfig eth0 up
piotrek@piotrek-Vostro-2520:~$ ping -n 212.77.100.101
connect: Network is unreachable
piotrek@piotrek-Vostro-2520:~$ ifconfig
eth0 Link encap:Ethernet HWaddr 08:3e:8e:2d:36:55
inet addr:10.36.253.241 Bcast:10.36.253.255 Mask:255.255.255.0
inet6 addr: fe80::a3e:8eff:fe2d:3655/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:439656 errors:0 dropped:0 overruns:0 frame:0
TX packets:224321 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:400827185 (400.8 MB) TX bytes:26267012 (26.2 MB)
piotrek@piotrek-Vostro-2520:~$ sudo ifconfig eth0 down
piotrek@piotrek-Vostro-2520:~$ ifconfig
eth0 Link encap:Ethernet HWaddr e0:db:55:97:de:cc
inet addr:10.36.253.122 Bcast:10.36.253.255 Mask:255.255.255.0
inet6 addr: fe80::e2db:55ff:fe97:decc/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:440302 errors:0 dropped:0 overruns:0 frame:0
TX packets:224862 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:401129508 (401.1 MB) TX bytes:26323176 (26.3 MB)
piotrek@piotrek-Vostro-2520:~$ sudo ifconfig eth0 down
piotrek@piotrek-Vostro-2520:~$ ifconfig eth0
eth0 Link encap:Ethernet HWaddr e0:db:55:97:de:cc
BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:440437 errors:0 dropped:0 overruns:0 frame:0
TX packets:224881 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:401147424 (401.1 MB) TX bytes:26326068 (26.3 MB)
//EDIT 6
I've tried solution suggested by @Moreaki but the same thing happens. Script runs around one second but my network is unreachable after using it. This is the code from @Moreaki:
#!/usr/bin/env bash
INTF=eth0
INTERFACE_STATUS=$(cat /sys/class/net/${INTF}/operstate)
echo "$INTERFACE_STATUS"
if [ "$INTERFACE_STATUS" == "up" ]; then
echo "Putting down ${INTF}"
# if you need to remove all IP addresses associated with ${INTF}
sudo ip addr flush dev ${INTF}
# set the interface status down
sudo ip link set dev ${INTF} down
# flush neighbour cache
sudo ip neigh flush dev ${INTF}
# flush routing cache entries pertaining to ${INTF}
sudo ip route flush table cache dev ${INTF}
echo "New state: $(cat /sys/class/net/${INTF}/operstate)"
fi
sudo ip link set dev ${INTF} address "08:3e:8e:2d:36:55"
sudo ip link set dev ${INTF} up
After using it I get:
piotrek@piotrek-Vostro-2520:~$ ./mac_test.sh
up
Putting down eth0
New state: down
And after trying ping:
piotrek@piotrek-Vostro-2520:~$ ping google.com
ping: unknown host google.com
piotrek@piotrek-Vostro-2520:~$ ping 8.8.8.8
connect: Network is unreachable
//EDIT 7
Using routing script from @Moreaki my routing before changing mac address looks like this:
piotrek@piotrek-Vostro-2520:~$ ./routing.sh
Destination Gateway Source Iface R_Type RT_table
default 10.36.253.1 10.36.253.122 eth0 main
10.36.253.0/24 0.0.0.0 10.36.253.122 eth0 main
169.254.0.0/16 0.0.0.0 10.36.253.122 eth0 main
And after changing MAC address using my script with 10s delay:
piotrek@piotrek-Vostro-2520:~$ ./routing.sh
Destination Gateway Source Iface R_Type RT_table
default 10.36.253.1 10.36.253.241 eth0 main
10.36.253.0/24 0.0.0.0 10.36.253.241 eth0 main
169.254.0.0/16 0.0.0.0 10.36.253.241 eth0 main
Routing after using @Moreaki script:
piotrek@piotrek-Vostro-2520:~$ ./routing.sh
Destination Gateway Source Iface R_Type RT_table
@Moreaki also suggested to comment line sudo ip addr flush dev ${INTF}
but I still get connect: Network is unreachable
. My routing after using his script with commented line looks like this:
piotrek@piotrek-Vostro-2520:~$ ./routing.sh
Destination Gateway Source Iface R_Type RT_table
10.36.253.0/24 0.0.0.0 10.36.253.122 eth0
ifconfig eth0 down
almost certainly makes a call to the kernel to effect the change, and sysfs reads the internal kernel data structures, so I don't see how sysfs could report the interface being down when it really is not. Maybe you are referring to something related but different?ifconfig eth0 up
is used to early because it never gets up with new MAC address. I need to put it down, wait 10 s, change MAC and put it back again. See my edited postifconfig eth0 down
,ifconfig eth0 hw ether ...
,ifconfig eth0 up
with no intervening delays not change the MAC address on eth0, when adding a delay betweendown
andether
does?", correct?grep -q "up" /sys/class/net/eth0/operstate && sudo ifdown eth0
This is a more accurate way of doing checks in bash. Also useifdown eth0
instead. This uses ifconfig to configure the interfaces.