Информация о сетевых интерфейсах
01.01.2007
unit netinfo; interface uses Libc; type INTERFACE_INFO = packed record Name: string; IPAddress: string; Broadcast: string; NetMask: string; IsUp: boolean; IsRun: boolean; IsBroadcast: boolean; IsMulticast: boolean; IsLoopBack: boolean; IsPPP: boolean; end; TAInfo = record INFO: array of INTERFACE_INFO; end; function EnumInterfaces(var IInfo: TAInfo): Boolean; implementation function EnumInterfaces(var IInfo: TAInfo): Boolean; var SHandle: integer; len: longint; bufChar; ifc: ifconf; pifr: pifreq; ifr: ifreq; lastlen, i: integer; pAddrChar; begin Result := False; //создать UDP сокет SHandle := Socket(AF_INET, SOCK_DGRAM, 0); if SHandle = INVALID_SOCKET then exit; { При вызове SIOCGIFCONF некоторые реализации не возвращают ошибок, если буфер слишком мал для хранения результата вызова (результат просто обрезается) Поэтому надо сделать вызов, запомнить возвращенную длину, увеличить буфер и сделать еще один вызов ксли после этого вызова длины будут равны - OK! иначе надо циклично увеличивать буфер. } lastlen := 0; len := 100 * sizeof(ifreq); while true do begin buf := Malloc(len); ifc.ifc_len := len; PChar(ifc.ifc_ifcu) := buf; if ioctl(SHandle, SIOCGIFCONF, @ifc) < 0 then begin if (errno <> EINVAL) and (lastlen <> 0) then warn('ioctl error'); end else begin if ifc.ifc_len = lastlen then break; lastlen := ifc.ifc_len; end; len := len + 10 * sizeof(ifreq); free(buf); end; Result := True; //здесь результат получен полностью //len - кол-во интерфейсов len := ifc.ifc_len div sizeof(ifreq); SetLength(IInfo.Info, len); //указатель - на начало буфера pifr := ifc.ifc_ifcu.ifcu_req; for i := 0 to len - 1 do begin fillchar(ifr, sizeof(ifreq), 0); //считать очередную порцию данных move(pifr^, ifr, sizeof(ifreq)); //имя интерфейса IInfo.INFO[i].Name := ifr.ifrn_name; //адрес интерфейса pAddr := inet_ntoa(ifr.ifru_addr.sin_addr); IInfo.INFO[i].IPAddress := pAddr; //ШВ адрес ioctl(SHandle, SIOCGIFBRDADDR, @ifr); pAddr := inet_ntoa(ifr.ifru_netmask.sin_addr); IInfo.INFO[i].Broadcast := pAddr; //маска сети ioctl(SHandle, SIOCGIFNETMASK, @ifr); pAddr := inet_ntoa(ifr.ifru_netmask.sin_addr); IInfo.INFO[i].NetMask := pAddr; //флаги ioctl(SHandle, SIOCGIFFLAGS, @ifr); IInfo.INFO[i].IsUP := (ifr.ifru_flags and IFF_UP) = IFF_UP; IInfo.INFO[i].IsRun := (ifr.ifru_flags and IFF_RUNNING) = IFF_RUNNING; IInfo.INFO[i].IsBroadcast := (ifr.ifru_flags and IFF_BROADCAST) = IFF_BROADCAST; IInfo.INFO[i].IsLoopBack := (ifr.ifru_flags and IFF_LOOPBACK) = IFF_LOOPBACK; IInfo.INFO[i].IsPPP := (ifr.ifru_flags and IFF_POINTOPOINT) = IFF_POINTOPOINT; IInfo.INFO[i].IsMulticast := (ifr.ifru_flags and IFF_MULTICAST) = IFF_MULTICAST; inc(pifr); end; end; end.
Взято с Исходников.Ru