311 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
			
		
		
	
	
			311 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
| #!/bin/sh
 | |
| #
 | |
| # Manage IP address configuration.
 | |
| #
 | |
| # The IP address configuration exists in 3 places:
 | |
| #
 | |
| #  - The persistent configuration is stored in network.conf on
 | |
| #    the configuration partition of the SD card.
 | |
| #    This configuration is activated on boot.
 | |
| #
 | |
| #    The syntax of this file is as follows:
 | |
| #
 | |
| #      MODE=dhcp / MODE=static
 | |
| #      IPADDR=172.16.3.4
 | |
| #      NETMASK=255.255.0.0
 | |
| #      GATEWAY=172.16.0.1
 | |
| #
 | |
| #  - The active configuration, which determines the actual IP address,
 | |
| #    is stored in /var/lib/puzzlefw/cfg/network_active.conf in
 | |
| #    the RAM filesystem. It has the same format as described above.
 | |
| #
 | |
| #    The same information is also present in /etc/network/interfaces.
 | |
| #
 | |
| 
 | |
| . /opt/puzzlefw/lib/functions.sh
 | |
| 
 | |
| # Load the persistent or active configuration.
 | |
| #   $1 = file name to read
 | |
| load_network_config() {
 | |
| 
 | |
|     if [ ! -f ${CONFIG_DIR}/${1} ]; then
 | |
|         echo "ERROR: File not found ${CONFIG_DIR}/${1}" >&2
 | |
|         exit 1
 | |
|     fi
 | |
| 
 | |
|     . ${CONFIG_DIR}/${1}
 | |
| }
 | |
| 
 | |
| # Write configuration to file.
 | |
| #   $1 = file name to write
 | |
| write_network_config() {
 | |
| 
 | |
|     mkdir -p ${CONFIG_DIR}
 | |
| 
 | |
|     cat >${CONFIG_DIR}/${1} <<EOF
 | |
| MODE=${MODE}
 | |
| IPADDR=${IPADDR}
 | |
| NETMASK=${NETMASK}
 | |
| GATEWAY=${GATEWAY}
 | |
| EOF
 | |
| }
 | |
| 
 | |
| # Write /etc/network/interfaces
 | |
| write_network_interfaces() {
 | |
| 
 | |
|     IF_METHOD="dhcp"
 | |
|     IF_ADDRESS=""
 | |
|     IF_NETMASK=""
 | |
|     IF_GATEWAY=""
 | |
| 
 | |
|     if [ "$MODE" = "static" ]; then
 | |
|         IF_METHOD="static"
 | |
|         IF_ADDRESS="    address ${IPADDR}"
 | |
| 	IF_NETMASK="    netmask ${NETMASK}"
 | |
|         if [ -n "$GATEWAY" ]; then
 | |
|             IF_GATEWAY="    gateway ${GATEWAY}"
 | |
|         fi
 | |
|     fi
 | |
| 
 | |
|     echo "Writing /etc/network/interfaces ..."
 | |
|     cat >/etc/network/interfaces.new <<EOF
 | |
| 
 | |
| auto lo
 | |
| iface lo inet loopback
 | |
| 
 | |
| auto eth0
 | |
| iface eth0 inet $IF_METHOD
 | |
| $IF_ADDRESS
 | |
| $IF_NETMASK
 | |
| $IF_GATEWAY
 | |
| EOF
 | |
| 
 | |
|     mv /etc/network/interfaces.new /etc/network/interfaces
 | |
| }
 | |
| 
 | |
| # Initialize configuration from SD card.
 | |
| ipcfg_init() {
 | |
| 
 | |
|     echo "Loading IP address configuration from SD card ..."
 | |
| 
 | |
|     # Copy configuration from SD card.
 | |
|     lock_config || exit 1
 | |
|     read_config || exit 1
 | |
| 
 | |
|     # Copy persistent configuration to active configuration.
 | |
|     cp -a ${CONFIG_DIR}/network.conf ${CONFIG_DIR}/network_active.conf
 | |
| 
 | |
|     # Load persistent configuration.
 | |
|     load_network_config network.conf
 | |
| 
 | |
|     # Write /etc/network/interfaces
 | |
|     write_network_interfaces
 | |
| }
 | |
| 
 | |
| # Show loaded network configuration.
 | |
| show_network_config() {
 | |
|     echo "    Mode:       $MODE"
 | |
|     if [ "$MODE" = "static" ]; then
 | |
|         echo "    IP address: $IPADDR"
 | |
|         echo "    Netmask:    $NETMASK"
 | |
|         echo "    Gateway:    $GATEWAY"
 | |
|     fi
 | |
| }
 | |
| 
 | |
| # Display configuration.
 | |
| ipcfg_show() {
 | |
| 
 | |
|     load_network_config network_active.conf
 | |
|     echo "Active IP address configuration:"
 | |
|     show_network_config
 | |
| 
 | |
|     load_network_config network.conf
 | |
|     echo "Saved IP address configuration:"
 | |
|     show_network_config
 | |
| }
 | |
| 
 | |
| # Check that parameter is a well-formed IPv4 address.
 | |
| check_ipaddr() {
 | |
|     IFS="." read a b c d <<EOF
 | |
| $1
 | |
| EOF
 | |
|     for i in "$a" "$b" "$c" "$d" ; do
 | |
|         if ! [ "$i" -ge 0 -a "$i" -le 255 ]; then
 | |
|             echo "ERROR: Invalid IP address '$1'" >&2
 | |
|             exit 1
 | |
|         fi
 | |
|     done
 | |
| }
 | |
| 
 | |
| # Check that parameter is a valid IPv4 netmask.
 | |
| check_netmask() {
 | |
|     IFS="." read a b c d <<EOF
 | |
| $1
 | |
| EOF
 | |
|     netmask_force_zero=0
 | |
|     for i in "$a" "$b" "$c" "$d" ; do
 | |
|         if [ "$netmask_force_zero" = "1" -a "$i" != "0" ]; then
 | |
|             echo "ERROR: Invalid netmask '$1'" >&2
 | |
|             exit 1
 | |
|         fi
 | |
|         if [ "$i" != "255" ]; then
 | |
|             netmask_force_zero=1
 | |
|             netmask_ok=0
 | |
|             for k in 254 252 248 240 224 192 128 0 ; do
 | |
|                 if [ "$i" = "$k" ]; then
 | |
|                     netmask_ok=1
 | |
|                 fi
 | |
|             done
 | |
| 	    if [ "$netmask_ok" != "1" ]; then
 | |
|                 echo "ERROR: Invalid netmask '$1'" >&2
 | |
|                 exit 1
 | |
|             fi
 | |
|         fi
 | |
|     done
 | |
| }
 | |
| 
 | |
| # Parse IP address options.
 | |
| parse_options() {
 | |
| 
 | |
|     while [ -n "$1" ]; do
 | |
| 
 | |
|         case "$1" in
 | |
| 
 | |
|           --mode)
 | |
|             if [ "$2" != "dhcp" -a "$2" != "static" ]; then
 | |
|                 echo "ERROR: Unknown mode '$2'" >&2
 | |
|                 exit 1
 | |
|             fi
 | |
|             MODE="$2"
 | |
|             ;;
 | |
| 
 | |
|           --ipaddr)
 | |
|             check_ipaddr "$2"
 | |
|             IPADDR="$2"
 | |
|             ;;
 | |
| 
 | |
|           --netmask)
 | |
|             check_netmask "$2"
 | |
|             NETMASK="$2"
 | |
|             ;;
 | |
| 
 | |
|           --gateway)
 | |
|             [ -z "$2" ] || check_ipaddr "$2"
 | |
|             GATEWAY="$2"
 | |
|             ;;
 | |
| 
 | |
|           *)
 | |
|             echo "ERROR: Unknown option '$1'" >&2
 | |
|             exit 1
 | |
|         esac
 | |
| 
 | |
|         shift 2
 | |
|     done
 | |
| 
 | |
|     if [ -z "$MODE" ]; then
 | |
|         echo "ERROR: Missing mode" >&2
 | |
|         exit 1
 | |
|     fi
 | |
| 
 | |
|     if [ "$MODE" = "static" ]; then
 | |
|         if [ -z "$IPADDR" ]; then
 | |
|             echo "ERROR: Missing IP address" >&2
 | |
|             exit 1
 | |
|         fi
 | |
|         if [ -z "$NETMASK" ]; then
 | |
|             echo "ERROR: Missing netmask" >&2
 | |
|             exit 1
 | |
|         fi
 | |
|     else
 | |
|         IPADDR=""
 | |
| 	NETMASK=""
 | |
| 	GATEWAY=""
 | |
|     fi
 | |
| }
 | |
| 
 | |
| # Change active IP address configuration.
 | |
| ipcfg_config() {
 | |
| 
 | |
|     # Lock to avoid conflicting changes.
 | |
|     lock_config || exit 1
 | |
| 
 | |
|     echo "Changing active IP address configuration ..."
 | |
| 
 | |
|     write_network_config network_active.conf.new
 | |
|     mv ${CONFIG_DIR}/network_active.conf.new ${CONFIG_DIR}/network_active.conf
 | |
| 
 | |
|     echo "Shutting down eth0 ..."
 | |
|     /sbin/ifdown eth0
 | |
|     sleep 2
 | |
| 
 | |
|     write_network_interfaces
 | |
| 
 | |
|     echo "Starting eth0 ..."
 | |
|     /sbin/ifup eth0 || exit 1
 | |
| }
 | |
| 
 | |
| # Change the persistent IP address configuration on the SD card.
 | |
| ipcfg_save() {
 | |
| 
 | |
|     # Lock to avoid conflicting changes.
 | |
|     lock_config || exit 1
 | |
| 
 | |
|     echo "Changing saved IP address configuration ..."
 | |
| 
 | |
|     write_network_config network.conf.new || exit 1
 | |
|     sync_config network.conf || exit 1
 | |
| }
 | |
| 
 | |
| case "$1" in
 | |
|   init)
 | |
|     ipcfg_init
 | |
|     ;;
 | |
|   show)
 | |
|     ipcfg_show
 | |
|     ;;
 | |
|   config)
 | |
|     shift
 | |
|     parse_options "$@"
 | |
|     ipcfg_config
 | |
|     ;;
 | |
|   save)
 | |
|     shift
 | |
|     parse_options "$@"
 | |
|     ipcfg_save
 | |
|     ;;
 | |
|   *)
 | |
|     cat <<EOF
 | |
| Usage: $0 {init|show|config|save|restart}
 | |
| 
 | |
| Manage IP address configuration.
 | |
| 
 | |
|   $0 init
 | |
|     Initialize IP address from saved configuration on SD card.
 | |
|     This command is used during boot and should not be invoked manually.
 | |
| 
 | |
|   $0 show
 | |
|     Display active and saved IP address configuration.
 | |
| 
 | |
|   $0 config {options}
 | |
|     Change active IP address configuration.
 | |
|     The new configuration is not written to the SD card.
 | |
| 
 | |
|     options:
 | |
|       --mode dhcp           Enable configuration via DHCP.
 | |
|       --mode static         Enable static IP address configuration.
 | |
|       --ipaddr n.n.n.n      Specify static IPv4 address.
 | |
|       --netmask n.n.n.n     Specify netmask.
 | |
|       --gateway n.n.n.n     Specify gateway address, or "" to disable gateway.
 | |
| 
 | |
|   $0 save {options}
 | |
|     Change the saved IP address configuration on the SD card.
 | |
|     Options are the same as for command 'config'.
 | |
| 
 | |
| EOF
 | |
|     exit 1
 | |
|     ;;
 | |
| esac
 | |
| 
 | |
| exit $?
 | |
| 
 |