#! /bin/perl use Socket; # --- Read the network interface to steal --- $netif = shift; # --- Start a child if so requested --- if (@ARGV) { socketpair(ONE, TOTHER, PF_UNIX, SOCK_STREAM, 0) or die "socketpair: $!"; $kid = fork(); defined $kid or die "fork: $!"; if ($kid) { close ONE; open STDIN, ">&TOTHER" or die "dup stdin: $!"; open STDOUT, ">&TOTHER" or die "dup stdout: $!"; close TOTHER; exec @ARGV; die "exec: $!"; } close TOTHER; open STDIN, ">&ONE" or die "dup stdin: $!"; open STDOUT, ">&ONE" or die "dup stdout: $!"; close ONE; } # --- Now start work on this --- open NETIF, "+> $netif" or die "open($netif): $!"; for (;;) { $rfd = ''; vec($rfd, fileno(STDIN), 1) = 1; vec($rfd, fileno(NETIF), 1) = 1; select($rfd, undef, undef, undef) or die "select: $!"; if (vec($rfd, fileno(NETIF), 1)) { sysread(NETIF, $pkt, 65536); $pkt = pack("n", length($pkt)) . $pkt; syswrite(STDOUT, $pkt, length($pkt)); } if (vec($rfd, fileno(STDIN), 1)) { sysread(STDIN, $clen, 2) or die "tunnel has vanished: $!"; $len = unpack("n", $clen); sysread(STDIN, $pkt, $len); syswrite(NETIF, $pkt, length($pkt)); } }