DEFINITION MODULE Inet2Misc;

        (********************************************************)
        (*                                                      *)
        (* Miscellaneous procedures for networking applications *)
        (*                                                      *)
        (*  Programmer:         P. Moylan                       *)
        (*  Started:            17 January 2002                 *)
        (*  Last edited:        19 May 2023                     *)
        (*  Status:             OK                              *)
        (*                                                      *)
        (********************************************************)


FROM SYSTEM IMPORT
    (* type *)  LOC, CARD16, CARD32;

FROM Sockets IMPORT
    (* type *)  Socket;

FROM Names IMPORT
    (* type *)  HostName;


PROCEDURE NameIsNumeric (VAR (*INOUT*) name: ARRAY OF CHAR): BOOLEAN;

    (* Returns TRUE iff name has the form N.N.N.N or [N.N.N.N] where each N is  *)
    (* a decimal number.  (The present version actually accepts an arbitrary    *)
    (* number of numbers separated by dots.)  As a side-effect, we also strip   *)
    (* the square brackets if they are present.                                 *)

PROCEDURE IPToString (IP: ARRAY OF LOC;  EncloseInBrackets: BOOLEAN;
                                VAR (*OUT*) result: ARRAY OF CHAR);

    (* Converts a four-byte IP address (in network byte order) to a             *)
    (* human-readable form.  There must be at least 15 character positions      *)
    (* available in the result array, or 17 if EncloseInBrackets is TRUE.       *)

PROCEDURE AddressToHostName (address: CARDINAL;
                             VAR (*OUT*) Name: HostName): BOOLEAN;

    (* Converts a numeric IP address to a name.  The result is TRUE if  *)
    (* we got a genuine name.  If the result is FALSE, then Name is     *)
    (* just a dotted quad form of the address.                          *)

PROCEDURE WaitForSocket (S: Socket;  timeout: CARDINAL): INTEGER;

    (* Waits until something is available on socket S.  The possible return     *)
    (* codes are +1 for OK, 0 for timeout, -1 for error (or cancel).            *)
    (* Specify timeout=MAX(CARDINAL) if you don't want a timeout.               *)

PROCEDURE WaitForSocketOut (S: Socket;  timeout: CARDINAL): INTEGER;

    (* Waits until socket S is ready for more output.  The possible     *)
    (* return codes are +1 for OK, 0 for timeout, -1 for error (or      *)
    (* cancel).  Set timeout=MAX(CARDINAL) if you don't want a timeout. *)

PROCEDURE WaitForDataSocket (output: BOOLEAN;
                             DataSocket, CommandSocket: Socket): BOOLEAN;

    (* Waits until DataSocket is ready or out-of-band data arrives on           *)
    (* CommandSocket.  The first parameter should be TRUE if DataSocket is      *)
    (* being used as an output socket, and FALSE if it is being used as an      *)
    (* input socket.  The function result is TRUE iff DataSocket is ready AND   *)
    (* no out-of-band data has arrived on CommandSocket.                        *)

PROCEDURE Receive (S: Socket;  VAR (*OUT*) data: ARRAY OF LOC;
                                                desired: CARDINAL): CARDINAL;

    (* Receives up to desired bytes from the socket.  The returned value is *)
    (* the actual number of bytes, or MAX(CARDINAL) on timeout or error.    *)

PROCEDURE Synch (S: Socket);

    (* Ensures that outgoing data is sent right now rather than being   *)
    (* buffered.  This reduces performance a little, but is needed to   *)
    (* work around a bug in Netscape and MS FTP Exploder.               *)

PROCEDURE StringToIPAddress (VAR (*IN*) name: ARRAY OF CHAR;
                                          VAR (*INOUT*) pos: CARDINAL): CARDINAL;

    (* Converts a string of the form N.N.N.N or [N.N.N.N], where each N is a    *)
    (* decimal number, starting at name[pos] and updating pos.  We assume that  *)
    (* the caller has already checked for syntactic correctness.                *)

PROCEDURE StringToIP (name: ARRAY OF CHAR): CARDINAL;

    (* Converts an N.N.N.N string to an address in network byte order.  We      *)
    (* assume that the caller has already checked that the string is in this    *)
    (* format.  Any out-of-range N is set to 0.                                 *)

PROCEDURE Swap2 (val: CARD16): CARD16;

    (* Returns the argument value in byte-reversed order.  This is needed       *)
    (* because network byte order is most significant byte first, whereas our   *)
    (* local host order is least significant byte first.                        *)

PROCEDURE Swap4 (val: CARD32): CARD32;

    (* Returns the argument value in byte-reversed order.  This is needed       *)
    (* because network byte order is most significant byte first, whereas our   *)
    (* local host order is least significant byte first.                        *)

PROCEDURE NonRouteable (address: CARDINAL): BOOLEAN;

    (* Returns TRUE iff address (in network byte order) is one of the   *)
    (* addresses reserved for internal LAN use.  These are:             *)
    (*     (Class A) 10.*.*.*                                           *)
    (*     (Class B) 172.16.*.* through 172.31.*.*                      *)
    (*     (Class C) 192.168.*.*                                        *)

PROCEDURE IsLoopback (address: CARDINAL): BOOLEAN;

    (* Returns TRUE iff address (in network byte order) is a loopback   *)
    (* address; that is, an address in the range 127.*.*.*              *)

END Inet2Misc.

