Article 4267 of comp.lang.perl:
Xref: feenix.metronet.com comp.lang.perl:4267
Newsgroups: comp.lang.perl
Path: feenix.metronet.com!news.utdallas.edu!wupost!usc!elroy.jpl.nasa.gov!ames!koriel!sh.wide!wnoc-tyo-news!sranha!sranhd!sran230!utashiro
From:
[email protected] (Kazumasa Utashiro)
Subject: Re: How to get the ip-address of socket 0
References: <
[email protected]>
Organization: Software Research Associates, Inc., Japan
Date: Fri, 16 Jul 1993 01:41:45 GMT
Message-ID: <
[email protected]>
Lines: 191
In article <
[email protected]>
Ulrich Pfeifer <
[email protected]> writes:
> I've a little (hopefully) problem setting up an tcp/ip server. The server ist
> started by inetd an i want to find the ip-address of the machine the client
> runs on for logging purposes. Reading the manual i found no way to investigate
> socket 0.
>
> $sockaddr = 'S n a4 x8';
> $mysockaddr = getpeername(0);
> ($family, $port, $myaddr, $mist) =
> unpack($sockaddr,$mysockaddr);
>
> Does't work. Preciselly getpeername(0) returns nothing.
Use getpeername(STDIN). I'm enclosing sample program which
you can use from inetd. Some more tcp related program can
be get from srawgw.sra.co.jp:pub/lang/perl/sra-scripts via
anonymous ftp.
---
K. Utashiro
[email protected]
#!/usr/local/bin/perl
;#
;# tcpconnect: make a connection to remote port by tcp
;#
;# Copyright (c) 1991,1992 Kazumasa Utashiro <
[email protected]>
;# Software Research Associates, Inc., Japan
;#
;; $rcsid = q$Id: tcpconnect,v 0.4 1992/12/17 07:58:30 utashiro Exp $;
;#
;# With this command, you can forward some specific protocol
;# on gateway machine which doesn't forward IP packet.
;#
;# Syntax:
;# tcpconnect server[:service]
;# tcpconnect server[:service] client
;# tcpconnect server[:service] client server[:service] client ...
;# tcpconnect -f config-file
;#
;# + If client is not specified or is '*', any client is allowed
;# to connect.
;#
;# + Server is choosed on first-hit policy. So, if there is '*'
;# client at the first, remained servers will not be checked.
;#
;# + Same port number will be used when no server services is
;# specified.
;#
;# + Client and server name can be symbolic hostname or IP
;# address in dotted decimal notation.
;#
;# + Service name can be specified by symbolic name or port-number
;#
;# + Configuration file contains client and server pair on each line.
;#
;# EXAMPLES:
;#
;# All SMTP connection is to be forwarded to mail-server:
;#
;# smtp stream tcp nowait root /etc/tcpconnect tcpconnect mail-server
;#
;# NNTP connectioned is exchanged between A and B:
;#
;# nntp stream tcp nowait root /etc/tcpconnect tcpconnect A B B A
;#
;# Simply connect a terminal to nntp server:
;#
;# % tcpconnect nntp-server:nntp
;#
;# require 'sys/socket.ph';
unless (do 'sys/socket.ph') {
#print "File sys/socket.ph is not found. Using default...\n";
eval 'sub SOCK_STREAM {1;} sub AF_INET {2;} sub PF_INET {2;}';
}
while ($_ = $ARGV[0], /^-/) {
shift;
if (/-f$/) {$configfile = shift || &usage; next;}
if (/-d(\d*)$/) {$debug = $1||1; next;}
if (/-h/) {&usage; next;}
&usage;
}
sub usage {
$0 =~ s|.*/||;
$* = 1;
($usage = <<" EOF") =~ s/^ //g;
Usage: $0 server[:service] [client] [server[:service] client ...]
$0 -f config-file
($rcsid)
EOF
for (@_) { print "ERROR: $_", /\n$/ ? "" : "\n"; }
print $usage;
exit(1);
}
unless ($configfile) {
@forwardlist = @ARGV;
} else {
open(CONF, $configfile) || die("$configfile: $!\n");
while(<CONF>) {
chop;
s/#.*$//;
s/^\s*//;
next if /^$/;
push(@forwardlist, (split($_))[0,1]);
}
close(CONF);
}
$sockaddr='S n a4 x8';
($name, $aliases, $TCP) = getprotobyname('tcp');
chop($localname = `hostname`);
unless ($hersockaddr = getpeername(STDIN)) {
$server = shift || &usage;
} else {
open(STDERR, ">/dev/console");
select(STDERR); $| = 1; select(STDOUT);
($family, $herport, $heraddr) = unpack($sockaddr, $hersockaddr);
$mysockaddr = getsockname(STDIN);
($family, $myport, $myaddr) = unpack($sockaddr, $mysockaddr);
if ($debug) {
printf STDERR ("$0: Connection from %s(%d)\n",
&dotted($heraddr), $herport);
}
CHECKADDR: {
while (($server, $client) = splice(@forwardlist, 0, 2)) {
if (!defined($client) || $client eq '*') {
$clientaddr = "\0\0\0\0";
} else {
($clientaddr = &getaddr($client)) || next;
}
if ($clientaddr eq "\0\0\0\0" || $clientaddr eq $heraddr) {
$server = "$server:$myport" unless ($server =~ /:/);
last CHECKADDR;
}
}
printf STDERR ("Connection from %s is not allowed!\n",
&dotted($heraddr));
exit(1);
}
}
($servername, $serverport) = split(/:/, $server);
$serverport || &usage("No server port");
($serveraddr = &getaddr($servername)) || die "Unknown server $servername.\n";
$serverport = (getservbyname($serverport, 'tcp'))[2]
unless $serverport =~ /^\d+$/;
$that = pack($sockaddr, &AF_INET, $serverport, $serveraddr);
socket(S, &PF_INET, &SOCK_STREAM, $TCP) || die "socket: $!";
connect(S, $that) || die "connect: $!";
select(S); $| = 1; select(stdout);
if ($child = fork) {
&forward(S, STDOUT);
} else {
&forward(STDIN, S);
}
print STDERR "$0($$): exiting\n" if $debug;
exit(0);
sub forward {
local($from, $to) = @_;
select($from); $| = 1;
select($to); $| = 1;
if (-t $from) {
eval "print $to \$_ while(<$from>);";
} else {
eval "print $to \$_ while(read($from, \$_, 4096));";
}
shutdown($from, 1); shutdown($to, 0);
}
sub getaddr {
local($_) = @_;
/^[0-9\.]+$/ ? pack("C4", split(/\./)) : (gethostbyname($_))[4];
}
sub dotted { join('.', unpack('C4', shift)); }