jaco has asked for the wisdom of the Perl Monks concerning the following question:

Fellow Monks,
I've been investigating ways to bypass routing tables using perl sockets. Much in the way Ping can do this. I've found this is possible using setsocketopt syntax with Socket.pm, But when using IO::Socket it only seems to work for one type of device. For example.

Using Socket.pm this syntax works with ethernet and PPP devices
use Socket qw( SOCK_DGRAM SOCK_STREAM SOCK_RAW PF_INET SOL_SOCKET inet +_aton inet_ntoa sockaddr_in ); $host="www.cnet.com"; $port="80"; socket(SOCK, PF_INET, SOCK_STREAM, getprotobyname('tcp')); setsockopt(SOCK, SOL_SOCKET, 25 , pack("Z*","eth0")) || die "error\n"; $iaddr = inet_aton($host); $paddr = sockaddr_in($port, $iaddr); connect(SOCK, $paddr);
The code which, from what i can tell for IO::Socket looks like this
use IO::Socket; $server = $ARGV[0]; $port = 80; $socket = IO::Socket::INET->new( Proto => 'tcp', PeerAddr => $server, PeerPort => $port, Timeout => 10, ); unless($socket) { die("Could not connect to $server:$port"); } $socket->autoflush(1); $socket->sockopt(25, "eth0") || die "error\n";
And this works with ethernet device but NOT PPP.

when i strace it, it hangs after printing to the socket.
I've also tried packing the device like above but it seems to make little difference, the sockopt returns true and hangs.

any ideas?

Replies are listed 'Best First'.
Re: Socket, IO::Socket and SO_BINDTODEVICE
by jaco (Pilgrim) on Sep 13, 2003 at 17:07 UTC
    Not that anyone appears to have ever cared about this. But it's only a small problem with IO::Socket. I read in Lincoln Stiens book that IO::Socket will handle the hard part of setsockopt for you, that is, the packed part. So Technically you could proably do
    $socket->sockopt("25", pack("Z*", "eth0"));
    Still though, the sockopt should fail when done the easier way. I've patched IO::Socket;
    sub SO_BINDTODEVICE{25}; + if(exists $arg->{Interface}){ + my $unit = $arg->{Interface}; + my $int = pack("Z*",$unit); + setsockopt($sock,SOL_SOCKET,SO_BINDTODEVICE,$int)|| die "er +ror $!\n"; + }
    Or whatever, it just gives you the option of giving interface as an arg much like Net::Ping does. I'm sure it's not useful to most of the world. Remember your milage may vary as SO_BINDTODEVICE is platform specific int as far as i know.

    I've also begun to document setsockopt pack formats. If anyone knows if this has already been done i'd greatly appreciate it.