#!/bin/bash # Copyright (c) 2003 Ole Craig , all rights # reserved. This software may be freely redistributed under the terms # of the GNU general public license. See (e.g.) # http://www.gnu.org/licenses/gpl.txt for details. Although it is not # required by the license terms, if you improve this script in any way # the author would deeply appreciate seeing (and perhaps learning # from) your changes. # we use this script because regular nameif doesn't handle the case # where we want to rename preexisting devices (e.g. swap eth0 <--> # eth1) and sometimes segfaults anyway. ME=`basename $0` dashs="" # we get our parameters from /etc/mactab unless otherwise specified CONFFILE=/etc/mactab function usage() { echo "usage: $ME [-c configurationfile] [-s] {ifname macaddress}" exit -1 } function loggit() { if [ "$dashs" == "" ]; then echo ${ME}[$$]: $* else logger -i -t $ME $* fi } function die() { loggit $* exit -1 } function namer() { # this is where we do the work on a given IF # expect 2 inputs: current name targetname err=`ip link set $1 name $2` status=$? if [ "$err" != "" ]; then $logger $err fi return $status } function isup() { # check to see if interface is active ip link show $1 2>&1 | cut -f3 -d" " | grep -qw UP return $? } # main body if [ ${#*} -gt 0 ]; then while [ ${#*} -gt 0 ]; do case $1 in -s) dashs="-s" shift ;; -c) if [ "$2" == "" -o ! -r $2 ]; then usage else CONFFILE=$2 shift shift fi ;; *) # we assume anything else is an interface name if [ "$2" == "" -o "$3" != "" ]; then usage else DES_IFNAME=$1 # attempt to sanitize input a bit DES_MAC=`echo $2 | tr 'a-f-' 'A-F:'` shift shift fi esac done i=0 BLOCKED=0 fi if [ "$DES_IFNAME" = "" ]; then if [ ! -r $CONFFILE ]; then die "can't read from $CONFFILE" fi # if we're processing a table (/etc/mactab by default) then we iterate # through... itab=0 for q in `cat $CONFFILE | sed 's/#.*$//g'`; do MACTABLE[$itab]=$q let itab++ done # ...and recurse for (( q=0 ; $q < $itab ; q++)); do $0 ${dashs} ${MACTABLE[((q++))]} ${MACTABLE[$q]} # note nasty increment of counter within loop. Ugh. done else # we were given an argument, use it # Build table of current IFs and their associated MAC addresses. While # we're at it, grab current values for IF name and IF/MAC of blocking # name, if any. If we only have one MAC address as input, then we # scan the table of available IFs for a match. If that MAC is # currently in use by another IF name, we swap. Otherwise, we just # name it. (Or leave it alone, as may be the case.) # DES_IFNAME is the desired name for the mac address supplied on commandline. i=0 GETMAC=0 for q in `ifconfig -a | grep -E ^eth\|^wlan | awk '{ print $1" "$5 }'`; do MACDESK[$i]=$q if [ "$GETMAC" != "0" ]; then CUR_MAC=$q GETMAC=0 fi if [ "$q" == "$DES_MAC" ]; then CUR_IFNAME=${MACDESK[$i-1]} fi if [ "$q" == "$DES_IFNAME" ]; then BLOCKED=1 GETMAC=1 fi let i++ done # CUR_IFNAME is the current name for the mac address supplied on commandline. # if $CUR_IFNAME is empty at this point, then we don't have an # interface with this MAC address if [ "$CUR_IFNAME" == "" ]; then die "no interface found with requested MAC address \"$DES_MAC\"" fi # swap "blocked" names isup $DES_IFNAME && die "$DES_IFNAME ($CUR_MAC) already active" isup $CUR_IFNAME && die "$CUR_IFNAME ($DES_MAC) already active" if [ "$CUR_IFNAME" == "$DES_IFNAME" ]; then exit 0 # everything's jake, current and desired IF names are the same fi if [ $BLOCKED == 1 ]; then namer $DES_IFNAME nameif_tmp$DES_IFNAME namer $CUR_IFNAME $DES_IFNAME namer nameif_tmp$DES_IFNAME $CUR_IFNAME else namer $CUR_IFNAME $DES_IFNAME fi fi