-
Сегодня столкнулся вот с каким случаем. В программе есть код, который определяет IP-адрес машины для дальнейших обработок и работы с этим адресом.
function GetLocalIP: String;
const
WSVer = $101;
var
wsaData: TWSAData;
P: PHostEnt;
Buf: array [0..127] of Char;
begin
Result := '';
if WSAStartup(WSVer, wsaData) = 0 then
begin
if GetHostName(@Buf, 128) = 0 then
begin
P := GetHostByName(@Buf);
if P <> nil then
Result := iNet_ntoa(PInAddr(p^.h_addr_list^)^);
end;
WSACleanup;
end;
end;
Все бы ничего, да возьми знакомый и попроси проверить в работе его web-камеру. Говорит, что при подключении к USB комп вешается или выпадает в BSOD. Так вот, включил камеру и пусть думаю весит день в подключенном состоянии. Взялся за отладку программы. Смотрю, а у меня вместо IP адреса моей машины появляется какая то ерунда. Долго не мог понять в чем дело, пока не залез в IpConfig /all. И что я там увидел : http://s018.radikal.ru/i526/1201/28/c9c3a9a00d1f.jpg . Вверху данные по сетевой карте. В подсвеченном участке - данные от web-камеры. Оказывается при подключении камеры в сетевом окруженни появилось еще одно "Подключение по локальной сети" И получается, что моя функция определения IP адреса показывает адрес web-камеры(0.1.0.4, непонятно кем назначенный, возможно прошитый в ней). А ведь к компу можно еще и других устройств наподключать и не известно что они пропишут в сетевом окружении. Вопрос в том, как определить реальный IP адрес именно сетевой карты, подключенной к локальной сети?
-
> как определить реальный IP адрес именно сетевой карты, подключенной > к локальной сети?
Ты не поверишь - других сетей с этой точки зрения и не бывает. Оценивать "реальность" каждого из доступных сетевых интерфейсов, каждому из которых может к тому же быть назнвчено более одного IP-адреса - дело мутное и неблагодарное)
Да и что будешь делать, если обнаружишь дюжину таких "реальных" ?
Правильное решение решение задачи ты скрыл за > для дальнейших обработок и работы с этим адресом
-
> Правильное решение решение задачи ты скрыл за
Ничего секретного. Просто потом вычисляется третий актет и выясняется пренадлежность адреса определенному региону области т.к. для каждого района это константа. Ну а далее другая задача, не важно уже.
-
Ну так вот и ответ на твой вопрос: для каждого IP-адреса (вкупе с маской его подсети) каждого из интерфейсов следует произвести анализ на принадлежность этого адреса диапазону адресов интересующей подсети.
-
Т.е. перебором собрать все найденные IP адреса, повыбирать из них 3-и актеты и сравнивать с шаблоном для дальнейшего анализа пренадлежности? Маска полсети тут я думаю не нужна. А вот что насчет мак-адресов? Смотрю, что реально имеющие значение только интересуемый меня IP-адрес именно сетевой карты. От него можно как то плясать?
-
> перебором собрать все найденные IP адреса, повыбирать из > них 3-и актеты и сравнивать с шаблоном для дальнейшего анализа > пренадлежности? Маска полсети тут я думаю не нужна
Маска подсети и есть шаблон.
> что насчет мак-адресов?
MAC-адрес сетевого устройства запросто может быть фиктивным, от него плясать нельзя. Плясать можно только от принадлежности IP-адреса диапазону адресов интересующей подсети.
-
> Маска подсети и есть шаблон.
В моем случае нет. В моем случае шаблоном является список из 22 номеров(третий актет конкретного региона). Маска подсети для всех одна.
-
> В моем случае нет
Того быть не могёт)
К примеру, у тебя нашлись адреса 1.2.3.4 - адрес в некоей одной подсети 5.6.3.8 - адрес в совсем другой подсети
3-й октет, как видишь, одинаков.
Вопрос на засыпку, какой адрес в интересующем тебя контексте есть "реальный" адрес ?)
-
Сейчас не успею ответить, вечером позже(с домашнего компа) отпишусь, объясню
-
Хуже будет, когда некий виртуальный интерфес поднимет 192.168.1.1/24 и попадет в такую же локальную подсеть :) Вопрос автору, какая маска подсети у этого интерфейса?
-
Система такая. Я не сетевик, особо не знаю как у них там закручено, но смысл такой. У нас в головной организации сервер, внутренняя сетка, маска модсети 255.255.254.0 ну и свои айпи адреса. В нашем подчинении 22 района у каждого своя сеть адресов, отличающаяся только тритьим актетом, маска подсети 255.255.255.0. Третий актет для всех регионов константа и повториться не может. Это как фирменная лейба региона. Посему для того, чтобы определить от какого района пришла информация, мне достаточнр считать айпи адрес на клиентской части, вычислить третий актет, из "справочника" найти что за регион передал инфу и дальше обработка на сервере. Вот как то так.
-
> считать айпи адрес на клиентской части, вычислить третий > актет, из "справочника" найти что за регион передал инфу > и дальше обработка на сервере
Чем дальше в лес - тем толще партизаны) ..
Какое отношение ф-ция GetLocalIP имеет к "что за регион передал инфу" ?
p.s.
> актет
Ты специально что ли коверкаешь слово "октет" ? Глаз режет ..
-
> Какое отношение ф-ция GetLocalIP имеет к "что за регион > передал инфу" ?
Ну же объяснил. По новой что ли писать?[2] 3 октет - число , определяющее район.
-
К принятой-то "инфе" получение локального адреса какое отношение имеет ?
Адрес отправителя "инфы" (адрес удаленного хоста) и адрес получателя "инфы" (адрес локального хоста, тот которым ты интересуешься в GetLocalIP) - это две разные разницы !
Накой шиш получателю интересоваться своим локальным адресом, если, по твоим же словам, его волнует адрес именно отправителя ?)
-
> 3 октет - число , определяющее район.
- 3 октет - определяет 16777216 - IPv4 адресов. У вас в районе 16 миллионов компьютеров?
- согласно маске подсети - район в вашем регионе определяется не октетом, а старшими 23 битами - для головной организации и 24 битами - для районов...
-
> Я не сетевик
"Беда, коль пироги начнет печи сапожник, А сапоги тачать пирожник" (с) «Щука и Кот»
-
> Накой шиш получателю интересоваться своим локальным адресом, > если, по твоим же словам, его волнует адрес именно отправителя > ?)
Я наверное не доходчиво объясняю. Попробую еще раз. В подчинении головного отделения имеется 22 районных предприятия. Сеть одна, связь по ADSL. Каждый район вклчает в себя ряд подразделений(деревни, поселки и т.д), информация из которых передается в районный центр, а уж потом район передает сводную информацию в головной офис.У районных узлов следующие айпи адреса:
1) Гадюкинский р-н 172.25.17.5 2) Муходрищинский р-н 172.25.38.10 3) Чкаловский р-н 172.25.30.3 и т.д
В головном офисе стоит программа-сортировщик которая получает с районов инфформацию. Сканируя принятый файл и находя в определенном месте документа цифру 17 программа определяет, что данные пришли от Гадюкинского района, далее обрабатывая следующий файл, обнаружив цифру 38, определяет, что данные получены от Муходрищинского района и т.д. У головной программы есть справочник со списком определенных чисел, представляющих из себя значения 3-х октетов IP-адресов локальных машин конкретного района. Ну теперь то понятно.
ps Вчера каким то образом получилось удалить сетевое соединение(полученное после подключения камеры, упорно не давало удалить). Сегодня подключил камеру, сетевого соединения не появилось, но камера работает и виден IP-адрес только сетевой карты. Чудеса...
-
> Ну теперь то понятно
Да по-прежнему нихрена не понятно)
Непонятно какова смысловая связь между получением списка локальных (!!!!!) адресов хоста (GetHostByName) и адресами удаленных (!!!!!) хостов, присылающих файлы...
-
> Я наверное не доходчиво объясняю. Попробую еще раз.
не получилось...
> В подчинении головного отделения имеется 22 районных предприятия. > Сеть одна, связь по ADSL.
Суть понимания кроется тут. Что такое "одна сеть"?
> Сканируя принятый файл и находя в определенном месте документа > цифру 17 программа определяет,
Куда-то в лес..
-
Вы может от большого ума все усложняете? (без обид...) но как еще объяснить я уже не знаю. Дайте наводящие вопросы - я отвечу.
-
> laguna © (18.01.12 12:11) [19]
Давай на огурцах - приведенная тобой ф-ция GetLocalIP где и в какой момент вызывается ? Это, видимо, фрагмент той самой "головной программы" ?
-
Нет, эта функция стоит на клиентских(на районах) машинах и определяет IP машины, с которой будет отослан отчет в "центр" Алексу :)
-
> laguna © (18.01.12 13:38) [21]
Во-от)..
Наконец подходим к развязке драмы: каким образом, т.е. с использованием какого конкретно штатного (либо тобой самописного) сервиса отчет доставляется "в центр" Алексу" ?
-
> Сергей М. © (18.01.12 13:45) [22]
по обычной почте (электронной) в виде текстового файла, определенной структуры.
-
> по обычной почте (электронной)
Во-от)..
А теперь главный вопрос - за каким тебе понадобилось искать локальный адрес явно, если smtp-сервер (наверняка у вас он в той же подсети) сам определит этот адрес (или имя хоста) и запишет в поле заголовка "Received" доставляемого письма ?
На принимающей письмо стороне остается только прочитать это поле..
-
Прочитать письмо - да , можно, глазами, выбрав его сначала из папки входящих, только этого мало. Нужно полученную информацию разнести по полочкам, соответствующим каждому району. И делает это "головная программа". Только это один из сервисов, работающих с районами. Некоторые модули отправляют данные напрямую в базу на головном сервере(одна сетка), проставляя соответствующие коды в соответствующие району поля. ДА и много чего еще. Всего объяснять нет смысла, т.к. каждый продумывает интервейс обмена данных по своему, применительно к местным условиям. Мне то нужно всего лишь праввильно извлеч IP адрес локальной машины(районной). Это я уже вернулся с чего начинался вопрос.
-
> Мне то нужно всего лишь праввильно извлеч IP адрес локальной > машины
Зачем ?!) Чтобы влупить его в текст отправляемого почтой документа что ли ?
-
лично ты какое отношение имеешь к "головной программе" ? ты ее разработчик или каким либо образом причастен к ее разработке ?
-
> Зачем ?!)Чтобы влупить его в текст отправляемого почтой > документа что ли ?
Чтобы данные положить туда куда надо, без дополнительного вмешательства операторов.
> лично ты какое отношение имеешь к "головной программе" ? > ты ее разработчик или каким либо образом причастен к ее > разработке ?
Да, разработчик. Да все работает как надо, просто говорю, что сегодня, точнее вчера с подключением камеры возник такой казус. Если бы не заметил, то и дальше работало бы.
-
Добавлю еще. Еще есть сирвис, в котором программа(районная) зная какой это район, отсылает письмо по конкретному адресу, т.к. определенный оператор обслуживает тот или иной район и у каждого есть свой личный п/я
-
> положить туда куда надо
smtp-клиент и без тебя и без вмешательства оператора определит этот адрес и положит туда куда следует - в параметр команды HELO/EHLO.
Тебе как разработчику "головной программы" остается получив письмо заглянуть в самое последнее поле "Received" его заголовка, взять оттуда адрес или имя хоста отправителя.
И зачем нужны все эти выкрутасы с "куда надо" при доставке именно почтой - по-прежнему совершенно не понятно. По сути ты попросту дублируешь инф-цию о сетевом адресе отправителя в случае именно почтовой доставки корреспонденции.
-
> Тебе как разработчику "головной программы" остается получив > письмо заглянуть в самое последнее поле "Received" его заголовка, > взять оттуда адрес или имя хоста отправителя.
Откуда мне знать каким клиентом будут отсылаться письма? Под каждый подстраиваться? Зачем еще вклиниваться в завязку с SMTP клиентами и прочей обработкой почтовой корреспонденции аутглюка. Позавчера у нас Exchange сдох, неделю ковырялись, переводили на другой. Толком почта не работает. Отправляли через интернет. Короче нафига лишние хлопоты, когда мне нужно только IP адрес нормально вычислить? Раньше я определялся от доменного имени, но потом решили от доменов отказаться, точнее всех ввести в один домен, а привязаться - к 3 октету.
-
Возвращаемся к пирожникам и т.п.
Ты написал софт, исходя из видения проблемы своими глазами и соответствующих своих знаниях (которых оказалось не достаточно т.к. "Я не сетевик" и баста). Теперь получил за это граблями от камеры. Далее два пути: 1 - курить rfc по почтовым протоколам и переделать свой софт 2 - склепать заплатку, авось и так сойдет и получить граблями в следующий раз
-
> Откуда мне знать каким клиентом будут отсылаться письма?
А тебе и знать это не нужно.
Любой приличный smtp-сервер соблюдает правила, установленные RFC 821, в соответствии с которыми smtp-клиент должен представиться параметром команды HELO/EHLO в сеансе инф.обмена с сервером. Клиент, нарушающий это правило, будь он то хоть Аутглюк хоть СуперПуперХрюк, приличным сервером будет послан лесом.
-
> почта не работает. Отправляли через интернет
Тебе-то до этого какое дело ? Этим админы должны заниматься, в крайнем случае продвинутые эникейщики) Но ты-то якобы разработчик !) > мне нужно только IP адрес нормально вычислить Да даже если и так, то ты как разработчик обязан был видеть, что Result := iNet_ntoa(PInAddr(p^.h_addr_list^)^);
-
Dennis I. Komarov © Сергей М. © Ребята, я конечно преклоняюсь перед вашим мастерством. Но данную ситуацию нельзя назвать проблемой повышенного разряда. Ведь код программы для всех районов одинаковый. Видать нужно привести еще немного кода, чтобы вы меня не считали ваще за идиота, который сам не понимает чего хочет. Как я уже писал, что в зависимости от того, кто передает данные, программа в базу на сервере запишет его ID(буду уже так говорить). Вот такие примеры для пояснения почему нужна привязка по IP. Допустим, повторяюсь, регион сформировал данные для отправки по почте оператору. Автоматизация здесь не нужна, т.к. полученные данные всерано оператором перпроверяются и вводяися руками в другую программу. Для того чтобы знать какой район привязан к какому оператору, в программе прописан массив адресов(вымышленные):
OperSDO_A : Array[1..9] of String[30] = ('operator1@region.firma.ru', 'operator3@region.firma.ru',
'operator5@region.firma.ru', 'operator6@region.firma.ru',
'operator7@region.firma.ru', 'operator8@region.firma.ru',
'operator9@region.firma.ru', 'operator10@region.firma.ru',
'operator12@region.firma.ru');
затем мы вычисляем, кому конкретно слать письмо с данными
function RupsOperSDOFromIP : Byte;
Var
oktet : String;
begin
oktet := ExtractWord(3, GetLocalIP, ['.']);
Case StrToInt(oktet) of
104, 112, 136 : Result := 1;
201, 240 : Result := 2;
216, 168 : Result := 3;
248, 80 : Result := 4;
88, 224 : Result := 5;
160, 208, 192 : Result := 6;
152, 60, 61 : Result := 7;
184, 128, 176 : Result := 8;
232, 96, 120 : Result := 9;
else
Result := 0;
end;
end;
затем отправляем письмо конкретному адресату
PolMail.Add(OperSDO_A[RupsOperSDOFromIP]);
прямая запись в базу ID региона через функцию(упрощенно показано)
function RupsKodFromIP : Byte;
Var
oktet : String;
begin
oktet := ExtractWord(3, GetLocalIP, ['.']);
Case StrToInt(oktet) of
60,61 : Result := 1;
80 : Result := 2;
248 : Result := 3;
88 : Result := 4;
96 : Result := 5;
104 : Result := 6;
112 : Result := 7;
120 : Result := 8;
128 : Result := 9;
152 : Result := 10;
160 : Result := 11;
168 : Result := 12;
176 : Result := 13;
184 : Result := 14;
216 : Result := 15;
192 : Result := 16;
136 : Result := 17;
201 : Result := 18;
208 : Result := 19;
224 : Result := 20;
232 : Result := 21;
240 : Result := 22;
else
Result := 0;
end;
end;
> Да даже если и так, то ты как разработчик обязан был видеть, > чтоResult := iNet_ntoa(PInAddr(p^.h_addr_list^)^);
Сергей, если честно я не разбирался с этой функцией, я просто ее использовал. Если не трудно скажи, что ты этим хотел сказать.
-
> Да даже если и так, то ты как разработчик обязан был видеть, > что > > Result := iNet_ntoa(PInAddr(p^.h_addr_list^)^);
Он же не сетевик - у него адрес у машины ([25]), а то что они не у машины и их много до сих пор нишьт ферштейн...
-
покажи код приема сообщения от региона...
-
> Laguna © (18.01.12 23:07) [35]
Это ты сейчас фрагмент чего привел - фрагмент "головной программы" ? > что ты этим хотел сказать
List в переводе с вражеского - это список. Присутствие слова List = "список" в и дентификаторе поля h_addr_list разве тебе ни о чем как разработчику не говорит ?
-
Кажись я начинаю соображать что здесь за каша)
Твоя клиентская часть, автоматизирующая отправку отчетов, локальному IP-адресу пытается однозначно сопоставить email-адрес, на который отчет должен быть отправлен. Типа чтобы у серверной части - получателя ("головной программы" или что там у тебя - не знаю) не болела голова о сортировке поступающих отчетов по отправителям.
И это вместо того чтобы завести один-единственный почтовый ящик, кидать туда (автоматически или вручную - не важно) всю корреспонденцию с отчетами и научить программу-получателя выгребать этот ящик и автоматически сортировать входящую корреспонденцию по признакам, фигурирующим в заголовках писем, в том числе и в первую очередь по полю "Received", коль речь идет об идентификации по IP-адресу хоста-отправителя.
-
> Это ты сейчас фрагмент чего привел - фрагмент "головной > программы" ?
Нет, это фрагмент "региональной" программы.
> покажи код приема сообщения от региона...
а там кода как такового нет. Сообщение - это текстовый фарм определенного формата. Смотря какая функция выполняется. Если отсылка опреатору - то простая отправка из региона по почте на конкретный адрес. Если запись в базу, то тоже писал. "Головная программа" - я даже не знаю как сказать. Это просто просмотр переданных данных с фильтрацией по конкретному региону.
-
> Типа чтобы у серверной части - получателя ("головной программы" > или что там у тебя - не знаю) не болела голова о сортировке > поступающих отчетов по отправителям.
Эврика !!! Наконец то. Именно так и есть.
> И это вместо того чтобы завести один-единственный почтовый > ящик, кидать туда
Иногда мы не в силах изменить установленные правила. Организация большая и правила установлены не мной. Я под них только подстраиваюсь.
-
Я бы повесил TCP-Server голове, который по ip-у клиента возвращал почтовый адрес оператора. И у клиента голова не болит, и управляется все в одном месте...
-
> который по ip-у клиента возвращал почтовый адрес оператора
А чем этот вариант будет отличатся от показанного мною выше варианта с массивом адресов и подстановкой нужного в зависимости от определенного IP адреса? Ведь суть от этого не меняется, суть всеравно заключается в первоначальном определении IP адреса региона.
-
Ну сам же сказал, что структуру поменять не можешь... Вот и заплатка соответствующая. Как по хорошему надо делать, уже Сергей сказал.
> А чем этот вариант будет отличатся от показанного мною выше > варианта с массивом адресов и подстановкой нужного в зависимости > от определенного IP адреса?
1. адрес будет того интерфейса, с которого произошло соединение (а не IP камеры и т.п.), и не важно, локальный он будет или белый прова, т.к. локальные оказались за NAT-ом, идентифицировать можно... 2. таблица соответствия находится не на многих клиентах, а на одном сервере, и если сегодня Маша ушла в декрет, Лена заболела, а Таня перешла в другой отдел, достаточно будет исправить эту одну табличку, а не устраивать разборки почему письмо ушло не туда, и в срочном порядке править софт n-му клиенту...
-
> Организация большая и правила установлены не мной
Бардак автоматизировать нельзя)
-
> Бардак автоматизировать нельзя)
При случае предложу эту мысль директору на рассмотрение :). Итак мы пришли к тому, что вы советуете разные варианты, ну никак не способы определения IP.
-
Ты проигнорировал [38]
-
Сергей М.
Я не проигнорировал, я просто не понял смысла намека. Что List - это список я и сам знаю, вот что он определяет в контексте приведенного куска кода я не понял как я должен был отреагировать. Если не трудно, продли мысль, только если можно без наводящих вопросов и пр. , дабы не флудить .
-
А может сначала справку внимательнло проштудируешь именно по описанию этого параметра ?
-
> я просто не понял смысла намека. Что List - это список я > и сам знаю
Ну если это список, значит он может содержать и более одного элемента. Но ты игнорируешь любые потенциально существующие в списке элементы кроме первого, а потом удивляешься почему адресов у интерфейса больше чем ты ожидал)
-
> у интерфейса
у хоста конечно же, а не у интерфейса
-
> Но ты игнорируешь любые потенциально существующие в списке > элементы кроме первого, а потом удивляешься почему адресов > у интерфейса больше чем ты ожидал)
Ну да, действительно функция тупо берет первый элемент списка и не важно какой IP будет на его месте. Плохо, что у меня уже пропал интерфейс камеры. Не могу сейчас проверить набор списка. Правда нужно еще подумать как к нему подобраться...
-
> Ну да, действительно функция тупо берет первый элемент списка
Ну так и сделай не "тупо", а по уму - прочитай ВЕСЬ список и ищи в нем адрес, попадающий под твои условия..
> Плохо, что у меня уже пропал интерфейс камеры. Не могу сейчас > проверить набор списка
Вот ведь трагедия-то) Ну возьми да установи на время тестирования любой софт, создающий хотя бы один виртуальный сетевой интерфейс ! Оного ж как дерьма за баней существует - возьми хоть тот же Хамачи для пущей наглядности)...
> нужно еще подумать как к нему подобраться
Ты программист или где ?) Открываешь справку - там все написано ..
-
Структуру HostEnt я обозрел. Чет в разъименованиях запутался.
Result := iNet_ntoa(PInAddr(p^.h_addr_list^)^);
-
> Чет в разъименованиях запутался
Мдя ..
function GetLocalIPs: String;
const
WSVer = $101;
type
PPInAddr = ^PInAddr;
var
wsaData: TWSAData;
P: PHostEnt;
Buf: array [0..127] of Char;
NextAddrTableItem: PPInAddr;
begin
Result := '';
if WSAStartup(WSVer, wsaData) = 0 then
begin
if GetHostName(@Buf, 128) = 0 then
begin
P := GetHostByName(@Buf);
if P <> nil then
begin
NextAddrTableItem := PPInAddr(p.h_addr_list);
while Assigned(NextAddrTableItem^) do
begin
if Result <> '' then
Result := Result + #13#10;
Result := Result + String(iNet_ntoa(PInAddr(NextAddrTableItem^)^));
Inc(NextAddrTableItem);
end;
end;
end;
WSACleanup;
end;
end;
-
Мдя... Зыж какой же гений сие вообще придумал?
-
За не очень скромное вознаграждение, вылечу вашу контору от гемороя :)
-
> Сергей М. © (19.01.12 16:05) [55]
Спасибю, завтра буду разбираться.
|