##@cooked comments # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8 ## Calculateur d'adresse IP ##@cooked nocomments ##@require base uprovide ipcalc urequire base function get_random_kvm_macaddr() { # Obtenir une adresse mac au hasard commençant par 52:54:00 pour KVM echo "52:54:00:$(awk 'BEGIN {srand(); printf("%02X:%02X:%02X", rand()*256, rand()*256, rand()*256)}' 2>/dev/null)" } function ipcalc_splitipmask() { # Découper $1 de la forme ip[/mask] entre l'adresse ip, qui est placé dans # la variable $2(=ip) et le masque, qui est placée dans la variable # $3(=mask) if [[ "$1" == */* ]]; then set_var "${2:-ip}" "${1%%/*}" set_var "${3:-mask}" "${1#*/}" else set_var "${2:-ip}" "$1" set_var "${3:-mask}" fi } function ipcalc_checkip() { # Vérifier l'adresse ip $1 pour voir si elle est valide. Si l'adresse est # valide, l'afficher. Sinon, retourner 1 awkrun status=0 '{ # si l"adresse ne fait pas la taille voulue, rajouter des .0 ip = $0 gsub(/[^.]/, "", ip) count = length(ip) while (count < 3) { $0 = $0 ".0" count++ } # puis tester la validité if ($0 !~ /^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$/) { status = 1 exit } match($0, /([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)/, ps) for (i = 1; i <= 4; i++) { p = 0 + ps[i] if (p > 255) { status = 1 exit } } print $0 } END { exit status }' <<<"$1" } function ipcalc_checkmask() { # vérifier le masque de sous-réseau $1 pour voir si elle est valide. Si oui, # afficher le suffixe (0, 8, 16, 24, 32) associé. Sinon retourner 1 case "$1" in 0|0.0.0.0) echo 0;; 8|255.0.0.0) echo 8;; 16|255.255.0.0) echo 16;; 24|255.255.255.0) echo 24;; 32|255.255.255.255) echo 32;; *) return 1;; esac return 0 } function ipcalc_netmask() { # à partir d'un suffixe (0, 8, 16, 24, 32) ou d'un masque de sous-réseau, # afficher le masque de sous-réseau. si le suffixe ou le masque ne sont pas # reconnus, retourner 1 case "$1" in 0|0.0.0.0) echo 0.0.0.0;; 8|255.0.0.0) echo 255.0.0.0;; 16|255.255.0.0) echo 255.255.0.0;; 24|255.255.255.0) echo 255.255.255.0;; 32|255.255.255.255) echo 255.255.255.255;; *) return 1;; esac return 0 } function ipcalc_broadcast() { # Calculer l'adresse de broadcast correspondant à l'adresse ip $1. Le masque # de sous-réseau peut-être indiqué dans l'adresse ip avec le suffixe /n ou # /x.x.x.x ou donné dans l'argument $2. Seuls les suffixes 0, 8, 16, 24, 32 # sont supportés. # Retourner 1 si un erreur s'est produite, par exemple si l'adresse ou le # suffixe sont invalides ou non supportés. [ -n "$1" ] || return local ip mask ipcalc_splitipmask "$1" ip mask [ -n "$mask" ] || mask="$2" [ -n "$mask" ] || mask=24 ip="$(ipcalc_checkip "$ip")" || return mask="$(ipcalc_checkmask "$mask")" || return case "$mask" in 0) echo "255.255.255.255";; 8) ip="${ip%.*.*.*}"; echo "$ip.255.255.255";; 16) ip="${ip%.*.*}"; echo "$ip.255.255";; 24) ip="${ip%.*}"; echo "$ip.255";; 32) echo "$ip";; esac } function ipcalc_gateway() { # Calculer l'adresse du gateway correspondant à l'adresse ip $1, en # considérant que le gateway est la première adresse du réseau. Le masque de # sous-réseau peut-être indiqué dans l'adresse ip avec le suffixe /n ou # /x.x.x.x ou donné dans l'argument $2. Seuls les suffixes 0, 8, 16, 24, 32 # sont supportés. # Retourner 1 si un erreur s'est produite, par exemple si l'adresse ou le # suffixe sont invalides ou non supportés. [ -n "$1" ] || return local ip mask ipcalc_splitipmask "$1" ip mask [ -n "$mask" ] || mask="$2" [ -n "$mask" ] || mask=24 ip="$(ipcalc_checkip "$ip")" || return mask="$(ipcalc_checkmask "$mask")" || return case "$mask" in 0) echo "0.0.0.1";; 8) ip="${ip%.*.*.*}"; echo "$ip.0.0.1";; 16) ip="${ip%.*.*}"; echo "$ip.0.1";; 24) ip="${ip%.*}"; echo "$ip.1";; 32) echo "$ip";; esac } function ipcalc_match() { # Vérifier si l'adresse $1 correspond au modèle $2, e.g.: # ipcalc_match 10.75.0.23 10/8 --> TRUE # ipcalc_match 10.75.0.23 10.75.0.0/24 --> TRUE # ipcalc_match 10.75.0.23 10.75.0.28 --> FALSE [ -n "$1" -a -n "$2" ] || return local ip tip tmask ipcalc_splitipmask "$2" tip tmask [ -n "$tmask" ] || tmask=32 ip="$(ipcalc_checkip "$1")" || return tip="$(ipcalc_checkip "$tip")" || return tmask="$(ipcalc_checkmask "$tmask")" || return case "$tmask" in 0) return 0;; 8) [ "${ip%.*.*.*}" == "${tip%.*.*.*}" ];; 16) [ "${ip%.*.*}" == "${tip%.*.*}" ];; 24) [ "${ip%.*}" == "${tip%.*}" ];; 32) [ "$ip" == "$tip" ];; esac } function ipcalc_fqdn() { # Calculer si possible le nom pleinement qualifié correspondant à l'hôte $1. # Dans tous les cas, afficher l'hôte, mais retourner 1 si la calcul n'a pas # pu être effectué. local -a ips hosts local ip host if ! ips=("$(ipcalc_checkip "$1")"); then resolv_ips ips "$1" if [ -z "${ips[*]}" ]; then echo "$1" return 1 fi fi for ip in "${ips[@]}"; do resolv_hosts hosts "$ip" if [ -n "${hosts[*]}" ]; then echo "${hosts[0]}" return 0 fi done echo "$1" return 1 } function ipcalc_fqdn_maybe() { # Si $1 *semble* déjà être un nom d'hôte pleinement qualifié, l'afficher tel # quel. Sinon utiliser ipcalc_fqdn() pour afficher le nom d'hôte pleinement # qualifié correspondant. if ipcalc_checkip "$1" >/dev/null; then ipcalc_fqdn "$1" elif [[ "$1" == *.* ]]; then echo "$1" else ipcalc_fqdn "$1" fi }