#!/bin/sh
#
# Help functions for network scripts
#

LOOPDEVICE=lo
ETHDEVICE=eth0
DHCP_PIDFILE="/var/run/dhcp_${ETHDEVICE}"

. /etc/rc.d/init.d/functions

start_loopback()
{
    # Fire up the loopback device.
    echo "INFO: Start loopback"
    /sbin/ifconfig ${LOOPDEVICE} 127.0.0.1
    /sbin/route add -net 127.0.0.0 netmask 255.0.0.0 ${LOOPDEVICE}
}

stop_loopback ()
{
  echo "INFO: stop loopback"
  /sbin/ifconfig ${LOOPDEVICE} down
}

configure_hostname ()
{
  HWADDR=`cat /sys/class/net/${ETHDEVICE}/address`;
  echo "INFO: ${ETHDEVICE} HW address detected : ${HWADDR}"
  
  BOARDID=$(echo "$HWADDR" | awk -F: '{print $3$4$5$6}' | tr '[:lower:]' '[:upper:]')
  echo "INFO: board id detected : ${BOARDID}"
  
  NEWHOSTNAME="${HOSTNAME}${BOARDID}"
  echo "INFO: new hostname : ${NEWHOSTNAME}"

  /bin/hostname ${NEWHOSTNAME}
  echo ${NEWHOSTNAME} >/etc/HOSTNAME
}

configure_tcp()
{
  # change connect TMO to 20 sec
  echo 2 >> /proc/sys/net/ipv4/tcp_syn_retries

  # remove optional timestamp field from TCP header
  echo 0 >> /proc/sys/net/ipv4/tcp_timestamps
}

#
# This function is called with only 1 argument : interface name
# It means that /tmp/gateway.$interface and /tmp/resolv.conf.$interface
#  were created with correct values
#
# This function will change default route and resolv only if necessary
# and regarding BEARERS_PRIORITY list (defined in /etc/sysconfig/network)
#
add_default_route_and_resolv()
{
  wanted_itf="$1"

  . /etc/sysconfig/network

  # Firstly, get its priono
  wanted_itf_priolvl=$(get_bearer_priolvl "$wanted_itf")
  echo "wanted_itf = $wanted_itf (prio $wanted_itf_priolvl)"
  # then get current default interface and its priority number
  cur_def_itf="$(route | grep "default" | awk '{print $8}')"
  cur_def_itf_priolvl=$(get_bearer_priolvl "$cur_def_itf")

  # Set it as default interface
  #   If no default route defined or if interface is highest priority than current one,
  if [ -z "${cur_def_itf}" ] ||
     [ ${wanted_itf_priolvl:=99} -le ${cur_def_itf_priolvl:=99} ]
  then
    # Delete default route if any
    route | grep -q "default"
    [ $? -eq 0 ] && route del default

    # Set new default route
    echo "Set default route for ${wanted_itf}"
    [ -f /tmp/gateway.${wanted_itf} ] && router="$(head -n 1 /tmp/gateway.${wanted_itf})"
    [ -n "$router" ] && ROUTE_ARGS="gw $router"
    route add default dev $wanted_itf $ROUTE_ARGS

    # Update resolv.conf
    [ -f /tmp/resolv.conf.$wanted_itf ] && cp -f /tmp/resolv.conf.$wanted_itf /etc/resolv.conf

    return 0
  fi

  return 1
}

# Echo priority no corresponding to interface name passed in argument
get_bearer_priolvl()
{
  itf="$1"

  # Check it's in the list
  echo "${BEARERS_PRIORITY}" | grep -q "$itf"

  if [ $? -ne 0 ]
  then
    # If not, return max priority
    echo "99"
  else
    # Otherwise, search for its position number in the list
    # (BEARERS_PRIORITY is formatted like this : "eth0,eth1,ppp0,wlan0")
    echo "${BEARERS_PRIORITY}" | awk -F, '
    {
      for (i = 1; i <= NF; i++)
        if($i == "'$itf'") print i
    }'
  fi
}

# Called by any disconnect handler to update default route and resolv
#
# Returns 0 if a fallback bearer is found, 1 otherwise
notify_interface_disconnect()
{
  itf="$1"

  # get current default interface
  cur_def_itf="$(route | grep "default" | awk '{print $8}')"
  # If the default route is/was based on, delete it
  #  and search for another fallback bearer
  # (Priority is NOT handled)
  if [ "$itf" == "${cur_def_itf}" ] || [ -z "${cur_def_itf}" ]
  then
    route del default dev $itf
    for i in `ip a show up | grep -v "^[\t ]" | awk '{print $2}' | sed 's/.$//'`
    do
      if [ -f /tmp/gateway.$i ] || [ -f /tmp/resolv.conf.$i ]
      then
        add_default_route_and_resolv $i
        return 0
      fi
    done
    return 1
  fi
  return 0
}

fix_addr()
{
  if [ -n "${ETHIPADDR}" ]
  then
    echo "INFO: ETHIPADDR defined"
  else
    echo "INFO: ETHIPADDR not defined, take default value"
    ETHIPADDR=192.168.4.155
    ETHNETMASK=255.255.255.0
    ETHBROADCAST=192.168.4.255
    ETHGATEWAY=192.168.4.1
  fi
  /sbin/ifconfig ${ETHDEVICE} ${ETHIPADDR} broadcast ${ETHBROADCAST} netmask ${ETHNETMASK}
  echo "INFO: Setup fix ${ETHDEVICE} address : ${ETHIPADDR}"
  rm -f /tmp/gateway.$ETHDEVICE
  if [ -n "${ETHGATEWAY}" ]
  then
    echo "${ETHGATEWAY}" > /tmp/gateway.$ETHDEVICE
    ROUTE_ARGS="gw ${ETHGATEWAY}"
  fi

  echo "nameserver $DNSSERVER1" > /tmp/resolv.conf.$ETHDEVICE
  echo "nameserver $DNSSERVER2" >> /tmp/resolv.conf.$ETHDEVICE

  add_default_route_and_resolv ${ETHDEVICE}
}

start_ethernet()
{
  # Make Sure Phy is UP before any action
  wirma2hw gpio_00 down

  if [ "${ETHAUTODETECT}" = "yes" ]
  then
    ifconfig ${ETHDEVICE} up
    # Wait Phy powering up
    sleep 4

    # Check link
    link=`cat /sys/class/net/${ETHDEVICE}/carrier`

    if [ $link -eq 0 ]
    then
      echo "No Link detected, Power down Phy !"
      # Power down Phy and don't start ifplugd
      stop_ethernet
      return
    fi
  fi

  ps -w | grep "ifplugd" | grep -q "eth0"
  if [ -f /var/run/ifplugd_eth0.pid ] && [ $? -eq 0 ]
  then
    # ifplugd yet started, return OK (PR 2776)
    rm -f /tmp/ethernet.*
    touch /tmp/ethernet.ok
  else
    start-stop-daemon -S -q -b -p /var/run/ifplugd_eth0.pid -m -x ifplugd -- -n -I -f -d 1 -r "/etc/ifplugd.action" -i ${ETHDEVICE}
  fi
}

stop_ethernet()
{
  # Make Sure Phy is UP before any action
  wirma2hw gpio_00 down

  start-stop-daemon -K -q -p /var/run/ifplugd_eth0.pid
  # Wait for interface down
  sleep 2
  rm -f /var/run/ifplugd_eth0.pid
  # Make Sure it's down
  ifconfig ${ETHDEVICE} 0.0.0.0 down
  wirma2hw gpio_00 up
}

#
# Called by ifplugd when interface is up
#
ifup_ethernet ()
{
  # Make sure ethernet is powered up
  wirma2hw gpio_00 down

  if [ "${ETHERVIRT}" = "yes" ]; then
    /sbin/ifconfig ${ETHDEVICE}:1 192.168.150.1 netmask 255.255.255.252
  fi

  if [ "${ETHDHCP}" = "yes" ]; then
    echo "INFO: DHCP REQUIRED : start on ${ETHDEVICE}"
    # DHCP config:
    #  -n          : Exit with failure if lease is not immediately obtained
    #  -R          : Release IP address on quit (don't release, let DHCP server do its job)
    #  -p PIDFILE  (in order to kill it in stop_ethernet)
    #  -V VENDOR   : Vendor Class (DHCP Option 60)
    #  -c CLIENTID : Client ID (DHCP Option 61)
    #  -h HOSTNAME : Hostname (DHCP Option 12)
    #  -S          : Log to Syslog
    #  -O          : Request DHCP option (staticroutes: option 121)
    UDHCPC_ARGS="-S -n -i ${ETHDEVICE} -s /etc/udhcpc.sh -p ${DHCP_PIDFILE} -V Kerlink -O staticroutes"
    # If exists, send Hostname in DHCP request in order to update DNS
    HOSTNAME=`hostname`
    [ ${HOSTNAME} ] && UDHCPC_ARGS=${UDHCPC_ARGS}" -h ${HOSTNAME}"
    [ -e ${DHCP_PIDFILE} ] && kill `cat ${DHCP_PIDFILE}`
    /sbin/udhcpc ${UDHCPC_ARGS}

    if [ $? -eq 0 ]; then
      echo "INFO: DHCP request success on ${ETHDEVICE}"
    else
      echo "ERROR: DHCP failed on ${ETHDEVICE}"
      echo "INFO: Set static address"
      # Don't need to kill udhcpc since '-n' option will automatically make exit if no lease obtained
      fix_addr
    fi
  else
    echo "INFO: Bringing up the ${ETHDEVICE} interface on fixe address..."
    fix_addr
  fi

  rm -f /tmp/ethernet.* 
  touch /tmp/ethernet.ok 

  if [ "${ROUTER}" = "yes" ] && [ "${DEVIN}" = "${ETHDEVICE}" ]
  then
    /etc/rc.d/init.d/router start
  fi

  return 0
}

#
# Called by ifplugd when interface is down
#
ifdown_ethernet ()
{
  if [ -e ${DHCP_PIDFILE} ]; then
    # PIDFILE will be deleted by udhcpc itself
    kill `cat ${DHCP_PIDFILE}`
  fi
  /sbin/ifconfig ${ETHDEVICE} 0.0.0.0 down
  echo "INFO: Bringing down the ${ETHDEVICE} interface..."
  notify_interface_disconnect ${ETHDEVICE}
  
  if [ "${ETHERVIRT}" = "yes" ]; then
    /sbin/ifconfig ${ETHDEVICE}:1 down
  fi

  rm -f /tmp/ethernet.* 
  touch /tmp/ethernet.ko
  
  if [ "${ROUTER}" = "yes" ] && [ "${DEVIN}" = "${ETHDEVICE}" ]
  then
    /etc/rc.d/init.d/router stop
  fi

}

