summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'net-scripts/net/ifconfig.sh')
-rw-r--r--net-scripts/net/ifconfig.sh425
1 files changed, 425 insertions, 0 deletions
diff --git a/net-scripts/net/ifconfig.sh b/net-scripts/net/ifconfig.sh
new file mode 100644
index 0000000..6ced9e2
--- /dev/null
+++ b/net-scripts/net/ifconfig.sh
@@ -0,0 +1,425 @@
+# Copyright (c) 2004-2006 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# Contributed by Roy Marples (uberlord@gentoo.org)
+
+# Fix any potential localisation problems
+# Note that LC_ALL trumps LC_anything_else according to locale(7)
+ifconfig() {
+ LC_ALL=C /sbin/ifconfig "$@"
+}
+
+ifconfig_tunnel() {
+ LC_ALL=C /sbin/iptunnel "$@"
+}
+
+route() {
+ LC_ALL=C /sbin/route "$@"
+}
+
+# void ifconfig_depend(void)
+#
+# Sets up the dependancies for the module
+ifconfig_depend() {
+ provide interface
+}
+
+# void ifconfig_expose(void)
+#
+# Expose variables that can be configured
+ifconfig_expose() {
+ variables config routes fallback metric ifconfig \
+ ifconfig_fallback routes inet6 iface alias broadcast netmask
+}
+
+# bool ifconfig_check_installed(void)
+#
+# Returns 1 if ifconfig is installed, otherwise 0
+ifconfig_check_installed() {
+ [[ -x /sbin/ifconfig ]] && return 0
+ ${1:-false} && eerror "For ifconfig support, emerge sys-apps/net-tools"
+ return 1
+}
+
+# bool ifconfig_exists(char *interface, bool report)
+#
+# Returns 1 if the interface exists, otherwise 0
+ifconfig_exists() {
+ local e="$(ifconfig -a | grep -o "^$1")" report="${2:-false}"
+ [[ -n ${e} ]] && return 0
+
+ if ${report} ; then
+ eerror "network interface $1 does not exist"
+ eerror "Please verify hardware or kernel module (driver)"
+ fi
+
+ return 1
+}
+
+# char* cidr2netmask(int cidr)
+#
+# Returns the netmask of a given CIDR
+cidr2netmask() {
+ local cidr="$1" netmask="" done=0 i sum=0 cur=128
+ local octets frac
+
+ (( octets=cidr/8 ))
+ (( frac=cidr%8 ))
+ while [[ octets -gt 0 ]] ; do
+ netmask="${netmask}.255"
+ (( octets-- ))
+ (( done++ ))
+ done
+
+ if [[ ${done} -lt 4 ]] ; then
+ for (( i=0; i<${frac}; i++ )); do
+ (( sum+=cur ))
+ (( cur/=2 ))
+ done
+ netmask="${netmask}.${sum}"
+ (( done++ ))
+
+ while [[ ${done} -lt 4 ]] ; do
+ netmask="${netmask}.0"
+ (( done++ ))
+ done
+ fi
+
+ echo "${netmask:1}"
+}
+
+# void ifconfig_up(char *iface)
+#
+# provides a generic interface for bringing interfaces up
+ifconfig_up() {
+ ifconfig "$1" up
+}
+
+# void ifconfig_down(char *iface)
+#
+# provides a generic interface for bringing interfaces down
+ifconfig_down() {
+ ifconfig "$1" down
+}
+
+# bool ifconfig_is_up(char *iface, bool withaddress)
+#
+# Returns 0 if the interface is up, otherwise 1
+# If withaddress is true then the interface has to have an IPv4 address
+# assigned as well
+ifconfig_is_up() {
+ local check="\<UP\>" addr="${2:-false}"
+ ${addr} && check="\<inet addr:.*${check}"
+ ifconfig "$1" | tr '\n' ' ' | grep -Eq "${check}" && return 0
+ return 1
+}
+
+# void ifconfig_set_flag(char *iface, char *flag, bool enabled)
+#
+# Sets or disables the interface flag
+ifconfig_set_flag() {
+ local iface="$1" flag="$2" enable="$3"
+ ${enable} || flag="-${flag}"
+ ifconfig "${iface}" "${flag}"
+}
+
+# void ifconfig_get_address(char *interface)
+#
+# Fetch the address retrieved by DHCP. If successful, echoes the
+# address on stdout, otherwise echoes nothing.
+ifconfig_get_address() {
+ local -a x=( $( ifconfig "$1" \
+ | sed -n -e 's/.*inet addr:\([^ ]*\).*Mask:\([^ ]*\).*/\1 \2/p' ) )
+ x[1]="$(netmask2cidr "${x[1]}")"
+ [[ -n ${x[0]} ]] && echo "${x[0]}/${x[1]}"
+}
+
+# bool ifconfig_is_ethernet(char *interface)
+#
+# Return 0 if the link is ethernet, otherwise 1.
+ifconfig_is_ethernet() {
+ ifconfig "$1" | grep -q "^$1[[:space:]]*Link encap:Ethernet[[:space:]]"
+}
+
+# void ifconfig_get_mac_address(char *interface)
+#
+# Fetch the mac address assingned to the network card
+ifconfig_get_mac_address() {
+ local mac="$(ifconfig "$1" | sed -n -e \
+ 's/.*HWaddr[ \t]*\<\(..:..:..:..:..:..\)\>.*/\U\1/p')"
+ [[ ${mac} != '00:00:00:00:00:00' \
+ && ${mac} != '44:44:44:44:44:44' \
+ && ${mac} != 'FF:FF:FF:FF:FF:FF' ]] \
+ && echo "${mac}"
+}
+
+# void ifconfig_set_mac_address(char *interface, char *mac)
+#
+# Assigned the mac address to the network card
+ifconfig_set_mac_address() {
+ ifconfig "$1" hw ether "$2"
+}
+
+# int ifconfig_set_name(char *interface, char *new_name)
+#
+# Renames the interface
+# This will not work if the interface is setup!
+ifconfig_set_name() {
+ [[ -z $2 ]] && return 1
+ local current="$1" new="$2"
+
+ local mac="$(ifconfig_get_mac_address "${current}")"
+ if [[ -z ${mac} ]]; then
+ eerror "${iface} does not have a MAC address"
+ return 1
+ fi
+
+ /sbin/nameif "${new}" "${mac}"
+}
+
+# void ifconfig_get_aliases_rev(char *interface)
+#
+# Fetch the list of aliases for an interface.
+# Outputs a space-separated list on stdout, in reverse order, for
+# example "eth0:2 eth0:1"
+ifconfig_get_aliases_rev() {
+ ifconfig | grep -o "^$1:[0-9]* " | tac
+}
+
+# bool ifconfig_del_addresses(char *interface, bool onlyinet)
+#
+# Remove addresses from interface. Returns 0 (true) if there
+# were addresses to remove (whether successful or not). Returns 1
+# (false) if there were no addresses to remove.
+# If onlyinet is true then we only delete IPv4 / inet addresses
+ifconfig_del_addresses() {
+ local iface="$1" i onlyinet="${2:-false}"
+ # We don't remove addresses from aliases
+ [[ ${iface} == *:* ]] && return 0
+
+ # If the interface doesn't exist, don't try and delete
+ ifconfig_exists "${iface}" || return 0
+
+ # iproute2 can add many addresses to an iface unlike ifconfig ...
+ # iproute2 added addresses cause problems for ifconfig
+ # as we delete an address, a new one appears, so we have to
+ # keep polling
+ while ifconfig "${iface}" | grep -q -m1 -o 'inet addr:[^ ]*' ; do
+ ifconfig "${iface}" 0.0.0.0 || break
+ done
+
+ # Remove IPv6 addresses
+ if ! ${onlyinet} ; then
+ for i in $( ifconfig "${iface}" \
+ | sed -n -e 's/^.*inet6 addr: \([^ ]*\) Scope:[^L].*/\1/p' ) ; do
+ /sbin/ifconfig "${iface}" inet6 del "${i}"
+ done
+ fi
+ return 0
+}
+
+# bool ifconfig_get_old_config(char *iface)
+#
+# Returns config and config_fallback for the given interface
+ifconfig_get_old_config() {
+ local iface="$1" ifvar="$(bash_variable "$1")" i inet6
+
+ config="ifconfig_${ifvar}[@]"
+ config=( "${!config}" )
+ config_fallback="ifconfig_fallback_${ifvar}[@]"
+ config_fallback=( "${!config_fallback}" )
+ inet6="inet6_${ifvar}[@]"
+ inet6=( "${!inet6}" )
+
+ # BACKWARD COMPATIBILITY: populate the config_IFACE array
+ # if iface_IFACE is set (fex. iface_eth0 instead of ifconfig_eth0)
+ i="iface_${ifvar}"
+ if [[ -n ${!i} && -z ${config} ]]; then
+ # Make sure these get evaluated as arrays
+ local -a aliases broadcasts netmasks
+
+ # Start with the primary interface
+ config=( ${!i} )
+
+ # ..then add aliases
+ aliases="alias_${ifvars}"
+ aliases=( ${!aliases} )
+ broadcasts="broadcast_${ifvar}"
+ broadcasts=( ${!broadcasts} )
+ netmasks="netmask_${ifvar}"
+ netmasks=( ${!netmasks} )
+ for (( i=0; i<${#aliases[@]}; i++ )); do
+ config[i+1]="${aliases[i]} ${broadcasts[i]:+broadcast ${broadcasts[i]}} ${netmasks[i]:+netmask ${netmasks[i]}}"
+ done
+ fi
+
+ # BACKWARD COMPATIBILITY: check for space-separated inet6 addresses
+ [[ ${#inet6[@]} == 1 && ${inet6} == *' '* ]] && inet6=( ${inet6} )
+
+ # Add inet6 addresses to our config if required
+ [[ -n ${inet6} ]] && config=( "${config[@]}" "${inet6[@]}" )
+
+ return 0
+}
+
+# bool ifconfig_iface_stop(char *interface)
+#
+# Do final shutdown for an interface or alias.
+#
+# Returns 0 (true) when successful, non-zero (false) on failure
+ifconfig_iface_stop() {
+ # If an alias is already down, then "ifconfig eth0:1 down"
+ # will try to bring it up with an address of "down" which
+ # fails. Do some double-checking before returning error
+ # status
+ ifconfig_is_up "$1" || return 0
+ ifconfig_down "$1" && return 0
+
+ # It is sometimes impossible to transition an alias from the
+ # UP state... particularly if the alias has no address. So
+ # ignore the failure, which should be okay since the entire
+ # interface will be shut down eventually.
+ [[ $1 == *:* ]] && return 0
+ return 1
+}
+
+# bool ifconfig_pre_start(char *interface)
+#
+# Runs any pre_start stuff on our interface - just the MTU atm
+# We set MTU twice as it may be needed for DHCP - a dhcp client could
+# change it in error, so we set MTU in post start too
+ifconfig_pre_start() {
+ local iface="$1"
+
+ interface_exists "${iface}" || return 0
+
+ local ifvar="$(bash_variable "$1")" mtu
+
+ # MTU support
+ mtu="mtu_${ifvar}"
+ [[ -n ${!mtu} ]] && ifconfig "${iface}" mtu "${!mtu}"
+
+ return 0
+}
+
+
+# bool ifconfig_post_start(char *iface)
+#
+# Bring up iface using ifconfig utilities, called from iface_start
+#
+# Returns 0 (true) when successful on the primary interface, non-zero
+# (false) when the primary interface fails. Aliases are allowed to
+# fail, the routine should still return success to indicate that
+# net.eth0 was successful
+ifconfig_post_start() {
+ local iface="$1" ifvar="$(bash_variable "$1")" routes x metric mtu cidr
+ metric="metric_${ifvar}"
+
+ ifconfig_exists "${iface}" || return 0
+
+ # Make sure interface is marked UP
+ ifconfig_up "${iface}"
+
+ # MTU support
+ mtu="mtu_${ifvar}"
+ [[ -n ${!mtu} ]] && ifconfig "${iface}" mtu "${!mtu}"
+
+ routes="routes_${ifvar}[@]"
+ routes=( "${!routes}" )
+
+ # BACKWARD COMPATIBILITY: set the default gateway
+ if [[ ${gateway} == "${iface}/"* ]]; then
+ # We don't add the old gateway if one has been set in routes_IFACE
+ local gw=true
+ for x in "${routes[@]}"; do
+ [[ ${x} != *"default gw"* ]] && continue
+ gw=false
+ break
+ done
+ ${gw} && routes=( "${routes[@]}" "default gw ${gateway#*/}" )
+ fi
+
+ [[ -z ${routes} ]] && return 0
+
+ # Add routes for this interface, might even include default gw
+ einfo "Adding routes"
+ eindent
+ for x in "${routes[@]}"; do
+ ebegin "${x}"
+
+ # Support iproute2 style routes
+ x="${x//via/gw} "
+ x="${x//scope * / }"
+
+ # Assume we're a net device unless told otherwise
+ [[ " ${x} " != *" -net "* && " ${x} " != *" -host "* ]] && x="-net ${x}"
+
+ # Support adding IPv6 addresses easily
+ if [[ ${x} == *:* ]]; then
+ [[ ${x} != *"-A inet6"* ]] && x="-A inet6 ${x}"
+ x="${x// -net / }"
+ fi
+
+ # Add a metric if we don't have one
+ [[ ${x} != *" metric "* ]] && x="${x} metric ${!metric}"
+
+ route add ${x} dev "${iface}"
+ eend $?
+ done
+ eoutdent
+
+ return 0
+}
+
+# bool ifconfig_add_address(char *iface, char *options ...)
+#
+# Adds the given address to the interface
+ifconfig_add_address() {
+ local iface="$1" i=0 r e real_iface="$(interface_device "$1")"
+
+ ifconfig_exists "${real_iface}" true || return 1
+
+ # Extract the config
+ local -a config=( "$@" )
+ config=( ${config[@]:1} )
+
+ if [[ ${config[0]} == *:* ]]; then
+ # Support IPv6 - nice and simple
+ config[0]="inet6 add ${config[0]}"
+ else
+ # IPv4 is tricky - ifconfig requires an aliased device
+ # for multiple addresses
+ if ifconfig "${iface}" | grep -Eq "\<inet addr:.*" ; then
+ # Get the last alias made for the interface and add 1 to it
+ i="$(ifconfig | tac | grep -m 1 -o "^${iface}:[0-9]*" \
+ | sed -n -e 's/'"${iface}"'://p')"
+ i="${i:-0}"
+ (( i++ ))
+ iface="${iface}:${i}"
+ fi
+
+ # ifconfig doesn't like CIDR addresses
+ local ip="${config[0]%%/*}" cidr="${config[0]##*/}" netmask
+ if [[ -n ${cidr} && ${cidr} != "${ip}" ]]; then
+ netmask="$(cidr2netmask "${cidr}")"
+ config[0]="${ip} netmask ${netmask}"
+ fi
+
+ # Support iproute2 style config where possible
+ r="${config[@]}"
+ config=( ${r//brd +/} )
+ config=( "${config[@]//brd/broadcast}" )
+ config=( "${config[@]//peer/pointopoint}" )
+ fi
+
+ # Ensure that the interface is up so we can add IPv6 addresses
+ interface_up "${real_iface}"
+
+ # Some kernels like to apply lo with an address when they are brought up
+ if [[ ${config[@]} == "127.0.0.1 netmask 255.0.0.0 broadcast 127.255.255.255" ]]; then
+ is_loopback "${iface}" && ifconfig "${iface}" 0.0.0.0
+ fi
+
+ ifconfig "${iface}" ${config[@]}
+}
+
+# vim: set ts=4 :