#!/bin/sh
#
# Copyright 2003 Meru Networks
# All rights reserved.
#
# Meru controller
#
if [ -f /etc/init.d/meru-functions ]; then
        . /etc/init.d/meru-functions
else
        echo "/etc/init.d/meru-functions must exist to use $0"; exit 1
fi

#lmgrd port number
LMGR_PORT=27000

# Add symbolic link to wlan
ln -f -s /opt/meru /opt/wlan

set_params

#
# Modules to load. Ordering is important.
#
MMODS="meru_util meru_debug mkctr ip_tables kcomm reg_table reg wncreg rebridging rebrid_ioctl ipt_CLSFY force_frag atsvif atsfilter"
LOG=/opt/meru/var/log/meru_init.log
export MMODS

#
# Reset passwords: in 1.0.3 admin account was associated to meru-cli, in 1.1
#                  it associated to ioscli
#
reset_passwds()
{
                echo "Resetting passwords ..." >> $LOG
                /usr/sbin/userdel guest >/dev/null
                /usr/sbin/useradd -c "Meru guest account" \
                        -s /opt/meru/bin/ioscli  -d / guest \
                        -p '$1$514fTeI1$sqBp9pQUlqx9gpa8Xk4Jz1' >/dev/null
                /usr/sbin/userdel admin >/dev/null
                /usr/sbin/useradd -c "Meru admin account" \
                        -s /opt/meru/bin/ioscli  -d / admin \
                        -p '$1$TU/PrZEx$0JjwzD75rjSC4v0yIy14s/' >/dev/null
                /usr/sbin/userdel support >/dev/null
                cat /etc/shadow | sed -e '/^root:/d' > $TMP
                echo 'root:$1$jHIztvRr$WzrSnVGbNA2XEGnE6dE/u1:13794::::::' >> $TMP
                mv $TMP /etc/shadow
}

TOTALBAR=31
ITRBAR=0
TEXTBAR="Stopping"

print_bar() {
	echo -e -n "\r${TEXTBAR} WLAN services:  [" >> `tty`
	for (( i = 0; i < $ITRBAR; i++ ))
	do
		echo -n "#" >> `tty`
	done
	for (( i = 0; i < `expr $TOTALBAR - $ITRBAR`; i++ ))
	do
		echo -n "." >> `tty`
	done
	echo -n "] " >> `tty`
}

finish_bar() {
    ITRBAR=$TOTALBAR
    print_bar
}

prog_bar () {
    print_bar
#   echo -n "$1" >> `tty`
    ITRBAR=`expr $ITRBAR + 1`
}

wait_stop() {

    prog_bar
        
    /etc/init.d/$1 stop

    EMERG_CTR=0
    while pgrep $1 >/dev/null 2>&1
      do
      sleep 1
	  EMERG_CTR=`expr $EMERG_CTR + 1`
      # If EMERG_CTR equals 10 (10 seconds), then emergency killall occurs
      if [ $EMERG_CTR -eq 10 ]; then
         echo "Process $1 did not shut down normally, issuing second termination signal..."
	     killall $1
      fi
      # If EMERG_CTR equals 20 (20 seconds), then emergency break occurs
      if [ $EMERG_CTR -eq 20 ]; then
         echo "Process $1 did not respond to second termination signal; continuing to stop WLAN services..."
         break
      fi
    done
    
    echo "$1 stopped."
}

start() {
    
    TOTALBAR=39
    TEXTBAR="Starting"
    
    echo "meru-wnc:start" >> $LOG 

    prog_bar "pre-app"; 

    for (( try_net=0; try_net < 3; try_net++ ))
    do
      if [ "$WIRELESS_SUBNET_ADDR" = "" ] || [ "$WIRELESS_SUBNET_MASK" = "" ];then
          
          if [ ! -e "/etc/sysconfig/network-scripts/ifcfg-$FIRST_IF" ];then
              # Before we fail, we could try to restore from a backup file...
              fail $'Network is not configured. \nLogin as admin and use the "setup" command.'
          fi
          echo "Retrying network start..." >> $LOG
                  #BUG: 15607:set the link up, and wait for 34 secs. the link should
                  #have stabilised in that time, and then bring the interface up
                  /etc/init.d/network stop
                  /sbin/ip link set $FIRST_IF up > /dev/null
                  sleep 34
                  /etc/init.d/network start	
          set_params          
      else
          break
      fi
      
    done
    
    prog_bar; 
    
    if [ "$WIRELESS_SUBNET_ADDR" = "" -o "$WIRELESS_SUBNET_MASK" = "" ];then
        
        case $PLATFORM in
            MC1000|MC3000|MC4000|MC4100)
            /etc/init.d/kdi unconfigured
            ;;
        esac

        echo "Network setup failed." >> $LOG
        fail $'Cannot determine wireless subnet address.\nSystem not fully operational.\nLogin as admin and use the "setup" command to correct configuration errors.'
    fi

    # check if we must reset the passwords due to a 1.0.3 to 1.1 upgrade
    [ -f /root/reset_passwords ] && {
        reset_passwds
        rm -f /root/reset_passwords
    }

    # Configure lkcd                                                                
    if [ -e /lib/modules/2.4.18-3-meruenabled/kernel/drivers/dump ]; then           
        mkswap $DUMP_DEV                                                           
        swapon $DUMP_DEV                                                           
        
            # To take care of the case where /dev/vmdump may be incorrectly pointing
            # to /dev/hda3 in the MC 1100 case, explicitly redo the link between
            # /dev/vmdump and whatever DUMP_DEV is set to.
        if [ -e /dev/vmdump ]; then
            rm /dev/vmdump
        fi
        ln -s $DUMP_DEV /dev/vmdump                                             
        modprobe dump                                                               
        /sbin/lkcd config                                                           
        /sbin/lkcd save  
            #Collect kernel trace to /opt/meru/images, where user can reach
        /opt/meru/bin/meru-kernel-diagnostics.sh
    fi
         
    prog_bar "modules    "; 

    # Load and start modules
    /etc/init.d/mmods start || fail "Could not load kernel modules"
    echo "Kernel Modules loaded" >> $LOG
    touch /opt/meru/var/run/rebridging

    prog_bar "routes     "; 
    
    # Record existing routes off of FIRST_IF
    FIRST_IF_ROUTES=`ip route show | egrep ".* via .* dev $FIRST_IF" | awk '{print $1 " " $3 " "}'`
    
    # Disable real_if's ip address
    FIRST_IF_HAS_DHCP=false

    [ "`pgrep dhcpcd`" ] && [ "`pgrep dhcpcd | xargs ps | grep -e $FIRST_IF`" ] && 
    {
        pgrep dhcpcd | xargs ps | grep -e $FIRST_IF | awk '{print $1}' | xargs kill -9
        FIRST_IF_HAS_DHCP=true
                # Wait for DHCP to die
        while pgrep dhcpcd | xargs ps | grep -e $FIRST_IF
          do
          sleep 1
        done
    }

    ifconfig $FIRST_IF 0.0.0.0 promisc || fail "ifconfig $FIRST_IF failed"                
    # Configure rebridging
    if [ "$FIRST_IF_HAS_DHCP" = "true" ]; then
    #FIRST_IF uses dhcp, reconfigure on meru (since mac is the same, we should get the same ip address)
        dhcpcd -d -t 180 -n $UDP_IF -c /opt/meru/bin/updatehosts.sh >/dev/null 2>&1 || fail "dhcpcd on $UDP_IF failed"
        [ -d /etc/dhcpc ] && cp -p /opt/meru/etc/dhcpcd.exe /etc/dhcpc
    else
        ifconfig $UDP_IF $WIRELESS_SUBNET_ADDR netmask $WIRELESS_SUBNET_MASK broadcast $WIRELESS_SUBNET_BCST up || fail "ifconfig $UDP_IF failed"
    fi
    
    if [ "$HIGH_AVAILABILITY_STATE" = "0" ]; then
        /etc/init.d/MeruSecondIf start || fail "Could not start second interface, hence the system is not fully operational."
    fi
    
    echo 1 > /proc/sys/net/ipv4/conf/$UDP_IF/proxy_arp

    prog_bar; 

    # Re-instate routes
    FIRST=true
    for tok in $FIRST_IF_ROUTES
      do
      [ "$FIRST" = "true" ] && {
          route=$tok
          FIRST=false
          continue
      }
      gw=$tok
      FIRST=true
      ip route add $route via $gw >/dev/null 2>&1
    done
    
        #in case of MC1000, if the default interface is configured as static, it
        #its default route is lost, so we add it here.-BUG 15927
    if [ "$FIRST_IF_HAS_DHCP" = "false" -a $PLATFORM = "MC1000" ]; then
        gw=`cat /etc/sysconfig/network-scripts/ifcfg-$FIRST_IF | grep GATEWAY | awk -F= '{ print $NF }'`
        if [ `echo $gw | grep "'" ` ]; then                             
            gw=`echo $gw | awk -F"'" '{print $2}'` 
        fi
        
        if [ $HIGH_AVAILABILITY_STATE = "1" ]; then
                        # this has to be done as eth0 would have come up with a route and
                        # we would not be able to add the default route.
            ip route del default > /dev/null 2>&1
        fi
        ip route add  default  via $gw dev meru > /dev/null 2>&1
    fi
    
    prog_bar "ats        "; 
    
        # Create the downstream (ats) interface
        # Give the virtual interface the gateway IP address.  This is used in the
        # ARP requests on the interface as the source, so we want it to be that
        # of the gateway
    
    ifconfig ats hw ether $MERU_MAC arp $WIRELESS_SUBNET_ADDR \
        broadcast $WIRELESS_SUBNET_BCST netmask 0xffffffff up
    
        # ...but, we don't want packets that arrive ON this interface to get
        # eaten locally, for that IP address
    
        # Disable ICMP redirects
    echo 0 > /proc/sys/net/ipv4/conf/ats/send_redirects
    
    # Allow to increase rcv socket buffer up to 13MB for specific mailbox enhancement
    # setsockopt makes SO_RCVBUF double, so that rmem_max must be half 
    echo 6500000 > /proc/sys/net/core/rmem_max

    prog_bar "upgd-check  "; 
    
        # First boot after upgrade, update DB
    if [ -e /opt/meru/images/.upgrade/UPGRADE_IN_PROGRESS ]
        then
        [ -e /opt/meru/etc/merudb.dbs ] && {
            /bin/mv -f /opt/meru/etc/merudb.dbs /opt/meru/etc/merudb.dbs.bak
        }
        /opt/meru/bin/wncagent /opt/meru/etc -i
    fi
        # Set to the default country code if the country.conf file not exists
    [ -f /opt/meru/etc/country_codes/country.conf ] || echo "COUNTRY_CODE=US" > /opt/meru/etc/country_codes/country.conf
    
    prog_bar "db-diag    "; 
    
        # Verify DB
    verify_db || {
        logger -p local7.info "Configuration file was corrupted.  Please verify your configuration."
        echo "Configuration file was corrupted. Please verify your configuration" >> $LOG 
    }
    
        # Pull DB
    pull_db
    echo "Configuration files copied at running-db" >> $LOG 
    [ -f /opt/meru/etc/EzStatsColl ] && cp -f /opt/meru/etc/EzStatsColl /opt/meru/var/run/
    
    # Generate passwords for rsync
    /opt/meru/bin/prsync
    if [ $? != 0 ]; then
        logger -p local7.info "Rsync passwords not created."
        echo "Rsync passwords not created" >> $LOG
    else
        chmod 600 /etc/rsyncd.password
        chmod 600 /etc/rsyncd.secrets
    fi
    
    # if merudtemp.lic exists, remove the file before starting lmgrd
    [ -f /opt/wlan/licenses/merudtemp.lic ] && {
        /bin/rm -f /opt/wlan/licenses/merudtemp.lic >/dev/null 2>&1
    }

    # make sure of hostname @ /etc/hosts in order to prevent lmgrd failure by missing host name and ip address
    /opt/wlan/bin/sethosts.pl $WIRELESS_SUBNET_ADDR >> $LOG

    prog_bar "apps     "; 
    
        # Start applications
    echo "Starting applications" >> $LOG
    prog_bar "lmgrd      "; /etc/init.d/lmgrd start
    prog_bar "rsync      "; /etc/init.d/rsync start
    prog_bar "vlan       "; /etc/init.d/vlan start
    prog_bar "wncagent   "; /etc/init.d/wncagent start
        # Do not add new components above KDI
        case $PLATFORM in
            MC1000|MC3000|MC4000|MC4100)
        /etc/init.d/kdi start
                ;;
        esac
    
    prog_bar "xclid      "; /etc/init.d/xclid start
        #/etc/init.d/ws start
    prog_bar "xems       "; /etc/init.d/xems start
    prog_bar "apache     "; /etc/init.d/apache start
    sleep 8
    prog_bar "hostapd    "; /etc/init.d/hostapd start 
    if [ -x /opt/meru/kernel/ipsec.o ]; then
        /etc/init.d/vpn start
    fi
    prog_bar "security-mm"; /etc/init.d/security-mm start
    prog_bar "coordinator"; /etc/init.d/coordinator start
    prog_bar "rogueapd   "; /etc/init.d/rogueapd start
    prog_bar "rulefd     "; /etc/init.d/rulefd start
    prog_bar "octwatchdog"; /etc/init.d/oct_watchdog start
    prog_bar "h323fd     "; /etc/init.d/h323fd start
    prog_bar "sipfd      "; /etc/init.d/sipfd start
    prog_bar "sccpfd     "; /etc/init.d/sccpfd start
    prog_bar "wncclid    "; /etc/init.d/wncclid start
    prog_bar "rfsmgr     "; /etc/init.d/rfsmgr start
    prog_bar "snmp       "; /etc/init.d/snmp start
    prog_bar "aeroscoutd       "; /etc/init.d/aeroscoutd start
    prog_bar "igmp-snoop-daemon   "; /etc/init.d/igmp-snoop-daemon start
    prog_bar "melfd      "; /etc/init.d/melfd start
    prog_bar "nmsagent      "; /etc/init.d/nmsagent start
    /etc/init.d/cmdd start

    # RebridMover is always running for monitoring link status
    /etc/init.d/RebridMover start
    
    # client locator
    if [ -f /opt/meru/etc/ping_ouis_on ]; then
        /etc/init.d/ping_ouis start
    fi
    
    prog_bar "app-done      "; 
    
        # Update db to pre-upgrade-config
    if [ -e /opt/meru/images/.upgrade/UPGRADE_IN_PROGRESS -a -f /opt/meru/images/pre-upgrade-config ]
        then
        logger -p local7.info "Saving the initial new database configuration"
        echo "Saving the initial new database configuration" >> $LOG
        i=0
        while ! vrfy snmp
          do
          let "i++"
          sleep 1
          if [ $i -gt 60 ]; then
              logger -p local7.info "Some processes did not start after upgrade.  Attempting to restore configuration anyway..."
              echo "Some processes did not start after upgrade.  Attempting to restore configuration anyway..." >> $LOG
              break
          fi
        done
        /opt/meru/bin/ioscli -c "copy running-config initial.cnf"
        /bin/mv /opt/meru/images/initial.cnf /opt/meru/images/.upgrade/initial.cnf
        /opt/meru/etc/cli/meru-wnc-upgrade.sh
    fi
    
    prog_bar "captive   "; 
    
    #
    # Captive portal rules
    #
    ip rule add fwmark 40b table 10 pref 400 || fail "ip rule failed"
    
    # Re-direct http from client
    #iptables -t nat -A PREROUTING -i ats -p tcp -m multiport --ports 80 -m mark --mark 1035 -j DNAT --to $WIRELESS_SUBNET_ADDR:8080
    #iptables -t nat -A PREROUTING -i ats -p tcp -m multiport --ports 443 -m mark --mark 1035 -j DNAT --to $WIRELESS_SUBNET_ADDR:8081
    
    # Bring the packet into the Communications Subsystem
    /sbin/iptables -A FORWARD -j CLSFY || fail "iptables 1 failed"
    # This allows our qosrule/firewall to perform FORWARD/DROP for packets to controller also.  Put it first in the chain.
    /sbin/iptables -I INPUT -j CLSFY || fail "iptables 2 failed"
    
    # Resolve bugs 18975, 18976, 18977, 18978, 18979, 18980, 18981, 18982,
    # 18984 and 18986 by rejecting any connection attempts to TCP ports
    # 8080 or 8081 that ingress the controller via the meru interface (wired side).
    /sbin/iptables -I INPUT -i meru -p tcp --dport 8080:8081 -j REJECT --reject-with tcp-reset || fail "iptables 8080:8081"

    # Also resolve bug 16951 by resetting any connection attempts to TCP port 10101.
    #
    # Note the reject type of "tcp-reset". This emulates the
    # controller behavior for all TCP ports that do not have a listener so
    # a scanning program sees the exact same behavior (TCP RST) when scanning
    # an unused port and 2) scanning a port for which we want to block
    # connections on from the wired side.
    /sbin/iptables -I INPUT -i meru -p tcp --dport 10101 -j REJECT --reject-with tcp-reset || fail "iptables 10101"

    # Resolve bug 16952 by blocking any ICMP timestamp requests
    /sbin/iptables -I INPUT -p icmp -s 0/0 --icmp-type timestamp-request -j DROP || fail "iptables icmp timestamp failed"

    # Fix for bug 18944. Note the reject type has been changed to use a
    # TCP reset instead of the default of ICMP dest unreachable/port unreachable.
    # As with the rules above, this is to emulate the behavior of the controller
    # for unused ports.
    /sbin/iptables -I INPUT -p tcp --dport $LMGR_PORT -j REJECT --reject-with tcp-reset || fail "iptables 3 failed"
    # Fix for bug 22580. This is to avoid classification of loopback packets.
    /sbin/iptables -I INPUT -i lo -j ACCEPT || fail "iptables 4 failed"

    echo 1 > /proc/sys/net/ipv4/ip_nonlocal_bind
    
    ##
    # Routing


    # Disable ICMP redirects
    echo 0 > /proc/sys/net/ipv4/conf/all/send_redirects

    # Force tcp packets to fit into tunnel, (MERU L2 (16B) + MERU L3 (IP(20B) + UDP(8B)))40B
    iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1416 || fail "iptables 3 failed"
    iptables -t mangle -A INPUT -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1416 || fail "iptables 3 failed"

    # Discard any broadcast IP pkts that happen to have the kcomm port - they are not kcomm
    /sbin/iptables -t mangle -A PREROUTING -p udp --dst 255.255.255.255 --dport 5000 -j DROP || fail "iptables UDP 5000"

    # Discard all stray DHCP reply packets 
    /sbin/iptables -t mangle -A PREROUTING -p udp --source-port 67 --destination-port 68 -m mark --mark 0xfefefefe -j DROP || fail "iptables DHCP failed"

    # Flush routes immediately (WARNING: THIS IS NOT UNDONE ON STOP)
    echo 0 > /proc/sys/net/ipv4/route/min_delay
    
    # Disable the route path filter.
    echo 0 > /proc/sys/net/ipv4/conf/meru/rp_filter

    # Relays
    if [ $DHCP_SERVER_IP ]; then
        /etc/init.d/WncDhcpRelay start
    fi
    
    prog_bar "netconf    "; 
    
    # Core routing. Host routes, before main route anyway
    ip rule add table 10 pref 300 || fail "ip rule failed"
    
    # Proxy ARPing
    if [ $DHCP_IF ]; then
        ifconfig $DHCP_IF $WIRELESS_SUBNET_ADDR netmask $WIRELESS_SUBNET_MASK \
            broadcast $WIRELESS_SUBNET_BCST up || fail "ifconfig $DHCP_IF failed"
        echo 1 > /proc/sys/net/ipv4/conf/$DHCP_IF/proxy_arp
        
    fi
    
    # Bug 10342: Set the number of ARP Cache entries to 4096 
    # instead of the default value of 1024 <temporary fix>.
    echo 4096 > /proc/sys/net/ipv4/neigh/default/gc_thresh3
    echo 3072 > /proc/sys/net/ipv4/neigh/default/gc_thresh4
    
    #tune up values for 1G using the new kernel parameters
    echo 6000 > /proc/sys/net/core/netdev_max_backlog
    echo 10   > /proc/sys/net/core/netdev_max_budget
       
    /sbin/ifconfig $FIRST_IF txqueuelen 5000
    /sbin/ifconfig $SECOND_IF txqueuelen 5000

    # Disable queuing on virtual device
    /sbin/ifconfig ats txqueuelen 0

    prog_bar "discovery"; 

    # Start discovery last
    /etc/init.d/discovery start
    if [ "$HIGH_AVAILABILITY_STATE" = "1" ]; then
        sleep 10
        /etc/init.d/heartbeat start
    fi
    
    prog_bar "          "; 
    
    /etc/init.d/RIos start
    prog_bar "icrd       "; /etc/init.d/icrd start
    prog_bar "diagd      "; /etc/init.d/diagagent start
    echo "meru-wnc:start - finished" >> $LOG
    
    finish_bar;
}

stop() {
    echo "meru-wnc:stop" >> $LOG 
    
    wait_stop diagagent
    wait_stop icrd 
    wait_stop RIos
    if [ "$HIGH_AVAILABILITY_STATE" = "1" ]; then
        wait_stop heartbeat
    fi
    if [ "$HIGH_AVAILABILITY_STATE" = "0" ]; then
       /etc/init.d/MeruSecondIf down || fail "fail to bring down second if"
    fi
    # Stop discovery first
    wait_stop discovery
    echo "Waiting for discovery to shut down ..." >> $LOG
    i=0
    while pgrep discovery >/dev/null 2>&1
      do
      i=`expr $i + 1`
      sleep 1
      [ $i -gt 20 ] && {
          echo "Discovery wait timed out." >> $LOG
          break
      }
    done
    
    if [ $DHCP_IF ]; then
        ifconfig $DHCP_IF down
        echo 0 > /proc/sys/net/ipv4/conf/$DHCP_IF/proxy_arp
    fi
    
    ip rule del fwmark 40b table 10 pref 400
    #iptables -t nat -D PREROUTING -i ats -p tcp -m multiport --ports 80 -m mark --mark 1035 -j DNAT --to $WIRELESS_SUBNET_ADDR:8080
    #iptables -t nat -D PREROUTING -i ats -p tcp -m multiport --ports 443 -m mark --mark 1035 -j DNAT --to $WIRELESS_SUBNET_ADDR:8081
    
    /sbin/iptables -D FORWARD -j CLSFY
    /sbin/iptables -D INPUT -j CLSFY
    
    wait_stop WncDhcpRelay
    
    iptables -t mangle -D FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1416
    #remove the rule that we added for droping the stray dhcp packet
    /sbin/iptables -t mangle -D PREROUTING -p udp --source-port 67 --destination-port 68 -m mark --mark 0xfefefefe -j DROP
    # remove port 5000 non-kcomm pkt filter
    /sbin/iptables -t mangle -D PREROUTING -p udp --dst 255.255.255.255 --dport 5000 -j DROP
    
    ip rule del table 10 pref 300
    
    wait_stop nmsagent
    wait_stop melfd
    wait_stop igmp-snoop-daemon
    wait_stop aeroscoutd
    wait_stop snmp
    wait_stop cmdd
    wait_stop rfsmgr
    wait_stop wncclid
    wait_stop sipfd
    wait_stop rulefd
    wait_stop oct_watchdog
    wait_stop h323fd
    wait_stop sccpfd
    wait_stop coordinator
    wait_stop security-mm
    if [ -x /opt/meru/kernel/ipsec.o ]; then
        wait_stop vpn
    fi
    wait_stop hostapd
    wait_stop rogueapd
    #wait_stop ws
    wait_stop xems
    wait_stop apache
    wait_stop xclid
    wait_stop wncagent
    wait_stop vlan
    wait_stop rsync
    wait_stop lmgrd

    # RebridMover is always running for monitoring link status
    wait_stop RebridMover
    
    # return back to original SO_RCVBUF size
    echo 131071 > /proc/sys/net/core/rmem_max

    [ -f /opt/meru/var/run/EzStatsColl ] && cp -f /opt/meru/var/run/EzStatsColl /opt/meru/etc/
    
    # client locator
    /etc/init.d/ping_ouis stop

    # Make sure the all files are saved
    sync
    sync
    sync
    
    # ALWAYS MAKE SURE KDI IS THE LAST COMPONENT!!!
    case $PLATFORM in
        MC1000|MC3000|MC4000|MC4100)
        wait_stop kdi
        ;;
    esac
    
    # Bring ats if down
    ifconfig ats down
    
    # Record existing routes off of rebridging
    UDP_IF_ROUTES=`ip route show | egrep ".* via .* dev $UDP_IF" | awk '{print $1 " " $3 " "}'`
    
    # Disable real_if's ip address
    UDP_IF_HAS_DHCP=false
    
    [ "`pgrep dhcpcd`" ] && [ "`pgrep dhcpcd | xargs ps | grep -w $UDP_IF`" ] && {
        pgrep dhcpcd | xargs ps | grep $UDP_IF | awk '{print $1}' | xargs kill -9
        UDP_IF_HAS_DHCP=true
    }
     
    # Remove rebridging
    ifconfig $UDP_IF down
    
    # Re-enable real-if, and remove promiscuity from all
    ifconfig $FIRST_IF -promisc     
    
    if [ "$UDP_IF_HAS_DHCP" = "true" ]; then
        [ -f /etc/dhcpc/dhcpcd.exe ] && rm -f /etc/dhcpc/dhcpcd.exe
                # UDP_IF uses dhcp,
        dhcpcd -n $FIRST_IF >/dev/null 2>&1
    else
        ifconfig $FIRST_IF $WIRELESS_SUBNET_ADDR netmask $WIRELESS_SUBNET_MASK up
    fi
  
 
    # Re-instate routes
    FIRST=true
    for tok in $UDP_IF_ROUTES
      do
      [ "$FIRST" = "true" ] && {
          route=$tok
          FIRST=false
          continue
      }
      gw=$tok
      FIRST=true
      ip route add $route via $gw >/dev/null 2>&1
    done
    
    rm -f /opt/meru/var/run/rebridging
    
    rm -rf /etc/rsyncd.password > /dev/null
    rm -rf /etc/rsyncd.secrets > /dev/null
    
    # stop kernel modules
    /etc/init.d/mmods stop

    echo "meru-wnc:stop - finished" >> $LOG
    finish_bar
}

#
# main()
#
set_params

case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    restart)
        stop
        start
        ;;
    *)
        echo $"Usage: $0 {start|stop|restart}"
        exit 1
esac

exit 0
