#!/bin/bash
PATH=/sbin:/usr/sbin:/bin:/usr/bin
TEXTDOMAIN=initscripts

. /etc/init.d/functions

cd /etc/sysconfig/network-scripts
. ../network
. network-functions

if [ "$DHCP_HOSTNAME" ] && [ "$DOMAINNAME" ]
then
	DHCP_HOSTNAME=`echo $DHCP_HOSTNAME | sed -e "s/\.$DOMAINNAME//g"`
fi

CONFIG=${1}

[ -z "${CONFIG}" ] && {
    echo $"usage: ifup <device name>" >&2
    exit 1
}

need_config ${CONFIG}

[ -f "${CONFIG}" ] || {
    echo $"$0: configuration for ${1} not found." >&2
    echo $"Usage: ifup <device name>" >&2
    exit 1
}

if [ ${UID} != 0 ]; then
    if [ -x /usr/sbin/usernetctl ]; then
	if /usr/sbin/usernetctl ${CONFIG} report ; then
	    exec /usr/sbin/usernetctl ${CONFIG} up
	fi
    fi
    echo $"Users cannot control this device." >&2
    exit 1
fi

source_config

if [ "foo$2" = "fooboot" -a "${ONBOOT}" = "no" -o "${ONBOOT}" = "NO" ]
then
    exit 0
fi
if [ -n "$IN_HOTPLUG" -a "${HOTPLUG}" = "no" -o "${HOTPLUG}" = "NO" ]
then
    exit 0
fi

DEVICETYPE=`echo ${DEVICE} | sed "s/[0-9]*$//"`
[ -z "$REALDEVICE" ] && REALDEVICE=`echo ${DEVICE} | sed 's/:.*//g'`
if echo ${DEVICE} | grep -q ':' ; then
    ISALIAS=yes
else
    ISALIAS=no
fi

if [ -x /sbin/vconfig -a "${VLAN}" = "yes" ]; then
    # 802.1q VLAN
    if echo ${DEVICE} | LANG=C egrep -v '(:)' | LANG=C egrep -q 'eth[0-9][0-9]*\.[0-9][0-9]?[0-9]?[0-9]?' ; then
	[ -d /proc/net/vlan ] || modprobe 8021q >/dev/null 2>&1 || {
	    echo $"No 802.1Q VLAN support available in kernel."
	    echo $"Error initializing device ${DEVICE}"
	    logger -p daemon.info -t ifup \
		$"No 802.1Q VLAN support available in kernel for device ${DEVICE}"
	    exit 1
	}

	VID="`echo ${DEVICE} | \
	    LANG=C egrep 'eth[0-9]+\.[0-9][0-9]?[0-9]?[0-9]?$' | \
	    LANG=C sed 's/^[a-z0-9]*\.//g;s/^0*//'`"
	PHYSDEV="`echo ${DEVICE} | \
	    LANG=C egrep 'eth[0-9]+\.[0-9][0-9]?[0-9]?[0-9]?$' | \
	    LANG=C sed 's/\.[a-z0-9]*$//g'`"

	is_available ${PHYSDEV} || {
	    if [ "$?" = "1" ] ; then
		echo $"$alias device ${DEVICE} does not seem to be present, delaying initialization."
		exit 1
	    else
		exit 0
	    fi
	}

	# Link on Physical device needs to be up but no ip required
	ip addr add 0.0.0.0/32 dev ${PHYSDEV}
	ip -o link set dev ${PHYSDEV} up

	if [ ! -f /proc/net/vlan/${DEVICE} ]; then
	    /sbin/vconfig add ${PHYSDEV} ${VID} || {
		(logger -p daemon.info -t ifup \
		    $"ERROR: could not add vlan ${VID} as ${DEVICE} on dev ${PHYSDEV}" &)&
		echo $"ERROR: could not add vlan ${VID} as ${DEVICE} on dev ${PHYSDEV}"
		exit 1
	    }
	fi

	if [ -f /proc/net/vlan/${DEVICE} ]; then
	    case "$REORDER_HDR" in
		yes|1)
		    /sbin/vconfig set_flag ${DEVICE} 1 1 || {
			(logger -p daemon.info -t ifup \
			    "WARNING: vconfig not able to enable REORDER_HDR on ${DEVICE}" &)&
		    }
		    ;;
		no|0)
		    /sbin/vconfig set_flag ${DEVICE} 1 0 || {
			(logger -p daemon.info -t ifup \
			    $"WARNING: vconfig not able to disable REORDER_HDR on ${DEVICE}" &)&
		    }
		    ;;
	    esac
	fi
    fi
fi

# Old BOOTP variable
if [ "${BOOTP}" = "yes" ]; then
    BOOTPROTO=bootp
fi

if [ "${BOOTPROTO}" = "bootp" -o "${BOOTPROTO}" = "dhcp" ]; then
    DYNCONFIG=true
    [ "${BOOTPROTO}" = bootp ] && DHCP_CLIENT=/sbin/pump
fi

if [ -x /sbin/ifup-pre-local ]; then
    /sbin/ifup-pre-local ${DEVICE}
fi

OTHERSCRIPT="/etc/sysconfig/network-scripts/ifup-${DEVICETYPE}"

if [ -x ${OTHERSCRIPT} ]; then
    exec ${OTHERSCRIPT} ${CONFIG} $2
fi

is_available ${REALDEVICE} || {
      if [ "$?" = "1" ] ; then
         echo $"$alias device ${DEVICE} does not seem to be present, delaying initialization."
         exit 1
      else
         exit 0
      fi
}
if [ -n "${HWADDR}" ]; then
    FOUNDMACADDR=`LC_ALL= LANG= ip -o link show ${REALDEVICE} | \
	sed 's/.*link\/ether \([[:alnum:]:]*\).*/\1/'`
    if [ "${FOUNDMACADDR}" != "${HWADDR}" ]; then
        NEWCONFIG=`fgrep -l "HWADDR=${FOUNDMACADDR}" /etc/sysconfig/network-scripts/ifcfg-*|head -1`
	rm -f /etc/sysconfig/networking/tmp/ifcfg-$DEVICE
	if [ -n "${NEWCONFIG}" ]; then
	    NEWSCRIPT=/etc/sysconfig/networking/tmp/ifcfg-$DEVICE
	    sed -e "s/^DEVICE=.*/DEVICE=$DEVICE/" < ${NEWCONFIG} > $NEWSCRIPT
	   exec /sbin/ifup ${NEWSCRIPT}
	fi
        NEWCONFIG=`fgrep -l "HWADDR=${FOUNDMACADDR}" /etc/sysconfig/networking/default/ifcfg-*|head -1`
	if [ -n "${NEWCONFIG}" ]; then
	    NEWSCRIPT=/etc/sysconfig/networking/tmp/ifcfg-$DEVICE
	    sed -e "s/^DEVICE=.*/DEVICE=$DEVICE/" < ${NEWCONFIG} > $NEWSCRIPT
	   exec /sbin/ifup ${NEWSCRIPT}
	else
        /sbin/nameif "${REALDEVICE}" "${HWADDR}" || {
	   echo $"Device ${DEVICE} has different MAC address than expected, ignoring."
	   exit 1
	}
	fi
    fi
fi

# is the device wireless? If so, configure wireless device specifics
IS_WIRELESS=
if is_wireless_device ${DEVICE}; then
    . ./ifup-wireless
    IS_WIRELESS=1
fi

# slave device?
if [ "${SLAVE}" = yes -a "${ISALIAS}" = no -a "${MASTER}" != "" -a \
     -x /sbin/ifenslave ]; then
    RFLAG="" ; [ "${RECEIVEONLY}" = yes ] && RFLAG="-r"

    /sbin/ip link set ${DEVICE} down
    echo $"Enslaving ${DEVICE} to ${MASTER}"
    ifenslave ${RFLAG} "${MASTER}" "${DEVICE}"

    exit 0
fi

# Now, run the specific script for Wireless LAN interfaces
# Note : we need the wireless parameters to be set up before IP parameters,
# so that we can perform DHCP over the Wireless link if needed. Jean II

if [ -n "${WIRELESS_MODE}${WIRELESS_ESSID}${WIRELESS_NWID}${WIRELESS_FREQ}${WIRELESS_SENS}${WIRELESS_RATE}${WIRELESS_ENC_KEY}${WIRELESS_RTS}${WIRELESS_FRAG}${WIRELESS_IWCONFIG}${WIRELESS_IWSPY}${WIRELESS_IWPRIV}${WIRELESS_ESSID}" -a -x /sbin/iwconfig ] ; then
    # Set all desired settings via iwconfig

    # Mode need to be first : some settings apply only in a specific mode !
    if [ "$WIRELESS_MODE" ] ; then
	/sbin/iwconfig $DEVICE mode $WIRELESS_MODE
    fi
    # This is a bit hackish, but should do the job right...
    if [ "$WIRELESS_ESSID" ] || [ "$WIRELESS_MODE" ] ; then
        NICKNAME=`/bin/hostname`
	/sbin/iwconfig $DEVICE nick $NICKNAME >/dev/null 2>&1
    fi
    # Regular stuff...
    if [ "$WIRELESS_NWID" ] ; then
	/sbin/iwconfig $DEVICE nwid $WIRELESS_NWID
    fi
    if [ "$WIRELESS_FREQ" ] ; then
	/sbin/iwconfig $DEVICE freq $WIRELESS_FREQ
    elif [ "$WIRELESS_CHANNEL" ] ; then
	/sbin/iwconfig $DEVICE channel $WIRELESS_CHANNEL
    fi
    if [ "$WIRELESS_SENS" ] ; then
	/sbin/iwconfig $DEVICE sens $SENS
    fi
    if [ "$WIRELESS_RATE" ] ; then
	/sbin/iwconfig $DEVICE rate $WIRELESS_RATE
    fi
    if [ "$WIRELESS_ENC_KEY" ] ; then
	/sbin/iwconfig $DEVICE key $WIRELESS_ENC_KEY
    fi
    if [ "$WIRELESS_RTS" ] ; then
	/sbin/iwconfig $DEVICE rts $WIRELESS_RTS
    fi
    if [ "$WIRELESS_FRAG" ] ; then
	/sbin/iwconfig $DEVICE frag $WIRELESS_FRAG
    fi
    # More specific parameters
    if [ "$WIRELESS_IWCONFIG" ] ; then
	/sbin/iwconfig $DEVICE $WIRELESS_IWCONFIG
    fi
    if [ "$WIRELESS_IWSPY" ] ; then
	/sbin/iwspy $DEVICE $WIRELESS_IWSPY
    fi
    if [ "$WIRELESS_IWPRIV" ] ; then
	/sbin/iwpriv $DEVICE $WIRELESS_IWPRIV
    fi
    # ESSID need to be last : most device re-perform the scanning/discovery
    # when this is set, and things like encryption keys are better be
    # defined if we want to discover the right set of APs/nodes.
    if [ "$WIRELESS_ESSID" ] ; then
	/sbin/iwconfig $DEVICE essid "$WIRELESS_ESSID"
    fi
fi

if [ -n "${MACADDR}" ]; then
   ifconfig ${DEVICE} hw ether ${MACADDR}
fi

BLURB="# temporary ifup addition"

if [ -n "$DYNCONFIG" -a "XXX$DHCP_CLIENT" = "XXX" ];then
    if [ -x /sbin/dhclient ];then
	DHCP_CLIENT=/sbin/dhclient
	# Remove any temporary references which were previously added to dhclient config
	if [ -w /etc/dhclient-${DEVICE}.conf -a -x /sbin/dhclient ] ; then
	    grep -v "$BLURB" /etc/dhclient-${DEVICE}.conf > /etc/dhclient-${DEVICE}.conf.ifupnew 2> /dev/null
	    cat /etc/dhclient-${DEVICE}.conf.ifupnew > /etc/dhclient-${DEVICE}.conf
	    rm -f /etc/dhclient-${DEVICE}.conf.ifupnew
	fi
    elif [ -x /sbin/dhcpcd ];then
	DHCP_CLIENT=/sbin/dhcpcd
    elif [ -x /sbin/pump ];then
	DHCP_CLIENT=/sbin/pump
    elif [ -x /sbin/dhcpxd ];then
	DHCP_CLIENT=/sbin/dhcpxd
    else 
	echo $"Can't find a dhcp client"
	exit 1;
    fi
fi  

DHCP_ARGS=
if [ "XXX$DHCP_CLIENT" != "XXX" ];then
case $(basename $DHCP_CLIENT) in
    dhcpcd)
    [ -n "$DHCP_HOSTNAME" ] && DHCP_ARGS="-h $DHCP_HOSTNAME"
    [ -n "$NEEDHOSTNAME" ] && DHCP_ARGS="$DHCP_ARGS -H"
    [ "${PEERDNS}" = "no" ] && DHCP_ARGS="$DHCP_ARGS -R"
    [ "${PEERYP}" = "yes" ] || DHCP_ARGS="$DHCP_ARGS -Y"
    [ "${PEERNTPD}" = "yes" ] || DHCP_ARGS="$DHCP_ARGS -N"
    [ "X${DOMAINNAME}" = "X" ] && DHCP_ARGS="$DHCP_ARGS -D"
    [ -n "$DHCP_TIMEOUT" ] && DHCP_ARGS="$DHCP_ARGS -t ${DHCP_TIMEOUT}"
    DHCP_ARGS="$DHCP_ARGS $DEVICE"
    PIDF=/etc/dhcpc/dhcpcd-$DEVICE.pid
    if [[ -f $PIDF ]];then
	PID=$(cat /etc/dhcpc/dhcpcd-$DEVICE.pid)
	if [[ -n $PID ]] && kill -0 $PID;then
	    echo "dhcpcd is running ifdown it before"
	    exit;
	fi
	/bin/rm -f $PIDF; #clear it
    fi
    ;;
    pump)
    [ -n "$DHCP_HOSTNAME" ] && DHCP_ARGS="-h $DHCP_HOSTNAME"
    [ -n "$NEEDHOSTNAME" ] && DHCP_ARGS="$DHCP_ARGS --lookup-hostname"
    [ "${PEERDNS}" = "no" ] && DHCP_ARGS="$DHCP_ARGS -d"
    DHCP_ARGS="$DHCP_ARGS -i $DEVICE"
    ;;
    dhcpxd)
    # Dhcpxd don't support NEED_HOSTNAME ? guess i need time to patch
    # this animal
    [ -n "$DHCP_HOSTNAME" ] && DHCP_ARGS="-H $HOSTNAME"
    DHCP_ARGS="$DHCP_ARGS --wait $DEVICE"
    ;;
    dhclient)
    DHCP_ARGS="$DHCP_ARGS -1 -q -lf /var/lib/dhcp/dhclient-${DEVICE}.leases -pf /var/run/dhclient-${DEVICE}.pid -cf /etc/dhclient-${DEVICE}.conf $DEVICE"
    if [ -n "$DHCP_HOSTNAME" ]; then
	if [ ! -e /etc/dhclient-${DEVICE}.conf ] || ! grep -q "[^# ]*send *host-name" /etc/dhclient-${DEVICE}.conf; then
	    echo "send host-name \"${DHCP_HOSTNAME}\";  $BLURB" >> /etc/dhclient-${DEVICE}.conf
	fi
    fi
    if [ -n "$DHCP_TIMEOUT" ]; then
	if [ ! -e /etc/dhclient-${DEVICE}.conf ] || ! grep -q "[^# ]*timeout" /etc/dhclient-${DEVICE}.conf; then
	    echo "timeout $DHCP_TIMEOUT;  $BLURB" >> /etc/dhclient-${DEVICE}.conf
	fi
    fi	
    ;;
esac
fi

if [ -n "${MTU}" ]; then
   ip link set ${DEVICE} mtu ${MTU}
fi

if [ -n "$DYNCONFIG" ]; then
    echo -n $"Determining IP information for ${DEVICE}..."
    if check_link_down ${DEVICE}; then
	echo $" failed; no link present.  Check cable?"
	ip link set ${DEVICE} down >/dev/null 2>&1
	exit 1
    fi

    if $DHCP_CLIENT $DHCP_ARGS ; then
	echo $" done."
    else
	# Associate a zeroconf IP address to an alias of the interface
	if [ -x /sbin/zcip ]; then
	    if /sbin/zcip -s -i $DEVICE:${ZEROCONF_ALIAS_NUMER=9}; then
		echo $" done."
		if [ -x /etc/init.d/tmdns ]; then
		    /etc/init.d/tmdns reload > /dev/null 2>&1
		fi
		exit 0
	    fi
	fi
	echo $" failed."
	exit 1
    fi

    # DHCP likes to create duplicate routes.  Fix that up.
    NUMDEFROUTES=`ip -o route | \
                  grep "^default" | \
                  awk '{ nlines++ } END { print nlines }'`
    if [ -n "$NUMDEFROUTES" -a "$NUMDEFROUTES" -gt 1 ]; then
	# remove the default route for the new device (old route wins)
	ip route del default dev ${DEVICE}
    fi
# end dynamic device configuration
else 
    if [ -z "${IPADDR}" ]; then
         # enable device without IP, useful for e.g. PPPoE
	 ip link set ${REALDEVICE} up
	 if [ "${NETWORKING_IPV6}" = "yes" ]; then
	    /etc/sysconfig/network-scripts/ifup-ipv6 ${CONFIG}
	 fi
	 exec /etc/sysconfig/network-scripts/ifup-post ${CONFIG} ${2}
    fi
  
    expand_config
    
    [ -n "${ARP}" ] && \
	ip link set ${REALDEVICE} $(toggle_value arp $ARP)
   
    if ! ip link set ${REALDEVICE} up ; then
	echo $"Failed to bring up ${DEVICE}."
	exit 1
    fi

    [ -n "$NO_ARPING" ] || \
	if ! arping -q -c 2 -w 3 -D -I ${REALDEVICE} ${IPADDR} ; then
	echo $"Error, some other host already uses address ${IPADDR}."
	exit 1
    fi

    if [ "${DEVICE}" = "lo" ]; then
    	SCOPE="scope host"
    else
        SCOPE=${SCOPE:-}
    fi
    
    if [ -n "$SRCADDR" ]; then
       SRC="src $SRCADDR"
    else
       SRC=
    fi
    
    if ! LC_ALL=C ip addr ls ${REALDEVICE} | grep -q "${IPADDR}/${PREFIX}" ; then
	 if ! ip addr add ${IPADDR}/${PREFIX} \
	    brd ${BROADCAST:-+} dev ${REALDEVICE} ${SCOPE} label ${DEVICE}; then
	    echo $"Error adding address ${IPADDR} for ${DEVICE}."
	 fi
    fi
    
    if [ -n "$SRCADDR" ]; then
           sysctl -n -w "net.ipv4.conf.${REALDEVICE}.arp_filter=1" >/dev/null 2>&1
    fi

    # update ARP cache of neighboring computers
    arping -q -A -c 1 -I ${REALDEVICE} ${IPADDR}
    ( sleep 2;
      arping -q -U -c 1 -I ${REALDEVICE} ${IPADDR} ) > /dev/null 2>&1 < /dev/null &

    # Add a route for the subnet.  Replace any existing route.
    if [ "${ISALIAS}" = no -a "${NETMASK}" != "255.255.255.255" ]; then
	ip route replace ${NETWORK}/${PREFIX} ${SRC} dev ${REALDEVICE}
    fi

    # Set a default route.
    if [ -z "${GATEWAYDEV}" -o "${GATEWAYDEV}" = "${REALDEVICE}" ]; then
	# set up default gateway. replace if one already exists
	if [ -n "${GATEWAY}" -a "`ipcalc --network ${GATEWAY} ${NETMASK} 2>/dev/null`" = "NETWORK=${NETWORK}" ]; then
	    ip route replace default via ${GATEWAY} ${SRC}
	elif [ "${GATEWAYDEV}" = "${DEVICE}" ]; then
	    ip route replace default ${SRC} dev ${REALDEVICE}
	fi
    fi
    
fi

. /etc/sysconfig/network

# IPv6 initialisation?
if [ "${NETWORKING_IPV6}" = "yes" ]; then
    /etc/sysconfig/network-scripts/ifup-ipv6 ${CONFIG}
fi

if [ "${IPX}" = yes ]; then
       /etc/sysconfig/network-scripts/ifup-ipx ${DEVICE}
fi

exec /etc/sysconfig/network-scripts/ifup-post ${CONFIG} ${2}
