Q-Bert has asked for the wisdom of the Perl Monks concerning the following question:

IO::Socket->sockopt is used to retrieve a socket option.

In the new 2.4 Linux, there is a new socket option in the netfilter code, called SO_ORIGINAL_DST. We use this to find the original socket destination once the socket has gone through the NAT code. netfilter_ipv4.h defines that value as SO_ORIGINAL_DST = 80.

If I try $socket->sockopt(80), I get $! = "Protocol not available". So I tried to modify Socket-1.5, and added a simple entry for SO_ORIGINAL_DST, but I then got:

Your vendor has not defined Socket macro SO_ORIGINAL_DST, used at ./proxy.pl line 14

How do I add this new socket option so that both IO::Socket and perl recognize it as valid and return the right value ?

Replies are listed 'Best First'.
Re: How do I *add* a socket option ?
by Fastolfe (Vicar) on Oct 12, 2000 at 17:49 UTC
    Either you need to run h2ph again on your various socket/inet include files, or perhaps Perl needs to be recompiled, taking the new 2.4 networking headers into account.
(tye)Re: How do I *add* a socket option ?
by tye (Sage) on Oct 12, 2000 at 18:33 UTC

    Fastolfe is right. But I can be more specific. The error "Your vendor has not defined..." means that the module knows about this option but that it wasn't defined when the module was compiled.

    The IO::Socket and Socket modules are included in the standard distribution but you are probably using dynamic loading so that all you need to do is recompile and install the Socket module (which IO::Socket uses to get its constants from).

    If you aren't using dynamic loading, then you'll need to recompile Perl. If you do that, you probably want to enable dynamic loading in the process.

    If you have the source code for Perl lying about, just go to that directory and do:

    % cd ext/Socket % perl Makefile.PL % make test % make install

    If you don't, then go fetch it from CPAN. It looks like the separate Socket module on CPAN is 1.5 while Perl comes with 1.72 so I wouldn't just fetch the Socket module.

            - tye (but my friends call me "Tye")
      Yep, I did exactly that, I got the 1.5 Socket version from CPAN, and installed *that*.

      Yes, I know that I downgraded Socket because of that, but I was ready to take that chance.

      I added

      if (strEQ(name, "SO_ORIGINAL_DST")) #ifdef SO_ORIGINAL_DST return SO_ORIGINAL_DST; #else goto not_there; #endif
      in Socket.xs ,and also put the SO_ORIGINAL_DST tag in Socket.pm

      I compiled it and installed it. It installed it in /usr/lib/perl5/site_perl/5.005/i386-linux/auto/Socket/Socket.so

      Now, when I run:

      my $destination_address = $server_socket->sockopt(SO_ORIGINAL_DST); print STDERR "Error: $!\n"; print STDERR "Requested destination address: $destination_address\n";
      I get "Your vendor has not defined Socket macro SO_ORIGINAL_DST, used at ./proxy.pl line 14".

      So the error appears as soon as $server_socket->sockopt() gets called, because it doesn't even reach the "Error: " output.

        Then SO_ORIGINAL_DST must not be defined when you compile that code. Check which include file that is defined in and what files you are including in Socket.xs. There could be #ifdef's that prevent it from being defined.

        FYI, you should get that error when your use imports that symbol, not when you try to use the symbol. And you must be importing that symbol since you don't have () on the end of it.

                - tye (but my friends call me "Tye")