312 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
			
		
		
	
	
			312 lines
		
	
	
		
			6.8 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 "Activating saved IP address configuration ..."
 | 
						|
 | 
						|
    # Lock to avoid conflicting changes.
 | 
						|
    lock_config || exit 1
 | 
						|
 | 
						|
    # Persistent configuration file has already been copied from SD card.
 | 
						|
    # 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
 | 
						|
    ;;
 | 
						|
  *)
 | 
						|
    script="${0##*/}"
 | 
						|
    cat <<EOF
 | 
						|
Usage: $script {init|show|config|save|restart}
 | 
						|
 | 
						|
Manage IP address configuration.
 | 
						|
 | 
						|
  $script init
 | 
						|
    Initialize IP address from saved configuration.
 | 
						|
    This command is used during boot and should not be invoked manually.
 | 
						|
 | 
						|
  $script show
 | 
						|
    Display active and saved IP address configuration.
 | 
						|
 | 
						|
  $script 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.
 | 
						|
 | 
						|
  $script 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 $?
 | 
						|
 |