getting IP address of remote host from socket (stdin)

O

Ollie Cook

Ordinarily I would use the getpeername and getsockname functions to get
the IP address associated with each end of a socket. However, this
appears not to work for a script which is started from xinetd[1].

xinetd connects the socket over which the connection arrives to stdin
and stdout of the spawned process so when you read from standard input
you are in fact reading from the network.

In a C application started in this way, you can retrieve the IP
addresses associated with the 'socket' as follows (pseudocode only):

getpeername(fileno(stdin), (struct sockaddr *) &sa, &sz);
inet_ntoa(sa.sin_addr);

even though 'stdin' isn't a real socket.

However, doing a similar thing in Perl:

$sockaddr = getpeername(fileno(STDIN)); # 0
($port, $addr) = sockaddr_in($sockaddr);

gives the following error:

getpeername() on unopened socket 0 at proxy.pl line 258.

Use of uninitialized value in subroutine entry at
/usr/local/lib/perl5/5.6.1/mach/Socket.pm line 312.
Bad arg length for Socket::unpack_sockaddr_in, length is 0, should be 16
at /usr/local/lib/perl5/5.6.1/mach/Socket.pm line 312.

Does anyone have any advice on how I might be able to get the IPs
associated with a socket, when that socket is in fact STDIN/STDOUT as
presented by xinetd? I am using Perl 5.6.1.

Any help would be greatly appreciated.

Ollie

1: www.xinetd.org
 
A

Anno Siegel

Ollie Cook said:
Ordinarily I would use the getpeername and getsockname functions to get
the IP address associated with each end of a socket. However, this
appears not to work for a script which is started from xinetd[1].

xinetd connects the socket over which the connection arrives to stdin
and stdout of the spawned process so when you read from standard input
you are in fact reading from the network.
[...]

$sockaddr = getpeername(fileno(STDIN)); # 0
($port, $addr) = sockaddr_in($sockaddr);

gives the following error:

getpeername() on unopened socket 0 at proxy.pl line 258.

Use of uninitialized value in subroutine entry at
/usr/local/lib/perl5/5.6.1/mach/Socket.pm line 312.
Bad arg length for Socket::unpack_sockaddr_in, length is 0, should be 16
at /usr/local/lib/perl5/5.6.1/mach/Socket.pm line 312.

Try this:

use IO::Socket::INET;

my $sock = IO::Socket::INET->new;
$sock->fdopen( fileno STDIN, 'r') or die "dup: $!";
my $peerhost = $sock->peerhost or die "peerhost: $!";
print "peerhost is $peerhost\n";

This works for me in a similar situation, though I can't be sure how
exactly inetd establishes the pipeline.

Anno
 
O

Ollie Cook

Try this:

use IO::Socket::INET;

my $sock = IO::Socket::INET->new;
$sock->fdopen( fileno STDIN, 'r') or die "dup: $!";
my $peerhost = $sock->peerhost or die "peerhost: $!";
print "peerhost is $peerhost\n";

Hi Anno,

That does just the trick. Thank you for your assistance.

Yours,

Ollie
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,066
Latest member
VytoKetoReviews

Latest Threads

Top