По
просьбамАвтор: Whisperer
Дата: 29.12.02
трудящихся бросаю в сюды.
Это набор функций, предназначенных для определения страны принадлежности IP-адреса, и попутно другой Whois-информации.
А точнее для работы с БД RIPE, слить которую всегда можно тут:
ftp://ftp.ripe.net/ripe/dbase/split/ripe.db.inetnum.gz
обновляется периодически
текущий размер архива около 40 метров.
текущий обьем БД — около 715 000 записей.
Cлить исходники можно
тут или
тут.
Исходники компилируются в две утилиты: geoconv и whois. (для windows соответственно, с расширением exe)
geoconv
Парсит исходный файл
ripe.db.inetnum и создает файл индекса
ripe.db.geo.
Это набор записей со следующим форматом:
Длина записи 16 байт.
0-3 IPv4 маска. (4 байта)
4 Длина маски (0..32)
5 Код страны. (0..255)
6-7 Двубуквенное обозначение страны (GB, RU, SU...)
8-11 32bit long Оффсет записи в файле ripe.db.inetnum
12-15 32bit long Длина записи.
Коды стран берутся из файла
countries.geo
Whois
Утилита — пример использования библиотеки.
При старте в память загружается индекс, после вы можете вводить IP-адреса и получать по ним информацию.
Как это работает.
Возьмем для примера rsdn.ru.
IP-адрес: 195.209.62.198
Соответствующая запись в файле
ripe.db.inetnum:
inetnum: 195.209.32.0 - 195.209.63.255
netname: GARNET-2
descr: Garant-Park
descr: Scince Park, MSU
descr: Lebedeva St., Leninskie Gory
descr: Moscow 119899, Russia
country: RU
admin-c: AES1-RIPE
tech-c: AES1-RIPE
status: ASSIGNED PA
mnt-by: ROSNIIROS-MNT
changed: aes@ns.garant.ru 19951016
changed: ip-reg@ripn.net 19960903
source: RIPE
Маска: 195.209.32.0
Длина маски: 19 бит.
То есть в диапазоне адресов
195.209.32.0 — 195.209.63.255
значимыми битами являются только первые 19 бит, эти биты неизменны на протяжении всего диапазона.
В побитовом эквиваленте диапазон выглядит так:
от {
11000011110100010010000000000000} до {
11000011110100010011111111111111}
Индекс
ripe.db.geo загружается в память в виде битового дерева,
таким образом поиск происходит максимум в 32 перехода (32бит в IP-адресе), то есть, очень быстро
Мы преобразуем исходный IP-адрес в цепочку битов, и следуем по дереву, поочередно сверяя каждый бит с узлами дерева.
Т.е. первый бит сверяем с корневым узлом дерева.
Если бит установлен(1), то берем правый дочерний узел, если сброшен(0), то левый дочерний узел.
Таким образом мы провалились в глубину дерева на 2 уровень.
Этот дочерний узел сверяем со вторым битом цепочки, и т.п.
При каждом сравнении смотрим код страны у узла. Если он не равен нулю(запись для него существует в базе) — запоминаем этот узел.
Мы посоянно помним последний найденный узел, для которого существует запись в базе.
Таким образом обеспечивается вложенность диапазонов. К примеру, большой диапазон IP-адресов мог быть выделен одной стране или фирме, но в этом диапазоне могут находиться поддиапазоны, выделенные другим фирмам, возможно даже, в другой стране.
Если IP-адрес не находится, для него все-равно возвращается запись:
inetnum: 0.0.0.0 - 255.255.255.255
netname: IANA-BLK
descr: The whole IPv4 address space
country: NL
admin-c: IANA1-RIPE
tech-c: IANA1-RIPE
status: ALLOCATED UNSPECIFIED
remarks: The country is really worldwide.
remarks: This address space is assigned at various other places in
remarks: the world and might therefore not be in the RIPE database.
mnt-by: RIPE-NCC-HM-MNT
mnt-lower: RIPE-NCC-HM-MNT
mnt-routes: RIPE-NCC-NONE-MNT
changed: bitbucket@ripe.net 20010529
changed: bitbucket@ripe.net 20020625
source: RIPE
Что она означает, вы можете сами прочитать в секции remarks.
Makefile сделан для FreeBSD.
bat-файлы — для компиляции под Win.
А теперь немного о проблемах:
Утилита whois дико глючит под Windows.
Под FreeBSD все ок. Где я допустил грабли, я не знаю.
Суть баги: после ввода хоть одного неправильного(не существующего в базе) IP — больше не работает до перезапуска проги.
Похоже, в памяти рассыпаются связи. Мне облом это ковырять — вроде бы я нигде в момент поиска не пишу ничего, только читаю.
А может быть я просто не знаю некоторых особенностей работы под виндой... (я в общем-то на Сях под Юних пишу, под винду как-то больше на Дельфи, на сях не приходилось...)
Компилил VC6.0
Так что кто найдет берлогу этой баги — милости прошу сообщить в этот топик.
З.Ы. Ногами сильно не пинать — сие описание писал слегка под хмелем и после тяжелого дня.
З.З.Ы. Посмотреть, как сие работает, можно тут:
http://911.ru/whois