hello,
I am searching for a way to get the local IP. I already found examples with winsock, synapse and indy. Does anyone know how to do that with lNet?
thanks,

Mailing lists / fpc-pascal / 2010-10
22 messages · 11 people · –
Reply by email Subscribe to this list Your subscription
Read-only archive. Use j and k to move between messages.
hello,
I am searching for a way to get the local IP. I already found examples with winsock, synapse and indy. Does anyone know how to do that with lNet?
thanks,
Local IP without winsock, synapse, indy or lnet:
http://code.google.com/p/lazsolutions/source/browse/trunk/Core/LSHTTPSend.pas#127
2010/10/5 Felipe Monteiro de Carvalho
Hello,
Actually it uses both synapse (under unix) and winsock (under Windows).
What should one put in the parameter AHTTPSend: THTTPSend ? Where is this type declared?
thanks,
I am searching for a way to get the local IP. I already found examples with winsock,…
I just read the first line in /etc/hosts file. The first entry is the IPv4.
Huh?! O.o
You'll only find "127.0.0.1" for my computer there... I don't think that this is a very good solution.
Regards,
Sven
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}''"';
VProcess.Options := [poWaitOnExit, poUsePipes];
VProcess.Execute;
VStrTemp.LoadFromStream(VProcess.Output);
Result := Trim(VStrTemp.Text);
finally
VStrTemp.Free;
VProcess.Free;
end;
{$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;
end.Huh?! O.o You'll only find "127.0.0.1" for my computer there... I don't think that this…
Sven Barth wroteYou'll only find "127.0.0.1" for my computer there... I don't think that this is a very good solution.
Oh well. That makes sense b/c these are servers that I have obtaining the same IP over DHCP.
On clients when DHCP is being used with dynamic IPs the host file may not be of much use or may require more parsing for the host name.
But from a file based solution you just need to read in the /etc/hostname file. That is the name of the box.
With the host name, ust search the /etc/hosts file for the IP matching that name.
It's similar to the ifconfig command with parsing of eth0 which by the way if there are more than 1 nick, could be problematic.
Is there an Gnome or KDE API we could use to officially get NIC related info like iphlpapi.dll API under Windows?
Ok, thanks everyone, it seams that I managed to extract a function from Silvio's code…
In our previous episode, Felipe Monteiro de Carvalho said:
function ChessGetLocalIP(): string; VProcess.CommandLine := 'sh -c "ifconfig eth0 | awk ''/inet end/ {print $3}''"';
Fails if eth0 is not the primary NIC. Doesn't work on non-linux (that use other ethernet naming schemes)
A safe solution will probably boil down to walking the list of ethernet adapters and routes to find the default route on *nix.
Ok, thanks everyone, it seams that I managed to extract a function from Silvio's code…
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,@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
In our previous episode, Brian Winfrey said:
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
Compiles on FreeBSD and the result looks sane (but on a system that has a routable address)
On Wed, Oct 6, 2010 at 7:09 AM, Re: [fpc-pascal] lNet getting the local IP I found an…
Wow, worked perfectely in Ubuntu-10.04, Mandriva-2010 and openSUSE-11.2.
Thanks for the exelent solutions. :)
2010/10/7 Brian Winfrey
In our previous episode, Brian Winfrey said: Compiles on FreeBSD and the result looks…
En/na Marco van de Voort ha escrit:
I didn't try it, but I see that it tries to connect to google's dns server, so it'd fail miserably if the computer has no internet access.
Bye
Choose a different address that would not fail in a specific situation. For example, one could read their /etc/resolve file to get the dns server.
Brian Winfrey
~~~~~~~~~~
Important Note:
Code provide as an example. There could be errors or risks in using it. There is no warranty implied or implicit, it may not even work.
En/na Marco van de Voort ha escrit: I didn't try it, but I see that it tries to connect…
2010/10/7 Luca Olivetti
I tested, without web access does not work. :o
I am developing for an embedded system and found out that 'nmap --iflist' does a faily good job of this if the output is examined and parsed properly. If it is suitable and you can possibly extract the code (if you are prepared to go that far) it might help you. It is also cross platform
A hard coded address will of course fail if it cannot be reached. The code was an example, you should use it as such. I substituted my router's ip for google's and it works.;)
Choose a different address that would not fail in a specific situation.
As another example, one could read their /etc/resolve file to get the dns server that is assigned.
Brian Winfrey
On Wed, Oct 6, 2010 at 7:09 AM, Re: [fpc-pascal] lNet getting the local IP I found an…
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.
Hi Brian,
I tested again, and discovered that's not is necessary a connection to a web.
I changed to 0.0.0.0 and returned 127.0.0.1, perfect! :)
I will use this function. Thanks very much again. :)
2010/10/7 Brian Winfrey
I think you want to use 127.0.0.1 to return the actual address.
In my case I would
const
CN_GDNS_ADDR = '127.0.0.1';run the progarm and the output would be 192.168.1.5 as long as there is an active interface.
I don't know if you noticed, but it appears that code has some depracated properties that should be changed.
Here are the modifications I made in exploring this issue:
program GetPrimaryIpAddress;
{$mode objfpc}uses
baseunix,
unixtype,
sockets,
SysUtils;procedure Get(out AddrOut: string);
const
CN_GDNS_ADDR = '127.0.0.1';
CN_GDNS_PORT = 53;
var
sock: longint;
err: longint;
UnixAddr: TInetSockAddr;
HostAddr: TSockAddr;
len: Integer;
begin
err := 0;
sock := fpsocket(AF_INET, SOCK_DGRAM, 0);
assert(sock -1);
// changed because previous properties were deprecated
UnixAddr.sin_family := AF_INET;
UnixAddr.sin_port := htons(CN_GDNS_PORT);
UnixAddr.sin_addr := StrToHostAddr(CN_GDNS_ADDR);
if (fpConnect(sock, @UnixAddr, SizeOf(UnixAddr)) = 0) then
begin
try
len := SizeOf(HostAddr);
if (fpgetsockname(sock, @HostAddr, @len) = 0) then
begin
AddrOut := NetAddrToStr(HostAddr.sin_addr);
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
strAddr: string;
begin
Get(strAddr);
WriteLn('ip : ',strAddr);
end.Here are the modifications I made in exploring this issue:
It works on:
-----
% uname -a
FreeBSD host.ipt.ru 9.0-CURRENT FreeBSD 9.0-CURRENT #3 r213198M: Mon Sep 27 15:43:54 MSD 2010 i386 -----