#!/bin/bash

# Copyright Jean-Philippe Guillemin <jp.guillemin@free.fr>. This program is free software; you can redistribute
# it and/or modify it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or (at your option)
# any later version. Please take a look at http://www.gnu.org/copyleft/gpl.htm
# Copyright Jean-Philippe Guillemin <jp.guillemin@free.fr>. This program is free software; you can redistribute
# it and/or modify it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or (at your option)
# any later version. Please take a look at http://www.gnu.org/copyleft/gpl.htm
#
# Xnetconf is a complete GTK network configuration tool for Zenwalk Linux
#

# version="1.1"


getIlist(){
for ((i=0; i <= $MAXNICS ; i++)) ; do
  [ ! -d /sys/class/net/eth${i} ] && continue

  IF="eth${i}"

  if [[ "$( /sbin/ifconfig -s | grep ${IF} )" && "$( cat /sys/class/net/${IF}/carrier 2>/dev/null )" = "1" ]] ; then
    state="up"
  else
    state="down"
  fi
	
  echo "${IF} | ${state}" 
done
}

getIP(){
  echo "$(ifconfig $IF | grep inet | awk '{print $2}' | sed -e 's/^.*addr:\([0-9\.]*\)$/\1/')"
}

getMASK(){
  echo "$(ifconfig $IF | grep inet | awk '{print $4}' | sed -e 's/^.*Mask:\([0-9\.]*\)$/\1/')"
}

getDHCP(){
  . $inetconf
  i="${IF##eth}"
  if [ "${USE_DHCP[$i]}" = "yes" ]; then
    echo "true"
  else
    echo "false"
  fi
}

getFW(){
  . $inetconf
  if [ "${NETFILTER}" = "yes" ]; then
    echo "true"  
  else
    echo "false"
  fi
}

getDHCPDNS(){
  . $inetconf
  i="${IF##eth}"
  if [ "${USE_DHCP[$i]}" != "yes" ]; then
    echo "false"
    return    
  fi
  
  if [ "${DHCP_KEEPRESOLV[$i]}" != "yes" ]; then
    echo "true"
  else
    echo "false"
  fi
}

getDHCPGW(){
  . $inetconf
  i="${IF##eth}"
  if [ "${USE_DHCP[$i]}" != "yes" ]; then
    echo "false"
    return    
  fi
  
  if [ "${DHCP_KEEPGW[$i]}" != "yes" ]; then
    echo "true"
  else
    echo "false"
  fi
}

getGATEWAY(){
  GW="$(route -n | grep "^0\.0\.0\.0.*" | sed -e 's/^[0\.]*[ \t]*\([0-9\.]*\)[ \t]*[0\.]*[ \t]*.*$/\1/')"
  if [ "$GW" ]; then
    echo $GW
  else
    . $inetconf 
    echo $GATEWAY
  fi
}

getINFO(){
  [ ! "$IF" ] && return
  mac="$( cat /sys/class/net/$IF/address 2>/dev/null )"
  driver="$(ethtool -i $IF 2>/dev/null | grep "^driver:" | cut -d ":" -f 2 )"
  duplex="$(ethtool $IF 2>/dev/null | grep "Duplex:" | cut -d ":" -f 2 )"
  speed="$(ethtool $IF 2>/dev/null | grep "Speed:" | cut -d ":" -f 2 )"
  echo -e "MAC address : $mac \nDriver : $driver \nDuplex mode : $duplex\nSpeed : $speed"
}

getDNS1(){
  echo "$( grep '^nameserver' $resolv \
  | grep 'nameserver' -n | grep -e "^1:" \
  | sed -e 's/1:nameserver[ \t]*\(.*\)$/\1/')"
}

getDNS2(){
  echo "$( grep '^nameserver' $resolv \
  | grep 'nameserver' -n | grep -e "^2:" \
  | sed -e 's/2:nameserver[ \t]*\(.*\)$/\1/')"
}

getHOST(){
  cut -d. -f1 -s $hostnamefile
}

getDOMAIN(){
  cut -d. -f2- -s $hostnamefile
}

###############################################
# Record parameter $1 number $2 with new value $3

recordipconf() {

  if [ "$(grep "$1\[$2\]" $inetconf)" ] ; then
    sed -i "s/^[\# \t]*$1\[$2\][ \t]*=.*$/$1[$2]=\"$3\"/" $inetconf
  else
    insertpoint="$(grep "\[$2\]" $inetconf | tail -n1 | cut -d "[" -f 1 | tr -d '\042')"
    if [ "$insertpoint" ] ; then
      sed -i "/.*$insertpoint\[$2\].*/i $1[$2]=\"$3\"" $inetconf
    else
      echo "$1[$2]=\"$3\"" >> $inetconf
    fi
  fi

}

###############################################
# Record parameter $1 with new value $2

recordglobalconf() {
    if [ "$(grep "$1" $inetconf)" ] ; then
      sed -i "s/^[\# \t]*$1[ \t]*=.*$/$1=\"$2\"/" $inetconf
    else
      echo "$1=\"$2\"" >> $inetconf
    fi

}

###############################################
# Apply configuration

apply() {
	
  if [ ! "$IF" ]; then 
    echo "No selected interface !"
    sleep 0.5
    echo 100   
    return
  fi
  echo "Saving and applying network configuration"

  # We get the number of the nic
  i="${IF##eth}"

  # You want to configure this interface, so ...
  /sbin/ifconfig $IF up 1>&2 2>/dev/null
 
  # DHCP STATUS ?
  if [ "$DHCP" = "true" ]; then
    echo 10  
    $dhcpclient -k -d $IF 1>&2 2>/dev/null
    recordipconf USE_DHCP $i yes
    echo 30 
    
    if [ "$DHCPDNS" = "true" ]; then
      for ((j=0; j <= $MAXNICS ; j++)) ; do
        [ ! -d /sys/class/net/eth${j} ] && continue
        recordipconf DHCP_KEEPRESOLV $j no
        recordipconf DHCP_KEEPNTP $j no 
      done 
    else
      DHCPOPTIONS="$DHCPOPTIONS -R"   
      for ((j=0; j <= $MAXNICS ; j++)) ; do
        [ ! -d /sys/class/net/eth${j} ] && continue
        recordipconf DHCP_KEEPRESOLV $j yes
        recordipconf DHCP_KEEPNTP $j yes 
      done     
    fi

    if [ "$DHCPGW" = "true" ]; then 
      for ((j=0; j <= $MAXNICS ; j++)) ; do
        [ ! -d /sys/class/net/eth${j} ] && continue
        recordipconf DHCP_KEEPGW $j no   
      done  
      /sbin/route del -net 0.0.0.0 1>&2 2>/dev/null 
    else
      DHCPOPTIONS="$DHCPOPTIONS -G"
      for ((j=0; j <= $MAXNICS ; j++)) ; do
        [ ! -d /sys/class/net/eth${j} ] && continue
        recordipconf DHCP_KEEPGW $j yes   
      done      
    fi    

    # Actually launch DHCP
    sleep 0.2
    $dhcpclient -d -t 10 $DHCPOPTIONS $IF 1>&2 2>/dev/null 
    
    
    echo 60      
    sleep 0.2
     
    # GATEWAY
    if [ "$DHCPGW" != "true" ]; then    
      /sbin/route del -net 0.0.0.0 1>&2 2>/dev/null    
      /sbin/route add -net 0.0.0.0 netmask 0.0.0.0 gw $GATEWAY metric 1 1>&2 2>/dev/null 
      recordglobalconf GATEWAY $GATEWAY
    fi
    
    echo 70 
    sleep 0.2
              
    # Static DNS
    if [ "$DHCPDNS" != "true" ]; then  
	  echo -n "" > $resolv
      [ "$DNS1" ] && echo "nameserver $DNS1" >> $resolv
      [ "$DNS2" ] && echo "nameserver $DNS2" >> $resolv 
    fi
    
    echo 80     
      
  else
    echo 10  
    
    # In case dhcpcd is running
    $dhcpclient -k -d $IF 1>&2 2>/dev/null
     
    # set interface parameters
    if [ ! "$MASK" ]; then
      [ "$(echo $IP | grep -e "^192\.168" )" ] && MASK='255.255.255.0'
      [ "$(echo $IP | grep -e "^172\.16" )" ] && MASK='255.255.0.0'
      [ "$(echo $IP | grep -e "^10\." )" ] && MASK='255.0.0.0'
    fi
    BROADCAST="$( /bin/ipmask $MASK $IP | cut -f1 -d' ' )"
    /sbin/ifconfig $IF $IP broadcast $BROADCAST netmask $MASK 1>&2 2>/dev/null
    /sbin/route del -net 0.0.0.0 1>&2 2>/dev/null
    /sbin/route add -net 0.0.0.0 netmask 0.0.0.0 gw $GATEWAY metric 1 1>&2 2>/dev/null 
    sleep 0.2    
    echo 30     

    # save interface parameters        
    recordipconf IPADDR $i $IP   
    recordipconf NETMASK $i $MASK    
    recordipconf USE_DHCP $i no  
    recordglobalconf GATEWAY $GATEWAY  
    sleep 0.2      
    echo 60 
      
    # DNS
	echo -n "" > $resolv
    [ "$DNS1" ] && echo "nameserver $DNS1" >> $resolv
    [ "$DNS2" ] && echo "nameserver $DNS2" >> $resolv 
    sleep 0.2       
    echo 80  
  fi
  
  # hosts file
  noloopback="$(grep -v "^127.0.0.1" $hosts)"
  echo "$noloopback" > $hosts
  echo "127.0.0.1		localhost" >> $hosts
  if [ "$DOMAIN" ]; then
    echo "127.0.0.1		$HOST.$DOMAIN $HOST" >> $hosts
  else
    echo "127.0.0.1		$HOST" >> $hosts
  fi

  # Search domain in resolv.conf
    [ "$DOMAIN" ] && sed -i "1isearch $DOMAIN" $resolv
    [ "$DOMAIN" ] && sed -i "1idomain $DOMAIN" $resolv

  # HOSTNAME file
  if [ "$DOMAIN" ]; then
    echo "$HOST.$DOMAIN" > $hostnamefile
  else
    echo "$HOST" > $hostnamefile
  fi
  
  echo 90

  
  # Apply the firewall policy if selected
  if [ "$FW" = "true" ]; then
  
    recordglobalconf NETFILTER "yes" 
    
    /sbin/modprobe ip_tables
    /sbin/modprobe iptable_filter
    /sbin/modprobe iptable_nat
    /sbin/modprobe ip_conntrack
    /sbin/modprobe ipt_state
    /sbin/modprobe ip_conntrack_ftp
    
    # Anti-spoofing
    if [ -e /proc/sys/net/ipv4/conf/all/rp_filter ] ; then
      for flag in /proc/sys/net/ipv4/conf/*/rp_filter ; do
        echo 1 > $flag 
      done
    fi    
    
    if [ -e /etc/netfilter/policy.netfilter ]; then
      /usr/sbin/iptables-restore < /etc/netfilter/policy.netfilter
    else
    
      /usr/sbin/iptables -t filter -D INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT 1>&2 2>/dev/null
      /usr/sbin/iptables -t filter -D OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT 1>&2 2>/dev/null
      /usr/sbin/iptables -t filter -D FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT 1>&2 2>/dev/null
      /usr/sbin/iptables -t filter -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
      /usr/sbin/iptables -t filter -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
      /usr/sbin/iptables -t filter -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
      /usr/sbin/iptables -t filter -D INPUT -i lo -j ACCEPT 1>&2 2>/dev/null
      /usr/sbin/iptables -t filter -A INPUT -i lo -j ACCEPT
      /usr/sbin/iptables -t filter -D OUTPUT -o lo -j ACCEPT 1>&2 2>/dev/null
      /usr/sbin/iptables -t filter -A OUTPUT -o lo -j ACCEPT
      
      # INPUT ####################################################    
      /usr/sbin/iptables -t filter -D INPUT -j DROP 1>&2 2>/dev/null  
      /usr/sbin/iptables -t filter -A INPUT -j DROP  
      
      # OUTPUT ####################################################
      /usr/sbin/iptables -t filter -D OUTPUT -j ACCEPT
      /usr/sbin/iptables -t filter -A OUTPUT -j ACCEPT
      
      # We save the policy ########################################
      mkdir -p /etc/netfilter 1>&2 2>/dev/null
      /usr/sbin/iptables-save > /etc/netfilter/policy.netfilter
    fi  
 
  else
    
    recordglobalconf NETFILTER "no" 

    # Flush and delete rules 
    for TABLE in filter nat mangle; do
      iptables -t $TABLE -F 1>&2 2>/dev/null
      iptables -t $TABLE -X 1>&2 2>/dev/null
    done
    
    for CHAIN in INPUT OUTPUT FORWARD; do
      iptables -t filter -P $CHAIN ACCEPT 1>&2 2>/dev/null
    done    

    # Disable anti-spoofing
    if [ -e /proc/sys/net/ipv4/conf/all/rp_filter ] ; then
      for flag in /proc/sys/net/ipv4/conf/*/rp_filter ; do
        echo 0 > $flag 
      done
    fi  

  fi
  
  echo 100
}
