[Ilugc] Find IP address of a machine
- From: girishvenkatachalam@xxxxxxxxx (Girish Venkatachalam)
- Date: Tue Oct 24 20:32:39 2006
On Tue, Oct 24, 2006 at 07:59:08AM +0200, Binand Sethumadhavan wrote:
On 24/10/06, Girish Venkatachalam <girishvenkatachalam@xxxxxxxxx> wrote:
Well, a given machine could have several different IP addresses, so
you need to be a bit more specific than that.
There are both multi homed and single interface having mutiple IP
addresses problem.
There are also NAT, multicasting, hot-standby protocols like
VRRP/CARP, load-balancing etc. that causes an IP address to be
associated with a given machine.
The point is that an IP address is not a property of the machine, so a
question like "how do I figure out the OP address of a machine?" is
meaningless. IP addresses are properties of TCP/IP connections, not of
machines/computers/hardware.
Given that, the way to figure out IP addresses at both ends of a
connection are the pair of system calls getsockname/getpeername
(perldoc -f for their usage details).
I created a lot of noise in misc@openbsd over this trivial issue.
http://marc.theaimsgroup.com/?l=openbsd-misc&m=116167876510367&w=2
And no one could give a proper solution. There are couple of possibilities ,
none of them elegant.
1)
http://libdnet.sourceforge.net/
2)
in_addr_t
defip(in_addr_t dst)
{
int s, slen = sizeof(struct sockaddr);
struct sockaddr_in sin;
s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (s < 0) {
perror("socket");
return -1;
}
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(60);
memcpy(&sin.sin_addr.s_addr, (char *)&dst, sizeof(in_addr_t));
if (connect(s, (struct sockaddr *)&sin, sizeof(struct sockaddr)) < 0) {
perror("connect");
return -1;
}
if (getsockname(s, (struct sockaddr *)&sin, &slen) < 0)
return -1;
close(s);
return (sin.sin_addr.s_addr);
}
The best and most interesting one of course is using getifaddrs(3) system call
but it is too complex to use and only available on *BSD systems. There is
something similar for linux. Too bad I don't recollect now.
The explanation for the above code is attached snipped from an e-mail from
Germany personally sent to me.
<<<<<<<cut>>>>>
The process of defip() is pretty well as you described only difference is
that the UDP socket gets connected. This doesn't change any functionality
of a UDP socket except that the socket will now listen to ICMP unreach
messages and return an error upon the next write/read if such was received.
(Since UDP sockets can't really be connected.. they're stateless).
<<<<<<<cut>>>>>
But as I said I don't like this. :-)
HTH,
Girish
Other related posts: