Получение IP-адреса и маски для всех сетевых интерфейсов

Автор: Giannis Sampaziotis
Существует множество методов получения IP адреса компьютера. Но данный пример представляет наиболее корректный способ получения всех адресов, сетевых масок, broadcast адресов и статусов для всех интерфейсов включая циклический 127.0.0.1 - требует WinSock 2.
Совместимость: Delphi 3.х (или выше)
Это завершённый Delphi компонент. Для его использования достаточно вызвать :
EnumInterfaces(var s string): Boolean;
которая вернёт строку, разделённую CRLF и содержащую всё, нужную нам информацию.

unit USock;

interface

uses Windows, Winsock;

{

 Если Вы поместите строку результатов в wide TMEMO (в его свойство memo.lines.text)

 то никаких результатов не увидите.

 Тестировалось на Win98/ME/2K, 95 OSR 2 и NT service

 pack #3 , потому что используется WinSock 2 (WS2_32.DLL)

}


function EnumInterfaces(var sInt: string): Boolean;

{ функция WSAIOCtl импортируется из Winsock 2.0 - Winsock 2 доступен }

{ только в Win98/ME/2K и 95 OSR2, NT srv pack #3 }

function WSAIoctl(s: TSocket; cmd: DWORD; lpInBuffer: PCHAR; dwInBufferLen:

 DWORD;

 lpOutBuffer: PCHAR; dwOutBufferLen: DWORD;

 lpdwOutBytesReturned: LPDWORD;

 lpOverLapped: POINTER;

 lpOverLappedRoutine: POINTER): Integer; stdcall; external 'WS2_32.DLL';

{ Константы взятые из заголовка C файлов }

const SIO_GET_INTERFACE_LIST = $4004747F;

 IFF_UP = $00000001;

 IFF_BROADCAST = $00000002;

 IFF_LOOPBACK = $00000004;

 IFF_POINTTOPOINT = $00000008;

 IFF_MULTICAST = $00000010;

type sockaddr_gen = packed record

  AddressIn: sockaddr_in;

  filler: packed array[0..7] of char;

 end;

type INTERFACE_INFO = packed record

  iiFlags: u_long; // Флаги интерфейса

  iiAddress: sockaddr_gen; // Адрес интерфейса

  iiBroadcastAddress: sockaddr_gen; // Broadcast адрес

  iiNetmask: sockaddr_gen; // Маска подсети

 end;

implementation

{-------------------------------------------------------------------

1. Открываем WINSOCK

2. Создаём сокет

3. Вызываем WSAIOCtl для доступа к сетевым интерфейсам

4. Для каждого интерфейса, получаем IP, MASK, BROADCAST, статус

5. Разделяем строку символом CRLF

6. Конец :)

--------------------------------------------------------------------}


function EnumInterfaces(var sInt: string): Boolean;

var s: TSocket;

 wsaD: WSADATA;

 NumInterfaces: Integer;

 BytesReturned, SetFlags: u_long;

 pAddrInet: SOCKADDR_IN;

 pAddrString: PCHAR;

 PtrA: pointer;

 Buffer: array[0..20] of INTERFACE_INFO;

 i: Integer;

begin

 result := true; // Инициализируем переменную

 sInt := '';

 WSAStartup($0101, wsaD); // Запускаем WinSock

  // Здесь можно дабавить различные обработчики ошибки :)

 s := Socket(AF_INET, SOCK_STREAM, 0); // Открываем сокет

 if (s = INVALID_SOCKET) then exit;

 try  // Вызываем WSAIoCtl

  PtrA := @bytesReturned;

  if (WSAIoCtl(s, SIO_GET_INTERFACE_LIST, nil, 0, @Buffer, 1024, PtrA, nil,

  nil)

  <> SOCKET_ERROR)

  then

  begin  // Если OK, то определяем количество существующих интерфейсов

  NumInterfaces := BytesReturned div SizeOf(INTERFACE_INFO);

  for i := 0 to NumInterfaces - 1 do  // Для каждого интерфейса

  begin

  pAddrInet := Buffer[i].iiAddress.addressIn; // IP адрес

  pAddrString := inet_ntoa(pAddrInet.sin_addr);

  sInt := sInt + ' IP=' + pAddrString + ',';

  pAddrInet := Buffer[i].iiNetMask.addressIn; // Маска подсети

  pAddrString := inet_ntoa(pAddrInet.sin_addr);

  sInt := sInt + ' Mask=' + pAddrString + ',';

  pAddrInet := Buffer[i].iiBroadCastAddress.addressIn; // Broadcast адрес

  pAddrString := inet_ntoa(pAddrInet.sin_addr);

  sInt := sInt + ' Broadcast=' + pAddrString + ',';

  SetFlags := Buffer[i].iiFlags;

  if (SetFlags and IFF_UP) = IFF_UP then

  sInt := sInt + ' Interface UP,'  // Статус интерфейса up/down

  else

  sInt := sInt + ' Interface DOWN,';

  if (SetFlags and IFF_BROADCAST) = IFF_BROADCAST then // Broadcasts

  sInt := sInt + ' Broadcasts supported,'  // поддерживает или

  else  // не поддерживается

  sInt := sInt + ' Broadcasts NOT supported,';

  if (SetFlags and IFF_LOOPBACK) = IFF_LOOPBACK then  // Циклический или

  sInt := sInt + ' Loopback interface'

  else

  sInt := sInt + ' Network interface'; // нормальный

  sInt := sInt + #13#10; // CRLF между каждым интерфейсом

  end;

  end;

 except

 end;

//

// Закрываем сокеты

//

 CloseSocket(s);

 WSACleanUp;

 result := false;

end;

end.

Взято из http://forum.sources.ru

Отправить комментарий

Проверка
Антиспам проверка
Image CAPTCHA
...