##@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 local mask="$1" [ "$mask" == 0.0.0.0 ] && mask=0 [ "$mask" == 255.0.0.0 ] && mask=8 [ "$mask" == 255.255.0.0 ] && mask=16 [ "$mask" == 255.255.255.0 ] && mask=24 [ "$mask" == 255.255.255.255 ] && mask=32 [ "$mask" == 0 -o "$mask" == 8 -o "$mask" == 16 -o "$mask" == 24 -o "$mask" == 32 ] || return 1 echo "$mask" } 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 }