Author Topic: htonl in REXX  (Read 5592 times)

Jan-Erik Lärka

  • Global Moderator
  • Sr. Member
  • *****
  • Posts: 275
  • Karma: +5/-0
    • View Profile
htonl in REXX
« 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

Dave Yeo

  • Hero Member
  • *****
  • Posts: 4786
  • Karma: +99/-1
    • View Profile
Re: htonl in REXX
« Reply #1 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.

Jan-Erik Lärka

  • Global Moderator
  • Sr. Member
  • *****
  • Posts: 275
  • Karma: +5/-0
    • View Profile
htonl and ntohl in REXX
« Reply #2 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.

Lars

  • Hero Member
  • *****
  • Posts: 1271
  • Karma: +65/-0
    • View Profile
Re: htonl in REXX
« Reply #3 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))

« Last Edit: December 20, 2017, 01:05:10 pm by Lars »

Jan-Erik Lärka

  • Global Moderator
  • Sr. Member
  • *****
  • Posts: 275
  • Karma: +5/-0
    • View Profile
Re: htonl in REXX
« Reply #4 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?

Lars

  • Hero Member
  • *****
  • Posts: 1271
  • Karma: +65/-0
    • View Profile
Re: htonl in REXX
« Reply #5 on: December 26, 2017, 11:49:14 am »
then do this:

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