Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Сети > Проблема определения MAC-адреса


Автор: p0s0l 6.11.2004, 16:49
Мне надо сделать привязку программы к железу.
Один из параметров привяки - MAC адрес сетевого адаптера.
Но возникли трудности... Не нашёл способа уверенного определения MAC-адреса.
Способы, которые я пробовал - ненадёжные...

1) Через функцию Netbios (см. DRKB).
Если нет сетевого подключения, получается облом... smile

2) Через сокеты (см. DRKB): socket, getsockopt.
Не работает в любом случае... Пока не разбирался в чём дело...

3) Создание GUID/UUID
В GUID/UUID используется MAC-адрес.
Опять же, если нет сетевого подключения, то будет кирдык - либо возьмётся MAC-адрес другого активного адаптера (например, их устанавливает VMWare), либо если их нет, будет какая-то ерунда вместо MAC-адреса...

4) Ip Helper API
GetAdaptersAddresses - в возвращаемой структуре есть поле PhysicalAddress, но почему он один ? А если несколько адаптеров ? В любом случае, на моём компе это поле заполняется нулями...
SendARP (inet_addr('127.0.0.1'), 0, ...) - не пашет... как им пользоваться ?
GetIpNetTable - в bPhysAddr что-то не то...
GetAdaptersInfo - работает, но опять же только если соединение активно smile


КАК БЫТЬ ? Какие идеи ?

Автор: Girder 10.11.2004, 02:08
Цитата(p0s0l @ 6.11.2004, 16:49)
SendARP (inet_addr('127.0.0.1'), 0, ...) - не пашет... как им пользоваться ?
К примеру вот так smile :
Код
uses ... winsock;
...
function SendARP(DestIP:DWord; SrcIP:DWord; pMacAddr:PULONG;
PhyAddrLen:PULONG):DWORD; stdcall; external 'IPHLPAPI.DLL';

var
 Form1: TForm1;

implementation

{$R *.dfm}

function GetIP():string;
var WSAData:TWSAData;
   p:PHostEnt;
   hName:array [0..255] of Char;
begin
WSAStartup($101,WSAData);
GetHostName(hName,255);
p:=GetHostByName(hName);
Result:=inet_ntoa(PInAddr(p.h_addr_list^)^);
WSACleanup;
end;

function GetMacByIP(const sIP:string):string;
var DestIP:integer;
   AddrLen:u_long;
   MacAddr: array[1..6] of byte;
   s:string;
   i:integer;
begin
DestIP:=inet_addr(pchar(sIP));
AddrLen:=sizeof(MacAddr);
if (SendARP(DestIP,0,PULONG(@MacAddr),@AddrLen)=0)and(AddrLen>0) then
 begin
  for i:=1 to AddrLen-1 do s:=s+IntToHex(MacAddr[i],2)+'.';
  s:=s+IntToHex(MacAddr[AddrLen],2);
 end else s:='00.00.00.00.00.00';
Result:= s;
end;

...
Использование: Caption:=GetMacByIP(GetIP) или Caption:=GetMacByIP('192.168.1.1')...

Цитата(p0s0l @ 6.11.2004, 16:49)
КАК БЫТЬ ? Какие идеи ?

Ну... можно обратиться к таблице маршрутизации на прямую, т.е. воспользоваться INETMIB1.DLL: SnmpExtensionInit - Функция инициализации; SnmpExtensionQuery - Функция запроса; SnmpExtensionTrap - Обработчик ловушек.

Проверять, при неактивном сетевом подключении, не стал... так как считаю что привязка по MAC не есть гуд... smile Т.к. МАС можно изменить!

Поясню...:
1)Для некоторых сетевых карт можно заменить МАС адресс в настройках драйвера;
2)Для некоторых... устанавливая соответствующие ключи в реестре
3)Использование двух интерфейсов - готовых реализаций в инете полно smile
4)Самый простой и надежный способ! - Корректировать драйвер сетевой карты. Т.к. драйвер сетевой карты считывает MAC-адрес через стандартные порты ввода-вывода только на этапе инициализации! Чтение MAC-адреса происходит через порт XXX и определение его не составляет труда: смотрится диапазон ввода-вывода сетевой карты... к примеру он равен=AA00h...AA1Fh => тогда XXX=AA00h+10h=AA10h... ну а дальше SoftIce и bpio AA10 r и... и... я думаю поймеш дальше сам... smile

PS: Даже если ты сделаеш определение МАС адресса через порт(имхо: самый надежный спрособ smile ), то... не хороший юзер... все равно быстро енто отсечет и воспользуется 4 способом... но уже не для драйвера, а для твоей программы.

Удачи.

Автор: p0s0l 10.11.2004, 13:08
Цитата
Т.к. МАС можно изменить!

Это понятно. Но моя прога сама не знает, какой MAC-адрес правильный (она лишь может сказать, есть изменения в аппаратуре или нет, а в чём именно изменения - это она не знает), поэтому какой адрес юзер будет ставить ?
Короче, тут всё продумано (вроде smile), даже если саму прогу кто-то заломает - он потом об этом пожалеет smile

Цитата(Girder @ 10.11.2004, 02:08)
К примеру вот так
Спасибо.... Но так не интересно smile Вот заставить бы для 127.0.0.1 работать - было бы круто, хотя нельзя видимо. А таким способом - это опять же узнаётся только адаптер активного соединения... smile
Еще пробовал через WMI - такая же фигня...
Придётся отказаться от MAC-адреса...


Автор: Akella 11.12.2004, 10:14
В WinXP такая программка исчезла, а в Win98 она была smile

Автор: Akella 11.12.2004, 10:15
пример, как работать с ARP

Автор: Akella 11.12.2004, 10:18
забыл, может быть, понаlобится WinSock2

Автор: dm9 13.12.2004, 05:41
Мне тоже сначала пришла в голову мысль использовать ipconfig /all smile

Автор: Alex 13.12.2004, 11:31
Цитата(dsergey @ 11.12.2004, 10:14)
В WinXP такая программка исчезла, а в Win98 она была

Ни куда она не изчезала Пуск->Выполнить->cmd /k ipconfig /all

Автор: p0s0l 17.12.2004, 23:08
dsergey, спасибо smile, но это всё равно не то что нужно...

Цитата(dm9 @ 13.12.2004, 05:41)
Мне тоже сначала пришла в голову мысль использовать ipconfig /all

IPConfig предназначен для IP-адресов, они назначаются при активном подключении. Нет подключения - нет IP-адреса, нет и MAC-адреса (если смотреть через IPConfig)...

Короче, всё в итоге сводится к такому вопросу:
Как узнать MAC-адрес, даже если нет сетевого подключения ?
Все API-функции, которые я просмотрел, думают, что если нет сетевого подключения, то как будто бы и нет сетевой карты вообще, физически...

Если делать через порт - то шкурка выделки не стоит...

Автор: Akella 23.12.2004, 12:11
ну звыняйте, бананив у нас нэмае smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)