Hai copiato parti del mio esempio senza capire come funziona, né dove sbagli, né perché sbagli.
Nel mio esempio, prendo tutti gli ultimi ottetti degli indirizzi presi dal db e li metto in un array (che ho chiamato last_octets).
A questo punto (e solo dopo aver estratto tutti i quarti ottetti in last_octets), inizio a cercare un nuovo ottetto.
Sono due cicli separati, non innestati! Il primo ciclo estrae i quarti ottetti e li copia in last_octets, il secondo genera un ottetto a caso e va a vedere se in last_octets è già stato usato.
Nel tuo codice prendi un indirizzo IP, estrai il quarto ottetto, poi generi un ottetto nuovo e ovviamente avrai un ottetto ‘intonso’, perché il tuo ‘octets[3]’ contiene solo un valore, quello corrispondente all'indirizzo IP preso dal db. All'iterazione successiva avrai un nuovo indirizzo IP preso dal db, ma non avrai più l'informazione degli ottetti precedenti.
Devi quindi prima estrarre tutti i quarti ottetti, poi cercare un ottetto non usato dentro last_octets, infine comporre il corrispondente indirizzo IP e farne l'uso che ti serve.