P.S. Писался "на коленках", поэтому в реальном приложении нужно добавить обработку "окончания памяти" в GetIpNetTable() и использование cbBuffer в MACToString() :)
Здравствуйте TSS, Вы писали:
SM>>А не мог бы кто-нибудь подкинуть эти самые либину и хэндл.... Плиз....
TSS>Если не секрет, а что такое "либина" и "хендл" ?
Либина, она же либ-файл, она же *.lib (в контексте iphlpapi.lib)
Хэндл, он же заголовочный файл, он же *.h (в контексте iphlpapi.h)
)
Я весь свой диск прошёл -- нет таких. VC 6.0 SP2, Win2kDDK.
Сори за местный слэнг -- привычка...
За сэмпл(он же пример) спасибо.
Здравствуйте ServerMouse, Вы писали:
SM>Здравствуйте TSS, Вы писали:
TSS>>Для использования понадобятся Iphlpapi.h и Iphlpapi.lib. TSS>>Работает на Win98+, WinNT 4.0 SP4+.
SM>А не мог бы кто-нибудь подкинуть эти самые либину и хэндл.... Плиз....
Надо тебе сливать Platform SDK , по всей видимости это там,
Здравствуйте ServerMouse, Вы писали:
SM>>>А не мог бы кто-нибудь подкинуть эти самые либину и хэндл.... Плиз....
TSS>>Если не секрет, а что такое "либина" и "хендл" ?
SM>Либина, она же либ-файл, она же *.lib (в контексте iphlpapi.lib) SM>Хэндл, он же заголовочный файл, он же *.h (в контексте iphlpapi.h) SM>))
SM>Я весь свой диск прошёл -- нет таких. VC 6.0 SP2, Win2kDDK.
Это из Platfrom SDK August'2001
SM>Сори за местный слэнг -- привычка...
Слишком "сильный" сленг
SM>За сэмпл(он же пример) спасибо.
Не за что.
SM>Мыльте лучше на yan@vektor.net
Лови на мыло. Одна проблема -- iphlpapi.h хочет ещё и кучку дрегих ip*.h ...
В зипе (38K) все они + .lib. Если что еще потребуеться -- пиши.
Здравствуйте TSS, Вы писали:
TSS>Здравствуйте ServerMouse, Вы писали:
TSS>Это из Platfrom SDK August'2001
TSS>Лови на мыло. Одна проблема -- iphlpapi.h хочет ещё и кучку дрегих ip*.h ... TSS>В зипе (38K) все они + .lib. Если что еще потребуеться -- пиши.
Здравствуйте ServerMouse, Вы писали:
TSS>>Это из Platfrom SDK August'2001
TSS>>Лови на мыло. Одна проблема -- iphlpapi.h хочет ещё и кучку дрегих ip*.h ... TSS>>В зипе (38K) все они + .lib. Если что еще потребуеться -- пиши.
SM>Вот спасибо! А то весь SDK — 380M....
Не за что. У меня он весь [SDK] стоит -- если что нужно -- пиши на мыло... =)
Вот возник сопутствующий вопрос -- как заставить систему занести туда какой-нибудь IP<->MAC?
Т.е. я понимаю, достаточно попытаться послать какой-нить пакет по IP-адресу, что бы сработала система ARP. Меня интересует минимально ресурсоёмкий и простой в организации, для Win32.
SendARP например в 9х не поддерживается. Должен мне кажется быть более простой способ чем UDP_SOCKET...
Я пытался пользовать NetBIOS для определения MAC, но не везде он включен...
Здравствуйте ServerMouse, Вы писали:
SM>Вот возник сопутствующий вопрос -- как заставить систему занести туда какой-нибудь IP<->MAC?
CreateIpNetEntry
The CreateIpNetEntry function creates an Address Resolution Protocol (ARP) entry in the ARP table on the local computer.
DWORD CreateIpNetEntry(
PMIB_IPNETROW pArpEntry // pointer to info for new entry
);
Parameters: pArpEntry [in] Pointer to a MIB_IPNETROW structure that specifies information for the new entry. The caller must specify values for all members of this structure.
Return Values
If the function succeeds, the return value is NO_ERROR.
If the function fails, use FormatMessage to obtain the message string for the returned error.
Requirements:
Windows NT/2000/XP: Included in Windows NT 4.0 SP4; Windows 2000; Windows XP Pro; and Windows .NET Server.
Windows 95/98/Me: Included in Windows 98 and later.
Header: Declared in Iphlpapi.h.
Library: Use Iphlpapi.lib.
SM>Т.е. я понимаю, достаточно попытаться послать какой-нить пакет по IP-адресу, что бы сработала система ARP. Меня интересует минимально ресурсоёмкий и простой в организации, для Win32.
См. выше.
SM>SendARP например в 9х не поддерживается. Должен мне кажется быть более простой способ чем UDP_SOCKET... SM>Я пытался пользовать NetBIOS для определения MAC, но не везде он включен...
Угу... точно. На самом деле тот аналог "arp" на 95-х работать не будет из-за GetIpNetTable()... Только 98+
Signed, [TSS] /SDL/
Re[10]: ARP-таблица (табл. соответствия IP <->MAC)
Здравствуйте TSS, Вы писали:
TSS>CreateIpNetEntry TSS>The CreateIpNetEntry function creates an Address Resolution Protocol (ARP) entry in the ARP table on the local computer.
TSS>
TSS>DWORD CreateIpNetEntry(
TSS> PMIB_IPNETROW pArpEntry // pointer to info for new entry
TSS>);
TSS>
Хм. Но ведь она, как я понял, заводит запись которую ты ей передаёшь, ничего не меняя. А я хочу отправить broadcast-ом ARP-запрос о таком-то IP и получив ответ вписать его в таблицу. Причём это пусть сделает система, а я потом просто заберу результат. Для этого ф-ция должна ещё и блокировать прогу пока ARP-ответ не получен или на таймаут.
Или я не прав?
Если человек программист, то это надолго.
Re[11]: ARP-таблица (табл. соответствия IP <->MAC)
Здравствуйте ServerMouse, Вы писали:
TSS>>CreateIpNetEntry TSS>>The CreateIpNetEntry function creates an Address Resolution Protocol (ARP) entry in the ARP table on the local computer.
SM>Хм. Но ведь она, как я понял, заводит запись которую ты ей передаёшь, ничего не меняя. А я хочу отправить broadcast-ом ARP-запрос о таком-то IP и получив ответ вписать его в таблицу. Причём это пусть сделает система, а я потом просто заберу результат. Для этого ф-ция должна ещё и блокировать прогу пока ARP-ответ не получен или на таймаут.
SM>Или я не прав?
Хмм... возможно Вы и правы.
В принципе, можно пойти самым топорным и "ламерским" путем -- посидеть со сниффером и посканировать трафик в сети.
Второй путь (что, в принципе, и делает SendARP) -- это пообщаться с IP Routing Manager. Вот только такая штука имхо есть только на WinNT.
Есть ещё один вариант. В конце хидера IPExport.h (Platform SDK August'2001) есть такая штука:
#ifdef CHICAGO // Это 95+
// Ioctls code exposed by Memphis tcpip stack.
// For NT these ioctls are define in ntddip.h (private\inc)#define IOCTL_IP_RTCHANGE_NOTIFY_REQUEST 101
#define IOCTL_IP_ADDCHANGE_NOTIFY_REQUEST 102
#define IOCTL_ARP_SEND_REQUEST 103
#define IOCTL_IP_INTERFACE_INFO 104
#define IOCTL_IP_GET_BEST_INTERFACE 105
#define IOCTL_IP_UNIDIRECTIONAL_ADAPTER_ADDRESS 106
#endif
Мемфис -- это 98 (одна из бервых бет). И все бы хорошо, если бы хоть какая-нить более-менее вразумительная дока была бы... но нету
Кста, IP Routing Manager очень крепко завязан на MprAdminXXX — функции. А они уж точно WinNT.
Это ещё не окончательный мой ответ, так что продолжение следует...
Signed, [TSS] /SDL/
Re[12]: ARP-таблица (табл. соответствия IP <->MAC)
Greetings, All!
TSS>Здравствуйте ServerMouse, Вы писали:
[skipped]
TSS>Это ещё не окончательный мой ответ, так что продолжение следует...
Итак, обещанное продолжение... =)
К сожалению, кроме SendARP я никакой вразумительной информации не нашел. На DeviceIoControl c вышеуказанным кодом IOCTL_ARP_SEND_REQUEST тоже ничего нет, поэтому, если требуеться создать "нормальную" таблицу, придеться извращаться по полной.
Я смоделировал одну ситуацию: есть пустая ARP-таблица и я обращаюсь на другую тачку (это был линух, билд не помню, но что-то красношляпное). При этом по сети проходил ARP-пакет с SourceMAC=<мой MAC адрес>, DestinationMAC=FF-FF-FF-FF-FF-FF и типом IP-фрейма 08-06. Линукс после этого отвечал и у меня в ARP-таблице появлялась новая "динамическая" запись об address resolution.
Описание пакетов (который прут по сети) и протоколов, которые использует Windows 2000 TCP/IP stack (я проверял на Win2K Advanced Server SP1) есть в RFC0826 (http://www.ietf.org/rfc/rfc0826.txt?number=0826) -- так гласит "библия" white paper "Microsoft Windows 2000 TCP/IP Implementation Details" (http://www.microsoft.com/windows2000/techinfo/howitworks/communications/networkbasics/tcpip_implement.asp). Доку я эту (рфц) прочел и ничего особо путного (окромя форматов) не нашел.
До проверки таблицы с неправильными записями (т.е. например 192.168.0.1 == FF-FF-FF-FF-FF-FF) руки у меня не дошли...
Поэтому самое "портабельное" решение IMHO будет написание функции, которые будут инициировать тот самый ARP-broadcast.
Вот, в принципе, и вcе.
Здравствуйте ServerMouse, Вы писали:
TSS>>Кста, все хотел спросить. А для чего все это ? Может есть более простой выход ?
SM>Хочется узнать адрес интерфейса работающего по IP, неважно что на том конце -- кофеварка или майнфрэйм.
"Ничего не понимаю" (C) мультик.
Как понять "адрес интерфейса" ? Хошь MAC адрес из IP вытащить ? А кто тебе сказал, что коферварка обязана обрабатывать ARP-запросы ? Тут уже все зависит от реализации сетевых компонентов у "клиента".
SM>Далее юзаю WPCAP, но самостоятельно делать с его помощью ARP-reqest и потом ждать ответа влом.
Здравствуйте TSS, Вы писали:
TSS>"Ничего не понимаю" (C) мультик. :) TSS>Как понять "адрес интерфейса" ?
Для сетевой карты в обычном понимании это MAC-адрес. В более общем случае " физический адрес сетевого интерфейса" являет собой адрес уникально идетифицирующий приёмо-передающее устройство в сети. Во завернул... ;) Соответствует канальному уровню модели OSI. Канальному уровню клубоко фиолетово с какими IP ты работаешь. Он не знает не IP не IPX. Что бы отправить любой пакет по Enthernet, необходимо знать физический адрес, то биш MAC (Media Access Control — управление доступом к носителю) или физ. адрес сетевого интерфейса.
TSS>Хошь MAC адрес из IP вытащить ? А кто тебе сказал, что коферварка обязана обрабатывать ARP-запросы?
Хорошо, ты подключил кофеварку работающую по IP. Выделил ей какой-то IP-адрес(10.0.0.1). КАК остальные компы в сети узнают о её существовании??? В обычной сети делается так:
Есть хост (10.0.0.2). Ты с него пытаешся достучатся до кофеваки.
1) Проверяется есть ли у хоста в табл. ARP запись о 10.0.0.1
1.1) Если нет отправляется ARP-reqest на физ. адрес FF FF FF FF FF FF
(broadcast).
1.2) Если в течении какого-то времени ответ не получен, обьявляем
о недостижимости IP-адреса 10.0.0.1
1.3) Ответ получен, добавляем соотв. IP<->MAC в таблицу.
Запись сея динамическая, существует только какое-то время.
2) Знаем физ. адрес. Влаживаем весь IP-пакет внутрь Enthernet кадра
и отправляем по MAC-адресу.
В данном случае кадр ARP-reqest бутет примерно таким:
Address 00-40-95-01-59-01 FF-FF-FF-FF-FF-FF // MAC-источник\MAC-назначение
Ethernet II Protocol Type ARP (08 06) // заголовок Enthernet
Address Resolution Protocol
Hardware Type Ethernet (00 01)
Protocol Type IP Protocol (08 00)
Hardware Address Length 6 bytes (06)
Protocol Address Length 4 bytes (04)
Operations ARP Request (00 01)
Source Hardware Address 00-40-95-01-59-01 // Это наш MAC
IP Source Address 10.0.0.2 (0A 00 00 02) // и IP
Destination Hardware Address 00-00-00-00-00-00 //Неизвестен, хотим узнать
IP Destination Address 10.0.0.1 (0A 00 00 01) // Ищем такой IP
Как видишь есть хитрое поле Hardware Address Length. Т.е. в принципе физ. адрес может быть другой длинны....
В принципе коферварка конечно не обязана обрабатывать ARP-запросы, но в таком случае тебе придётся ходить и ручками вписывать в ARP-таблицу соотв. IP<->MAC статически. А если там хотя бы 200 машин... О да....
Насколько я знаю, по такому принципу работают все Win и *nix.
SM>>Далее юзаю WPCAP, но самостоятельно делать с его помощью ARP-reqest и потом ждать ответа влом.
TSS>Это ещё что за зверь ?
Здравствуйте ServerMouse, Вы писали:
TSS>>Как понять "адрес интерфейса" ?
SM>Для сетевой карты в обычном понимании это MAC-адрес. В более общем случае " физический адрес сетевого интерфейса" являет собой адрес уникально идетифицирующий приёмо-передающее устройство в сети. Во завернул... ;) Соответствует канальному уровню модели OSI. Канальному уровню клубоко фиолетово с какими IP ты работаешь. Он не знает не IP не IPX. Что бы отправить любой пакет по Enthernet, необходимо знать физический адрес, то биш MAC (Media Access Control — управление доступом к носителю) или физ. адрес сетевого интерфейса.
Ясненько. :)
TSS>>Хошь MAC адрес из IP вытащить ? А кто тебе сказал, что коферварка обязана обрабатывать ARP-запросы?
SM>Хорошо, ты подключил кофеварку работающую по IP. Выделил ей какой-то IP-адрес(10.0.0.1). КАК остальные компы в сети узнают о её существовании??? В обычной сети делается так:
[skipped]
SM>В принципе коферварка конечно не обязана обрабатывать ARP-запросы, но в таком случае тебе придётся ходить и ручками вписывать в ARP-таблицу соотв. IP<->MAC статически. А если там хотя бы 200 машин... О да....
SM>Насколько я знаю, по такому принципу работают все Win и *nix.
Как они работают, написано в RFC0826. Но принцип именно тот, какой ты описал. Правда есть один гвоздик. Что произойдет если запись в ARP-таблице невалидна ?
И вот в связи с этим возникает интересный вопрос. Если мы сформируем (через CreateIpNetEntry) таблицу с "битыми" записями, типа
То что останеться системе ? Записи вроде статические. Но куда пойдут пакеты ?!
Я проверял, что если убить какую-нить запись, то система её восстановит при "ближайшем" обращении по указанному IP, проделав следующий фокус:
У меня в таблице был один dynamic arp на 192.168.0.22 (intranet). Я его снес и добавил static на 192.168.0.22, MAC 00-00-00-00-00-00. После этого сделал обычный net view \\192.168.0.22 (т.е. инициировал процесс передачи данных между станциями). Проверка таблицы показала, что все вернулось в первоначальный вид...
Здравствуйте TSS, Вы писали:
TSS>Как они работают, написано в RFC0826. Но принцип именно тот, какой ты описал. Правда есть один гвоздик. Что произойдет если запись в ARP-таблице невалидна ? TSS>И вот в связи с этим возникает интересный вопрос. Если мы сформируем (через CreateIpNetEntry) таблицу с "битыми" записями, типа
TSS> 10.0.0.1 --> FF-FF-FF-FF-FF-FF TSS> 10.0.0.2 --> FF-FF-FF-FF-FF-FF
TSS>То что останеться системе ? Записи вроде статические. Но куда пойдут пакеты ?! TSS>Я проверял, что если убить какую-нить запись, то система её восстановит при "ближайшем" обращении по указанному IP, проделав следующий фокус:
TSS> У меня в таблице был один dynamic arp на 192.168.0.22 (intranet). Я его снес и добавил static на 192.168.0.22, MAC 00-00-00-00-00-00. После этого сделал обычный net view \\192.168.0.22 (т.е. инициировал процесс передачи данных между станциями). Проверка таблицы показала, что все вернулось в первоначальный вид...
Что-то мне подсказывает, что всё равно был обмен ARP-пакетами. :) Это конечно можно отсниферить и убедится. НО это только в том случае, если адрес явно указан как невалидный, а если его чуток 'подправить' то до указаного IP тебе недостучаться.... :) Классическая ARP-атака.
В принципе запись будет создана даже если попытатся просто чего-то послать хосту, например UDP-датаграму, даже если удалёный хост не работает по UDP и порт у него закрыт. ARP то этого не знает. Вопрос был как минимально просто и не привязано к операционке и установленым протоколам это сделать. Способов то очень много.