Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 2004.07.25;
Скачать: [xml.tar.bz2];

Вниз

Выявление "коллизий" в сети   Найти похожие ветки 

 
diMAN   (2004-05-25 19:25) [0]

У нас на предприятии закупили партию компьютеров у которых сетевые карты имеют одинаковый MAC-адрес, а т.к. все эти компьютеры выходят в локальную сеть, то пришлось вручную перенастраивать MAC-адреса, чтобы они были уникальными и могли через DHCP-сервер получить уникальные IP-адреса. Но время от времени в локальной сети выявляются компьютеры, имеющие одинаковые IP-адреса, вследствии одинаковых MAC-адресов. Толи не все компьютеры были первоначально нами перенастроены, толи пользователи переставили Windows, грохнув наши настройки, но проблема существует.
Хотелось бы узнать как можно програмным путём вычислить такие "проблемные" компьютеры? Я так думаю что нужно посылать ARP-пакет и вслучае прихода двух или более ответов считать что этот ip-адрес проблемный.


 
Rouse_ ©   (2004-05-25 21:31) [1]

Если карты Реалтековские (а насколько я знаю, только они поддерживают перепрошивку МАС) то просто сделай у каждой разные МАС и все...
Ты же сам сказал: > пришлось вручную перенастраивать MAC-адреса так в чем проблема?
А ARP получишь посредством SendARP (правда при битом IP сомневаюсь что что-то получится) или через GetIfTable

const
 // Для работы с ARP (Address Resolution Protocol) таблицей
 IPHLPAPI = "IPHLPAPI.DLL";
 MAX_ADAPTER_ADDRESS_LENGTH = 7;

type

 // Следующие три типа используются для работы с Iphlpapi.dll
 // Выдрал из Iphlpapi.h

 // Так будет выглядеть МАС
 TMacAddress = array[0..MAX_ADAPTER_ADDRESS_LENGTH] of byte;

 // Это структура для единичного запроса
 TMibIPNetRow = packed record
   dwIndex         : DWORD;
   dwPhysAddrLen   : DWORD;
   bPhysAddr       : TMACAddress;  // Вот здесь и лежит МАС!!!
   dwAddr          : DWORD;
   dwType          : DWORD;
 end;
 
 // Как и в статье не будем выделять память динамически,
 // а сразу создадим массив... (хотя, чесно говоря, это не правильно,
 // но я иду простым путем :)
 TMibIPNetRowArray = array [0..512] of TMibIPNetRow;

 // А это, как и во всей библиотеке, такая вот...
 // запрашиваемая структура (в моей статье уже видел пример...)
 PTMibIPNetTable = ^TMibIPNetTable;
 TMibIPNetTable = packed record
   dwNumEntries    : DWORD;
   Table: TMibIPNetRowArray;
 end;
// Из всех приведенных функций эта самая интересная.
// Я много раз говорил о незаслуженном невнимании программистов
// к IPHLPAPI.DLL. Данный пример подтверждает это. На всех форумах
// можно услышать о получании МАС адреса посредством посылки IPX пакета
// и разбора заголовка ответа от удаленного компьютера
// (что само по себе геморой, если не принимать во внимание,
// что IPX уже практически вымер, и его мало где встретишь).
// Здесь же строится полная ARP таблица, на основании которой мы
// можем спокойно произвести выборку по нужному IP адресу,
// а так как все берется из кэша, то мы сможем узнать МАС адреса
// даже выключенных компьютеров...
// Единственный минус: в таблице (не всегда) отсутсвует информация
// по локальному компьютеру, т.е. таким образом можно получить
// все МАС адреса за исключением своего,
// но для этого есть уже другие функции...

// Приведу выдержку из MSDN:
// You can use IP Helper to perform Address Resolution Protocol (ARP) operations for the local computer.
// Use the following functions to retrieve and modify the ARP table.
// The GetIpNetTable retrieves the ARP table.
// The ARP table contains the mapping of IP addresses to physical addresses.
// Physical addresses are sometimes referred to as Media Access Controller (MAC) addresses.

// Хочу заметить что для NT есть очень интересная функция SendARP - позволяющая
// напрямую получить требуемый МАС без построения таблицы, поэтому советую
// модифицировать код программы для более эффективного исполнения участков кода
// под различными системами.

function TMainForm.GetMacFromIP(const IP: String): String;

 // (Будем использовать функцию приведения из статьи)
 // В качестве первого значения массив, второе значение,
 // размер данных в массиве
 function GetMAC(Value: TMacAddress; Length: DWORD): String;
 var
   I: Integer;
 begin
   if Length = 0 then Result := "00-00-00-00-00-00" else
   begin
     Result := "";
     for i:= 0 to Length -2 do
       Result := Result + IntToHex(Value[i], 2) + "-";
     Result := Result + IntToHex(Value[Length-1], 2);
   end;
 end;

 // Получаем IP адрес, заметь в отличии от работы с классом WC_IPADDRESS
 // здесь преобразование идет в обратном порядке!
 function GetDottedIPFromInAddr(const InAddr: Integer): String;
 begin
   Result := "";
   Result := IntToStr(FOURTH_IPADDRESS(InAddr));
   Result := Result + "." + IntToStr(THIRD_IPADDRESS(InAddr));
   Result := Result + "." + IntToStr(SECOND_IPADDRESS(InAddr));
   Result := Result + "." + IntToStr(FIRST_IPADDRESS(InAddr));
 end;

 // Основная функция
var
 Table: TMibIPNetTable;
 Size: Integer;
 CatchIP: String;
 Err, I: Integer;
begin
 Result := RES_UNKNOWN;
 Size := SizeOf(Table);                      // Ну тут все просто...
 Err := GetIpNetTable(@Table, @Size, False); // Выполняем...
 if Err <> NO_ERROR then                     // Проверка на ошибку...
 begin
   MessageDlg(ERR_MAC, mtError, [mbOK], 0);
   Exit;
 end;
 // Теперь мы имеем таблицу из IP адресов и соответсвующих им MAC адресов
 for I := 0 to Table.dwNumEntries - 1 do     // Ищем нужный IP ...
 begin
   CatchIP := GetDottedIPFromInAddr(Table.Table[I].dwAddr);
   if CatchIP = IP then                      // И выводим его МАС ...
   begin
     Result := GetMAC(Table.Table[I].bPhysAddr, Table.Table[I].dwPhysAddrLen);
     Break;
   end;
 end;
end;

procedure TMainForm.GetShares(const CompName: String);
var
 Enum, I: Cardinal;
 ScanRes: array [0..512] of TNetResource; // Можно сделать и больший размер массива
 Size, Entries, Err: DWORD;               // но, как показывает практика, такого достаточно
 CurrRes: TNetResource;
 ParentName: array [0..1] of TNetResource;
 Str: PChar;
begin
 with CurrRes do
 begin
   dwScope := RESOURCE_GLOBALNET;
   dwType := RESOURCETYPE_DISK;
   dwDisplayType := RESOURCEDISPLAYTYPE_SERVER;
   dwUsage := RESOURCEUSAGE_CONTAINER;
   lpLocalName := "";
   lpRemoteName := PChar("\\ROUSE");
   lpComment := "";
   lpProvider := nil;
 end;
     Size := SizeOf(ScanRes);
     Entries := DWORD(-1);
     WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_DISK, 0, @CurrRes, Enum);
     Err := WNetEnumResource(Enum, Entries, @ScanRes, Size);
     Caption := ScanRes[0].lpRemoteName;
//  ParentName[0].lpProvider;

end;


---
Желаю успехов


 
Rouse_ ©   (2004-05-25 21:34) [2]

procedure TMainForm.GetShares(const CompName: String);
это я захватил лишнего, к основному примеру данная процедура не имеет никакого отношения ;)


 
Rouse_ ©   (2004-05-25 21:36) [3]

Да забыл: ARP таблица строится динамически и время ее жизДни примерно 30 сек. поэтому желательно пропинговать удаленную машину, но это тоже может оказаться проблематичным с битым IP :)



Страницы: 1 вся ветка

Форум: "Сети";
Текущий архив: 2004.07.25;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.47 MB
Время: 0.034 c
3-1088513201
Igoryok
2004-06-29 16:46
2004.07.25
Не удается найти строку для обновления. Некоторые значения могли


14-1089166782
Aldor_
2004-07-07 06:19
2004.07.25
Восстановление стертой информации (NTFS)


1-1089651413
AndersoNRules
2004-07-12 20:56
2004.07.25
V kakom file i kak hraniti peremennuyu tipa: TmyData=record...


4-1086605735
Andrew
2004-06-07 14:55
2004.07.25
Посылка сообщений...


14-1089110984
Rule
2004-07-06 14:49
2004.07.25
Всем привет с того света ...





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский