[fpc-pascal] lNet getting the local IP

Brian Winfrey bwcode4u at gmail.com
Fri Oct 8 00:04:58 CEST 2010


>> On 06/10/10 14:27, Felipe Monteiro de Carvalho wrote:
>>> Ok, thanks everyone, it seams that I managed to extract a function
>>> from Silvio's code which doesn't use Synapse. I only tested in Windows
>>> so far:
>>>
>>> unit chesstcputils;
>>>
>>> {$mode objfpc}{$H+}
>>>
>>> interface
>>>
>>> uses
>>>    {$IFDEF MSWINDOWS}
>>>    Winsock,
>>>    {$ENDIF}
>>>    Classes, SysUtils;
>>>
>>> function ChessGetLocalIP(): string;
>>>
>>> implementation
>>>
>>> const
>>>    CFormatIPMask = '%d.%d.%d.%d';
>>>
>>> function ChessGetLocalIP(): string;
>>> var
>>>    I, VAttempt: Integer;
>>>    VStrTemp, VSitesToTry: TStringList;
>>> {$IFDEF UNIX}
>>>    VProcess: TProcess;
>>> {$ENDIF}
>>> {$IFDEF MSWINDOWS}
>>> var
>>>    VWSAData: TWSAData;
>>>    VHostEnt: PHostEnt;
>>>    VName: string;
>>> {$ENDIF}
>>> begin
>>>    Result := '';
>>> {$IFDEF UNIX}
>>>        VStrTemp := TStringList.Create;
>>>        VProcess := TProcess.Create(nil);
>>>        try
>>>          VProcess.CommandLine :=
>>>            'sh -c "ifconfig eth0 | awk ''/inet end/ {print $3}''"';
>>
>> Yuck.  This doesn't work on my system (debian).  If you really want the
>> least effort, you may have more luck with simply parsing `hostname -I`
>> somehow.  The right way to do this is with an ioctl, I believe
>> (SIOCGIFCONF).  Look here:
>>
>> http://www.kernel.org/doc/man-pages/online/pages/man7/netdevice.7.html
>>
>> I'm sure there's some code floating around, but it probably means that
>> you have to translate some headers :(.
>>
>> Henry
>>
> Re: [fpc-pascal] lNet getting the local IP
>>
>
> I found an example for linux on stack overflow that was in c
> http://stackoverflow.com/questions/212528/linux-c-get-the-ip-address-of-local-computer
>
> - here is a rough translation:
>
> program GetPrimaryIpAddress;
> {$mode objfpc}
>
> uses
>  baseunix,
>  unixtype,
>  sockets,
>  SysUtils;
>
> procedure Get(var buf: array of char; const len: longint);
> const
>  CN_GDNS_ADDR = '8.8.8.8';
>  CN_GDNS_PORT = 53;
> var
>  s: string;
>  sock: longint;
>  err: longint;
>  HostAddr: TSockAddr;
>  l: Integer;
>  UnixAddr: TInetSockAddr;
>
> begin
>  err := 0;
>  Assert(len >= 16);
>
>  sock := fpsocket(AF_INET, SOCK_DGRAM, 0);
>  assert(sock <> -1);
>
>  UnixAddr.family := AF_INET;
>  UnixAddr.port := htons(CN_GDNS_PORT);
>  UnixAddr.addr := StrToHostAddr(CN_GDNS_ADDR).s_addr;
>
>  if (fpConnect(sock, at UnixAddr,SizeOf(UnixAddr)) = 0) then
>  begin
>    try
>      l := SizeOf(HostAddr);
>      if (fpgetsockname(sock, @HostAddr, @l) = 0) then
>      begin
>        s := NetAddrToStr(HostAddr.sin_addr);
>        StrPCopy(PChar(Buf), s);
>      end
>      else
>      begin
>        err:=socketError;
>      end;
>    finally
>      if (fpclose(sock) <> 0) then
>      begin
>        err := socketError;
>      end;
>    end;
>  end
>  else
>  begin
>    err:=socketError;
>  end;
>
>  if (err <> 0) then
>  begin
>    // report error
>  end;
> end;
>
> var
>  ipbuf: array[0..255] of char;
>
> begin
>  system.FillChar(ipbuf, sizeOf(ipBuf), #0);
>  Get(ipbuf, system.SizeOf(ipbuf));
>  WriteLn(StrPas(ipbuf));
> end.
>
> BrianW
>
I have tried this code with multiple scenarios.

if interfaces are down, no ip address is returned. I would say that is
expected as there is no network.
ifconfig will return same. only lo has an address 127.0.0.1.

Otherwise I get the primary ip address as long as routing is used.

if connecting to 0.0.0.0, 127.0.0.1 is returned

Use 127.0.0.1 and the primary is returned.

Run some tests and let me know what you find.



More information about the fpc-pascal mailing list