Ping по диапазону ip-адрессов (Нужен скрипт, который будет пинговать диапазон ip-адресов)

Обсуждение настройки и работы сервисов, резервирования, сетевых настроек и вопросов безопасности ОС.

Модераторы: SLEDopit, Модераторы разделов

putin
Сообщения: 20
ОС: XP+FreeBSD

Ping по диапазону ip-адрессов

Сообщение putin »

Привет всем. Нужна помощь по созданию sh скрипта, который бы в определенное время, либо при ручном запуске, начинал пинговать ip-диапазон, на несколько сотен компътеров и сохранял в файл те ip-адресса, у которых TTL отличен от 128. Это мне нужно для вычисления клиентов которые использую роутеры, либо же сетевые мосты! Некоторые компьютеры могут не отвечать, по этому не хотелось бы чтобы скрипт зацикливался на на некотором хосте, а допустим посылал 3 пакета, и если нет ответа переходил на следующий хост. Очень надеюсь на вашу помощь. скрипт будет устанавливаться а ФРИбсд, утсановлены все необходимые пакеты, перл, апаче, пхп, мускул, баш, программа arpping тоже есть, если бы прикрутить и ее к скрипту, вообще было бы замечательно, так-как она позволяет пинговать по маку, это в том случае если на компътере или на каком-либо оборудовании запрещены icmp пакеты. В сети установлены управляемые свичи 2-го уровня, раздача ip производится по DHCP, база с МАКами тоже есть! IP-MACbinding включен! В основном свичи DES-3526.
Спасибо сказали:
Аватара пользователя
Denjs
Сообщения: 1685
ОС: SuSe 10.2

Re: Ping по диапазону ip-адрессов

Сообщение Denjs »

озвучтебюджетпроектапожалуйста? :)

PS: после этого можно будет даже обсудить как именно "пинговать по маку, в том случае если на компъютере или на каком-либо оборудовании запрещены icmp пакеты" )
нет в принципе понятно конечно что вы хотели сказать, но звучит весело)
QDroid - Среда исполнения и фреймворк для QtScript.
OTPD - Открытые драйвера промышленных принтеров чеков и этикеток (кроссплатформенная подсистема печати).
Спасибо сказали:
putin
Сообщения: 20
ОС: XP+FreeBSD

Re: Ping по диапазону ip-адрессов

Сообщение putin »

Denjs писал(а):
21.09.2010 23:57
озвучтебюджетпроектапожалуйста? :)

PS: после этого можно будет даже обсудить как именно "пинговать по маку, в том случае если на компъютере или на каком-либо оборудовании запрещены icmp пакеты" )
нет в принципе понятно конечно что вы хотели сказать, но звучит весело)

Должен огорчить, бюджет проэкта с нулем, по этому на полно рабочий скрипт и не надеюсь, но очень хотелосьбы, чтобы скрипт записывал в файл те айпи, у которых ТТЛ отличен от 128. По моеу это не очень сложно! А поповоду пинга по маку я написал, что хотелось бы, но если это стоит денег, тогда помогите хоть так. ICMP пакеты могут быть перекрыты фаерволами, а в настройках роутера может быть отключен ответ на пинг через ВАН порт. надеюсь на вш помощь.
Спасибо сказали:
IMB
Сообщения: 2567
ОС: Debian

Re: Ping по диапазону ip-адрессов

Сообщение IMB »

Вы заходите не стого бока. Никто за Вас писать скрипт не будет, подсказать - можно.
Лучше бы Вы показали текущие наработки и озвучили имеющиеся проблемы.

Для пингования по диапазону адресов могу порекомендовать fping. Да и принимать решение на основе значения TTL не очень надёжно, у многих систем TTL имеет значение не равное 128 (http://www.map.meteoswiss.ch/map-doc/ftp-probleme.htm), да и изменить его не сложно.
Спасибо сказали:
putin
Сообщения: 20
ОС: XP+FreeBSD

Re: Ping по диапазону ip-адрессов

Сообщение putin »

#!/bin/sh
probe () {
ping -c1 -w5 $1 >&- 2>&- || touch /tmp/pingfail.$1
}
rm /tmp/pingfail.* 2>&-
for i in $(seq 1 50); do
probe 192.168.0.$i &
done;
wait
for failip in /tmp/pingfail.*; do
echo ${failip#*.}
done|sort -nt. -k1,1 -k2,2 -k3,3 -k4,4
rm /tmp/pingfail.* 2>&-

собственно вот скрипт, который пингует и аписывает в файл те хосты, которые не ответили, я вот и хочу его переделать на ответ по ТТЛ, а то, что ТТЛ можно подменить, это не для нашей сети, мало вероятно, что найдуться такие умники, да и практически все под Windows сидят.
Спасибо сказали:
Аватара пользователя
sash-kan
Администратор
Сообщения: 13939
Статус: oel ngati kameie
ОС: GNU

Re: Ping по диапазону ip-адрессов

Сообщение sash-kan »

putin
во время работы вашего скрипта можете записывать icmp-трафик:
$ sudo tshark -ni br0 -w <файл> icmp
а после отработки (прервав tshark), посмотреть нужные вам ip-адреса:
$ tshark -r <файл> -R 'icmp.type == 0 and ip.ttl != 128' -T fields -e ip.src | sort -u

запуск/прерывание записи можно добавить и в ваш скрипт. см. man bash на предмет переменной $!

putin писал(а):
22.09.2010 10:33
touch /tmp/pingfail.$1
ну и зверство. прямо-таки классика быдлокодирования.
программа ping, как и любая нормальная программа, имеет код возврата. вы не поверите, но его можно проанализировать.
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
Спасибо сказали:
Аватара пользователя
arkhnchul
Сообщения: 2284
Статус: Толчковый инженер
ОС: Debian, Fedora

Re: Ping по диапазону ip-адрессов

Сообщение arkhnchul »

а не лучше все это сделать nmap-ом?

Код: Выделить всё

[root@darkstar]# nmap -n -sP 192.168.149.0/24 --traceroute -oX out.xml

получаем xml-ку (хоть и обожаю я их лютой ненавистью), каковую не так уж проблемно потом погрепать на предмет чего угодно.
вот кусок для одного хоста:

Код: Выделить всё

<host starttime="1285159094" endtime="1285159105"><status state="up" reason="echo-reply"/>
<address addr="192.168.149.202" addrtype="ipv4" />
<hostnames>
</hostnames>
<trace proto="icmp">
<hop ttl="1" ipaddr="192.168.77.1" rtt="0.13"/>
<hop ttl="2" ipaddr="10.189.189.1" rtt="42.50"/>
<hop ttl="3" ipaddr="192.168.149.202" rtt="44.92"/>
</trace>
<times srtt="51605" rttvar="33849" to="187001" />
</host>

и состояния, и хопы. Та хоть черта рогатого туда можно записать, если покурить ман нмапа.
Losing is fun!
Спасибо сказали:
Аватара пользователя
arkhnchul
Сообщения: 2284
Статус: Толчковый инженер
ОС: Debian, Fedora

Re: Ping по диапазону ip-адрессов

Сообщение arkhnchul »

или -oN, если не нравится XML, там вывод будет вполне обрабатываем всякими sed-ами и прочим стандартным инструментарием.
Losing is fun!
Спасибо сказали:
putin
Сообщения: 20
ОС: XP+FreeBSD

Re: Ping по диапазону ip-адрессов

Сообщение putin »

arkhnchul писал(а):
22.09.2010 16:49
а не лучше все это сделать nmap-ом?

Код: Выделить всё

[root@darkstar]# nmap -n -sP 192.168.149.0/24 --traceroute -oX out.xml

получаем xml-ку (хоть и обожаю я их лютой ненавистью), каковую не так уж проблемно потом погрепать на предмет чего угодно.
вот кусок для одного хоста:

Код: Выделить всё

<host starttime="1285159094" endtime="1285159105"><status state="up" reason="echo-reply"/>
<address addr="192.168.149.202" addrtype="ipv4" />
<hostnames>
</hostnames>
<trace proto="icmp">
<hop ttl="1" ipaddr="192.168.77.1" rtt="0.13"/>
<hop ttl="2" ipaddr="10.189.189.1" rtt="42.50"/>
<hop ttl="3" ipaddr="192.168.149.202" rtt="44.92"/>
</trace>
<times srtt="51605" rttvar="33849" to="187001" />
</host>

и состояния, и хопы. Та хоть черта рогатого туда можно записать, если покурить ман нмапа.

Спасибо буду пробовать! Но если еще варианты-буду только рад.
Спасибо сказали:
Аватара пользователя
arkhnchul
Сообщения: 2284
Статус: Толчковый инженер
ОС: Debian, Fedora

Re: Ping по диапазону ip-адрессов

Сообщение arkhnchul »

nmap плюс быстрее работает. В примере я сканил сеть /24, находящуюся за впн-ом на фиговом канале - 110 секунд. Скриптовый пинг тремя пакетами в лучшем случае при этом - 3(кол-во)*1(интервал)*254(кол-во хостов) = 762 секунды. 13 минут ажно он только пинговать будет. Причем это в любом случае. Для пущего сравнения, скан локальной сети:

Код: Выделить всё

[root@darkstar pub]# nmap -n -sP 192.168.77.0/24 --traceroute
Starting Nmap 5.21 ( http://nmap.org ) at 2010-09-23 14:46 YEKST
Nmap scan report for 192.168.77.1
Host is up (0.00010s latency).
MAC Address: 00:21:91:92:FE:73 (D-Link)

HOP RTT     ADDRESS
1   0.10 ms 192.168.77.1

Nmap scan report for 192.168.77.2
Host is up (0.00033s latency).
MAC Address: 1C:AF:F7:9A:E1:1E (D-link International PTE Limited)

HOP RTT     ADDRESS
1   0.33 ms 192.168.77.2
.....

Nmap done: 256 IP addresses (21 hosts up) scanned in 1.66 seconds

1.66 секунды.
Losing is fun!
Спасибо сказали:
Аватара пользователя
Alex2ndr
Сообщения: 443
ОС: Debian Lenny

Re: Ping по диапазону ip-адрессов

Сообщение Alex2ndr »

arkhnchul писал(а):
23.09.2010 12:47
Скриптовый пинг тремя пакетами в лучшем случае при этом - 3(кол-во)*1(интервал)*254(кол-во хостов) = 762 секунды.

Поэтому пинг стоит делать в несколько потоков. Я как-то заморачивался этим вопросом и написал скрипт на Python, который это делает.
Расчитан на Python 2.5

Код: Выделить всё

#!/usr/bin/env python
# -*-coding: utf-8 -*-

import subprocess
import threading
import Queue

def ipgen(oct1,oct2,oct3,oct4):
    for o1 in xrange(oct1[0],oct1[1]+1):
        for o2 in xrange(oct2[0],oct2[1]+1):
            for o3 in xrange(oct3[0],oct3[1]+1):
                for o4 in xrange(oct4[0],oct4[1]+1):
                    yield '%s.%s.%s.%s' % (o1,o2,o3,o4)

def ping2mac(ip):
    subprocess.call(("/bin/ping -c1 -s1 %s &>/dev/null" % ip), \
            shell=True)
    macstr = subprocess.Popen(('arp -an | grep "(%s)"' % ip), \
             shell=True, stdout=subprocess.PIPE)
    mac = macstr.communicate()[0]
    if mac:
        mac = mac.split()[3]
        if mac != '<incomplete>':
            return mac
    return ''

def pinger(que):
    while True:
        ip = que.get()
        mac = ping2mac(ip)
        if mac: print ip,mac
        que.task_done()

if __name__ == '__main__':
    queue = Queue.Queue()
    for i in xrange(20):
        worker = threading.Thread(target=pinger,args=(queue,))
        worker.setDaemon(True)
        worker.start()

    for ip in ipgen((192,192),(168,168),(0,0),(0,255)):
        queue.put(ip)
    queue.join()

Так как штука сугубо унитарная, то красивостей (читай констант в начале скрипта) нету. Кроме того она определяет на ttl(хотя могла бы) а просто доступность компа. Работает так:
- Пингуем адрес.
- Смотрим arp кэш. Если появилась запись для данного айпишника, то считаем что комп в сети и возвращаем его ip и mac.
- Переходим к следующему адресу.
И все это добро в столько потоков, сколько нужно. Если поставить 255 потоков, то 24 подсеть можно пропинговать секунды за 3. Минус - ограничение в дистрибутиве на кол-во порожденных потоков(вроде ulimits).
Менять параметры так -
в строке for ip in ipgen((192,192),(168,168),(0,0),(0,255)): задается диапазон.
в строке for i in xrange(20): можно выставить кол-во потоков. Сейчас - 20.

Если постараться, то на шеле тоже можно это переписать. Только нужно использовать fork.
Спасибо сказали:
putin
Сообщения: 20
ОС: XP+FreeBSD

Re: Ping по диапазону ip-адрессов

Сообщение putin »

Alex2ndr писал(а):
29.09.2010 12:20
arkhnchul писал(а):
23.09.2010 12:47
Скриптовый пинг тремя пакетами в лучшем случае при этом - 3(кол-во)*1(интервал)*254(кол-во хостов) = 762 секунды.

Поэтому пинг стоит делать в несколько потоков. Я как-то заморачивался этим вопросом и написал скрипт на Python, который это делает.
Расчитан на Python 2.5

Код: Выделить всё

#!/usr/bin/env python
# -*-coding: utf-8 -*-

import subprocess
import threading
import Queue

def ipgen(oct1,oct2,oct3,oct4):
    for o1 in xrange(oct1[0],oct1[1]+1):
        for o2 in xrange(oct2[0],oct2[1]+1):
            for o3 in xrange(oct3[0],oct3[1]+1):
                for o4 in xrange(oct4[0],oct4[1]+1):
                    yield '%s.%s.%s.%s' % (o1,o2,o3,o4)

def ping2mac(ip):
    subprocess.call(("/bin/ping -c1 -s1 %s &>/dev/null" % ip), \
            shell=True)
    macstr = subprocess.Popen(('arp -an | grep "(%s)"' % ip), \
             shell=True, stdout=subprocess.PIPE)
    mac = macstr.communicate()[0]
    if mac:
        mac = mac.split()[3]
        if mac != '<incomplete>':
            return mac
    return ''

def pinger(que):
    while True:
        ip = que.get()
        mac = ping2mac(ip)
        if mac: print ip,mac
        que.task_done()

if __name__ == '__main__':
    queue = Queue.Queue()
    for i in xrange(20):
        worker = threading.Thread(target=pinger,args=(queue,))
        worker.setDaemon(True)
        worker.start()

    for ip in ipgen((192,192),(168,168),(0,0),(0,255)):
        queue.put(ip)
    queue.join()

Так как штука сугубо унитарная, то красивостей (читай констант в начале скрипта) нету. Кроме того она определяет на ttl(хотя могла бы) а просто доступность компа. Работает так:
- Пингуем адрес.
- Смотрим arp кэш. Если появилась запись для данного айпишника, то считаем что комп в сети и возвращаем его ip и mac.
- Переходим к следующему адресу.
И все это добро в столько потоков, сколько нужно. Если поставить 255 потоков, то 24 подсеть можно пропинговать секунды за 3. Минус - ограничение в дистрибутиве на кол-во порожденных потоков(вроде ulimits).
Менять параметры так -
в строке for ip in ipgen((192,192),(168,168),(0,0),(0,255)): задается диапазон.
в строке for i in xrange(20): можно выставить кол-во потоков. Сейчас - 20.

Если постараться, то на шеле тоже можно это переписать. Только нужно использовать fork.

Пробую пока юзать ваш вариант скрипта, вот только я не понял на против он пишет айпи адресса он пишет инкомплит, что это обозначает, или пишет МАК, а потом инкомплит!
Спасибо сказали:
Аватара пользователя
Alex2ndr
Сообщения: 443
ОС: Debian Lenny

Re: Ping по диапазону ip-адрессов

Сообщение Alex2ndr »

putin писал(а):
09.10.2010 18:05
Пробую пока юзать ваш вариант скрипта, вот только я не понял на против он пишет айпи адресса он пишет инкомплит, что это обозначает, или пишет МАК, а потом инкомплит!

Здесь дело в том, что возможно в наших дистрибутивах различается вывод команды
У меня получение резальтата основано на парсинге этой команды. Дело происходит так:
1. Выполняем

Код: Выделить всё

ping -c1 -s1 адрес_назначения &>/dev/null

2. Выполняем

Код: Выделить всё

arp -an | grep "(адрес_назначения)"

3. Берем первую строку получившегося вывода.
4. Берем 3-й элемент этой строки (считаем что элементы разделены пробелами).
5. Если это элемент не равен <incomplete> то возвращаем строку ip, mac, иначе переходим к следующему адресу.

Проверьте эту последовательность и посмотрите проходит ли такой алгоритм. Если что-то идет не так то можем подправить.

Еще один момент - данный скрипт работает только если с компами есть связь на канальном уровне( т е не через маршрутизатор и они находятся в одной подсети). Иначе в arp кэше не будет мака и соответственно алгоритм работать не будет. Вообще за эту часть отвечает функция ping2mac.
Спасибо сказали:
putin
Сообщения: 20
ОС: XP+FreeBSD

Re: Ping по диапазону ip-адрессов

Сообщение putin »

Alex2ndr писал(а):
11.10.2010 10:04
putin писал(а):
09.10.2010 18:05
Пробую пока юзать ваш вариант скрипта, вот только я не понял на против он пишет айпи адресса он пишет инкомплит, что это обозначает, или пишет МАК, а потом инкомплит!

Здесь дело в том, что возможно в наших дистрибутивах различается вывод команды
У меня получение резальтата основано на парсинге этой команды. Дело происходит так:
1. Выполняем

Код: Выделить всё

ping -c1 -s1 адрес_назначения &>/dev/null

2. Выполняем

Код: Выделить всё

arp -an | grep "(адрес_назначения)"

3. Берем первую строку получившегося вывода.
4. Берем 3-й элемент этой строки (считаем что элементы разделены пробелами).
5. Если это элемент не равен <incomplete> то возвращаем строку ip, mac, иначе переходим к следующему адресу.

Проверьте эту последовательность и посмотрите проходит ли такой алгоритм. Если что-то идет не так то можем подправить.

Еще один момент - данный скрипт работает только если с компами есть связь на канальном уровне( т е не через маршрутизатор и они находятся в одной подсети). Иначе в arp кэше не будет мака и соответственно алгоритм работать не будет. Вообще за эту часть отвечает функция ping2mac.

Спасибо огромное, кажись разобрался. Если будут вопросы обязательно напишу-пока все норм - удалось вычислить несколько роутеров+апаче, Так все работает. Все пингуется со стороны сервера, и маршрутизация у пользователей прописана иначе бы у них интернет не работал!
Спасибо сказали:
Аватара пользователя
Alex2ndr
Сообщения: 443
ОС: Debian Lenny

Re: Ping по диапазону ip-адрессов

Сообщение Alex2ndr »

Небольшая правка:
Вместо
4. Берем 3-й элемент этой строки (считаем что элементы разделены пробелами).

должно быть
4. Берем 4-й элемент этой строки (считаем что элементы разделены пробелами).

так как в питоне индексация элементов списка начинается с 0.
Спасибо сказали: