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

I am working on a proprietary protocol. The structure requires additional IP addresses to be passed. I have had success useing the following snippet.
pack("a4", inet_aton("192.168.1.1"));
This works for the majority of IP's except when there is a 10 in the first, second or thrid position in the IP ie 10.10.10.1. This packs correctly, but fails after sending it to the server. Where it does the following.
unpack("a4", inet_ntoa($buffer);
I am including a sample client:
use IO::Socket; $IP_Address = '10.10.10.1'; $buffer = inet_aton($IP_Address); $buffer = pack("a4", $buffer); my $sock = new IO::Socket::INET ( PeerAddr => 'localhost', PeerPort => '7070', Proto => 'tcp' ); die "Could not create socket: $!\n" unless $sock; print $sock $buffer; close($sock);
Here is a sample server that exhibits the same error.
use IO::Socket; my $new_sock; my $sock = new IO::Socket::INET ( LocalHost => 'localhost', LocalPort => '7070', Proto => 'tcp', Listen => 1, Reuse => 1, ); die "Could not create socket: $!\n" unless $sock; while ($new_sock = $sock->accept()){ while(defined($buffer = <$new_sock>)) { $buffer = unpack("a4", $buffer); $buffer = inet_ntoa($buffer); print $buffer, "\n"; } } close($sock);
Thank You for your wisdom.

Replies are listed 'Best First'.
Re: What is the best way to pack an ip address?
by Juerd (Abbot) on Jan 14, 2002 at 03:05 UTC
    When packing an IP, the four numbers are turned into four bytes.
    You could also have written chr(10) . chr(10) . chr(10) . chr(1). The tenth ascii value (Update: Actually, linefeed's the eleventh ascii character, as \0 is the first) happens to be a linefeed (\n), which might cause problems if your $/ is a linefeed (which it is by default).

    Note: In perl 5.6 and later, you can use vector notation for ip constants: v10.10.10.1 or just 10.10.10.1 (so you can actually write things like PeerAddr => 10.10.10.1,.

    2;0 juerd@ouranos:~$ perl -e'undef christmas' Segmentation fault 2;139 juerd@ouranos:~$

Re: What is the best way to pack an ip address?
by chipmunk (Parson) on Jan 14, 2002 at 06:38 UTC
    As Juerd said, chr(10) is a linefeed character. I suspect that one of your Perl scripts is running on Windows, and you forgot to call binmode() on the socket handle. Under Windows, Perl does some magic with newlines, converting "\r\n" to "\n" on input, and "\n" to "\r\n" on output. Calling binmode() disables this behavior for a specific filehandle.
Re: What is the best way to pack an ip address?
by metadoktor (Hermit) on Jan 14, 2002 at 02:37 UTC
    I think you are making a mistake here but it is probably a typo?
    unpack("a4", inet_ntoa($buffer);
    Also have you tried doing this on the same machine?
    my $buf,$str; my $ip_addr="10.10.10.1"; $buf=pack("a4",inet_aton($ip_addr)); $str=inet_ntoa(unpack("a4",$buf)); print "$str\n";
    Do you get the correct address after doing this? If you do perhaps you are misconfiguring your setup to transmit the bytes over the socket?

    metadoktor

    "The doktor is in."