*DECK IPPBINS 
USETEXT TEXTIPL 
USETEXT TEXTXDR 
      PROC IPPBINS (SOCKID, PORT, SOCKSTATUS);
*CALL COPYRITE          CDCNET - COPYRIGHT CONTROL DATA. 1992.
# TITLE IPPBINS - BIND SOCKET                                          #
  
      BEGIN                            # IPPBINS                       #
# 
****  IPPBINS  BIND SOCKET
* 
*     THIS PROCEDURE BINDS AN IP ADDRESS AND A PORT TO A SOCKET.
* 
*     PROC IPPBINS
* 
*     ENTRY    SOCKID     = INTEGER VALUE OF SOCKET 
*              PORT       = INTEGER VALUE OF PORT.  IF THE PORT NUMBER
*                           IS 0 THEN THE PORT IS ASSIGNED BY THE CDCNET
*                           TCP/IP GATEWAY. 
* 
*     EXIT     SOCKSTATUS = COMPLETION STATUS 
* 
*     METHOD   IF THE SOCKET STATE IS NOT OPEN THEN RETURN WITH AN
*              APPROPRIATE STATUS INDICATION BASED ON THE CURRENT 
*              STATE. IF THE SOCKET IS USING THE *UDP* PROTOCOL, THEN 
*              SEND AN OPEN SAP REQUEST TO THE CDCNET TCP/IP GATEWAY. 
*              IF A *PORT* IS NON-ZERO, INCLUDE IN THE ADDRESS PORTION
*              OF THE CALL REQUEST.  THE PROCEDURE IPPRECV IS CALLED
*              TO WAIT FOR A CALL INDICATION FROM THE TCP/IP GATEWAY. 
*              IF A RESPONSE IS NOT RECEIVED IN 60 SECONDS OR IF DATA 
*              OTHER THAN A CALL RESPONSE IS RECEIVED, RETURN AN ERROR. 
*              IF A VALID RESPONSE IS RECEIVED, STORE THE SOURCE ADDRESS
*              IN THE ACN ENTRY AND RETURN. 
# 
  
# 
****  PROC IPPBINS - XREF LIST
# 
      XREF
        BEGIN 
        PROC IPPRECV;    # RECEIVE BLOCK OF DATA                       #
        PROC IPUMCLR;    # MEMORY CLEAR                                #
        PROC NETPUT;     # OUTPUT A MESSAGE TO THE NETWORK             #
        PROC XDRBYTE;    # CONVERT BYTES TO XDR FORMAT                 #
        PROC XDRINT;     # CONVERT INTEGERS TO XDR FORMAT              #
        END 
# 
**
# 
      ITEM SOCKID              I;      # SOCKET IDENTIFIER             #
      ITEM PORT                I;      # PORT NUMBER                   #
      ITEM SOCKSTATUS S:SOCKSTAT;      # RETURNED SOCKET STATUS        #
  
      ITEM BUFLENGTH           I;      # LENGTH OF RECEIVE BUFFER      #
      ITEM BUFPOS              I;      # CURRENT POSITION IN BUFFER    #
      ARRAY ADDRESS [00:00] S(ADDSIZE$);;# SOURCE ADDRESS FROM CALL RES#
      BASED ARRAY IPADDR [00:00] S(1);;# SOURCE ADDRESS FOR XDR CALL   #
      CONTROL EJECT;
  
# 
****  START MAIN PROCEDURE
# 
  
      IF ACN$STATE [SOCKID] NQ S"OPEN"
      THEN
        BEGIN 
        SOCKSTATUS = SOCKSTAT"INVALIDST"; 
        RETURN; 
        END 
  
      IF (ACN$ABORT [SOCKID]) 
      THEN
        BEGIN                          # CONNECTION ABORTED            #
        SOCKSTATUS = S"ABORT";
        RETURN; 
        END 
  
      SWITCH SOCK$:PTYPE  SOCK$UDP:SOCKETUDP, 
                          SOCK$TCP:SOCKETTCP; 
  
      GOTO SOCK$ [ACN$PTYPE [SOCKID]];
        BEGIN                          # SOCKET TYPE                   #
  
    SOCK$UDP: 
        BUFPOS = 0;                    # INITIALIZE BUFFER POSITION    #
  
        P<IP$ADDR$REC> = LOC (HST$ADDR);
        P<IPADDR> = LOC (HST$ADDR) + 1;# LOCATION FOR XDR ROUTINES     #
        IP$UDPORT = 0;                 # CLEAR PORT OF LOCAL HOST ADDR #
  
        IF PORT NQ 0
        THEN
          BEGIN                        # ADD PORT TO THE HOST ADDRESS  #
          IP$PIU = TRUE;               # SET PORT IN USE               #
          IP$PORT = PORT; 
          END 
  
# 
****  PACK THE CALL REQUEST FOR THE UDP INTERFACE INTO *OUTBUF*.
*     THE REQUEST CONSISTS OF THE CALL TYPE, UDP VERSION, A BYTE
*     INDICATING WHAT IP ADDRESS FIELDS ARE INCULDED, AND THREE 32
*     BIT INTEGERS INCLUDING THE NETWORK, HOST, AND PORT.  THE NETWORK
*     AND HOST PORTION COME FROM THE COMMON HST$ADDR ARRAY. 
# 
  
        IPUMCLR (LOC (OUTBUF), 4);     # CLEAR 4 WORDS OF OUTPUT       #
        UDP$HEADER [0] = CALLREQ$;
        UDP$FIU [0] = IP$IPFIU [0]; 
        XDRBYTE (OUTBUF, BUFPOS, UDP$HEAD$REC, 4, XDROPER"WRITE");
        XDRINT (OUTBUF, BUFPOS, IPADDR, 3, XDROPER"WRITE"); 
        BUFPOS = BUFPOS + 14;          # DESTINATION ADDRESS ZERO      #
  
        P<ABH> = LOC (DABH);           # BASE ABH POINTER              #
        ABHADR [0] = SOCKID;           # STORE CONNECTION NUMBER       #
        ABHABN [0] = ACN$ABN [SOCKID]; # STORE APPLICATION BLOCK NUMBER#
        ABHTLC [0] = BUFPOS;           # STORE TEXT LENGTH IN BYTES    #
        ACN$ABN [SOCKID] = ACN$ABN [SOCKID] + 1;
        ACN$OBC [SOCKID] = ACN$OBC [SOCKID] + 1;
        NETPUT (DABH, OUTBUF);         # SEND THE REQUEST              #
  
# 
****  WAIT FOR A RESPONSE FROM THE BIND.  ONCE RECEIVED VERIFY THAT THE 
*     RESPONSE IS A CALL RESPONSE.  SAVE THE RETURNED IP ADDRESS IN 
*     THE ACN SOCKET ENTRY. 
* 
# 
  
        IPPRECV (SOCKID, WORKBUF, BUFLENGTH, ADDRESS, SOCKSTATUS);
  
        IF (SOCKSTATUS NQ S"OK") OR 
           (REC$REQ [0] NQ CALLRES$)
        THEN
          BEGIN                        # BIND FAILED                   #
          SOCKSTATUS = S"REQFAIL";
          END 
        ELSE
          BEGIN                        # MOVE IP ADDRESS TO ACN ENTRY  #
          P<IP$ADDR$REC> = LOC (ADDRESS); 
          ACN$SIPFIU [SOCKID] = IP$IPFIU [0]; 
          ACN$SIPHOST [SOCKID] = IP$IPHOST [0]; 
          ACN$SIPNET [SOCKID] = IP$IPNET [0]; 
          ACN$SIUPORT [SOCKID] = IP$UDPORT [0]; 
          ACN$STATE [SOCKID] = S"BOUND";
          SOCKSTATUS = S"OK"; 
          END 
  
        GOTO BIND$END;
  
    SOCK$TCP: 
        GOTO BIND$END;
        END                            # SOCKET TYPE                   #
  
    BIND$END: 
  
      RETURN;                          # RETURN TO CALLER              #
  
      END                              # IPPBINS                       #
  
      TERM
