Hi all,
I'm wondering if there's a way to list all IP addresses on a
multihomed system using Ruby's Socket API. I actually want this for
the sys-host library (at http://www.rubyforge.org/projects/sysutils).
It's C, but I figure I can reverse engineer the Ruby code back to C.
Here's the equivalent of what I'm currently doing (in C):
#include <unistd.h>
#include <netdb.h>
#include <stdio.h>
#include <arpa/inet.h>
#define BUF 256
int main(){
struct hostent* h;
char hostname[BUF];
char ip[BUF];
if(gethostname(hostname, BUF) != 0){
printf("gethostbyname failed\n");
return -1;
}
printf("Hostname: %s\n", hostname);
h = gethostbyname(hostname);
if(!h){
printf("gethostbyname failed\n");
return -1;
}
while(*h->h_addr_list){
printf("Addr: %s\n", inet_ntop(h->h_addrtype, *h->h_addr_list,
ip, BUF));
*h->h_addr_list++;
}
return 0;
}
But, at least one user has reported that he has eth0 configured with a
LAN IP and eth1 that has 5 attached IP addresses. The above code
doesn't pick them up.
Is there a pure Ruby solution? Is it just a matter of
Socket.getaddrinfo(Socket.gethostname, 80)? Or, does anyone happen to
know the C solution?
Thanks,
Dan
Since you're obviously using Linux, how about just parsing the output of
ethtool?
···
On 7/18/07, Daniel Berger <djberg96@gmail.com> wrote:
Hi all,
I'm wondering if there's a way to list all IP addresses on a
multihomed system using Ruby's Socket API. I actually want this for
the sys-host library (at http://www.rubyforge.org/projects/sysutils\).
It's C, but I figure I can reverse engineer the Ruby code back to C.
Here's the equivalent of what I'm currently doing (in C):
#include <unistd.h>
#include <netdb.h>
#include <stdio.h>
#include <arpa/inet.h>
#define BUF 256
int main(){
struct hostent* h;
char hostname[BUF];
char ip[BUF];
if(gethostname(hostname, BUF) != 0){
printf("gethostbyname failed\n");
return -1;
}
printf("Hostname: %s\n", hostname);
h = gethostbyname(hostname);
if(!h){
printf("gethostbyname failed\n");
return -1;
}
while(*h->h_addr_list){
printf("Addr: %s\n", inet_ntop(h->h_addrtype, *h->h_addr_list,
ip, BUF));
*h->h_addr_list++;
}
return 0;
}
But, at least one user has reported that he has eth0 configured with a
LAN IP and eth1 that has 5 attached IP addresses. The above code
doesn't pick them up.
Is there a pure Ruby solution? Is it just a matter of
Socket.getaddrinfo(Socket.gethostname, 80)? Or, does anyone happen to
know the C solution?
Thanks,
Dan
In article <1184772029.010310.165980@j4g2000prf.googlegroups.com>,
Daniel Berger <djberg96@gmail.com> writes:
I'm wondering if there's a way to list all IP addresses on a
multihomed system using Ruby's Socket API. I actually want this for
the sys-host library (at http://www.rubyforge.org/projects/sysutils\).
It's C, but I figure I can reverse engineer the Ruby code back to C.
[ extraneous program based on gethostbyname elided]
But, at least one user has reported that he has eth0 configured with a
LAN IP and eth1 that has 5 attached IP addresses. The above code
doesn't pick them up.
As your user has reported, your C-based program does not do what
you desire. gethostbyname (and its friends) can only deal with
DNS-based information. Information about multi-hosting is not
stored in the DNS. In fact, it is actually system dependent and is
only stored in the local kernel's network tables.
Most UNIX and Linux systems provide a mechanism to access this
information via some variant of the ioctl(2) call with command
SIOCGIFCONF. BSDi and FreeBSD have a set of subroutines (originally
based on the ioctl) called getifaddrs. MS Windows WinSock2 uses
the command SIO_GET_INTERFACE_LIST with the WSAIoctl procedure.
You will need to look in the documentation for your system (and
probably do a net search for programming examples) to see how it
works.
Is there a pure Ruby solution? Is it just a matter of
Socket.getaddrinfo(Socket.gethostname, 80)? Or, does anyone happen to
know the C solution?
I'm fairly certain that this could be done in ruby via IO.ioctl
and pack/unpack on UNIX/Linux, but I'm also fairly certain that
this would be a real PITA. I don't have any familiarity with the
Win32-specific solutions.
Dan
Good luck, - dmw
Notes:
- DNS = Domain Name System
- The ioctl commands evolve over time and over various systems.
The ones I note there may well be deprecated, obsolete, and/or
non-existent on your system.
···
--
. Douglas Wells . Connection Technologies .
. Internet: -sp9804- -at - contek.com- .
Eh? No, the C code above works just fine on Solaris (with -lsocket and
-lnsl added). Besides, I need the code to be as cross platform as
possible (for Unix flavors, that is - I use a different approach on MS
Windows). So, parsing system calls is out of the question.
Regards,
Dan
···
On 7/18/07, Francis Cianfrocca <garbagecat10@gmail.com> wrote:
On 7/18/07, Daniel Berger <djberg96@gmail.com> wrote:
>
> Hi all,
>
> I'm wondering if there's a way to list all IP addresses on a
> multihomed system using Ruby's Socket API. I actually want this for
> the sys-host library (at http://www.rubyforge.org/projects/sysutils\).
> It's C, but I figure I can reverse engineer the Ruby code back to C.
>
> Here's the equivalent of what I'm currently doing (in C):
>
> #include <unistd.h>
> #include <netdb.h>
> #include <stdio.h>
> #include <arpa/inet.h>
>
> #define BUF 256
>
> int main(){
> struct hostent* h;
> char hostname[BUF];
> char ip[BUF];
>
> if(gethostname(hostname, BUF) != 0){
> printf("gethostbyname failed\n");
> return -1;
> }
>
> printf("Hostname: %s\n", hostname);
>
> h = gethostbyname(hostname);
>
> if(!h){
> printf("gethostbyname failed\n");
> return -1;
> }
>
> while(*h->h_addr_list){
> printf("Addr: %s\n", inet_ntop(h->h_addrtype, *h->h_addr_list,
> ip, BUF));
> *h->h_addr_list++;
> }
>
> return 0;
> }
>
> But, at least one user has reported that he has eth0 configured with a
> LAN IP and eth1 that has 5 attached IP addresses. The above code
> doesn't pick them up.
>
> Is there a pure Ruby solution? Is it just a matter of
> Socket.getaddrinfo(Socket.gethostname, 80)? Or, does anyone happen to
> know the C solution?
>
> Thanks,
>
> Dan
>
Since you're obviously using Linux, how about just parsing the output of
ethtool?
<snip>
Indeed, there's an example in Stevens' "Unix Network Programming, Vol.
1" staring at me now.
Many thanks for the lead. I should be ok from
here (I hope).
I'll see if I can come up with a pure Ruby solution and post it here
eventually.
Regards,
Dan
···
On Jul 18, 2:10 pm, s...@signature.invalid (Douglas Wells) wrote:
In article <1184772029.010310.165...@j4g2000prf.googlegroups.com>,
Daniel Berger <djber...@gmail.com> writes:
> I'm wondering if there's a way to list all IP addresses on a
> multihomed system using Ruby's Socket API. I actually want this for
> the sys-host library (athttp://www.rubyforge.org/projects/sysutils).
> It's C, but I figure I can reverse engineer the Ruby code back to C.
> [ extraneous program based on gethostbyname elided]
> But, at least one user has reported that he has eth0 configured with a
> LAN IP and eth1 that has 5 attached IP addresses. The above code
> doesn't pick them up.
As your user has reported, your C-based program does not do what
you desire. gethostbyname (and its friends) can only deal with
DNS-based information. Information about multi-hosting is not
stored in the DNS. In fact, it is actually system dependent and is
only stored in the local kernel's network tables.
Most UNIX and Linux systems provide a mechanism to access this
information via some variant of the ioctl(2) call with command
SIOCGIFCONF. BSDi and FreeBSD have a set of subroutines (originally
based on the ioctl) called getifaddrs. MS Windows WinSock2 uses
the command SIO_GET_INTERFACE_LIST with the WSAIoctl procedure.
You will need to look in the documentation for your system (and
probably do a net search for programming examples) to see how it
works.
Sorry, it's the "eth0" and "eth1" that made me think you were doing this for
Linux.
···
On 7/18/07, Daniel Berger <djberg96@gmail.com> wrote:
> > But, at least one user has reported that he has eth0 configured with
a
> > LAN IP and eth1 that has 5 attached IP addresses. The above code
> > doesn't pick them up.
> >
In article <1184796959.469021.157500@g12g2000prg.googlegroups.com>, Daniel Berger <djberg96@gmail.com> writes:
> In article <1184772029.010310.165...@j4g2000prf.googlegroups.com>,
> Daniel Berger <djber...@gmail.com> writes:
>
> > I'm wondering if there's a way to list all IP addresses on a
> > multihomed system using Ruby's Socket API. I actually want this for
> > the sys-host library (athttp://www.rubyforge.org/projects/sysutils).
> > It's C, but I figure I can reverse engineer the Ruby code back to C.
>
> Most UNIX and Linux systems provide a mechanism to access this
> information via some variant of the ioctl(2) call with command
> SIOCGIFCONF. BSDi and FreeBSD have a set of subroutines (originally
> based on the ioctl) called getifaddrs. MS Windows WinSock2 uses
> the command SIO_GET_INTERFACE_LIST with the WSAIoctl procedure.
> You will need to look in the documentation for your system (and
> probably do a net search for programming examples) to see how it
> works.
Indeed, there's an example in Stevens' "Unix Network Programming, Vol.
1" staring at me now.
Many thanks for the lead. I should be ok from
here (I hope).
I'll see if I can come up with a pure Ruby solution and post it here
eventually.
Dan
Please let us know if you do. I managed to find time to take a
slightly deeper look, and the problem that I found is that SIOCGIFCONF
requires that you place an actual virtual address in the additional
argument to ioctl. I doubt that there is a "pure Ruby" way of
doing that. You'll can probably do ok getting the addresses
associated with an interface name, however.
- dmw
···
On Jul 18, 2:10 pm, s...@signature.invalid (Douglas Wells) wrote:
--
. Douglas Wells . Connection Technologies .
. Internet: -sp9804- -at - contek.com- .
Douglas Wells wrote:
In article <1184796959.469021.157500@g12g2000prg.googlegroups.com>, Daniel Berger <djberg96@gmail.com> writes:
In article <1184772029.010310.165...@j4g2000prf.googlegroups.com>,
Daniel Berger <djber...@gmail.com> writes:
I'm wondering if there's a way to list all IP addresses on a
multihomed system using Ruby's Socket API. I actually want this for
the sys-host library (athttp://www.rubyforge.org/projects/sysutils).
It's C, but I figure I can reverse engineer the Ruby code back to C.
Most UNIX and Linux systems provide a mechanism to access this
information via some variant of the ioctl(2) call with command
SIOCGIFCONF. BSDi and FreeBSD have a set of subroutines (originally
based on the ioctl) called getifaddrs. MS Windows WinSock2 uses
the command SIO_GET_INTERFACE_LIST with the WSAIoctl procedure.
You will need to look in the documentation for your system (and
probably do a net search for programming examples) to see how it
works.
Indeed, there's an example in Stevens' "Unix Network Programming, Vol.
1" staring at me now.
Many thanks for the lead. I should be ok from
here (I hope).
I'll see if I can come up with a pure Ruby solution and post it here
eventually.
Dan
Please let us know if you do. I managed to find time to take a
slightly deeper look, and the problem that I found is that SIOCGIFCONF
requires that you place an actual virtual address in the additional
argument to ioctl. I doubt that there is a "pure Ruby" way of
doing that. You'll can probably do ok getting the addresses
associated with an interface name, however.
It also appears that you can use sysctl() + NET_RT_IFLIST. It's easier, but less portable. I'll probably just suck it up and use the more portable version.
Regards,
Dan
···
On Jul 18, 2:10 pm, s...@signature.invalid (Douglas Wells) wrote: