From 2f59a957d7f8c555e66e6c86de81345093125a52 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?C=C3=A9drix?= <cedric@abonnel.fr>
Date: Tue, 11 Mar 2025 21:07:10 +0100
Subject: [PATCH] =?UTF-8?q?optimisation=20pour=20r=C3=A9cup=C3=A9rer=20l'a?=
 =?UTF-8?q?dresse=20IP=20disponible?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 scripts/server-dhcp/get_first_free_ip.sh | 73 +++++++++++++++++-------
 1 file changed, 51 insertions(+), 22 deletions(-)

diff --git a/scripts/server-dhcp/get_first_free_ip.sh b/scripts/server-dhcp/get_first_free_ip.sh
index 4358fec..e15084d 100644
--- a/scripts/server-dhcp/get_first_free_ip.sh
+++ b/scripts/server-dhcp/get_first_free_ip.sh
@@ -1,13 +1,32 @@
 #!/bin/bash
 
-# Fichier contenant les réservations DHCP (modifier si nécessaire)
+# Déterminer l'interface réseau active (exclure loopback)
+INTERFACE=$(ip route | awk '/default/ {print $5; exit}')
+
+# Vérifier si une interface est détectée
+if [[ -z "$INTERFACE" ]]; then
+    echo "❌ Aucune interface réseau active détectée."
+    exit 1
+fi
+
+# Déterminer l'adresse IP et le masque réseau de l'interface active
+IP_INFO=$(ip -4 addr show "$INTERFACE" | awk '/inet / {print $2}')
+NETWORK_IP=$(echo "$IP_INFO" | cut -d'/' -f1)
+NETMASK_CIDR=$(echo "$IP_INFO" | cut -d'/' -f2)
+
+# Extraire le préfixe réseau (ex: "192.168.100")
+PREFIX=$(echo "$NETWORK_IP" | awk -F. '{print $1"."$2"."$3}')
+
+# Calculer les bornes de la plage d'adresses IP en fonction du masque
+NETMASK=$(( 32 - NETMASK_CIDR ))
+TOTAL_HOSTS=$(( 2 ** NETMASK ))
+IP_RANGE_START="$PREFIX.1"
+IP_RANGE_END="$PREFIX.$(( TOTAL_HOSTS - 2 ))"  # -2 pour exclure le broadcast
+
+# Fichier contenant les réservations DHCP
 RESERVATION_FILE="/etc/dnsmasq.d/custom_hosts"
 
-# Plage d'adresses IP à analyser (exemple : 192.168.1.100-192.168.1.200)
-IP_RANGE_START="192.168.1.100"
-IP_RANGE_END="192.168.1.200"
-
-# Fonction pour convertir une IP en un entier pour la comparaison
+# Fonction pour convertir une IP en un entier
 ip_to_int() {
     local IFS=.
     local ip=($1)
@@ -29,23 +48,33 @@ fi
 # Lire toutes les IP utilisées dans le fichier de réservation
 USED_IPS=($(grep -oE 'address=/[^/]+/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' "$RESERVATION_FILE" | awk -F'/' '{print $3}'))
 
-# Convertir les IP utilisées en entiers pour faciliter la recherche
-declare -A USED_IP_MAP
+# Si aucune IP n'est réservée, retourner la première adresse disponible
+if [[ ${#USED_IPS[@]} -eq 0 ]]; then
+    echo "✅ Première IP disponible : $IP_RANGE_START"
+    exit 0
+fi
+
+# Trouver la plus grande IP utilisée
+MAX_IP_INT=0
 for ip in "${USED_IPS[@]}"; do
-    USED_IP_MAP[$(ip_to_int "$ip")]=1
-done
-
-# Trouver la première IP disponible
-START_INT=$(ip_to_int "$IP_RANGE_START")
-END_INT=$(ip_to_int "$IP_RANGE_END")
-
-for (( ip=START_INT; ip<=END_INT; ip++ )); do
-    if [[ -z "${USED_IP_MAP[$ip]}" ]]; then
-        FREE_IP=$(int_to_ip "$ip")
-        echo "✅ Première IP disponible : $FREE_IP"
-        exit 0
+    ip_int=$(ip_to_int "$ip")
+    if (( ip_int > MAX_IP_INT )); then
+        MAX_IP_INT=$ip_int
     fi
 done
 
-echo "❌ Aucune IP libre trouvée dans la plage définie."
-exit 1
+# Calculer la prochaine IP disponible
+NEXT_IP_INT=$((MAX_IP_INT + 1))
+NEXT_IP=$(int_to_ip "$NEXT_IP_INT")
+
+# Vérifier que cette IP est bien dans la plage autorisée
+START_INT=$(ip_to_int "$IP_RANGE_START")
+END_INT=$(ip_to_int "$IP_RANGE_END")
+
+if (( NEXT_IP_INT > END_INT )); then
+    echo "❌ Plus aucune IP disponible dans la plage définie."
+    exit 1
+fi
+
+echo "✅ Première IP disponible : $NEXT_IP"
+exit 0