Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2006-10

Get Local IP using glib (eth0,eth1)

14 messages · 5 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Jeff Pohlmeyer
I'm trying to write a function to read the local IP eth0/eth1 using glibc library...
program ip_addr;
{$MODE OBJFPC}
uses libc;
const
  IP_NAMESIZE = 16;
type
  ipstr = array[0..IP_NAMESIZE-1] of char;
function GetIPAddressOfInterface( if_name:ansistring):ansistring;
var
  ifr : ifreq;
  tmp:ipstr;
  sock : longint;
  p:pChar;
begin
  Result:='0.0.0.0';
  strncpy( ifr.ifr_ifrn.ifrn_name, pChar(if_name), IF_NAMESIZE-1 );
  ifr.ifr_ifru.ifru_addr.sa_family := AF_INET;
  FillChar(tmp[0], IP_NAMESIZE, #0);
  sock := socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
  if ( sock >= 0 ) then begin
    if ( ioctl( sock, SIOCGIFADDR, @ifr ) >= 0 ) then begin
      p:=inet_ntoa( ifr.ifr_ifru.ifru_addr.sin_addr );
      if ( p  nil ) then strncpy(tmp, p, IP_NAMESIZE-1);
      if ( tmp[0]  #0 ) then Result :=  tmp;
    end;
    libc.__close(sock);
  end;
end;

begin
if (ParamCount=1)
then WriteLn(GetIPAddressOfInterface(ParamStr(1))) else WriteLn('Usage:', ParamStr(0), '<interface-name>') end.

- Jeff

Jeff Pohlmeyer
Show quoted text 5 lines
> function to read the local IP eth0/eth1 using glibc library. program ip_addr; ... end.

Please ignore my last post -
This one is a little cleaner...

program ip_addr;
{$MODE OBJFPC}
uses libc;
function GetIPAddressOfInterface( if_name:ansistring):ansistring;
var
  ifr : ifreq;
  sock : longint;
  p:pChar;
begin
  Result:='0.0.0.0';
  strncpy( ifr.ifr_ifrn.ifrn_name, pChar(if_name), IF_NAMESIZE-1 );
  ifr.ifr_ifru.ifru_addr.sa_family := AF_INET;
  sock := socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
  if ( sock >= 0 ) then begin
    if ( ioctl( sock, SIOCGIFADDR, @ifr ) >= 0 ) then begin
      p:=inet_ntoa( ifr.ifr_ifru.ifru_addr.sin_addr );
      if ( p  nil ) then Result :=  p;
    end;
    libc.__close(sock);
  end;
end;
var
  i:LongInt;
begin
  if (ParamCount>0)
  then for i:=1 to ParamCount
       do WriteLn(GetIPAddressOfInterface(ParamStr(i)))
  else WriteLn('Usage:', ParamStr(0), '<interface-name>')
end.
Micha Nelissen
to Jeff Pohlmeyer
Jeff Pohlmeyer wrote 8 lines
> > function to read the local IP eth0/eth1 using glibc library. This one is a little cleaner... program ip_addr; {$MODE OBJFPC} uses libc;

It doesn't seem like you're using libc specific functions ? You can also write a fpc 'native' one using fpsocket and fpioctl in baseunix/unix, I think.

Micha

TOUZEAU DAVID
to Jeff Pohlmeyer: program ip_addr; {$MODE OBJFPC} uses libc; const IP_NAMESIZE = 16; type ipstr =…

Many Thanks Jeff and Micha.

This function works perfectly without need to regex ifconfig... And i use glibc
I develop only on linux system.

Great respects...
Just another question... (this because i came from Windows OS) how can i list wich interface loaded without need to parse /etc/networks/...? (wlan0,wlan1,eth0,eth1...)

Best regards...

Jeff Pohlmeyer wrote 53 lines
> I'm trying to write a function to read the local IP eth0/eth1 > using glibc library... program ip_addr; {$MODE OBJFPC} uses libc; const IP_NAMESIZE = 16; type ipstr = array[0..IP_NAMESIZE-1] of char; function GetIPAddressOfInterface( if_name:ansistring):ansistring; var ifr : ifreq; tmp:ipstr; sock : longint; p:pChar; begin Result:='0.0.0.0'; strncpy( ifr.ifr_ifrn.ifrn_name, pChar(if_name), IF_NAMESIZE-1 ); ifr.ifr_ifru.ifru_addr.sa_family := AF_INET; FillChar(tmp[0], IP_NAMESIZE, #0); sock := socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); if ( sock >= 0 ) then begin if ( ioctl( sock, SIOCGIFADDR, @ifr ) >= 0 ) then begin p:=inet_ntoa( ifr.ifr_ifru.ifru_addr.sin_addr ); if ( p nil ) then strncpy(tmp, p, IP_NAMESIZE-1); if ( tmp[0] #0 ) then Result := tmp; end; libc.__close(sock); end; end; begin if (ParamCount=1) then WriteLn(GetIPAddressOfInterface(ParamStr(1))) else WriteLn('Usage:', ParamStr(0), '<interface-name>') end. - Jeff _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal
David Touzeau -------------------------- Linux Ubuntu Dapper 6.0.6 FreePascal-Lazarus,perl,delphi,php icq:160018849
Marco van de Voort
to TOUZEAU DAVID
This function works perfectly without need to regex ifconfig... And i use glibc I develop only on linux system.

Note that it is linux/x86 only. No 64-bit, or other platforms.

TOUZEAU DAVID
to Marco van de Voort

OK i understand that i using i386 no 64 bits

Marco van de Voort wrote 10 lines
> This function works perfectly without need to regex ifconfig... And i > use glibc > I develop only on linux system. > Note that it is linux/x86 only. No 64-bit, or other platforms.
David Touzeau -------------------------- Linux Ubuntu Dapper 6.0.6 FreePascal-Lazarus,perl,delphi,php icq:160018849
Jeff Pohlmeyer
how can i list wich interface loaded without need to parse /etc/networks/...?

I would parse /proc/net/dev instead....

program ifnames;
var
  s:shortstring;
  f:text;
  p:LongInt;
begin
  assign(f,'/proc/net/dev');
  reset(f);
  while not eof(f) do begin
    readln(f,s);
    p:=pos(':',s);
    if ( p > 0 ) then begin
      delete(s, p, 255);
      while ( s  '' ) and (s[1]=#32) do delete(s,1,1);
      writeln(s);
    end;
  end;
  close(f);
end.
Marco van de Voort
to Jeff Pohlmeyer
I would parse /proc/net/dev instead....

Better, but still Linux only. For a good solution, a resolver unit that accesses libc should be written that is portable (unlike the libc unit)

TOUZEAU DAVID
to Marco van de Voort

Many Thanks for this way jeff...
/proc/net/dev is more compatible
Impressed it
for your information.
My program will run only on linux system...

Marco van de Voort wrote 11 lines
> I would parse /proc/net/dev instead.... > Better, but still Linux only. For a good solution, a resolver unit that accesses libc should be written that is portable (unlike the libc unit) _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal
David Touzeau -------------------------- Linux Ubuntu Dapper 6.0.6 FreePascal-Lazarus,perl,delphi,php icq:160018849
Jeff Pohlmeyer
Better, but still Linux only. For a good solution, a resolver unit that accesses libc should be written that is portable (unlike the libc unit)

If I understood correctly, the OP had two questions:

1. Retrieve a list of interface names on a *linux* system.
2. Return the IP address for a given *linux* interface name.

And the only "good" solution is a portable resolver unit?

How will you resolve "eth0" on Win32 or BSD ?

-Jeff

Graeme Geldenhuys
to Jeff Pohlmeyer

I have these two functions in my .bashrc file. You only need to run "ii" for the cool output. Now back to the question - If it is for linux only, why not just use the /sbin/ifconfig output. After all, it is accurate and seem much easier than all those libc/library methods. I pull the IPs and Interfaces available from the /sbin/ifconfig output and works just fine. If it was needed on windows, I am sure you could to the same thing with the 'ipconfig' output.

My 2c worth! :-)

Regards,
- Graeme -

------------ .bashrc ---------------------
function my_ip() # get IP adresses
{
MY_IP=$(/sbin/ifconfig eth0 | awk '/inet/ { print $2 } ' | sed -e s/addr://) MY_ISP=$(/sbin/ifconfig ppp0 | awk '/P-t-P/ { print $3 } ' | sed -e s/P-t-P://)
}

function ii() # get current host related info
{
echo -e "\nYou are logged on ${RED}$HOST"
echo -e "\nAdditionnal information:$NC " ; uname -a echo -e "\n${RED}Users logged on:$NC " ; w -h
echo -e "\n${RED}Current date :$NC " ; date
echo -e "\n${RED}Machine stats :$NC " ; uptime
echo -e "\n${RED}Memory stats :$NC " ; free

    my_ip 2>&- ;
    echo -e "\n${RED}Local IP Address :$NC" ; echo ${MY_IP:-"Not connected"}
    echo -e "\n${RED}ISP Address :$NC" ; echo ${MY_ISP:-"Not connected"}
    echo

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

Jeff Pohlmeyer wrote 16 lines
> Better, but still Linux only. For a good solution, > a resolver unit that accesses libc should be > written that is portable (unlike the libc unit) If I understood correctly, the OP had two questions: 1. Retrieve a list of interface names on a *linux* system. 2. Return the IP address for a given *linux* interface name. And the only "good" solution is a portable resolver unit? How will you resolve "eth0" on Win32 or BSD ? -Jeff
There's no place like 127.0.0.1
Marco van de Voort
to Jeff Pohlmeyer: If I understood correctly, the OP had two questions: 1. Retrieve a list of interface…
Show quoted text 8 lines
> Better, but still Linux only. For a good solution, > a resolver unit that accesses libc should be > written that is portable (unlike the libc unit) If I understood correctly, the OP had two questions: 1. Retrieve a list of interface names on a *linux* system. 2. Return the IP address for a given *linux* interface name.

I don't understand that last one. _WHY_ would you want to enumerate and then still use hardcoded "eth0" What if eth0 is my internal and eth1 my external interface? The only meaning of the name is order of detection.

And the only "good" solution is a portable resolver unit? How will you resolve "eth0" on Win32 or BSD ?

Usually you enumerate the interfaces list, till you find the interface with the "default" (ANY) route, so you have the default gateway, regardless of name. That is usually the interface you interested in.

IOW names say nothing, routes and masks do.

TOUZEAU DAVID
to Graeme Geldenhuys: I have these two functions in my .bashrc file. You only need to run "ii" for the cool…

Many thanks to the community

To reply to Graeme :
why not just use the /sbin/ifconfig output ?
Simply to be more dev compliance... using an external program is slower and sometime ifconfig doesn't exist or is deleted on target computers.

To reply to Marco :
And the only "good" solution is a portable resolver unit? How will you resolve "eth0" on Win32 or BSD ?

For WIN32, i d'ont care because the program is only for Linux systems. Your are true, in BSD the network interface is not the same and i must detect wich interface is used...

Best regards

Graeme Geldenhuys wrote 60 lines
I have these two functions in my .bashrc file. You only need to run "ii" for the cool output. Now back to the question - If it is for linux only, why not just use the /sbin/ifconfig output. After all, it is accurate and seem much easier than all those libc/library methods. I pull the IPs and Interfaces available from the /sbin/ifconfig output and works just fine. If it was needed on windows, I am sure you could to the same thing with the 'ipconfig' output. My 2c worth! :-) Regards, - Graeme - ------------ .bashrc --------------------- function my_ip() # get IP adresses { MY_IP=$(/sbin/ifconfig eth0 | awk '/inet/ { print $2 } ' | sed -e s/addr://) MY_ISP=$(/sbin/ifconfig ppp0 | awk '/P-t-P/ { print $3 } ' | sed -e s/P-t-P://) } function ii() # get current host related info { echo -e "\nYou are logged on ${RED}$HOST" echo -e "\nAdditionnal information:$NC " ; uname -a echo -e "\n${RED}Users logged on:$NC " ; w -h echo -e "\n${RED}Current date :$NC " ; date echo -e "\n${RED}Machine stats :$NC " ; uptime echo -e "\n${RED}Memory stats :$NC " ; free my_ip 2>&- ; echo -e "\n${RED}Local IP Address :$NC" ; echo ${MY_IP:-"Not connected"} echo -e "\n${RED}ISP Address :$NC" ; echo ${MY_ISP:-"Not connected"} echo } --------------------------------- On 06/10/06, Jeff Pohlmeyer wrote: > > Better, but still Linux only. For a good solution, > > a resolver unit that accesses libc should be > > written that is portable (unlike the libc unit) > > > If I understood correctly, the OP had two questions: > > 1. Retrieve a list of interface names on a *linux* system. > 2. Return the IP address for a given *linux* interface name. > > > And the only "good" solution is a portable resolver unit? > > How will you resolve "eth0" on Win32 or BSD ? > > -Jeff
David Touzeau -------------------------- Linux Ubuntu Dapper 6.0.6 FreePascal-Lazarus,perl,delphi,php icq:160018849