Никитенко Максим (Sets88)

Личная страница

Python - Дубликаты IP

Работаю я админом и вот однажды возникло у меня подозрение, что в моей сети несколько свичей имеют один и тот-же IP адрес.

Что совсем не круто, ведь часть свичей останется неучтенной, да и учтенные свичи будут не очень адекватно работать в такой ситуации.

Вот только как это проверить, на ум сразу же пришел arping.

Вот только не перебирать же две /23 сети вручную, что ни много ни мало, более тысячи адресов.

Для этого написал простенький скрипт который делает всю ручную работу за меня, принцып действия скрипта прост:
- В словаре nets хранятся подсети и интерфейс на котором эти подсети.
- В переменной threads_count записано число одновременных потоков.
- Скрипт Перебирает все IP адреса из подсетей и выполняет arping, который шлет ARP запрос в сеть.
- arping принимает ARP ответы от адресов
- Eсли на 1 IP адрес приходит 2 ответа, значит что-то не так, о чем скрипт незамедлительно и сообщает.


В итоге Вам придется разобраться индивидуально по каждому IP адресу, который вывел скрипт и проблема решена.

Исходный код
#! /usr/bin/python
# -*- coding: utf-8 -*-
""" Check if there's dublicate IPs """

import ipaddr
import os
from multiprocessing import Pool

# Subnet and interface
nets = {"10.90.90.0/23": "eth1", "10.100.90.0/23": "eth1.110"}
# Multithreading
threads_count = 10

def get_response_count(ip, iface):
    proc = os.popen("arping %s -I %s -c1" % (str(ip), iface))
    text = proc.read().split("\n")
    return text[-2].split()[1]


def print_response(ipnet):
    response_count = int(get_response_count(ipnet[0], ipnet[1]))
    if response_count > 1:
        print "%d Responses got from ip %s on %s" % (response_count, ipnet[0], ipnet[1])


def ip_net_generator(iplist, net):
    for ip in iplist:
        yield (ip, net)


def main():
    pool = Pool(threads_count)
    for net in nets:
#        ips = [(x,y) for x in ipaddr.IPNetwork(net) for y in [nets[net]]]
        try:
            pool.map_async(print_response, ip_net_generator(ipaddr.IPNetwork(net), nets[net])).get(9999)
        except KeyboardInterrupt:
            pool.terminate()
            return


if __name__ == "__main__":
    main()
Яндекс.Метрика