#!/bin/bash ############################################################################### # # # IPFire.org - A linux based firewall # # Copyright (C) 2012 IPFire Network Development Team # # # # This program is free software: you can redistribute it and/or modify # # it under the terms of the GNU General Public License as published by # # the Free Software Foundation, either version 3 of the License, or # # (at your option) any later version. # # # # This program is distributed in the hope that it will be useful, # # but WITHOUT ANY WARRANTY; without even the implied warranty of # # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # # GNU General Public License for more details. # # # # You should have received a copy of the GNU General Public License # # along with this program. If not, see . # # # ############################################################################### NETWORK_DHCP_DUID_FILE="${NETWORK_CONFIG_DIR}/dhcp-duid" dhclient_start() { local interface=${1} local proto=${2} assert isset interface assert device_exists ${interface} local service=$(dhclient_proto2service ${proto} ${interface}) service_start ${service} } dhclient_stop() { local interface=${1} local proto=${2} local service=$(dhclient_proto2service ${proto} ${interface}) service_stop ${service} } dhclient_status() { local interface=${1} local proto=${2} local service=$(dhclient_proto2service ${proto} ${interface}) service_status ${service} } dhclient_proto2service() { local proto=${1} assert isset proto local interface=${2} assert isset interface local service case "${proto}" in ipv4) service="dhclient4@${interface}.service" ;; ipv6) service="dhclient6@${interface}.service" ;; *) return ${EXIT_ERROR} ;; esac assert isset service echo "${service}" return ${EXIT_OK} } dhclient_write_config() { local interface="${1}" shift assert isset interface local hostname local vendor local config_file local leases_file while [ $# -gt 0 ]; do case "${1}" in --config-file=*) config_file="$(cli_get_val "${1}")" ;; --hostname=*) hostname="$(cli_get_val "${1}")" ;; --leases-file=*) leases_file="$(cli_get_val "${1}")" ;; --vendor=*) vendor="$(cli_get_val "${1}")" ;; *) log WARNING $"Unknown configuration option passed: ${1}." ;; esac shift done assert isset config_file # Set default values if ! isset hostname; then hostname="$(config_hostname)" fi if ! isset vendor; then vendor="$(distro_get_pretty_name)" fi # Clear configuration file (if any). mkdir -p $(dirname ${config_file}) 2>/dev/null # Print the header. config_header "dhclient daemon configuration file for ${interface}" \ > "${config_file}" # Global options. fappend "${config_file}" "send vendor-class-identifier \"${vendor}\";" fappend "${config_file}" # empty line # Interface options. ( echo "interface \"${interface}\" {" if isset hostname; then echo " send host-name \"${hostname}\";" print fi echo "}" ) >> "${config_file}" # Update leases file if isset leases_file; then __dhclient_update_leases_file "${leases_file}" || return $? fi return ${EXIT_OK} } dhclient_get_duid() { # If the DUID already exists, we do not do anything at all. if [ -s "${NETWORK_DHCP_DUID_FILE}" ]; then print "$(<${NETWORK_DHCP_DUID_FILE})" return ${EXIT_OK} fi # If no DUID exists, we will need to create a new one local duid="$(dhclient_generate_duid)" log DEBUG "Created new DHCP DUID: ${duid}" # Save the new DUID to file and return it print "${duid}" > "${NETWORK_DHCP_DUID_FILE}" print "${duid}" return ${EXIT_OK} } dhclient_generate_duid() { # Find lowest MAC/link-local address local address="$(ports_lowest_address)" # Use a random MAC address if no physical address could # be found. if ! isset address; then log WARNING "Could not determine the lowest MAC/link-local address" address="$(mac_generate)" fi log DEBUG "Using '${address}' to generate the DHCP DUID" print "00030001${address//\:/}" return ${EXIT_OK} } __dhclient_update_leases_file() { local file="${1}" local duid="$(dhclient_get_duid)" if [ -e "${leases_file}" ]; then local old_duid="$(__dhclient_get_duid_from_leases_file "${leases_file}")" if [ "${duid}" = "${old_duid}" ]; then log DEBUG "DUID in leases file matches. Nothing to do" return ${EXIT_OK} fi fi # If the leases file does not exist, yet, or the # DUID in there is different, we will create/overwrite # the leases file with the correct DUID. ( printf "default-duid \"" local i=0 while [ ${i} -lt ${#duid} ]; do printf "\\\\\\\\" printf "x${duid:${i}:2}" i=$(( ${i} + 2 )) done print "\";" ) > "${leases_file}" return ${EXIT_OK} } __dhclient_get_duid_from_leases_file() { local file="${1}" # Do nothing if the leases file cannot be read [ -r "${file}" ] || return ${EXIT_OK} local line while read line; do if [[ ${line} =~ ^default-duid ]]; then line="${line/default-duid/}" line="${line//\\\\x/}" line="${line//;/}" line="$(strip "${line}")" unquote "${line}" return ${EXIT_OK} fi done < "${file}" return ${EXIT_ERROR} }