OS2 World Community Forum

OS/2, eCS & ArcaOS - Technical => Programming => Topic started by: Jan-Erik Lärka on December 19, 2017, 07:19:59 pm

Title: htonl in REXX
Post by: Jan-Erik Lärka on December 19, 2017, 07:19:59 pm
The socket call translates a long integer from host-byte order to network-byte order.

Syntax
htonl( a )

Parameters
a
integer (whole) number to be converted to/from network-byte order (on little endian systems).

Description
htonl(...) call convert an host-byte order integer to internet network-byte order.
htonl(...) call also convert an internet network-byte order integer to host-byte order.

The internet network requires addresses and ports in network standard-byte order.
Use the htonl(...) call to convert the host integer representation of addresses and ports to internet network-byte order.

Returns
The translated integer

Example:
SAY htonl( 16384 )  //4194304
SAY htonl( 4194304 )  //16384

Code:
Code: [Select]
htonl: PROCEDURE
   hex = D2X( ARG( 1 ) )
   exp = ''
   DO i = 1 TO LENGTH( hex ) BY 8
      exp =  STRIP( TRANSLATE( '12345678', RIGHT( STRIP( SUBSTR( hex, i, 8 ) ), 8, '0' ), '78563412' ) )||exp
   END
RETURN X2D( exp )

ClamAV use it for zINSTREAM
Other applications that communicate over the network

Regards,
//Jan-Erik
Title: Re: htonl in REXX
Post by: Dave Yeo on December 19, 2017, 08:01:24 pm
Quote
Description
htonl(...) call convert an host-byte order integer to internet network-byte order.
htonl(...) call also convert an internet network-byte order integer to host-byte order.

Strange that it doesn't use ntohl(...) to convert back to little endian like most languages. Would seem clearer.
Title: htonl and ntohl in REXX
Post by: Jan-Erik Lärka on December 20, 2017, 06:38:33 am
Quote
Description
htonl(...) call convert an host-byte order integer to internet network-byte order.
htonl(...) call also convert an internet network-byte order integer to host-byte order.

Strange that it doesn't use ntohl(...) to convert back to little endian like most languages. Would seem clearer.
True, the gcc version wrap a function and try to overcome the problem with a check.

Description
htonl(...) call convert an host-byte order integer to internet network-byte order (long).
ntohl(...) call convert an internet network-byte order integer to host-byte order (long).

Code: [Select]
htonl: PROCEDURE
   swp = swap( ARG(1) )
   IF ARG(1) < swp THEN
      RETURN swp
RETURN ARG(1)

ntohl: PROCEDURE
   swp = swap( ARG(1) )
   IF swp < ARG(1) THEN
      RETURN swp
RETURN ARG(1)

swap: PROCEDURE
   hex = D2X( ARG( 1 ) )
   exp = ''
   DO i = 1 TO LENGTH( hex ) BY 8
      exp =  STRIP( TRANSLATE( '12345678', RIGHT( STRIP( SUBSTR( hex, i, 8 ) ), 8, '0' ), '78563412' ) )||exp
   END
RETURN X2D( exp )
gcc's htonl use __swab32 that does the same thing in the background in its own way and have the same "problem" as one then have to know if it has been converted.
Title: Re: htonl in REXX
Post by: Lars on December 20, 2017, 01:03:38 pm
Why don't you just use "reverse" function ? At least that is what I use:

htonl: procedure
parse arg swp .
return reverse(swp)

If you have to work on binary data directly you would likely need to do this:

htonl: procedure
parse arg swp .
return c2d(reverse(swp))

Title: Re: htonl in REXX
Post by: Jan-Erik Lärka on December 26, 2017, 10:53:15 am
It's not true reverse, it's more reverse in group of 2.
But that is if one start with a number and use Hex to do the swap.

What do you use as input?
Title: Re: htonl in REXX
Post by: Lars on December 26, 2017, 11:49:14 am
then do this:

c2d(Reverse(d2c(swp,4)))