Получение локального IP адреса [win & linux]
Модератор: Модераторы
У меня FreeBSD 8.x и 9.x - будет работать этот метод?
У меня на RFR-19 возврат ifconfig немного отличается, поэтому внёс изменения:
Код: Выделить всё
if Pos('inet addr',Result)>0 then
Result:=Copy(Result,Pos('inet addr',Result)+10,20)
else
if Pos('inet',Result)>0 then
Result:=Copy(Result,Pos('inet',Result)+5,20);
Result:=Trim(ExtractWord(1,Result,[':',' '])); У меня FreeBSD 8.x и 9.x - будет работать этот метод?
нет
отредактировал заголовок и добавил примечание - надеюсь автор напишет более точно в каких системах работает
Ну чтож , товарищи, провел жесточайший рефракторинг, теперь утилиты вообще не используются, все через /proc/net и системные вызовы. Пришлось перелопатить исходники Fpc
Проверяйте, модуль с процедурой прикреплен
Ссылки по теме
http://www.f-notes.info/linux:linux_command
http://www.linuxdevcenter.com/lpt/a/461
http://linux.die.net/man/5/proc
Тадааам
unit ip_utils;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils,ctypes,strutils{$IFDEF UNIX} ,BaseUnix,Sockets{$ENDIF}{$IFDEF WINDOWS},Winsock {$ENDIF};
function GetLocalIP: string;
const IF_NAMESIZE = 16;
IFNAMSIZ = IF_NAMESIZE;
implementation
function GetLocalIP: string;
{$IFDEF UNIX}
type
__caddr_t = char;
Pifmap = ^ifmap;
ifmap = record
mem_start : dword;
mem_end : dword;
base_addr : word;
irq : byte;
dma : byte;
port : byte;
end;
Pifreq = ^ifreq;
ifreq = record
ifr_ifrn : record
case longint of
0 : ( ifrn_name : array[0..(IFNAMSIZ)-1] of char );
end;
ifr_ifru : record
case longint of
0 : ( ifru_addr : sockaddr );
1 : ( ifru_dstaddr : sockaddr );
2 : ( ifru_broadaddr : sockaddr );
3 : ( ifru_netmask : sockaddr );
4 : ( ifru_hwaddr : sockaddr );
5 : ( ifru_flags : smallint );
6 : ( ifru_ivalue : longint );
7 : ( ifru_mtu : longint );
8 : ( ifru_map : ifmap );
9 : ( ifru_slave : array[0..(IFNAMSIZ)-1] of char );
10 : ( ifru_newname : array[0..(IFNAMSIZ)-1] of char );
11 : ( ifru_data : __caddr_t );
end;
end;
var
I:Integer;
VStrTemp,VStrTempRes: TStringList;
sockaddr_:ifreq;
socket_:cint;
const SIOCGIFADDR = $8915;
{$ENDIF}
{$IFDEF MSWINDOWS}
var
VWSAData: TWSAData;
VHostEnt: PHostEnt;
VName: string;
const CFormatIPMask = '%d.%d.%d.%d';
{$ENDIF}
begin
Result := '';
{$IFDEF UNIX}
VStrTemp := TStringList.Create;
VStrTempRes := TStringList.Create;
VStrTempRes.Clear;
VStrTempRes.Sorted:=true;
VStrTempRes.Duplicates:=dupIgnore;
VStrTemp.LoadFromFile('/proc/net/route');
for i:=0 to VStrTemp.Count-1 do
begin
if ExtractWord(4,VStrTemp[i],[#9])='0001' then VStrTempRes.Add(ExtractWord(1,VStrTemp[i],[#9])); // 0001 Флаг U в таблице маршрутизации
end;
socket_:=fpsocket(AF_INET,SOCK_DGRAM,0);
sockaddr_.ifr_ifrn.ifrn_name:=VStrTempRes[0];
FpIOCtl(socket_,SIOCGIFADDR,@sockaddr_);
CloseSocket(socket_);
Result:='';;
for i:=1 to 4 do Result:=Result+IntToStr(sockaddr_.ifr_ifru.ifru_addr.sin_addr.s_bytes[i])+'.';
Result:=Copy(Result,1,Length(Result)-1);
FreeAndNil(VStrTemp);
FreeAndNil(VStrTempRes);
{$ENDIF}
{$IFDEF MSWINDOWS}
{$HINTS OFF}
WSAStartup(2, VWSAData);
{$HINTS ON}
SetLength(VName, 255);
GetHostName(PChar(VName), 255);
SetLength(VName, StrLen(PChar(VName)));
VHostEnt := GetHostByName(PChar(VName));
with VHostEnt^ do
Result := Format(CFormatIPMask, [Byte(h_addr^[0]), Byte(h_addr^[1]),
Byte(h_addr^[2]), Byte(h_addr^[3])]);
WSACleanup;
{$ENDIF}
end;
Проверяйте, модуль с процедурой прикреплен
Ссылки по теме
http://www.f-notes.info/linux:linux_command
http://www.linuxdevcenter.com/lpt/a/461
http://linux.die.net/man/5/proc
Тадааам
unit ip_utils;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils,ctypes,strutils{$IFDEF UNIX} ,BaseUnix,Sockets{$ENDIF}{$IFDEF WINDOWS},Winsock {$ENDIF};
function GetLocalIP: string;
const IF_NAMESIZE = 16;
IFNAMSIZ = IF_NAMESIZE;
implementation
function GetLocalIP: string;
{$IFDEF UNIX}
type
__caddr_t = char;
Pifmap = ^ifmap;
ifmap = record
mem_start : dword;
mem_end : dword;
base_addr : word;
irq : byte;
dma : byte;
port : byte;
end;
Pifreq = ^ifreq;
ifreq = record
ifr_ifrn : record
case longint of
0 : ( ifrn_name : array[0..(IFNAMSIZ)-1] of char );
end;
ifr_ifru : record
case longint of
0 : ( ifru_addr : sockaddr );
1 : ( ifru_dstaddr : sockaddr );
2 : ( ifru_broadaddr : sockaddr );
3 : ( ifru_netmask : sockaddr );
4 : ( ifru_hwaddr : sockaddr );
5 : ( ifru_flags : smallint );
6 : ( ifru_ivalue : longint );
7 : ( ifru_mtu : longint );
8 : ( ifru_map : ifmap );
9 : ( ifru_slave : array[0..(IFNAMSIZ)-1] of char );
10 : ( ifru_newname : array[0..(IFNAMSIZ)-1] of char );
11 : ( ifru_data : __caddr_t );
end;
end;
var
I:Integer;
VStrTemp,VStrTempRes: TStringList;
sockaddr_:ifreq;
socket_:cint;
const SIOCGIFADDR = $8915;
{$ENDIF}
{$IFDEF MSWINDOWS}
var
VWSAData: TWSAData;
VHostEnt: PHostEnt;
VName: string;
const CFormatIPMask = '%d.%d.%d.%d';
{$ENDIF}
begin
Result := '';
{$IFDEF UNIX}
VStrTemp := TStringList.Create;
VStrTempRes := TStringList.Create;
VStrTempRes.Clear;
VStrTempRes.Sorted:=true;
VStrTempRes.Duplicates:=dupIgnore;
VStrTemp.LoadFromFile('/proc/net/route');
for i:=0 to VStrTemp.Count-1 do
begin
if ExtractWord(4,VStrTemp[i],[#9])='0001' then VStrTempRes.Add(ExtractWord(1,VStrTemp[i],[#9])); // 0001 Флаг U в таблице маршрутизации
end;
socket_:=fpsocket(AF_INET,SOCK_DGRAM,0);
sockaddr_.ifr_ifrn.ifrn_name:=VStrTempRes[0];
FpIOCtl(socket_,SIOCGIFADDR,@sockaddr_);
CloseSocket(socket_);
Result:='';;
for i:=1 to 4 do Result:=Result+IntToStr(sockaddr_.ifr_ifru.ifru_addr.sin_addr.s_bytes[i])+'.';
Result:=Copy(Result,1,Length(Result)-1);
FreeAndNil(VStrTemp);
FreeAndNil(VStrTempRes);
{$ENDIF}
{$IFDEF MSWINDOWS}
{$HINTS OFF}
WSAStartup(2, VWSAData);
{$HINTS ON}
SetLength(VName, 255);
GetHostName(PChar(VName), 255);
SetLength(VName, StrLen(PChar(VName)));
VHostEnt := GetHostByName(PChar(VName));
with VHostEnt^ do
Result := Format(CFormatIPMask, [Byte(h_addr^[0]), Byte(h_addr^[1]),
Byte(h_addr^[2]), Byte(h_addr^[3])]);
WSACleanup;
{$ENDIF}
end;
- Вложения
-
- ip_utils.7z
- (1.25 КБ) 1320 скачиваний
какие ос поддерживаются?
а то не знаю - мне проверять или нет
а то не знаю - мне проверять или нет
ev писал(а):какие ос поддерживаются?
а то не знаю - мне проверять или нет
Те же, что в исправленном вами заголовке. Разве по коду не видно ?
Просто подключите модуль из архива, верно для Lazarus 1.0.10
Если ктото в макось напишет, вообще шедевр будет
Добавлено спустя 1 час 51 минуту 44 секунды:
Хотя МакОс тоже чемто юникс, возможно код будет похожим
Добавлено спустя 2 часа 15 минут 35 секунд:
Да , и пример с FpIOCtl можно переделать для других системных вызовов Linux, недрах исходников Fpc есть нужные структуры, напрямую модулем почемуто их подключить нельзя
То, что выше из nifh.inc
Ism писал(а):Разве по коду не видно ?
проще спросить, чем вчитываться в опять не особо актуальный (для меня) код
Ism писал(а):Хотя МакОс тоже чемто юникс
при чем тут макось?
