#!/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 $?