#!/bin/sh
# dhclient-script for Linux. Dan Halbert, March, 1997.
# Updated for Linux 2.[12] by Brian J. Murrell, January 1999.

#/******************************************************************************
#   * Copyright (c) 2007 Palm, Inc. or its subsidiaries.
#   * All rights reserved.
# *****************************************************************************/

#/*******************************************************************
#*
#*    DESCRIPTION: Palm-modified dhclient script for use with PmWiFiService;
#*
#*    FILE: PmWiFiDhclient-script
#*
#*    AUTHOR: Vitaly Kruglikov
#*
#*******************************************************************/

# Notes:

# 0. This script is based on the netbsd script supplied with dhcp-970306.

# 1. ifconfig down apparently deletes all relevant routes and flushes
# the arp cache, so this doesn't need to be done explicitly.

# 2. The alias address handling here has not been tested AT ALL.
# I'm just going by the doc of modern Linux ip aliasing, which uses
# notations like eth0:0, eth0:1, for each alias.

# 3. I have to calculate the network address, and calculate the broadcast
# address if it is not supplied. This might be much more easily done
# by the dhclient C code, and passed on.

# 4. TIMEOUT not tested. ping has a flag I don't know, and I'm suspicious
# of the $1 in its args.

# make_resolv_conf() {
#   if [ "x$new_domain_name" != x ] && [ x"$new_domain_name_servers" != x ]; then
#     echo search $new_domain_name >/etc/resolv.conf
#     chmod 644 /etc/resolv.conf
#     for nameserver in $new_domain_name_servers; do
#       echo nameserver $nameserver >>/etc/resolv.conf
#     done
#   fi
# }

# Must be used on exit. Invokes the local dhcp client exit hooks, if any.
exit_with_hooks() {
  exit_status=$1
#   if [ -f /etc/dhclient-exit-hooks ]; then
#     . /etc/dhclient-exit-hooks
#   fi

  # probably should do something with exit status of the local script
  exit $exit_status
}

# Send DHCP results via the DHCP results forwarder application
call_results_forwarder() {
    forward_args="$opt_command \
$opt_session_id \
$opt_interface \
$opt_hostname \
$opt_ipchanged \
$opt_ipaddr \
$opt_subnet \
$opt_broadcast \
$opt_routers \
$opt_netnum \
$opt_dns \
$opt_domains \
$opt_dhcp_lease_time \
$opt_dhcp_message_type \
$opt_dhcp_server_identifier \
$opt_dhcp_renewal_time \
$opt_dhcp_rebinding_time \
"

  echo "$forward_args"
}

# Invoke the local dhcp client enter hooks, if they exist.
# if [ -f /etc/dhclient-enter-hooks ]; then
#   exit_status=0
#   . /etc/dhclient-enter-hooks
#   # allow the local script to abort processing of this state
#   # local script must set exit_status variable to nonzero.
#   if [ $exit_status -ne 0 ]; then
#     exit $exit_status
#   fi
# fi

# release=`uname -r`
# release=`expr $release : '\(.*\)\..*'`
# relminor=`echo $release |sed -e 's/[0-9]*\.\([0-9][0-9]*\)\(\..*\)*$/\1/'`
# relmajor=`echo $release |sed -e 's/\([0-9][0-9]*\)\..*$/\1/'`

# Session ID is palm's extension
if [ x$PM_DHCLIENT_WRAP_SID != x ]; then
  opt_session_id="--sessionId $PM_DHCLIENT_WRAP_SID"
fi

if [ x$interface != x ]; then
  opt_interface="--interface $interface"
fi

if [ x$new_broadcast_address != x ]; then
  opt_broadcast="--broadcast $new_broadcast_address"
fi

# if [ x$old_broadcast_address != x ]; then
#   old_broadcast_arg="broadcast $old_broadcast_address"
# fi

if [ "x$new_ip_address" != x ]; then
  opt_ipaddr="--ipaddr $new_ip_address"
fi

if [ "x$new_network_number" != x ]; then
  opt_netnum="--netnum $new_network_number"
fi

if [ "x$new_routers" != x ]; then
  opt_routers="--routers $new_routers"
fi

if [ "x$new_domain_name" != x ]; then
  opt_domains="--domains $new_domain_name"
fi

if [ "x$new_domain_name_servers" != x ]; then
  opt_dns="--dns_servers $new_domain_name_servers"
fi

if [ x$new_subnet_mask != x ]; then
  opt_subnet="--netmask $new_subnet_mask"
fi

if [ x$new_dhcp_rebinding_time != x ]; then
  opt_dhcp_rebinding_time="--rebindtime $new_dhcp_rebinding_time"
fi

if [ x$new_dhcp_renewal_time != x ]; then
  opt_dhcp_renewal_time="--renewaltime $new_dhcp_renewal_time"
fi

if [ x$new_dhcp_server_identifier != x ]; then
  opt_dhcp_server_identifier="--serveridentifier $new_dhcp_server_identifier"
fi

if [ x$new_dhcp_message_type != x ]; then
  opt_dhcp_message_type="--messagetype $new_dhcp_message_type"
fi

if [ x$new_dhcp_lease_time != x ]; then
  opt_dhcp_lease_time="--leasetime $new_dhcp_lease_time"
fi

# if [ x$old_subnet_mask != x ]; then
#   old_subnet_arg="netmask $old_subnet_mask"
# fi

if [ x$reason = xMEDIUM ]; then
  # Linux doesn't do mediums (ok, ok, media).
  exit_with_hooks 0
fi

#
# WiFi service: we will only ifconfig for PREINIT.  All other ifconfig
# will be delegated to Net Config Manager
#
if [ x$reason = xPREINIT ]; then

#
#

#   if [ x$alias_ip_address != x ]; then
#     # Bring down alias interface. Its routes will disappear too.
#     ifconfig $interface:0- inet 0
#   fi

#
# @todo WiFi service - do we really need this "ifconfig ... up" here?
#   - Doesn't WiFi Service bring up the interface before invoking DHCP client?
#   - What about the setting of inet, netmask, broadcast - code below does it
#     only for Linux <= 2.0, is this the right approach for Nova?
#

#   if [ $relmajor -lt 2 ] || ( [ $relmajor -eq 2 ] && [ $relminor -eq 0 ] )
#    then
#     ifconfig $interface inet 0.0.0.0 netmask 0.0.0.0 \
# 		broadcast 255.255.255.255 up
#     # Add route to make broadcast work. Do not omit netmask.
#     route add default dev $interface netmask 0.0.0.0
#   else
#   ifconfig $interface 0 up
#   fi

  exit_with_hooks 0
fi

if [ x$reason = xARPCHECK ] || [ x$reason = xARPSEND ]; then
  exit_with_hooks 0
fi
  
if [ x$reason = xBOUND ] || [ x$reason = xRENEW ] || \
   [ x$reason = xREBIND ] || [ x$reason = xREBOOT ]; then

  #
  # @todo WiFi service: do we really need the hostname???
  #
  current_hostname=`hostname`
  if [ x$current_hostname = x ] || \
     [ x$current_hostname = x$old_host_name ]; then
    if [ x$current_hostname = x ] || \
       [ x$new_host_name != x$old_host_name ]; then
      #hostname $new_host_name
      opt_hostname="--hostname '$new_host_name'"
    fi
  fi

  if [ x$old_ip_address != x ] && [ x$old_ip_address != x$new_ip_address ]; then
    # IP address changed. Bringing down the interface will delete all routes,
    # and clear the ARP cache.

    #
    # @todo WiFi service: what should we do when IP address changes?
    #
    # ifconfig $interface inet 0 down
    opt_ipchanged="--ipchanged"
  fi

#   if [ x$old_ip_address = x ] || [ x$old_ip_address != x$new_ip_address ] || \
#      [ x$reason = xBOUND ] || [ x$reason = xREBOOT ]; then
# 
# 
#     ifconfig $interface inet $new_ip_address $new_subnet_arg \
# 							$new_broadcast_arg
# 
#     # Add a network route to the computed network address.
#     if [ $relmajor -lt 2 ] || \
# 		( [ $relmajor -eq 2 ] && [ $relminor -eq 0 ] ); then
#       route add -net $new_network_number $new_subnet_arg dev $interface
#     fi
#     for router in $new_routers; do
#       route add default gw $router
#     done
#   fi

  if [ x$reason = xBOUND ] || [ x$reason = xREBOOT ]; then
    opt_command="dhcp-results --op configure --status success"
  else
    opt_command="dhcp-results --op renew --status success"
  fi

#  make_resolv_conf

  call_results_forwarder

  exit_with_hooks 0
fi

if [ x$reason = xEXPIRE ] || [ x$reason = xFAIL ] || [ x$reason = xRELEASE ] \
   || [ x$reason = xSTOP ]; then

  #if [ x$old_ip_address != x ]; then
    # Shut down interface, which will delete routes and clear arp cache.
    #
    # @todo WiFi service: Do we need this ifconfig/down, or leave it up
    # to Net Config Manager?
    #
    #ifconfig $interface inet 0 down
  #fi

  if [ x$reason = xFAIL ]; then
    opt_command="dhcp-results --op configure --status fail"
  else
    opt_command="dhcp-results --op renew --status fail"
  fi

  call_results_forwarder

  exit_with_hooks 0
fi

if [ x$reason = xTIMEOUT ]; then

  opt_command="dhcp-results --op configure --status fail"

  call_results_forwarder

  exit_with_hooks 0
fi

exit_with_hooks 0

