Add script for IP address configuration
This commit is contained in:
		
							parent
							
								
									5ceb5ad882
								
							
						
					
					
						commit
						c3398e9e1d
					
				|  | @ -1,5 +1,6 @@ | |||
| devicetree/devicetree.dtb | ||||
| buildroot_overlay/opt/ | ||||
| buildroot_overlay/opt/puzzlefw/bin/puzzlecmd | ||||
| buildroot_overlay/opt/puzzlefw/driver/ | ||||
| downloads/ | ||||
| buildroot-2023.02.8/ | ||||
| u-boot/ | ||||
|  |  | |||
|  | @ -0,0 +1,310 @@ | |||
| #!/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 $? | ||||
| 
 | ||||
|  | @ -0,0 +1,63 @@ | |||
| # | ||||
| # Settings and functions for shell scripts. | ||||
| # | ||||
| 
 | ||||
| CONFIG_PARTITION=mmcblk0p2 | ||||
| CONFIG_MOUNTPOINT=/mnt/cfg | ||||
| CONFIG_DIR=/var/lib/puzzlefw/cfg | ||||
| 
 | ||||
| # Lock the configuration files. | ||||
| lock_config() { | ||||
| 
 | ||||
|     # Make config directory in RAM filesystem. | ||||
|     mkdir -p $CONFIG_DIR | ||||
| 
 | ||||
|     # Create or open lock file. | ||||
|     # The file remains open until the calling script ends. | ||||
|     exec 3>>${CONFIG_DIR}/lockfile | ||||
| 
 | ||||
|     # Get exclusive lock on the file. | ||||
|     if ! flock -n 3 ; then | ||||
|         echo "ERROR: Configuration locked" >&2 | ||||
|         return 1 | ||||
|     fi | ||||
| } | ||||
| 
 | ||||
| # Read configuration files from the SD card. | ||||
| # This is only used during boot. | ||||
| read_config() { | ||||
| 
 | ||||
|     # Mount config filesystem read-only. | ||||
|     mkdir -p $CONFIG_MOUNTPOINT | ||||
|     mount -t ext4 -r -o noatime,data=journal /dev/${CONFIG_PARTITION} $CONFIG_MOUNTPOINT || return 1 | ||||
| 
 | ||||
|     # Copy config files to RAM filesystem. | ||||
|     cp -a ${CONFIG_MOUNTPOINT}/*.conf $CONFIG_DIR | ||||
| 
 | ||||
|     umount $CONFIG_MOUNTPOINT | ||||
| } | ||||
| 
 | ||||
| # Write changed configuration files to the SD card. | ||||
| # Parameters: names of config files to synchronize | ||||
| sync_config() { | ||||
| 
 | ||||
|     # Mount config filesystem. | ||||
|     mkdir -p $CONFIG_MOUNTPOINT | ||||
|     mount -t ext4 -o noatime,data=journal /dev/${CONFIG_PARTITION} $CONFIG_MOUNTPOINT || return 1 | ||||
| 
 | ||||
|     for fname in "$@" ; do | ||||
| 
 | ||||
|         # Copy new version of file to SD card. | ||||
|         cp ${CONFIG_DIR}/${fname}.new $CONFIG_MOUNTPOINT | ||||
| 
 | ||||
| 	# Atomically replace the old file on the SD card. | ||||
| 	mv ${CONFIG_MOUNTPOINT}/${fname}.new ${CONFIG_MOUNTPOINT}/${fname} | ||||
| 
 | ||||
| 	# Replace the old file in te RAM filesystem. | ||||
| 	mv ${CONFIG_DIR}/${fname}.new ${CONFIG_DIR}/${fname} | ||||
|     done | ||||
| 
 | ||||
|     umount $CONFIG_MOUNTPOINT | ||||
|     sync | ||||
| } | ||||
| 
 | ||||
		Loading…
	
		Reference in New Issue