#!/bin/bash # # This script is triggered by udhcpc and handle the DHCP information # given to this script as parameters. export PATH=$PATH:/opt/openslx/sbin:/opt/openslx/bin . /opt/openslx/config if [ -z "$SLX_PXE_NETIF" ]; then echo "Missing PXE network interface information." exit 1 fi MAIN_NETIF="$SLX_PXE_NETIF" [ -n "$SLX_VLAN_ID" ] && MAIN_NETIF="${SLX_PXE_NETIF}.${SLX_VLAN_ID}" [ -n "$SLX_BRIDGE" ] && MAIN_NETIF="$SLX_BRIDGE" readonly MAIN_NETIF RESOLV_CONF="/opt/openslx/resolv.conf" THIS_RESOLV="/run/network/${MAIN_NETIF}.resolv" rebuild_resolv_conf () { # Don't do anything if the active resolv.conf is not ours # Also this will not run resolvconf update.d... No idea if we should still do so... [ -L "/etc/resolv.conf" ] || return 0 [ "x$(readlink "/etc/resolv.conf")" == "x${RESOLV_CONF}" ] || return 0 # Maybe make this smarter some time, if anyone is using clients that are on multiple networks at once etc... # This is a little braindead but should work most of the time sort -u /run/network/*.resolv > "$RESOLV_CONF" 2> /dev/null # add support for resolv.conf update scripts // see man(8) resolvconf for s in /etc/resolvconf/update.d/*.sh; do [ -f "$s" ] && [ -x "$s" ] && "$s" done } escape_search() { echo "$@" | sed -e 's/[]\/()$*.^|[]/\\&/g' } escape_replace() { echo "$@" | sed -e 's/[\/&]/\\&/g' } check_env() { if [ -z "$ip" ] || [ -z "$subnet" ] || [ -z "$interface" ]; then echo "$1 event with missing data" >&2 echo "ip = '$ip'" >&2 echo "subnet = '$subnet'" >&2 echo "interface = '$interface'" >&2 exit 1 fi # only run for the boot network interface # TODO VLAN support if [ "$interface" != "$MAIN_NETIF" ]; then echo "Ignoring '$interface'..." exit 1 fi } case "$1" in bound|renew) check_env "$1" # Set address on interface ip addr add "$ip/$(ipcalc -s -p "$ip" "$subnet" | sed s/.*=//)" dev "$interface" # Set default route, if given if [ -n "$router" ]; then ip route replace default via "$router" fi # get domain, hostname and thus fqdn from DNS dns_fqdn=$(busybox timeout -t 3 rdns "$ip") dns_short="${dns_fqdn%%.*}" # check if it is fqdn if [ "$dns_fqdn" == "$dns_short" ]; then unset dns_fqdn dns_short fi # Update resolver configuration file conf_file="$(mktemp)" # Own domain suffix if [ -n "$domain" ]; then : elif [ -n "$dns_fqdn" ]; then domain="${dns_fqdn#*.}" elif [ -n "$SLX_NET_DOMAIN" ]; then domain="$SLX_NET_DOMAIN" fi if [ -n "$domain" ]; then echo "domain ${domain%% *}" >> "${conf_file}" fi # Add domain to list of search domains if not in there yet if [ -n "$domain" ] && [ -n "$search" ]; then FOUND=no for sd in $search; do [ "x$sd" = "x$domain" ] && FOUND=yes done [ "$FOUND" = "no" ] && search="$domain $search" elif [ -n "$domain" ]; then search="$domain" fi # Search domains if [ -n "$search" ]; then echo "search $search" >> "${conf_file}" elif [ -n "$SLX_NET_SEARCH" ]; then echo "search $SLX_NET_SEARCH" >> "${conf_file}" elif [ -n "$SLX_NET_DOMAIN" ]; then echo "search $SLX_NET_DOMAIN" >> "${conf_file}" fi for i in $dns; do echo "$0: Adding DNS $i" echo "nameserver $i" >> "${conf_file}" done if [ -x "/sbin/resolvconf" ] && [ -L "/etc/resolv.conf" ] && [ -d "/etc/resolvconf/update.d" ]; then # Automatic handling :-) resolvconf --create-runtime-directories resolvconf --enable-updates < "$conf_file" resolvconf -a "${interface}.udhcpc" rm -- "$conf_file" else # Manual handling required :-( mv -f "$conf_file" "$THIS_RESOLV" rebuild_resolv_conf fi # TODO: check if we really want/need to overwrite the PXE_IP, # it might be better/clearer to change the SLX_DHCP_CLIENT_IP... sed -i "s/^\(SLX_PXE_CLIENT_IP=\).*$/\1'$ip'/" /opt/openslx/config # Write DOMAIN and SEARCH to /opt/openslx/config if empty if [ -z "$SLX_NET_DOMAIN" ] && [ -n "$domain" ]; then sed -i "/^SLX_NET_DOMAIN=/d" /opt/openslx/config echo "SLX_NET_DOMAIN='$domain'" >> /opt/openslx/config fi if [ -z "$SLX_NET_SEARCH" ] && [ -n "$search" ]; then sed -i "/^SLX_NET_SEARCH=/d" /opt/openslx/config echo "SLX_NET_SEARCH='$search'" >> /opt/openslx/config fi # Same for WINS servers if [ -z "$SLX_NET_WINS" ] && [ -n "$wins" ]; then sed -i "/^SLX_NET_WINS=/d" /opt/openslx/config echo "SLX_NET_WINS='$wins'" >> /opt/openslx/config fi # TODO find a better way to trigger additional code, hook dir? # Update /etc/issue for proper spacing [ -x "/opt/openslx/scripts/openslx-create_issue" ] && /opt/openslx/scripts/openslx-create_issue # Remove any stray addresses; we expect the primary interface to only have one # address supplied via DHCP. We do this after adding the new one, obviously. rem_list=$( ip -o addr show "$interface" | awk '{ for (i=1;i "/proc/sys/net/ipv4/conf/$interface/promote_secondaries" for addr in $rem_list; do ip addr del "$addr" dev "$interface" sed -i "/^$(escape_search "${addr%/*}")(\s|$)/d" /etc/hosts done fi # Write to openslx-config echo "# Config written by openslx-dhcp-script (2)" >> /opt/openslx/config sed -i "/^SLX_DNS=/d" /opt/openslx/config echo "SLX_DNS='$dns'" >> /opt/openslx/config ;; deconfig) check_env "$1" if [ "$interface" = "$primary" ]; then echo "Ignoring deconfig for primary interface" else echo 1 > "/proc/sys/net/ipv4/conf/$interface/promote_secondaries" clientip=${ip%%:*} ip addr del "$clientip/$(ipcalc -s -p "$clientip" "$subnet" | sed s/.*=//)" dev "$interface" sed -i "/^$(escape_search "$ip")(\s|$)/d" /etc/hosts fi if [ -x /sbin/resolvconf ] && [ -L /etc/resolv.conf ] && [ -d /etc/resolvconf/update.d ]; then # Automatic handling :-) resolvconf -d "${interface}.udhcpc" else # Manual handling required :-( rm -f -- "$THIS_RESOLV" rebuild_resolv_conf fi ;; leasefail) echo "$0: Lease failed: $message" >&2 ;; nak) echo "$0: Received a NAK: $message" >&2 ;; *) echo "$0: Unknown udhcpc command: $1" >&2 exit 1 ;; esac exit 0