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

I need to convert from Network byte order to Host Byte order, such as the ntohl() function performs in C.I haven't been able to find an equivalant function in perl. I do not have access to install any additional perl modules from cpan.

Knowing that network order begins with the most significant byte first and host order is just the opposite i tried using the reverse() function, with no luck.

Replies are listed 'Best First'.
Re: ntohl() in perl
by nothingmuch (Priest) on Oct 27, 2002 at 18:29 UTC
    the pack and unpack functions handle such data representation. $unsigned_local_long = pack("L",unpack("N",$unsigned_network_long)) will take the 4 (supposedly) bytes in $unsigned_network_long, interpret them into a perl scalar integer value. After the network format was unpacked, it is passed to pack, which then converts the perl scalar to a local C compiler representation of the integer, in 32 bits. You can see the documentation for a more complete reference of packing templates, but the ones you're probably interested in are:

    N - network order long integer (unsigned)
    n - network order short integer (unsigned)
    V - a vax order ('host order') long integer (unsigned)
    v - a vax order short (unsigned)
    s - a local (network or vax, depending on processor) signed short (16 bits)
    S - a local order unsigned short (16 bits)
    l - a local order signed long (32 bits)
    L - a local order unsigned long (32 bits)
    i - a local order signed long (32/64 bits)
    I - a local order unsigned long (32/64 bits)

    If you suffix s/S/l/L with !, then they become the native width of 'shorts' and 'longs', as treated by the compiler which made perl. If you have a 64 bit processor, than the native integer width may be larger. A more comprehensive documentation of the templates and how to use them can be found in perlfunc -f pack.

    -nuffin
    zz zZ Z Z #!perl
Re: ntohl() in perl
by tadman (Prior) on Oct 27, 2002 at 20:11 UTC
    As nothingmuch suggested:
    sub ntohl { pack("L", unpack("N", $_[0])); } sub ntohs { pack("S", unpack("n", $_[0])); } sub htonl { ntohl(@_); } sub htons { ntohs(@_); }
    Remember that on some systems there is no difference between "Network" and "Host" order. Using reverse is irresponsible.

    This is all mostly irrelevant anyway, since standard modules like IO::Socket take care of it all for you automatically.
Re: ntohl() in perl
by Enlil (Parson) on Oct 27, 2002 at 18:28 UTC