home *** CD-ROM | disk | FTP | other *** search
/ Programmer's ROM - The Computer Language Library / programmersrom.iso / ada / defdata / tcpsub.src < prev    next >
Encoding:
Text File  |  1988-05-03  |  355.8 KB  |  9,998 lines

  1. --::::::::::::::
  2. --buffer_.ada
  3. --::::::::::::::
  4. -----------------------------------------------------------------------
  5. --
  6. --         DoD Protocols    NA-00001-200       80-00988-100(-)
  7. --         E-Systems, Inc.  August 07, 1985
  8. --
  9. --         BUFFER_.ADA       Author : Jim Baldo
  10. --
  11. -----------------------------------------------------------------------
  12. with SYSTEM;                use SYSTEM;    
  13.  
  14.             package    BUFFER_DATA is
  15.  
  16. -----------------------------------------------------------------------------
  17. --This package represents the data abstraction of a message that travels   --
  18. --through each layer in the DoD reference model.  Upon recieving a message -- 
  19. --the protocol uses a pointer to gain access to the beginning of its       --
  20. --header.  The package is implementation dependent.  Its intend is to      --
  21. --facilatate the portibility of this communications program by narrowing   --
  22. --the packages to be change to an absolute minimum for different machines. --
  23. --                                                                         --
  24. --design:                                                                  --
  25. --                                                                         --
  26. --                                                                         --
  27. -- The packed bit stream buffer definition.                                --
  28. -- A buffer record contains the following information:                     -- 
  29. --  STATUS      : indicating the current owner, if any. A process must not --
  30. --                free a buffer if it is owned by any other process.       --
  31. --  TELNET_PTR  : indicates the position of the first byte of data for     --
  32. --                Telnet.                                                  --
  33. --  TCP_PTR     : indicates the position of the first byte of data for TCP.--
  34. --  IP_PTR      : indicates the position of the first byte of data for IP. --
  35. --  SUBNET_PTR    : Indicates the position of the first byte of data         --
  36. --              for SUBNET                                       --
  37. --  SIZE        : total size in bytes                                      --
  38. --  BYTE        : The actual transmitted data, in an array of packed bytes.--
  39. --  NEXT        : A link field used to manage free buffers.                --
  40. --                                                                         -- 
  41. --                                                                         --
  42. --                                                                         --
  43. --      Organization of buffer                                             --
  44. --       Note that unused portion of the buffer is at the front or the back--
  45. --         of the buffer.                                                  --
  46. --                                                                         -- 
  47. --      +-------------+                                                    -- 
  48. --      |             |                                                    --
  49. --      |   unused    |                                                    --
  50. --      |             |                                                    --
  51. --      +-------------+ <-------- SUBNET_PTR                               --
  52. --      |             |                                                    --
  53. --      |    SUBNET   |                                                    --
  54. --      |   header    |                                                    --
  55. --      |             |                                                    -- 
  56. --      +-------------+ <-------- IP_PTR                                   --
  57. --      |             |                                                    --
  58. --      |     IP      |                                                    --
  59. --      |   header    |                                                    --
  60. --      |             |                                                    --
  61. --      +-------------+ <-------- TCP_PTR                                  --
  62. --      |             |                                                    --
  63. --      |    TCP      |                                                    --
  64. --      |   header    |                                                    --
  65. --      |             |                                                    --
  66. --      +-------------+ <-------- TELNET_PTR                               --
  67. --      |             |                                                    --
  68. --      |   TELNET    |                                                    --
  69. --      |    data     |                                                    --
  70. --      |             |                                                    --
  71. --      +-------------+                                                    --
  72. --      |             |                                                    --
  73. --      |   unused    |                                                    --
  74. --      |             |                                                    --
  75. --      +-------------+                                                    --
  76. --                                                                         --
  77. -----------------------------------------------------------------------------
  78.  
  79.         subtype THIRTYTWO_BITS is INTEGER; -- DEC/Ada
  80.         --TEL subtype THIRTYTWO_BITS is INTEGER; --Telesoft Ada version 1.5
  81.         subtype SIXTEEN_BITS is SHORT_INTEGER; -- DEC/Ada
  82.         --TEL subtype SIXTEEN_BITS is SHORT_INTEGER; --Telesoft Ada version 1.5
  83.         subtype SYSTEM_BYTE is UNSIGNED_BYTE; -- DEC/Ada
  84.         --TEL subtype SYSTEM_BYTE is SYSTEM.BYTE; -- Telesoft Ada version 1.5
  85.  
  86.      MAXIMUM_DATAGRAM_SIZE : constant SIXTEEN_BITS  := 576;
  87.     type BUFFER_STATUS is (NONE, OWNER_TELNET, OWNER_TCP, OWNER_IP,
  88.                    OWNER_X25);
  89.     type BUFFER_AREA IS ARRAY(1..MAXIMUM_DATAGRAM_SIZE) OF SYSTEM_BYTE;
  90.                                                             
  91.     TELNET_SIZE : constant SIXTEEN_BITS := 512; --for efficent block transfer
  92.     TCP_SIZE : constant SIXTEEN_BITS := 512;
  93.     IP_SIZE : constant SIXTEEN_BITS := 512;
  94.     SUBNET_SIZE : constant SIXTEEN_BITS := 512; --set appropiately to SUBNET
  95.                            --specification
  96.  
  97.     subtype TELNET_PTR_TYPE is SIXTEEN_BITS  range 0..TELNET_SIZE;
  98.     subtype TCP_PTR_TYPE is SIXTEEN_BITS  range 0..TCP_SIZE;
  99.     subtype IP_PTR_TYPE is SIXTEEN_BITS  range 0..IP_SIZE;
  100.     subtype SUBNET_PTR_TYPE is SIXTEEN_BITS  range 0..SUBNET_SIZE;
  101.  
  102.     type PACKED_BUFFER;
  103.     type PACKED_BUFFER_PTR is access PACKED_BUFFER;
  104.     type PACKED_BUFFER is 
  105.         record 
  106.             STATUS     : BUFFER_STATUS := NONE;
  107.             IN_USE     : BOOLEAN := false;
  108.                      -- THE LAYER USING IT MAY NOT 
  109.                      -- BE THE OWNER.
  110.                         SIZE       : SIXTEEN_BITS  range 0..MAXIMUM_DATAGRAM_SIZE ;
  111.             TELNET_PTR : TELNET_PTR_TYPE;
  112.             TCP_PTR    : TCP_PTR_TYPE;
  113.             IP_PTR     : IP_PTR_TYPE;
  114.             SUBNET_PTR : SUBNET_PTR_TYPE;
  115.             BYTE       : BUFFER_AREA;
  116.             NEXT       : PACKED_BUFFER_PTR;
  117.         end record;
  118.  
  119.     --type BUFFER_ERROR_TYPE is (RETURNING_A_BUFFER,OUT_OF_FREE_BUFFERS);
  120.  
  121.     procedure INIT;
  122.  
  123.         --This subprogram is called when the system is intialize to 
  124.         --create a finite number of buffers.
  125.  
  126.     procedure BUFFREE
  127.         ( BUFPTR :  in out PACKED_BUFFER_PTR;
  128.                   BUFFTYPE : in SIXTEEN_BITS );
  129.  
  130.         --This subprogram frees a buffer to be used again.
  131.         --Change buffer status to free and place it on a free list 
  132.         --of buffers.
  133.  
  134.     procedure BUFFGET
  135.         ( BUFPTR : in out PACKED_BUFFER_PTR; 
  136.                   BUFFTYPE : in SIXTEEN_BITS );
  137.  
  138.         --This subprogram obtains a buffer to be used.
  139.  
  140. end BUFFER_DATA;
  141.  
  142. --::::::::::::::
  143. --buffer.ada
  144. --::::::::::::::
  145. -----------------------------------------------------------------------
  146. --
  147. --         DoD Protocols    NA-00001-200       80-00989-100(-)
  148. --         E-Systems, Inc.  August 07, 1985
  149. --
  150. --         BUFFER.ADA       Author : Jim Baldo
  151. --
  152. -----------------------------------------------------------------------
  153. with UNCHECKED_CONVERSION;
  154. with TEXT_IO;                         use TEXT_IO;
  155.  
  156.  
  157. ----------------------------------------------------------------------------
  158. -- 
  159. -- Implementation for DEC VAX installation only!
  160. --
  161. ----------------------------------------------------------------------------
  162.  
  163. package    body BUFFER_DATA  is
  164.  
  165. package INT_IO is new INTEGER_IO( THIRTYTWO_BITS );
  166.   
  167. HEAD : PACKED_BUFFER_PTR; -- The pointer to the head of the buffer free 
  168. BUFFER_COUNT : THIRTYTWO_BITS ;
  169.  
  170. BUFFER_PRINT_FLAG : THIRTYTWO_BITS  := 1;
  171.  
  172. task buffer_manager is
  173.   pragma priority (15) ; 
  174.   entry free (bufptr : in out packed_buffer_ptr) ;
  175.   entry get  (bufptr :    out packed_buffer_ptr) ;
  176. end buffer_manager ;
  177.  
  178. task body buffer_manager is
  179. begin
  180. loop
  181.   select
  182.     accept free (bufptr : in out packed_buffer_ptr) do
  183.       bufptr.next := head;
  184.     head := bufptr;
  185.         end free ;
  186.   or
  187.     accept  get  (bufptr : out packed_buffer_ptr) do
  188.       bufptr := head;
  189.       if head /= null then
  190.         head := head.next ;
  191.       end if ;
  192.     end get ;
  193.   end select ;
  194. end loop ;
  195. exception
  196.   when others => 
  197.     put_line("ERROR IN BUFFER MANAGER") ;
  198.  
  199. end buffer_manager ;
  200.  
  201.  
  202. --
  203. -- The view from the outside world:
  204. --
  205.  
  206. procedure BUFFREE
  207.     ( BUFPTR : in out PACKED_BUFFER_PTR; 
  208.           BUFFTYPE : in SIXTEEN_BITS ) is
  209. begin
  210.  if BUFPTR.STATUS = NONE and then NOT BUFPTR.IN_USE then
  211.     BUFFER_COUNT := BUFFER_COUNT + 1; 
  212.     bufptr.in_use := true;
  213.     buffer_manager.free(bufptr) ;
  214.     bufptr := null; -- return a null pointer
  215.  else
  216.   PUT_LINE("FAILED TO FREE BUFFER IN BUFFREE");
  217.  end if;
  218.  TEXT_IO.PUT("FREEING A BUFFER. NUMBER OF FREE BU");
  219.  INT_IO.PUT(BUFFER_COUNT);
  220.  TEXT_IO.NEW_LINE;
  221. exception
  222.   when others => 
  223.     put_line("ERROR IN BUFFREE") ;
  224. end BUFFREE;
  225.  
  226. procedure BUFFGET
  227.     (BUFPTR : in out PACKED_BUFFER_PTR; 
  228.      BUFFTYPE : in SIXTEEN_BITS ) is
  229. begin
  230.  buffer_manager.get(bufptr) ;
  231.  if bufptr /= null then
  232.    bufptr.in_use     := false ;
  233.    bufptr.telnet_ptr := 255 ;
  234.    bufptr.tcp_ptr    := 255 ;
  235.    bufptr.ip_ptr     := 255 ;
  236.    bufptr.subnet_ptr := 255 ;
  237.    bufptr.status     := NONE ;
  238.  TEXT_IO.NEW_LINE;
  239.  PUT("BUFFGET No. OF BUFFERS := ");
  240.  INT_IO.PUT(BUFFER_COUNT);
  241.  TEXT_IO.NEW_LINE;
  242.  else
  243.    text_io.put_line("BUFFER_ERROR  OUT_OF_FREE_BUFFERS") ; -- for debug
  244.  end if ;
  245.  if BUFFER_COUNT /= 0 then
  246.   BUFFER_COUNT := BUFFER_COUNT - 1;
  247.  end if;
  248. -- if BUFFER_PRINT_FLAG /= 0 then--for debug only (JB 1/25/85)
  249. --    if BUFFER_COUNT /= 0 then
  250. --        TEXT_IO.NEW_LINE;
  251. --                TEXT_IO.PUT
  252. --                 ("GETTING A BUFFER. NUMBER OF FREE BU");
  253. --        INT_IO.PUT(BUFFER_COUNT);
  254. --        TEXT_IO.NEW_LINE;
  255. --    else
  256. --                TEXT_IO.PUT_LINE("NO FREE BUFFERS ON BUFFER GET");
  257. --    end if;
  258. -- end if;
  259. exception
  260.   when others =>
  261.     TEXT_IO.PUT_LINE("ERROR IN BUFFER GET");
  262.     raise ;
  263. end BUFFGET;
  264.  
  265. procedure INIT is
  266.  
  267.  I : THIRTYTWO_BITS ;
  268.  NEXT_BUFFER : PACKED_BUFFER_PTR;
  269. begin
  270.   -- get one hundred and one buffers.
  271.   HEAD := new PACKED_BUFFER;
  272.   NEXT_BUFFER := new PACKED_BUFFER;
  273.   HEAD.NEXT := NEXT_BUFFER;
  274.   for I in 1..50 loop
  275.     next_buffer := new packed_buffer;
  276.     buffree(next_buffer,0) ;
  277.     end loop;
  278.   BUFFER_COUNT := 50;
  279. exception 
  280.   when STORAGE_ERROR =>
  281.     TEXT_IO.PUT_LINE("OUT OF ROOM TO INITIALIZE BUFFERS");
  282.   when others =>
  283.     TEXT_IO.PUT_LINE("ERROR IN INITIALIZE BUFFERS");
  284. end INIT;
  285.  
  286.  
  287.  
  288. --
  289. -- Package initialization
  290. --
  291.  
  292.  
  293. begin
  294.  BUFFER_COUNT := 0; -- initialize buffer count.
  295.  INIT; -- generate buffers
  296. end BUFFER_DATA;
  297. --::::::::::::::
  298. --ipglb_.ada
  299. --::::::::::::::
  300. -----------------------------------------------------------------------
  301. --
  302. --         DoD Protocols    NA-00001-200       80-00996-100(-)
  303. --         E-Systems, Inc.  August 07, 1985
  304. --
  305. --         IPGLB_.ADA       Author : Jim Baldo
  306. --
  307. -----------------------------------------------------------------------
  308. with BUFFER_DATA ;        use BUFFER_DATA ;
  309. with SYSTEM;            use SYSTEM;
  310. with TEXT_IO;            use TEXT_IO;
  311.  
  312.             package IP_GLOBALS is
  313.  
  314.         -----------------------------------------------
  315.         --This implementation is for use with the    --
  316.         --DEC/Ada compiler .                         --
  317.         -----------------------------------------------
  318.  
  319. ------------------------------------------------------------------------------
  320. -- THIS SPECIFICATION CONTAINS ALL NECESSARY GLOBAL VARIABLES FOR THE       --
  321. -- INTERNET PROTOCOL.                                                       --
  322. ------------------------------------------------------------------------------
  323.  
  324.         subtype LOCAL_ADDRESS_TYPE  is SIXTEEN_BITS ;
  325.     NUMBER_OF_ADDRESSES : constant SIXTEEN_BITS  := 4; -- TEMPORARY VALUE ***
  326.     MAX_HOSTS : constant SIXTEEN_BITS  := 4; -- TEMP.
  327.     type MY_ADDRESS_LIST is array(1..MAX_HOSTS) of LOCAL_ADDRESS_TYPE ;
  328.     type ADDRESS_LIST is array(1..NUMBER_OF_ADDRESSES) of THIRTYTWO_BITS ;
  329.     VALID_ADDRESS_LIST : constant ADDRESS_LIST := (1, 2, 3, 128);
  330.     MY_IP_ADDRESS : constant MY_ADDRESS_LIST := (1,2,3,128); -- TEMPORARY **
  331.     BAD_CHECKSUM : SIXTEEN_BITS  := 0;
  332.     WHOIAM : constant THIRTYTWO_BITS  := 1 ; 
  333.  
  334.     subtype    SEVEN_BITS is SIXTEEN_BITS ;
  335.     subtype    TEN_BITS is SIXTEEN_BITS ;
  336.     subtype    THREE_BITS is SIXTEEN_BITS ;
  337.     subtype    TWO_BITS is SIXTEEN_BITS ;
  338.     subtype    FOUR_OCTETS is THIRTYTWO_BITS ;
  339.     subtype    TWO_OCTETS is SIXTEEN_BITS ;
  340.     subtype    ONE_OCTET is SIXTEEN_BITS ;
  341.     subtype    HALF_OCTET is SIXTEEN_BITS ;
  342.     subtype    SIX_BITS is SIXTEEN_BITS ;
  343.     subtype    ONE_BIT    is SIXTEEN_BITS ;
  344.  
  345.     subtype BTYPE_TYPE is SIXTEEN_BITS ;
  346.  
  347.         subtype OPTION_TYPE_RANGE is SIXTEEN_BITS range 1..50;
  348.  
  349.     type OPTION_TYPE is array(OPTION_TYPE_RANGE) of SIXTEEN_BITS ;
  350.  
  351.     type BUFFER_POINTER is
  352.         record
  353.             BTYPE :    BTYPE_TYPE;
  354.             VERSION    : HALF_OCTET;
  355.             IHL : HALF_OCTET;
  356.             TOS : ONE_OCTET;
  357.             TOT_LEN    : TWO_OCTETS;
  358.             ID : TWO_OCTETS;
  359.             FLAGS : THREE_BITS;
  360.             FRAG_OFFSET : TWO_OCTETS;
  361.             TTL : ONE_OCTET;
  362.             PROT : ONE_OCTET;
  363.             IPCSUM : TWO_OCTETS;
  364.             SOURCE : FOUR_OCTETS;
  365.             DEST : FOUR_OCTETS;
  366.               --OPTIONS    FOR IP HERE.
  367.             IP_OPTIONS : OPTION_TYPE := 
  368.                         (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  369.                          0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  370.                          0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  371.                          0);
  372.         end record;
  373.  
  374. type PRECEDENCE_TYPE is ( NETWORK_CONTROL, -- 111
  375.                           INTERNETWORK_CONTROL, -- 110
  376.                           CRITIC_ECP, -- 101
  377.                           FLASH_OVERRIDE, --100
  378.                           FLASH, --011
  379.                           IMMEDIATE, --010
  380.                           PRIORITY, --001
  381.                           ROUTINE); --000
  382.  
  383. type RELIABILITY_TYPE is ( NORMAL,
  384.                            HIGH);
  385.  
  386. type DELAY_TYPE is ( NORMAL,
  387.                      LOW);
  388.  
  389. type THROUGHPUT_TYPE is ( NORMAL,
  390.                           HIGH);
  391.  
  392. subtype DATAGRAM_LENGTH is SIXTEEN_BITS ;
  393.  
  394. type RESULT_TYPE is (OK, NOK);
  395.  
  396. type IP_ACTION is ( IP_SEND, ERROR_MESSAGE, DATA_FROM_SUBNET, 
  397.                    FROM_TCP, RECEIVE_IP, NO_IP_ACTION ) ;
  398.  
  399. type IP_MESSAGE(EVENT : IP_ACTION := IP_SEND) is
  400.  record
  401.   BUFPTR : PACKED_BUFFER_PTR := null;
  402.   case EVENT is
  403.    when IP_SEND => 
  404.     LOCAL_DESTINATION : LOCAL_ADDRESS_TYPE ;
  405.     PRECEDENCE : PRECEDENCE_TYPE := ROUTINE;
  406.     RELIABILITY : RELIABILITY_TYPE := NORMAL;
  407.     DELAY_IP : DELAY_TYPE := NORMAL;
  408.     THROUGHPUT : THROUGHPUT_TYPE := NORMAL;
  409.     LENGTH : DATAGRAM_LENGTH := 0 ;
  410.    when ERROR_MESSAGE => ERROR_NUMBER : SIXTEEN_BITS ;
  411.    when RECEIVE_IP => 
  412.     SOURCE : THIRTYTWO_BITS ;
  413.     PROT : SIXTEEN_BITS ;
  414.     RESULT : RESULT_TYPE;
  415.    when FROM_TCP => 
  416.     DEST : THIRTYTWO_BITS ;
  417.     TOS, TTL, LEN, ID, DF : SIXTEEN_BITS ;
  418.     OPTIONS : OPTION_TYPE ;
  419.     SRC : THIRTYTWO_BITS ;
  420.    when DATA_FROM_SUBNET => BYTE_COUNT : SIXTEEN_BITS ;
  421.    when NO_IP_ACTION => null;
  422.   end case;
  423.  end record;
  424.  
  425. end IP_GLOBALS;
  426. --::::::::::::::
  427. --vmodulo_.ada
  428. --::::::::::::::
  429. -----------------------------------------------------------------------
  430. --
  431. --         DoD Protocols    NA-00001-200       80-01031-100(-)
  432. --         E-Systems, Inc.  August 07, 1985
  433. --
  434. --         VMODULO_.ADA       Author : Jim Baldo     
  435. --
  436. -----------------------------------------------------------------------
  437. with BUFFER_DATA ;            use BUFFER_DATA ;
  438.  
  439.             package MODULO is
  440.  
  441. type MODULAR is record
  442.  HI, LOW : THIRTYTWO_BITS ;
  443. end record;
  444.  
  445. function "<" (X,Y: MODULAR) return BOOLEAN;
  446.  
  447. function "<=" (X,Y: MODULAR) return BOOLEAN;
  448.  
  449. function ">" (X,Y: MODULAR) return BOOLEAN;
  450.  
  451. function ">=" (X,Y : MODULAR) return BOOLEAN;
  452.  
  453. function "+" (X,Y: MODULAR) return MODULAR;
  454.  
  455. function "+" (X: MODULAR;Y : THIRTYTWO_BITS ) return MODULAR;
  456.  
  457. function "+" ( X : THIRTYTWO_BITS ;
  458.                Y : MODULAR) return MODULAR;
  459.  
  460. function "+" (X    : MODULAR; Y : SIXTEEN_BITS ) return MODULAR;
  461.  
  462. function "+" ( X : SIXTEEN_BITS ;
  463.                Y : MODULAR) return MODULAR;
  464.  
  465. function "-" ( X : MODULAR; 
  466.                Y : SIXTEEN_BITS ) return MODULAR;
  467.  
  468. function "-" (X,Y: MODULAR) return MODULAR;
  469.  
  470. function LONG(X : MODULAR) return THIRTYTWO_BITS ;
  471.  
  472. function MODULAR_CONVERT (X : SIXTEEN_BITS ) return MODULAR;
  473.  
  474. function MODULAR_CONVERT (X : THIRTYTWO_BITS ) return MODULAR;
  475.  
  476. function GET_MODULAR(PP:STRING) return MODULAR;
  477.  
  478. procedure PUT_MODULAR(PP : MODULAR);
  479.  
  480. end MODULO;
  481.  
  482. --::::::::::::::
  483. --vmodulo.ada
  484. --::::::::::::::
  485. -----------------------------------------------------------------------
  486. --
  487. --         DoD Protocols    NA-00001-200       80-01032-100(-)
  488. --         E-Systems, Inc.  August 07, 1985
  489. --
  490. --         VMODULO.ADA       Author : Jim Baldo
  491. --
  492. -----------------------------------------------------------------------
  493.  
  494. with TEXT_IO;            use TEXT_IO;
  495.  
  496.         package body MODULO is
  497.  
  498. package INT_IO is new INTEGER_IO( THIRTYTWO_BITS );
  499.  
  500. function LONG(X : MODULAR) return THIRTYTWO_BITS   is
  501.  
  502. begin
  503.  return X.HI+X.LOW ;  -- DOES NOT WORK ALL THE TIME! MAY RAISE NUMERIC ERROR
  504. end LONG;
  505.  
  506. function MODULAR_CONVERT (X : SIXTEEN_BITS ) return MODULAR is
  507. Y : MODULAR ;
  508. begin
  509.  Y.HI := 0 ;
  510.  Y.LOW := THIRTYTWO_BITS (X);
  511.  return Y;
  512. exception
  513. when CONSTRAINT_ERROR =>
  514. -- PUT_LINE("CONSTRAINT ERROR IN INT MODULAR_CONVERT");
  515. raise;
  516. when others =>
  517. -- PUT_LINE("ERROR IN INT MODULAR_CONVERT");
  518. raise;
  519. end;
  520.  
  521. function MODULAR_CONVERT (X : THIRTYTWO_BITS  ) return MODULAR is
  522. Y : MODULAR;
  523. begin
  524.  Y.HI := X / 2**16 ;
  525.  Y.LOW := X MOD 2**16 ;
  526.  return Y;
  527. exception
  528. when CONSTRAINT_ERROR =>
  529. -- PUT_LINE("CONSTRAINT ERROR IN LONG_INT MODULAR_CONVERT");
  530. raise;
  531. when others =>
  532. -- PUT_LINE("ERROR IN LONG_INT MODULAR_CONVERT");
  533. raise;
  534. end;
  535.  
  536. procedure PUT_MODULAR(PP : MODULAR) is
  537. begin
  538.   TEXT_IO.PUT("THE ANSWER IS ");
  539.   IF PP.HI <= 2**15-1 THEN
  540.     INT_IO.PUT((PP.HI * (2**16)) + PP.LOW) ;
  541.     TEXT_IO.PUT_LINE("");
  542.   ELSE
  543.     TEXT_IO.PUT(" negative ") ;
  544.     INT_IO.PUT(PP.HI) ;
  545.     TEXT_IO.PUT(",");
  546.     INT_IO.PUT(PP.LOW) ;
  547.     TEXT_IO.PUT_LINE("") ;
  548.   END IF ;
  549. end;
  550.  
  551. function GET_MODULAR(PP:STRING) return MODULAR is
  552. X : MODULAR ;
  553. begin
  554. --  TEXT_IO.PUT_LINE(PP);
  555. --  TEXT_IO.PUT_LINE("");
  556. -- return VAL;
  557. X.HI := 0 ; X.LOW := 0 ;
  558. RETURN(X) ;
  559. end;
  560.  
  561.  
  562. function "+" (X    : SIXTEEN_BITS ; Y : MODULAR) return MODULAR is
  563. begin
  564.   RETURN(MODULAR_CONVERT(X) + Y) ;
  565. end;
  566.  
  567.  
  568. function "+" ( X : MODULAR; 
  569.                Y : SIXTEEN_BITS ) return MODULAR is
  570. begin
  571.   RETURN(MODULAR_CONVERT(Y) + X) ;
  572. end;
  573.  
  574.  
  575. function "+" ( X : THIRTYTWO_BITS  ;
  576.                Y : MODULAR) return MODULAR is
  577. begin
  578.   RETURN(MODULAR_CONVERT(X) + Y) ;
  579. end;
  580.  
  581.  
  582. function "+" (X    : MODULAR;Y : THIRTYTWO_BITS  ) return MODULAR is
  583. begin
  584.   RETURN(MODULAR_CONVERT(Y) + X) ;
  585. end;
  586.  
  587.  
  588.  
  589. function "+" (X,Y: MODULAR) return MODULAR is
  590. Z : MODULAR;
  591. CARRY : INTEGER := 0 ;
  592. begin
  593. Z.LOW := X.LOW + Y.LOW;
  594. IF Z.LOW >= 2**16 THEN          -- CARRY
  595.   Z.LOW := Z.LOW - 2**16 ;
  596.   CARRY := 1 ;
  597. END IF ;
  598. Z.HI := (Y.HI + X.HI + CARRY) MOD 2**16 ;
  599. return Z;
  600. end; 
  601.  
  602. function "<=" (X,Y : MODULAR) return BOOLEAN is
  603. begin
  604. if X.HI = Y.HI then
  605.   RETURN X.LOW <= Y.LOW ;
  606. elsif (X.HI -  Y.HI) > 2**15  then   -- we wrapped around
  607.   if X.HI > Y.HI  then                 -- Y wrapped around
  608.     return (TRUE) ;
  609.   else
  610.     return (FALSE) ;
  611.   end if ;
  612. else
  613.   return (X.HI <= Y.HI) ;
  614. end if ;
  615. end;
  616.  
  617.  
  618.  
  619. function ">=" (X,Y : MODULAR) return BOOLEAN is
  620. begin
  621. if X.HI = Y.HI then
  622.   RETURN X.LOW >= Y.LOW ;
  623. elsif (X.HI -  Y.HI) > 2**15  then   -- we wrapped around
  624.   if X.HI < Y.HI  then                 -- Y wrapped around
  625.     return (TRUE) ;
  626.   else
  627.     return (FALSE) ;
  628.   end if ;
  629. else
  630.   return (X.HI >= Y.HI) ;
  631. end if ;
  632. end;
  633.  
  634.  
  635.  
  636. function "<" (X,Y : MODULAR) return BOOLEAN is
  637. begin
  638. return(not (X >= Y)) ;
  639. end;
  640.  
  641.  
  642. function ">" (X,Y : MODULAR) return BOOLEAN is
  643. begin
  644. return(not (X <= Y)) ;
  645. end;
  646.  
  647.  
  648.  
  649. function "-" ( X : MODULAR; 
  650.                Y : SIXTEEN_BITS ) return MODULAR is
  651.  
  652. begin
  653. return(X - MODULAR_CONVERT(Y)) ;
  654. end;
  655.  
  656.  
  657. function "-" (X, Y : MODULAR) return MODULAR is
  658. Z : MODULAR ;
  659. BORROW : INTEGER := 0 ;
  660. begin
  661. Z.LOW := X.LOW - Y.LOW ;
  662. if Z.LOW < 0 then
  663.   Z.LOW := Z.LOW + 2**16 ;    -- BORROW
  664.   BORROW := 1 ;
  665.   end if ;
  666. Z.HI := (X.HI - Y.HI - BORROW) ;
  667. IF Z.HI < 0 THEN
  668.   Z.HI := 2**16 - ABS(Z.HI) ; 
  669. END IF ;
  670. RETURN (Z) ;
  671. end;
  672.  
  673. end MODULO;
  674. --::::::::::::::
  675. --rtclkdate_.ada
  676. --::::::::::::::
  677. -----------------------------------------------------------------------
  678. --
  679. --         DoD Protocols    NA-00001-200       80-01006-100(-)
  680. --         E-Systems, Inc.  August 07, 1985
  681. --
  682. --         RTCLKDATE_.ADA       Author : Jim Baldo
  683. --
  684. -----------------------------------------------------------------------
  685. with CALENDAR;            use CALENDAR;
  686. with TEXT_IO;            use TEXT_IO;
  687. with BUFFER_DATA ;        use BUFFER_DATA ;
  688.  
  689.             package REAL_TIME_CLOCK_AND_DATE is
  690.  
  691.         ----------------------------------------------------
  692.         --This implementation is for use with the DEC/ADA --
  693.         --compiler.                                       --
  694.         ----------------------------------------------------
  695.  
  696. -------------------------------------------------------------------------------
  697. --This package will provide the user with the local time of day in           --
  698. --hundred's of seconds.                                                      --
  699. --                                                                           --
  700. --J. Baldo 17-Jan_85                                                         --
  701. -------------------------------------------------------------------------------
  702.  
  703. subtype DAY_TYPE is positive range 1..31;
  704.  
  705. subtype MONTH_TYPE is positive range 1..12;
  706.  
  707. subtype YEAR_TYPE is THIRTYTWO_BITS ;
  708.  
  709. type DATE_TYPE is 
  710.  record
  711.   DAY : DAY_TYPE;
  712.   MONTH : MONTH_TYPE;
  713.   YEAR : YEAR_TYPE;
  714.  end record;
  715.  
  716. --TEL subtype TIME_TYPE is INTEGER;
  717. subtype TIME_TYPE is DAY_DURATION;
  718.  
  719. function SYSTEM_TIME return TIME_TYPE;
  720.  
  721.     --This function will return the CPU time in milliseconds.
  722.  
  723. function SYSTEM_DATE return DATE_TYPE;
  724.  
  725.     --This function returns the day, month , and year , that
  726.     --is currently set by the system.
  727.  
  728. end REAL_TIME_CLOCK_AND_DATE;
  729.  
  730. --::::::::::::::
  731. --rtclkdate.ada
  732. --::::::::::::::
  733. -----------------------------------------------------------------------
  734. --
  735. --         DoD Protocols    NA-00001-200       80-01007-100(-)
  736. --         E-Systems, Inc.  August 07, 1985
  737. --
  738. --         RTCLKDATE.ADA       Author : Jim Baldo
  739. --
  740. -----------------------------------------------------------------------
  741. with TEXT_IO;            use TEXT_IO;
  742.  
  743.         package body REAL_TIME_CLOCK_AND_DATE is
  744.  
  745.  
  746. function SYSTEM_TIME return TIME_TYPE is
  747.  
  748. --Implementation restriction : for VAX implementation the time will be obtained
  749. --                             in hundred's of seconds.
  750.  
  751. --TEL SYSTEM_TIME_FROM_CLOCK : TIME;
  752. --TEL RESULT : ERROR_CLASS;--will be implemented later to achieve dynamic error 
  753. --TEL                      --checking
  754.  
  755. begin
  756. --TEL  GET_TIME(SYSTEM_TIME_FROM_CLOCK,RESULT);
  757. --TEL  return SYSTEM_TIME_FROM_CLOCK.TICKS_SINCE_MIDNIGHT;
  758.  return SECONDS(CLOCK);
  759. end SYSTEM_TIME;
  760.  
  761. function SYSTEM_DATE return DATE_TYPE is
  762.  
  763. SECONDS : DAY_DURATION;
  764. CURRENT_SYSTEM_DATE : DATE_TYPE;
  765. --TEL SYSTEM_TIME_FROM_CLOCK : TIME;
  766. --TEL RESULT : ERROR_CLASS;--will be implemented later to achieve dynamic error 
  767. --TEL                      --checking
  768.  
  769. begin
  770. --TEL  GET_TIME(SYSTEM_TIME_FROM_CLOCK,RESULT);
  771. --TEL  CURRENT_SYSTEM_DATE := (SYSTEM_TIME_FROM_CLOCK.DAY,
  772. --TEL                          SYSTEM_TIME_FROM_CLOCK.MONTH,
  773. --TEL                          SYSTEM_TIME_FROM_CLOCK.YEAR);
  774.  SPLIT (CLOCK,  --get time from system clock
  775.         CURRENT_SYSTEM_DATE.YEAR,
  776.         CURRENT_SYSTEM_DATE.MONTH,
  777.         CURRENT_SYSTEM_DATE.DAY,
  778.         SECONDS);
  779.  return CURRENT_SYSTEM_DATE;
  780. end SYSTEM_DATE;
  781.  
  782. end REAL_TIME_CLOCK_AND_DATE;
  783. --::::::::::::::
  784. --ip_tcp_.ada
  785. --::::::::::::::
  786. -----------------------------------------------------------------------
  787. --
  788. --         DoD Protocols    NA-00001-200       80-00997-100(-)
  789. --         E-Systems, Inc.  August 07, 1985
  790. --
  791. --         IP_TCP_.ADA       Author : Jim Baldo
  792. --
  793. -----------------------------------------------------------------------
  794. with IP_GLOBALS;                use IP_GLOBALS;
  795. with BUFFER_DATA;                use BUFFER_DATA;
  796.  
  797.             package IP_TCP is
  798.  
  799.         ---------------------------------------
  800.         --This implementation is for the     --
  801.         --DEC/Ada compiler .                 --
  802.         ---------------------------------------
  803.  
  804. subtype Q_ITEM is IP_MESSAGE ;
  805.  
  806. task IP_FROM_TCP is
  807.  entry Q_ADD ( ITEM : in Q_ITEM ) ;
  808.  entry Q_GET ( ITEM : in out Q_ITEM ) ;
  809. end IP_FROM_TCP ;
  810.  
  811. end IP_TCP ; 
  812. --::::::::::::::
  813. --ip_tcp.ada
  814. --::::::::::::::
  815. -----------------------------------------------------------------------
  816. --
  817. --         DoD Protocols    NA-00001-200       80-00998-100(-)
  818. --         E-Systems, Inc.  August 07, 1985
  819. --
  820. --         IP_TCP.ADA       Author : Jim Baldo
  821. --
  822. -----------------------------------------------------------------------
  823. with TEXT_IO;                use TEXT_IO;
  824.  
  825.             package body IP_TCP is
  826.  
  827.         ---------------------------------------
  828.         --This implementation is for the     --
  829.         --DEC/Ada compiler .                 --
  830.         ---------------------------------------
  831.  
  832. package INT_IO is new INTEGER_IO( SIXTEEN_BITS ) ;
  833.  
  834. type QUEUE_ELEMENT;
  835. type QUEUE_ELEMENT_POINTER is access QUEUE_ELEMENT;
  836. type QUEUE_ELEMENT is
  837.  record
  838.   ELEMENT : Q_ITEM;
  839.   NEXT : QUEUE_ELEMENT_POINTER;
  840.  end record;
  841.  
  842. type QHEADS is 
  843.  record
  844.   ELEMENT_COUNT : SIXTEEN_BITS  := 0;
  845.   FIRST_ELEMENT : QUEUE_ELEMENT_POINTER;
  846.   LAST_ELEMENT  : QUEUE_ELEMENT_POINTER;
  847.  end record;
  848.  
  849. TO_IP_QUEUE : QHEADS ; --queue for IP
  850. MAX_QUEUE_SIZE : constant SIXTEEN_BITS  := 32;
  851. NUMBER_OF_QUEUES : constant SIXTEEN_BITS  := 1;
  852. QUEUE_FREE_LIST : QUEUE_ELEMENT_POINTER;
  853.  
  854. function QUEUE_EMPTY return BOOLEAN is
  855.  
  856. RESULT : BOOLEAN := FALSE;
  857.  
  858. begin
  859.  if TO_IP_QUEUE.ELEMENT_COUNT = 0 then
  860.   RESULT := TRUE;
  861.  end if;
  862.  return RESULT;
  863. end QUEUE_EMPTY;
  864.  
  865. function QUEUE_FULL return BOOLEAN is
  866.  
  867. RESULT : BOOLEAN := FALSE ;
  868.  
  869. begin 
  870.  if TO_IP_QUEUE.ELEMENT_COUNT = MAX_QUEUE_SIZE then
  871.   RESULT := TRUE ;
  872.  end if;
  873.  return RESULT ;
  874. end QUEUE_FULL ;
  875.  
  876. function GET_Q_STRUCTURE return QUEUE_ELEMENT_POINTER is
  877.  
  878. X : QUEUE_ELEMENT_POINTER;
  879.  
  880. begin
  881.  X := QUEUE_FREE_LIST;
  882.  QUEUE_FREE_LIST := QUEUE_FREE_LIST.NEXT;
  883.  return X;
  884. exception
  885.  when CONSTRAINT_ERROR =>
  886.   PUT_LINE("CONSTRAINT ERROR IN COMM WITH IP GET_Q_STRUCTURE");
  887.  when others =>
  888.   PUT_LINE("UNKNOWN ERROR RAISED IN COMM. WITH IP GET_Q_STRUCTURE");
  889. end GET_Q_STRUCTURE;
  890.  
  891. procedure FREE_Q_STRUCTURE(Q_STRUCTURE : in out QUEUE_ELEMENT_POINTER) is
  892.  
  893. begin
  894.  Q_STRUCTURE.NEXT := QUEUE_FREE_LIST;
  895.  QUEUE_FREE_LIST := Q_STRUCTURE; --ADDS TO FRONT OF LIST
  896.  -- MAKE THE POINTER NULL NOW.
  897.  Q_STRUCTURE := null;
  898. exception
  899.  when CONSTRAINT_ERROR =>
  900.   PUT_LINE("CONSTRAINT ERROR IN FREE_Q_STRUCTURE");
  901.  when others =>
  902.   PUT_LINE("UNKNOWN ERROR RAISED IN FREE_Q_STRUCTURE");
  903. end FREE_Q_STRUCTURE;
  904.  
  905. procedure QUEUE_GET ( ITEM : out Q_ITEM) is
  906.  
  907. Q_ELEMENT_TO_BE_FREED : QUEUE_ELEMENT_POINTER;
  908.  
  909. begin
  910.  if TO_IP_QUEUE.ELEMENT_COUNT > 0 then
  911.   TO_IP_QUEUE.ELEMENT_COUNT := TO_IP_QUEUE.ELEMENT_COUNT - 1;
  912.   Q_ELEMENT_TO_BE_FREED := TO_IP_QUEUE.FIRST_ELEMENT;
  913.   ITEM := TO_IP_QUEUE.FIRST_ELEMENT.ELEMENT;
  914.   TO_IP_QUEUE.FIRST_ELEMENT := TO_IP_QUEUE.FIRST_ELEMENT.NEXT;
  915.   if TO_IP_QUEUE.ELEMENT_COUNT = 0 then 
  916.    -- AN EMPTY LIST
  917.    TO_IP_QUEUE.LAST_ELEMENT := null;
  918.   end if;
  919.   FREE_Q_STRUCTURE(Q_ELEMENT_TO_BE_FREED);   -- FREE UP THE FORMER FIRST ELEMENT
  920.  else -- AN EMPTY LIST
  921.   PUT_LINE("A QGET ATTEMPT ON AN EMPTY LIST");
  922.  end if;
  923. exception
  924.  when CONSTRAINT_ERROR =>
  925.   PUT_LINE("CONSTRAINT ERROR IN QGET");
  926.  when others =>
  927.   PUT_LINE("UNKNOWN  ERROR IN QUEUE_GET");
  928. end QUEUE_GET;
  929.  
  930. procedure QUEUE_ADD ( ITEM : Q_ITEM) is
  931.  
  932. NEW_ITEM : QUEUE_ELEMENT_POINTER := GET_Q_STRUCTURE;
  933.  
  934. begin
  935.  NEW_ITEM.ELEMENT := ITEM;
  936.  NEW_ITEM.NEXT := null;
  937.  if TO_IP_QUEUE.ELEMENT_COUNT < MAX_QUEUE_SIZE then
  938.   if TO_IP_QUEUE.ELEMENT_COUNT /= 0 then 
  939.    -- ITS NOT AN EMPTY QUEUE. SO LINK FORMER
  940.    -- LAST ITEM TO NEW ONE.
  941.    TO_IP_QUEUE.LAST_ELEMENT.NEXT := NEW_ITEM;
  942.   else -- FIRST ADD TO THE QUEUE
  943.    TO_IP_QUEUE.FIRST_ELEMENT := NEW_ITEM;
  944.   end if;
  945.   TO_IP_QUEUE.LAST_ELEMENT := NEW_ITEM;
  946.   TO_IP_QUEUE.ELEMENT_COUNT := TO_IP_QUEUE.ELEMENT_COUNT + 1;
  947.  else -- NO ROOM TOO BAD. PUT Q STRUCTURE 
  948.       -- ON THE FREE LIST.
  949.   FREE_Q_STRUCTURE(NEW_ITEM);
  950.  end if;
  951. exception
  952.  when CONSTRAINT_ERROR =>
  953.   PUT_LINE("CONSTRAINT ERROR IN QUEUE ADD");
  954.  when others =>
  955.   PUT_LINE("ERROR IN QADD");
  956.   INT_IO.PUT(TO_IP_QUEUE.ELEMENT_COUNT);
  957. end QUEUE_ADD;
  958.  
  959. task body IP_FROM_TCP is
  960.  
  961. begin
  962.  loop
  963.   select
  964.    when not QUEUE_FULL =>
  965.     accept Q_ADD ( ITEM : in Q_ITEM ) do
  966.      QUEUE_ADD ( ITEM ) ;
  967.     end Q_ADD ;
  968.   or
  969.    when not QUEUE_EMPTY =>
  970.     accept Q_GET ( ITEM : in out Q_ITEM ) do
  971.      QUEUE_GET ( ITEM ) ;
  972.     end Q_GET ;
  973.   end select ;
  974.  end loop ;
  975. end IP_FROM_TCP ;
  976.  
  977. procedure INITIALIZE_QUEUES is
  978.  
  979. --This subprogram allocates and links together in a list (pointed to by
  980. --queue_free_list) of queue elements to be used by all of the queue
  981. --routines. It allocates them via new. They are never deallocated.
  982. --they are simply put back in the free queue element list.
  983. --the max queue size times the number of queues is the number of queue
  984. --elements that are allocated.
  985.  
  986.  NEXT_STRUCTURE : QUEUE_ELEMENT_POINTER;
  987.  
  988. begin
  989.  QUEUE_FREE_LIST := new QUEUE_ELEMENT;
  990.  NEXT_STRUCTURE :=  new QUEUE_ELEMENT;
  991.  QUEUE_FREE_LIST.NEXT := NEXT_STRUCTURE;
  992.  for I in 3..MAX_QUEUE_SIZE * NUMBER_OF_QUEUES loop
  993.   -- SET UP A FREE LIST OF QUEUE STRUCTURES.
  994.   NEXT_STRUCTURE.NEXT := new QUEUE_ELEMENT;
  995.   NEXT_STRUCTURE := NEXT_STRUCTURE.NEXT;
  996.  end loop;
  997. end INITIALIZE_QUEUES;
  998.  
  999. begin
  1000.  
  1001.  INITIALIZE_QUEUES ;
  1002.  
  1003. end IP_TCP ;
  1004. --::::::::::::::
  1005. --subnet_calls_.ada
  1006. --::::::::::::::
  1007. -----------------------------------------------------------------------
  1008. --
  1009. --         DoD Protocols    NA-00001-200       80-01012-100(-)
  1010. --         E-Systems, Inc.  August 07, 1985
  1011. --
  1012. --         SUBNET_CALLS_.ADA       Author : Jim Baldo
  1013. --
  1014. -----------------------------------------------------------------------
  1015.      
  1016. with BUFFER_DATA;               use BUFFER_DATA;
  1017. with IP_GLOBALS;                use IP_GLOBALS;
  1018.      
  1019.                            package SUBNET_CALLS is
  1020.                 -------------------------------------------------
  1021.                 --This implementation version is for use with  --
  1022.                 --DEC/Ada                                      --
  1023.                 -------------------------------------------------
  1024.      
  1025. -----------------------------------------------------------------------------
  1026. --This package contains procedure calls and data structures necessary for  --
  1027. --the Internet Protocol Group and the Subnet Protocol Group to communicate.--
  1028. -----------------------------------------------------------------------------
  1029.      
  1030. task SNP is
  1031.      
  1032. pragma priority(14) ;
  1033.      
  1034.  entry SEND( DATAGRAM          : in out PACKED_BUFFER_PTR;
  1035.              LOCAL_DESTINATION : in     LOCAL_ADDRESS_TYPE ;
  1036.              PRECEDENCE        : in     PRECEDENCE_TYPE;
  1037.              RELIABILITY       : in     RELIABILITY_TYPE;
  1038.              DELAY_IP          : in     DELAY_TYPE;
  1039.              THROUGHPUT        : in     THROUGHPUT_TYPE;
  1040.              LENGTH            : in     DATAGRAM_LENGTH) ;
  1041.      
  1042.      
  1043.         --This entry sends a datagram to the subnet for transmit.
  1044.         --Fully compatible with MIL-STD 1777.
  1045.      
  1046.   entry DELIVER( DATAGRAM : out PACKED_BUFFER_PTR);
  1047.      
  1048.         --This entry requests for a datagram from the subnet.  If
  1049.         --the pointer is null, the subnet queue is empty.  Fully compatible
  1050.         --with MIL-STD 1777.
  1051.      
  1052.   entry SEND_TO_IP( DATAGRAM : in out PACKED_BUFFER_PTR);
  1053.      
  1054.  end SNP;
  1055.      
  1056.      
  1057. procedure start_subnet_driver ;
  1058.      
  1059. end SUBNET_CALLS;
  1060.      
  1061. --::::::::::::::
  1062. --subnet_calls.ada
  1063. --::::::::::::::
  1064. -----------------------------------------------------------------------
  1065. --
  1066. --         DoD Protocols    NA-00001-200       80-01013-100(-)
  1067. --         E-Systems, Inc.  August 07, 1985
  1068. --
  1069. --         SUBNET_CALLS.ADA       Author : Jim Baldo
  1070. --
  1071. -----------------------------------------------------------------------
  1072. with system;  use system ;
  1073. with starlet; use starlet;
  1074. with condition_handling ; use condition_handling ;
  1075. with unchecked_conversion ;
  1076. with tasking_services; use tasking_services;
  1077. with text_io ; use text_io ;
  1078.      
  1079.      
  1080.      
  1081. package body SUBNET_CALLS is
  1082.      
  1083. -------------------------------------------------
  1084. --This implementation version is for use with  --
  1085. --DEC/Ada and ethernet                         --
  1086. -------------------------------------------------
  1087.      
  1088.      
  1089.      
  1090. -------------------------------------------------------------------------------
  1091. --
  1092. -- subnet driver routines
  1093. --
  1094. -------------------------------------------------------------------------------
  1095. --
  1096.      
  1097. -- for passing addresses as long integers in qio calls:
  1098.      
  1099. function physical_address is
  1100.   new unchecked_conversion(address,unsigned_longword) ;
  1101.      
  1102. -- ethernet subnet driver routines
  1103.      
  1104. ret_status : condition_handling.cond_value_type ;
  1105. deuna_number : channel_type ;
  1106. enet_iosb    : iosb_type ;
  1107. bufaddr      : unsigned_longword ;
  1108. buflen       : unsigned_longword ;
  1109. devname      : device_name_type (1..4) := "XEA0" ;
  1110.      
  1111. type ethernet_address is array (1..8) of SYSTEM_byte ;
  1112. type host_ethernet_pair is record
  1113.   host_number : local_address_type ;
  1114.   local_addr  : ethernet_address ;
  1115.   end record ;
  1116.      
  1117. address_table : array (1..max_hosts) of host_ethernet_pair
  1118.              := ( (1,   (16#AA#,16#00#,16#04#,16#00#,          -- vax saturn
  1119.                          16#01#,16#04#,16#00#,16#00#)) ,
  1120.                   (2,   (16#AA#,16#00#,16#04#,16#00#,          -- vax mars
  1121.                          16#02#,16#04#,16#00#,16#00#)) ,
  1122.                   (3,   (16#02#,16#60#,16#8c#,16#00#,          -- unused
  1123.                          16#79#,16#42#,16#00#,16#00#)) ,
  1124.                   (128, (16#00#,16#00#,16#00#,16#00#,          -- unused
  1125.                          16#00#,16#00#,16#00#,16#00#))) ;
  1126.      
  1127. subtype zero is THIRTYTWO_BITS ;
  1128.      
  1129. pad  : array (1..512) of zero ;
  1130.      
  1131. --
  1132. --  ethernet setup characteristics
  1133. --
  1134.      
  1135. type parm_block_type is record
  1136.   number_of_buffers : SIXTEEN_BITS := 16#451# ;  -- nma_c_plci_bfn
  1137.   number_1          : unsigned_longword := 1 ;
  1138.   protocol_type     : SIXTEEN_BITS :=  16#B0E# ; -- nma_c_plci_pty
  1139.   non_decnet        : unsigned_longword := 16#6006# ;
  1140. end record ;
  1141.      
  1142. parm_block : parm_block_type ;
  1143.      
  1144. type parm_descriptor_type is record
  1145.   parm_length  : unsigned_longword := parm_block'size / 8 ;  -- in bytes
  1146.   parm_addr    : system.address    := parm_block'address ;
  1147.   end record ;
  1148.      
  1149. parm_descriptor : parm_descriptor_type ;
  1150.      
  1151.      
  1152.      
  1153. --
  1154. -- The actual i/o tasks for reading....
  1155. --
  1156.      
  1157. task ethernet_read_task is
  1158.   pragma priority (12) ;
  1159.   entry start ;
  1160. end  ethernet_read_task ;
  1161.      
  1162. task body ethernet_read_task is
  1163. response_buffer, response_buffer1 : packed_buffer_ptr ;
  1164. begin
  1165.   accept start ;
  1166.   buffget(response_buffer,0) ;
  1167.   loop
  1168.     task_qiow (
  1169.          status       => ret_status,
  1170.          chan         => deuna_number,
  1171.          func         => io_readvblk,
  1172.          p1           => physical_address(response_buffer.byte'address),
  1173.          p2           => 512,
  1174.          iosb         => enet_iosb) ;
  1175.     if not condition_handling.success(ret_status) then
  1176.       put_line("QIOW GET FROM ETHERNET ERROR") ;
  1177.       signal(ret_status) ;
  1178.     end if ;
  1179.     ret_status := unsigned_longword(enet_iosb.status) ;
  1180.     if not condition_handling.success(ret_status) then
  1181.       signal(ret_status) ;
  1182.     end if ;
  1183.     buffget(response_buffer1,0) ;    -- get a free one before giving up old one
  1184.     if response_buffer1 /= null then
  1185.       response_buffer.size := SIXTEEN_BITS (enet_iosb.count) ;
  1186.       response_buffer.ip_ptr := 1 ;
  1187.       snp.send_to_ip(response_buffer) ;
  1188.       response_buffer := response_buffer1 ;
  1189.     else
  1190.       put_line("LOST ETHERNET PACKET -- OUT OF BUFFERS") ;  -- debug
  1191.     end if ;
  1192.   end loop ;
  1193. exception
  1194.   when others =>
  1195.     put_line ("EXCEPTION IN ETHERNET READ TASK") ;
  1196. end ethernet_read_task ;
  1197.      
  1198.      
  1199. --
  1200. -- writing to the subnet is done directly, without a buffer
  1201. --
  1202.      
  1203. procedure subnet_put (buf : in out packed_buffer_ptr;
  1204.                       adr : in     local_address_type;
  1205.                       len : in     datagram_length) is
  1206. adr_address : system.address ;
  1207. adr_valid   : boolean := false ;
  1208.   begin
  1209.     for i in 1..max_hosts loop
  1210.       if address_table(i).host_number = adr then
  1211.         adr_address := address_table(i).local_addr'address ;
  1212.         adr_valid := true ;
  1213.         exit ;
  1214.       end if ;
  1215.     end loop ;
  1216.     if adr_valid then
  1217.       task_qiow(
  1218.          status => ret_status,
  1219.          chan => deuna_number,
  1220.          func => starlet.io_writevblk,
  1221.          iosb => enet_iosb,
  1222.          p1 => physical_address(buf.byte(buf.subnet_ptr)'address) ,
  1223.          p2 => unsigned_longword(len),
  1224.          p5 => physical_address(adr_address)) ;
  1225.     if not condition_handling.success(ret_status) then
  1226.       put_line("QIOW PUT TO ETHERNET ERROR") ;
  1227.       signal(ret_status) ;
  1228.     end if ;
  1229.     ret_status := unsigned_longword(enet_iosb.status) ;
  1230.     if not condition_handling.success(ret_status) then
  1231.       signal(ret_status) ;
  1232.     end if ;
  1233.     BUF.IN_USE := FALSE;
  1234.     buffree(buf,0) ;
  1235. --    put_line("put ok") ;
  1236.   else
  1237.     put_line("INVALID ADDRESS TO ETHERNET PUT") ;  -- for debug
  1238.   end if ;
  1239.   end ;
  1240.      
  1241.      
  1242. --
  1243. -- Interface to the users of this stuff
  1244. --
  1245.      
  1246.      
  1247. task body SNP is
  1248.      
  1249. buffer_size : constant := 16 ;
  1250. type dg_array is array (0..buffer_size) of packed_buffer_ptr ;
  1251.      
  1252. type buffer_type is record
  1253.   put : THIRTYTWO_BITS range 0..buffer_size := 0 ;
  1254.   get : THIRTYTWO_BITS range 0..buffer_size := 0 ;
  1255.   val : dg_array ;
  1256.   end record ;
  1257.      
  1258. buffer : buffer_type ;
  1259.      
  1260.  begin
  1261.    loop
  1262.    select
  1263.      when (buffer.put /= buffer.get) =>
  1264.         accept deliver( datagram : OUT packed_buffer_ptr) do
  1265.           datagram := buffer.val(buffer.get) ;
  1266.           buffer.get := (buffer.get + 1) mod buffer_size ;
  1267.           end deliver ;
  1268.    or
  1269.      accept send( datagram           : in out packed_buffer_ptr;
  1270.                  local_destination   : in     local_address_type;
  1271.                  precedence          : in     precedence_type;
  1272.                  reliability         : in     reliability_type;
  1273.                  delay_ip            : in     delay_type;
  1274.                  throughput          : in     throughput_type;
  1275.                  length              : in     datagram_length)
  1276.         do
  1277.           subnet_put(datagram, local_destination, length) ;
  1278.           end send ;
  1279.     or
  1280.       accept send_to_ip(datagram : in out packed_buffer_ptr) do
  1281.           if buffer.get /= (buffer.put + 1) mod buffer_size then
  1282.             buffer.val(buffer.put)  := datagram ;
  1283.             buffer.put := (buffer.put + 1) mod buffer_size ;
  1284.           else
  1285.             put_line("LOST AN ETHERNET PACKET -- NO QUEUE SPACE ") ;
  1286.             DATAGRAM.IN_USE := FALSE;
  1287.             buffree(datagram,0) ;
  1288.           end if ;
  1289.         end send_to_ip ;
  1290.      end select ;
  1291.   end loop ;
  1292. exception
  1293.   when others =>
  1294.     put_line (" EXCEPTION IN SUBNET INTERFACE PACKAGE - SNP ") ;
  1295.      
  1296.  end SNP;
  1297.      
  1298.      
  1299.      
  1300. --
  1301. -- package initialization
  1302. --
  1303.      
  1304. procedure start_subnet_driver is
  1305.      
  1306. begin
  1307.  put_line("assign deuna...") ;
  1308.  starlet.assign(
  1309.     status  => ret_status,
  1310.     devnam  => devname,
  1311.     chan    => deuna_number) ;
  1312.      
  1313.   if not condition_handling.success(ret_status) then
  1314.     put_line("COULD NOT ASSIGN DEUNA") ;
  1315.     signal(ret_status) ;
  1316.   end if ;
  1317.      
  1318.      
  1319.  put_line("start deuna...") ;
  1320.   starlet.qiow(
  1321.      status => ret_status,
  1322.      chan => deuna_number,
  1323.      func => IO_setmode+io_m_ctrl+io_m_startup,
  1324.      p2 => physical_address(parm_descriptor'address),
  1325.      iosb => enet_iosb );
  1326.   if not condition_handling.success(ret_status) then
  1327.     put_line("COULD NOT INITIALIZE DEUNA") ;
  1328.     signal(ret_status) ;
  1329.   end if ;
  1330.      
  1331.   ret_status := unsigned_longword(enet_iosb.status) ;
  1332.   if not condition_handling.success(ret_status) then
  1333.     signal(ret_status) ;
  1334.   end if ;
  1335.      
  1336.  put_line("deuna initialized") ;
  1337.      
  1338.  ethernet_read_task.start ;
  1339.      
  1340. exception
  1341.   when others =>
  1342.     put_line (" EXCEPTION IN START_SUBNET_DRIVER") ;
  1343.      
  1344.      
  1345. end start_subnet_driver ;
  1346.      
  1347. begin
  1348. null ;
  1349.      
  1350. exception
  1351.   when others =>
  1352.     put_line (" EXCEPTION IN SUBNET INTERFACE PACKAGE INITIALIZTION") ;
  1353.      
  1354. end SUBNET_CALLS;
  1355. --::::::::::::::
  1356. --tcpglbdat_.ada
  1357. --::::::::::::::
  1358. -----------------------------------------------------------------------
  1359. --
  1360. --         DoD Protocols    NA-00001-200       80-01016-100(-)
  1361. --         E-Systems, Inc.  August 07, 1985
  1362. --
  1363. --         TCPGLBDAT_.ADA       Author : Jim Baldo
  1364. --
  1365. -----------------------------------------------------------------------
  1366. with STARLET ;            use STARLET ;
  1367. with MODULO;            use MODULO;
  1368. with IP_GLOBALS;        use IP_GLOBALS;
  1369. with BUFFER_DATA;        use BUFFER_DATA;
  1370.  
  1371.         package T_TCP_GLOBALS_DATA_STRUCTURES is
  1372.  
  1373.     -----------------------------------------------------------
  1374.     --This implementation is for use with the DEC/Ada        --
  1375.     --compiler .                                             --
  1376.     -----------------------------------------------------------
  1377.  
  1378. --*****************************************************************************
  1379. --*Implementation Restrictions                                                *
  1380. --*---------------------------                                                *
  1381. --* Some of these types could have their bit size set when the compiler       *
  1382. --* is able to do it.                                                         *
  1383. --*****************************************************************************
  1384.  
  1385.     TABLE_RANGE : constant SIXTEEN_BITS  := 32;
  1386.     subtype ERROR_TYPE is SIXTEEN_BITS ;
  1387.     type STATUS_TYPE is 
  1388.         (CONNECTION_OPEN, CONNECTION_CLOSED, OPENING, CLOSING);
  1389.     type ACKPASS is (PASSIVE, ACTIVE);
  1390.     type TIMER_TYPE is (TIME_WAIT_TIMER, RETRANS_TIMER, TIMEOUT_TIMER);
  1391.     type HEADER_TYPE is 
  1392.         (ACK, SYN, SYN_ACK, SEGMENT, SEG_ACK, FIN, RST, RST_ACK);
  1393.     type STATES is (CLOSED,SYN_SENT,SYN_RECEIVED,ESTABLISHED,LISTEN,
  1394.         FIN_WAIT_1,CLOSE_WAIT,FIN_WAIT_2,CLOSING,TIME_WAIT,LAST_ACK);
  1395.     type SECURE is array(1..9) of SIXTEEN_BITS ; 
  1396.                     -- EACH ELEMENT OF THIS ARRAY IS ONE
  1397.                        -- OCTET OF SECURITY OPTION INFO. AFTER
  1398.                        -- THE TYPE AN LENGTH FIELD.
  1399.     type TABLE_TYPE is array(1..TABLE_RANGE) of SIXTEEN_BITS ;
  1400.     type TIME_ACTION is (NONE, RETRANSMIT_TIMEOUT, CONNECTION_TIMEOUT, 
  1401.              TIME_WAIT_TIMEOUT);
  1402.     subtype    WND_PORT is SIXTEEN_BITS ; -- THE ACTUAL RANGE IS + OR - 2**16 - 1
  1403.     subtype    SEVEN_BITS is SIXTEEN_BITS ;
  1404.     subtype    TEN_BITS is SIXTEEN_BITS ;
  1405.     subtype    TWO_BITS is INTEGER;
  1406.     subtype    FOUR_OCTETS is THIRTYTWO_BITS ;
  1407.     subtype    TWO_OCTETS is SIXTEEN_BITS ;
  1408.     subtype    ONE_OCTET is SIXTEEN_BITS ;
  1409.     subtype    HALF_OCTET is SIXTEEN_BITS ;
  1410.     subtype    SIX_BITS is SIXTEEN_BITS ;
  1411.     subtype    ONE_BIT    is SIXTEEN_BITS ;
  1412.  
  1413.     type BUFFER_POINTER is
  1414.         record
  1415.             BTYPE :    SIXTEEN_BITS ;
  1416.             DATA_LEN : SIXTEEN_BITS  := 0;
  1417.             SOURCE_PORT : TWO_OCTETS;
  1418.             DESTINATION_PORT : TWO_OCTETS;
  1419.             SEQ_NUM    : MODULAR;
  1420.             ACK_NUM    : MODULAR;
  1421.             DATA_OFFSET : HALF_OCTET;
  1422.             RESERVED : SIX_BITS;
  1423.             URG_FLAG : ONE_BIT;
  1424.             ACK : ONE_BIT;
  1425.             PUSH_FLAG : ONE_BIT;
  1426.             RST : ONE_BIT;     
  1427.             SYN : ONE_BIT;
  1428.             FIN : ONE_BIT;
  1429.             WINDOW : TWO_OCTETS;
  1430.             TCP_CSUM : TWO_OCTETS;
  1431.             URG_PTR    : TWO_OCTETS;
  1432.                   --OPTIONS FOR TCP
  1433.             TCP_OPTIONS : OPTION_TYPE 
  1434.                        := (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  1435.                          0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  1436.                          0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  1437.                          0);
  1438.             DATA : BUFFER_AREA;
  1439.                 -- ARRAY OF SYSTEM.BYTES. FROM USER LEVEL.
  1440.         end record;
  1441.     ERROR_TABLE_CLEAR : constant TABLE_TYPE 
  1442.                 := (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
  1443.                   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
  1444.                   0, 0, 0, 0, 0, 0, 0);
  1445.  
  1446. --*********************QUEUE TYPES******************************
  1447.     type QNAME is (TRANSMIT_QUEUE, TCP_RETRANSMIT_QUEUE, 
  1448.                TCP_RECEIVED_SEGMENT_QUEUE, RECEIVE_QUEUE,
  1449.            PROCESSED_SEGMENTS_FOR_USER_QUEUE);
  1450.  
  1451.     type STD_Q_ITEM is 
  1452.         record
  1453.             BUFFER : PACKED_BUFFER_PTR;
  1454.             UNPACKED_BUFFER : BUFFER_POINTER;
  1455.             LENGTH : SIXTEEN_BITS ;
  1456.         end record;
  1457.     type STD_QUEUE_ELEMENT;
  1458.     type STD_QUEUE_ELEMENT_POINTER is access STD_QUEUE_ELEMENT;
  1459.     type STD_QUEUE_ELEMENT is 
  1460.         record
  1461.             ELEMENT : STD_Q_ITEM;
  1462.             TIME : THIRTYTWO_BITS ; -- FOR THE RETRANSMISSION TIME.
  1463.             IP_ID : SIXTEEN_BITS ; -- THE IP ID FOR RETRANSMISSION
  1464.             NEXT : STD_QUEUE_ELEMENT_POINTER;
  1465.         end record;
  1466.     type STD_HEAD_PTR is
  1467.         record
  1468.             ELEMENT_COUNT : SIXTEEN_BITS ;
  1469.             FIRST_ELEMENT : STD_QUEUE_ELEMENT_POINTER;
  1470.             LAST_ELEMENT : STD_QUEUE_ELEMENT_POINTER;
  1471.         end record;
  1472.     type STD_QUEUE_HEAD_POINTERS is array(QNAME) of STD_HEAD_PTR;
  1473. --*********************QUEUE TYPES******************************
  1474.     NUMBER_OF_QUEUES : constant SIXTEEN_BITS  := 5;
  1475.     MAX_QUEUE_SIZE : constant SIXTEEN_BITS  := 32;
  1476.     INITIAL_QUEUE_HEADER : STD_HEAD_PTR := (0, NULL, NULL);
  1477.     INITIAL_QUEUE_HEADER_POINTERS : STD_QUEUE_HEAD_POINTERS := 
  1478.     (INITIAL_QUEUE_HEADER, INITIAL_QUEUE_HEADER, INITIAL_QUEUE_HEADER, 
  1479.      INITIAL_QUEUE_HEADER, INITIAL_QUEUE_HEADER);
  1480.  
  1481.         type TRANSMISSION_CONTROL_BLOCK;
  1482.         type TCB_PTR is access TRANSMISSION_CONTROL_BLOCK;
  1483.  
  1484.     type TRANSMISSION_CONTROL_BLOCK    is 
  1485.         record
  1486.                         TCP_CHANNEL_NAME : STRING(1..30) ;
  1487.                         TCP_CHANNEL_PTR  : CHANNEL_TYPE ;
  1488.             STATE : STATES;
  1489.             CONNECTION_STATUS : STATUS_TYPE;
  1490.             LOCAL_PORT : SIXTEEN_BITS  := -1;
  1491.             LOCAL_NET : SIXTEEN_BITS  := 0;--TEMPORARY**
  1492.             LOCAL_HOST : SIXTEEN_BITS  := 1;-- TEMPORARY**
  1493.             SOURCE_ADDRESS : THIRTYTWO_BITS  := 1;-- TEMPORARY**
  1494.             DESTINATION_ADDRESS : THIRTYTWO_BITS ;
  1495.             FOREIGN_PORT : SIXTEEN_BITS  := -1;
  1496.             FOREIGN_HOST : THIRTYTWO_BITS  := -1;
  1497.             FOREIGN_NET : THIRTYTWO_BITS  := -1;
  1498.             SND_UNA : MODULAR;
  1499.             SND_UP : MODULAR;
  1500.             SND_NXT : MODULAR;
  1501.             SND_WND : SIXTEEN_BITS  := 190;
  1502.             RCV_NXT : MODULAR;
  1503.             PRECEDENCE : SIXTEEN_BITS  := 0;
  1504.             USER_NOTIFICATION : BOOLEAN := FALSE;
  1505.             SECURITY : SECURE := (0, 0, 0, 0, 0, 0, 0, 0, 0);
  1506. --    SOURCE_PORT    : SIXTEEN_BITS ;   --    LIMITED    BITS AND RANGE IS YET TO BE DET
  1507. --    ERMINED
  1508.             BUFFSIZE : SIXTEEN_BITS ;
  1509.             RCV_BUFFER_SIZE : WND_PORT;
  1510.             RCV_URGENT_POINTER : SIXTEEN_BITS ;
  1511.             SND_WL1 : MODULAR; -- SEQ NUM OF THE  LAST SEGMENT 
  1512.                        --USED TO UPDATE SND.WND
  1513.             SND_WL2 : MODULAR;-- RECORDS THE ACK NUM OF THE 
  1514.             --LAST SEGMENT USED TO
  1515.             -- UPDATE SND.WND. THIS    VARIABLE AND THE ABOVE ONE
  1516.             -- PREVENT AN OLD SEGMENT FROM BEING USED TO UPDATE
  1517.             -- THE WINDOW.
  1518.             RCV_WINDOW : WND_PORT := 190;
  1519.             INIT_RCV_SEQ_NUM : MODULAR;
  1520.             ISS : MODULAR;-- THE INITIAL SEND SEQUENCE NUMBER (ISS)
  1521.             RETRANS_INTERVAL : SIXTEEN_BITS  := 30;  
  1522.                 -- LAST ARE PROBABLY TEMPORARY
  1523.             MAX_RETRY_OF_PACKET : SIXTEEN_BITS  RANGE 0..8;
  1524.             PROTOCOL : SIXTEEN_BITS  := 0;
  1525.                 --(PTCL) UNKNOWN VALUE FOR TCP***
  1526.             ACTIVE_PASSIVE : ACKPASS;
  1527.             CLOSE_PENDING : BOOLEAN := FALSE; 
  1528.                 -- FOR A CLOSE WITH DATA TO SEND.
  1529.             ERROR_TABLE : TABLE_TYPE := ERROR_TABLE_CLEAR;
  1530.             QHEADS : STD_QUEUE_HEAD_POINTERS 
  1531.                 := INITIAL_QUEUE_HEADER_POINTERS;
  1532.             IDENT : SIXTEEN_BITS  := -1; 
  1533.                 -- THE IDENTIFICATION NUMBER FOR AN IP DATAGRAM
  1534.             RETRANS_IDENT : SIXTEEN_BITS ; 
  1535.             -- SUPPLIED BY THE QUEUE RETRANS ROUTINE FOR IP.
  1536.             NEXT_CONNECTION_TIMEOUT : THIRTYTWO_BITS ;
  1537.             NEXT_TIME_WAIT_TIMEOUT : THIRTYTWO_BITS ;
  1538.             CONNECTION_TIMEOUT : SIXTEEN_BITS  := 180; 
  1539.                 -- DEFAULT IS 180 SECONDS OR 3 MINUTES
  1540.             CLOSE_OK_NOTIFICATION : BOOLEAN := FALSE;
  1541.                         NEXT : TCB_PTR;
  1542.     end record;
  1543.  
  1544. -- THE PSEUDO HEADER
  1545.     SOURCE, DESTINATION : THIRTYTWO_BITS ;
  1546.     PROTOCOL, IP_TOS : SIXTEEN_BITS ;
  1547.     -- THE SECURITY OPTION FROM IP
  1548.     SECURITY : SECURE;
  1549.     SECURE_CLEAR : SECURE := (0, 0, 0, 0, 0, 0, 0, 0, 0);
  1550.         
  1551.         MAX_PORTS : constant SIXTEEN_BITS  := 4;
  1552.         type PORT_LIST is array(1..MAX_PORTS) of SIXTEEN_BITS ;
  1553.  
  1554.         VALID_PORT_LIST : PORT_LIST := ( 20, 21, 23, 25);
  1555.  
  1556.     LEN, IDENT  : SIXTEEN_BITS ;
  1557.     LCN_TCB_STATE :    STATES;
  1558.     TYPE_FLAG : HEADER_TYPE;
  1559.     RESERVE : TCB_PTR;
  1560.     BIT_SET : constant SIXTEEN_BITS  := 1;
  1561.     LCN : TCB_PTR; -- THE GLOBAL LOCAL CONNECTION NAME
  1562.     OPTIONS : OPTION_TYPE;
  1563. -- THESE DECLARATIONS ARE CONSTANT IP PARAMETERS.
  1564.     ONE_MINUTE : constant SIXTEEN_BITS  := 60; --    00111100
  1565.     TOS : constant SIXTEEN_BITS  := 0; 
  1566.         --    THE VALUE FROM TCP SPEC    FOR THE    IP AS THE LOWER
  1567.                 --    LEVEL PROTOCOL.
  1568.     TTL : constant SIXTEEN_BITS  := ONE_MINUTE;
  1569.     DONT_FRAGMENT :    constant SIXTEEN_BITS  := 1; -- WE ARE NOT A GATEWAY.
  1570.     CLEAR : OPTION_TYPE 
  1571.         := (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  1572.             0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
  1573.     TCP_SECURITY_OPTIONS : OPTION_TYPE 
  1574.                 := (130,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  1575.                        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  1576.                        0,0,0,0,0,0,0,0,0,0,0,0);
  1577.  
  1578. end T_TCP_GLOBALS_DATA_STRUCTURES;
  1579. --::::::::::::::
  1580. --lcnkeep_.ada
  1581. --::::::::::::::
  1582. -----------------------------------------------------------------------
  1583. --
  1584. --         DoD Protocols    NA-00001-200       80-00999-100(-)
  1585. --         E-Systems, Inc.  August 07, 1985
  1586. --
  1587. --         LCNKEEP_.ADA       Author : Jim Baldo
  1588. --
  1589. -----------------------------------------------------------------------
  1590. with T_TCP_GLOBALS_DATA_STRUCTURES;    use T_TCP_GLOBALS_DATA_STRUCTURES;
  1591.  
  1592.             package TCB_ALLOCATOR is
  1593.  
  1594.     -----------------------------------------------------------
  1595.     --This implementation is for use with the DEC/Ada        --
  1596.     --compiler .                                             --
  1597.     -----------------------------------------------------------
  1598.  
  1599.         procedure TCB_CLEAR( LCN : in TCB_PTR);
  1600.  
  1601.             --This subprogram reintializes a TCB.
  1602.  
  1603.     procedure TCB_FREE
  1604.         (LCN :  in out TCB_PTR);
  1605.  
  1606.         --This subprogram frees a buffer to be used again.
  1607.                 --If TCB is not returned null, the TCB was not found
  1608.                 --on the TCB_IN_USE_LIST.
  1609.  
  1610.     function TCB_GET return TCB_PTR;
  1611.  
  1612.         --This subprogram obtains a buffer to be used.
  1613.                 --If TCB is returned null, the TCB_FREE_LIST resource is
  1614.                 --empty.
  1615.  
  1616.         function OBTAIN_HEAD_OF_LCN_IN_USE_QUEUE return TCB_PTR;
  1617.  
  1618.         --The function returns the head of a queue containing
  1619.         --all current active LCNs in use.
  1620.  
  1621. end TCB_ALLOCATOR;
  1622. --::::::::::::::
  1623. --lcnkeep.ada
  1624. --::::::::::::::
  1625. -----------------------------------------------------------------------
  1626. --
  1627. --         DoD Protocols    NA-00001-200       80-01000-100(-)
  1628. --         E-Systems, Inc.  August 07, 1985
  1629. --
  1630. --         LCNKEEP.ADA       Author : Jim Baldo
  1631. --
  1632. -----------------------------------------------------------------------
  1633. with STARLET ;                use STARLET ;
  1634. with BUFFER_DATA ;            use BUFFER_DATA ;
  1635. with MODULO;                use MODULO;
  1636. with UNCHECKED_CONVERSION;
  1637. with TEXT_IO;                         use TEXT_IO;
  1638. with SYSTEM;
  1639.  
  1640.         package    body TCB_ALLOCATOR is
  1641.  
  1642.   
  1643. TCB_FREE_LIST_HEAD : TCB_PTR; -- The pointer to the head of the buffer free 
  1644. TCB_FREE_LIST_BUFFER_COUNT : SIXTEEN_BITS ;
  1645. TCB_IN_USE_LIST_HEAD : TCB_PTR := null; --Pointer to the head of buffers currently
  1646.                                 --being used.
  1647. TCB_IN_USE_LIST_BUFFER_COUNT : SIXTEEN_BITS ;
  1648.  
  1649. function PHYSICAL_ADDRESS is new UNCHECKED_CONVERSION( THIRTYTWO_BITS ,
  1650.                           SYSTEM.ADDRESS);
  1651.  
  1652. --These variables are used by TCB_FREE only!
  1653. --They are instantiated durning intialization
  1654. --Rationale for this method is that garbage collection
  1655. --may not be implemented for the Unchecked_Deallocate.
  1656. CURRENT_LIST_POINTER : TCB_PTR;
  1657. PRIOR_LIST_POINTER : TCB_PTR;
  1658.  
  1659. procedure TCB_CLEAR( LCN : in TCB_PTR) is
  1660.  
  1661. begin
  1662. LCN.TCP_CHANNEL_NAME := "                              ";
  1663. LCN.TCP_CHANNEL_PTR := CHANNEL_ZERO ;
  1664. LCN.STATE := CLOSED;
  1665. LCN.CONNECTION_STATUS := CONNECTION_CLOSED;
  1666. LCN.LOCAL_PORT := -1;
  1667. LCN.LOCAL_NET :=0;
  1668. LCN.LOCAL_HOST :=1;
  1669. LCN.SOURCE_ADDRESS := 1;
  1670. LCN.DESTINATION_ADDRESS := 0;
  1671. LCN.FOREIGN_PORT := -1;
  1672. LCN.FOREIGN_HOST := -1;
  1673. LCN.FOREIGN_NET := -1; 
  1674. LCN.SND_UNA := MODULAR_CONVERT( THIRTYTWO_BITS ( 0 ) );
  1675. LCN.SND_UP := MODULAR_CONVERT( THIRTYTWO_BITS ( 0 ) );
  1676. LCN.SND_NXT := MODULAR_CONVERT( THIRTYTWO_BITS ( 0 ) );
  1677. LCN.SND_WND := 190;
  1678. LCN.RCV_NXT := MODULAR_CONVERT( THIRTYTWO_BITS ( 0 ) );
  1679. LCN.PRECEDENCE := 0;
  1680. LCN.USER_NOTIFICATION := FALSE;
  1681. LCN.SECURITY := SECURE_CLEAR;
  1682. LCN.BUFFSIZE := 0;
  1683. LCN.RCV_BUFFER_SIZE := -1;
  1684. LCN.RCV_URGENT_POINTER := 0;
  1685. LCN.SND_WL1 := MODULAR_CONVERT( THIRTYTWO_BITS ( 0 ) );
  1686. LCN.SND_WL2 := MODULAR_CONVERT( THIRTYTWO_BITS ( 0 ) );
  1687. LCN.RCV_WINDOW := 190;
  1688. LCN.INIT_RCV_SEQ_NUM := MODULAR_CONVERT( THIRTYTWO_BITS ( 0 ) );
  1689. LCN.ISS := MODULAR_CONVERT( THIRTYTWO_BITS ( 0 ));
  1690. LCN.RETRANS_INTERVAL := 30;
  1691. LCN.MAX_RETRY_OF_PACKET := 0;
  1692. LCN.PROTOCOL :=0;
  1693. LCN.ACTIVE_PASSIVE := ACTIVE;
  1694. LCN.CLOSE_PENDING := FALSE;
  1695. LCN.ERROR_TABLE := ERROR_TABLE_CLEAR;
  1696. LCN.QHEADS :=INITIAL_QUEUE_HEADER_POINTERS;
  1697. LCN.IDENT := -1;
  1698. LCN.RETRANS_IDENT := 0;
  1699. LCN.NEXT_CONNECTION_TIMEOUT := 0;
  1700. LCN.NEXT_TIME_WAIT_TIMEOUT := 0;
  1701. LCN.CONNECTION_TIMEOUT := 180;
  1702. LCN.CLOSE_OK_NOTIFICATION := FALSE;
  1703. end TCB_CLEAR;
  1704.  
  1705. procedure TCB_FREE
  1706.     (LCN : in out TCB_PTR) is
  1707.  
  1708. begin
  1709.         PRIOR_LIST_POINTER := null ; -- intialize 
  1710.         --Remove TCB from in_use list
  1711.         CURRENT_LIST_POINTER := TCB_IN_USE_LIST_HEAD;
  1712.         while LCN /= CURRENT_LIST_POINTER  
  1713.                and (CURRENT_LIST_POINTER /= null) loop
  1714.          PRIOR_LIST_POINTER := CURRENT_LIST_POINTER;
  1715.          CURRENT_LIST_POINTER := CURRENT_LIST_POINTER.NEXT;
  1716.         end loop;
  1717.         if CURRENT_LIST_POINTER /= null then
  1718.          -- Update TCB_IN_USE_LIST_HEAD and remove from list
  1719.          if PRIOR_LIST_POINTER = null and
  1720.            (CURRENT_LIST_POINTER.NEXT /= null ) then --new head
  1721.           TCB_IN_USE_LIST_HEAD := CURRENT_LIST_POINTER.NEXT;
  1722.          elsif PRIOR_LIST_POINTER /= null and
  1723.            (CURRENT_LIST_POINTER.NEXT /= null ) then
  1724.           PRIOR_LIST_POINTER.NEXT := CURRENT_LIST_POINTER.NEXT ;
  1725.          elsif PRIOR_LIST_POINTER /= null and
  1726.            (CURRENT_LIST_POINTER.NEXT = null ) then
  1727.           PRIOR_LIST_POINTER.NEXT := null ;
  1728.          else -- empty list
  1729.           TCB_IN_USE_LIST_HEAD := null ;
  1730.          end if;
  1731.          --Place TCB on free list
  1732.      TCB_FREE_LIST_BUFFER_COUNT := TCB_FREE_LIST_BUFFER_COUNT + 1; 
  1733.          -- ALWAYS INCREMENT
  1734.      LCN.NEXT := TCB_FREE_LIST_HEAD;
  1735.      TCB_FREE_LIST_HEAD := LCN;
  1736.      LCN := null; -- RETURN A NULL POINTER
  1737.         end if;
  1738.  exception
  1739.   when CONSTRAINT_ERROR =>
  1740.    PUT_LINE("Constraint error in TCB_FREE");
  1741.   when OTHERS =>
  1742.    PUT_LINE("Unkown error in TCB_FREE");
  1743. end TCB_FREE;
  1744.  
  1745. function TCB_GET return TCB_PTR is
  1746.  
  1747. begin
  1748.  --Remove buffer from free list
  1749.  LCN := TCB_FREE_LIST_HEAD;
  1750.  if TCB_FREE_LIST_HEAD /= null then
  1751.   TCB_FREE_LIST_HEAD := TCB_FREE_LIST_HEAD.NEXT ;
  1752.   --Place buffer on in_use list
  1753.   LCN.NEXT :=  TCB_IN_USE_LIST_HEAD;
  1754.   TCB_IN_USE_LIST_HEAD := LCN;
  1755.   --Decrement counter
  1756.   TCB_FREE_LIST_BUFFER_COUNT := TCB_FREE_LIST_BUFFER_COUNT - 1;
  1757.   --Increment counter
  1758.   TCB_IN_USE_LIST_BUFFER_COUNT := TCB_IN_USE_LIST_BUFFER_COUNT + 1 ;
  1759.   return LCN;
  1760.  else
  1761.   LCN := null;-- out of buffers
  1762.   return LCN;
  1763.  end if ;
  1764. exception
  1765.     when CONSTRAINT_ERROR =>
  1766.         TEXT_IO.PUT_LINE("ERROR/CONSTRAINT IN TCB_GET");
  1767.     --    SYSTEM.REPORT_ERROR;
  1768.     when others =>
  1769.         TEXT_IO.PUT_LINE("ERROR IN TCB_GET");
  1770.     --    SYSTEM.REPORT_ERROR;
  1771. end TCB_GET;
  1772.  
  1773. procedure TCB_INIT is
  1774.  
  1775.         --This subprogram is called when the system is intialize to 
  1776.         --create a finite number of buffers.
  1777.  
  1778.  I : SIXTEEN_BITS ;
  1779.  NEXT_BUFFER : TCB_PTR;
  1780.  
  1781. begin
  1782.                 -- Telesoft does not allow the elboration durning instantiation
  1783.                 RESERVE := new TRANSMISSION_CONTROL_BLOCK;
  1784.         -- get 20 buffers.
  1785.         TCB_FREE_LIST_HEAD := new TRANSMISSION_CONTROL_BLOCK;
  1786.         NEXT_BUFFER := new TRANSMISSION_CONTROL_BLOCK;
  1787.         TCB_FREE_LIST_HEAD.NEXT := NEXT_BUFFER;
  1788.         for I in 1..18 loop
  1789.             NEXT_BUFFER.NEXT := new TRANSMISSION_CONTROL_BLOCK;
  1790.                                                               -- Link them 
  1791.             NEXT_BUFFER := NEXT_BUFFER.NEXT ;
  1792.         end loop;
  1793.         TCB_FREE_LIST_BUFFER_COUNT := 20;
  1794.         TCB_IN_USE_LIST_BUFFER_COUNT := 0;
  1795.     exception 
  1796.         when STORAGE_ERROR =>
  1797.          TEXT_IO.PUT_LINE("OUT OF ROOM TO INITIALIZE TCB BUFFERS");
  1798. end TCB_INIT;
  1799.  
  1800. function OBTAIN_HEAD_OF_LCN_IN_USE_QUEUE return TCB_PTR is
  1801.  
  1802. begin
  1803.  return TCB_IN_USE_LIST_HEAD;
  1804. end OBTAIN_HEAD_OF_LCN_IN_USE_QUEUE;
  1805.  
  1806. begin
  1807.  TCB_FREE_LIST_BUFFER_COUNT := 0; -- initialize buffer count.
  1808.  TCB_INIT;
  1809.  CURRENT_LIST_POINTER := new TRANSMISSION_CONTROL_BLOCK;
  1810.  PRIOR_LIST_POINTER := new TRANSMISSION_CONTROL_BLOCK;
  1811.  
  1812. end TCB_ALLOCATOR;
  1813. --::::::::::::::
  1814. --ncomm_.ada
  1815. --::::::::::::::
  1816. -----------------------------------------------------------------------
  1817. --
  1818. --         DoD Protocols    NA-00001-200       80-01001-100(-)
  1819. --         E-Systems, Inc.  August 07, 1985
  1820. --
  1821. --         NCOMM_.ADA       Author : Jim Baldo
  1822. --
  1823. -----------------------------------------------------------------------
  1824. with STARLET ;                use STARLET ;
  1825. with IP_GLOBALS;            use IP_GLOBALS;
  1826. with BUFFER_DATA;            use BUFFER_DATA;
  1827. with T_TCP_GLOBALS_DATA_STRUCTURES;    use T_TCP_GLOBALS_DATA_STRUCTURES;
  1828.     
  1829.         package    WITH_TCP_COMMUNICATE is
  1830.  
  1831.     ---------------------------------------------------------------
  1832.     --This implementation is for use with DEC/Ada compiler.      --
  1833.     ---------------------------------------------------------------
  1834.  
  1835. -------------------------------------------------------------------------------
  1836. --This package contains all the data abstractions and operations necessary   --
  1837. --to support the User/TCP interface and TCP/lower-level interface.           --
  1838. --The enumerated type ACTION represents the type of request primitive        --
  1839. --that is sent by the upper layer or lower layer protocols.                  --
  1840. -------------------------------------------------------------------------------
  1841.  
  1842. type STATUS_TYPE is ( CONNECTION_OPEN, CONNECTION_CLOSED, OPENING, CLOSING);
  1843. type SECURITIES is array(1..9) of SIXTEEN_BITS ;
  1844. type STATE_TYPE is ( CLOSED, SYSN_SENT, SYN_RECEIVED, ESTABLISHED, LISTEN,
  1845.                      FIN_WAIT_1, CLOSE_WAIT, FIN_WAIT_2, CLOSING, TIME_WAIT,
  1846.                      LAST_ACK); -- same as in TCPGLB
  1847.  
  1848. type STATUS_RECORD is
  1849.  record
  1850.   SOURCE_PORT : SIXTEEN_BITS ;
  1851.   SOURCE_ADDRESS : THIRTYTWO_BITS ;
  1852.   DESTINATION_PORT : SIXTEEN_BITS ;
  1853.   DESTINATION_ADDRESS : THIRTYTWO_BITS ;
  1854.   CONNECTION_STATE : STATE_TYPE;
  1855.   STATUS : STATUS_TYPE;
  1856.   LOCAL_RCV_WINDOW : SIXTEEN_BITS ;
  1857.   REMOTE_RCV_WINDOW : SIXTEEN_BITS ;
  1858.   OCTETS_ON_RETRANSMIT_QUEUE : SIXTEEN_BITS ;
  1859.   DATA_WAITING_FOR_ULP : SIXTEEN_BITS ;
  1860.   URGENT_STATE : BOOLEAN;
  1861.   PRECEDENCE : SIXTEEN_BITS ;
  1862.   SECURITY : SECURITIES;
  1863.   ULP_TIMEOUT : SIXTEEN_BITS ;
  1864. end record; 
  1865.  
  1866. subtype LCN_TYPE is TCB_PTR;
  1867.  
  1868. type LCN_PTR_TYPE is 
  1869.  record
  1870.   LCN : LCN_TYPE := null;
  1871.   CHANNEL_PTR : CHANNEL_TYPE ;
  1872.   CHANNEL_NAME : STRING(1..30) ;
  1873.  end record;
  1874.  
  1875. type USER_MESSAGE(MESSAGE_NUMBER : SIXTEEN_BITS  := 0) is 
  1876.   record
  1877.    LOCAL_CONNECTION_NAME : LCN_PTR_TYPE;
  1878.     case MESSAGE_NUMBER is
  1879.       when 10 | 19  =>
  1880.         DATA_BUFFER : PACKED_BUFFER_PTR;
  1881.       when 15 =>
  1882.             -- STATUS PARAMETERS
  1883.         STATUS_PARAMS : STATUS_RECORD;
  1884.       when others => null;
  1885.     end case;
  1886.   end record;
  1887.  
  1888. type ACTION is (OPEN,SEND,RECEIVE,ABOR_T,CLOSE,STATUS,DATA_FROM_IP,
  1889.         TIMER_TIMEOUT, ERROR_MESSAGE, TIMEOUT_IN_RETRANS_QUEUE,
  1890.         TIMEOUT_IN_TIME_WAIT, NO_TCP_ACTION);
  1891.  
  1892. subtype SECURITY_OPTION_ARRAY is SIXTEEN_BITS range 1..9;
  1893.  
  1894. type SECURITY_OPTION_TYPE is array( SECURITY_OPTION_ARRAY ) of SIXTEEN_BITS ; 
  1895.                     -- EACH ELEMENT CONTAINS AN
  1896.                          -- OCTET OF SECURITY DATA.
  1897. type TCP_OPTION_TYPE is array(1..50) of SIXTEEN_BITS ;
  1898.  
  1899. type ACKPASS is (PASSIVE, ACTIVE);
  1900.     
  1901. type TIMER_PARAMS is
  1902.     record
  1903.         MESSAGE_NUMBER : SIXTEEN_BITS ;
  1904.     end record;
  1905.     
  1906. type TIME_WAIT_PARAMS is
  1907.     record
  1908.       LCN_BLOCK : LCN_PTR_TYPE ;
  1909.     end record;
  1910.  
  1911. type OPEN_PARAMS is
  1912.  record
  1913.   LOCAL_PORT, FOREIGN_PORT : SIXTEEN_BITS ;
  1914.   FOREIGN_NET_HOST : THIRTYTWO_BITS ;
  1915.   ACTIVE_PASSIVE : ACKPASS;
  1916.   BUFFER_SIZE, TIMEOUT : SIXTEEN_BITS ;
  1917.   LCN_BLOCK : LCN_PTR_TYPE ;
  1918.   SECURITY, PRECEDENCE : SIXTEEN_BITS ;
  1919.   OPTIONS : TCP_OPTION_TYPE;
  1920. end record;
  1921.  
  1922. type STATUS_PARAMS is
  1923.  record
  1924.   LCN_BLOCK : LCN_PTR_TYPE ;
  1925.  end record;
  1926.   
  1927. type ERROR_PARAMS is
  1928.  record
  1929.   ERROR_INDICATOR : SIXTEEN_BITS ; -- THIS MAY CHANGE.
  1930.  end record;
  1931.   
  1932. type RETRANS_PARAMS is
  1933.  record
  1934.   QUEUE_NUM : SIXTEEN_BITS ;
  1935.  end record;
  1936.  
  1937. type SEG_ARRIVE_PARAMS is
  1938.  record
  1939.   BUFPTR : PACKED_BUFFER_PTR;
  1940.   BYTE_COUNT : SIXTEEN_BITS ;
  1941.   SOURCE_ADDRESS, DESTINATION_ADDRESS : THIRTYTWO_BITS ;
  1942.   PROTOCOL : SIXTEEN_BITS ;
  1943.   TOS : SIXTEEN_BITS ;
  1944.   SECURITY : SECURITY_OPTION_TYPE;
  1945.  end record;
  1946.   
  1947. type SEND_PARAMS is
  1948.  record
  1949.   LCN_BLOCK : LCN_PTR_TYPE ;
  1950.   BUFPTR : PACKED_BUFFER_PTR;
  1951.   BYTE_COUNT, PUSH_FLAG, URG_FLAG, TIMEOUT : SIXTEEN_BITS ;
  1952. end record;
  1953.  
  1954. type RECEIVE_PARAMS is
  1955.  record
  1956.   LCN_BLOCK : LCN_PTR_TYPE ;
  1957.   BUFPTR : PACKED_BUFFER_PTR;
  1958.   BYTE_COUNT : SIXTEEN_BITS ;
  1959.  end record;
  1960.   
  1961. type ABORT_CLOSE_PARAMS    is
  1962.  record
  1963.   LCN_BLOCK : LCN_PTR_TYPE ;
  1964.  end record;
  1965.   
  1966. --TCP responds to message which are associated with a type of event.  The
  1967. --data abstraction of MESSAGE creates the appropiate message for the given
  1968. --event.
  1969. type MESSAGE(EVENT : ACTION := OPEN) is
  1970.  record
  1971.   case EVENT is
  1972.    when   ABOR_T |  CLOSE
  1973.      => ABORT_CLOSE_PARAMETERS : ABORT_CLOSE_PARAMS;
  1974.    
  1975.    when DATA_FROM_IP 
  1976.     => DATA_FROM_IP_PARAMETERS : SEG_ARRIVE_PARAMS;
  1977.    
  1978.    when RECEIVE 
  1979.     => RECEIVE_PARAMETERS : RECEIVE_PARAMS;
  1980.    
  1981.    when SEND => SEND_PARAMETERS : SEND_PARAMS;
  1982.    
  1983.    when OPEN  => OPEN_PARAMETERS : OPEN_PARAMS;
  1984.     
  1985.    when STATUS
  1986.           => STATUS_PARAMETERS : STATUS_PARAMS;
  1987.     
  1988.    when  TIMEOUT_IN_TIME_WAIT
  1989.            =>  TIME_WAIT_PARAMETERS : TIME_WAIT_PARAMS;
  1990.     
  1991.    when TIMEOUT_IN_RETRANS_QUEUE 
  1992.           => RETRANS_PARAMETERS    : RETRANS_PARAMS;
  1993.    
  1994.    when ERROR_MESSAGE 
  1995.           => ERROR_PARAMETERS : ERROR_PARAMS;
  1996.  
  1997.    when TIMER_TIMEOUT 
  1998.           => TIMER_PARAMETERS : TIMER_PARAMS;
  1999.   
  2000.    when NO_TCP_ACTION => NULL;
  2001.  end case;
  2002. end record;
  2003.  
  2004. TO_TCP_CHANNEL : CHANNEL_TYPE ;
  2005.  
  2006. end WITH_TCP_COMMUNICATE;
  2007. --::::::::::::::
  2008. --unpack_.ada
  2009. --::::::::::::::
  2010. -----------------------------------------------------------------------
  2011. --
  2012. --         DoD Protocols    NA-00001-200       80-01029-100(-)
  2013. --         E-Systems, Inc.  August 07, 1985
  2014. --
  2015. --         UNPACK_.ADA       Author : Jim Baldo
  2016. --
  2017. -----------------------------------------------------------------------
  2018. with IP_GLOBALS;    use IP_GLOBALS;
  2019. with BUFFER_DATA;    use BUFFER_DATA;
  2020.  
  2021.         package IP_UNPACK_AND_PACK_UTILITIES is
  2022.  
  2023.     --------------------------------------------------------------
  2024.     --This implementation is for use with the DEC/Ada compiler. --
  2025.     --------------------------------------------------------------
  2026.  
  2027.   function UNPACK
  2028.     (PACKED_BUFFER : PACKED_BUFFER_PTR) return BUFFER_POINTER;
  2029.  
  2030.     --This function will unpack a packet of SYSTEM_BYTE to facilatate
  2031.     --access to data.
  2032.  
  2033.   procedure PACK_BUFFER_INTO_BIT_STREAM
  2034.       (BUFPTR : BUFFER_POINTER; PACKED_BUFFER : 
  2035.               in out PACKED_BUFFER_PTR);
  2036.  
  2037.     --This procedure transform an IP header and date into SYSTEM_BYTE
  2038.  
  2039.   function CHECKSUM( START_PTR : in SIXTEEN_BITS ; 
  2040.                      END_PTR : in SIXTEEN_BITS ; 
  2041.                      PACKED_BUFFER : in PACKED_BUFFER_PTR) return SIXTEEN_BITS ;
  2042.  
  2043.     --This function performs a checksum calculation on the 
  2044.     --arrived datagram and compares its value with that contained 
  2045.     --in the IP header.
  2046.  
  2047. end IP_UNPACK_AND_PACK_UTILITIES;
  2048. --::::::::::::::
  2049. --unpack.ada
  2050. --::::::::::::::
  2051. -----------------------------------------------------------------------
  2052. --
  2053. --         DoD Protocols    NA-00001-200       80-01030-100(-)
  2054. --         E-Systems, Inc.  August 07, 1985
  2055. --
  2056. --         UNPACK.ADA       Author : Jim Baldo
  2057. --
  2058. -----------------------------------------------------------------------
  2059. with BUFFER_DATA;         use BUFFER_DATA;
  2060. with WITH_TCP_COMMUNICATE;      use WITH_TCP_COMMUNICATE;
  2061. with TEXT_IO;              use TEXT_IO;
  2062. with SYSTEM;            use SYSTEM;
  2063. with UNCHECKED_CONVERSION;
  2064.  
  2065.         package body IP_UNPACK_AND_PACK_UTILITIES is
  2066.  
  2067. package INT_IO is new INTEGER_IO( SIXTEEN_BITS );
  2068.  
  2069.   function UNPACK
  2070.     (PACKED_BUFFER : PACKED_BUFFER_PTR) return BUFFER_POINTER is
  2071.  
  2072.     --This function will unpack a buffer full of bytes and put them in the
  2073.     --proper fields of a record for ease of processing by other routines.
  2074.     --
  2075.     -- RESTRICTIONS :
  2076.     --
  2077.     --   ** This routine is likely to be implementation dependent. **
  2078.  
  2079. --TEL  pragma suppress(OVERFLOW_CHECK);
  2080.  
  2081.   type INDEX is (HIGH_WORD_HI_BYTE, HIGH_WORD_LO_BYTE, 
  2082.          LOW_WORD_HI_BYTE, LOW_WORD_LO_BYTE); -- THIS IS THE WAY 
  2083.                   -- UNCHECKED CONV PUTS
  2084.                   -- THE BYTES IN. IT IS
  2085.                   -- OPPOSITE FOR THE VAX.
  2086.   type LONG_CONV is array(1..1) of THIRTYTWO_BITS ; 
  2087.           -- CURRENTLY NECESSARY FOR 
  2088.                  -- IMPLEMENTATION RESTRICTION
  2089.  
  2090.   type BYTE_TYPE is array(INDEX) of SYSTEM_BYTE;
  2091.  
  2092.   function CONVERT is new UNCHECKED_CONVERSION(BYTE_TYPE, LONG_CONV);
  2093.   BYTES_TO_CONVERT : BYTE_TYPE;
  2094.   CONVERTED_WORDS : LONG_CONV;
  2095.   BUFPTR : BUFFER_POINTER;
  2096.   COUNT, I, X, Y : SIXTEEN_BITS ;
  2097.   SHIFT_WORD : CONSTANT THIRTYTWO_BITS  := 65536;
  2098.   
  2099.   begin
  2100.   -- IT IS ASSUMED THAT THE POINTER IN THE BUFFER POINTS TO 
  2101.   --THE PROPER HEADER.
  2102.     I := PACKED_BUFFER.IP_PTR;
  2103.     X := SIXTEEN_BITS (PACKED_BUFFER.BYTE(I)/2**4) ;
  2104.     BUFPTR.VERSION := X;
  2105.     BUFPTR.IHL := SIXTEEN_BITS (PACKED_BUFFER.BYTE(I)) - X * 2**4 ;
  2106.     BUFPTR.TOS := SIXTEEN_BITS (PACKED_BUFFER.BYTE(I+1)) ;
  2107.     BUFPTR.TOT_LEN := SIXTEEN_BITS (PACKED_BUFFER.BYTE(I+2) * 2**8 + 
  2108.       PACKED_BUFFER.BYTE(I+3)) ;
  2109.     BUFPTR.ID := SIXTEEN_BITS (PACKED_BUFFER.BYTE(I+4) * 2**8 + 
  2110.       PACKED_BUFFER.BYTE(I+5)) ;
  2111.     X := SIXTEEN_BITS (PACKED_BUFFER.BYTE(I+6)/2**5) ;
  2112.     BUFPTR.FLAGS := X;
  2113.     BUFPTR.FRAG_OFFSET := (SIXTEEN_BITS (PACKED_BUFFER.BYTE(I+6)) - X * 2**5) * 
  2114.       2**8 + SIXTEEN_BITS (PACKED_BUFFER.BYTE(I+7)) ;
  2115.     BUFPTR.TTL := SIXTEEN_BITS (PACKED_BUFFER.BYTE(I+8)) ;
  2116.     BUFPTR.PROT := SIXTEEN_BITS (PACKED_BUFFER.BYTE(I+9)) ;
  2117.     BUFPTR.IPCSUM := SIXTEEN_BITS (PACKED_BUFFER.BYTE(I+10)) * 2**8 + 
  2118.       SIXTEEN_BITS (PACKED_BUFFER.BYTE(I+11)) ;
  2119.     -- PUT IN SOURCE
  2120.     BYTES_TO_CONVERT(HIGH_WORD_HI_BYTE) := 
  2121.                         PACKED_BUFFER.BYTE(I+12) ;
  2122.     BYTES_TO_CONVERT(HIGH_WORD_LO_BYTE) := 
  2123.                         PACKED_BUFFER.BYTE(I+13) ;
  2124.     BYTES_TO_CONVERT(LOW_WORD_HI_BYTE) := 
  2125.                         PACKED_BUFFER.BYTE(I+14) ;
  2126.     BYTES_TO_CONVERT(LOW_WORD_LO_BYTE) :=   
  2127.                         PACKED_BUFFER.BYTE(I+15) ;
  2128.     CONVERTED_WORDS := CONVERT(BYTES_TO_CONVERT);
  2129.     BUFPTR.SOURCE := CONVERTED_WORDS(1);
  2130.     -- PUT IN DESTINATION
  2131.     BYTES_TO_CONVERT(HIGH_WORD_HI_BYTE) := 
  2132.                         PACKED_BUFFER.BYTE(I+16) ;
  2133.     BYTES_TO_CONVERT(HIGH_WORD_LO_BYTE) := 
  2134.                         PACKED_BUFFER.BYTE(I+17) ;
  2135.     BYTES_TO_CONVERT(LOW_WORD_HI_BYTE) := 
  2136.                         PACKED_BUFFER.BYTE(I+18) ;
  2137.     BYTES_TO_CONVERT(LOW_WORD_LO_BYTE) :=   
  2138.                         PACKED_BUFFER.BYTE(I+19) ;
  2139.     CONVERTED_WORDS := CONVERT(BYTES_TO_CONVERT);
  2140.     BUFPTR.DEST := CONVERTED_WORDS(1);
  2141.     -- NOW FOR THE OPTIONS IF ANY
  2142.     I := I + 20;
  2143.     if BUFPTR.IHL > 5 then -- OPTIONS EXIST
  2144.       COUNT := 1;
  2145.       for J in 1..BUFPTR.IHL - 5 LOOP
  2146.         for K in 0..3 loop
  2147.          BUFPTR.IP_OPTIONS( COUNT + SIXTEEN_BITS(K) ) := 
  2148.             SIXTEEN_BITS (PACKED_BUFFER.BYTE( I + SIXTEEN_BITS(K)) ) ;
  2149.          if BUFPTR.IP_OPTIONS( COUNT + SIXTEEN_BITS(K) ) < 0 then
  2150.           BUFPTR.IP_OPTIONS( COUNT + SIXTEEN_BITS(K) ) := 
  2151.            BUFPTR.IP_OPTIONS( COUNT + SIXTEEN_BITS(K) )  + 256 ;
  2152.             -- for unsigned_byte conversion (DEC/ADA)
  2153.          end if;
  2154.         end loop;
  2155.         COUNT := COUNT + 4;
  2156.         I := I + 4;
  2157.       end loop;
  2158.     end IF;
  2159.     PACKED_BUFFER.TCP_PTR := I; 
  2160.       -- UPDATE THE POINTER TO POINT TO THE FIRST 
  2161.         -- BYTE OF THE TCP HEADER.
  2162.     return BUFPTR;
  2163.   exception
  2164.      when CONSTRAINT_ERROR =>
  2165.         PUT_LINE("IP UNPACK?, CONSTRAINT ERROR");
  2166.       INT_IO.PUT(I);
  2167.     when others =>
  2168.       PUT_LINE("IP UNPACK?, ERROR");
  2169.       --  SYSTEM.REPORT_ERROR;
  2170.   end UNPACK;
  2171.  
  2172.   procedure PACK_BUFFER_INTO_BIT_STREAM
  2173.       (BUFPTR : BUFFER_POINTER; PACKED_BUFFER : 
  2174.               in out PACKED_BUFFER_PTR) is
  2175.  
  2176.     --This subprogram will take an unpacked IP header record with each 
  2177.     --field having its own spot, and pack the fields into a bit 
  2178.     --stream( in the form of bytes).  It assumes that the pointer given 
  2179.     --it (for the packed array) is correctly set. The IP header picture 
  2180.     --in the specification shows how the packed stream should look.  
  2181.     --It also calls the header checksum routine and packs the checksum 
  2182.     --in the stream.
  2183.  
  2184. --TEL   pragma SUPPRESS(OVERFLOW_CHECK);
  2185.  
  2186.   type INDEX is (HIGH_WORD_HI_BYTE, HIGH_WORD_LO_BYTE, 
  2187.          LOW_WORD_HI_BYTE, LOW_WORD_LO_BYTE); -- THIS IS THE WAY 
  2188.                 -- UNCHECKED CONV PUTS
  2189.                 -- THE BYTES IN.
  2190.                 -- IT IS OPPOSITE FOR
  2191.                 -- THE VAX.
  2192.   type LONG_CONV is array(1..1) of THIRTYTWO_BITS ; 
  2193.             -- CURRENTLY NECESSARY FOR 
  2194.                   -- IMPLEMENTATION RESTRICTION
  2195.  
  2196.   type BYTE_TYPE is array(INDEX) of SYSTEM_BYTE; --DEC/Ada
  2197.  
  2198.   type TWO_BYTE is array(1..2) of SYSTEM_BYTE; --DEC/Ada
  2199.  
  2200.   type TELEGOOFUP is array(1..1) of SIXTEEN_BITS ;
  2201.   function CONVERT_TO_TWO_BYTES is new 
  2202.       UNCHECKED_CONVERSION(TELEGOOFUP, TWO_BYTE);
  2203.   function CONVERT is new UNCHECKED_CONVERSION(LONG_CONV, BYTE_TYPE);
  2204.   SHIFT_WORD : constant THIRTYTWO_BITS  := 65536;
  2205.   J : SIXTEEN_BITS  := 1;
  2206.   IP_LENGTH : constant SIXTEEN_BITS  := BUFPTR.IHL * 4;
  2207.   HIGH_BYTE : BOOLEAN := TRUE;
  2208.   COUNT : SIXTEEN_BITS  := 0;
  2209.   I, CSUM, X : SIXTEEN_BITS ;
  2210.   BYTES: BYTE_TYPE;
  2211.   WORDS_TO_CONVERT : LONG_CONV;
  2212.   TEMP : TWO_BYTE;
  2213.   WORD_TO_CONVERT : TELEGOOFUP;
  2214.  
  2215.   begin
  2216.     --SET POINTER
  2217.     PACKED_BUFFER.IP_PTR := PACKED_BUFFER.IP_PTR - 
  2218.             IP_LENGTH + 1;-- POINTER IS
  2219.          -- INITIALLY AT THE FIRST OPEN BYTE IN THE BUFFER(ARRAY).
  2220.     I := PACKED_BUFFER.IP_PTR;
  2221.     PACKED_BUFFER.BYTE(I) := SYSTEM_BYTE (BUFPTR.VERSION * 2**4 + BUFPTR.IHL);
  2222.     PACKED_BUFFER.BYTE(I+1) := SYSTEM_BYTE (BUFPTR.TOS) ;
  2223.     WORD_TO_CONVERT(1) := BUFPTR.TOT_LEN;
  2224.     TEMP := CONVERT_TO_TWO_BYTES(WORD_TO_CONVERT);
  2225.     PACKED_BUFFER.BYTE(I+2) := TEMP(2); 
  2226.         -- FOR VAX. TEMP(2);-- HIGH BYTE
  2227.     PACKED_BUFFER.BYTE(I+3) := TEMP(1); -- FOR VAX. TEMP(1);
  2228.     WORD_TO_CONVERT(1) := BUFPTR.ID;
  2229.     TEMP := CONVERT_TO_TWO_BYTES(WORD_TO_CONVERT);
  2230.     PACKED_BUFFER.BYTE(I+4) := TEMP(1);
  2231.         -- HIGH BYTE. OPPOSITE FOR THE mc68000
  2232.     PACKED_BUFFER.BYTE(I+5) := TEMP(2);
  2233.     WORD_TO_CONVERT(1) := BUFPTR.FRAG_OFFSET;
  2234.     TEMP := CONVERT_TO_TWO_BYTES(WORD_TO_CONVERT);
  2235.     PACKED_BUFFER.BYTE(I+6) := TEMP(2) + SYSTEM_BYTE ( BUFPTR.FLAGS * 2**5) ; 
  2236.                 -- HIGH BYTE
  2237.     PACKED_BUFFER.BYTE(I+7) := TEMP(1); -- OPPOSITE OF THE VAX.
  2238.     PACKED_BUFFER.BYTE(I+8) := SYSTEM_BYTE ( BUFPTR.TTL ) ;
  2239.     PACKED_BUFFER.BYTE(I+9) := SYSTEM_BYTE ( BUFPTR.PROT ) ;
  2240.     -- CHECKSUM GOES HERE
  2241.     PACKED_BUFFER.BYTE(I+10) := 0;
  2242.     PACKED_BUFFER.BYTE(I+11) := 0;
  2243.     WORDS_TO_CONVERT(1) := BUFPTR.SOURCE;
  2244.     BYTES := CONVERT(WORDS_TO_CONVERT);
  2245.     PACKED_BUFFER.BYTE(I+12) := BYTES(HIGH_WORD_HI_BYTE);
  2246.     PACKED_BUFFER.BYTE(I+13) := BYTES(HIGH_WORD_LO_BYTE);
  2247.     PACKED_BUFFER.BYTE(I+14) := BYTES(LOW_WORD_HI_BYTE);
  2248.     PACKED_BUFFER.BYTE(I+15) := BYTES(LOW_WORD_LO_BYTE);
  2249.     WORDS_TO_CONVERT(1) := BUFPTR.DEST;
  2250.     BYTES := CONVERT(WORDS_TO_CONVERT);
  2251.     PACKED_BUFFER.BYTE(I+16) := BYTES(HIGH_WORD_HI_BYTE);
  2252.     PACKED_BUFFER.BYTE(I+17) := BYTES(HIGH_WORD_LO_BYTE);
  2253.     PACKED_BUFFER.BYTE(I+18) := BYTES(LOW_WORD_HI_BYTE);
  2254.     PACKED_BUFFER.BYTE(I+19) := BYTES(LOW_WORD_LO_BYTE);
  2255.   
  2256.     -- NOW THE OPTIONS
  2257.     I := I + 20;
  2258.     COUNT := (BUFPTR.IHL - 5) * 4; 
  2259.     for J in 1..COUNT loop
  2260.       PACKED_BUFFER.BYTE(I + SIXTEEN_BITS ( J ) - 1) := 
  2261.                                    SYSTEM_BYTE (BUFPTR.IP_OPTIONS(J) ) ;
  2262.     end loop;
  2263.   
  2264.     -- MOVE THE POINTER TO POINT TO THE NEXT OPEN SPACE FOR TCP
  2265. --    PACKED_BUFFER.CPM_PTR := PACKED_BUFFER.IP_PTR - 1;
  2266. -- PUT IN THE CHECKSUM
  2267.     WORD_TO_CONVERT(1) := CHECKSUM(PACKED_BUFFER.IP_PTR, 
  2268.                                    BUFPTR.IHL * 4, 
  2269.                                    PACKED_BUFFER);
  2270.     TEMP := CONVERT_TO_TWO_BYTES(WORD_TO_CONVERT);
  2271.     I := PACKED_BUFFER.IP_PTR;
  2272.     PACKED_BUFFER.BYTE(I + 10) := TEMP(1); -- FOR THE 68000 TEMP(2);
  2273.     PACKED_BUFFER.BYTE(I + 11) := TEMP(2); -- FOR THE 68000 TEMP(1); 
  2274.   exception
  2275.      when CONSTRAINT_ERROR => 
  2276.       PUT_LINE("CONSTRAINT ERROR IN IP PACK");
  2277.                         INT_IO.PUT(PACKED_BUFFER.IP_PTR);
  2278.     when others =>
  2279.       PUT_LINE("PACK EM ERROR");
  2280.       INT_IO.PUT(PACKED_BUFFER.IP_PTR);
  2281.       INT_IO.PUT(CSUM);
  2282.     --     SYSTEM.REPORT_ERROR;
  2283.     
  2284.   end PACK_BUFFER_INTO_BIT_STREAM;
  2285.  
  2286. function PHYSICAL_ADDRESS is new UNCHECKED_CONVERSION(THIRTYTWO_BITS ,
  2287.                               SYSTEM.ADDRESS);
  2288.  
  2289. function CHECKSUM( START_PTR : in SIXTEEN_BITS ; 
  2290.                    END_PTR : in SIXTEEN_BITS ;
  2291.                    PACKED_BUFFER : in PACKED_BUFFER_PTR) 
  2292.                                           return SIXTEEN_BITS  is
  2293.  
  2294.     --This subprogram performs a checksum on the internet header only. It
  2295.     --will be the 16 bit one's complement of all 16 bit words in the 
  2296.     --header.  The value of the checksum field for computation will be 0.
  2297.     --
  2298.     -- RESTRICTIONS :
  2299.     --
  2300.     --This routine is implementation dependant.  It is currently set for 
  2301.     --a VAX 11/780.
  2302.  
  2303. type TWO_WORDS is array(1..2) of SIXTEEN_BITS ;
  2304. type TELEFOOL is array(1..1) of THIRTYTWO_BITS ;
  2305. function CONVERSION is new UNCHECKED_CONVERSION(TELEFOOL, TWO_WORDS);
  2306. HIGH_BYTE : BOOLEAN := TRUE;
  2307. PCSUM : THIRTYTWO_BITS  := 0;
  2308. CSUM : TWO_WORDS :=(0,0);
  2309. CHECKSM : TELEFOOL;
  2310.  
  2311. begin
  2312.  -- ADD UP ALL THE 16 BIT FIELDS. THIS WILL BE SOMEWHAT TRICKY, SO 
  2313.  --HANG ON.  MUST SWAP HIGH AND LOW BITS IN EACH WORD. HOWEVER WE WILL 
  2314.  --TRY IT THE INTUITIVE WAY FOR NOW.
  2315.         for I in 0..END_PTR - 1 loop
  2316.         if (I /= 10) and I /= 11 then -- DON'T ADD IN THE CHECKSUM
  2317.             if HIGH_BYTE then
  2318.                 PCSUM := PCSUM + 
  2319.                 THIRTYTWO_BITS (PACKED_BUFFER.BYTE(START_PTR + I))
  2320.                 * THIRTYTWO_BITS (2**8); 
  2321.                 HIGH_BYTE := FALSE;
  2322.             else
  2323.                 HIGH_BYTE := TRUE;
  2324.                 PCSUM := PCSUM + 
  2325.                 THIRTYTWO_BITS (PACKED_BUFFER.BYTE(START_PTR + I));
  2326.             end if;
  2327.         end if;
  2328.         end loop;
  2329.         -- GET ONES COMPLEMENT
  2330.         PCSUM := -PCSUM;
  2331.         PCSUM := PCSUM - 1;
  2332.         CHECKSM(1) := PCSUM;
  2333.         CSUM := CONVERSION(CHECKSM);
  2334.             -- GET BOTH WORDS AND RETURN LOW WORD.
  2335.         RETURN CSUM(1); -- IT IS ONE FOR THE VAX
  2336. exception
  2337.     when CONSTRAINT_ERROR =>
  2338.         PUT_LINE("CHECKSUM CONSTRAINT ERROR");
  2339.         INT_IO.PUT(START_PTR);
  2340.         --  SYSTEM.REPORT_ERROR;
  2341.     when others =>
  2342.         PUT_LINE("CHECKSUM ERROR");
  2343.         --  SYSTEM.REPORT_ERROR;
  2344. end CHECKSUM;
  2345.  
  2346. end IP_UNPACK_AND_PACK_UTILITIES;
  2347. --::::::::::::::
  2348. --tcp_q_.ada
  2349. --::::::::::::::
  2350. -----------------------------------------------------------------------
  2351. --
  2352. --         DoD Protocols    NA-00001-200       80-01018-100(-)
  2353. --         E-Systems, Inc.  August 07, 1985
  2354. --
  2355. --         TCP_Q_.ADA       Author : Jim Baldo
  2356. --
  2357. -----------------------------------------------------------------------
  2358. with WITH_TCP_COMMUNICATE;            use WITH_TCP_COMMUNICATE;
  2359.  
  2360.             package TCP_Q_TASK is
  2361.  
  2362.         --------------------------------------
  2363.         --This implementation is for the    --
  2364.         --the DEC/Ada compiler .            --
  2365.         --------------------------------------
  2366.  
  2367. subtype Q_ITEM is MESSAGE;
  2368.  
  2369. task TCP_Q is
  2370.  entry Q_ADD ( ITEM : in Q_ITEM ) ;
  2371.  entry Q_GET ( ITEM : in out Q_ITEM ) ;
  2372. end TCP_Q ;
  2373.  
  2374. end TCP_Q_TASK ;
  2375. --::::::::::::::
  2376. --tcp_q.ada
  2377. --::::::::::::::
  2378. -----------------------------------------------------------------------
  2379. --
  2380. --         DoD Protocols    NA-00001-200       80-01019-100(-)
  2381. --         E-Systems, Inc.  August 07, 1985
  2382. --
  2383. --         TCP_Q.ADA       Author : Jim Baldo
  2384. --
  2385. -----------------------------------------------------------------------
  2386. with TEXT_IO;                use TEXT_IO;
  2387. with BUFFER_DATA ;            use BUFFER_DATA ;
  2388.  
  2389.             package body TCP_Q_TASK is
  2390.  
  2391. package INT_IO is new INTEGER_IO ( SIXTEEN_BITS );
  2392.  
  2393. type QUEUE_ELEMENT;
  2394. type QUEUE_ELEMENT_POINTER is access QUEUE_ELEMENT;
  2395.  
  2396. type QUEUE_ELEMENT is
  2397. record
  2398.   ELEMENT : Q_ITEM;
  2399.   NEXT : QUEUE_ELEMENT_POINTER;
  2400. end RECORD;
  2401.  
  2402. type QHEADS is 
  2403. record
  2404.   ELEMENT_COUNT : SIXTEEN_BITS  := 0;
  2405.   FIRST_ELEMENT : QUEUE_ELEMENT_POINTER;
  2406.   LAST_ELEMENT  : QUEUE_ELEMENT_POINTER;
  2407. end RECORD;
  2408.  
  2409. TO_TCP_QUEUE : QHEADS;
  2410.  
  2411. QUEUE_FREE_LIST : QUEUE_ELEMENT_POINTER;
  2412. MAX_QUEUE_SIZE : constant SIXTEEN_BITS  := 32;
  2413. NUMBER_OF_QUEUES : CONSTANT SIXTEEN_BITS  := 1;
  2414. TO_TCP_QUEUE_LENGTH : SIXTEEN_BITS  := 0;
  2415. MAX : CONSTANT SIXTEEN_BITS  := 32; -- TEMPORARY
  2416. NO_ADD_COUNT : SIXTEEN_BITS  := 0;
  2417.  
  2418. function QUEUE_FULL return BOOLEAN is
  2419.  
  2420. RESULT : BOOLEAN := FALSE;
  2421.  
  2422. begin
  2423.  if TO_TCP_QUEUE.ELEMENT_COUNT = 32 then
  2424.   RESULT := TRUE ;
  2425.  end if ;
  2426.  return RESULT;
  2427. exception
  2428.  when others =>
  2429.   PUT_LINE(" Error in QUEUE_EMPTY function ");
  2430. end QUEUE_FULL;
  2431.  
  2432. function QUEUE_EMPTY return BOOLEAN is
  2433.  
  2434. RESULT : BOOLEAN := FALSE;
  2435.  
  2436. begin
  2437.  if TO_TCP_QUEUE.ELEMENT_COUNT = 0 then
  2438.   RESULT := TRUE;
  2439.  end if;
  2440.  return RESULT;
  2441. end QUEUE_EMPTY;
  2442.  
  2443. function GET_Q_STRUCTURE return QUEUE_ELEMENT_POINTER is
  2444.  
  2445. X : QUEUE_ELEMENT_POINTER;
  2446.  
  2447. begin
  2448.  X := QUEUE_FREE_LIST;
  2449.  QUEUE_FREE_LIST := QUEUE_FREE_LIST.NEXT;
  2450.  return X;
  2451. exception
  2452.  when constraint_error =>
  2453.   TEXT_IO.PUT_LINE("CONSTRAINT ERROR IN GET_Q_STRUCTURE");
  2454.  when others =>
  2455.   TEXT_IO.PUT_LINE("UNKNOWN ERROR RAISED IN GET_Q_STRUCTURE");
  2456. end GET_Q_STRUCTURE;
  2457.  
  2458. procedure FREE_Q_STRUCTURE(Q_STRUCTURE : in out QUEUE_ELEMENT_POINTER) is
  2459.  
  2460. begin
  2461.  Q_STRUCTURE.NEXT := QUEUE_FREE_LIST;
  2462.  QUEUE_FREE_LIST := Q_STRUCTURE; --ADDS TO FRONT OF LIST
  2463.  -- MAKE THE POINTER NULL NOW.
  2464.  Q_STRUCTURE := null;
  2465. exception
  2466.  when constraint_error =>
  2467.   TEXT_IO.PUT_LINE("CONSTRAINT ERROR IN FREE_Q_STRUCTURE");
  2468.  when others =>
  2469.   TEXT_IO.PUT_LINE("UNKNOWN ERROR RAISED IN FREE_Q_STRUCTURE");
  2470. end FREE_Q_STRUCTURE;
  2471.  
  2472.  procedure QUEUE_DELETE ( ITEM :Q_ITEM) is
  2473.  
  2474.  BEFORE_PTR : QUEUE_ELEMENT_POINTER := TO_TCP_QUEUE.FIRST_ELEMENT;
  2475.  CURRENT_ELEMENT_POINTER : QUEUE_ELEMENT_POINTER := TO_TCP_QUEUE.FIRST_ELEMENT;
  2476.  FOUND : BOOLEAN := FALSE;
  2477.  
  2478.  begin
  2479.   while CURRENT_ELEMENT_POINTER /= null and (not FOUND) loop
  2480.    if CURRENT_ELEMENT_POINTER.ELEMENT = ITEM then 
  2481.             -- FREE IT AND THE BUFFER UP
  2482.     BEFORE_PTR.NEXT := CURRENT_ELEMENT_POINTER.NEXT;
  2483.     -- TAKE CARE OF DELETING FROM THE END OR BEGINNING OF A LIST.
  2484.     if TO_TCP_QUEUE.FIRST_ELEMENT = CURRENT_ELEMENT_POINTER then
  2485.      TO_TCP_QUEUE.FIRST_ELEMENT := CURRENT_ELEMENT_POINTER.NEXT;
  2486.     end if;
  2487.     if TO_TCP_QUEUE.LAST_ELEMENT = CURRENT_ELEMENT_POINTER then
  2488.          -- WE ARE DELETING LAST ELEMENT.
  2489.      if TO_TCP_QUEUE.FIRST_ELEMENT /= null then
  2490.       TO_TCP_QUEUE.LAST_ELEMENT := BEFORE_PTR;
  2491.      else -- AN EMPTY LIST NOW
  2492.       TO_TCP_QUEUE.LAST_ELEMENT := NULL;
  2493.      end if;
  2494.     end if;
  2495.     -- FREE THE ELEMENT AND DECREMENT THE ELEMENT COUNT
  2496.     FREE_Q_STRUCTURE(CURRENT_ELEMENT_POINTER);
  2497.     TO_TCP_QUEUE.ELEMENT_COUNT := TO_TCP_QUEUE.ELEMENT_COUNT - 1;
  2498.     FOUND := TRUE;
  2499.    else
  2500.     BEFORE_PTR := CURRENT_ELEMENT_POINTER;
  2501.     CURRENT_ELEMENT_POINTER := CURRENT_ELEMENT_POINTER.NEXT;
  2502.    end if;
  2503.   end loop;
  2504.   if not FOUND then --ERROR
  2505.    TEXT_IO.PUT_LINE("WAS UNABLE TO DELETE");
  2506.   end if;
  2507.  exception
  2508.   when constraint_error =>
  2509.    TEXT_IO.PUT_LINE("CONSTRAINT ERROR IN QUEUE DELETE");
  2510.   when others =>
  2511.    TEXT_IO.PUT_LINE(" ERROR IN QUEUE DELETE");
  2512.  end QUEUE_DELETE;
  2513.  
  2514.  procedure QUEUE_CLEAR is
  2515.  
  2516.  X : QUEUE_ELEMENT_POINTER;
  2517.  
  2518.  begin
  2519.   while TO_TCP_QUEUE.ELEMENT_COUNT > 0 loop
  2520.    X := TO_TCP_QUEUE.FIRST_ELEMENT;
  2521.    TO_TCP_QUEUE.FIRST_ELEMENT := X.NEXT;
  2522.    FREE_Q_STRUCTURE(X);
  2523.    TO_TCP_QUEUE.ELEMENT_COUNT := TO_TCP_QUEUE.ELEMENT_COUNT - 1;
  2524.   end loop;
  2525.   -- RESET THE HEAD AND TAIL POINTERS.
  2526.   TO_TCP_QUEUE.FIRST_ELEMENT := null;
  2527.   TO_TCP_QUEUE.LAST_ELEMENT := null;
  2528.  exception
  2529.   when constraint_error =>
  2530.    TEXT_IO.PUT_LINE("CONSTRAINT ERROR IN QUEUE CLEAR");
  2531.   when others =>
  2532.    TEXT_IO.PUT_LINE("UNKNOWN ERROR TYPE IN QUEUE CLEAR");
  2533.  end QUEUE_CLEAR;
  2534.  
  2535.  procedure QUEUE_ADD ( ITEM : Q_ITEM) is
  2536.  
  2537.  NEW_ITEM : QUEUE_ELEMENT_POINTER := GET_Q_STRUCTURE;
  2538.  
  2539.  begin
  2540.   NEW_ITEM.ELEMENT := ITEM;
  2541.   NEW_ITEM.NEXT := null;
  2542.   if TO_TCP_QUEUE.ELEMENT_COUNT < MAX_QUEUE_SIZE theN
  2543.    if TO_TCP_QUEUE.ELEMENT_COUNT /= 0 then 
  2544.     -- ITS NOT AN EMPTY QUEUE. SO LINK FORMER
  2545.     -- LAST ITEM TO NEW ONE.
  2546.     TO_TCP_QUEUE.LAST_ELEMENT.NEXT := NEW_ITEM;
  2547.    else -- FIRST ADD TO THE QUEUE
  2548.     TO_TCP_QUEUE.FIRST_ELEMENT := NEW_ITEM;
  2549.    end if;
  2550.    TO_TCP_QUEUE.LAST_ELEMENT := NEW_ITEM;
  2551.    TO_TCP_QUEUE.ELEMENT_COUNT := TO_TCP_QUEUE.ELEMENT_COUNT + 1;
  2552.   else -- NO ROOM TOO BAD
  2553.    FREE_Q_STRUCTURE(NEW_ITEM);
  2554.   end if;
  2555.  exception
  2556.   when constraint_error =>
  2557.    PUT_LINE("CONSTRAINT ERROR IN QUEUE ADD");
  2558.   when others =>
  2559.    PUT_LINE("ERROR IN QADD");
  2560.    INT_IO.PUT ( TO_TCP_QUEUE.ELEMENT_COUNT);
  2561.  end QUEUE_ADD;
  2562.  
  2563. procedure QUEUE_GET ( ITEM : in out Q_ITEM) is
  2564.  
  2565. Q_ELEMENT_TO_BE_FREED : QUEUE_ELEMENT_POINTER;
  2566.  
  2567. begin
  2568.  if TO_TCP_QUEUE.ELEMENT_COUNT > 0 then
  2569.   TO_TCP_QUEUE.ELEMENT_COUNT := TO_TCP_QUEUE.ELEMENT_COUNT - 1;
  2570.   Q_ELEMENT_TO_BE_FREED := TO_TCP_QUEUE.FIRST_ELEMENT;
  2571.   ITEM := TO_TCP_QUEUE.FIRST_ELEMENT.ELEMENT;
  2572.   TO_TCP_QUEUE.FIRST_ELEMENT := TO_TCP_QUEUE.FIRST_ELEMENT.NEXT;
  2573.   if TO_TCP_QUEUE.ELEMENT_COUNT = 0 then -- AN EMPTY LIST
  2574.    TO_TCP_QUEUE.LAST_ELEMENT := null;
  2575.   end if;
  2576.   FREE_Q_STRUCTURE(Q_ELEMENT_TO_BE_FREED); -- FREE UP THE FORMER FIRST ELEMENT
  2577.  else -- AN EMPTY LIST
  2578.   TEXT_IO.PUT_LINE("A FOOLISH QGET ATTEMPT ON AN EMPTY LIST");
  2579.  end if;
  2580. exception
  2581.  when constraint_error =>
  2582.   PUT_LINE("CONSTRAINT ERROR IN QGET");
  2583.  when others =>
  2584.   PUT_LINE("UNKNOWN  ERROR IN QUEUE_GET");
  2585. end QUEUE_GET;
  2586.  
  2587. task body TCP_Q is
  2588.  
  2589. begin
  2590.  loop
  2591.   select
  2592.    when not QUEUE_EMPTY =>
  2593.     accept Q_GET ( ITEM : in out Q_ITEM ) do
  2594.      QUEUE_GET ( ITEM ) ; 
  2595.     end Q_GET;
  2596.   or
  2597.    when not QUEUE_FULL =>
  2598.     accept Q_ADD ( ITEM : in Q_ITEM ) do
  2599.      QUEUE_ADD ( ITEM ) ;
  2600.     end Q_ADD ;
  2601.   end select ;
  2602.  end loop ;
  2603. end TCP_Q ;
  2604.  
  2605. procedure INITIALIZE_QUEUES is
  2606.  
  2607.  --   THIS PROCEDURE IS CALLED TO SET UP A FREE LIST OF QUEUE ELEMENTS.
  2608.  --   IT IS CALLED AT SYSTEM INITIALIZATION TIME.
  2609.  --
  2610.  --   THIS ROUTINE ALLOCATES AND LINKS TOGETHER IN A LIST (POINTED TO BY
  2611.  --   QUEUE_FREE_LIST) OF QUEUE ELEMENTS TO BE USED BY ALL OF THE QUEUE
  2612.  --   ROUTINES. IT ALLOCATES THEM VIA NEW. THEY ARE NEVER DEALLOCATED.
  2613.  --   THEY ARE SIMPLY PUT BACK IN THE FREE QUEUE ELEMENT LIST.
  2614.  --   THE MAX QUEUE SIZE TIMES THE NUMBER OF QUEUES IS THE NUMBER OF QUEUE\
  2615.  --   ELEMENTS THAT ARE ALLOCATED.
  2616.  
  2617. NEXT_STRUCTURE : QUEUE_ELEMENT_POINTER;
  2618.  
  2619. begin
  2620.  QUEUE_FREE_LIST := NEW QUEUE_ELEMENT;
  2621.  NEXT_STRUCTURE :=  NEW QUEUE_ELEMENT;
  2622.  QUEUE_FREE_LIST.NEXT := NEXT_STRUCTURE;
  2623.  for I in 3..MAX_QUEUE_SIZE*NUMBER_OF_QUEUES loop
  2624.   -- SET UP A FREE LIST OF QUEUE STRUCTURES.
  2625.   NEXT_STRUCTURE.NEXT := NEW QUEUE_ELEMENT;
  2626.   NEXT_STRUCTURE := NEXT_STRUCTURE.NEXT;
  2627.  end loop;
  2628. end INITIALIZE_QUEUES;
  2629.  
  2630. begin --intialization
  2631.  INITIALIZE_QUEUES;
  2632.  
  2633. end TCP_Q_TASK ;
  2634. --::::::::::::::
  2635. --tcp_queue_.ada
  2636. --::::::::::::::
  2637. -----------------------------------------------------------------------
  2638. --
  2639. --         DoD Protocols    NA-00001-200       80-01020-100(-)
  2640. --         E-Systems, Inc.  August 07, 1985
  2641. --
  2642. --         TCP_QUEUE_.ADA       Author : Jim Baldo
  2643. --
  2644. -----------------------------------------------------------------------
  2645. with BUFFER_DATA;            use BUFFER_DATA;
  2646. with MODULO;                use MODULO;
  2647. with T_TCP_GLOBALS_DATA_STRUCTURES;    USE T_TCP_GLOBALS_DATA_STRUCTURES;
  2648.  
  2649. --         ************** GLOBAL ROUTINES ***************
  2650. ------------------------- GLOBAL Q PACKAGE --------------------------------
  2651.  
  2652.                 package QUEUES is
  2653.  
  2654.         ----------------------------------------------------
  2655.         --This implementation is for use with the DEC/Ada --
  2656.         --compiler .                                      --
  2657.         ----------------------------------------------------
  2658.  
  2659. -------------------------------------------------------------------------------
  2660. -- This package will contain all data and routines necessary to manipulate   --
  2661. -- the queues.                                                               --
  2662. -------------------------------------------------------------------------------
  2663.  
  2664. procedure INITIALIZE_QUEUES;
  2665.  
  2666.     --This subprogram allocates and links together in a list (pointed to by
  2667.     --queue_free_list) of queue elements to be used by all of the queue
  2668.     --routines. It allocates them via new. They are never deallocated.
  2669.     --They are simply put back in the free queue element list.
  2670.     --The max queue size times the number of queues is the number of queue
  2671.     --elements that are allocated.
  2672.  
  2673. function QUEUE_EMPTY(QUEUE : in QNAME; LCN : in TCB_PTR) return BOOLEAN;
  2674.  
  2675.     --This function returns a boolean indication of whether a queue for a
  2676.     --specific TCB as defined by the LCN is empty.
  2677.  
  2678. procedure QUEUE_GET( QUEUE : in QNAME; 
  2679.                      LCN : in TCB_PTR; 
  2680.                      ITEM : in out STD_Q_ITEM);
  2681.  
  2682.     --This subprogram obtains a queue element from a specified queue which
  2683.     --passed as parameter QUEUE.  If the a queue element is availible  
  2684.     --it is loaded into ITEM.  ITEM returns null in ITEM.BUFFER and zero
  2685.     --in ITEM.LENGTH if queue elements are empty.
  2686.  
  2687. procedure QUEUE_DELETE( QUEUE : in QNAME; 
  2688.                         LCN : in TCB_PTR; 
  2689.                         ITEM : in STD_Q_ITEM);
  2690.  
  2691.     --This subprogram will delete a messaged from a specified queue and 
  2692.     --associated LCN.
  2693.  
  2694. procedure DELETE_FROM_RETRANS_QUEUE( LCN : in TCB_PTR; 
  2695.                                      SEQ_NUM : in MODULAR);
  2696.  
  2697.     --This subprogram removes a message specified by the LCN and SEQ_QUN 
  2698.     --parameters.
  2699.  
  2700. function QUEUE_SIZE( QUEUE :  in QNAME) return SIXTEEN_BITS ;
  2701.  
  2702.     --The element count of the queue header is returned as the size of
  2703.     --the queue.  
  2704.  
  2705. procedure QUEUE_CLEAR( QUEUE : in QNAME; LCN : in TCB_PTR);
  2706.  
  2707.     --This subprogram clears a specified queue of all messages belonging 
  2708.     --to the LCN parameter passed as an argument.
  2709.  
  2710. procedure QUEUE_CLEAR(QUEUE : in QNAME);
  2711.  
  2712.     --This procedure is called to clear a queue of all its entries.  
  2713.       --It will return all the queue structures or queue elements to the 
  2714.     --free list.  The element count is set to zero.  It will also return
  2715.     --any buffers in the queue to the buffer free list.
  2716.  
  2717. procedure QUEUE_ADD( QUEUE : in QNAME; LCN : in TCB_PTR; ITEM : in STD_Q_ITEM);
  2718.  
  2719.     --This subprogram adds a message to a queue specified in the parameter 
  2720.     --list associated with a LCN.
  2721.  
  2722. procedure QUEUE_ADD( QUEUE : in QNAME; 
  2723.                      LCN : in TCB_PTR; 
  2724.                      ITEM : in STD_Q_ITEM; 
  2725.                      RESULT : out BOOLEAN);
  2726.  
  2727.     --This subprogram adds a message to a queue specified in the parameter 
  2728.     --list associated with a LCN.  Parameter RESULT  indicates if the 
  2729.     --queue add was successful.
  2730.  
  2731.  
  2732. procedure QUEUE_ADD_TO_FRONT( QUEUE : in QNAME; 
  2733.                               LCN : in TCB_PTR; 
  2734.                               ITEM : in STD_Q_ITEM);
  2735.  
  2736.     --This subprogram pushes a message on a queue specified in the parameter
  2737.     --list with its associated LCN.
  2738.  
  2739. function QUEUE_RETRANS_TIME(LCN : in TCB_PTR) return THIRTYTWO_BITS ;
  2740.  
  2741.     --This subprogram returns the retransmission time of the first queue 
  2742.     --element of the TCP retransmission queue.
  2743.  
  2744. NULL_BUFFER : PACKED_BUFFER_PTR := NULL;
  2745. NULL_FLAG : BOOLEAN := TRUE;
  2746. NULL_UNPACKED_BUFFER : BUFFER_POINTER;
  2747. QUEUE_FREE_LIST : STD_QUEUE_ELEMENT_POINTER; -- HEAD OF QUEUE FREE LIST
  2748.  
  2749. end QUEUES ;
  2750.  
  2751. --::::::::::::::
  2752. --tcp_queue.ada
  2753. --::::::::::::::
  2754. -----------------------------------------------------------------------
  2755. --
  2756. --         DoD Protocols    NA-00001-200       80-01021-100(-)
  2757. --         E-Systems, Inc.  August 07, 1985
  2758. --
  2759. --         TCP_QUEUE.ADA       Author : Jim Baldo
  2760. --
  2761. -----------------------------------------------------------------------
  2762. -----------------------------GLOBAL Q PACKAGE ----------------------------
  2763.  
  2764. with REAL_TIME_CLOCK_AND_DATE;        use REAL_TIME_CLOCK_AND_DATE;
  2765. with UNCHECKED_CONVERSION;
  2766. with SYSTEM;
  2767. with TEXT_IO;                use TEXT_IO;
  2768. with WITH_TCP_COMMUNICATE;        use WITH_TCP_COMMUNICATE; 
  2769. with IP_GLOBALS ;            use IP_GLOBALS ;
  2770.  
  2771.         package BODY QUEUES is
  2772.  
  2773. package INT_IO_16 is new INTEGER_IO ( SIXTEEN_BITS ) ;
  2774. package INT_IO_32 is new INTEGER_IO ( THIRTYTWO_BITS ) ;
  2775.  
  2776. FREE_Q_ELEMENT : SIXTEEN_BITS ;
  2777.  
  2778. procedure TCP_ERROR( ERROR_INDICATION : in ERROR_TYPE) is
  2779.  
  2780. begin
  2781.  -- INCREMENT THE ERROR COUNTER.
  2782.  LCN.ERROR_TABLE(ERROR_INDICATION) := 
  2783.        LCN.ERROR_TABLE(ERROR_INDICATION) + 1;
  2784. end TCP_ERROR;
  2785.  
  2786. --procedure QUEUE_CHECKER is
  2787. --
  2788. --QUEUE_COUNTER : SIXTEEN_BITS := FREE_Q_ELEMENT;
  2789. --QUEUE_POINTER : STD_QUEUE_ELEMENT_POINTER := QUEUE_FREE_LIST;
  2790. --COUNTER : SIXTEEN_BITS := FREE_Q_ELEMENT;
  2791. --DUMMY : CHARACTER;
  2792. --
  2793. --begin
  2794. -- while QUEUE_COUNTER > 1 loop
  2795. --  if QUEUE_POINTER = null then
  2796. --   PUT_LINE("FOUND A MODIFIED QUEUE ELEMENT");
  2797. --   PUT("NO. := ");
  2798. --   INT_IO_16.PUT(QUEUE_COUNTER);
  2799. --   NEW_LINE;
  2800. --   PUT("STRIKE ANY CHAR TO CONTINUE");
  2801. --   GET(DUMMY);
  2802. --   exit;
  2803. --  end if;
  2804. --  QUEUE_COUNTER := QUEUE_COUNTER - 1;
  2805. --  QUEUE_POINTER := QUEUE_POINTER.NEXT;
  2806. -- end loop;
  2807. --exception
  2808. -- when CONSTRAINT_ERROR =>
  2809. --  PUT_LINE("CONSTRAINT_ERROR IN QUEUE_CHECKER");
  2810. -- when others =>
  2811. --  PUT_LINE("UNKNOWN ERROR IN QUEUE_CHECKER");
  2812. --end QUEUE_CHECKER;
  2813.  
  2814. procedure INITIALIZE_QUEUES is
  2815.  
  2816. NEXT_STRUCTURE : STD_QUEUE_ELEMENT_POINTER;
  2817.  
  2818. begin
  2819.  QUEUE_FREE_LIST := new STD_QUEUE_ELEMENT;
  2820.  NEXT_STRUCTURE := new STD_QUEUE_ELEMENT;
  2821.  QUEUE_FREE_LIST.NEXT := NEXT_STRUCTURE;
  2822.  for I in 2..MAX_QUEUE_SIZE*NUMBER_OF_QUEUES loop
  2823.   -- SET UP A FREE LIST OF QUEUE STRUCTURES.
  2824.   NEXT_STRUCTURE.NEXT := new STD_QUEUE_ELEMENT;
  2825.   NEXT_STRUCTURE := NEXT_STRUCTURE.NEXT;
  2826.  end loop;
  2827.  FREE_Q_ELEMENT := 162;
  2828. end INITIALIZE_QUEUES;
  2829.  
  2830. function QUEUE_EMPTY(QUEUE : in QNAME; LCN : in TCB_PTR) return BOOLEAN is
  2831.  
  2832. RESULT : BOOLEAN := FALSE;
  2833.  
  2834. begin
  2835.  if LCN.QHEADS(QUEUE).ELEMENT_COUNT = 0 then
  2836.   RESULT := TRUE;
  2837.  end if;
  2838.  return RESULT;
  2839. end QUEUE_EMPTY;
  2840.  
  2841. procedure FREE_Q_STRUCTURE(Q_STRUCTURE : in out STD_QUEUE_ELEMENT_POINTER) is
  2842.     
  2843. begin
  2844.  if Q_STRUCTURE /= null then
  2845.   Q_STRUCTURE.NEXT := QUEUE_FREE_LIST;
  2846.   QUEUE_FREE_LIST := Q_STRUCTURE; --Adds to front of list
  2847.   Q_STRUCTURE := null; --make the pointer null now
  2848.   if QUEUE_FREE_LIST.NEXT = null then
  2849.    TEXT_IO.PUT(ASCII.BEL);
  2850.    PUT_LINE("QUEUE_FREE_LIST.NEXT set to null in FREE_Q_STRUCTURE");
  2851.   end if;
  2852.   FREE_Q_ELEMENT := FREE_Q_ELEMENT + 1;
  2853. --  NEW_LINE;
  2854. --  PUT("FREE_Q_ELEMENT := ");
  2855. --  INT_IO_16.PUT(FREE_Q_ELEMENT);
  2856.  else
  2857.   TEXT_IO.PUT(ASCII.BEL);
  2858.   PUT_LINE("null pointer passed to FREE_Q_STRUCTURE");
  2859.  end if;
  2860. exception
  2861.  when constraint_error =>
  2862.   TEXT_IO.PUT_LINE("Constraint error in FREE_Q_STRUCTURE ");
  2863.   TEXT_IO.PUT(ASCII.BEL);
  2864.  when others =>
  2865.   TEXT_IO.PUT_LINE("unknown error raised in FREE_Q_STRUCTURE ");
  2866.   TEXT_IO.PUT(ASCII.BEL);
  2867. end FREE_Q_STRUCTURE;
  2868.     
  2869. procedure QUEUE_GET( QUEUE : in QNAME; 
  2870.                      LCN : in TCB_PTR; 
  2871.                      ITEM : in out STD_Q_ITEM) is
  2872.  
  2873. QHEAD : STD_HEAD_PTR renames LCN.QHEADS(QUEUE);
  2874. Q_ELEMENT_TO_BE_FREED : STD_QUEUE_ELEMENT_POINTER;
  2875. DUMMY : CHARACTER;
  2876.  
  2877. begin
  2878.  --QUEUE_CHECKER;
  2879. -- NEW_LINE;
  2880. -- if QUEUE_FREE_LIST.NEXT = null then
  2881. --  put_line("queue_free_list.next QUEUE_GET= null");
  2882. --  PUT_LINE("STRIKE ANY CHAR TO CONTINUE");
  2883. --  GET(DUMMY);
  2884. -- else
  2885. --  put_line("queue_free_list.next QUEUE_GET/= null");
  2886. -- end if;
  2887.  if QHEAD.ELEMENT_COUNT > 0 then
  2888.   QHEAD.ELEMENT_COUNT := QHEAD.ELEMENT_COUNT - 1;
  2889.   Q_ELEMENT_TO_BE_FREED := QHEAD.FIRST_ELEMENT;
  2890.   -- SET UP IP ID FOR RETRANSMISSION.
  2891.   LCN.RETRANS_IDENT := QHEAD.FIRST_ELEMENT.IP_ID;
  2892.   ITEM := QHEAD.FIRST_ELEMENT.ELEMENT;
  2893.   QHEAD.FIRST_ELEMENT := QHEAD.FIRST_ELEMENT.NEXT;
  2894.   if QHEAD.ELEMENT_COUNT = 0 then -- AN EMPTY LIST
  2895.    QHEAD.LAST_ELEMENT := null;
  2896.   end if;
  2897.   FREE_Q_STRUCTURE(Q_ELEMENT_TO_BE_FREED); 
  2898.   -- FREE UP THE FORMER FIRST ELEMENT
  2899.  else
  2900.   ITEM.BUFFER := null; -- AN EMPTY QUEUE
  2901.   ITEM.LENGTH := 0;   
  2902.   -- AN INDICATION FOR A STANDARD BUFFER NO ENTRY EXISTS
  2903.  end if;
  2904. -- NEW_LINE;
  2905. -- if QUEUE_FREE_LIST.NEXT = null then
  2906. --  put_line("queue_free_list.next QUEUE_GET= null");
  2907. --  PUT_LINE("STRIKE ANY CHAR TO CONTINUE");
  2908. --  GET(DUMMY);
  2909. -- else
  2910. --  put_line("queue_free_list.next QUEUE_GET/= null");
  2911. -- end if;
  2912. -- QUEUE_CHECKER;
  2913. exception
  2914.  when CONSTRAINT_ERROR =>
  2915.   PUT_LINE("CONSTRAINT ERROR IN QGET");
  2916.  when others =>
  2917.   PUT_LINE("UNKNOWN  ERROR IN QUEUE_GET");
  2918. end QUEUE_GET;
  2919.  
  2920. procedure QUEUE_DELETE( QUEUE : in QNAME; 
  2921.                         LCN : in TCB_PTR; 
  2922.                         ITEM : in STD_Q_ITEM) is
  2923.  
  2924. QHEAD : STD_HEAD_PTR renames LCN.QHEADS(QUEUE);
  2925. BEFORE_PTR : STD_QUEUE_ELEMENT_POINTER := QHEAD.FIRST_ELEMENT;
  2926. CURRENT_ELEMENT_POINTER : STD_QUEUE_ELEMENT_POINTER 
  2927.                     := QHEAD.FIRST_ELEMENT;
  2928. FOUND : BOOLEAN := FALSE;
  2929. BUFFTYPE : SIXTEEN_BITS ;
  2930. DUMMY : CHARACTER;
  2931.  
  2932. begin
  2933.  --QUEUE_CHECKER;
  2934.  while CURRENT_ELEMENT_POINTER /= null and (not FOUND) loop
  2935. -- NEW_LINE;
  2936. -- if QUEUE_FREE_LIST.NEXT = null then
  2937. --  put_line("queue_free_list.next QUEUE_DELETE = null");
  2938. --  PUT_LINE("STRIKE ANY CHAR TO CONTINUE");
  2939. --  GET(DUMMY);
  2940. -- else
  2941. --  put_line("queue_free_list.next QUEUE_DELETE /= null");
  2942. -- end if;
  2943.   if CURRENT_ELEMENT_POINTER.ELEMENT = ITEM then
  2944.    -- FREE IT AND THE BUFFER UP
  2945.    if CURRENT_ELEMENT_POINTER.ELEMENT.BUFFER /= null then 
  2946.     -- RETURN BUFFER TO POOL
  2947.    CURRENT_ELEMENT_POINTER.ELEMENT.BUFFER.STATUS := NONE;
  2948.    BUFFREE(CURRENT_ELEMENT_POINTER.ELEMENT.BUFFER, BUFFTYPE);
  2949.    end if;
  2950.    BEFORE_PTR.NEXT := CURRENT_ELEMENT_POINTER.NEXT;
  2951.    -- TAKE CARE OF DELETING FROM THE END 
  2952.    --OR BEGINNING OF A LIST.
  2953.    if QHEAD.FIRST_ELEMENT = CURRENT_ELEMENT_POINTER then
  2954.     QHEAD.FIRST_ELEMENT := CURRENT_ELEMENT_POINTER.NEXT;
  2955.    end if;
  2956.    if QHEAD.LAST_ELEMENT = CURRENT_ELEMENT_POINTER then
  2957.     -- WE ARE DELETING LAST ELEMENT.
  2958.     if QHEAD.FIRST_ELEMENT /= null then
  2959.      QHEAD.LAST_ELEMENT := BEFORE_PTR;
  2960.     else -- AN EMPTY LIST NOW
  2961.      QHEAD.LAST_ELEMENT := null;
  2962.     end if;
  2963.    end if;
  2964.    -- FREE THE ELEMENT AND DECREMENT THE ELEMENT COUNT
  2965.    --FREE_Q_STRUCTURE(CURRENT_ELEMENT_POINTER);
  2966.    QHEAD.ELEMENT_COUNT := QHEAD.ELEMENT_COUNT - 1;
  2967.    FOUND := TRUE;
  2968.   else
  2969.    BEFORE_PTR := CURRENT_ELEMENT_POINTER;
  2970.    CURRENT_ELEMENT_POINTER := CURRENT_ELEMENT_POINTER.NEXT;
  2971.   end if;
  2972. -- NEW_LINE;
  2973. -- if QUEUE_FREE_LIST.NEXT = null then
  2974. --  put_line("queue_free_list.next QUEUE_DELETE = null");
  2975. --  PUT_LINE("STRIKE ANY CHAR TO CONTINUE");
  2976. --  GET(DUMMY);
  2977. -- else
  2978. --  put_line("queue_free_list.next QUEUE_DELETE /= null");
  2979. -- end if;
  2980.  end loop;
  2981.  if not FOUND then
  2982.   --ERROR
  2983.   NEW_LINE;-- DEBUG JB 7/5/85
  2984.   PUT_LINE("ERROR IN DELETE_QUEUE package QUEUES");
  2985.   TCP_ERROR(11);
  2986.  end if;
  2987. -- QUEUE_CHECKER;
  2988. exception
  2989.  when CONSTRAINT_ERROR =>
  2990.   PUT_LINE("CONSTRAINT ERROR IN QUEUE DELETE");
  2991.  when others =>
  2992.   PUT_LINE(" ERROR IN QUEUE DELETE");
  2993. end QUEUE_DELETE;
  2994.  
  2995. procedure DELETE_FROM_RETRANS_QUEUE( LCN : in TCB_PTR; 
  2996.                                      SEQ_NUM : in MODULAR) is
  2997.  
  2998. type FOUR_BYTES is array(1..4) of SYSTEM_BYTE ;
  2999. type ONELONG is array(1..1) of THIRTYTWO_BITS ;
  3000. function CONVERT is new UNCHECKED_CONVERSION(FOUR_BYTES, ONELONG);
  3001. SEARCH_NUM : MODULAR := SEQ_NUM - 1; 
  3002. -- WE GOT IN SND_UNA AND WILL TAKE OFF
  3003. -- EVERTHING THAT IS SND_UNA - 1 OR LESS.
  3004. SEQUENCE_NUM : MODULAR;
  3005. PACKED_BUFFER : PACKED_BUFFER_PTR;
  3006. TEMP : FOUR_BYTES;
  3007. RESULT : ONELONG;
  3008. DATA_LENGTH, DATA_OFFSET, INDEX : SIXTEEN_BITS ;
  3009. QHEAD : STD_HEAD_PTR renames LCN.QHEADS(TCP_RETRANSMIT_QUEUE);
  3010. TEMP_PTR : STD_QUEUE_ELEMENT_POINTER;
  3011. BEFORE_PTR : STD_QUEUE_ELEMENT_POINTER := QHEAD.FIRST_ELEMENT;
  3012. CURRENT_ELEMENT_POINTER : STD_QUEUE_ELEMENT_POINTER := 
  3013.                     QHEAD.FIRST_ELEMENT;
  3014.  
  3015. begin
  3016.  while CURRENT_ELEMENT_POINTER /= null loop 
  3017. -- QUEUE_CHECKER;
  3018. -- NEW_LINE;
  3019. -- if QUEUE_FREE_LIST.NEXT = null then
  3020. --  put_line("queue_free_list.next DELETE_FROM_RETRANS_Q = null");
  3021. --  PUT_LINE("STRIKE ANY CHAR TO CONTINUE");
  3022. --  GET(DUMMY);
  3023. -- else
  3024. --  put_line("queue_free_list.next DELETE_FROM_RETRANS_Q /= null");
  3025. -- end if;
  3026.   -- TAKE ANYTHING WE CAN OFF OF THE QUEUE.
  3027.   PACKED_BUFFER := CURRENT_ELEMENT_POINTER.ELEMENT.BUFFER;
  3028.   -- GET THE DATA OFFSET.
  3029.   INDEX := PACKED_BUFFER.TCP_PTR + 12;
  3030.   DATA_OFFSET := SIXTEEN_BITS ( PACKED_BUFFER.BYTE ( INDEX ) ) / 2**4 ;
  3031.   -- GET THE SEQUENCE NUMBER
  3032.   INDEX := PACKED_BUFFER.TCP_PTR - 1;
  3033.   TEMP(4) :=  PACKED_BUFFER.BYTE ( INDEX + SIXTEEN_BITS ( 4 ) + 4) ; 
  3034.   TEMP(3) :=  PACKED_BUFFER.BYTE ( INDEX + SIXTEEN_BITS ( 3 ) + 4) ; 
  3035.   TEMP(2) :=  PACKED_BUFFER.BYTE ( INDEX + SIXTEEN_BITS ( 2 ) + 4) ; 
  3036.   TEMP(1) :=  PACKED_BUFFER.BYTE ( INDEX + SIXTEEN_BITS ( 1 ) + 4) ; 
  3037. -- GET THE SEQ NUMBER
  3038.   -- INITIALIZE RESULT
  3039.   RESULT(1) := 0;
  3040.   RESULT := CONVERT(TEMP); 
  3041. --  NEW_LINE;
  3042. --  PUT_LINE("RESULT := ");
  3043. --  INT_IO_32.PUT(RESULT(1));
  3044. --  NEW_LINE;
  3045.   -- CONVERT IT TO A LONG INTEGER
  3046.   SEQUENCE_NUM := MODULAR_CONVERT(RESULT(1)); 
  3047.   -- MAKE IT MODULAR
  3048.   -- GET THE DATA LENGTH
  3049.   DATA_LENGTH := CURRENT_ELEMENT_POINTER.ELEMENT.LENGTH -
  3050.              DATA_OFFSET * 4;
  3051.   if DATA_LENGTH > 0 then 
  3052.   -- SINCE WE NEVER SEND DATA WITH A SYN 
  3053.   --OR A FIN( WHICH ARE CONSIDERED DATA
  3054.   -- OCTETS, THE DATA LENGTH IN ADDITION TO THE 
  3055.   --SEQ NUM IS ONE LESS THAN THE
  3056.   -- ACTUAL NUMBER OF DATA OCTETS.
  3057.    DATA_LENGTH := DATA_LENGTH - 1;
  3058.   end if;
  3059. --  xxx := SEQUENCE_NUM + DATA_LENGTH ;
  3060. --  new_line;
  3061. --  put("SEQUENCE_NUM + DATA_LENGTH := ");
  3062. --  int_io_32.put(xxx.hi);
  3063. --  int_io_32.put(xxx.low);
  3064. --  new_line;
  3065.   if SEQUENCE_NUM + DATA_LENGTH <= SEARCH_NUM then 
  3066.    -- DELETE THIS QUEUE ELEMENT.
  3067.    BEFORE_PTR.NEXT := CURRENT_ELEMENT_POINTER.NEXT;
  3068.    -- TAKE CARE OF DELETING FROM THE END OR BEGINNING OF A LIST.
  3069.    if QHEAD.FIRST_ELEMENT = CURRENT_ELEMENT_POINTER then
  3070.     QHEAD.FIRST_ELEMENT := CURRENT_ELEMENT_POINTER.NEXT;
  3071.    end if;
  3072.    if QHEAD.LAST_ELEMENT = CURRENT_ELEMENT_POINTER then
  3073.     -- WE ARE DELETING LAST ELEMENT.
  3074.     if QHEAD.FIRST_ELEMENT /= null then
  3075.      QHEAD.LAST_ELEMENT := BEFORE_PTR;
  3076.     else -- AN EMPTY LIST NOW
  3077.      QHEAD.LAST_ELEMENT := null;
  3078.     end if;
  3079.    end if;
  3080.    TEMP_PTR := BEFORE_PTR.NEXT; 
  3081.    -- THE NEXT ELEMENT TO BE CHECKED
  3082.    -- FREE UP THE ELEMENT AND DECREMENT THE QUEUE COUNT.
  3083.    FREE_Q_STRUCTURE(CURRENT_ELEMENT_POINTER);
  3084.    QHEAD.ELEMENT_COUNT := QHEAD.ELEMENT_COUNT - 1;
  3085.    -- FREE UP THE BUFFER
  3086.    PACKED_BUFFER.STATUS := NONE;
  3087.    BUFFREE(PACKED_BUFFER, 1);
  3088.    -- UPDATE CURRENT_ELEMENT_POINTER TO POINT AT THE 
  3089.    --NEXT ELEMENT TO BE CHECKED.
  3090.    CURRENT_ELEMENT_POINTER := TEMP_PTR;
  3091.   else -- ADVANCE THE POINTERS.
  3092. --   PUT_LINE("MY NAME IS TROUBLE");
  3093. --   PUT("**************");
  3094. --   GET(DUMMY);
  3095. --   NEW_LINE;
  3096.    BEFORE_PTR := CURRENT_ELEMENT_POINTER;
  3097.    CURRENT_ELEMENT_POINTER := CURRENT_ELEMENT_POINTER.NEXT;
  3098.   end if;
  3099. -- NEW_LINE;
  3100. -- if QUEUE_FREE_LIST.NEXT = null then
  3101. --  put_line("queue_free_list.next DELETE_FROM_RETRANS_Q = null");
  3102. --  PUT_LINE("HIT ANY CHARACTER TO CONTINUE ");
  3103. --  GET(DUMMY);
  3104. -- else
  3105. --  put_line("queue_free_list.next DELETE_FROM_RETRANS_Q /= null");
  3106. -- end if;
  3107. -- QUEUE_CHECKER;
  3108.  end loop;
  3109. exception
  3110.  when CONSTRAINT_ERROR =>
  3111.   PUT_LINE("CONSTRAINT ERROR IN DELETE FROM RETRANS QUEUE");
  3112.   PUT_LINE("");
  3113.   PUT("INDEX VALUE IS ");
  3114.   INT_IO_16.PUT(INDEX);
  3115.   INT_IO_16.PUT(PACKED_BUFFER.TCP_PTR);
  3116.   if CURRENT_ELEMENT_POINTER = null then
  3117.    PUT_LINE("A NULL CURRENT ELEMENT POINTER.");
  3118.   end if;
  3119.   if BEFORE_PTR.NEXT = null then
  3120.    PUT_LINE("A NULL BEFORE POINTER NEXT FIELD");
  3121.   end if;
  3122.   if PACKED_BUFFER = null then
  3123.    PUT_LINE("A NULL PACKED BUFFER ON THE RETRANS QUEUE");
  3124.   end if;
  3125.  when others =>
  3126.   PUT_LINE("UNKNOWN ERROR IN DELETE FROM RETRANS QUEUE");
  3127.  end DELETE_FROM_RETRANS_QUEUE;
  3128.  
  3129. function QUEUE_SIZE( QUEUE : in QNAME) return SIXTEEN_BITS  is
  3130.     
  3131. QHEAD : STD_HEAD_PTR renames LCN.QHEADS(QUEUE);
  3132.     
  3133. begin
  3134.  return QHEAD.ELEMENT_COUNT;
  3135. exception
  3136.  when CONSTRAINT_ERROR =>
  3137.   PUT_LINE("CONSTRAINT ERROR in QUEUE_SIZE");
  3138.  when others =>
  3139.   PUT_LINE("unknown error in QUEUE_SIZE");
  3140. end QUEUE_SIZE;
  3141.  
  3142. procedure QUEUE_CLEAR( QUEUE : in QNAME) is
  3143.  
  3144. QHEAD : STD_HEAD_PTR renames LCN.QHEADS(QUEUE);
  3145. X : STD_QUEUE_ELEMENT_POINTER;
  3146. BUFFTYPE : SIXTEEN_BITS ;
  3147. DUMMY : CHARACTER;
  3148.  
  3149. begin
  3150.  while QHEAD.ELEMENT_COUNT > 0 loop
  3151.  --QUEUE_CHECKER;
  3152. -- NEW_LINE;
  3153. -- if QUEUE_FREE_LIST.NEXT = null then
  3154. --  put_line("queue_free_list.next QUEUE_CLEAR= null");
  3155. --  PUT_LINE("STRIKE ANY CHAR TO CONTINUE");
  3156. --  GET(DUMMY);
  3157. -- else
  3158. --  put_line("queue_free_list.next QUEUE_CLEAR /= null");
  3159. -- end if;
  3160.   X := QHEAD.FIRST_ELEMENT;
  3161.   if X.ELEMENT.BUFFER /= null then
  3162.    if X.ELEMENT.BUFFER.STATUS =OWNER_TCP then -- if it is ours,
  3163.                                               -- it is no longer.
  3164.     X.ELEMENT.BUFFER.STATUS := BUFFER_DATA.NONE;
  3165.    end if;
  3166.    X.ELEMENT.BUFFER.STATUS := NONE;
  3167.    BUFFREE(X.ELEMENT.BUFFER, BUFFTYPE);
  3168.   end if;
  3169.   QHEAD.FIRST_ELEMENT := X.NEXT;
  3170.   FREE_Q_STRUCTURE(X);
  3171.   QHEAD.ELEMENT_COUNT := QHEAD.ELEMENT_COUNT - 1;
  3172.  --NEW_LINE;
  3173. -- if QUEUE_FREE_LIST.NEXT = null then
  3174. --  put_line("queue_free_list.next QUEUE_CLEAR = null");
  3175. --  PUT_LINE("STRIKE ANY CHAR TO CONTINUE");
  3176. --  GET(DUMMY);
  3177. -- else
  3178. --  put_line("queue_free_list.next QUEUE_CLEAR /= null");
  3179. -- end if;
  3180. -- QUEUE_CHECKER;
  3181.  end loop;
  3182.  -- reset the head and tail pointers
  3183.  QHEAD.FIRST_ELEMENT := null;
  3184.  QHEAD.LAST_ELEMENT := null;
  3185. exception
  3186.  when CONSTRAINT_ERROR =>
  3187.   PUT_LINE(" CONSTRAINT ERROR IN QUEUE CLEAR");
  3188.  when others =>
  3189.   PUT_LINE(" UNKNOWN ERROR TYPE IN QUEUE CLEAR");
  3190. end QUEUE_CLEAR;
  3191.  
  3192. procedure QUEUE_CLEAR( QUEUE : in QNAME; LCN : in TCB_PTR) is
  3193.  
  3194. QHEAD : STD_HEAD_PTR renames LCN.QHEADS(QUEUE);
  3195. X : STD_QUEUE_ELEMENT_POINTER;
  3196. BUFFTYPE : SIXTEEN_BITS ;
  3197. DUMMY : CHARACTER;
  3198.  
  3199. begin
  3200.  while QHEAD.ELEMENT_COUNT > 0 loop
  3201.  --QUEUE_CHECKER;
  3202. -- NEW_LINE;
  3203. -- if QUEUE_FREE_LIST.NEXT = null then
  3204. --  put_line("queue_free_list.next QUEUE_CLEAR = null");
  3205. --  PUT_LINE("STRIKE ANY CHAR TO CONTINUE");
  3206. --  GET(DUMMY);
  3207. -- else
  3208. --  put_line("queue_free_list.next QUEUE_CLEAR /= null");
  3209. -- end if;
  3210.   X := QHEAD.FIRST_ELEMENT;
  3211.   if X.ELEMENT.BUFFER /= null then
  3212.    X.ELEMENT.BUFFER.STATUS := NONE;
  3213.    BUFFREE(X.ELEMENT.BUFFER, BUFFTYPE);
  3214.   end if;
  3215.   QHEAD.FIRST_ELEMENT := X.NEXT;
  3216.   FREE_Q_STRUCTURE(X);
  3217.   QHEAD.ELEMENT_COUNT := QHEAD.ELEMENT_COUNT - 1;
  3218.  --NEW_LINE;
  3219. -- if QUEUE_FREE_LIST.NEXT = null then
  3220. --  put_line("queue_free_list.next QUEUE_CLEAR = null");
  3221. --  PUT_LINE("STRIKE ANY CHAR TO CONTINUE");
  3222. --  GET(DUMMY);
  3223. -- else
  3224. --  put_line("queue_free_list.next QUEUE_CLEAR /= null");
  3225. -- end if;
  3226. -- QUEUE_CHECKER;
  3227.  end loop;
  3228.  -- RESET THE HEAD AND TAIL POINTERS.
  3229.  QHEAD.FIRST_ELEMENT := null;
  3230.  QHEAD.LAST_ELEMENT := null;
  3231. exception
  3232.  when CONSTRAINT_ERROR =>
  3233.   PUT_LINE("CONSTRAINT ERROR IN QUEUE CLEAR");
  3234.  when others =>
  3235.   PUT_LINE("UNKNOWN ERROR TYPE IN QUEUE CLEAR");
  3236. end QUEUE_CLEAR;
  3237.  
  3238. function GET_Q_STRUCTURE return STD_QUEUE_ELEMENT_POINTER is
  3239.  
  3240. X : STD_QUEUE_ELEMENT_POINTER;
  3241. DUMMY : CHARACTER;
  3242.  
  3243. begin
  3244.  X := QUEUE_FREE_LIST;
  3245.  if X = null then
  3246.   TEXT_IO.PUT(ASCII.BEL);
  3247.   put_line("who stuffed the queue element with a null pointer?");
  3248.   put_line("GET_Q_STRUCTURE");
  3249.  end if;
  3250.  if QUEUE_FREE_LIST.NEXT /= null then
  3251.   QUEUE_FREE_LIST := QUEUE_FREE_LIST.NEXT;
  3252. --  NEW_LINE;
  3253. --  PUT("FREE_Q_ELEMENT := ");
  3254. --  FREE_Q_ELEMENT := FREE_Q_ELEMENT - 1;
  3255. --  INT_IO_16.PUT(FREE_Q_ELEMENT);
  3256.   if X = QUEUE_FREE_LIST then
  3257.    NEW_LINE;
  3258.    PUT_LINE("X = QUEUE_FREE_LIST (OH NO!!!)");
  3259.    PUT_LINE("STIKE ANY CHARACTER TO CONTINUE");
  3260.    GET(DUMMY);
  3261.   end if;
  3262.   return X;
  3263.  else
  3264.   TEXT_IO.PUT(ASCII.BEL);
  3265.   PUT_LINE("NULL POINTER GET_Q_STRUCTURE");
  3266.   RETURN null;
  3267.  end if;
  3268. exception
  3269.  when constraint_error =>
  3270.   PUT_LINE("CONSTRAINT ERROR IN GET_Q_STRUCTURE");
  3271.  when others =>
  3272.   PUT_LINE("UNKNOWN ERROR RAISED IN GET_Q_STRUCTURE");
  3273. end GET_Q_STRUCTURE;
  3274.  
  3275. procedure QUEUE_ADD( QUEUE : in QNAME; 
  3276.                      LCN : in TCB_PTR; 
  3277.                      ITEM : in STD_Q_ITEM) is
  3278.  
  3279. QHEAD : STD_HEAD_PTR renames LCN.QHEADS(QUEUE);
  3280. NEW_ITEM : STD_QUEUE_ELEMENT_POINTER := GET_Q_STRUCTURE;
  3281. DUMMY : CHARACTER;
  3282.  
  3283. begin
  3284.  --QUEUE_CHECKER;
  3285. -- NEW_LINE;
  3286. -- if QUEUE_FREE_LIST.NEXT = null then
  3287. --  put_line("queue_free_list.next QUEUE_ADD = null");
  3288. --  PUT_LINE("STRIKE ANY CHAR TO CONTINUE");
  3289. --  GET(DUMMY);
  3290. -- else
  3291. --  put_line("queue_free_list.next QUEUE_ADD /= null");
  3292. -- end if;
  3293.  NEW_ITEM.ELEMENT := ITEM;
  3294.  NEW_ITEM.NEXT := null;
  3295.  if QUEUE = TCP_RETRANSMIT_QUEUE then
  3296.  -- PUT ON A TIME FOR THE RETRANS QUEUE
  3297.  NEW_ITEM.TIME := THIRTYTWO_BITS ( SYSTEM_TIME ) ;
  3298.  NEW_ITEM.IP_ID := LCN.IDENT; -- SAVE THE ID FOR IP.
  3299.  end if;
  3300.  if QHEAD.ELEMENT_COUNT < MAX_QUEUE_SIZE then
  3301.   if QHEAD.ELEMENT_COUNT /= 0 then
  3302.    -- ITS NOT AN EMPTY QUEUE. SO LINK FORMER
  3303.    -- LAST ITEM TO NEW ONE.
  3304.    QHEAD.LAST_ELEMENT.NEXT := NEW_ITEM;
  3305.   else -- FIRST ADD TO THE QUEUE
  3306.    QHEAD.FIRST_ELEMENT := NEW_ITEM;
  3307.   end if;
  3308.   QHEAD.LAST_ELEMENT := NEW_ITEM;
  3309.   QHEAD.ELEMENT_COUNT := QHEAD.ELEMENT_COUNT + 1;
  3310.  else -- NO ROOM TOO BAD
  3311.   TCP_ERROR(18);
  3312.   FREE_Q_STRUCTURE(NEW_ITEM);
  3313.  end if;
  3314.  --NEW_LINE;
  3315. -- if QUEUE_FREE_LIST.NEXT = null then
  3316. --  put_line("queue_free_list.next QUEUE_ADD = null");
  3317. --  PUT_LINE("STRIKE ANY CHAR TO CONTINUE");
  3318. --  GET(DUMMY);
  3319. -- else
  3320. --  put_line("queue_free_list.next QUEUE_ADD /= null");
  3321. -- end if;
  3322. -- QUEUE_CHECKER;
  3323. exception
  3324.  when CONSTRAINT_ERROR =>
  3325.   PUT_LINE("CONSTRAINT ERROR IN QUEUE ADD");
  3326.  when others =>
  3327.   PUT_LINE("ERROR IN QADD");
  3328. --  INTEGER_IO.PUT(LCN);
  3329.   INT_IO_16.PUT(QHEAD.ELEMENT_COUNT);
  3330. end QUEUE_ADD;
  3331.  
  3332. procedure QUEUE_ADD( QUEUE : in QNAME; 
  3333.                      LCN : in TCB_PTR; 
  3334.                      ITEM : in STD_Q_ITEM; 
  3335.                      RESULT : out BOOLEAN) is
  3336.  
  3337. QHEAD : STD_HEAD_PTR renames LCN.QHEADS(QUEUE);
  3338. NEW_ITEM : STD_QUEUE_ELEMENT_POINTER := GET_Q_STRUCTURE;
  3339. DUMMY : CHARACTER;
  3340.  
  3341. begin
  3342.  --QUEUE_CHECKER;
  3343. -- NEW_LINE;
  3344. -- if QUEUE_FREE_LIST.NEXT = null then
  3345. --  put_line("queue_free_list.next QUEUE_ADD = null");
  3346. --  PUT_LINE("STRIKE ANY CHAR TO CONTINUE");
  3347. --  GET(DUMMY);
  3348. -- else
  3349. --  put_line("queue_free_list.next QUEUE_ADD /= null");
  3350. -- end if;
  3351.  NEW_ITEM.ELEMENT := ITEM;
  3352.  NEW_ITEM.NEXT := null;
  3353.  if QUEUE = TCP_RETRANSMIT_QUEUE then
  3354.   -- PUT ON A TIME FOR THE RETRANS QUEUE
  3355.   NEW_ITEM.TIME := THIRTYTWO_BITS ( SYSTEM_TIME ) ;
  3356.   NEW_ITEM.IP_ID := LCN.IDENT; -- SAVE THE ID FOR IP.
  3357.  end if;
  3358.  if QHEAD.ELEMENT_COUNT < MAX_QUEUE_SIZE then
  3359.   if QHEAD.ELEMENT_COUNT /= 0 then
  3360.    -- ITS NOT AN EMPTY QUEUE. SO LINK FORMER
  3361.    -- LAST ITEM TO NEW ONE.
  3362.    QHEAD.LAST_ELEMENT.NEXT := NEW_ITEM;
  3363.   else --FIRST ELEMENT IN QUEUE
  3364.    QHEAD.FIRST_ELEMENT := NEW_ITEM;
  3365.   end if;
  3366.   QHEAD.LAST_ELEMENT := NEW_ITEM;
  3367.   QHEAD.ELEMENT_COUNT := QHEAD.ELEMENT_COUNT + 1;
  3368.   RESULT := FALSE;
  3369.  else -- NO ROOM TOO BAD. 
  3370.   -- PUT QUEUE STRUCTURE BACK ON THE FREE LIST.
  3371.   TCP_ERROR(18);
  3372.   FREE_Q_STRUCTURE(NEW_ITEM);
  3373.   RESULT := TRUE;
  3374.  end if;
  3375.  --NEW_LINE;
  3376. -- if QUEUE_FREE_LIST.NEXT = null then
  3377. --  put_line("queue_free_list.next QUEUE_ADD = null");
  3378. --  PUT_LINE("STRIKE ANY CHAR TO CONTINUE");
  3379. --  GET(DUMMY);
  3380. -- else
  3381. --  put_line("queue_free_list.next QUEUE_ADD /= null");
  3382. -- end if;
  3383. -- QUEUE_CHECKER;
  3384. exception
  3385.  when CONSTRAINT_ERROR =>
  3386.   PUT_LINE("CONSTRAINT ERROR IN ");
  3387.   PUT_LINE("QUEUE ADD, WITH RESULT INDICATION.");
  3388.  when others =>
  3389.   PUT_LINE("UNKNOWN ERROR TYPE IN ");
  3390.   PUT_LINE("QUEUE ADD, WITH RESULT INDICATION.");
  3391. end QUEUE_ADD;
  3392.  
  3393. procedure QUEUE_ADD_TO_FRONT( QUEUE : in QNAME; 
  3394.                               LCN : in TCB_PTR; 
  3395.                               ITEM : in STD_Q_ITEM) is
  3396.  
  3397. QHEAD : STD_HEAD_PTR renames LCN.QHEADS(QUEUE);
  3398. NEW_ITEM : STD_QUEUE_ELEMENT_POINTER := GET_Q_STRUCTURE; 
  3399. DUMMY : CHARACTER;
  3400. -- GET A QUEUE STRUCTURE FROM FREE LIST.
  3401.  
  3402. begin
  3403.  --QUEUE_CHECKER;
  3404. -- NEW_LINE;
  3405. -- if QUEUE_FREE_LIST.NEXT = null then
  3406. --  put_line("queue_free_list.next QUEUE_ADD_TO_FRONT = null");
  3407. --  PUT_LINE("STRIKE ANY CHAR TO CONTINUE");
  3408. --  GET(DUMMY);
  3409. -- else
  3410. --  put_line("queue_free_list.next QUEUE_ADD_TO_FRONT /= null");
  3411. -- end if;
  3412.  NEW_ITEM.ELEMENT := ITEM;
  3413.  NEW_ITEM.NEXT := null;
  3414.  if QHEAD.ELEMENT_COUNT < MAX_QUEUE_SIZE then
  3415.   NEW_ITEM.NEXT := QHEAD.FIRST_ELEMENT;
  3416.   QHEAD.FIRST_ELEMENT := NEW_ITEM;
  3417.   if QHEAD.ELEMENT_COUNT = 0 then
  3418.    -- ADDING TO AN EMPTY LIST
  3419.    QHEAD.LAST_ELEMENT := NEW_ITEM;
  3420.   end if;
  3421.   QHEAD.ELEMENT_COUNT := QHEAD.ELEMENT_COUNT + 1;
  3422.  else -- A MAJOR PROBLEM SHOULDN'T HAPPEN
  3423.   TCP_ERROR(18);
  3424.   FREE_Q_STRUCTURE(NEW_ITEM); 
  3425.   -- FREE QUEUE STRUCTURE ANYWAY.
  3426.   PUT_LINE("NO ROOM FOR QUEUE ADD TO FRONT IN TCP");
  3427.  end if;
  3428.  --NEW_LINE;
  3429. -- if QUEUE_FREE_LIST.NEXT = null then
  3430. --  put_line("queue_free_list.next QUEUE_ADD_TO_FRONT = null");
  3431. --  PUT_LINE("STRIKE ANY CHAR TO CONTINUE");
  3432. --  GET(DUMMY);
  3433. -- else
  3434. --  put_line("queue_free_list.next QUEUE_ADD_TO_FRONT /= null");
  3435. -- end if;
  3436. -- QUEUE_CHECKER;
  3437. exception
  3438.  when CONSTRAINT_ERROR =>
  3439.   PUT_LINE("CONSTRAINT ERROR IN QUEUE ADD TO FRONT");
  3440.  when others =>
  3441.   PUT_LINE("UNKNOWN ERROR TYPE IN QUEUE ADD TO FRONT");
  3442. end QUEUE_ADD_TO_FRONT;
  3443.  
  3444. function QUEUE_RETRANS_TIME( LCN : in TCB_PTR) return THIRTYTWO_BITS is
  3445.  
  3446. QHEAD : STD_HEAD_PTR renames LCN.QHEADS(TCP_RETRANSMIT_QUEUE);
  3447.  
  3448. begin
  3449.  RETURN QHEAD.FIRST_ELEMENT.TIME;
  3450. end QUEUE_RETRANS_TIME;
  3451.  
  3452. begin
  3453.  
  3454.  INITIALIZE_QUEUES ;
  3455.  
  3456. end QUEUES;
  3457. --::::::::::::::
  3458. --tcp_to_ulp_.ada
  3459. --::::::::::::::
  3460. -----------------------------------------------------------------------
  3461. --
  3462. --         DoD Protocols    NA-00001-200       80-01023-100(-)
  3463. --         E-Systems, Inc.  August 07, 1985
  3464. --
  3465. --         TCP_TO_ULP_.ADA       Author : Jim Baldo
  3466. --
  3467. -----------------------------------------------------------------------
  3468. with WITH_TCP_COMMUNICATE ;                     use WITH_TCP_COMMUNICATE ;
  3469.      
  3470.                         package TCP_TO_ULP_COMMUNICATE is
  3471.      
  3472. procedure MESSAGE_FOR_USER ( USER_MESS : in out USER_MESSAGE ) ;
  3473.      
  3474.         --This procedure is used by TCP to put a message  for the ULP.
  3475.      
  3476. end TCP_TO_ULP_COMMUNICATE ;
  3477. --::::::::::::::
  3478. --tcp_to_ulp.ada
  3479. --::::::::::::::
  3480. -----------------------------------------------------------------------
  3481. --
  3482. --         DoD Protocols    NA-00001-200       80-01024-100(-)
  3483. --         E-Systems, Inc.  August 07, 1985
  3484. --
  3485. --         TCP_TO_ULP.ADA       Author : Jim Baldo
  3486. --
  3487. -----------------------------------------------------------------------
  3488. with BUFFER_DATA;                use BUFFER_DATA;
  3489. with STARLET ;                    use STARLET ;
  3490. with CONDITION_HANDLING ;            use CONDITION_HANDLING ;
  3491. with UNCHECKED_CONVERSION ;
  3492. with TEXT_IO ;                    use TEXT_IO;
  3493. with TASKING_SERVICES ;                use TASKING_SERVICES ;
  3494. with SYSTEM ;                    use SYSTEM ;
  3495.  
  3496.  
  3497.             package body TCP_TO_ULP_COMMUNICATE is
  3498.  
  3499. function PHYSICAL_ADDRESS is new 
  3500.            UNCHECKED_CONVERSION ( ADDRESS, UNSIGNED_LONGWORD ) ;
  3501.  
  3502. type XUSER_MESSAGE_TYPE is
  3503.  record
  3504.   THE_USER_MESSAGE : USER_MESSAGE;
  3505.   THE_BUFFER : PACKED_BUFFER;
  3506.   THE_STATUS_PARAMS : STATUS_RECORD;
  3507.  end record;
  3508.  
  3509. procedure MESSAGE_FOR_USER ( USER_MESS : in out USER_MESSAGE ) is
  3510.  
  3511. MBX_STATUS  : COND_VALUE_TYPE ;
  3512. XUSER_MESSAGE : XUSER_MESSAGE_TYPE;
  3513.  
  3514. begin
  3515.  XUSER_MESSAGE.THE_USER_MESSAGE := USER_MESS;
  3516.  case USER_MESS.MESSAGE_NUMBER is
  3517.   when 10 | 19 =>
  3518.    XUSER_MESSAGE.THE_BUFFER := USER_MESS.DATA_BUFFER.ALL;
  3519.    USER_MESS.DATA_BUFFER.IN_USE := FALSE;
  3520.    USER_MESS.DATA_BUFFER.STATUS := NONE;
  3521.    BUFFREE( USER_MESS.DATA_BUFFER, 0 );
  3522.   when 15 =>
  3523.    new_line;--debug
  3524.    put_line("About to send a STATUS to ULP");
  3525.    XUSER_MESSAGE.THE_STATUS_PARAMS := USER_MESS.STATUS_PARAMS ;
  3526.   when others =>
  3527.    null;
  3528.  end case;
  3529.  TASK_QIOW ( STATUS  => MBX_STATUS,
  3530.              CHAN    => USER_MESS.LOCAL_CONNECTION_NAME.CHANNEL_PTR,
  3531.              FUNC    => IO_WRITEVBLK + IO_M_NOW,
  3532.              P1      => PHYSICAL_ADDRESS ( XUSER_MESSAGE'ADDRESS ),
  3533.              P2      => UNSIGNED_LONGWORD( XUSER_MESSAGE'SIZE/8 ) ) ;
  3534.  if not SUCCESS ( MBX_STATUS ) then
  3535.   PUT_LINE ( "Error in write attempt to ULP mailbox from TCP ") ;--for debug
  3536.   SIGNAL(MBX_STATUS) ;
  3537.  end if; 
  3538.  case USER_MESS.MESSAGE_NUMBER is
  3539.   when 8 | 16 | 18 | 24 => --delete mailbox: successful close; abort; 
  3540.                            --connection timeout; connection reset
  3541.    DELMBX( STATUS  => MBX_STATUS,
  3542.            CHAN    => USER_MESS.LOCAL_CONNECTION_NAME.CHANNEL_PTR ) ;
  3543.   when others =>
  3544.    null;
  3545.  end case;
  3546. end MESSAGE_FOR_USER ;
  3547.  
  3548. end TCP_TO_ULP_COMMUNICATE ;
  3549. --::::::::::::::
  3550. --tcp_ulp_get_.ada
  3551. --::::::::::::::
  3552. -----------------------------------------------------------------------
  3553. --
  3554. --         DoD Protocols    NA-00001-200       80-01025-100(-)
  3555. --         E-Systems, Inc.  August 07, 1985
  3556. --
  3557. --         TCP_ULP_GET_.ADA       Author : Jim Baldo
  3558. --
  3559. -----------------------------------------------------------------------
  3560. with WITH_TCP_COMMUNICATE ;                     use WITH_TCP_COMMUNICATE ;
  3561.      
  3562.                         package GET_MESSAGES_FROM_ULP is
  3563.      
  3564.                 ------------------------------------------------
  3565.                 --This implementation is for the DEC/Ada      --
  3566.                 --compiler .                                  --
  3567.                 ------------------------------------------------
  3568.      
  3569. task OBTAIN_MESSAGE_FROM_ULP_QUEUE ;
  3570.      
  3571. end GET_MESSAGES_FROM_ULP ;
  3572. --::::::::::::::
  3573. --tcp_ulp_get.ada
  3574. --::::::::::::::
  3575. -----------------------------------------------------------------------
  3576. --
  3577. --         DoD Protocols    NA-00001-200       80-01026-100(-)
  3578. --         E-Systems, Inc.  August 07, 1985
  3579. --
  3580. --         TCP_ULP_GET.ADA       Author : Jim Baldo
  3581. --
  3582. -----------------------------------------------------------------------
  3583. with TCP_Q_TASK ;                                       use TCP_Q_TASK ;
  3584. with UNCHECKED_CONVERSION ;
  3585. with TASKING_SERVICES ;                                 use TASKING_SERVICES ;
  3586. with SYSTEM ;                                           use SYSTEM ;
  3587. with CONDITION_HANDLING ;                               use CONDITION_HANDLING ;
  3588. with STARLET ;                                          use STARLET ;
  3589. with TEXT_IO ;                                          use TEXT_IO ;
  3590. with BUFFER_DATA ;                                      use BUFFER_DATA ;
  3591.      
  3592.                         package body GET_MESSAGES_FROM_ULP is
  3593.      
  3594.      
  3595. package INT_IO is new INTEGER_IO( SIXTEEN_BITS ) ;
  3596.      
  3597. --Conversion information
  3598. type XMESSAGE_TYPE is
  3599.  record
  3600.   THE_TCP_MESSAGE : MESSAGE;
  3601.   THE_BUFFER : PACKED_BUFFER;
  3602.  end record;
  3603.      
  3604. type XUSER_MESSAGE_TYPE is
  3605.   record
  3606.     THE_USER_MESSAGE : USER_MESSAGE ;
  3607.     THE_BUFFER       : PACKED_BUFFER ;
  3608.     THE_STATUS       : STATUS_RECORD ;
  3609.   end record ;
  3610.      
  3611. --Mailbox information
  3612. RETURN_STATUS : COND_VALUE_TYPE ;
  3613. PERMANENT_MAILBOX : BOOLEAN := TRUE ;
  3614. TO_TCP_CHANNEL : CHANNEL_TYPE ;
  3615. MAILBOX_PROTECTION : FILE_PROTECTION_TYPE := 0; --for debug
  3616.      
  3617. function PHYSICAL_ADDRESS is new UNCHECKED_CONVERSION
  3618.                                   ( ADDRESS, UNSIGNED_LONGWORD);
  3619.      
  3620. task body OBTAIN_MESSAGE_FROM_ULP_QUEUE is
  3621.      
  3622. BUFFER : PACKED_BUFFER_PTR ;
  3623. XTCP_MESSAGE : XMESSAGE_TYPE;
  3624. TCP_MESSAGE : MESSAGE ;
  3625.      
  3626. begin
  3627.  PUT ( "TCP_MESSAGE SIZE := " ) ;
  3628.  INT_IO.PUT ( TCP_MESSAGE'SIZE ) ;
  3629.  NEW_LINE ;
  3630.  CREMBX( STATUS => RETURN_STATUS ,
  3631.          PRMFLG => PERMANENT_MAILBOX ,        -- permanent
  3632.          CHAN   => TO_TCP_CHANNEL,
  3633.          MAXMSG => XTCP_MESSAGE'SIZE/8,       --size of message
  3634.          BUFQUO => 5 * XTCP_MESSAGE'SIZE/8 ,  --size of queue
  3635.          LOGNAM => "TO_TCP_CHANNEL") ;        -- fixed name
  3636.  if NOT SUCCESS( RETURN_STATUS ) then
  3637.   PUT_LINE("Could not assign tcp channel") ;
  3638.  end if ;
  3639.  loop
  3640.   TASK_QIOW ( STATUS    => RETURN_STATUS ,
  3641.               CHAN      => TO_TCP_CHANNEL ,
  3642.               FUNC      => IO_READVBLK ,
  3643.               P1        => PHYSICAL_ADDRESS ( XTCP_MESSAGE'ADDRESS ) ,
  3644.               P2        => UNSIGNED_LONGWORD ( XTCP_MESSAGE'SIZE/8 ) ) ;
  3645.   if NOT SUCCESS ( RETURN_STATUS ) then
  3646.    PUT_LINE ( "Error in reading to mailbox TO_TCP_MAILBOX " );
  3647.   else
  3648.    TCP_MESSAGE := XTCP_MESSAGE.THE_TCP_MESSAGE ;
  3649.    if TCP_MESSAGE.EVENT = SEND then
  3650.     BUFFGET( BUFFER, 1 ) ;
  3651.     BUFFER.IN_USE := TRUE;
  3652.     BUFFER.STATUS := OWNER_TCP;
  3653.     TCP_MESSAGE.SEND_PARAMETERS.BUFPTR := BUFFER ; -- Give it a buffer
  3654.     TCP_MESSAGE.SEND_PARAMETERS.BUFPTR.ALL := XTCP_MESSAGE.THE_BUFFER;
  3655.    elsif TCP_MESSAGE.EVENT = RECEIVE then
  3656.     BUFFGET( BUFFER, 1);
  3657. --    BUFFER.IN_USE := TRUE;
  3658.     BUFFER.STATUS := OWNER_TCP;
  3659.     TCP_MESSAGE.RECEIVE_PARAMETERS.BUFPTR := BUFFER ;
  3660.    end if;
  3661.   end if ;
  3662.   if TCP_MESSAGE.EVENT = OPEN then
  3663.    CREMBX( STATUS => RETURN_STATUS ,
  3664.            PRMFLG => PERMANENT_MAILBOX ,             -- permanent
  3665.            CHAN   => TCP_MESSAGE.OPEN_PARAMETERS.LCN_BLOCK.CHANNEL_PTR,
  3666.            MAXMSG => XUSER_MESSAGE_TYPE'SIZE,        --size of message
  3667.            BUFQUO => 5 * XUSER_MESSAGE_TYPE'SIZE ,  --size of queue
  3668.            LOGNAM => TCP_MESSAGE.OPEN_PARAMETERS.LCN_BLOCK.CHANNEL_NAME(1..30)
  3669.                                                                              ) ;
  3670.                                                              -- fixed name
  3671.    PUT("TCP_MESSAGE.LOCAL_PORT := ");
  3672.    INT_IO.PUT( TCP_MESSAGE.OPEN_PARAMETERS.LOCAL_PORT ) ;
  3673.   end if ;
  3674.   TCP_Q.Q_ADD ( TCP_MESSAGE ) ;
  3675.  end loop ;
  3676. end OBTAIN_MESSAGE_FROM_ULP_QUEUE ;
  3677.      
  3678. end GET_MESSAGES_FROM_ULP ;
  3679.      
  3680.      
  3681. --::::::::::::::
  3682. --send_ip_task_.ada
  3683. --::::::::::::::
  3684. -----------------------------------------------------------------------
  3685. --
  3686. --         DoD Protocols    NA-00001-200       80-01010-100(-)
  3687. --         E-Systems, Inc.  August 07, 1985
  3688. --
  3689. --         SEND_IP_TASK_.ADA       Author : Jim Baldo
  3690. --
  3691. -----------------------------------------------------------------------
  3692. with IP_GLOBALS ;                               use IP_GLOBALS ;
  3693. with BUFFER_DATA ;                              use BUFFER_DATA ;
  3694.      
  3695.                         package SEND_IP_TASK is
  3696.      
  3697.  task TCP_TO_IP;
  3698.      
  3699. end SEND_IP_TASK ;
  3700. --::::::::::::::
  3701. --send_ip_task.ada
  3702. --::::::::::::::
  3703. -----------------------------------------------------------------------
  3704. --
  3705. --         DoD Protocols    NA-00001-200       80-01011-100(-)
  3706. --         E-Systems, Inc.  August 07, 1985
  3707. --
  3708. --         SEND_IP_TASK.ADA       Author : Jim Baldo
  3709. --
  3710. -----------------------------------------------------------------------
  3711. with TCP_Q_TASK;                                use TCP_Q_TASK;
  3712. with WITH_TCP_COMMUNICATE;                      use WITH_TCP_COMMUNICATE;
  3713. with IP_UNPACK_AND_PACK_UTILITIES;
  3714. use IP_UNPACK_AND_PACK_UTILITIES;
  3715. with IP_TCP ;                                   use IP_TCP ;
  3716. with SUBNET_CALLS ;                             use SUBNET_CALLS ;
  3717. with TEXT_IO ;                                  use TEXT_IO ;
  3718.                         package body SEND_IP_TASK is
  3719.      
  3720. package INT_IO_16 is new INTEGER_IO ( SIXTEEN_BITS ) ;
  3721.      
  3722. task body TCP_TO_IP is
  3723.      
  3724. type TEST_RESULT is (CORRECT, INCORRECT);
  3725. ITEM : IP_MESSAGE ;
  3726. BUFPTR : BUFFER_POINTER;
  3727. CURRENT_VERSION : constant SIXTEEN_BITS := 4;
  3728. TCP : constant SIXTEEN_BITS := 5;
  3729. INDEX : SIXTEEN_BITS := 1;
  3730. ERROR : SIXTEEN_BITS;
  3731. PROPER_DESTINATION, OPTION_CHECK : TEST_RESULT;
  3732. OPTIONS_REQUESTED_BY_IP_EXIST : BOOLEAN := FALSE;-- NONE NOW
  3733. BYTE_COUNT : SIXTEEN_BITS ;
  3734. TASK_MESSAGE : MESSAGE ;
  3735. IP_PARAMS : SEG_ARRIVE_PARAMS;
  3736. SECURITY_OPTION : SECURITY_OPTION_TYPE ;
  3737. BUFFER : PACKED_BUFFER_PTR;
  3738.      
  3739.     function OPTION_CHECKER ( OPTIONS : in OPTION_TYPE)
  3740.                                                    return TEST_RESULT is
  3741.      
  3742.         --This function will check that the options have been
  3743.         --correctly supplied in the option array.  It will return the
  3744.         --result of the test.
  3745.         --The security values have been mapped to the integers in the
  3746.         --following manner:
  3747.         --
  3748.         --   00000000 00000000 - UNCLASSIFIED => 0
  3749.         --   11110001 00110101 - CONFIDENTIAL => 1
  3750.         --   01111000 10011010 - EFTO => 2
  3751.         --   10111100 01001101 - MMMM  => 3
  3752.         --   01011110 00100110 - PROG => 4
  3753.         --   10101111 00010011 - RESTRICTED => 5
  3754.         --   11010111 10001000 - SECRET => 6
  3755.         --   01101011 11000101 - TOP SECRET => 7
  3756.      
  3757.     RESULT : TEST_RESULT := CORRECT;
  3758.     OPTION_NOT_CORRECT, OPTIONS_EXIST : BOOLEAN;
  3759.     I : SIXTEEN_BITS := 1;
  3760.      
  3761.     begin
  3762.       while OPTIONS(I) /= 0 and then (RESULT = CORRECT) loop
  3763.       -- WE MUST DETERMINE THE TYPE AND CHECK THE TYPE
  3764.       --VALIDITY.
  3765.         case OPTIONS(I) is
  3766.           when 1 => null;
  3767.           when 130 => -- SECURITY OPTION
  3768.             if OPTIONS(I + 1) /= 11 then
  3769.               RESULT := INCORRECT;
  3770.             else
  3771.               case OPTIONS(I + 2) is
  3772.              -- 0 - 7 MAP TO THE 8
  3773.              --LEGAL VALUES FOR SECURITY.
  3774.               when 0 | 1 |2 | 3 | 4 | 5
  3775.               | 6 | 7 => null;
  3776.               when others =>
  3777.                RESULT := INCORRECT;
  3778.               end case;
  3779.               if RESULT = CORRECT then
  3780.                case OPTIONS(I + 3) is
  3781.                            -- 0 - 7 MAP TO THE 8 LEGAL
  3782.                --VALUES FOR SECURITY.
  3783.                 when 0 | 1 | 2 | 3 | 4
  3784.                  | 5 | 6 | 7 => null;
  3785.                 when others =>
  3786.                  RESULT := INCORRECT;
  3787.                 end case;
  3788.               end if;
  3789.                     if RESULT = CORRECT and
  3790.                     (OPTIONS(I + 4) = 0) and
  3791.               (OPTIONS(I + 5) = 0)
  3792.                     then
  3793.                if OPTIONS(I + 2) /= OPTIONS(I
  3794.                + 3) then
  3795.                 RESULT := INCORRECT;
  3796.                end if;
  3797.               else
  3798.                RESULT := INCORRECT;
  3799.               end if;
  3800.               -- HERE WE WOULD CHECK OTHER
  3801.               --FIELDS WHICH ARE CURRENTLY
  3802.               --UNKNOWN IN FORMAT
  3803.               I := I + 11;
  3804.                    end if;
  3805.                   when 131 | 137 | 7 =>
  3806.             -- LOOSE SOURCE AND RECORD
  3807.             --ROUTE, STRICT SOURCE AND
  3808.             --RECORD ROUTE,  AND RECORD
  3809.             --ROUTE OPTIONS RESPECTIVELY.
  3810.             -- WE WILL CHECK FOR A VALID
  3811.             --POINTER.
  3812.              if (OPTIONS(I + 2) < 4) or
  3813.              (OPTIONS(I + 2) >
  3814.              (OPTIONS(I + 1) + 1)) then
  3815.               RESULT := INCORRECT;
  3816.              end if;
  3817.              I := I + OPTIONS(I +1);
  3818.              --UPDATE THE INDEX.
  3819.             when 136 =>
  3820.             -- STREAM IDENTIFIER
  3821.             -- CHECK FOR PROPER LENGTH. WE
  3822.             --DON'T KNOW WHAT THE PROPER
  3823.             --STREAM ID IS.
  3824.              if OPTIONS(I + 1) /= 4 then
  3825.               RESULT := INCORRECT;
  3826.              end if;
  3827.              I := I + 4; -- ADVANCE INDEX
  3828.             when 68 =>
  3829.             -- THE INTERNET TIMESTAMP OPTION
  3830.             -- CHECK LENGTH AND POINTER
  3831.              if OPTIONS(I + 1) >= 40 or
  3832.              (OPTIONS(I + 1) < 12) then
  3833.               RESULT := INCORRECT;
  3834.              elsif OPTIONS(I + 2) < 5 then
  3835.               RESULT := INCORRECT;
  3836.              end if;
  3837.              I := I + OPTIONS(I + 1);
  3838.              -- ADVANCE INDEX
  3839.             when others => -- A BAD TYPE
  3840.              RESULT := INCORRECT;
  3841.         end case;
  3842.       end loop;
  3843.     return RESULT;
  3844.     end OPTION_CHECKER;
  3845.      
  3846.     function DESTINATION_CHECK
  3847.       (DEST : THIRTYTWO_BITS ) return TEST_RESULT is
  3848.      
  3849.         --This subprogram will check that the requested destination is
  3850.         --legal.
  3851.      
  3852.     RESULT : TEST_RESULT := INCORRECT;
  3853.     DONE : BOOLEAN := FALSE;
  3854.     I : SIXTEEN_BITS := 1;
  3855.     begin
  3856.       while I <= NUMBER_OF_ADDRESSES and (not DONE) loop
  3857.         if DEST = VALID_ADDRESS_LIST(I) then
  3858.           RESULT := CORRECT;
  3859.           DONE := TRUE;
  3860.         end if;
  3861.         -- NEXT ENTRY
  3862.         I := I + 1;
  3863.       end loop;
  3864.       return RESULT;
  3865.     end DESTINATION_CHECK;
  3866.      
  3867.     function OPTION_OCTETS(X : OPTION_TYPE) return SIXTEEN_BITS is
  3868.      
  3869.             --Option_octets will determine how many option octets there
  3870.             --are in an IP header.  It determines the number by looking
  3871.             --at the length field of each existent option type and adding
  3872.             --them up.  The total is then returned to  the caller.  This
  3873.             --routine knows the option format.  One octet is contained
  3874.             --in each element of the option array x.
  3875.      
  3876.     I : SIXTEEN_BITS := 1;
  3877.     OCTET_COUNT : SIXTEEN_BITS := 0;
  3878.     OPTION_LENGTH : SIXTEEN_BITS;
  3879.      
  3880.     begin
  3881.       -- WE WILL PUT ONE OCTET IN PER 16 BITS.
  3882.       while X(I) /= 0 and then (X(I + 1) > 0) loop
  3883.         OPTION_LENGTH := X(I + 1);
  3884.         OCTET_COUNT := OCTET_COUNT + OPTION_LENGTH;
  3885.         I := I + X(I + 1); -- NEXT OPTION FIELD.
  3886.       end loop;
  3887.       if OCTET_COUNT /= ((OCTET_COUNT/4)*4) then
  3888.         OCTET_COUNT := ((OCTET_COUNT/4) + 1) * 4;
  3889.             -- PAD WITH OCTETS.
  3890.       end if;
  3891.       return OCTET_COUNT;
  3892.     end OPTION_OCTETS;
  3893.      
  3894. begin
  3895.  loop
  3896.   IP_FROM_TCP.Q_GET ( ITEM ) ;
  3897.   if ITEM.EVENT /= FROM_TCP then
  3898.    PUT_LINE ( "Error from SEND_IP_TASK; IP_MESSAGE /= IP_SEND " ) ;
  3899.    --exit ; --terminate Q_GET
  3900.   end if ;
  3901.      
  3902.         --This subprogram takes a segment from the user layer(TCP) and wraps
  3903.         --it in a datagram. It checks to make sure a viable call has been
  3904.         --made.  It will send a formatted datagram to the subnet protocol
  3905.         --SUBNET.  It is called by the IP controller after the TCP has
  3906.         --requested that a segment be sent wrapped in a datagram.  The
  3907.         --following is a description of the parameters:
  3908.         --
  3909.         --   SRC - THE SOURCE ADDRESS OF THE DATAGRAM.
  3910.         --   DEST - THE DESTINATION OF THE DATAGRAM.
  3911.         --   TOS - THE TYPE OF SERVICE DESIRED BY THE TCP(USER APPLICATION).
  3912.         --   TTL - THE TIME TO LIVE FOR THE DATAGRAM.
  3913.         --   LEN - THE NUMBER OF OCTETS IN THE BUFFER.
  3914.         --   ID - VARIABLE THAT IS SET BY THE SENDER TO HELP IN REASSEMBLING
  3915.         --        FRAGMENTS.
  3916.         --   DF - THE DONT FRAGMENT BIT. ALWAYS SET IN OUR CASE.
  3917.         --   OPTIONS - THE ARRAY THAT CONTAINS THE OPTIONS THAT THE TCP OR
  3918.         --             USER WISHES TO HAVE IMPLEMENTED.
  3919.      
  3920.      
  3921.      
  3922.   -- CHECK ALL PARAMETERS ON SEND CALL HERE. ARE ANY NOT CHECKED??
  3923.     PROPER_DESTINATION := DESTINATION_CHECK( ITEM.DEST );
  3924.     ERROR := 0;
  3925.     if PROPER_DESTINATION = INCORRECT then
  3926.       ERROR := 1;
  3927.     elsif (ITEM.TOS > 256) or (ITEM.TOS < 0) then
  3928.       ERROR := 2;
  3929.     elsif ( ITEM.TTL > 255) or ( ITEM.TTL < 0) then -- TIMES ARE IN SECONDS.
  3930.       ERROR := 3;
  3931.     else
  3932.       OPTION_CHECK := OPTION_CHECKER( ITEM.OPTIONS );
  3933.       if OPTION_CHECK = INCORRECT then
  3934.         ERROR := 4;
  3935.       end if;
  3936.     end if;
  3937.     if ERROR /= 0 then
  3938.       NEW_LINE;
  3939.       PUT("BAD PACKET FOR TRANSMIT"); --** TEMP
  3940.       INT_IO_16.PUT( ERROR); --** TEMP
  3941.       NEW_LINE;
  3942.       ITEM.BUFPTR.IN_USE := FALSE;
  3943.       BUFFREE( ITEM.BUFPTR, 1 ); -- TEMPORARY FOR TEST**
  3944.     else
  3945.       if ITEM.DEST = WHOIAM then
  3946.        for INDEX in 3..11 loop
  3947.         SECURITY_OPTION( SIXTEEN_BITS(INDEX - 2) ) :=
  3948.          ITEM.OPTIONS( SIXTEEN_BITS(INDEX) ) ;
  3949.        end loop ;
  3950. --       BYTE_COUNT := MAXIMUM_DATAGRAM_SIZE - ITEM.BUFPTR.IP_PTR ;
  3951.        BYTE_COUNT := 255 - ITEM.BUFPTR.IP_PTR ;
  3952.        BUFFGET( BUFFER, 0 );
  3953.        BUFFER.STATUS := OWNER_TCP;
  3954.        BUFFER.ALL := ITEM.BUFPTR.ALL;
  3955.        IP_PARAMS := ( BUFFER,
  3956.                       BYTE_COUNT,
  3957.                       ITEM.SRC,
  3958.                       ITEM.DEST,
  3959.                       5, -- TCP Protocol Number
  3960.                       ITEM.TOS,
  3961.                       SECURITY_OPTION ) ;
  3962.        TASK_MESSAGE := ( DATA_FROM_IP, IP_PARAMS ) ;
  3963.        TCP_Q.Q_ADD( TASK_MESSAGE ) ; -- Send to TCP
  3964. --       PUT_LINE("BUFFREE LOOP BACK AT IP");--DEBUG JB 7/3/85
  3965.        ITEM.BUFPTR.IN_USE := FALSE;
  3966.        BUFFREE( ITEM.BUFPTR, 0 );
  3967.      else
  3968.         -- FORMAT AN IP HEADER
  3969.       BUFPTR.VERSION := CURRENT_VERSION;
  3970.       BUFPTR.TOS := ITEM.TOS;
  3971.       BUFPTR.ID := ITEM.ID ;
  3972.       BUFPTR.FLAGS := 2;
  3973.       -- REALLY THREE BITS (010) MEANS DONT FRAGMENT.
  3974.       BUFPTR.FRAG_OFFSET := 0; -- WE DO NOT FRAGMENT.
  3975.       BUFPTR.TTL := ITEM.TTL; -- TIME TO LIVE (TBD)
  3976.       BUFPTR.PROT := TCP; -- PROTOCOL NUMBERS DEFINED IN RFC 870
  3977.       BUFPTR.SOURCE := ITEM.SRC ;
  3978.       BUFPTR.DEST := ITEM.DEST ;
  3979.       -- SET UP TRANSMIT OPTIONS AS REQUESTED BY THE ABOVE
  3980.       --LAYER(TCP). COPY ARRAY.
  3981.       BUFPTR.IP_OPTIONS := ITEM.OPTIONS;
  3982.      
  3983.       -- CURRENTLY IP WILL NOT REQUEST ANY OPTIONS. LATER
  3984.       -- SWITCHES MAY BE SET. TO CAUSE OPTIONS TO BE USED.
  3985.       while OPTIONS_REQUESTED_BY_IP_EXIST loop
  3986.       --/PUT IN ANY NEW OPTIONS IN THE PROPER PLACE/
  3987.       --/ INCREMENT OPTIONS_OCTET COUNT THE PROPER AMOUNT./
  3988.         null;
  3989.       end loop;
  3990.       -- SET UP THE INTERNET HEADER LENGTH
  3991.       BUFPTR.IHL := 5 + OPTION_OCTETS(BUFPTR.IP_OPTIONS)/4;
  3992.       BUFPTR.TOT_LEN := (BUFPTR.IHL * 4) + ITEM.LEN;
  3993.         -- THE TOTAL NUMBER OF OCTETS IN THE
  3994.               -- DATAGRAM INCLUDING HEADER AND DATA.
  3995.       -- DETERMINE AND FILL IN THE CHECKSUM. DONE ON THE PACK
  3996.       -- PACK THE BUFFER UP
  3997.       PACK_BUFFER_INTO_BIT_STREAM
  3998.                 ( BUFPTR, ITEM.BUFPTR );
  3999.       --/ SEND IT ON TO THE CHANNEL PROTOCOL MODULE/
  4000.       ITEM.BUFPTR.SUBNET_PTR := ITEM.BUFPTR.IP_PTR ;
  4001.       SNP.SEND ( ITEM.BUFPTR ,
  4002.                  LOCAL_ADDRESS_TYPE ( ITEM.DEST ) ,
  4003.                  ROUTINE ,
  4004.                  NORMAL ,
  4005.                  NORMAL ,
  4006.                  NORMAL ,
  4007.                  BUFPTR.TOT_LEN ) ;
  4008. --    PUT_LINE("Just sent a datagram to SUBNET");--debug JB 3/June/85
  4009.    end if;
  4010.   end if;
  4011.  end loop ;
  4012.  exception
  4013.   when CONSTRAINT_ERROR =>
  4014.    PUT_LINE("CONSTRAINT ERROR IN SEND_IP ROUTINE OF IP SYSTEM");
  4015.   when others =>
  4016.    PUT_LINE("ERROR IN SEND_IP ROUTINE OF IP SYSTEM");
  4017. end TCP_TO_IP ;
  4018.      
  4019. end SEND_IP_TASK ;
  4020. --::::::::::::::
  4021. --tcp_globals_.ada
  4022. --::::::::::::::
  4023. -----------------------------------------------------------------------
  4024. --
  4025. --         DoD Protocols    NA-00001-200       80-01017-100(-)
  4026. --         E-Systems, Inc.  August 07, 1985
  4027. --
  4028. --         TCP_GLOBALS_.ADA       Author : Jim Baldo
  4029. --
  4030. -----------------------------------------------------------------------
  4031. with IP_GLOBALS ;                       use IP_GLOBALS ;
  4032. with T_TCP_GLOBALS_DATA_STRUCTURES;     use T_TCP_GLOBALS_DATA_STRUCTURES;
  4033. with BUFFER_DATA;                       use BUFFER_DATA;
  4034.      
  4035.                         package TCP_GLOBALS is
  4036.      
  4037.                 ----------------------------------------------------
  4038.                 --This implementation is for use with the DEC/Ada --
  4039.                 --compiler .                                      --
  4040.                 ----------------------------------------------------
  4041.      
  4042. -------------------------------------------------------------------------------
  4043. --This  package contains all necessary global variables for any tcp routine. --
  4044. --This includes the TCB and any operations necessary to operate on the global--
  4045. -- data.                                                                     --
  4046. -------------------------------------------------------------------------------
  4047.      
  4048. procedure PACK_BUFFER_INTO_BIT_STREAM( BUFPTR : in
  4049.                                  T_TCP_GLOBALS_DATA_STRUCTURES.BUFFER_POINTER;
  4050.                                        PACKED_BUFFER : in PACKED_BUFFER_PTR);
  4051.      
  4052.         --This subprogram will break up a record of integers, long_integers,
  4053.         --and modular types into system bytes.  It uses the function
  4054.         --unchecked_conversion to move integers, etc. into the array of system
  4055.         --bytes.
  4056.      
  4057. procedure TCP_HEADER_FORMAT( LCN : in TCB_PTR;
  4058.                              BUFPTR : in out
  4059.                               T_TCP_GLOBALS_DATA_STRUCTURES.BUFFER_POINTER;
  4060.                              TYPE_FLAG : in HEADER_TYPE;
  4061.                              OPTIONS : in OPTION_TYPE);
  4062.      
  4063.         --This subprogram is responsible for formatting a TCP header for any
  4064.         --type of segment.  The segment type is denoted by the type_flag.  A
  4065.         --checksum will be performed over the formatted header and conceptual
  4066.         --pseudo header.  All header fields are reset and/or filled in.
  4067.      
  4068. function CHECKSUM( TCP_HEADER_LENGTH : in SIXTEEN_BITS ;
  4069.                    PACKED_BUFFER : in PACKED_BUFFER_PTR;
  4070.                    DESTINATION, SOURCE : in THIRTYTWO_BITS ;
  4071.                    PROTOCOL : in SIXTEEN_BITS ) return SIXTEEN_BITS ;
  4072.      
  4073.         --This function performs the 16 bit one's complement checksum over the
  4074.         --entire TCP header and data as well as the 96 bit pseudo header which
  4075.         --is the source and destination address, the protocol, and the TCP
  4076.         --length.
  4077.      
  4078. procedure TCP_ERROR( ERROR_INDICATION : in ERROR_TYPE);
  4079.      
  4080.         --This subprogram is called upon an error occurrence. Currently it
  4081.         --simply increments a counter in the appropriate TCB'S table.
  4082.      
  4083.      
  4084. function FOREIGN_SOCKET_UNSPECIFIED( LCN : in TCB_PTR) return boolean;
  4085.      
  4086.         --This subprogram attempts to determine if the foreign socket is
  4087.         --unspecified by checking for illegal values and the net and host
  4088.         --addresses the same (as they were initialized).
  4089.      
  4090. function ISS return THIRTYTWO_BITS ;
  4091.      
  4092.         --This function gets the local time in milliseconds and multiplies it
  4093.         --by 250 to determine the ISS.  This means it will cycle approximately
  4094.         --every 4.55 hours.
  4095.      
  4096. procedure ADDRESS_DECODER( CONCATENATION : in THIRTYTWO_BITS );
  4097.      
  4098.         --This subprogram will determine the form of the net and host addresses
  4099.         --from the first three bits of the concatenated form. It will then
  4100.         --separate and decode the bits into the proper TCB varibles by using
  4101.         --unchecked conversions between types. The format of the concatenated
  4102.         --version can be found in the IP spec.
  4103.      
  4104. procedure INSERT_TEXT_IN_BUFFER( LENGTH : in SIXTEEN_BITS ;
  4105.                                  RECEIVED_PACKED_BUFFER : in PACKED_BUFFER_PTR;
  4106.                                  DATA_LENGTH : in SIXTEEN_BITS ;
  4107.                                  PACKED_BUFFER : in PACKED_BUFFER_PTR);
  4108.      
  4109.         --This subprogram will put a slice of data from one array of sytem
  4110.         --bytes to another of system bytes.  It begins at the points in the
  4111.         --respective arrays as indicated by their first element.
  4112.      
  4113. procedure TIMEOUT_CHECK( LCN : in TCB_PTR; ACTION : out TIME_ACTION);
  4114.      
  4115.         --This subprogram determines if the connection has timeout, waiting
  4116.         --for a timeout, or retransmit timeout has occured.  An action result
  4117.         --parameter indicating which of previously described events has
  4118.         --occurred is returned.  The LCN parameter is passed to the subprogram.
  4119.      
  4120. procedure START_TIMER(LCN : in TCB_PTR; TIMER : in TIMER_TYPE);
  4121.      
  4122.         --This procedure will reset the connection timeout timer in a TCB
  4123.         --or the time wait timer as specified by an LCN.  There will be a
  4124.         --problem when the clock cycles after 6 hours, but this can be taken
  4125.         --care of with the modular type.
  4126.      
  4127. end TCP_GLOBALS;
  4128.      
  4129. --::::::::::::::
  4130. --vtcp_globals.ada
  4131. --::::::::::::::
  4132. -----------------------------------------------------------------------
  4133. --
  4134. --         DoD Protocols    NA-00001-200       80-01033-100(-)
  4135. --         E-Systems, Inc.  August 07, 1985
  4136. --
  4137. --         VTCP_GLOBALS.ADA       Author : Jim Baldo
  4138. --
  4139. -----------------------------------------------------------------------
  4140. with QUEUES;                            use QUEUES;
  4141. with SYSTEM;
  4142. with MODULO;                            use MODULO;
  4143. with TEXT_IO;                           use TEXT_IO;
  4144. with UNCHECKED_CONVERSION;
  4145. with REAL_TIME_CLOCK_AND_DATE;          use REAL_TIME_CLOCK_AND_DATE;
  4146.      
  4147.                         package BODY TCP_GLOBALS is
  4148.      
  4149. package INT_IO_16 is new INTEGER_IO ( SIXTEEN_BITS ) ;
  4150. package INT_IO_32 is new INTEGER_IO ( THIRTYTWO_BITS ) ;
  4151.      
  4152. DUMMY : CHARACTER;--DEBUG
  4153.      
  4154. procedure PACK_BUFFER_INTO_BIT_STREAM ( BUFPTR : in
  4155.                                  T_TCP_GLOBALS_DATA_STRUCTURES.BUFFER_POINTER;
  4156.                                  PACKED_BUFFER : in PACKED_BUFFER_PTR) is
  4157.      
  4158. HEADER_LENGTH : SIXTEEN_BITS  := BUFPTR.DATA_OFFSET * 4;
  4159. INDEX : SIXTEEN_BITS  := PACKED_BUFFER.TCP_PTR;
  4160. LENGTH : SIXTEEN_BITS  := BUFPTR.DATA_LEN + HEADER_LENGTH;
  4161. -- CURRENTLY THE HEADER
  4162. -- LENGTH IS ALWAYS 20
  4163. -- SINCE NO OPTIONS ARE
  4164. -- IMPLEMENTED.
  4165.  procedure PUT_AN_INTEGER_IN_THE_BUFFER(VALUE : SIXTEEN_BITS ) is
  4166.      
  4167.   type STUPID is array(1..1) of SIXTEEN_BITS ;
  4168.   type TWO_BYTES is array(1..2) of SYSTEM_BYTE;
  4169.   function CONVERT_INTEGER_TO_BYTES is new
  4170.      UNCHECKED_CONVERSION(STUPID,TWO_BYTES);
  4171.   TEMP_INT : STUPID;
  4172.   BYTES_FROM_INTEGER : TWO_BYTES;
  4173.  begin
  4174.   TEMP_INT(1) := VALUE;
  4175.   BYTES_FROM_INTEGER(1) := 0; --intialized here due to Telesoft subset
  4176.   BYTES_FROM_INTEGER(2) := 0;
  4177.   BYTES_FROM_INTEGER := CONVERT_INTEGER_TO_BYTES(TEMP_INT);
  4178.   for I in 1..2 loop
  4179.    PACKED_BUFFER.BYTE( INDEX + SIXTEEN_BITS ( I ) - 1 ) :=
  4180.                    BYTES_FROM_INTEGER(I);
  4181.   end loop;
  4182.   INDEX := INDEX + 2;
  4183. exception
  4184.  when others =>
  4185.   PUT_LINE("ERROR IN PUT INTEGER INTO BUFFER");
  4186.   INT_IO_16.PUT(INDEX);
  4187. end PUT_AN_INTEGER_IN_THE_BUFFER;
  4188.      
  4189. procedure PUT_A_LONG_INTEGER_IN_THE_BUFFER
  4190.           (DOUBLE_WORD : THIRTYTWO_BITS ) is
  4191.      
  4192.  type STUPID_LONG is array(1..1) of THIRTYTWO_BITS ;
  4193.  type FOUR_BYTES is array(1..4) of SYSTEM_BYTE ;
  4194.  function CONVERT_LONG_INT_TO_BYTES is new
  4195.    UNCHECKED_CONVERSION(STUPID_LONG,FOUR_BYTES);
  4196.  TEMP_LONG_INT : STUPID_LONG;
  4197.  BYTES_FROM_LONG_INT : FOUR_BYTES;
  4198. begin
  4199.  TEMP_LONG_INT(1) := DOUBLE_WORD;
  4200.  BYTES_FROM_LONG_INT := CONVERT_LONG_INT_TO_BYTES(TEMP_LONG_INT);
  4201.  for I in 1..4 loop -- PUT THEM IN
  4202.   PACKED_BUFFER.BYTE( INDEX + SIXTEEN_BITS(I) - 1 ) := BYTES_FROM_LONG_INT(I);
  4203.  end loop;
  4204.  INDEX := INDEX + 4;
  4205. exception
  4206.  when others =>
  4207.   PUT_LINE("ERROR IN PUT LONG INTEGER INTO BUFFER");
  4208.   INT_IO_16.PUT(INDEX);
  4209. end PUT_A_LONG_INTEGER_IN_THE_BUFFER;
  4210.      
  4211.      
  4212. procedure PUT_A_LO_WORD_IN_THE_BUFFER
  4213.           (DOUBLE_WORD : THIRTYTWO_BITS ) is
  4214.      
  4215.  type STUPID_LONG is array(1..1) of THIRTYTWO_BITS ;
  4216.  type FOUR_BYTES is array(1..4) of SYSTEM_BYTE ;
  4217.  function CONVERT_LONG_INT_TO_BYTES is new
  4218.    UNCHECKED_CONVERSION(STUPID_LONG,FOUR_BYTES);
  4219.  TEMP_LONG_INT : STUPID_LONG ;
  4220.  BYTES_FROM_LONG_INT : FOUR_BYTES;
  4221. begin
  4222.  for I in 1..4 loop --due TELESOFT 1.3d compiler
  4223.   BYTES_FROM_LONG_INT(I) := 0 ;
  4224.  end loop ;
  4225.  TEMP_LONG_INT(1) := DOUBLE_WORD;
  4226.  BYTES_FROM_LONG_INT := CONVERT_LONG_INT_TO_BYTES(TEMP_LONG_INT);
  4227.  for I in 1..2 loop -- PUT THEM IN
  4228.   PACKED_BUFFER.BYTE( INDEX + SIXTEEN_BITS(I) - 1 ) := BYTES_FROM_LONG_INT(I);
  4229.  end loop;
  4230.  INDEX := INDEX + 2;
  4231. exception
  4232.  when others =>
  4233.   PUT_LINE("ERROR IN PUT LO WORD INTO BUFFER");
  4234.   INT_IO_16.PUT(INDEX);
  4235. end PUT_A_LO_WORD_IN_THE_BUFFER;
  4236.      
  4237.      
  4238.      
  4239. begin
  4240.  -- SET UP THE INITIAL INDEX
  4241.  INDEX := (INDEX - HEADER_LENGTH) + 1;-- THEIR DIFFERENCE PLUS 1
  4242.                                              -- SO PROPER # PLACES USED
  4243.                              -- DATA IS ALREADY IN BUFFER.
  4244.  PACKED_BUFFER.TCP_PTR := INDEX;
  4245.  PUT_AN_INTEGER_IN_THE_BUFFER(BUFPTR.SOURCE_PORT);
  4246.  PUT_AN_INTEGER_IN_THE_BUFFER(BUFPTR.DESTINATION_PORT);
  4247. --NEW_LINE;
  4248. --PUT("XSEQ_NUM.HI := ");
  4249. --INT_IO_32.PUT(BUFPTR.SEQ_NUM.HI);
  4250. --NEW_LINE;
  4251. --NEW_LINE;
  4252. --PUT("XSEQ_NUM.LO := ");
  4253. --INT_IO_32.PUT(BUFPTR.SEQ_NUM.LOW);
  4254. --NEW_LINE;
  4255.  PUT_A_LO_WORD_IN_THE_BUFFER(BUFPTR.SEQ_NUM.LOW);
  4256.  PUT_A_LO_WORD_IN_THE_BUFFER(BUFPTR.SEQ_NUM.HI);
  4257.  PUT_A_LO_WORD_IN_THE_BUFFER(BUFPTR.ACK_NUM.LOW);
  4258.  PUT_A_LO_WORD_IN_THE_BUFFER(BUFPTR.ACK_NUM.HI);
  4259.  -- PUT IN SOME SMALL FIELDS AND BIT FIELDS
  4260.  PACKED_BUFFER.BYTE(INDEX) := SYSTEM_BYTE ( BUFPTR.DATA_OFFSET * 16 ) ;
  4261.  PACKED_BUFFER.BYTE(INDEX+1) := SYSTEM_BYTE ( BUFPTR.URG_FLAG * 32 +
  4262.    BUFPTR.ACK * 16 + BUFPTR.PUSH_FLAG * 8 + BUFPTR.RST * 4 +
  4263.                        BUFPTR.SYN * 2 + BUFPTR.FIN ) ;
  4264.  INDEX := INDEX + 2;
  4265.  PUT_AN_INTEGER_IN_THE_BUFFER(BUFPTR.WINDOW);
  4266.  -- CLEAR THE CHECKSUM FIELD
  4267.  PACKED_BUFFER.BYTE(INDEX) := 0;
  4268.  PACKED_BUFFER.BYTE(INDEX+1) := 0;
  4269.  INDEX := INDEX + 2;
  4270.  PUT_AN_INTEGER_IN_THE_BUFFER(BUFPTR.URG_PTR);
  4271.  -- NOW WE PUT THE OPTIONS IN THE BUFFER. HOWEVER THEY ARE
  4272.  -- CURRENTLY NOT IMPLEMENTED
  4273.  -- HERE WE COULD PUT THE DATA IN THE BUFFER.
  4274.  --FOR I IN 1..LENGTH - HEADER_LENGTH LOOP
  4275.  -- PACKED_BUFFER.BYTE(INDEX + I - 1) := BUFPTR.DATA(I);
  4276.  --END LOOP;
  4277.  -- PERFORM THE HEADER CHECKSUM
  4278.  INDEX := INDEX - 4; -- TO POINT TO THE CHECKSUM FIELD.
  4279.  PUT_AN_INTEGER_IN_THE_BUFFER(CHECKSUM(LENGTH,
  4280.                                        PACKED_BUFFER,
  4281.                                        LCN.DESTINATION_ADDRESS,
  4282.                                        LCN.SOURCE_ADDRESS,
  4283.                                        5)
  4284.                               );
  4285.  -- SET THE POINTER FOR THE NEXT LAYER
  4286.  PACKED_BUFFER.IP_PTR := PACKED_BUFFER.TCP_PTR - 1;
  4287.      
  4288. exception
  4289.  when others =>
  4290.   PUT_LINE("ERROR IN PACK BUFFER MAIN");
  4291.   INT_IO_16.PUT(INDEX);
  4292.   PUT_LINE("");
  4293.   INT_IO_16.PUT(LENGTH);
  4294. end PACK_BUFFER_INTO_BIT_STREAM;
  4295.      
  4296. procedure TCP_HEADER_FORMAT ( LCN : in TCB_PTR;
  4297.                               BUFPTR : in out
  4298.                                T_TCP_GLOBALS_DATA_STRUCTURES.BUFFER_POINTER;
  4299.                               TYPE_FLAG : in HEADER_TYPE;
  4300.                               OPTIONS : in OPTION_TYPE) is
  4301.      
  4302. --pragma SUPPRESS(OVERFLOW_CHECK);-- ENABLES MOD 2**16 IDENT FOR THE IP.
  4303.      
  4304. begin
  4305.  LCN.IDENT := LCN.IDENT + 1; -- INCREMENT IP ID NUMBER.
  4306.  IDENT := LCN.IDENT; -- SET UP THE PARAMETER FOR CALL TO IP
  4307.  -- HERE WE INITIALIZE THE COMMONNLY UNUSED PORTIONS OF THE HEADER.
  4308.  BUFPTR.URG_PTR := 0;
  4309.  BUFPTR.ACK := 0;
  4310.  BUFPTR.URG_FLAG := 0;
  4311.  -- WE CURRENTLY DO NOT IMPLEMENT THE URGENT OPTION ON SENDS.
  4312.  BUFPTR.PUSH_FLAG := 0;
  4313.  -- WE CURRENTLY DO NOT IMPLEMENT THE PUSH OPTION ON SENDS.
  4314.  BUFPTR.RST := 0;
  4315.  BUFPTR.SYN := 0;
  4316.  BUFPTR.FIN := 0;
  4317.  case TYPE_FLAG is
  4318.   when ACK =>
  4319.    BUFPTR.ACK := BIT_SET;
  4320.   when RST =>
  4321.    BUFPTR.RST := BIT_SET;
  4322.   when SYN =>
  4323.    BUFPTR.SYN := BIT_SET;
  4324.   when SYN_ACK =>
  4325.    BUFPTR.ACK := BIT_SET;
  4326.    BUFPTR.SYN := BIT_SET;
  4327.   when SEGMENT =>
  4328.    BUFPTR.ACK := BIT_SET;
  4329.   -- HERE WE WOULD CHECK IF WE NEED TO SET OUR URGENT POINTER.
  4330.   when SEG_ACK =>
  4331.    BUFPTR.ACK := BIT_SET;
  4332.    -- HERE WE WOULD CHECK IF WE NEED TO SET OUR URGENT POINTER.
  4333.   when FIN =>
  4334.    BUFPTR.FIN := BIT_SET;
  4335.    BUFPTR.ACK := BIT_SET; -- THE ACK BIT MUST ALWAYS BE SET.
  4336.   when RST_ACK => BUFPTR.RST := BIT_SET;
  4337.    BUFPTR.ACK := BIT_SET;
  4338.  end case;
  4339.  -- FILL IN THE RESET OF THE HEADER.
  4340.  -- NOTE WE DO NOT CURRENTLY IMPLEMENT OPTIONS.
  4341.  -- THIS MEANS THE DATA OFFSET IS CONSTANT.
  4342.  BUFPTR.DATA_OFFSET := 5;
  4343.  BUFPTR.SOURCE_PORT := LCN.LOCAL_PORT;
  4344.  BUFPTR.DESTINATION_PORT := LCN.FOREIGN_PORT;
  4345.  BUFPTR.SEQ_NUM := LCN.SND_NXT;
  4346. -- NEW_LINE;
  4347. -- PUT_LINE("ASSIGNED IN TCP_HEADER_FORMAT");
  4348. -- PUT("SEQ_NUM.HI := ");
  4349. -- INT_IO_32.PUT(BUFPTR.SEQ_NUM.HI);
  4350. -- NEW_LINE;
  4351. -- PUT("SEQ_NUM.LO := ");
  4352. -- INT_IO_32.PUT(BUFPTR.SEQ_NUM.LOW);
  4353. -- NEW_LINE;
  4354.  BUFPTR.ACK_NUM := LCN.RCV_NXT;
  4355.  BUFPTR.WINDOW := LCN.SND_WND;
  4356.  -- WE COULD PERFORM CHECKSUM AND PLACE IT IN THE
  4357.  -- HEADER HERE BUT IT WILL BE
  4358.  -- DONE BY THE PACK ROUTINE.
  4359. end TCP_HEADER_FORMAT;
  4360.      
  4361. function CHECKSUM ( TCP_HEADER_LENGTH : in SIXTEEN_BITS ;
  4362.                     PACKED_BUFFER : in PACKED_BUFFER_PTR;
  4363.                     DESTINATION, SOURCE : in THIRTYTWO_BITS ;
  4364.                     PROTOCOL : in SIXTEEN_BITS ) return SIXTEEN_BITS  is
  4365.      
  4366. --pragma SUPPRESS(OVERFLOW_CHECK);
  4367. type TWO_WORDS is array(1..2) of SIXTEEN_BITS ;
  4368. type TELEHOSE is array(1..1) of THIRTYTWO_BITS ;
  4369. function CONVERSION is neW UNCHECKED_CONVERSION(TELEHOSE, TWO_WORDS);
  4370. START_PTR : SIXTEEN_BITS  := PACKED_BUFFER.TCP_PTR;
  4371. END_PTR : SIXTEEN_BITS  := START_PTR + TCP_HEADER_LENGTH - 1;
  4372. CHECKSUM_TOTAL, TWO_INTEGERS : TWO_WORDS;
  4373. TCSUM : THIRTYTWO_BITS  := 0;
  4374. TEMP, TEMP1, TEMP2 : THIRTYTWO_BITS  := 0;
  4375. WORD_SHIFT : constant THIRTYTWO_BITS  := 65536;
  4376. HIGH_BYTE : BOOLEAN := FALSE;
  4377. --TRUE; FOR 68000. WORDS ARE BYTE SWAPPED ON VAX.
  4378. CHECKSM, LONG_HOLDER : TELEHOSE;
  4379.      
  4380. begin
  4381.  -- THIS CHECKSUM IS PERFORMED ON THE TCP HEADER AS WELL AS A 96 BIT
  4382.  -- PSEUDO HEADER WHICH IS THE SOURCE AND DESTINATION ADDRESS,
  4383.  -- THE PROTOCOL, AND THE TCP LENGTH.
  4384.  -- PERFORM THE CHECKSUM OVER THE PSEUDO HEADER.
  4385.  LONG_HOLDER(1) := SOURCE;
  4386.  TWO_INTEGERS := CONVERSION(LONG_HOLDER);
  4387.  TCSUM := THIRTYTWO_BITS (TWO_INTEGERS(1)) +
  4388.  THIRTYTWO_BITS (TWO_INTEGERS(2));
  4389.  LONG_HOLDER(1) := DESTINATION;
  4390.  TWO_INTEGERS := CONVERSION(LONG_HOLDER);
  4391.  TCSUM := TCSUM + THIRTYTWO_BITS (TWO_INTEGERS(1)) +
  4392.  THIRTYTWO_BITS (TWO_INTEGERS(2));
  4393.  TCSUM := TCSUM + THIRTYTWO_BITS (PROTOCOL) +
  4394.         THIRTYTWO_BITS ( TCP_HEADER_LENGTH );
  4395.  -- NOW DO THE ACTUAL HEADER
  4396.  for I in 0..END_PTR-START_PTR loop
  4397.   if (I /= 16) and I /= 17 then -- DON'T ADD IN THE CHECKSUM
  4398.    if I = 12 then HIGH_BYTE := TRUE;-- NECESSARY FOR VAX BYTE SWAPPING
  4399.    end if;
  4400.    if I = 14 then HIGH_BYTE := FALSE;-- NECESSARY FOR VAX BYTE SWAPPING
  4401.    end if;
  4402.    if I = 20 then HIGH_BYTE := TRUE;-- DATA IS STORED UNSWAPPED.
  4403.    end if;
  4404.    TEMP := THIRTYTWO_BITS( PACKED_BUFFER.BYTE(START_PTR + I) );
  4405.    if TEMP < 0 then
  4406.     TEMP := TEMP + 256;-- VAX SIGN EXTENSION(PROBLEM)
  4407.    end if;
  4408.    if HIGH_BYTE then
  4409.     TCSUM := TCSUM + TEMP * THIRTYTWO_BITS ( 2**8 );
  4410.     HIGH_BYTE := FALSE;
  4411.    else
  4412.     HIGH_BYTE := TRUE;
  4413.     TCSUM := TCSUM + TEMP ;
  4414.    end if;
  4415.   end if;
  4416.  end loop;
  4417.  -- GET ONE'S COMPLEMENT
  4418.  TCSUM := (-TCSUM) - 1;
  4419.  CHECKSM(1) := TCSUM;
  4420.  CHECKSUM_TOTAL := CONVERSION(CHECKSM);
  4421.  -- GET BOTH WORDS AND RETURN LOW WORD.
  4422.  return CHECKSUM_TOTAL(1);
  4423. exception
  4424.  when others =>
  4425.   PUT_LINE("ERROR IN CHECKSUM");
  4426.   INT_IO_16.PUT(START_PTR);
  4427.   PUT_LINE("END POINTER");
  4428.   INT_IO_16.PUT(END_PTR);
  4429. end CHECKSUM;
  4430.      
  4431. procedure TCP_ERROR( ERROR_INDICATION : in ERROR_TYPE ) is
  4432.      
  4433. begin
  4434.  -- INCREMENT THE ERROR COUNTER.
  4435.  case ERROR_INDICATION is
  4436.   when 15 | 16 => -- currently cannot proccess
  4437.    null;
  4438.   when others =>
  4439.    LCN.ERROR_TABLE(ERROR_INDICATION) :=
  4440.     LCN.ERROR_TABLE(ERROR_INDICATION) + 1;
  4441.  end case ;
  4442. end TCP_ERROR;
  4443.      
  4444. function FOREIGN_SOCKET_UNSPECIFIED(LCN : in TCB_PTR) return boolean is
  4445.      
  4446. RESULT : BOOLEAN := FALSE;
  4447.      
  4448. begin
  4449.  -- THIS COULD BE A TROUBLE SPOT IF -1 IS A LEGAL ADDRESS.***
  4450.  if (LCN.FOREIGN_NET = LCN.FOREIGN_HOST) and
  4451.                  LCN.FOREIGN_PORT = -1 then
  4452.   RESULT := TRUE;
  4453.  end if;
  4454.  return RESULT;
  4455. end FOREIGN_SOCKET_UNSPECIFIED;
  4456.      
  4457. function ISS return THIRTYTWO_BITS  is
  4458.      
  4459. X : THIRTYTWO_BITS  := 0;
  4460.      
  4461. begin
  4462.  -- THE TIME IS IN MILLISECONDS. MULTIPLYING BY 250
  4463.  -- MAKES THE TIME APPEAR TO BELONG TO A CLOCK
  4464.  -- INCREMENTED EVERY FOUR MICROSECONDS.
  4465.  return X;-- TEMPORARY FOR TEST(LOCAL_TIME_NOW * 250);
  4466. end ISS;
  4467.      
  4468. procedure ADDRESS_DECODER ( CONCATENATION : in THIRTYTWO_BITS ) is
  4469.      
  4470. type DUMB is array(1..1) of THIRTYTWO_BITS ;
  4471. type TEMP is array(1..4) of SYSTEM_BYTE;
  4472. function CONVERT is new UNCHECKED_CONVERSION(DUMB, TEMP);
  4473. function CONVERT_LONG is new UNCHECKED_CONVERSION(TEMP, DUMB);
  4474. X : DUMB := (1 => CONCATENATION);
  4475. Y,W : TEMP;
  4476. Z : DUMB;
  4477.      
  4478. begin
  4479.  -- THE ADDRESSES ARE CONCATENATED INTO A 32 BIT LONG WORD. THE CODE FOR
  4480.  -- THE TYPES CAN BE FOUND IN THE INTERNET SPECIFICATION.
  4481.  W(1) := 0;
  4482.  W(2) := 0;
  4483.  W(3) := 0;
  4484.  W(4) := 0;
  4485.  Y := CONVERT(X);
  4486.  -- 7 BITS INTERNET ADDRESS AND 24 BITS HOST ADDRESS.
  4487.  if X(1) > 0 then
  4488.  LCN.FOREIGN_NET := THIRTYTWO_BITS (Y(4));
  4489.  Y(4) := 0;
  4490.  Z := CONVERT_LONG(Y);
  4491.  LCN.FOREIGN_HOST := Z(1);
  4492.  -- 14 BITS INTERNET ADDRESS AND 16 HOST ADDRESS.
  4493. elsif SIXTEEN_BITS ( Y(4) ) / 2**6 = 2 then
  4494.  Y(4) := SYSTEM."-" (Y(4), 192 ) ;
  4495.  W(2) := Y(4);
  4496.  W(1) := Y(3);
  4497.  Z := CONVERT_LONG(W);
  4498.  LCN.FOREIGN_NET := Z(1);
  4499.  W(2) := Y(2);
  4500.  W(1) := Y(1);
  4501.  Z := CONVERT_LONG(W);
  4502.  LCN.FOREIGN_HOST := Z(1);
  4503. elsif SIXTEEN_BITS(Y(4))/2**5 = 6 then
  4504.  -- 21 BITS INTERNET ADDRESS AND 8 HOST ADDRESS.
  4505.  Y(4) := SYSTEM."-" (Y(4), 192 ) ;
  4506.  W(3) := Y(4);
  4507.  W(2) := Y(3);
  4508.  W(1) := Y(2);
  4509.  Z := CONVERT_LONG(W);
  4510.  LCN.FOREIGN_NET := Z(1);
  4511. LCN.FOREIGN_HOST := THIRTYTWO_BITS (Y(1));
  4512. elsif SIXTEEN_BITS(Y(4))/2**5 = 7 then
  4513.  -- CURRENTLY NO EXTENDED ADDRESSING
  4514.  TCP_ERROR(2);
  4515.  null;
  4516. else
  4517.  TCP_ERROR(3);
  4518. end if;
  4519. exception
  4520. when others =>
  4521.  PUT_LINE("ADDRESS DECODER FAILED");
  4522.  for I in 1..4 loop
  4523.   INT_IO_16.PUT( SIXTEEN_BITS(Y(I)) );
  4524.  end loop;
  4525. -- INTEGER_IO.PUT(LCN);
  4526. end ADDRESS_DECODER;
  4527.      
  4528. procedure INSERT_TEXT_IN_BUFFER( LENGTH : in SIXTEEN_BITS ;
  4529.                                  RECEIVED_PACKED_BUFFER : in PACKED_BUFFER_PTR;
  4530.                                  DATA_LENGTH : in SIXTEEN_BITS ;
  4531.                                  PACKED_BUFFER : in PACKED_BUFFER_PTR) is
  4532.      
  4533.         -- THE FIRST PARAMETERS ARE THE LENGTH OF THE DATA
  4534.         -- FIELD IN THE RECEIVE BUFFER  AND THE BUFFER.
  4535.         -- THE SECOND SET OF PARAMETERS ARE THE LENGTH OF THE DATA
  4536.         -- BUFFER AND THE DATA BUFFER.
  4537.      
  4538. INDEX, INDEX1 : SIXTEEN_BITS ;
  4539.      
  4540. begin
  4541.  INDEX := RECEIVED_PACKED_BUFFER.TCP_PTR;
  4542.  INDEX1 := PACKED_BUFFER.TCP_PTR;
  4543.  if DATA_LENGTH = LENGTH then
  4544.   RECEIVED_PACKED_BUFFER.BYTE(INDEX..INDEX+LENGTH) :=
  4545.    PACKED_BUFFER.BYTE(INDEX1..INDEX1+LENGTH);
  4546.    RECEIVED_PACKED_BUFFER.TELNET_PTR := RECEIVED_PACKED_BUFFER.TCP_PTR +
  4547.                                         LENGTH - 1;
  4548.  elsif DATA_LENGTH < LENGTH then
  4549.   RECEIVED_PACKED_BUFFER.BYTE(INDEX..INDEX + DATA_LENGTH) :=
  4550.    PACKED_BUFFER.BYTE(INDEX1..INDEX1 + DATA_LENGTH);
  4551.   -- Set the TELNET Pointer
  4552.   RECEIVED_PACKED_BUFFER.TELNET_PTR := RECEIVED_PACKED_BUFFER.TCP_PTR +
  4553.                                       DATA_LENGTH - 1;
  4554.  else -- WE CURRENTLY CAN'T HANDLE THIS CASE.
  4555.   TCP_ERROR(8);
  4556.  end if;
  4557. exception
  4558.  when others =>
  4559.   PUT_LINE("ERROR IN INSERT TEXT INTO BUFFER.");
  4560.   INT_IO_16.PUT(INDEX);
  4561.   INT_IO_16.PUT(INDEX1);
  4562.   INT_IO_16.PUT(LENGTH);
  4563. end INSERT_TEXT_IN_BUFFER;
  4564.      
  4565.         procedure TIMEOUT_CHECK(LCN : in TCB_PTR; ACTION : out TIME_ACTION) is
  4566.         TIME : THIRTYTWO_BITS  := THIRTYTWO_BITS(SYSTEM_TIME);
  4567.         RETRANS_TIME : THIRTYTWO_BITS  := QUEUES.QUEUE_RETRANS_TIME(LCN);
  4568.         begin
  4569.          if TIME >= LCN.NEXT_CONNECTION_TIMEOUT then
  4570.           ACTION := CONNECTION_TIMEOUT;
  4571.          elsif TIME >= LCN.NEXT_TIME_WAIT_TIMEOUT then
  4572.           ACTION :=  TIME_WAIT_TIMEOUT;
  4573.           -- WE MUST CHECK THE RETRANS TIMES
  4574.          elsif TIME >= RETRANS_TIME then
  4575.           ACTION := RETRANSMIT_TIMEOUT;
  4576.          end if;
  4577.         end TIMEOUT_CHECK;
  4578.      
  4579.  procedure START_TIMER(LCN : in TCB_PTR; TIMER : in TIMER_TYPE) is
  4580.      
  4581. -- pragma SUPPRESS(OVERFLOW_CHECK);
  4582.  --Note there will be a problem when local time now cycles.
  4583.  --this is every six hours.(VAX clock units are every .01 secs)
  4584.  begin
  4585.   --the MSL is one minute
  4586.   if TIMER = TIMEOUT_TIMER then
  4587.    LCN.NEXT_CONNECTION_TIMEOUT := THIRTYTWO_BITS(SYSTEM_TIME) +
  4588.                                      THIRTYTWO_BITS (10) *
  4589.                                      THIRTYTWO_BITS (LCN.CONNECTION_TIMEOUT);
  4590.                                      --APPROX 2 * MSL
  4591.   elsif TIMER = TIME_WAIT_TIMER then
  4592.    LCN.NEXT_TIME_WAIT_TIMEOUT := THIRTYTWO_BITS(SYSTEM_TIME) +
  4593.                                       THIRTYTWO_BITS (14);
  4594.                                       --14 sec. Two more then retrans time.
  4595.   else --calling the retrans timer which start automatically when queued.
  4596.    TCP_ERROR(17);
  4597.   end if;
  4598.  exception
  4599.   when CONSTRAINT_ERROR =>
  4600.    PUT_LINE("CONSTRAINT_ERROR in START_TIMER");
  4601.    NEW_LINE;
  4602.   when others =>
  4603.    PUT_LINE("unknown error in START_TIMER");
  4604.    NEW_LINE;
  4605.  end START_TIMER;
  4606.      
  4607. END TCP_GLOBALS;
  4608. --::::::::::::::
  4609. --icmp_.ada
  4610. --::::::::::::::
  4611. -----------------------------------------------------------------------
  4612. --
  4613. --         DoD Protocols    NA-00001-200       80-00990-100(-)
  4614. --         E-Systems, Inc.  August 07, 1985
  4615. --
  4616. --         ICMP_.ADA       Author : Jim Baldo
  4617. --
  4618. -----------------------------------------------------------------------
  4619.  
  4620. with SYSTEM;                use SYSTEM;
  4621. with BUFFER_DATA;            use BUFFER_DATA;
  4622. with IP_GLOBALS;            use IP_GLOBALS;
  4623.  
  4624.             package UTILITIES_FOR_ICMP is
  4625.  
  4626.         ----------------------------------------------------
  4627.         --This implementation is for use with DEC/ADA     --
  4628.         --compiler.                                       --
  4629.         ----------------------------------------------------
  4630.  
  4631. -- TEMPORARY FOR TESTING
  4632. -- UNTIL TCP MODULES ARE COMBINED
  4633. type TCP_PORT_ADDRESS_TYPE is array(1..2) of SYSTEM_BYTE; 
  4634.  
  4635.   function ICMP_CHECKSUM( START_PTR : SIXTEEN_BITS ; 
  4636.                           END_PTR : SIXTEEN_BITS ; 
  4637.                           PACKED_BUFFER : PACKED_BUFFER_PTR) 
  4638.                                  return SIXTEEN_BITS ;
  4639.  
  4640.     --This function requires a pointer to the beginning of 
  4641.     --the ICMP control message, pointer to the end of the IP header, 
  4642.     --and pointer to the datagram.  This function is compatible with 
  4643.     --MIL-STD-1777 section 9.4.6.2.4.
  4644.  
  4645.   procedure ICMP_MESSAGE_PROCESSOR( ICMP_MESSAGE : in out PACKED_BUFFER_PTR; 
  4646.                                 BUFPTR : IP_GLOBALS.BUFFER_POINTER);
  4647.  
  4648.     --This subprogram will determine what type of ICMP message has 
  4649.     --been sent by a remote host and process the message appropiately.
  4650.  
  4651.   procedure SEND_ICMP_MESSAGE( ICMP_MESSAGE : in out PACKED_BUFFER_PTR);
  4652.  
  4653.     --This subprogram takes an ICMP message datagram and sends it to 
  4654.     --the subnet protocol.
  4655.  
  4656. end UTILITIES_FOR_ICMP;
  4657. --::::::::::::::
  4658. --icmp.ada
  4659. --::::::::::::::
  4660. -----------------------------------------------------------------------
  4661. --
  4662. --         DoD Protocols    NA-00001-200       80-00991-100(-)
  4663. --         E-Systems, Inc.  August 07, 1985
  4664. --
  4665. --         ICMP.ADA       Author : Jim Baldo
  4666. --
  4667. -----------------------------------------------------------------------
  4668. with BUFFER_DATA;
  4669. with IP_UNPACK_AND_PACK_UTILITIES;
  4670. with UNCHECKED_CONVERSION;
  4671. with WITH_TCP_COMMUNICATE;
  4672. with TEXT_IO;
  4673.  
  4674. package body UTILITIES_FOR_ICMP is
  4675.  
  4676.   package INT_IO is new TEXT_IO.INTEGER_IO( SIXTEEN_BITS );
  4677.  
  4678.   type ERROR_TYPE is ( PARAM_PROBLEM,EXPIRED_TTL,PROTOCOL_UNREACH );
  4679.  
  4680.   function ICMP_CHECKSUM( START_PTR : SIXTEEN_BITS ; 
  4681.                           END_PTR : SIXTEEN_BITS ;
  4682.                           PACKED_BUFFER : BUFFER_DATA.PACKED_BUFFER_PTR) 
  4683.                                    return SIXTEEN_BITS  is
  4684.  
  4685.     --This function performs a checksum on the ICMP control message
  4686.     --For purpose of computing the checksum, the checksum field
  4687.     --(octets 2-3) is set to zero.  Implementation dependent action.
  4688.  
  4689.   type TWO_WORDS is array (1..2) of SIXTEEN_BITS ;
  4690.   type TELESOFT_FIXUP is array (1..1) of THIRTYTWO_BITS ;
  4691.   function CONVERSION is new UNCHECKED_CONVERSION( TELESOFT_FIXUP,TWO_WORDS );
  4692.   HIGH_BYTE : BOOLEAN := TRUE;
  4693.   ICMP_CHECKSUM : THIRTYTWO_BITS  := 0;
  4694.   CSUM : TWO_WORDS := ( 0,0 );
  4695.   CHECKSUM : TELESOFT_FIXUP;
  4696.  
  4697.   begin
  4698.     for I in 0..END_PTR-1 loop
  4699.       if ( I /= 2 ) and then ( I /= 3 ) then
  4700.         if HIGH_BYTE then
  4701.           HIGH_BYTE := FALSE;
  4702.           ICMP_CHECKSUM := ICMP_CHECKSUM + 
  4703.         THIRTYTWO_BITS ( PACKED_BUFFER.BYTE( START_PTR + I ) ) *
  4704.                     THIRTYTWO_BITS ( 2**8 );
  4705.         else
  4706.           HIGH_BYTE := TRUE;
  4707.           ICMP_CHECKSUM := ICMP_CHECKSUM + 
  4708.         THIRTYTWO_BITS ( PACKED_BUFFER.BYTE( START_PTR + I ) );
  4709.         end if;
  4710.       end if;
  4711.     end loop;
  4712.     -- Take one's complement of ICMP_CHECKSUM
  4713.     ICMP_CHECKSUM := -ICMP_CHECKSUM;
  4714.     ICMP_CHECKSUM := ICMP_CHECKSUM - 1;
  4715.     
  4716.     -- This is a parameter passing problem globally specific to Telesoft
  4717.     CHECKSUM(1) := ICMP_CHECKSUM;
  4718.     
  4719.     -- Get both words and return low word.
  4720.     CSUM := CONVERSION( CHECKSUM );
  4721.     return CSUM( 2 );
  4722.     exception
  4723.       when constraint_error => 
  4724.         TEXT_IO.PUT_LINE( "Checksum Error in package UTILITIES_FOR_ICMP ");
  4725.     TEXT_IO.PUT_LINE( "function CHECKSUM )" );
  4726.         INT_IO.PUT( START_PTR );
  4727.       -- SYSTEM.REPORT ERROR
  4728.       when others => 
  4729.         TEXT_IO.PUT_LINE( "Checksum Error in package UTILITIES_FOR_ICMP ");
  4730.     TEXT_IO.PUT_LINE( "function CHECKSUM )" );
  4731.   end ICMP_CHECKSUM;
  4732.  
  4733.   procedure SEND_ICMP_MESSAGE
  4734.     (ICMP_MESSAGE : in out BUFFER_DATA.PACKED_BUFFER_PTR) is
  4735.  
  4736.     --This subprogram takes an ICMP message datagram and sends it to 
  4737.     --the subnet protocol.  
  4738.   begin
  4739.   --  X_25_DATA.LOCAL_DESTINATION_ADDRESS := ICMP_BUFPTR.DEST;
  4740.   --  X_25_DATA.TYPE_OF_SERVICE := ICMP_BUFPTR.TOS;
  4741.   --  X_25_DATA.LENGTH := ICMP_BUFPTR.TOT_LEN;
  4742.   --  X_25_DATA.DTGM := ICMP_MESSAGE;
  4743.   --  X_25_SEND(X_25_DATA);
  4744.   null;
  4745.   exception
  4746.     when constraint_error =>
  4747.       TEXT_IO.PUT_LINE("constraint error in package UTILITES_FOR_ICMP ");
  4748.       TEXT_IO.PUT_LINE( "procedure SEND_ICMP_MESSAGE");
  4749.     when others =>
  4750.       TEXT_IO.PUT_LINE("error OTHERS in package UTILITES_FOR_ICMP procedure ");
  4751.       TEXT_IO.PUT_LINE( "SEND_ICMP_MESSAGE");
  4752.   end SEND_ICMP_MESSAGE;
  4753.  
  4754.   procedure ICMP_MESSAGE_PROCESSOR
  4755.     (ICMP_MESSAGE : in out BUFFER_DATA.PACKED_BUFFER_PTR; 
  4756.     BUFPTR : IP_GLOBALS.BUFFER_POINTER) is
  4757.   type GOOD_OR_BAD IS (GOOD,BAD);
  4758.   type TWO_BYTE is array(1..2) of SYSTEM_BYTE;
  4759.   type TELEGOOFUP is array(1..1) of SIXTEEN_BITS ;
  4760.  
  4761.   function CONVERT_TO_TWO_BYTES is new 
  4762.     UNCHECKED_CONVERSION(TELEGOOFUP, TWO_BYTE);
  4763.  
  4764.   WORD_TO_CONVERT : TELEGOOFUP;
  4765.   TEMP : TWO_BYTE;
  4766.   IHL_IN_OCTETS : SIXTEEN_BITS  := 0;
  4767.   ULP_SOURCE_PORT : TCP_PORT_ADDRESS_TYPE;
  4768.   ULP_DESTINATION_PORT : TCP_PORT_ADDRESS_TYPE;
  4769.   ICMP_ERROR_MESSAGE : STRING(1..80);
  4770.   IP_SOURCE_ADDRESS_TEMPORARY_SAVE_FRONT : SYSTEM_BYTE;
  4771.   IP_SOURCE_ADDRESS_TEMPORARY_SAVE_BACK : SYSTEM_BYTE;
  4772.   IP_HEADER_INFO : IP_GLOBALS.BUFFER_POINTER;
  4773.   IP_HEADER_POINTER : SIXTEEN_BITS  := 0;
  4774.   IP_DATAGRAM_TOTAL_LENGTH : SIXTEEN_BITS  := 0;
  4775.   VERSIONS : SIXTEEN_BITS  := 0;
  4776.   IHL : SIXTEEN_BITS  := 0;
  4777.   ICMP_TYPE : SIXTEEN_BITS  := 0;
  4778.   ICMP_CODE : SIXTEEN_BITS  :=0;
  4779.   START_PTR_FOR_ICMP_CHECKSUM : SIXTEEN_BITS  := 0;
  4780.   END_PTR_FOR_ICMP_CHECKSUM : SIXTEEN_BITS  := 0;
  4781.   TELNET_PTR : constant SIXTEEN_BITS  := ICMP_MESSAGE.TELNET_PTR;
  4782.   TCP_PTR : constant SIXTEEN_BITS  := ICMP_MESSAGE.TCP_PTR;
  4783.   IP_PTR : constant SIXTEEN_BITS  := ICMP_MESSAGE.IP_PTR;
  4784.   function CHECK_ICMP_CHECKSUM return GOOD_OR_BAD is
  4785.     type INT_ARRAY is array(1..1) of SIXTEEN_BITS ;
  4786.     type TWO_BYTES is array(1..2) of SYSTEM_BYTE;
  4787.     
  4788.     function CONVERT_TO_INTEGER is new 
  4789.     UNCHECKED_CONVERSION(TWO_BYTES,INT_ARRAY);
  4790.     BUF_CSUM : TWO_BYTES;
  4791.     CARRIER_CSUM : INT_ARRAY;
  4792.     INCOMING_ICMP_DATAGRAM_CHECKSUM_CARRIER : INT_ARRAY;
  4793.     INCOMING_ICMP_DATAGRAM_CHECKSUM_CALCULATED : INT_ARRAY;
  4794.     START_PRT_FOR_ICMP_CHECKSUM : SIXTEEN_BITS  := 0;
  4795.     END_PTR_FOR_ICMP_CHECKSUM : SIXTEEN_BITS  := 0;
  4796.     
  4797.     begin
  4798.       BUF_CSUM(1) := ICMP_MESSAGE.BYTE(IP_HEADER_POINTER + 2);
  4799.       BUF_CSUM(2) := ICMP_MESSAGE.BYTE(IP_HEADER_POINTER + 3);
  4800.       INCOMING_ICMP_DATAGRAM_CHECKSUM_CARRIER := CONVERT_TO_INTEGER(BUF_CSUM);
  4801.       START_PTR_FOR_ICMP_CHECKSUM := IP_HEADER_POINTER + IHL;
  4802.       END_PTR_FOR_ICMP_CHECKSUM := IP_HEADER_POINTER + 
  4803.     IP_DATAGRAM_TOTAL_LENGTH;
  4804.       INCOMING_ICMP_DATAGRAM_CHECKSUM_CALCULATED(1) :=
  4805.         ICMP_CHECKSUM
  4806.     (START_PRT_FOR_ICMP_CHECKSUM,END_PTR_FOR_ICMP_CHECKSUM,ICMP_MESSAGE);
  4807.       if INCOMING_ICMP_DATAGRAM_CHECKSUM_CARRIER = 
  4808.         INCOMING_ICMP_DATAGRAM_CHECKSUM_CALCULATED  then
  4809.         return GOOD;
  4810.       else
  4811.         return BAD;
  4812.       end if;
  4813.     end CHECK_ICMP_CHECKSUM;
  4814.  
  4815.     procedure PACK_ICMP_MESSAGE_FOR_ULP( ULP_SOURCE_PORT,
  4816.                                          ULP_DESTINATION_PORT :
  4817.                                          in TCP_PORT_ADDRESS_TYPE;
  4818.                                          ICMP_ERROR_MESSAGE : in STRING) is
  4819.  
  4820.     type STUPID is array(1..1) of CHARACTER;
  4821.     type A_BYTE is array(1..1) of SYSTEM_BYTE;
  4822.     function CONVERT_STRING_TO_SYSTEM_BYTE is 
  4823.     new UNCHECKED_CONVERSION(STUPID,A_BYTE);
  4824.     OFFSET : SIXTEEN_BITS ;
  4825.     SLICE_SAVER : STUPID;
  4826.  
  4827.     begin
  4828.       -- Load message
  4829.       OFFSET := ICMP_ERROR_MESSAGE'LENGTH;
  4830.       -- Convert string to system byte
  4831.       for I in 0..OFFSET-1 loop
  4832. --        SLICE_SAVER(1) := ICMP_ERROR_MESSAGE( I );
  4833. --        ICMP_MESSAGE.BYTE(TELNET_PTR + I)
  4834. --          := CONVERT_STRING_TO_SYSTEM_BYTE(SLICE_SAVER)(1) ;
  4835.         null;--temp
  4836.       end loop;
  4837.       -- TCP Header Setput
  4838.         -- Load Source Port
  4839.       for I in 1..2 loop
  4840.         ICMP_MESSAGE.BYTE(TCP_PTR + SIXTEEN_BITS ( I ) -1) :=
  4841.           ULP_SOURCE_PORT(I);
  4842.       end loop;
  4843.         -- Load Destination Port
  4844.       for I in 1..2 loop
  4845.         ICMP_MESSAGE.BYTE(TCP_PTR + SIXTEEN_BITS ( I ) + 2 -1) :=
  4846.           ULP_DESTINATION_PORT(I);
  4847.       end loop;
  4848.     end PACK_ICMP_MESSAGE_FOR_ULP;
  4849.  
  4850.     procedure OBTAIN_ULP_SOURCE_DESTINATION(ULP_SOURCE_PORT,
  4851.               ULP_DESTINATION_PORT :
  4852.               out TCP_PORT_ADDRESS_TYPE;
  4853.               IHL : SIXTEEN_BITS ) is
  4854.  
  4855.     VERSION_SENT_DATAGRAM : SIXTEEN_BITS ;
  4856.     IHL_SENT_DATAGRAM : SIXTEEN_BITS ;
  4857.     IHL_PORT_POINTER : SIXTEEN_BITS ;
  4858.     IHL_PORT_POINTER_SENT_DATAGRAM : SIXTEEN_BITS ;
  4859.     begin
  4860.       VERSION_SENT_DATAGRAM := SIXTEEN_BITS ( 
  4861.                       ICMP_MESSAGE.BYTE(IP_PTR + IHL + 4)/2**4 ) ;
  4862.       IHL_SENT_DATAGRAM := SIXTEEN_BITS ( 
  4863.                 ICMP_MESSAGE.BYTE(IP_PTR + IHL + 4) ) -
  4864.             (VERSION_SENT_DATAGRAM * (2**4)) * 4;
  4865.       IHL_PORT_POINTER_SENT_DATAGRAM := IP_PTR + IHL + 4 + IHL_SENT_DATAGRAM;
  4866.       ULP_SOURCE_PORT(1) := ICMP_MESSAGE.BYTE(IHL_PORT_POINTER); 
  4867.       ULP_SOURCE_PORT(2) := ICMP_MESSAGE.BYTE(IHL_PORT_POINTER + 1);
  4868.       ULP_DESTINATION_PORT(1) := ICMP_MESSAGE.BYTE(IHL_PORT_POINTER + 2);
  4869.       ULP_DESTINATION_PORT(2) := ICMP_MESSAGE.BYTE(IHL_PORT_POINTER + 3);
  4870.     end OBTAIN_ULP_SOURCE_DESTINATION;
  4871.   begin
  4872.     IP_HEADER_POINTER := ICMP_MESSAGE.IP_PTR;
  4873.     -- Convert IHL from 32-bit word size to 8-bit OCTETS
  4874.     IHL_IN_OCTETS := BUFPTR.IHL * 4;
  4875.     ICMP_TYPE := SIXTEEN_BITS ( 
  4876.         ICMP_MESSAGE.BYTE(IP_HEADER_POINTER + IHL_IN_OCTETS)) ;
  4877.     ICMP_CODE := SIXTEEN_BITS ( 
  4878.                   ICMP_MESSAGE.BYTE(IP_HEADER_POINTER + IHL_IN_OCTETS + 1)) ;
  4879.     if (BUFPTR.PROT = 1) and (CHECK_ICMP_CHECKSUM = GOOD)  then
  4880.       case ICMP_TYPE is
  4881.         
  4882.         when 0 => -- echo reply message
  4883.           -- Presently not supported by this implementation version
  4884.           TEXT_IO.PUT_LINE(" Recieved echo reply message ");
  4885.           TEXT_IO.PUT_LINE(" package UTILITIES_FOR_ICMP ");
  4886.       TEXT_IO.PUT_LINE( "procedure ICMP_MESSAGE_PROCESSOR ");
  4887.           -- never recieved; always sent
  4888.  
  4889.         when 3=> -- destination unreachable messasge
  4890.           case ICMP_CODE is
  4891.             
  4892.             when 0 => -- net unreachable
  4893.               OBTAIN_ULP_SOURCE_DESTINATION(ULP_SOURCE_PORT,
  4894.                     ULP_DESTINATION_PORT,
  4895.                     IHL);
  4896.               -- load error message for net unreachable to be displayed by ULP
  4897.               ICMP_ERROR_MESSAGE(1..38) := 
  4898.         " ICMP Error Message : Net Unreachable ";
  4899.               -- format ICMP error message for ULP
  4900.               PACK_ICMP_MESSAGE_FOR_ULP(ULP_SOURCE_PORT,
  4901.                     ULP_DESTINATION_PORT,
  4902.                     ICMP_ERROR_MESSAGE);
  4903.             
  4904.             when 1 => -- host unreachable
  4905.               OBTAIN_ULP_SOURCE_DESTINATION(ULP_SOURCE_PORT,
  4906.                     ULP_DESTINATION_PORT,
  4907.                     IHL);
  4908.               -- load error message for host unreachable to be displayed by ULP
  4909.               ICMP_ERROR_MESSAGE(1..39) := 
  4910.         " ICMP Error Message : Host Unreachable ";
  4911.               -- format ICMP error message for ULP
  4912.               PACK_ICMP_MESSAGE_FOR_ULP(ULP_SOURCE_PORT,
  4913.                     ULP_DESTINATION_PORT,
  4914.                     ICMP_ERROR_MESSAGE);
  4915.             
  4916.             when 2 => -- protocol unreachable
  4917.               OBTAIN_ULP_SOURCE_DESTINATION(ULP_SOURCE_PORT,
  4918.                     ULP_DESTINATION_PORT,
  4919.                     IHL);
  4920.               -- load error message for protocol unreachable to be displayed 
  4921.           -- by ULP
  4922.               ICMP_ERROR_MESSAGE(1..43) := 
  4923.         " ICMP Error Message : Protocol Unreachable ";
  4924.               -- format ICMP error message for ULP
  4925.               PACK_ICMP_MESSAGE_FOR_ULP(ULP_SOURCE_PORT,
  4926.                     ULP_DESTINATION_PORT,
  4927.                     ICMP_ERROR_MESSAGE);
  4928.             
  4929.             when 3 => -- port unreachable
  4930.               OBTAIN_ULP_SOURCE_DESTINATION(ULP_SOURCE_PORT,
  4931.                     ULP_DESTINATION_PORT,
  4932.                     IHL);
  4933.               -- load error message for port unreachable to be displayed by ULP
  4934.               ICMP_ERROR_MESSAGE(1..39) := 
  4935.         " ICMP Error Message : Port Unreachable ";
  4936.               -- format ICMP error message for ULP
  4937.               PACK_ICMP_MESSAGE_FOR_ULP(ULP_SOURCE_PORT,
  4938.                     ULP_DESTINATION_PORT,
  4939.                     ICMP_ERROR_MESSAGE);
  4940.             
  4941.             when 4 => -- fragmentation needed and Don't Fragment
  4942.                       -- Flag is set              
  4943.               OBTAIN_ULP_SOURCE_DESTINATION(ULP_SOURCE_PORT,
  4944.                     ULP_DESTINATION_PORT,
  4945.                     IHL);
  4946.               -- load error message to be displayed by ULP
  4947.           ICMP_ERROR_MESSAGE(1..74) := 
  4948. " ICMP Error Message : fragmentation needed and Don't Fragment Flag is set ";
  4949.               -- format ICMP error message for ULP
  4950.               PACK_ICMP_MESSAGE_FOR_ULP(ULP_SOURCE_PORT,
  4951.                     ULP_DESTINATION_PORT,
  4952.                     ICMP_ERROR_MESSAGE);
  4953.             
  4954.             when 5 => -- source route failed
  4955.               OBTAIN_ULP_SOURCE_DESTINATION(ULP_SOURCE_PORT,
  4956.                     ULP_DESTINATION_PORT,
  4957.                     IHL);
  4958.               -- load error message to be displayed by ULP
  4959.               ICMP_ERROR_MESSAGE(1..42) := 
  4960.         " ICMP Error Message : source route failed ";
  4961.               -- format ICMP error message for ULP
  4962.               PACK_ICMP_MESSAGE_FOR_ULP(ULP_SOURCE_PORT,
  4963.                     ULP_DESTINATION_PORT,
  4964.                     ICMP_ERROR_MESSAGE);
  4965.             when others =>
  4966.       TEXT_IO.PUT_LINE(" Error message package UTILITIES_FOR_ICMP ");
  4967. TEXT_IO.PUT_LINE( "procedure ICMP_MESSAGE_PROCESSOR case exhaustive error ");
  4968.           TEXT_IO.PUT_LINE(" Bogus ICMP message #3 code field ");
  4969.           end case;
  4970.         
  4971.         when 4 => -- Source Quench Message
  4972.               OBTAIN_ULP_SOURCE_DESTINATION(ULP_SOURCE_PORT,
  4973.                     ULP_DESTINATION_PORT,
  4974.                     IHL);
  4975.               -- load error message to be displayed by ULP
  4976.               ICMP_ERROR_MESSAGE(1..44) := 
  4977.         " ICMP Error Message : source quench message ";
  4978.               -- format ICMP error message for ULP
  4979.               PACK_ICMP_MESSAGE_FOR_ULP(ULP_SOURCE_PORT,
  4980.                     ULP_DESTINATION_PORT,
  4981.                     ICMP_ERROR_MESSAGE);
  4982.         
  4983.         when 5 => -- Redirect Message
  4984.           case ICMP_CODE is
  4985.             
  4986.             when 0 => -- redirect datagrams for the Network
  4987.               OBTAIN_ULP_SOURCE_DESTINATION(ULP_SOURCE_PORT,
  4988.                     ULP_DESTINATION_PORT,
  4989.                     IHL);
  4990.               -- load error message to be displayed by ULP 
  4991.         ICMP_ERROR_MESSAGE(1..57) := 
  4992.           " ICMP Error Message : redirect datagrams for the Network ";
  4993.               -- format ICMP error message for ULP
  4994.               PACK_ICMP_MESSAGE_FOR_ULP(ULP_SOURCE_PORT,
  4995.                     ULP_DESTINATION_PORT,
  4996.                     ICMP_ERROR_MESSAGE);
  4997.             
  4998.             
  4999.             when 1 => -- redirect datagrams for the Host
  5000.               OBTAIN_ULP_SOURCE_DESTINATION(ULP_SOURCE_PORT,
  5001.                     ULP_DESTINATION_PORT,
  5002.                     IHL);
  5003.               -- load error message to be displayed by ULP
  5004.         ICMP_ERROR_MESSAGE(1..54) := 
  5005.           " ICMP Error Message : redirect datagrams for the Host ";
  5006.               -- format ICMP error message for ULP
  5007.               PACK_ICMP_MESSAGE_FOR_ULP(ULP_SOURCE_PORT,
  5008.                     ULP_DESTINATION_PORT,
  5009.                     ICMP_ERROR_MESSAGE);
  5010.             
  5011.             
  5012.             when 2 => -- redirect datagrams for the type of service and network
  5013.               OBTAIN_ULP_SOURCE_DESTINATION(ULP_SOURCE_PORT,
  5014.                     ULP_DESTINATION_PORT,
  5015.                     IHL);
  5016.               -- load error message to be displayed by ULP
  5017.         ICMP_ERROR_MESSAGE(1..76) := 
  5018. "ICMP Error Message : redirect datagrams for the type of service and network ";
  5019.               -- format ICMP error message for ULP
  5020.               PACK_ICMP_MESSAGE_FOR_ULP(ULP_SOURCE_PORT,
  5021.                     ULP_DESTINATION_PORT,
  5022.                     ICMP_ERROR_MESSAGE);
  5023.             
  5024.             when 3 => -- redirect datagrams for the type of service and host
  5025.               OBTAIN_ULP_SOURCE_DESTINATION(ULP_SOURCE_PORT,
  5026.                     ULP_DESTINATION_PORT,
  5027.                     IHL);
  5028.               -- load error message to be displayed by ULP
  5029.         ICMP_ERROR_MESSAGE(1..74) := 
  5030. " ICMP Error Message : redirect datagrams for the type of service and host ";
  5031.               -- format ICMP error message for ULP
  5032.               PACK_ICMP_MESSAGE_FOR_ULP(ULP_SOURCE_PORT,
  5033.                     ULP_DESTINATION_PORT,
  5034.                     ICMP_ERROR_MESSAGE);
  5035.             when others =>
  5036.         TEXT_IO.PUT_LINE(" Error message package UTILITIES_FOR_ICMP ");
  5037. TEXT_IO.PUT_LINE( "procedure ICMP_MESSAGE_PROCESSOR case exhaustive error ");
  5038.   TEXT_IO.PUT_LINE(" Bogus ICMP message #5 code field ");
  5039.           end case;            
  5040.       
  5041.         
  5042.         when 8 => -- Echo Message
  5043.           ICMP_MESSAGE.BYTE(IP_HEADER_POINTER + IHL_IN_OCTETS) := 0; 
  5044.         -- Echo Reply Message Type
  5045.           ICMP_MESSAGE.BYTE(IP_HEADER_POINTER + IHL_IN_OCTETS + 1) := 0; 
  5046.         -- Code field
  5047.           IP_SOURCE_ADDRESS_TEMPORARY_SAVE_FRONT := 
  5048.         ICMP_MESSAGE.BYTE(IP_HEADER_POINTER + 6);
  5049.           IP_SOURCE_ADDRESS_TEMPORARY_SAVE_BACK := 
  5050.         ICMP_MESSAGE.BYTE(IP_HEADER_POINTER + 7);
  5051.           ICMP_MESSAGE.BYTE(IP_HEADER_POINTER + 6) := 
  5052.             ICMP_MESSAGE.BYTE(IP_HEADER_POINTER + 8);
  5053.           ICMP_MESSAGE.BYTE(IP_HEADER_POINTER + 7) :=
  5054.             ICMP_MESSAGE.BYTE(IP_HEADER_POINTER + 9);
  5055.           ICMP_MESSAGE.BYTE(IP_HEADER_POINTER + 8) := 
  5056.             IP_SOURCE_ADDRESS_TEMPORARY_SAVE_FRONT;
  5057.           ICMP_MESSAGE.BYTE(IP_HEADER_POINTER + 9) :=
  5058.             IP_SOURCE_ADDRESS_TEMPORARY_SAVE_BACK;
  5059.           START_PTR_FOR_ICMP_CHECKSUM := IP_HEADER_POINTER + IHL_IN_OCTETS;
  5060.           END_PTR_FOR_ICMP_CHECKSUM := IP_HEADER_POINTER + 
  5061.         IP_DATAGRAM_TOTAL_LENGTH;
  5062.           -- load icmp checksum
  5063.           WORD_TO_CONVERT(1) := 
  5064.             ICMP_CHECKSUM(START_PTR_FOR_ICMP_CHECKSUM,END_PTR_FOR_ICMP_CHECKSUM,
  5065.             ICMP_MESSAGE);
  5066.           TEMP := CONVERT_TO_TWO_BYTES(WORD_TO_CONVERT);
  5067.           -- implementation dependent (VAX)
  5068.           ICMP_MESSAGE.BYTE(IP_HEADER_POINTER + IHL_IN_OCTETS + 2) := TEMP(2);
  5069.           ICMP_MESSAGE.BYTE(IP_HEADER_POINTER + IHL_IN_OCTETS + 3) := TEMP(1); 
  5070.           SEND_ICMP_MESSAGE(ICMP_MESSAGE);
  5071.         
  5072.         when 12 => -- Parameter Problem Message
  5073.           OBTAIN_ULP_SOURCE_DESTINATION(ULP_SOURCE_PORT,
  5074.                 ULP_DESTINATION_PORT,
  5075.                 IHL);
  5076.           -- load error message to be displayed by ULP
  5077.           ICMP_ERROR_MESSAGE(1..48) := 
  5078.         " ICMP Error Message : Parameter Problem Message ";
  5079.           -- format ICMP error message for ULP
  5080.           PACK_ICMP_MESSAGE_FOR_ULP(ULP_SOURCE_PORT,
  5081.                 ULP_DESTINATION_PORT,
  5082.                 ICMP_ERROR_MESSAGE);
  5083.         
  5084.         when 13 => -- Timestamp Message
  5085.           -- not implemented
  5086.           null;
  5087.         
  5088.         when 14 => -- Timestamp Message Reply
  5089.           -- not implemented
  5090.           null;
  5091.         
  5092.         when 15 => -- Information Request Message
  5093.           -- not implemented
  5094.           null;
  5095.         
  5096.         when 16 => -- Information Reply
  5097.           -- not implemented
  5098.           null;
  5099.         when others =>
  5100. TEXT_IO.PUT_LINE(" Error message package UTILITIES_FOR_ICMP ");
  5101. TEXT_IO.PUT_LINE( "procedure ICMP_MESSAGE_PROCESSOR case exhaustive error ");
  5102.   TEXT_IO.PUT_LINE(" Bogus ICMP type ");
  5103.       end case;
  5104.     else
  5105.       if BUFPTR.PROT /= 1 then
  5106.         --for fault tolertant software reliability to protect against users of 
  5107.     --package this should never happen if package is understood by user or 
  5108.     --runtime system is functionally properly
  5109.         TEXT_IO.PUT_LINE("Error message : package UTILITES_FOR_ICMP  ");
  5110.     TEXT_IO.PUT_LINE( "procedure ICMP_MESSAGE_PROCESSOR");
  5111.         TEXT_IO.PUT_LINE("procedure called with wrong protocol number");
  5112.       end if;
  5113.       if CHECK_ICMP_CHECKSUM = BAD then
  5114.         TEXT_IO.PUT_LINE("Error message : package UTILITES_FOR_ICMP  ");
  5115.     TEXT_IO.PUT_LINE( "procedure ICMP_MESSAGE_PROCESSOR");
  5116.         TEXT_IO.PUT_LINE("ICMP_CHECKSUM  message was BAD");
  5117.       end if;
  5118.     end if;
  5119.   end ICMP_MESSAGE_PROCESSOR;
  5120. end UTILITIES_FOR_ICMP;
  5121. --::::::::::::::
  5122. --reassem_.ada
  5123. --::::::::::::::
  5124. -----------------------------------------------------------------------
  5125. --
  5126. --         DoD Protocols    NA-00001-200       80-01004-100(-)
  5127. --         E-Systems, Inc.  August 07, 1985
  5128. --
  5129. --         REASSEM_.ADA       Author : Jim Baldo
  5130. --
  5131. -----------------------------------------------------------------------
  5132. with SYSTEM;                use SYSTEM;
  5133. with BUFFER_DATA;            use BUFFER_DATA;
  5134. with IP_GLOBALS;            use IP_GLOBALS;
  5135.  
  5136.         package REASSEMBLY_UTILITIES is
  5137.  
  5138.     ----------------------------------------------------------
  5139.     --This implementation is for use with the DEC/Ada       --
  5140.     --compiler.                                             --
  5141.     ----------------------------------------------------------
  5142.  
  5143.  
  5144. ------------------------------------------------------------------------------
  5145. --This package contains the necessary functions and subprograms needed      --
  5146. --to support the reassembly mechnism of IP as specified by MIL-STD-1777.    --
  5147. ------------------------------------------------------------------------------
  5148.  
  5149. MAXIMUM_DATA_RECEIVED_IN_FRAGMENT : constant SIXTEEN_BITS  := 512;
  5150. MAXIMUM_DATAGRAM_SIZE : constant SIXTEEN_BITS  := 576;
  5151. type STATE_NAME_TYPE is ( INACTIVE, REASSEMBLING );
  5152. type DATA_AREA is array(1..MAXIMUM_DATA_RECEIVED_IN_FRAGMENT) of SYSTEM_BYTE;
  5153. type BIT_MAP is array(1..MAXIMUM_DATAGRAM_SIZE) of SIXTEEN_BITS ;
  5154.  
  5155. subtype PROTOCOL_TYPE is SIXTEEN_BITS ; --should be a set of DoD accepted protocols
  5156. subtype IDENTIFICATION_TYPE is SIXTEEN_BITS ; --should have a range constraint
  5157.  
  5158. type BUFID_TYPE is
  5159.   record
  5160.     SOURCE : THIRTYTWO_BITS ;
  5161.     DESTINATION : THIRTYTWO_BITS ;
  5162.     PROTOCOL : PROTOCOL_TYPE;
  5163.     IDENTIFICATION : IDENTIFICATION_TYPE;
  5164.   end record;
  5165. type YES_OR_NO is (YES,NO);
  5166.  
  5167. MAXIMUM_REASSEMBLY_TIMEOUT : constant SIXTEEN_BITS := 225;
  5168.  
  5169. subtype TIMER_TYPE is SIXTEEN_BITS range 15..MAXIMUM_REASSEMBLY_TIMEOUT;
  5170.  
  5171. type REASSEMBLY_TABLE_TYPE;
  5172. type REASSEMBLY_TABLE_POINTER is access REASSEMBLY_TABLE_TYPE;
  5173. type REASSEMBLY_TABLE_TYPE is 
  5174.   record
  5175.     PRIOR_ENTRY_REASSEMBLY_TABLE : REASSEMBLY_TABLE_POINTER;
  5176.     REASSEMBLY_DATAGRAM : BUFFER_DATA.PACKED_BUFFER_PTR;
  5177.     NEXT_ENTRY_REASSEMBLY_TABLE : REASSEMBLY_TABLE_POINTER;
  5178.       -- reassembly information
  5179.     BUFID : BUFID_TYPE;
  5180.     STATE_NAME : STATE_NAME_TYPE := INACTIVE;
  5181.     HAS_FRAGMENT_ZERO_ARRIVED : BOOLEAN := FALSE;
  5182.     REASSEMBLY_MAP : BIT_MAP;
  5183.     TIMER : TIMER_TYPE := 15;
  5184.     TOTAL_DATA_LENGTH :SIXTEEN_BITS  range 1..MAXIMUM_DATAGRAM_SIZE;
  5185.     DATA : DATA_AREA;
  5186.     HEADER : IP_GLOBALS.BUFFER_POINTER;
  5187.   end record;
  5188. type REASSEMBLY_ERROR_TYPE is 
  5189.     (NO_MORE_FREE_BUFFER_SPACE,NO_ERROR,NO_MORE_REASSEMBLY_BUFFER_SPACE);
  5190. --******************
  5191. --* USER Semantics *
  5192. --******************
  5193. --This function will return a true value if the incoming datagram
  5194. --is part of a fragment.
  5195.   function A_FRAG
  5196.     ( PACKED_BUFFER : in BUFFER_DATA.PACKED_BUFFER_PTR;
  5197.       BUFPTR :  in IP_GLOBALS.BUFFER_POINTER )
  5198.         return YES_OR_NO;
  5199. --**************************
  5200. --* PACKAGE BODY Semantics *
  5201. --**************************
  5202. --The following algorithm is completly compatible with MIL-STD-1777
  5203. --section 9.4.6.2.1.
  5204. --
  5205. --  Data examine:
  5206. --    FROM_SNP.DTGM.FRAGMENT_OFFSET
  5207. --    FROM_SNP.DTGM.MORE_FRAG_FLAG
  5208. --
  5209. --    if ((FROM_SNP.DTGM.FRAGMENT_OFFSET = 0)
  5210. --      and (FROM_SNP.DTGM.MORE_FRAG_FLAG = 0))
  5211. --      then return false
  5212. --      else return true;
  5213. --    end if;
  5214. --******************
  5215. --* USER Semantics *
  5216. --******************
  5217. --This function will return a true value if the incoming datagram
  5218. --completes the fragment being reassembled.
  5219.   function REASS_DONE
  5220.     ( REASSEMBLY_BUFFER : in REASSEMBLY_TABLE_POINTER;
  5221.       BUFPTR : IP_GLOBALS.BUFFER_POINTER )
  5222.         return YES_OR_NO;
  5223. --**************************
  5224. --* PACKAGE BODY Semantics *
  5225. --**************************
  5226. --  The total data length of the original datagram, as computed
  5227. --  from "tail" fragment, must be known before completion is
  5228. --  possible.
  5229. --
  5230. --  Data examined:
  5231. --    STATE_VECTOR.REASSEMBLY_MAP
  5232. --    STATE_VECTOR.TOTAL_DATA_LENGTH
  5233. --    FROM_SNP.DTGM.TOTAL_LENGTH
  5234. --    FROM_SNP.DTGM.MORE_FRAG_FLAG
  5235. --    FROM_SNP.DTGM.HEADER_LENGTH
  5236. --
  5237. --  if ( STATE_VECTOR.TOTAL_DATA_LENGTH = 0 ) then
  5238. --    Check incoming datagram for "tail."
  5239. --    if ( FROM_SNP.DTGM.MORE_FRAG_FLAG = false ) then
  5240. --      Compute total data length and see if data in
  5241. --      this fragment fill out reasembly map.
  5242. --      if ( STATE_VECTOR.REASEMBLY_MAP from 0 to
  5243. --         (((FROM_SNP.DTGM.TOTAL_LENGTH -
  5244. --            (FROM_SNP.DTGM.HEADER_LENGTH*4) + 7 ) / 8 )
  5245. --          + 7 ) / 8  is set )
  5246. --      then return true;
  5247. --      end if;
  5248. --    else
  5249. --      Reassembly cannot be complete if total data length
  5250. --      unknown.
  5251. --      return false;
  5252. --    end if;
  5253. --  else
  5254. --    Total data length is already known.  See if data in this
  5255. --    fragment fill out reassembly map.
  5256. --    if ( all reassembly map from 0 to
  5257. --      (STATE_VECTOR.TOTAL_DATA_LENGTH + 7 ) / 8 is set )
  5258. --    then
  5259. --      return YES;
  5260. --    else
  5261. --      return NO;
  5262. --  end if;
  5263. --******************
  5264. --* USER Semantics *
  5265. --******************
  5266. --This subprogram will generate an error datgram to the source IP informing
  5267. --it of the datagram's expiration during reassembly.
  5268.   procedure REASSEMBLY_TIMEOUT
  5269.     ( REASSEMBLY_DATAGRAM_THAT_TIMED_OUT : in out REASSEMBLY_TABLE_POINTER;
  5270.       BUFPTR : in IP_GLOBALS.BUFFER_POINTER );
  5271. --**************************
  5272. --* PACKAGE BODY Semantics *
  5273. --**************************
  5274. --
  5275. --  Data examined:
  5276. --    STATE_VECTOR.HEADER
  5277. --    STATE_VECTOR.DATA
  5278. --
  5279. --  Data modified:
  5280. --    TO_SNP.DTGM    TO_SNP.TYPE_OF_SERVICE_INDICATORS
  5281. --    TO_SNP.LENGTH    TO_SNP.HEADER_LENGTH
  5282. --
  5283. --  Format and transmit an error datagram to the source IP.
  5284. --
  5285. --  TO_SNP.DTGM.VERSION := 4; -- standard IP version
  5286. --  TO_SNP.DTGM.HEADER_LENGTH := 5; -- standard header size
  5287. --  TO_SNP.DTGM.TYPE_OF_SERVICE := 0; -- routine service quality
  5288. --  TO_SNP.DTGM.IDENTIFICATION := new value selected
  5289. --  TO_SNP.DTGM.MORE_FRAG_FLAG := false;
  5290. --  TO_SNP.DTGM.DONT_FRAG_FLAG := false;
  5291. --  TO_SNP.DTGM.FRAGMENT_OFFSET := 0;
  5292. --  TO_SNP.DTGM.TIME_TO_LIVE := 60;
  5293. --  TO_SNP.DTGM.PROTOCOL := this number will be assigned
  5294. --        by the DoD Executive Agent for
  5295. --        Protocols;
  5296. --  TO_SNP.DTGM.SOURCE_ADDR := STATE_VECTOR.HEADER.DESTINATION_ADDR;
  5297. --  TO_SNP.DTGM.DESTINATION_ADDR := STATE_VECTOR.HEADER.SOURCE_ADDR;
  5298. --  If the fragment received is the first fragment, then the data section
  5299. --  caries the ICMP error message, the header of the timed-out datagram,
  5300. --  and its first 64 bytes of data.  If fragment zero is not available
  5301. --  then no time exceeded need be sent at all.
  5302. --
  5303. --  TO_SNP.DTGM.DATA[0] := 12; -- ICMP type = Time Exceeded
  5304. --  TO_SNP.DTGM.DATA[1] := 1; -- Code = fragment reassembly timeout
  5305. --
  5306. --  Copy in the timed-out datagram's header plus the first
  5307. --  64 bytes of its data section (asumed to be of length "N" ).
  5308. --
  5309. --  TO_SNP.DTGM.DATA[8..N+3] := STATE_VECTOR[0..N-1];
  5310. --  TO_SNP.DTGM.TOTAL_LENGTH := TO_SNP.HEADER_LENGTH * 4 + N + 8;
  5311. --  COMPUTE_ICMP_CHECKSUM;
  5312. --
  5313. --  Compute datagram's header checksum, determine the route for the 
  5314. --  datagram, the type of service indicators, and the datagram size 
  5315. --  for the SNP.
  5316. --
  5317. --  COMPUTE_CHECKSUM;
  5318. --  TO_SNP.TYPE_OF_SERVICE_INDICATORS := 0;
  5319. --  TO_SNP.LENGTH := TO_SNP.DTGM.TOTAL_LENGTH;
  5320. --  ROUTE;
  5321. --
  5322. --  Request the execution environment to pass the contents of
  5323. --  TO_SNP to the local subnet protocol for transmision.
  5324. --
  5325. --  TRANSFER TO_SNP to the SNP.
  5326. --******************
  5327. --* USER Semantics *
  5328. --******************
  5329. --This subprogram will add a fragment to a reassembling datagram.
  5330.   procedure REASSEMBLY
  5331.     ( PACKED_BUFFER : in out BUFFER_DATA.PACKED_BUFFER_PTR;
  5332.       REASSEMBLY_TABLE_ELEMENT : in out REASSEMBLY_TABLE_POINTER;
  5333.       BUFPTR : IP_GLOBALS.BUFFER_POINTER );
  5334. --**************************
  5335. --* PACKAGE BODY Semantics *
  5336. --**************************
  5337. --The following algorithm is completly compatible with MIL-STD-1777
  5338. --section 9.4.6.2.2.
  5339. --
  5340. --  Data examined:
  5341. --    FROM_SNP.DTGM
  5342. --
  5343. --  Data modified:
  5344. --    STATE_VECTOR.REASSEMBLY_MAP
  5345. --    STATE_VECTOR.TIMER
  5346. --    STATE_VECTOR.TOTAL_DATA_LENGTH
  5347. --    STATE_VECTOR.HEADER
  5348. --    STATE_VECTOR.DATA
  5349. --
  5350. --  Local variables:
  5351. --    j -- loop counter
  5352. --    DATA_IN_FRAG -- the number of octets of data in received
  5353. --           -- fragment
  5354. --
  5355. --  DATA_IN_FRAG := ( FROM_SNP.DTGM.TOTAL_LENGTH - FROM_SNP.
  5356. --      DTGM.HEADER_LENGTH*4 );
  5357. --
  5358. --  Put data in its relative position in the data area of the state 
  5359. --  vector.
  5360. --  
  5361. --  STATE_VECTOR.DATA[FROM_SNP.DTGM.FRAGMENT_OFFSET*8..
  5362. --    FROM_SNP.DTGM.FRAGMENT_OFFSET*8+DATA_IN_FRAG] :=
  5363. --      FROM SNP.DTGM.DATA[0..DATA_IN_FRAG-1];
  5364. --
  5365. --  Fill in the corresponding entries of the reassembly map
  5366. --  frpresenting each 8-octet unit of received data.
  5367. --
  5368. --  for j in ( FOR_SNP.DTGM.FRAGMENT_OFFSET ) ..
  5369. --     (( FROM_SNP.DTGM.FRAGMENT_OFFSET + DATA_IN_FRAG +
  5370. --     7)/8 ) loop
  5371. --    STATE_VECTOR.REASSEMBLY_MAP[J] := 1;
  5372. --  end if;
  5373. --
  5374. --  Compute the total datagram length from the "tail-end"
  5375. --  fragment.
  5376. --
  5377. --  if ( FROM_SNP.DTGM.MORE_FRAG_FLAG = false )
  5378. --  then STATE_VECTOR.TOTAL_DATA_LENGTH :=
  5379. --    FROM_SNP.DTGM.FRAGMENT_OFFSET*8 +
  5380. --    DATA_IN_FRAG;
  5381. --  end if;
  5382. --
  5383. --  Record the header of the "head-end" fragment.
  5384. --
  5385. --  if ( FROM_SNP.DTGM.FRAGMENT_OFFSET = 0 )
  5386. --    then STATE_VECTOR.HEADER := FROM_SNP.DTGM;
  5387. --  end if;
  5388. --
  5389. --  Reset the reassembly timer if its current value is less
  5390. --  than the time-to-live field of the received datagram.
  5391. --
  5392. --  if ( STATE_VECTOR.TIMER < FROM_SNP.DTGM.TIME_TO_LIVE )
  5393. --    then STATE_VECTOR.TIMER := MAXIMUM
  5394. --      (FROM_SNP.DTGM.TIME_TO_LIVE, STATE_VECTOR.TIMER );
  5395. --
  5396. --  Mandatory Requirements
  5397. --    a.) IP module must have the capacity to receive a
  5398. --        datagram of 576 octets in length(either in one piece
  5399. --        or in fragments).
  5400. --    b.) if (FROM_SNP.DTGM.FRAGMENT_OFFSET = 0 ) then
  5401. --           fragment header becomes the header of the
  5402. --           reassembling datagram
  5403. --    c.) The total length of the reassembling datagram is calculated
  5404. --        from the fragment with FROM_SNP.DTGM.MORE_FRAG_FLAG 
  5405. --        equal to zero(i.e., the "tail-end" fragment ).
  5406. --    d.) A reassembly timer is associated with each datagram 
  5407. --        being reassembled.  The current recommendation for the
  5408. --        initial timer setting is 15 seconds.  Note that the choice
  5409. --        of this parameter value is related to the buffer capacity
  5410. --        available and the data rate of the transmission medium.
  5411. --    e.) As each fragment arrives, the reassembly timer is reset
  5412. --        to:  STATE_VECTOR.TIMER := MAXIMUM
  5413. --      (FROM_SNP.DTGM.TIME_TO_LIVE, STATE_VECTOR.TIMER );
  5414. --
  5415. --    f.) The first fragment of the datagram being reassembled must
  5416. --        contain all options, except padding and no-op octets.
  5417. --    g.) The SOURCE_ADDR, DESTINATION_ADDR, PROTOCOL, and IDENTIFIER
  5418. --        of the first fragment received must be recorded.  All 
  5419. --        subsequent fragments' SOURCE_ADDR, DESTINATION_ADDR, 
  5420. --        PROTOCOL, and IDENTIFIER will be compared against those
  5421. --        recorded.
  5422. --    h.) As each fragment arrives, the security and precedence
  5423. --        fields, if available, must be checked.  If the security
  5424. --        level of the fragment does not match the security level
  5425. --        of datagram or if the precedence level of the fragment
  5426. --        does not match the precedence level of the datagram, the
  5427. --        datagram being assembled is discarded.  Also, an error
  5428. --        datagram is returned to the source IP to report the 
  5429. --        "mismatched security/precedence" error.
  5430. --    i.) If the reassembly timer expires, the datagram being
  5431. --        reassembled is discarded.  Also, an error datagram is 
  5432. --        returned to the source IP to report the "time exceeded
  5433. --        during reassembly" error.
  5434. --******************
  5435. --* USER Semantics *
  5436. --******************
  5437. --This subprogram transforms a datagram that has been reassembled in the 
  5438. --state vector into interface parameters and data, then delivers them to a
  5439. --ULP.
  5440.   procedure REASSEMBLED_DELIVERY
  5441.     ( PACKED_BUFFER : in BUFFER_DATA.PACKED_BUFFER_PTR );
  5442. --**************************
  5443. --* PACKAGE BODY Semantics *
  5444. --**************************
  5445. --  Data examined:
  5446. --
  5447. --    STATE_VECTOR.HEADER.DESTINATION_ADDR
  5448. --    STATE_VECTOR.HEADER.SOURCE_ADDR
  5449. --    STATE_VECTOR.HEADER.PROTOCOL
  5450. --    STATE_VECTOR.HEADER.TYPE_OF_SERVICE
  5451. --    STATE_VECTOR.HEADER.HEADER_LENGTH
  5452. --    STATE_VECTOR.HEADER.TOTAL_LENGTH
  5453. --    STATE_VECTOR.HEADER.OPTIONS
  5454. --    STATE_VECTOR.DATA
  5455. --
  5456. --  Data modified:
  5457. --
  5458. --    TO_ULP.DESTINATION_ADDR    TO_ULP.LENGTH
  5459. --    TO_ULP.SOURCE_ADDR    TO_ULP.DATA
  5460. --    TO_ULP.PROTOCOL      TO_ULP.OPTIONS
  5461. --    TO_ULP.TYPE_OF_SERVICE
  5462. --
  5463. --  TO_ULP.DESTINATION_ADDR := STATE_VECTOR.HEADER.DESTINATION_ADDR;
  5464. --  TO_ULP.SOURCE_ADDR := STATE_VECTOR.HEADER.SOURCE_ADDR;
  5465. --  TO_ULP.PROTOCOL := STATE_VECTOR.HEADER.PROTOCOL;
  5466. --  TO_ULP.TYPE_OF_SERVICE := STATE_VECTOR.HEADER.TYPE_OF_SERVICE;
  5467. --  TO_ULP.LENGTH := STATE_VECTOR.HEADER.TOTAL_LENGTH -
  5468. --           STATE_VECTOR.HEADER.HEADER_LENGTH * 4;
  5469. --  TO_ULP.OPTIONS := STATE_VECTOR.HEADER.OPTIONS;
  5470. --  TO_ULP.DATA := STATE_VECTOR.DATA;
  5471. --******************
  5472. --* USER Semantics *
  5473. --******************
  5474. --This subprogram decomposes a datagram arriving from a remote IP into 
  5475. --interface parameters and data and delivers them to the destination ULP.
  5476.   procedure REMOTE_DELIVERY
  5477.     ( PACKED_BUFFER : in BUFFER_DATA.PACKED_BUFFER_PTR );
  5478. --**************************
  5479. --* PACKAGE BODY Semantics *
  5480. --**************************
  5481. --
  5482. --  Data examined:
  5483. --    FROM_SNP.DTGM.SOURCE_ADDR
  5484. --    FROM_SNP.DTGM.DESTINATION_ADDR
  5485. --    FROM_SNP.DTGM.PROTOCOL
  5486. --    FROM_SNP.DTGM.TYPE_OF_SERVICE
  5487. --    FROM_SNP.DTGM.TOTAL_LENGTH
  5488. --    FROM_SNP.DTGM.HEADER_LENGTH
  5489. --    FROM_SNP.DTGM.DATA
  5490. --    FROM_SNP.DTGM.OPTIONS
  5491. --
  5492. --  Data modified:
  5493. --    TO_ULP.DESTINATION_ADDR    TO_ULP.LENGTH
  5494. --    TO_ULP.SOURCE_ADDR    TO_ULP.DATA
  5495. --    TO_ULP.PROTOCOL      TO_ULP.OPTIONS
  5496. --    TO_ULP.TYPE_OF_SERVICE
  5497. --
  5498. --  TO_ULP.DESTINATION_ADDR := FROM_SNP.DTGM.DESTINATION_ADDR;
  5499. --  TO_ULP.SOURCE_ADDR := FROM_SNP.DTGM.SOURCE_ADDR;
  5500. --  TO_ULP.PROTOCOL := FROM_SNP.DTGM.PROTOCOL;
  5501. --  TO_ULP.TYPE_OF_SERVICE := FROM_SNP.DTGM.TYPE_OF_SERVICE;
  5502. --  TO_ULP.LENGTH := FROM_SNP.DTGM.TOTAL_LENGTH - 
  5503. --        FROM_SNP.DTGM.HEADER_LENGTH * 4;
  5504. --  TO_ULP.DATA := FROM_SNP.DTGM.DATA;
  5505. --  TO_ULP.OPTIONS := FROM_SNP.DTGM.OPTIONS;  
  5506. --**************************
  5507. --* PACKAGE BODY SEMANTICS *
  5508. --**************************
  5509. --This procedure is invoked upon system intialization or recovery
  5510. --to initialize the reassembly queue
  5511.   procedure INITIALIZE_REASSEMBLY_QUEUE;
  5512. end REASSEMBLY_UTILITIES;
  5513.  
  5514. --::::::::::::::
  5515. --reassem.ada
  5516. --::::::::::::::
  5517. -----------------------------------------------------------------------
  5518. --
  5519. --         DoD Protocols    NA-00001-200       80-01005-100(-)
  5520. --         E-Systems, Inc.  August 07, 1985
  5521. --
  5522. --         REASSEM.ADA       Author : Jim Baldo
  5523. --
  5524. -----------------------------------------------------------------------
  5525. with IP_UNPACK_AND_PACK_UTILITIES;
  5526. with UNCHECKED_CONVERSION;
  5527. with TEXT_IO;    use TEXT_IO;
  5528. with IP_GLOBALS;
  5529. with UTILITIES_FOR_ICMP;
  5530.  
  5531.         package body REASSEMBLY_UTILITIES is
  5532.  
  5533.     ---------------------------------------------------------
  5534.     --This implementation is for the DEC/Ada compiler      --
  5535.     ---------------------------------------------------------
  5536.  
  5537. package INT_IO is new INTEGER_IO( SIXTEEN_BITS );
  5538.  
  5539. FREE_LIST_REASSEMBLY_ELEMENTS : REASSEMBLY_TABLE_POINTER;
  5540. TOP_OF_REASSEMBLY_TABLE_POINTER : REASSEMBLY_TABLE_POINTER;
  5541. COUNTER_REASSEMBLY_ENTRIES : SIXTEEN_BITS  range 0..20;
  5542. TOP_OF_REASSEMBLY_FREE_LIST : REASSEMBLY_TABLE_POINTER;
  5543. REASSEMBLY_FREE_LIST_ELEMENT_COUNT : SIXTEEN_BITS  range 0..20;
  5544. MAXIMUM_TABLE_SIZE : constant SIXTEEN_BITS  := 20;
  5545.  
  5546.   procedure INITIALIZE_REASSEMBLY_QUEUE is
  5547.  
  5548.  
  5549.     --This procedure is invoked upon system intialization or recovery
  5550.     --to initialize the reassembly queue
  5551.  
  5552.   NEW_ELEMENT : REASSEMBLY_TABLE_POINTER;
  5553.   LIST_GENERATOR : REASSEMBLY_TABLE_POINTER;
  5554.  
  5555.   begin
  5556.     REASSEMBLY_FREE_LIST_ELEMENT_COUNT := 20;
  5557.     COUNTER_REASSEMBLY_ENTRIES := 0;
  5558.     TOP_OF_REASSEMBLY_TABLE_POINTER := null;
  5559.     TOP_OF_REASSEMBLY_FREE_LIST := new REASSEMBLY_TABLE_TYPE;
  5560.     TOP_OF_REASSEMBLY_FREE_LIST .PRIOR_ENTRY_REASSEMBLY_TABLE := null;
  5561.     TOP_OF_REASSEMBLY_FREE_LIST .NEXT_ENTRY_REASSEMBLY_TABLE := null;
  5562.     -- To be used durning FREE_LIST construction
  5563.     LIST_GENERATOR := TOP_OF_REASSEMBLY_FREE_LIST;
  5564.     -- Set up free queue list
  5565.     for I in 2..MAXIMUM_TABLE_SIZE loop
  5566.       NEW_ELEMENT := new REASSEMBLY_TABLE_TYPE;
  5567.       LIST_GENERATOR.NEXT_ENTRY_REASSEMBLY_TABLE := NEW_ELEMENT;
  5568.       NEW_ELEMENT.PRIOR_ENTRY_REASSEMBLY_TABLE := 
  5569.         LIST_GENERATOR;
  5570.       NEW_ELEMENT.NEXT_ENTRY_REASSEMBLY_TABLE := null;
  5571.       LIST_GENERATOR := NEW_ELEMENT;
  5572.     end loop;
  5573.     exception
  5574.       when CONSTRAINT_ERROR =>
  5575.         PUT_LINE("CONSTRAINT ERROR in package REASSEMBLY_UTILITIES ");
  5576.         PUT_LINE("procedure INITIALIZE_REASSEMBLY_QUEUE ");
  5577.       when others =>
  5578.         PUT_LINE("ERROR in package REASSEMBLY_UTILITIES ");
  5579.         PUT_LINE("procedure INITIALIZE_REASSEMBLY_QUEUE ");
  5580.   end INITIALIZE_REASSEMBLY_QUEUE;
  5581.  
  5582.   function OBTAIN_TOP_OF_REASSEMBLY_TABLE return 
  5583.  
  5584.     REASSEMBLY_TABLE_POINTER is
  5585.  
  5586.   begin
  5587.     return TOP_OF_REASSEMBLY_TABLE_POINTER;
  5588.   exception
  5589.     when CONSTRAINT_ERROR =>
  5590.     PUT_LINE("CONSTRAINT ERROR in package REASSEMBLY_UTILITIES ");
  5591.     PUT_LINE("procedure OBTAIN_TOP_OF_REASSEMBLY_TABLE ");
  5592.     when others =>
  5593.       PUT_LINE("ERROR in package REASSEMBLY_UTILITIES ");
  5594.       PUT_LINE("procedure OBTAIN_TOP_OF_REASSEMBLY_TABLE ");
  5595.   end OBTAIN_TOP_OF_REASSEMBLY_TABLE;
  5596.  
  5597.   procedure ADD_ENTRY_TO_REASSEMBLY_TABLE(NEW_DATAGRAM_FRAGMENT :  
  5598.  
  5599.   REASSEMBLY_TABLE_POINTER;
  5600.     ERROR : out REASSEMBLY_ERROR_TYPE) is
  5601.  
  5602.   begin
  5603.     if COUNTER_REASSEMBLY_ENTRIES < 20 then
  5604.       ERROR := NO_ERROR;
  5605.       COUNTER_REASSEMBLY_ENTRIES := COUNTER_REASSEMBLY_ENTRIES + 1;
  5606.       NEW_DATAGRAM_FRAGMENT.PRIOR_ENTRY_REASSEMBLY_TABLE := null;
  5607.       NEW_DATAGRAM_FRAGMENT.NEXT_ENTRY_REASSEMBLY_TABLE := 
  5608.       TOP_OF_REASSEMBLY_TABLE_POINTER;
  5609.       TOP_OF_REASSEMBLY_TABLE_POINTER := NEW_DATAGRAM_FRAGMENT;
  5610.     else
  5611.       -- reassembly resources full
  5612.       -- send ICMP message
  5613.       ERROR := NO_MORE_REASSEMBLY_BUFFER_SPACE;
  5614.     end if;
  5615.   exception
  5616.     when CONSTRAINT_ERROR =>
  5617.     PUT_LINE("CONSTRAINT ERROR in package REASSEMBLY_UTILITIES ");
  5618.     PUT_LINE("procedure ADD_ENTRY_TO_REASSEMBLY_TABLE ");
  5619.     when others =>
  5620.       PUT_LINE("ERROR in package REASSEMBLY_UTILITIES ");
  5621.       PUT_LINE("procedure ADD_ENTRY_TO_REASSEMBLY_TABLE ");
  5622.   end ADD_ENTRY_TO_REASSEMBLY_TABLE;
  5623.  
  5624.   procedure DELETE_ENTRY_FROM_REASSEMBLY_TABLE(DATAGRAM : 
  5625.   in out REASSEMBLY_TABLE_POINTER) is
  5626.  
  5627.     procedure ADD_REASSEMBLY_ELEMENT_TO_FREE_LIST is
  5628.  
  5629.     begin
  5630.       REASSEMBLY_FREE_LIST_ELEMENT_COUNT := REASSEMBLY_FREE_LIST_ELEMENT_COUNT +
  5631.  1;
  5632.       TOP_OF_REASSEMBLY_FREE_LIST.PRIOR_ENTRY_REASSEMBLY_TABLE :=
  5633.         DATAGRAM;
  5634.       DATAGRAM.NEXT_ENTRY_REASSEMBLY_TABLE :=
  5635.         TOP_OF_REASSEMBLY_FREE_LIST;
  5636.       TOP_OF_REASSEMBLY_FREE_LIST := DATAGRAM;
  5637.       TOP_OF_REASSEMBLY_FREE_LIST.PRIOR_ENTRY_REASSEMBLY_TABLE :=
  5638.         null;
  5639.     exception
  5640.       when CONSTRAINT_ERROR =>
  5641.     PUT_LINE("CONSTRAINT ERROR in package REASSEMBLY_UTILITIES ");
  5642.     PUT_LINE("procedure ADD_REASSEMBLY_ELEMENT_TO_FREE_LIST ");
  5643.       when others =>
  5644.       PUT_LINE("ERROR in package REASSEMBLY_UTILITIES ");
  5645.       PUT_LINE("procedure ADD_REASSEMBLY_ELEMENT_TO_FREE_LIST ");
  5646.     end ADD_REASSEMBLY_ELEMENT_TO_FREE_LIST;
  5647.  
  5648.   begin
  5649.     COUNTER_REASSEMBLY_ENTRIES := COUNTER_REASSEMBLY_ENTRIES - 1;
  5650.     DATAGRAM.PRIOR_ENTRY_REASSEMBLY_TABLE.NEXT_ENTRY_REASSEMBLY_TABLE :=
  5651.       DATAGRAM.NEXT_ENTRY_REASSEMBLY_TABLE;
  5652.     ADD_REASSEMBLY_ELEMENT_TO_FREE_LIST;
  5653.   exception
  5654.     when CONSTRAINT_ERROR =>
  5655.     PUT_LINE("CONSTRAINT ERROR in package REASSEMBLY_UTILITIES ");
  5656.     PUT_LINE("procedure DELETE_ENTRY_FROM_REASSEMBLY_TABLE ");
  5657.     when others =>
  5658.       PUT_LINE("ERROR in package REASSEMBLY_UTILITIES ");
  5659.       PUT_LINE("procedure DELETE_ENTRY_FROM_REASSEMBLY_TABLE ");
  5660.   end DELETE_ENTRY_FROM_REASSEMBLY_TABLE;
  5661.  
  5662.   procedure GET_REASSEMBLY_STRUCTURE( REASSEMBLY_STRUCTURE : 
  5663.                                       in out REASSEMBLY_TABLE_POINTER;
  5664.                                       ERROR : out REASSEMBLY_ERROR_TYPE) is
  5665.  
  5666.     procedure DELETE_REASSEMBLY_STRUCTURE_FROM_FREE_LIST is
  5667.     
  5668.     begin
  5669.       if REASSEMBLY_FREE_LIST_ELEMENT_COUNT > 0 then
  5670.         ERROR := NO_ERROR;
  5671.         REASSEMBLY_FREE_LIST_ELEMENT_COUNT := REASSEMBLY_FREE_LIST_ELEMENT_COUNT
  5672.  -1;
  5673.         TOP_OF_REASSEMBLY_FREE_LIST :=  
  5674.           TOP_OF_REASSEMBLY_FREE_LIST.NEXT_ENTRY_REASSEMBLY_TABLE;
  5675.         TOP_OF_REASSEMBLY_FREE_LIST.PRIOR_ENTRY_REASSEMBLY_TABLE := null;
  5676.       else
  5677.         -- no more buffer space to perform reassembly
  5678.         -- send ICMP message
  5679.         ERROR := NO_MORE_FREE_BUFFER_SPACE;
  5680.       end if;
  5681.     exception
  5682.       when CONSTRAINT_ERROR =>
  5683.     PUT_LINE("CONSTRAINT ERROR in package REASSEMBLY_UTILITIES ");
  5684.     PUT_LINE("procedure DELETE_REASSEMBLY_STRUCTURE_FROM_FREE_LIST ");
  5685.       when others =>
  5686.       PUT_LINE("ERROR in package REASSEMBLY_UTILITIES ");
  5687.       PUT_LINE("procedure DELETE_REASSEMBLY_STRUCTURE_FROM_FREE_LIST ");
  5688.     end DELETE_REASSEMBLY_STRUCTURE_FROM_FREE_LIST;
  5689.   
  5690.   begin
  5691.     REASSEMBLY_STRUCTURE := TOP_OF_REASSEMBLY_FREE_LIST;
  5692.     DELETE_REASSEMBLY_STRUCTURE_FROM_FREE_LIST;
  5693.     REASSEMBLY_STRUCTURE.PRIOR_ENTRY_REASSEMBLY_TABLE := null;
  5694.     REASSEMBLY_STRUCTURE.NEXT_ENTRY_REASSEMBLY_TABLE := null;
  5695.   exception
  5696.     when CONSTRAINT_ERROR =>
  5697.     PUT_LINE("CONSTRAINT ERROR in package REASSEMBLY_UTILITIES ");
  5698.     PUT_LINE("procedure GET_REASSEMBLY_STRUCTURE ");
  5699.     when others =>
  5700.       PUT_LINE("ERROR in package REASSEMBLY_UTILITIES ");
  5701.       PUT_LINE("procedure GET_REASSEMBLY_STRUCTURE ");
  5702.   end GET_REASSEMBLY_STRUCTURE;
  5703.  
  5704.   function A_FRAG( PACKED_BUFFER : in BUFFER_DATA.PACKED_BUFFER_PTR;
  5705.                    BUFPTR : in IP_GLOBALS.BUFFER_POINTER )
  5706.                                              return YES_OR_NO is
  5707.  
  5708.   begin
  5709.     if (BUFPTR.FRAG_OFFSET = 0) and (BUFPTR.FLAGS = 2) then
  5710.       return NO;
  5711.     elsif (BUFPTR.FLAGS = 1) or (BUFPTR.FLAGS = 0) then
  5712.       return YES;
  5713.     else
  5714.       NEW_LINE;
  5715.       PUT("Flag error := ");
  5716.       INT_IO.PUT(BUFPTR.FLAGS);
  5717.       NEW_LINE;
  5718.       PUT_LINE("function A_FRAG package REASSEMBLY_UTILITIES ");
  5719.       return NO;
  5720.     end if;
  5721.   end A_FRAG;
  5722.  
  5723.   function REASS_DONE
  5724.     ( REASSEMBLY_BUFFER : in REASSEMBLY_TABLE_POINTER;
  5725.       BUFPTR : IP_GLOBALS.BUFFER_POINTER )
  5726.         return YES_OR_NO is
  5727.   begin
  5728.     if REASSEMBLY_BUFFER.TOTAL_DATA_LENGTH = 0 then
  5729.       -- check incoming datagram for "tail"
  5730.       if BUFPTR.FLAGS = 0 then
  5731.         REASSEMBLY_BUFFER.TOTAL_DATA_LENGTH := BUFPTR.FRAG_OFFSET + 
  5732.         (BUFPTR.TOT_LEN - BUFPTR.IHL);
  5733.         for I in BUFPTR.FRAG_OFFSET..(BUFPTR.FRAG_OFFSET + 
  5734.         (BUFPTR.TOT_LEN - BUFPTR.IHL)) loop
  5735.           REASSEMBLY_BUFFER.REASSEMBLY_MAP(I) := 1;
  5736.         end loop;
  5737.         for I in 1..REASSEMBLY_BUFFER.TOTAL_DATA_LENGTH loop
  5738.           if REASSEMBLY_BUFFER.REASSEMBLY_MAP(I) = 1 then
  5739.             null;
  5740.           else
  5741.             return NO;
  5742.           end if;
  5743.         end loop;
  5744.         return YES;
  5745.       else
  5746.         return NO;
  5747.       end if;
  5748.     else
  5749.       for I in 1..REASSEMBLY_BUFFER.TOTAL_DATA_LENGTH loop
  5750.         if REASSEMBLY_BUFFER.REASSEMBLY_MAP(I) = 1 then
  5751.           null;
  5752.         else
  5753.           return NO;
  5754.         end if;
  5755.       end loop;
  5756.       return YES;
  5757.     end if;
  5758.   exception
  5759.     when CONSTRAINT_ERROR =>
  5760.       PUT_LINE(" CONSTRAINT_ERROR in package REASSEMBLY_UTILITIES ");
  5761.       PUT_LINE("procedure REASS_DONE ");
  5762.     when others =>
  5763.       PUT_LINE(" UNKNOWN ERROR in package  REASSEMBLY_UTILITIES ");
  5764.       PUT_LINE("procedure REASS_DONE ");
  5765.   end REASS_DONE;
  5766.  
  5767.   procedure REASSEMBLY_TIMEOUT
  5768.     ( REASSEMBLY_DATAGRAM_THAT_TIMED_OUT : in out REASSEMBLY_TABLE_POINTER;
  5769.       BUFPTR : in IP_GLOBALS.BUFFER_POINTER ) is
  5770.  
  5771.   type TELEGOOFUP is array(1..1) of SIXTEEN_BITS ;
  5772.           -- Currently necessary for
  5773.           -- implementation restriction
  5774.   type TWO_BYTE is array(1..2) of SYSTEM_BYTE;
  5775.   function CONVERT_TO_TWO_BYTES is new 
  5776.   UNCHECKED_CONVERSION(TELEGOOFUP, TWO_BYTE);
  5777.   WORD_TO_CONVERT : TELEGOOFUP;
  5778.   TEMP : TWO_BYTE;
  5779.   ICMP_MESSAGE : BUFFER_DATA.PACKED_BUFFER_PTR;
  5780.   ICMP_BUFPTR : IP_GLOBALS.BUFFER_POINTER;
  5781.   ICMP_HEADER_POINTER : SIXTEEN_BITS  range 20..60;
  5782.   IP_HEADER_POINTER : SIXTEEN_BITS  := 0;
  5783.   IHL_IN_OCTETS : SIXTEEN_BITS  range 20..60;
  5784.   BUFFER_TYPE : SIXTEEN_BITS  := 0;
  5785.  
  5786.   begin
  5787.     BUFFER_DATA.BUFFGET(ICMP_MESSAGE,BUFFER_TYPE);
  5788.     if REASSEMBLY_DATAGRAM_THAT_TIMED_OUT.HAS_FRAGMENT_ZERO_ARRIVED = TRUE then
  5789.       ICMP_BUFPTR.VERSION := 4;
  5790.       ICMP_BUFPTR.IHL := 5;
  5791.       ICMP_BUFPTR.TOS := 0;
  5792.       ICMP_BUFPTR.ID := 0; -- Temporary; need to implement some type of ID gener
  5793. --ation
  5794.       ICMP_BUFPTR.FLAGS := 2; -- MORE_FRAG_FLAG = FALSE AND DONT_FRAG_FLAG = FALSE
  5795.       ICMP_BUFPTR.FRAG_OFFSET := 0;
  5796.       ICMP_BUFPTR.TTL := 60;
  5797.       ICMP_BUFPTR.PROT := 1;
  5798.       ICMP_BUFPTR.SOURCE := BUFPTR.DEST;
  5799.       ICMP_BUFPTR.DEST := BUFPTR.SOURCE;
  5800.       --
  5801.       IP_HEADER_POINTER := 
  5802.       REASSEMBLY_DATAGRAM_THAT_TIMED_OUT.REASSEMBLY_DATAGRAM.IP_PTR;
  5803.       -- Convert IHL from 32-bit word size to 8-bit OCTETS
  5804.       IHL_IN_OCTETS := BUFPTR.IHL * 4;
  5805.       -- Calculate position of ICMP header
  5806.       ICMP_HEADER_POINTER := IP_HEADER_POINTER + IHL_IN_OCTETS;
  5807.       -- Load Time Exceeded Message Type
  5808.       ICMP_MESSAGE.BYTE(ICMP_HEADER_POINTER) := 11;
  5809.       -- Load code(fragment reassembly time exceeded)
  5810.       ICMP_MESSAGE.BYTE(ICMP_HEADER_POINTER + 1) := 1;
  5811.       -- Telesoft does not support packed aggregates
  5812.       for I in 0..5 loop
  5813.         ICMP_MESSAGE.BYTE(ICMP_HEADER_POINTER + 2 + 
  5814.                          SIXTEEN_BITS ( I ) ) := 0;
  5815.       end loop;
  5816.       -- load internet header and 64 bits of original datagram
  5817.         -- Telesoft does not support packed aggregates
  5818.       for I in 0..IHL_IN_OCTETS + 64 loop
  5819.         ICMP_MESSAGE.BYTE(ICMP_HEADER_POINTER + 8 + 
  5820.             SIXTEEN_BITS ( I ) ) := 
  5821.         REASSEMBLY_DATAGRAM_THAT_TIMED_OUT.REASSEMBLY_DATAGRAM.BYTE
  5822.         (ICMP_HEADER_POINTER + I);
  5823.       end loop;
  5824.       -- Calculate ICMP checksum
  5825.       WORD_TO_CONVERT(1) := UTILITIES_FOR_ICMP.ICMP_CHECKSUM
  5826.             (ICMP_HEADER_POINTER,
  5827.             (ICMP_HEADER_POINTER + ICMP_BUFPTR.TOT_LEN),
  5828.             ICMP_MESSAGE);
  5829.       TEMP := CONVERT_TO_TWO_BYTES(WORD_TO_CONVERT);
  5830.       ICMP_MESSAGE.BYTE(ICMP_HEADER_POINTER + 2) := TEMP(2);
  5831.       ICMP_MESSAGE.BYTE(ICMP_HEADER_POINTER + 3) := TEMP(1);
  5832.       IP_UNPACK_AND_PACK_UTILITIES.PACK_BUFFER_INTO_BIT_STREAM
  5833.         (ICMP_BUFPTR,ICMP_MESSAGE);
  5834.       -- Send ICMP message to subnet protocol
  5835.       UTILITIES_FOR_ICMP.SEND_ICMP_MESSAGE(ICMP_MESSAGE);
  5836.       -- release reassembly resoures
  5837.       DELETE_ENTRY_FROM_REASSEMBLY_TABLE(REASSEMBLY_DATAGRAM_THAT_TIMED_OUT);
  5838.     else
  5839.       -- no time exceeded message will be sent
  5840.       -- release reassembly resoures
  5841.       DELETE_ENTRY_FROM_REASSEMBLY_TABLE(REASSEMBLY_DATAGRAM_THAT_TIMED_OUT);
  5842.     end if;
  5843.   exception
  5844.     when CONSTRAINT_ERROR =>
  5845.       PUT_LINE(" CONSTRAINT_ERROR in package REASSEMBLY_UTILITIES ");
  5846.       PUT_LINE("procedure REASSEMBLY_TIMEOUT ");
  5847.     when others =>
  5848.       PUT_LINE(" UNKNOWN ERROR in package  REASSEMBLY_UTILITIES ");
  5849.       PUT_LINE("procedure REASSEMBLY_TIMEOUT ");
  5850.   end REASSEMBLY_TIMEOUT;  
  5851.  
  5852.   procedure REASSEMBLY( PACKED_BUFFER : in out BUFFER_DATA.PACKED_BUFFER_PTR;
  5853.                         REASSEMBLY_TABLE_ELEMENT : in out REASSEMBLY_TABLE_POINTER;
  5854.                         BUFPTR : IP_GLOBALS.BUFFER_POINTER ) is
  5855.  
  5856.   INCOMING_DATAGRAM_BUFID : BUFID_TYPE;
  5857.   DATA_IN_FRAG : SIXTEEN_BITS  := 0;
  5858.   ERROR : REASSEMBLY_ERROR_TYPE := NO_ERROR;
  5859.   BUFFER_TYPE : SIXTEEN_BITS  := 0;
  5860.  
  5861.     procedure STUFF_DATA_FROM_FRAGMENT is
  5862.     
  5863.     begin
  5864.       for I in 0..DATA_IN_FRAG loop
  5865.         REASSEMBLY_TABLE_ELEMENT.DATA(BUFPTR.FRAG_OFFSET + I + 1) :=
  5866.           PACKED_BUFFER.BYTE(PACKED_BUFFER.IP_PTR + (BUFPTR.IHL * 4) + I);
  5867.       end loop;
  5868.     exception
  5869.     when CONSTRAINT_ERROR =>
  5870.         NEW_LINE;
  5871.         PUT("CONSTRAINT ERROR procedure STUFF_DATA_FROM_FRAGMENT");
  5872.         NEW_LINE;
  5873.         PUT("package REASSEMBLY UTILITIES");
  5874.     end STUFF_DATA_FROM_FRAGMENT;
  5875.  
  5876.     procedure SET_BIT_MAP is
  5877.  
  5878.     begin
  5879.       for I in 0..DATA_IN_FRAG loop
  5880.         REASSEMBLY_TABLE_ELEMENT.REASSEMBLY_MAP(BUFPTR.FRAG_OFFSET + I + 1) 
  5881.         := 1;
  5882.       end loop;
  5883.     exception
  5884.     when CONSTRAINT_ERROR =>
  5885.         NEW_LINE;
  5886.         PUT("CONSTRAINT ERROR procedure SET_BIT_MAP ");
  5887.         NEW_LINE;
  5888.         PUT("package REASSEMBLY UTILITIES");
  5889.     end SET_BIT_MAP;
  5890.  
  5891.   begin
  5892.     DATA_IN_FRAG := BUFPTR.TOT_LEN - BUFPTR.IHL * 4;
  5893.     INCOMING_DATAGRAM_BUFID := 
  5894.     (BUFPTR.SOURCE,BUFPTR.DEST,BUFPTR.PROT,BUFPTR.ID);
  5895.     REASSEMBLY_TABLE_ELEMENT := TOP_OF_REASSEMBLY_TABLE_POINTER;
  5896.     --REMOVE
  5897.     NEW_LINE;
  5898.     PUT("WE ARE REASSEMBLY");
  5899.     NEW_LINE;
  5900.     --REMOVE
  5901.     while not(REASSEMBLY_TABLE_ELEMENT = null) and then
  5902.     not(REASSEMBLY_TABLE_ELEMENT.BUFID = INCOMING_DATAGRAM_BUFID) loop
  5903.       REASSEMBLY_TABLE_ELEMENT := 
  5904.         REASSEMBLY_TABLE_ELEMENT.NEXT_ENTRY_REASSEMBLY_TABLE;
  5905.     end loop;
  5906.     if (REASSEMBLY_TABLE_ELEMENT /= null) and (BUFPTR.TTL > 0) then
  5907.       -- store data
  5908.       STUFF_DATA_FROM_FRAGMENT;
  5909.       -- set bitmap
  5910.       SET_BIT_MAP;
  5911.       if not(REASSEMBLY_TABLE_ELEMENT.HAS_FRAGMENT_ZERO_ARRIVED) then
  5912.         -- here's the tail
  5913.         REASSEMBLY_TABLE_ELEMENT.TOTAL_DATA_LENGTH := 
  5914.           BUFPTR.FRAG_OFFSET + (BUFPTR.TOT_LEN - BUFPTR.IHL);
  5915.         REASSEMBLY_TABLE_ELEMENT.HAS_FRAGMENT_ZERO_ARRIVED := TRUE;
  5916.         REASSEMBLY_TABLE_ELEMENT.HEADER := 
  5917.         IP_UNPACK_AND_PACK_UTILITIES.UNPACK(PACKED_BUFFER);
  5918.       end if;
  5919.       -- reset reassembly timer if its current value is less
  5920.       -- than the time-to-live field of the recieved datagram
  5921.       if REASSEMBLY_TABLE_ELEMENT.TIMER < BUFPTR.TTL then
  5922.         REASSEMBLY_TABLE_ELEMENT.TIMER := 15;
  5923.       end if;
  5924.     elsif (REASSEMBLY_TABLE_ELEMENT = null) and (BUFPTR.TTL > 0) then
  5925.       -- fragment is a new fragmented datagram
  5926.       -- obtain fragment buffer
  5927.       GET_REASSEMBLY_STRUCTURE(REASSEMBLY_TABLE_ELEMENT,ERROR);
  5928.       if ERROR = NO_ERROR then
  5929.         REASSEMBLY_TABLE_ELEMENT.STATE_NAME := INACTIVE;
  5930.         REASSEMBLY_TABLE_ELEMENT.BUFID := INCOMING_DATAGRAM_BUFID;
  5931.         -- store data
  5932.         STUFF_DATA_FROM_FRAGMENT;
  5933.         -- set bitmap
  5934.         SET_BIT_MAP;
  5935.       elsif (ERROR = NO_MORE_FREE_BUFFER_SPACE) then
  5936.         -- send ICMP message
  5937.         null;
  5938.       else
  5939.         -- we should never get here!!!
  5940.         null;
  5941.       end if;
  5942.     elsif (REASSEMBLY_TABLE_ELEMENT /= null) and not(BUFPTR.TTL > 0) then
  5943.       REASSEMBLY_TIMEOUT(REASSEMBLY_TABLE_ELEMENT,BUFPTR);
  5944.       BUFFER_DATA.BUFFREE(PACKED_BUFFER,BUFFER_TYPE);
  5945.       DELETE_ENTRY_FROM_REASSEMBLY_TABLE(REASSEMBLY_TABLE_ELEMENT);
  5946.     else
  5947.       -- should never get here
  5948.       null;
  5949.     end if;          
  5950.   end REASSEMBLY;
  5951.  
  5952.   procedure REASSEMBLED_DELIVERY
  5953.     ( PACKED_BUFFER : in BUFFER_DATA.PACKED_BUFFER_PTR ) is
  5954.  
  5955.   begin
  5956.     null;
  5957.   end REASSEMBLED_DELIVERY;
  5958.  
  5959.   procedure REMOTE_DELIVERY
  5960.     ( PACKED_BUFFER : in BUFFER_DATA.PACKED_BUFFER_PTR ) is
  5961.  
  5962.   begin
  5963.     null;
  5964.   end REMOTE_DELIVERY;
  5965.  
  5966. end REASSEMBLY_UTILITIES;
  5967. --::::::::::::::
  5968. --per1_.ada
  5969. --::::::::::::::
  5970. -----------------------------------------------------------------------
  5971. --
  5972. --         DoD Protocols    NA-00001-200       80-01002-100(-)
  5973. --         E-Systems, Inc.  August 07, 1985
  5974. --
  5975. --         PER1_.ADA       Author : Jim Baldo
  5976. --
  5977. -----------------------------------------------------------------------
  5978. with TCP_GLOBALS;        use TCP_GLOBALS;
  5979. with QUEUES;            use QUEUES;
  5980. with T_TCP_GLOBALS_DATA_STRUCTURES;
  5981. use T_TCP_GLOBALS_DATA_STRUCTURES;
  5982. with BUFFER_DATA;        use BUFFER_DATA;
  5983.  
  5984.         package    TCP_ARRIVES_PERIPHERALS is
  5985.  
  5986.     ----------------------------------------------------------
  5987.     --This implementation is for use with the Telesoft Ada  --
  5988.     --compiler version 1.5 .                                --
  5989.     ----------------------------------------------------------
  5990.  
  5991. ------------------------------------------------------------------------------
  5992. -- THIS    PACKAGE    CONTAINS ALL THE PROCEDURES AND    FUNCTIONS NECESSARY FOR     --
  5993. -- PROCESSING ARRIVED SEGMENTS.    IT ALSO    CONTAINS THE HEADER FORMAT ROUTINE. --
  5994. ------------------------------------------------------------------------------
  5995.  
  5996. type RES is (GOOD, BAD);
  5997.  
  5998. --***********************GLOBAL ROUTINES********************************
  5999.  
  6000. procedure PROCESS_RESET_IN_DATA_ACCEPTING_STATES( LCN : in TCB_PTR);
  6001.  
  6002.     --This procedure process an arrived reset in the data accepting 
  6003.     --states. It basically closes down the connection and clears 
  6004.     --the necessary data out of the appropriate queues.
  6005.  
  6006. procedure SEND_A_RESET( LCN : in TCB_PTR);
  6007.  
  6008.     --This procedure will format and send a reset, for the remote host, to
  6009.     --the ip.
  6010.  
  6011. procedure FIN_CHECK_FOR_ESTAB_OR_SYN_RECEIVED_STATES
  6012.                               ( LCN : in out TCB_PTR; 
  6013.                             BUFPTR : in out BUFFER_POINTER);
  6014.  
  6015.     --This procedure checks to see if the fin bit is set. If the fin is 
  6016.     --set it then puts the TCB in the close-wait state.
  6017.  
  6018. procedure PROCESS_SEGMENT_TEXT( LCN : in TCB_PTR; 
  6019.                                 BUFPTR : in out BUFFER_POINTER);
  6020.  
  6021.     --This procedure will determine if text exists and if so fill as many
  6022.     --receive buffers as it can and return them to the user. Any data it 
  6023.     --can not return it will queue up.
  6024.  
  6025. procedure PROCESS_URGENT_FLAG( LCN : in TCB_PTR; 
  6026.                                BUFPTR : in out BUFFER_POINTER);
  6027.  
  6028.     --This procedure checks the urgent bit and if set, it will notify the 
  6029.     --user of urgent data (if the urgent pointer is in advance of the data 
  6030.     --and the user has not already been notified).
  6031.  
  6032. procedure PROCESS_A_FIN( LCN : in out TCB_PTR; 
  6033.                          BUFPTR : in out BUFFER_POINTER);
  6034.  
  6035.     --This procedure will notify the user that the connection is closing,
  6036.     --and return all receives with data if possible. It will also ensure
  6037.     --that an ack was or will be sent for the fin.
  6038.  
  6039. procedure SEND_A_PIGGYBACKED_ACK( LCN : in out TCB_PTR);
  6040.  
  6041.     --This procedure will send an ack together with data (if available) 
  6042.     --to the IP for processing. It will also try to clear the transmit 
  6043.     --queue of data.  By sending it. It will update everything necessary 
  6044.     --in the TCB.
  6045.  
  6046. procedure SEND_FROM_TRANSMIT_QUEUE( LCN : in out TCB_PTR);
  6047.  
  6048.     --This procedure will send any segments from the transmit queue that
  6049.     --will fit in the window. It will format them for transmission.  It 
  6050.     --will check upon emptying its queue for the close pending flag and 
  6051.     --take appropriate action.
  6052.  
  6053. function UNPACK( PACKED_BUFFER : in PACKED_BUFFER_PTR; 
  6054.                  TOTAL_DATA_BYTES : in SIXTEEN_BITS ) return BUFFER_POINTER;
  6055.  
  6056.     --This function will take an array of system.bytes (a bit stream) and
  6057.     --unpack this into an easy to use record. It uses the generic
  6058.     --function unchecked conversion via several functions to move the bits 
  6059.     --into the record fields. The system bytes are considered to be 
  6060.     --integers. We simply move the proper number of bits into the proper 
  6061.     --fields in the record.
  6062.  
  6063. procedure PROCESS_COMMON_ACK( LCN : in TCB_PTR; 
  6064.                               BUFPTR : in BUFFER_POINTER;
  6065.                     RESULT : out RES);
  6066.  
  6067.     --This procedure does all the processing for an arrived ack in the 
  6068.     --established state as per the specification. This processing is 
  6069.     --common to the other states also.
  6070.  
  6071. procedure ENTER_ESTABLISHED_STATE_PROCESSING( LCN : in TCB_PTR; 
  6072.                                               BUFPTR : in out BUFFER_POINTER);
  6073.  
  6074.     --This procedure will perform all the processing of a segment in the
  6075.     --established state, beginning with the check of the urgent flag.
  6076.     --It will also process all the data on the TCP received segment queue.
  6077.  
  6078. procedure SEND_A_SYN_AND_ACK( LCN : in TCB_PTR);
  6079.  
  6080.     --This procedure will format a segment for a syn and an ack and send it
  6081.     --to the IP bound for the remote host.
  6082.  
  6083. procedure BAD_SYN_HANDLER( LCN : in TCB_PTR; 
  6084.                            BUFPTR : in out BUFFER_POINTER);
  6085.  
  6086.     --This procedure checks to make sure that the syn is indeed bad. Then
  6087.     --it sends a reset to the offending host and clears the necessary 
  6088.     --queues of entries for this connection. It tells the user that the 
  6089.     --connection was reset and closes the connection.
  6090.  
  6091. procedure SEND_A_RESET_AND_ACK( LCN : in TCB_PTR);
  6092.  
  6093.     --This procedure will format a header for a segment with the reset 
  6094.     --and ack control bits set. This will be sent to the IP layer for 
  6095.     --transmission to the remote host.
  6096. -- *******************************************************************
  6097.  
  6098. RESULTS    : RES;
  6099. BUFFTYPE : CONSTANT SIXTEEN_BITS  := 1; -- ONLY ONE TYPE OF BUFFER FOR NOW.
  6100. GLOBAL_PACKED_BUFFER : PACKED_BUFFER_PTR;
  6101.  
  6102. end TCP_ARRIVES_PERIPHERALS;
  6103.  
  6104. --::::::::::::::
  6105. --per1.ada
  6106. --::::::::::::::
  6107. -----------------------------------------------------------------------
  6108. --
  6109. --         DoD Protocols    NA-00001-200       80-01003-100(-)
  6110. --         E-Systems, Inc.  August 07, 1985
  6111. --
  6112. --         PER1.ADA       Author : Jim Baldo
  6113. --
  6114. -----------------------------------------------------------------------
  6115. with IP_GLOBALS ;        use IP_GLOBALS ;
  6116. with IP_TCP ;            use IP_TCP ;
  6117. with TCP_TO_ULP_COMMUNICATE ;   use TCP_TO_ULP_COMMUNICATE ;
  6118. with TEXT_IO;            use TEXT_IO;
  6119. with SYSTEM;
  6120. with UNCHECKED_CONVERSION;
  6121. with MODULO;            use MODULO;
  6122. with WITH_TCP_COMMUNICATE;    use WITH_TCP_COMMUNICATE;
  6123. with TCB_ALLOCATOR;        use TCB_ALLOCATOR;
  6124.  
  6125.         package    body TCP_ARRIVES_PERIPHERALS is
  6126.  
  6127. package INT_IO_16 is new INTEGER_IO ( SIXTEEN_BITS ) ;
  6128. package INT_IO_32 is new INTEGER_IO ( THIRTYTWO_BITS ) ;
  6129. DUMMY : CHARACTER ;
  6130.  
  6131.     procedure PROCESS_RESET_IN_DATA_ACCEPTING_STATES( LCN : in TCB_PTR) is
  6132.  
  6133.          UMESSAGE : USER_MESSAGE;
  6134.          NULL_BUFF : T_TCP_GLOBALS_DATA_STRUCTURES.BUFFER_POINTER;
  6135.          SOCKET_PARAMS : LCN_PTR_TYPE;
  6136.  
  6137.         begin
  6138.          QUEUE_CLEAR(TCP_RECEIVED_SEGMENT_QUEUE, LCN);
  6139.          -- WE HAVE NO SEND QUEUE AS SUCH. QUEUE_CLEAR(SEND_QUEUE, LCN);
  6140.          QUEUE_CLEAR(RECEIVE_QUEUE, LCN);
  6141.          QUEUE_CLEAR(TRANSMIT_QUEUE, LCN);
  6142.          QUEUE_CLEAR(TCP_RETRANSMIT_QUEUE, LCN);
  6143.          QUEUE_CLEAR(PROCESSED_SEGMENTS_FOR_USER_QUEUE, LCN);
  6144.          -- TELL USER
  6145.          --  ERROR: CONNECTION RESET 
  6146.          SOCKET_PARAMS.LCN := LCN;
  6147.          SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  6148.          SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  6149.          UMESSAGE := ( 16, 
  6150.                        SOCKET_PARAMS);
  6151.          MESSAGE_FOR_USER(UMESSAGE);
  6152.          LCN.STATE := CLOSED;
  6153.          -- MAY HAVE TO CLEAR THE TCB HERE.
  6154.          TCB_CLEAR(LCN);
  6155.        exception
  6156.         when constraint_error =>
  6157.          PUT_LINE("CONSTRAINT ERROR IN RESET PROCESSOR ");
  6158.          PUT_LINE("OF DATA ACCEPTING STATES");
  6159.         when others =>
  6160.          PUT_LINE("UNKNOWN ERROR IN RESET PROCESSOR ");
  6161.          PUT_LINE("OF DATA ACCEPTING STATES");
  6162.        end PROCESS_RESET_IN_DATA_ACCEPTING_STATES;
  6163.  
  6164.     procedure SEND_A_RESET( LCN : in TCB_PTR) is
  6165.  
  6166.          BUFFTYPE : SIXTEEN_BITS ;
  6167.          BUFPTR : T_TCP_GLOBALS_DATA_STRUCTURES.BUFFER_POINTER;
  6168.          PACKED_BUFFER : PACKED_BUFFER_PTR;
  6169.          UMESSAGE : USER_MESSAGE;
  6170.          SOCKET_PARAMS : LCN_PTR_TYPE;
  6171.          MESSAGE_FOR_IP : IP_MESSAGE ;
  6172.  
  6173.         begin
  6174.          -- GET A BUFFER
  6175.          BUFFGET(PACKED_BUFFER, BUFFTYPE);
  6176.          if PACKED_BUFFER = null then
  6177.           -- TELL USER    ERROR OUT OF BUFFERS
  6178.           SOCKET_PARAMS.LCN := LCN;
  6179.           SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  6180.           SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  6181.           UMESSAGE := ( 20, 
  6182.                         SOCKET_PARAMS);
  6183.           MESSAGE_FOR_USER(UMESSAGE);
  6184.          else
  6185.           PACKED_BUFFER.STATUS := OWNER_TCP;
  6186.           PACKED_BUFFER.IN_USE := TRUE;
  6187.           -- CLEAR THE OPTIONS ARRAY 
  6188.           OPTIONS := CLEAR;
  6189.           TCP_HEADER_FORMAT(LCN, BUFPTR, RST, OPTIONS);
  6190.           -- HERE WE MUST SET UP THE SECURITY OPTIONS FOR IP
  6191.           OPTIONS := TCP_SECURITY_OPTIONS;
  6192.           -- PACK UP A BUFFER
  6193.           PACK_BUFFER_INTO_BIT_STREAM(BUFPTR, PACKED_BUFFER);
  6194.           LEN := BUFPTR.DATA_OFFSET * 4;
  6195.           MESSAGE_FOR_IP := ( FROM_TCP,
  6196.                               PACKED_BUFFER,
  6197.                               LCN.DESTINATION_ADDRESS,
  6198.                               TOS,
  6199.                               TTL,
  6200.                               LEN,
  6201.                               IDENT,
  6202.                               DONT_FRAGMENT,
  6203.                               OPTIONS,
  6204.                               LCN.SOURCE_ADDRESS ) ;
  6205.           IP_FROM_TCP.Q_ADD( MESSAGE_FOR_IP ) ;
  6206.           -- UPDATE SEND NEXT IS UNECESSARY.
  6207.           ---  LCN.SND_NXT := LCN.SND_NXT + 1;
  6208. --          if RESULT /= OK then
  6209.            -- TELL USER WE ARE    OUT OF SPACE
  6210. --           SOCKET_PARAMS.LCN := LCN;
  6211. --           SOCKET_PARAMS.FOREIGN_NET_HOST := LCN.DESTINATION_ADDRESS;
  6212. --           SOCKET_PARAMS.FOREIGN_PORT := LCN.FOREIGN_PORT;
  6213. --           UMESSAGE := ( 21, 
  6214. --                         SOCKET_PARAMS);
  6215. --           MESSAGE_FOR_USER(UMESSAGE);
  6216. --          end if;
  6217.          end if;
  6218.         exception
  6219.          when constraint_error =>
  6220.           PUT_LINE("CONSTRAINT ERROR IN SEND A RESET");
  6221.          when others =>
  6222.           PUT_LINE("UNKNOWN ERROR IN SEND A RESET");
  6223.         end SEND_A_RESET;
  6224.     
  6225.     procedure FIN_CHECK_FOR_ESTAB_OR_SYN_RECEIVED_STATES
  6226.             (LCN : in out TCB_PTR; 
  6227.                              BUFPTR : in out 
  6228.                                T_TCP_GLOBALS_DATA_STRUCTURES.BUFFER_POINTER) is
  6229.         begin
  6230.          if BUFPTR.FIN = BIT_SET then
  6231.           PROCESS_A_FIN(LCN, BUFPTR);
  6232.           LCN.STATE := CLOSE_WAIT;
  6233.          end if;
  6234.         exception
  6235.          when constraint_error =>
  6236.           PUT_LINE("CONSTRAINT ERROR IN FIN CHECKER");
  6237.          when others =>
  6238.           PUT_LINE("UNKNOWN ERROR IN FIN CHECKER");
  6239.         end FIN_CHECK_FOR_ESTAB_OR_SYN_RECEIVED_STATES;
  6240.  
  6241.     procedure PROCESS_SEGMENT_TEXT( LCN : in TCB_PTR; 
  6242.                                         BUFPTR : in out 
  6243.                          T_TCP_GLOBALS_DATA_STRUCTURES.BUFFER_POINTER) is
  6244.  
  6245.         NEW_DATA : SIXTEEN_BITS  := BUFPTR.DATA_LEN;
  6246.         NULL_BUFFER : PACKED_BUFFER_PTR := NULL;
  6247.         PACKED_BUFF, RECEIVE_BUFFER, 
  6248.         QUEUED_DATA_BUFFER : PACKED_BUFFER_PTR;
  6249.         BUFFTYPE, LENGTH, DATA_LENGTH : SIXTEEN_BITS ;
  6250.         UMESSAGE : USER_MESSAGE;
  6251.         Q_ITEM : STD_Q_ITEM;
  6252.         LCN_OUT : TCB_PTR := LCN; -- NECESSARY TO PASS OUT THE LCN
  6253.         DATA_QUEUED_FOR_USER : BOOLEAN := TRUE;
  6254.         SOCKET_PARAMS : LCN_PTR_TYPE;
  6255.  
  6256.         begin
  6257.          while not QUEUE_EMPTY(PROCESSED_SEGMENTS_FOR_USER_QUEUE, LCN_OUT) 
  6258.            and then (NOT QUEUE_EMPTY(RECEIVE_QUEUE, LCN_OUT)) loop 
  6259.           -- SO DATA EXISTS AND A RECEIVE
  6260.           -- GET A BUFFER OFF OF THE PROCESSED QUEUE
  6261.           QUEUE_GET(PROCESSED_SEGMENTS_FOR_USER_QUEUE, LCN, Q_ITEM);
  6262.           QUEUED_DATA_BUFFER := Q_ITEM.BUFFER;
  6263.           DATA_LENGTH := Q_ITEM.LENGTH;
  6264.           QUEUE_GET(RECEIVE_QUEUE, LCN, Q_ITEM);
  6265.           RECEIVE_BUFFER := Q_ITEM.BUFFER;
  6266.           LENGTH := Q_ITEM.LENGTH;
  6267.           if RECEIVE_BUFFER /= null then 
  6268.            -- SHOULD NEVER HAPPEN THAT IT IS NULL
  6269.            -- FILL A RECEIVE BUFFER AND RETURN IT TO THE USER
  6270.            INSERT_TEXT_IN_BUFFER(LENGTH, RECEIVE_BUFFER, DATA_LENGTH, 
  6271.                        QUEUED_DATA_BUFFER);
  6272.            -- SET UP MESSAGE
  6273.            SOCKET_PARAMS.LCN := LCN;
  6274.            SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  6275.            SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  6276.            UMESSAGE := ( 10, 
  6277.                          SOCKET_PARAMS,
  6278.                          RECEIVE_BUFFER);
  6279.            MESSAGE_FOR_USER(UMESSAGE);
  6280.            -- FREE UP THE BUFFER FROM THE PROCESSED Q SINCE ONE EXISTS.
  6281.            QUEUED_DATA_BUFFER.STATUS := NONE;
  6282.            --PUT_LINE("BUFFREE PROCESS_SEGMENT_TEXT"); --DEBUG JB 7/3/85
  6283.            BUFFREE(QUEUED_DATA_BUFFER, BUFFTYPE);
  6284.            -- GO TRY TO GET A NEW ONE.
  6285.           else
  6286.            -- PUT IT BACK ON THE QUEUE
  6287.            -- RESTORE THE Q_ITEM.
  6288.            Q_ITEM.BUFFER := QUEUED_DATA_BUFFER;
  6289.            Q_ITEM.LENGTH := DATA_LENGTH;
  6290.            QUEUE_ADD_TO_FRONT(PROCESSED_SEGMENTS_FOR_USER_QUEUE, LCN, Q_ITEM);
  6291.            PUT_LINE("A STRANGE RESULT IN PROCESS TEXT");
  6292.           end if;
  6293.          end loop;
  6294.          if NEW_DATA > 0 then
  6295.           QUEUE_GET(RECEIVE_QUEUE, LCN, Q_ITEM);
  6296.           RECEIVE_BUFFER := Q_ITEM.BUFFER;
  6297.           LENGTH := Q_ITEM.LENGTH;
  6298.           if RECEIVE_BUFFER /= null then -- WE GOT ONE
  6299.            -- PUT IN THE DATA
  6300.            RECEIVE_BUFFER.BYTE
  6301.             (RECEIVE_BUFFER.TCP_PTR..RECEIVE_BUFFER.TCP_PTR
  6302.             + NEW_DATA - 1) := BUFPTR.DATA(1..NEW_DATA);
  6303.            RECEIVE_BUFFER.TELNET_PTR := RECEIVE_BUFFER.TCP_PTR + NEW_DATA - 1;
  6304.            if BUFPTR.PUSH_FLAG = BIT_SET then
  6305.             -- NOTIFY USER WHEN DATA IS RETURNED
  6306.             -- SET UP PROPER MESSAGE RECORD
  6307.             SOCKET_PARAMS.LCN := LCN;
  6308.             SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  6309.             SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  6310.             UMESSAGE := ( 19, 
  6311.                           SOCKET_PARAMS,
  6312.                           NULL_BUFFER);
  6313.             MESSAGE_FOR_USER(UMESSAGE);
  6314.            end if;
  6315.            -- GIVE IT TO THE USER
  6316.            -- SET UP MESSAGE
  6317.            SOCKET_PARAMS.LCN := LCN;
  6318.            SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  6319.            SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  6320.            UMESSAGE := ( 10, 
  6321.                          SOCKET_PARAMS,
  6322.                          RECEIVE_BUFFER);
  6323.            MESSAGE_FOR_USER(UMESSAGE);
  6324.           else
  6325.            -- TRY TO QUEUE IT ON UP
  6326.            BUFFGET(PACKED_BUFF, BUFFTYPE);
  6327.            if PACKED_BUFF = null then
  6328.             TCP_ERROR(7);
  6329.             DATA_QUEUED_FOR_USER := FALSE;
  6330.            else
  6331.             -- SET UP THE POINTER AND INSERT ALL THE DATA.
  6332.             PACKED_BUFF.STATUS := OWNER_TCP;
  6333.             PACKED_BUFF.IN_USE := TRUE;
  6334.             PACKED_BUFF.TCP_PTR := 10;
  6335.             -- PUT THE DATA IN THE BUFFER
  6336.             PACKED_BUFF.BYTE(10..9+NEW_DATA) := 
  6337.                 BUFPTR.DATA(1..NEW_DATA);
  6338.             Q_ITEM := 
  6339.              (PACKED_BUFF,  NULL_UNPACKED_BUFFER, NEW_DATA);
  6340.             QUEUE_ADD(PROCESSED_SEGMENTS_FOR_USER_QUEUE, LCN, Q_ITEM);
  6341.            end if;
  6342.           end if;
  6343.          end if;
  6344.          -- IF WE GOT SOME TEXT WE WILL UPDATE RCV_NXT 
  6345.          -- AND SEND A PIGGYBACKED ACK.
  6346.          if NEW_DATA > 0 and (DATA_QUEUED_FOR_USER) then
  6347.           LCN.RCV_NXT := LCN.RCV_NXT + NEW_DATA;
  6348.          if BUFPTR.FIN = BIT_SET then 
  6349.           -- ADVANCE RCV NEXT OVER THE FIN ALSO. THIS WILL
  6350.           -- CAUSE IT TO ALSO BE ACKED.
  6351.           LCN.RCV_NXT := LCN.RCV_NXT + MODULAR_CONVERT( SIXTEEN_BITS( 1 ) ) ;
  6352.          end if;
  6353.          SEND_A_PIGGYBACKED_ACK(LCN_OUT);
  6354.         end if;
  6355.        exception
  6356.         when constraint_error =>
  6357.          PUT_LINE("CONSTRAINT ERROR IN PROCESS SEGMENT TEXT");
  6358.          INT_IO_16.PUT(RECEIVE_BUFFER.TCP_PTR);
  6359.          INT_IO_16.PUT(NEW_DATA);
  6360.          PUT_LINE("");
  6361.         when others =>
  6362.          PUT_LINE("ERROR IN PROCESS SEGMENT TEXT");
  6363.        end PROCESS_SEGMENT_TEXT;
  6364.     procedure PROCESS_URGENT_FLAG
  6365.             (LCN : in TCB_PTR; BUFPTR : in out 
  6366.                         T_TCP_GLOBALS_DATA_STRUCTURES.BUFFER_POINTER) is
  6367.  
  6368.         UMESSAGE : USER_MESSAGE;
  6369.         SOCKET_PARAMS : LCN_PTR_TYPE;
  6370.  
  6371.         begin
  6372.          if BUFPTR.URG_FLAG = BIT_SET then
  6373.           if LCN.RCV_URGENT_POINTER < BUFPTR.URG_PTR then
  6374.            LCN.RCV_URGENT_POINTER := BUFPTR.URG_PTR;
  6375.           end if;
  6376.           if (LCN.USER_NOTIFICATION = FALSE) 
  6377.             and (LCN.RCV_URGENT_POINTER
  6378.             > BUFPTR.DATA_LEN) then
  6379.            -- TELL USER
  6380.            -- URGENT DATA IS ON THE WAY.
  6381.            SOCKET_PARAMS.LCN := LCN;
  6382.            SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  6383.            SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  6384.            UMESSAGE := ( 7, 
  6385.                          SOCKET_PARAMS);
  6386.            MESSAGE_FOR_USER(UMESSAGE);
  6387.            LCN.USER_NOTIFICATION := TRUE;
  6388.           end if;
  6389.          else
  6390.           LCN.USER_NOTIFICATION := FALSE;
  6391.          end if;
  6392.         exception
  6393.          when constraint_error =>
  6394.           PUT_LINE("CONSTRAINT ERROR IN PROCESS URGENT FLAG");
  6395.          when others =>
  6396.           PUT_LINE("UNKNOWN ERROR IN PROCESS URGENT FLAG");
  6397.         end PROCESS_URGENT_FLAG;
  6398.  
  6399.     procedure PROCESS_A_FIN
  6400.      (LCN : in out TCB_PTR; BUFPTR : in out 
  6401.                         T_TCP_GLOBALS_DATA_STRUCTURES.BUFFER_POINTER) is
  6402.         UMESSAGE : USER_MESSAGE;
  6403.         LENGTH, DATA_LENGTH, INDEX, INDEX1 : SIXTEEN_BITS ;
  6404.         RECEIVED_PACKED_BUFFER, PACKED_BUFFER : PACKED_BUFFER_PTR;
  6405.         BUFFTYPE : SIXTEEN_BITS ;
  6406.         Q_ITEM : STD_Q_ITEM;
  6407.         SOCKET_PARAMS : LCN_PTR_TYPE;
  6408.  
  6409.         begin 
  6410.      -- NOTE THAT THE FIN IMPLIES A PUSH FUNCTION 
  6411.      -- WHICH WE CURRENTLY DO NOT IMPLEMENT.
  6412.          -- TELL USER CONNECTION CLOSING IF HE HAS 
  6413.          -- NOT ALREADY REQUESTED A CLOSE.
  6414.          if LCN.STATE /= T_TCP_GLOBALS_DATA_STRUCTURES.FIN_WAIT_1 and 
  6415.        (LCN.STATE /= T_TCP_GLOBALS_DATA_STRUCTURES.FIN_WAIT_2) then
  6416.           SOCKET_PARAMS.LCN := LCN;
  6417.           SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  6418.           SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  6419.           UMESSAGE := ( 6, 
  6420.                         SOCKET_PARAMS);
  6421.           MESSAGE_FOR_USER(UMESSAGE);
  6422.          end if;
  6423.          QUEUE_GET(RECEIVE_QUEUE, LCN, Q_ITEM);
  6424.          RECEIVED_PACKED_BUFFER := Q_ITEM.BUFFER;
  6425.          LENGTH := Q_ITEM.LENGTH;
  6426.          while RECEIVED_PACKED_BUFFER /= null loop
  6427.           QUEUE_GET(PROCESSED_SEGMENTS_FOR_USER_QUEUE, LCN, Q_ITEM);
  6428.           PACKED_BUFFER := Q_ITEM.BUFFER;
  6429.           DATA_LENGTH := Q_ITEM.LENGTH;
  6430.           if PACKED_BUFFER /= null then
  6431.            -- FILL RECEIVE BUFFER WITH DATA, INDICATE A 
  6432.            -- PUSH AND DELETE DATA FROM Q.
  6433.            -- A PUSH IS AUTOMATICALLY IMPLIED AND Q ROUTINE 
  6434.            -- PERFORMS DELETE.   RETURN THE DATA
  6435.            INSERT_TEXT_IN_BUFFER(LENGTH, RECEIVED_PACKED_BUFFER, 
  6436.             DATA_LENGTH,PACKED_BUFFER);
  6437.            -- FREE UP THE UNEEDED BUFFER FROM PROCESSED Q.
  6438.            PACKED_BUFFER.STATUS := NONE;
  6439.            --PUT_LINE("BUFFREE PROCESS_A_FIN"); --DEBUG JB 7/3/85
  6440.            BUFFREE(PACKED_BUFFER, BUFFTYPE);
  6441.            -- GET THE NEXT RECEIVE.
  6442.            QUEUE_GET(RECEIVE_QUEUE, LCN, Q_ITEM);
  6443.            RECEIVED_PACKED_BUFFER := Q_ITEM.BUFFER;
  6444.            LENGTH := Q_ITEM.LENGTH;
  6445.           else -- PUT RECEIVE BACK ON QUEUE
  6446.            Q_ITEM := (RECEIVED_PACKED_BUFFER, 
  6447.              NULL_UNPACKED_BUFFER, LENGTH);
  6448.            QUEUE_ADD_TO_FRONT(RECEIVE_QUEUE, LCN, Q_ITEM);
  6449.            RECEIVED_PACKED_BUFFER := NULL; -- DID NOT GET ANY TEXT
  6450.           end if;
  6451.          end loop;
  6452.          -- DETERMINE IF FIN WAS ACKED PREVIOUSLY, 
  6453.          -- IF NOT ADVANCE RCV.NXT AND ACK IT
  6454.          if LCN.RCV_NXT <= BUFPTR.SEQ_NUM then
  6455.           -- ADVANCE IT AND SEND AN ACK
  6456.           LCN.RCV_NXT := LCN.RCV_NXT + MODULAR_CONVERT( SIXTEEN_BITS ( 1 ) ) ;
  6457.           SEND_A_PIGGYBACKED_ACK(LCN);
  6458.          end if;
  6459.         exception
  6460.          when constraint_error =>
  6461.           PUT_LINE("CONSTRAINT ERROR IN PROCESS A FIN");
  6462.          when others =>
  6463.           PUT_LINE("UNKNOWN ERROR IN PROCESS A FIN");
  6464.         end PROCESS_A_FIN;
  6465.  
  6466. procedure SEND_A_PIGGYBACKED_ACK( LCN : in out TCB_PTR) is
  6467.  
  6468. TRANS_BUFFER : T_TCP_GLOBALS_DATA_STRUCTURES.BUFFER_POINTER;
  6469. LENGTH, BUFFTYPE : SIXTEEN_BITS ;
  6470. QUEUE_EMPTY : BOOLEAN;
  6471. TYPE_FLAG : HEADER_TYPE;
  6472. PACKED_BUFFER : PACKED_BUFFER_PTR;
  6473. Q_ITEM : STD_Q_ITEM;
  6474. ACK_BUFFER_EXISTS : BOOLEAN := TRUE;
  6475. MESSAGE_FOR_IP : IP_MESSAGE ;
  6476.  
  6477.  procedure SET_UP_TO_SEND_AN_ACK is
  6478.      -- EVERTHING IS EXTERNAL TO THIS PROCEDURE. 
  6479.      -- WHICH GETS A BUFFER,SETS THE TYPE FLAG AND UPDATES SND_NXT.
  6480.  
  6481.  begin
  6482.   -- MUST GET A BUFFER
  6483.   BUFFGET(PACKED_BUFFER, BUFFTYPE);
  6484.   if PACKED_BUFFER = null then
  6485.    --WE HAVE A BAD ERROR
  6486.    TCP_ERROR(7);
  6487.    ACK_BUFFER_EXISTS := FALSE;
  6488.   else
  6489.    PACKED_BUFFER.STATUS := NONE;
  6490.    PACKED_BUFFER.IN_USE := FALSE;
  6491.    TYPE_FLAG := ACK;
  6492.   end if;
  6493.  end SET_UP_TO_SEND_AN_ACK;
  6494.  
  6495.  begin
  6496.   -- GET A BUFFER FROM THE TRANSMIT QUEUE IF POSSIBLE.
  6497.   QUEUE_GET(TRANSMIT_QUEUE, LCN, Q_ITEM);
  6498.   PACKED_BUFFER := Q_ITEM.BUFFER;
  6499.   LENGTH := Q_ITEM.LENGTH;
  6500.   QUEUE_EMPTY := PACKED_BUFFER = null;
  6501.   if not QUEUE_EMPTY then
  6502.    if LCN.SND_WND + LCN.SND_UNA >= 
  6503.     (LENGTH + LCN.SND_NXT) then
  6504.      --IT IS OFF THE QUEUE
  6505.      TYPE_FLAG := SEG_ACK;
  6506.     else -- SEND THE ACK ANYWAY
  6507.      -- PUT THE BUFFER BACK ON THE QUEUE.
  6508.      QUEUE_ADD_TO_FRONT(TRANSMIT_QUEUE, LCN, Q_ITEM);
  6509.      -- THIS PROCEDURE GETS A BUFFER AND DOES THE 
  6510.      -- OTHER NECESSARY THINGS TO SEND AN ACK ONLY.
  6511.      SET_UP_TO_SEND_AN_ACK;
  6512.     end if;
  6513.    else -- JUST SEND AN ACK
  6514.     -- THIS PROCEDURE GETS A BUFFER AND DOES THE OTHER 
  6515.     -- NECESSARY THINGS TO SEND AN ACK ONLY.
  6516.     SET_UP_TO_SEND_AN_ACK;
  6517.    end if;
  6518.     -- NOW WE SEND OUT AN ACK OR PIGGYBACKED ACK
  6519.     -- CLEAR OPTIONS ARRAY
  6520.     if ACK_BUFFER_EXISTS then -- DO IT
  6521.      OPTIONS := CLEAR;
  6522.      TCP_HEADER_FORMAT(LCN, TRANS_BUFFER, TYPE_FLAG, OPTIONS);
  6523.      -- HERE WE MUST SET UP THE SECURITY OPTIONS FOR IP
  6524.      OPTIONS := TCP_SECURITY_OPTIONS;
  6525.      -- PACK THE BUFFER
  6526.      PACK_BUFFER_INTO_BIT_STREAM(TRANS_BUFFER, PACKED_BUFFER);
  6527.      LEN := TRANS_BUFFER.DATA_OFFSET * 4 + LENGTH;
  6528.      MESSAGE_FOR_IP := ( FROM_TCP,
  6529.                          PACKED_BUFFER,
  6530.                          LCN.DESTINATION_ADDRESS,
  6531.                          TOS,
  6532.                          TTL,
  6533.                          LEN,
  6534.                          IDENT,
  6535.                          DONT_FRAGMENT,
  6536.                          OPTIONS,
  6537.                          LCN.SOURCE_ADDRESS ) ;
  6538.      IP_FROM_TCP.Q_ADD( MESSAGE_FOR_IP ) ;
  6539.      -- UPDATE SND_NXT 
  6540.      -- WE DO NOT CHANGE THE SEQUENCE NUMBER IF WE ONLY SEND AN ACK
  6541.      if LENGTH > 0 then
  6542.       LCN.SND_NXT := LCN.SND_NXT + LENGTH;
  6543.       -- A PIGGYBACKED ACK WAS SENT
  6544.      end if;
  6545.      if TYPE_FLAG = SEG_ACK then
  6546.       -- PUT IT ON THE RETRANSMIT QUEUE
  6547.       Q_ITEM :=(PACKED_BUFFER, NULL_UNPACKED_BUFFER, LEN);
  6548.       QUEUE_ADD(TCP_RETRANSMIT_QUEUE, LCN, Q_ITEM);
  6549.      end if;
  6550.      -- SEE IF WE CAN SEND SOME MORE SEGMENTS FROM THE TRANSMIT Q.
  6551.      if NOT QUEUE_EMPTY then
  6552.       SEND_FROM_TRANSMIT_QUEUE(LCN);
  6553.      end if;
  6554.     end if;
  6555.    exception
  6556.     when others =>
  6557.      PUT_LINE("PROBLEM IN PIGGYBACKED ACK ROUTINE");
  6558.    end SEND_A_PIGGYBACKED_ACK;
  6559.  
  6560.     procedure SEND_FROM_TRANSMIT_QUEUE(LCN : in out TCB_PTR) is
  6561.         TRANS_BUFFER : T_TCP_GLOBALS_DATA_STRUCTURES.BUFFER_POINTER;
  6562.         CAN_SEND : BOOLEAN := TRUE;
  6563.         PACKED_BUFF : PACKED_BUFFER_PTR;
  6564.         DATA_LENGTH, INDEX : SIXTEEN_BITS ;
  6565.         Q_ITEM : STD_Q_ITEM;
  6566.         MESSAGE_FOR_IP : IP_MESSAGE ;
  6567.  
  6568.         begin
  6569.          -- TRY TO GET THE INITIAL BUFFER OF DATA FOR TRANSMIT.
  6570.          -- DATA LENGTH WILL BE THE NUMBER OF DATA OCTETS IN THE BUFFER. 
  6571.          -- THEY WILL BE THE ONLY THINGS IN THE BUFFER.
  6572.          QUEUE_GET(TRANSMIT_QUEUE, LCN, Q_ITEM);
  6573.          PACKED_BUFF := Q_ITEM.BUFFER;
  6574.          DATA_LENGTH := Q_ITEM.LENGTH;
  6575.          while PACKED_BUFF /= null and CAN_SEND loop
  6576.           if LCN.SND_WND + LCN.SND_UNA >= 
  6577.            (LCN.SND_NXT + DATA_LENGTH) then 
  6578.            -- WE CAN SEND IT.
  6579.            -- CLEAR OPTIONS ARRAY. IF ANY OPTIONS WENT 
  6580.            -- HERE WE WOULD ADD TO THE HEADER LENGTH APPROPRIATELY.
  6581.            OPTIONS := CLEAR;
  6582.            -- PUT THE DATA IN THE BUFFER.
  6583.            -- CURRENTLY MAX OF ONE OCTET SO JUST PUT IT IN.
  6584.            INDEX := PACKED_BUFF.TCP_PTR;
  6585.            TRANS_BUFFER.DATA(1..DATA_LENGTH) := 
  6586.             PACKED_BUFF.BYTE(INDEX..INDEX + DATA_LENGTH - 1);
  6587.            TCP_HEADER_FORMAT(LCN, TRANS_BUFFER, SEGMENT, OPTIONS);
  6588.            -- HERE WE MUST SET UP THE SECURITY OPTIONS FOR IP
  6589.            OPTIONS := TCP_SECURITY_OPTIONS;
  6590.            -- PACK THE BUFFER
  6591.            PACK_BUFFER_INTO_BIT_STREAM(TRANS_BUFFER, PACKED_BUFF);
  6592.            LEN := TRANS_BUFFER.DATA_OFFSET * 4 + DATA_LENGTH; 
  6593.            -- TOTAL TCP LENGTH
  6594.            MESSAGE_FOR_IP := ( FROM_TCP,
  6595.                                PACKED_BUFF,
  6596.                                LCN.DESTINATION_ADDRESS,
  6597.                                TOS,
  6598.                                TTL,
  6599.                                LEN,
  6600.                                IDENT,
  6601.                                DONT_FRAGMENT,
  6602.                                OPTIONS,
  6603.                                LCN.SOURCE_ADDRESS ) ;
  6604.            IP_FROM_TCP.Q_ADD( MESSAGE_FOR_IP ) ;
  6605.            -- UPDATE SND_NXT 
  6606.            LCN.SND_NXT := LCN.SND_NXT + 
  6607.             TRANS_BUFFER.DATA_LEN;
  6608.            -- PUT IT ON THE RETRANSMIT QUEUE
  6609.            Q_ITEM := (PACKED_BUFF, NULL_UNPACKED_BUFFER,LEN);
  6610.            QUEUE_ADD(TCP_RETRANSMIT_QUEUE, LCN, Q_ITEM);
  6611.            -- GET ANOTHER BUNCH OF DATA TO BE SENT
  6612.            QUEUE_GET(TRANSMIT_QUEUE, LCN, Q_ITEM);
  6613.            PACKED_BUFF := Q_ITEM.BUFFER;
  6614.            DATA_LENGTH := Q_ITEM.LENGTH;
  6615.           else
  6616.            CAN_SEND := FALSE;
  6617.            -- PUT IT BACK ON THE QUEUE IN THE FIRST SPOT
  6618.            QUEUE_ADD_TO_FRONT(TRANSMIT_QUEUE, LCN, Q_ITEM);
  6619.           end if;
  6620.          end loop;
  6621.          if QUEUE_EMPTY(TRANSMIT_QUEUE, LCN) then
  6622.          -- CHECK FOR CLOSE PENDING
  6623.           if LCN.CLOSE_PENDING then
  6624.            if LCN.STATE = T_TCP_GLOBALS_DATA_STRUCTURES.CLOSE_WAIT then
  6625.             LCN.STATE := CLOSING;
  6626.            else
  6627.         LCN.STATE := T_TCP_GLOBALS_DATA_STRUCTURES.FIN_WAIT_1;
  6628.            end if;
  6629.           end if;
  6630.          end if;
  6631.         exception 
  6632.          when constraint_error =>
  6633.           PUT_LINE("A CONSTRAINT ERROR IN SEND ");
  6634.           PUT_LINE("FROM TRANSMIT QUEUE");
  6635.          when others =>
  6636.           PUT_LINE("AN UNKNOWN ERROR IN SEND FROM TRANSMIT QUEUE");
  6637.         end SEND_FROM_TRANSMIT_QUEUE;
  6638.  
  6639. function UNPACK( PACKED_BUFFER : in PACKED_BUFFER_PTR; 
  6640.                  TOTAL_DATA_BYTES : in SIXTEEN_BITS ) return 
  6641.                       T_TCP_GLOBALS_DATA_STRUCTURES.BUFFER_POINTER is
  6642.  
  6643.          type ARRAY_OF_BITS is array(1..6) of SIXTEEN_BITS ;
  6644.      UNPACKED_BUFFER : T_TCP_GLOBALS_DATA_STRUCTURES.BUFFER_POINTER;
  6645.      INDEX : SIXTEEN_BITS  := PACKED_BUFFER.TCP_PTR;
  6646.      BIT_ARRAY : ARRAY_OF_BITS;
  6647.      TCP_DATA_BYTES : SIXTEEN_BITS  := TOTAL_DATA_BYTES;
  6648.  function CONVERT_BYTE_TO_BITS( LENGTH : SIXTEEN_BITS ; BYTE : SYSTEM_BYTE)
  6649.             return ARRAY_OF_BITS is
  6650.            
  6651.     --   THIS FUNCTION IS CALLED TO CONVERT A BYTE INTO ITS 
  6652.     -- COMPONENT 'LENGTH' BITS
  6653.     --
  6654.     --   AN ARRAY OF BITS. EACH ELEMENT OF THE ARRAY IS EITHER 0 OR 1. 
  6655.     --  IT IS 0 IF
  6656.     --   THE CORRESPONDING BIT IN BYTE IS NOT SET AND ONE OTHERWISE.
  6657.     --
  6658.     -- PROCESSING :
  6659.     --
  6660.     --   IF THE BYTE'S VALUE IS GREATER THAT 2**LENGTH-1 AND IF SO IT 
  6661.     --   KNOWS THAT THE BIT IS SET. IT THEN DECREMENTS LENGTH AND 
  6662.     --   SUBTRACTS 2**LENGTH-1 FROM BYTE IF THE BIT WAS SET. THIS PROCESS 
  6663.     --   IS CONTINUED UNTIL 0 IS REACHED.
  6664.     --
  6665.     -- RESTRICTIONS :
  6666.     --
  6667.  TEMP : SIXTEEN_BITS  := SIXTEEN_BITS  ( BYTE ) ;
  6668.  BIT_ARRAY : ARRAY_OF_BITS;
  6669.  
  6670.  begin
  6671.   for I in reverse 0..LENGTH-1 loop
  6672.    if TEMP >=  SIXTEEN_BITS(2) ** THIRTYTWO_BITS(I)  then
  6673.     BIT_ARRAY( THIRTYTWO_BITS(I + SIXTEEN_BITS(1)) ) := SIXTEEN_BITS (1);
  6674.     TEMP := TEMP - SIXTEEN_BITS (2)** THIRTYTWO_BITS(I) ;
  6675.    else
  6676.     BIT_ARRAY( THIRTYTWO_BITS(I + SIXTEEN_BITS (1)) ) := 0;
  6677.    end if;
  6678.   end loop;
  6679.   return BIT_ARRAY;
  6680.  exception
  6681.   when others => 
  6682.    PUT_LINE("ERROR IN UNPACK CONVERT BYTES TO BITS");
  6683.    INT_IO_16.PUT(INDEX);
  6684.  end CONVERT_BYTE_TO_BITS;
  6685.           
  6686.  function CONVERTED_LONG_INTEGER( INDEX : in SIXTEEN_BITS ) return 
  6687.                                                   THIRTYTWO_BITS is
  6688.                  
  6689.     --   THIS FUNCTION TAKES FOUR SYSTEM.BYTES FROM THE ARRAY POINTED TO BY
  6690.     --   PACKED_BUFFER AND MOVES THEM INTO A LONG_INTEGER WITH THE FUNCTION
  6691.     --   UNCHECKED_CONVERSION. IT FIRST MOVES THE SYSTEM BYTES INTO A 
  6692.     --   TEMPORARY ARRAY OF FOUR SYSTEM BYTES AND PUTS THESE IN A ONE 
  6693.     --   ELEMENT LONG_INTEGER ARRAY.
  6694.  
  6695.  type HOLD_LONG_INTEGER is array(1..1) of THIRTYTWO_BITS ;
  6696.  type FOUR_BYTES is array(1..4) of SYSTEM_BYTE;
  6697.  function CONVERT_BYTES_TO_LONG_INTEGER is new 
  6698.           UNCHECKED_CONVERSION(FOUR_BYTES,HOLD_LONG_INTEGER);
  6699.  HOLD_LONG_INT : HOLD_LONG_INTEGER;
  6700.  FOUR_BYTE_HOLDER : FOUR_BYTES;
  6701.  
  6702.  begin
  6703.   for I in 1..4 loop
  6704.    FOUR_BYTE_HOLDER(I) := PACKED_BUFFER.BYTE( INDEX + SIXTEEN_BITS(I) - 1 ) ;
  6705.   end loop;
  6706.   HOLD_LONG_INT :=  CONVERT_BYTES_TO_LONG_INTEGER(FOUR_BYTE_HOLDER);
  6707.   return HOLD_LONG_INT(1);
  6708.  exception
  6709.   when others => 
  6710.    PUT_LINE("ERROR IN UNPACK CONVERTED LONG INTEGER");
  6711.    INT_IO_16.PUT(INDEX);
  6712.  end CONVERTED_LONG_INTEGER;
  6713.  
  6714.  function CONVERTED_INTEGER( INDEX : in SIXTEEN_BITS ) return SIXTEEN_BITS  is
  6715.  
  6716.     --   THIS FUNCTION USES UNCHECKED_CONVERSION TO ALLOW AN ARRAY OF TWO 
  6717.     --   SYSTEM BYTES TO BE PLACED IN A ONE ELEMENT INTEGER ARRAY. THIS 
  6718.     --   ARRAY ELEMENT IS THEN RETURNED.
  6719.  
  6720.  type TWO_BYTES is array(1..2) of SYSTEM_BYTE;
  6721.  type HOLD_AN_INTEGER is array(1..1) of SIXTEEN_BITS ;
  6722.  function CONVERT_BYTES_TO_INTEGER is new 
  6723.           UNCHECKED_CONVERSION(TWO_BYTES,HOLD_AN_INTEGER);
  6724.  TWO_BYTE_HOLDER : TWO_BYTES;
  6725.  HOLD_INTEGER : HOLD_AN_INTEGER;
  6726.  
  6727.  begin
  6728.   for I in 1..2 loop
  6729.    TWO_BYTE_HOLDER(I) := PACKED_BUFFER.BYTE( INDEX + SIXTEEN_BITS(I) - 1 ) ;
  6730.   end loop;
  6731.   HOLD_INTEGER := CONVERT_BYTES_TO_INTEGER(TWO_BYTE_HOLDER);
  6732.   return HOLD_INTEGER(1);
  6733.  exception
  6734.   when others => 
  6735.    PUT_LINE("ERROR IN UNPACK CONVERTED INTEGER");
  6736.    INT_IO_16.PUT(INDEX);
  6737.   end CONVERTED_INTEGER;
  6738.  
  6739. begin -- MAIN
  6740.  -- PUT UNPACKED DATA IN THE BUFFER
  6741.  UNPACKED_BUFFER.SOURCE_PORT := CONVERTED_INTEGER(INDEX);
  6742.  INDEX := INDEX + 2;
  6743.  UNPACKED_BUFFER.DESTINATION_PORT := CONVERTED_INTEGER(INDEX);
  6744.  INDEX := INDEX + 2;
  6745.  UNPACKED_BUFFER.SEQ_NUM := MODULAR_CONVERT(CONVERTED_LONG_INTEGER(INDEX));
  6746. --PUT_LINE("UNPACK.SEQ_NUM(HI) := ");
  6747. --INT_IO_16.PUT(SIXTEEN_BITS(UNPACKED_BUFFER.SEQ_NUM.HI));
  6748. --NEW_LINE;
  6749. --PUT_LINE("UNPACK.SEQ_NUM(LO) := ");
  6750. --INT_IO_16.PUT(SIXTEEN_BITS(UNPACKED_BUFFER.SEQ_NUM.LOW));
  6751. --NEW_LINE;
  6752.  INDEX := INDEX + 4;
  6753.  UNPACKED_BUFFER.ACK_NUM := MODULAR_CONVERT(CONVERTED_LONG_INTEGER(INDEX));
  6754. -- PUT_LINE("UNPACK.ACK_NUM(HI) := ");
  6755. -- INT_IO_32.PUT(UNPACKED_BUFFER.ACK_NUM.HI);
  6756. -- NEW_LINE;
  6757. -- PUT_LINE("UNPACK.ACK_NUM(LO) := ");
  6758. -- INT_IO_32.PUT(UNPACKED_BUFFER.ACK_NUM.LOW);
  6759. -- NEW_LINE;
  6760.  INDEX := INDEX + 4;
  6761.  UNPACKED_BUFFER.DATA_OFFSET :=  SIXTEEN_BITS(PACKED_BUFFER.BYTE(INDEX))/ 
  6762.                                  (2**4) ;
  6763.                                                   -- THE HIGH 4 BITS
  6764.  INDEX := INDEX + 1;
  6765.  -- SET THE TCP FLAGS
  6766.  BIT_ARRAY := CONVERT_BYTE_TO_BITS(6, PACKED_BUFFER.BYTE(INDEX));
  6767.  UNPACKED_BUFFER.URG_FLAG := BIT_ARRAY(6);
  6768.  UNPACKED_BUFFER.ACK := BIT_ARRAY(5);
  6769.  UNPACKED_BUFFER.PUSH_FLAG := BIT_ARRAY(4);
  6770.  UNPACKED_BUFFER.RST := BIT_ARRAY(3);
  6771.  UNPACKED_BUFFER.SYN := BIT_ARRAY(2);
  6772.  UNPACKED_BUFFER.FIN := BIT_ARRAY(1);
  6773.  INDEX := INDEX + 1;
  6774.  UNPACKED_BUFFER.WINDOW := CONVERTED_INTEGER(INDEX);
  6775.  INDEX := INDEX + 2;
  6776.  UNPACKED_BUFFER.TCP_CSUM := CONVERTED_INTEGER(INDEX);
  6777.  INDEX := INDEX + 2;
  6778.  UNPACKED_BUFFER.URG_PTR := CONVERTED_INTEGER(INDEX);
  6779.  INDEX := INDEX +2;
  6780.  -- HERE WE WOULD CONVERT THE CURRENTLY UNIMPLEMENTED 
  6781.  -- OPTIONS.
  6782.  if UNPACKED_BUFFER.DATA_OFFSET > 5 then
  6783.   PUT_LINE("ERROR IN UNPACKING A BUFFER");
  6784.   TCP_ERROR(10);
  6785.  end if;
  6786.  -- UNPACK THE DATA
  6787.  TCP_DATA_BYTES := TCP_DATA_BYTES - UNPACKED_BUFFER.DATA_OFFSET * 4; -- WE
  6788.  UNPACKED_BUFFER.DATA_LEN := 
  6789.          TCP_DATA_BYTES;-- SET UP THE DATA LENGTH IN BUFFER
  6790.  -- ARE PASSED THE TOTAL BYTES(OCTETS) IN THE TCP. 
  6791.  -- WE ONLY WANT DATA.
  6792.  for I in 1..TCP_DATA_BYTES loop
  6793.   UNPACKED_BUFFER.DATA(I) := PACKED_BUFFER.BYTE(INDEX+I-1);
  6794.  end loop;
  6795.  return UNPACKED_BUFFER;
  6796. exception
  6797.  when others => 
  6798.   PUT_LINE("ERROR IN UNPACK MAIN");
  6799.   INT_IO_16.PUT(INDEX);
  6800. end UNPACK;
  6801.     
  6802.     procedure PROCESS_COMMON_ACK( LCN : in TCB_PTR; 
  6803.                                       BUFPTR : in 
  6804.                          T_TCP_GLOBALS_DATA_STRUCTURES.BUFFER_POINTER;
  6805.                           RESULT : out RES) is
  6806.         LOC_CON_NAME : TCB_PTR := LCN;
  6807.         NULL_ITEM : STD_Q_ITEM := (NULL,  NULL_UNPACKED_BUFFER, 0);
  6808.         begin
  6809.          RESULT := GOOD;
  6810.          if BUFPTR.ACK_NUM > LCN.SND_NXT then
  6811.           -- IT ACKS SOMETHING NOT YET SENT
  6812.           SEND_A_PIGGYBACKED_ACK(LOC_CON_NAME);
  6813.           RESULT := BAD;
  6814.          else
  6815.           if BUFPTR.ACK_NUM <= LCN.SND_UNA then  
  6816.            -- IGNORE IT, SINCE IT IS A DUPLICATE.
  6817.            -- THE SEGMENT IS OK, HOWEVER. SO THE RESULT IS GOOD.
  6818.            RESULT := GOOD;
  6819.           else
  6820.            -- UPDATE THE SENT UNACKNOWLEDGED FIELD OF THE TCB.
  6821.            LCN.SND_UNA := BUFPTR.ACK_NUM;
  6822.            -- REMOVE ALL BUFFERS THAT ARE FULLY ACKNOWLEDGED 
  6823.            -- FROM THE RETRANS QUEUE.
  6824.            -- RETURN SEND BUFFERS TO USER WITH OK RESPONSE. 
  6825.         -- THESE ARE BOTH DONE BY RETRANSMIT QUEUE.
  6826.            DELETE_FROM_RETRANS_QUEUE(LCN, LCN.SND_UNA);
  6827.            if (LCN.SND_WL1 < BUFPTR.SEQ_NUM) 
  6828.         or ((LCN.SND_WL1 = 
  6829.           BUFPTR.SEQ_NUM) and
  6830.         (LCN.SND_WL2 <= BUFPTR.ACK_NUM))  then
  6831.             LCN.SND_WND := BUFPTR.WINDOW;
  6832.             LCN.SND_WL1 := BUFPTR.SEQ_NUM;
  6833.             LCN.SND_WL2 := BUFPTR.ACK_NUM;
  6834.            end if;
  6835.            -- SEE IF WE CAN SEND ANYTHING WITHIN THE SEND WINDOW 
  6836.            -- FROM THE TRANSMIT Q
  6837.            SEND_FROM_TRANSMIT_QUEUE(LOC_CON_NAME);
  6838.           end if;
  6839.          end if;
  6840.         exception
  6841.          when constraint_error =>
  6842.           PUT_LINE("CONSTRAINT ERROR IN PROCESS COMMON ACK");
  6843.          when others =>
  6844.           PUT_LINE("UNKNOWN ERROR IN PROCESS COMMON ACK");
  6845.         end PROCESS_COMMON_ACK;
  6846.  
  6847.     procedure ENTER_ESTABLISHED_STATE_PROCESSING
  6848.                 ( LCN : in TCB_PTR; BUFPTR : in out
  6849.                    T_TCP_GLOBALS_DATA_STRUCTURES.BUFFER_POINTER) is
  6850.     MORE_THAN_ONCE : BOOLEAN := FALSE;
  6851.     NEW_LCN : TCB_PTR;
  6852.     ITEM : STD_Q_ITEM := (NULL, NULL_UNPACKED_BUFFER, 0);
  6853.     TEMP_BUFPTR : T_TCP_GLOBALS_DATA_STRUCTURES.BUFFER_POINTER;
  6854.     begin
  6855.      LCN.CONNECTION_STATUS := CONNECTION_OPEN;
  6856.      NEW_LCN := LCN; 
  6857.      -- NECESSARY FOR A IN OUT PARAM. IN FIN CHECK CALL.
  6858.      TEMP_BUFPTR := BUFPTR;-- SAVE THE BUFFER.
  6859.      -- PROCESS THE REST OF FIRST BUFFER AND 
  6860.      -- THEN ALL PARTIALLY PROCESSED BUFFERS
  6861.      -- ON THE TCP_RETRANSMIT_QUEUE
  6862.      while not MORE_THAN_ONCE or (ITEM.LENGTH > 0 ) loop
  6863.           PROCESS_URGENT_FLAG(LCN, BUFPTR);
  6864.           PROCESS_SEGMENT_TEXT(LCN, BUFPTR);
  6865.           FIN_CHECK_FOR_ESTAB_OR_SYN_RECEIVED_STATES(NEW_LCN, BUFPTR);
  6866.           -- CHECK THE RECEIVED SEGMENT QUEUE TO 
  6867.           -- DETERMINE IF THERE ARE ANY SEG
  6868.           -- THAT NEED CONTINUED PROCESSING ON IT.
  6869.           QUEUE_GET(TCP_RECEIVED_SEGMENT_QUEUE, LCN, ITEM);
  6870.           MORE_THAN_ONCE := TRUE;
  6871.           BUFPTR := ITEM.UNPACKED_BUFFER;
  6872.          end loop;
  6873.          BUFPTR := TEMP_BUFPTR; -- RESTORE THE BUFFER
  6874.          -- HERE WE WILL TRANSMIT ALL DATA WAITING 
  6875.          -- TO GO ON THE SEND QUEUE
  6876.          SEND_FROM_TRANSMIT_QUEUE(NEW_LCN);
  6877.         exception
  6878.          when constraint_error =>
  6879.          PUT_LINE("CONSTRAINT ERROR IN ENTER ESTABLISHED ");
  6880.       PUT_LINE("STATE PROCESSING");
  6881.      when others =>
  6882.       PUT_LINE("UNKNOWN ERROR IN ENTER ESTABLISHED ");
  6883.       PUT_LINE("STATE PROCESSING");
  6884.     end ENTER_ESTABLISHED_STATE_PROCESSING;
  6885.  
  6886.     procedure SEND_A_SYN_AND_ACK( LCN : in TCB_PTR) is
  6887.  
  6888.     BUFFTYPE : SIXTEEN_BITS ;
  6889.     BUFPTR : T_TCP_GLOBALS_DATA_STRUCTURES.BUFFER_POINTER;
  6890.     PACKED_BUFFER : PACKED_BUFFER_PTR;
  6891.     UMESSAGE : USER_MESSAGE;
  6892.     Q_ITEM : STD_Q_ITEM;
  6893.         SOCKET_PARAMS : LCN_PTR_TYPE;
  6894.         MESSAGE_FOR_IP : IP_MESSAGE ;
  6895.  
  6896.     begin
  6897.      -- CLEAR THE OPTIONS ARRAY AND THE NECESSARY 
  6898.      -- EXTRA HEADER OCTETS GET ADDED IN.
  6899.      BUFFGET(PACKED_BUFFER, BUFFTYPE);
  6900.      if PACKED_BUFFER = null then
  6901.           -- TELL USER    ERROR OUT OF BUFFERS
  6902.           SOCKET_PARAMS.LCN := LCN;
  6903.           SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  6904.           SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  6905.           UMESSAGE := ( 20, 
  6906.                         SOCKET_PARAMS);
  6907.         MESSAGE_FOR_USER(UMESSAGE);
  6908.      else
  6909.           PACKED_BUFFER.STATUS := OWNER_TCP;
  6910.           PACKED_BUFFER.IN_USE := TRUE;
  6911.         TCP_HEADER_FORMAT(LCN, BUFPTR, SYN_ACK, OPTIONS);
  6912.         -- HERE WE MUST SET UP THE SECURITY OPTIONS FOR IP
  6913.         OPTIONS := TCP_SECURITY_OPTIONS;
  6914.         -- PACK A BUFFER
  6915.         PACK_BUFFER_INTO_BIT_STREAM(BUFPTR, PACKED_BUFFER);
  6916.         LEN := BUFPTR.DATA_OFFSET * 4;
  6917.           MESSAGE_FOR_IP := ( FROM_TCP,
  6918.                               PACKED_BUFFER,
  6919.                               LCN.DESTINATION_ADDRESS,
  6920.                               TOS,
  6921.                               TTL,
  6922.                               LEN,
  6923.                               IDENT,
  6924.                               DONT_FRAGMENT,
  6925.                               OPTIONS,
  6926.                               LCN.SOURCE_ADDRESS ) ;
  6927.          IP_FROM_TCP.Q_ADD( MESSAGE_FOR_IP ) ;
  6928. --        if RESULT = OK then
  6929.            -- PUT BUFFER ON THE RETRANSMISSION QUEUE.
  6930.            LCN.SND_NXT := LCN.SND_NXT + MODULAR_CONVERT( SIXTEEN_BITS (1) ) ;
  6931.            Q_ITEM := (PACKED_BUFFER,  NULL_UNPACKED_BUFFER, LEN);
  6932.            QUEUE_ADD(TCP_RETRANSMIT_QUEUE, LCN, Q_ITEM);
  6933. --        else
  6934. --           -- TELL USER WE ARE    OUT OF SPACE
  6935. --           SOCKET_PARAMS.LCN := LCN;
  6936. --           SOCKET_PARAMS.FOREIGN_NET_HOST := LCN.DESTINATION_ADDRESS;
  6937. --           SOCKET_PARAMS.FOREIGN_PORT := LCN.FOREIGN_PORT;
  6938. --           UMESSAGE := ( 22,
  6939. --                         SOCKET_PARAMS);
  6940. --           MESSAGE_FOR_USER(UMESSAGE);
  6941. --        end if;
  6942.      end if;
  6943.     exception
  6944.       when constraint_error =>
  6945.          PUT_LINE("CONSTRAINT ERROR IN SEND A SYN AND ACK");
  6946.       when others =>
  6947.          PUT_LINE("UNKNOWN ERROR IN SEND A SYN AND ACK");
  6948.     end SEND_A_SYN_AND_ACK;
  6949.  
  6950.     procedure BAD_SYN_HANDLER( LCN : in TCB_PTR; 
  6951.                                    BUFPTR : in out 
  6952.                             T_TCP_GLOBALS_DATA_STRUCTURES.BUFFER_POINTER) is
  6953.  
  6954.     UMESSAGE : USER_MESSAGE;
  6955.         NULL_BUFF : T_TCP_GLOBALS_DATA_STRUCTURES.BUFFER_POINTER;
  6956.         SOCKET_PARAMS : LCN_PTR_TYPE;
  6957.  
  6958.     begin
  6959.      -- THE SYN SHOULD BE IN THE WINDOW OR WE WOULD NOT BE HERE
  6960.        if (BUFPTR.SEQ_NUM >= LCN.RCV_NXT) 
  6961.         and (BUFPTR.SEQ_NUM <= 
  6962.            LCN.RCV_NXT +
  6963.            LCN.RCV_WINDOW) then
  6964.           SEND_A_RESET(LCN);
  6965.       -- CLEAR THE QUEUES OUT
  6966.          QUEUE_CLEAR(TCP_RECEIVED_SEGMENT_QUEUE, LCN);
  6967.           -- WE HAVE NO SEND QUEUE AS SUCH. QUEUE_CLEAR(SEND_QUEUE, LCN);
  6968.          QUEUE_CLEAR(RECEIVE_QUEUE, LCN);
  6969.          QUEUE_CLEAR(TRANSMIT_QUEUE, LCN);
  6970.          QUEUE_CLEAR(PROCESSED_SEGMENTS_FOR_USER_QUEUE, LCN);
  6971.          QUEUE_CLEAR(TCP_RETRANSMIT_QUEUE, LCN);
  6972.           -- TELL USER
  6973.           --  ERROR: CONNECTION RESET 
  6974.           SOCKET_PARAMS.LCN := LCN;
  6975.           SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  6976.           SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  6977.           UMESSAGE := ( 16, 
  6978.                         SOCKET_PARAMS);
  6979.           MESSAGE_FOR_USER(UMESSAGE);
  6980.           LCN.STATE := CLOSED;
  6981.           -- MAY HAVE TO CLEAR THE TCB HERE.
  6982.          TCB_CLEAR(LCN);
  6983.        else
  6984.           -- ERROR: WE'VE MADE A MISTAKE
  6985.           TCP_ERROR(9);
  6986.        end if;
  6987.     exception
  6988.       when constraint_error =>
  6989.          PUT_LINE("CONSTRAINT ERROR IN BAD SYN HANDLER");
  6990.       when others =>
  6991.          PUT_LINE("UNKNOWN ERROR IN BAD SYN HANDLER");
  6992.     end BAD_SYN_HANDLER;
  6993.  
  6994.     procedure SEND_A_RESET_AND_ACK( LCN : in TCB_PTR) is
  6995.  
  6996.     BUFFTYPE : SIXTEEN_BITS ;
  6997.     BUFPTR : T_TCP_GLOBALS_DATA_STRUCTURES.BUFFER_POINTER;
  6998.     PACKED_BUFFER : PACKED_BUFFER_PTR;
  6999.     UMESSAGE : USER_MESSAGE;
  7000.         SOCKET_PARAMS : LCN_PTR_TYPE;
  7001.         MESSAGE_FOR_IP : IP_MESSAGE ;
  7002.  
  7003.     begin
  7004.      -- GET A BUFFER
  7005.      BUFFGET(PACKED_BUFFER,    BUFFTYPE);
  7006.      if PACKED_BUFFER = null then
  7007.         -- TELL USER    ERROR OUT OF BUFFERS
  7008.           SOCKET_PARAMS.LCN := LCN;
  7009.           SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  7010.           SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  7011.         UMESSAGE := ( 20, 
  7012.                         SOCKET_PARAMS);
  7013.         MESSAGE_FOR_USER(UMESSAGE);
  7014.      else
  7015.           PACKED_BUFFER.STATUS := OWNER_TCP;
  7016.           PACKED_BUFFER.IN_USE := TRUE;
  7017.         -- CLEAR THE OPTIONS ARRAY 
  7018.         OPTIONS := CLEAR;
  7019.         TCP_HEADER_FORMAT(LCN, BUFPTR, RST_ACK, OPTIONS);
  7020.         -- HERE WE MUST SET UP THE SECURITY OPTIONS FOR IP
  7021.         OPTIONS := TCP_SECURITY_OPTIONS;
  7022.         -- PACK BUFFER UP
  7023.         PACK_BUFFER_INTO_BIT_STREAM(BUFPTR, PACKED_BUFFER);
  7024.         -- THE LENGTH OF THE BUFFER WILL BE HEADER LENGTH ONLY
  7025.           MESSAGE_FOR_IP := ( FROM_TCP,
  7026.                               PACKED_BUFFER,
  7027.                               LCN.DESTINATION_ADDRESS,
  7028.                               TOS,
  7029.                               TTL,
  7030.                               BUFPTR.DATA_OFFSET * 4 ,
  7031.                               IDENT,
  7032.                               DONT_FRAGMENT,
  7033.                               OPTIONS,
  7034.                               LCN.SOURCE_ADDRESS ) ;
  7035.          IP_FROM_TCP.Q_ADD( MESSAGE_FOR_IP ) ;
  7036. --      if RESULT = OK then
  7037.        -- UPDATE SEND NEXT. NOT REALLY NECESSARY.
  7038. --       null;
  7039. --      else
  7040. --           -- TELL USER WE ARE    OUT OF SPACE
  7041. --           SOCKET_PARAMS.LCN := LCN;
  7042. --           SOCKET_PARAMS.FOREIGN_NET_HOST := LCN.DESTINATION_ADDRESS;
  7043. --           SOCKET_PARAMS.FOREIGN_PORT := LCN.FOREIGN_PORT;
  7044. --           UMESSAGE := ( 22,
  7045. --                         SOCKET_PARAMS);
  7046. --           MESSAGE_FOR_USER(UMESSAGE);
  7047. --          end if;
  7048.      end if;
  7049.         exception
  7050.       when constraint_error =>
  7051.          PUT_LINE("CONSTRAINT ERROR IN SEND A RESET AND ACK");
  7052.       when others =>
  7053.          PUT_LINE("UNKNOWN ERROR IN SEND A RESET AND ACK");
  7054.     end SEND_A_RESET_AND_ACK;
  7055.  
  7056. end TCP_ARRIVES_PERIPHERALS;
  7057. --::::::::::::::
  7058. --iparrive_.ada
  7059. --::::::::::::::
  7060. -----------------------------------------------------------------------
  7061. --
  7062. --         DoD Protocols    NA-00001-200       80-00992-100(-)
  7063. --         E-Systems, Inc.  August 07, 1985
  7064. --
  7065. --         IPARRIVE_.ADA       Author : Jim Baldo
  7066. --
  7067. -----------------------------------------------------------------------
  7068. with BUFFER_DATA;        use BUFFER_DATA;
  7069.  
  7070.             package IP_ARRIVE_PROCESSING is
  7071.  
  7072.         -----------------------------------------------------
  7073.         --This implementation is for use with the DEC/ADA  --
  7074.         --compiler.                                        --
  7075.         -----------------------------------------------------
  7076.  
  7077. ------------------------------------------------------------------------------
  7078. -- THIS PACKAGE IS RESPONSIBLE FOR PROCESSING AN ARRIVED DATAGRAM RECEIVED  --
  7079. -- FROM THE CHANNEL PROTOCOL MODULE.                                        --
  7080. ------------------------------------------------------------------------------
  7081.  
  7082.     procedure IP_DATAGRAM_ARRIVE(PACKED_BUFF : in out PACKED_BUFFER_PTR);
  7083.  
  7084.         --This subprogram is called by the ip controller when a 
  7085.         --datagram arrives for the IP.
  7086.  
  7087.  
  7088. end IP_ARRIVE_PROCESSING;
  7089.  
  7090. --::::::::::::::
  7091. --iparrive.ada
  7092. --::::::::::::::
  7093. -----------------------------------------------------------------------
  7094. --
  7095. --         DoD Protocols    NA-00001-200       80-00993-100(-)
  7096. --         E-Systems, Inc.  August 07, 1985
  7097. --
  7098. --         IPARRIVE.ADA       Author : Jim Baldo
  7099. --
  7100. -----------------------------------------------------------------------
  7101. with WITH_TCP_COMMUNICATE;    use WITH_TCP_COMMUNICATE;
  7102. with UNCHECKED_CONVERSION;
  7103. with SYSTEM;            use SYSTEM;
  7104. with TEXT_IO;            use TEXT_IO;
  7105. with IP_GLOBALS;        use IP_GLOBALS;
  7106. with TCP_Q_TASK;        use TCP_Q_TASK;
  7107. with IP_UNPACK_AND_PACK_UTILITIES; use IP_UNPACK_AND_PACK_UTILITIES;
  7108. with UTILITIES_FOR_ICMP;
  7109. with REASSEMBLY_UTILITIES;    use REASSEMBLY_UTILITIES;
  7110.  
  7111.         package body IP_ARRIVE_PROCESSING is
  7112.  
  7113. package INT_IO is new INTEGER_IO( SIXTEEN_BITS );
  7114.  
  7115.     PRINT_DATAGRAM_FLAG : SIXTEEN_BITS  := 1;--for debug
  7116.     PRINT_FLAG : SIXTEEN_BITS := 1;--for debug
  7117.  
  7118.  
  7119. procedure IP_DATAGRAM_ARRIVE(PACKED_BUFF : in out PACKED_BUFFER_PTR) is
  7120.  
  7121.     --This subprogram will accept an arrived datagram check it for 
  7122.     --correctness and if correct return it to the user layer 
  7123.     --(TCP in our case).
  7124.     --
  7125.     -- RESTRICTIONS :
  7126.     --
  7127.     --We do not do any fragment reassembly or any option processing, 
  7128.     --other than the options required by the TCP (security and precedence.)
  7129.  
  7130. type INT_ARRAY is array(1..1) of SIXTEEN_BITS ;
  7131. type TWO_BYTES is array(1..2) of SYSTEM_BYTE;
  7132.  
  7133. function CONVERT_TO_INTEGER is new
  7134.      UNCHECKED_CONVERSION(TWO_BYTES, INT_ARRAY);
  7135.  
  7136. BYTE_COUNT : SIXTEEN_BITS := 0;
  7137. BUF_CSUM : TWO_BYTES;
  7138. CARRIED_CSUM : INT_ARRAY;
  7139. SECURITY_OPTION : SECURITY_OPTION_TYPE;
  7140. X, IP_LENGTH_IN_OCTETS, HEADER_CHECKSUM : SIXTEEN_BITS ;
  7141. I : SIXTEEN_BITS  := 1;
  7142. DESTINATION_FAKE_HOST : BOOLEAN := FALSE; -- TEMPORARY FOR TEST ***
  7143. BAD_OPTION : BOOLEAN := FALSE;
  7144. BUFPTR : BUFFER_POINTER;
  7145. OPTIONS_EXIST : BOOLEAN;
  7146. TASK_MESSAGE : MESSAGE;
  7147. IP_PARAMS : SEG_ARRIVE_PARAMS;
  7148. BUFFTYPE : SIXTEEN_BITS; 
  7149. --OUTPUT : INTEGER := 0;
  7150. OUTPUT : FILE_TYPE;
  7151. REASSEMBLY_TABLE_ELEMENT : 
  7152.     REASSEMBLY_UTILITIES.REASSEMBLY_TABLE_POINTER;
  7153.     
  7154. function ADDRESS_FOR_ME(ADDRESS : THIRTYTWO_BITS ) return BOOLEAN is
  7155.  
  7156. RESULT : BOOLEAN := FALSE;
  7157.  
  7158. begin
  7159.  for I in 1..MAX_HOSTS loop
  7160.   if ADDRESS = THIRTYTWO_BITS( MY_IP_ADDRESS(I)) then
  7161.    RESULT := TRUE;
  7162.   end if;
  7163.  end loop;
  7164.  return RESULT;
  7165. end ADDRESS_FOR_ME;
  7166.  
  7167. function ADDRESS_LEGAL(X : THIRTYTWO_BITS ) return BOOLEAN is
  7168.  
  7169.     --This function searches a table in the IP global package for 
  7170.     --the address.  All legal addresses are in there.  If the 
  7171.     --address is correct a value of true is returned false 
  7172.     --otherwise.
  7173.  
  7174. RESULT : BOOLEAN := FALSE;
  7175. I : SIXTEEN_BITS  := 1;
  7176.  
  7177. begin
  7178.  while I <= NUMBER_OF_ADDRESSES and (not RESULT) loop
  7179.   if X = VALID_ADDRESS_LIST(I) then
  7180.    RESULT := TRUE;
  7181.   end if;
  7182.   I := I + 1;
  7183.  end loop;
  7184.  return RESULT;
  7185. exception
  7186.  when CONSTRAINT_ERROR =>
  7187.   PUT_LINE("CONSTRAINT ERROR IN THE ADDRESS CHECKER");
  7188. --TEL  INTEGER_IO.PUT(I);
  7189.   INT_IO.PUT(I);
  7190.  when others =>
  7191.   PUT_LINE("UNKNOWN ERROR IN THE ADDRESS CHECKER");
  7192. end ADDRESS_LEGAL;
  7193.  
  7194. begin
  7195.  -- IP_LENGTH_IN_OCTETS := BUFPTR.IHL * 4;
  7196.  -- IT WILL WORK FOR HIGH BET SET IN A BYTE.
  7197.  IP_LENGTH_IN_OCTETS := SIXTEEN_BITS ( PACKED_BUFF.BYTE(PACKED_BUFF.IP_PTR) 
  7198.             MOD 16)    * 4; -- LOW 4 BITS. * 4 BYTES PER 32 BITS.
  7199.  -- NOTE UPPER BOUND MUST BE MOVED LATER.
  7200.  if IP_LENGTH_IN_OCTETS >= 20 AND (IP_LENGTH_IN_OCTETS <= 60) 
  7201.                     then -- OK 
  7202.   HEADER_CHECKSUM := CHECKSUM(PACKED_BUFF.IP_PTR, 
  7203.             IP_LENGTH_IN_OCTETS, PACKED_BUFF);
  7204.   BUF_CSUM(1) := PACKED_BUFF.BYTE(PACKED_BUFF.IP_PTR+10); 
  7205.                         -- FIRST BYTE OF CSUM
  7206.   BUF_CSUM(2) := PACKED_BUFF.BYTE(PACKED_BUFF.IP_PTR+11); 
  7207.                         -- LOW BYTE OF CSUM
  7208.   CARRIED_CSUM := CONVERT_TO_INTEGER(BUF_CSUM);
  7209.  else --ERROR
  7210.   PUT_LINE("BAD IP LENGTH");
  7211.   HEADER_CHECKSUM := 0;
  7212.   CARRIED_CSUM(1) := 4;
  7213.  end if;
  7214.  BUFPTR := IP_UNPACK_AND_PACK_UTILITIES.UNPACK(PACKED_BUFF); -- UNPACK IT.
  7215.  if HEADER_CHECKSUM = CARRIED_CSUM(1) then
  7216.   BUFPTR := IP_UNPACK_AND_PACK_UTILITIES.UNPACK(PACKED_BUFF); -- UNPACK IT.
  7217.   -- SET OPTIONS EXIST FLAG.
  7218.   -- TESTING
  7219.   -- FOR VAX TESTING *****************
  7220. --            PRINT_DATAGRAM_FLAG := 0;
  7221. --            if PRINT_DATAGRAM_FLAG = 0 then
  7222. --                PUT_LINE("GOT A BUFFER FROM THE SUBNET");
  7223. --                                PUT("DESTINATION := ");
  7224. --                LONG_INTEGER_IO.PUT( BUFPTR.DEST);
  7225. --                                NEW_LINE;
  7226. --                                PUT("VERSION := ");
  7227. --                INTEGER_IO.PUT(BUFPTR.VERSION);
  7228. --                                NEW_LINE;
  7229. --                                PUT("IHL := ");
  7230. --                INTEGER_IO.PUT(BUFPTR.IHL);
  7231. --                                NEW_LINE;
  7232. --                                PUT("TOS := ");
  7233. --                INTEGER_IO.PUT(BUFPTR.TOS);
  7234. --                                NEW_LINE;
  7235. --                                PUT("TOT_LEN := ");
  7236. --                INTEGER_IO.PUT(BUFPTR.TOT_LEN);
  7237. --                                NEW_LINE;
  7238. --                                PUT("ID := ");
  7239. --                INTEGER_IO.PUT(BUFPTR.ID);
  7240. --                                NEW_LINE;
  7241. --                                PUT("FLAGS :=");
  7242. --                INTEGER_IO.PUT(BUFPTR.FLAGS);
  7243. --                NEW_LINE;
  7244. --                                PUT("FRAG_OFFSET := ");
  7245. --                INTEGER_IO.PUT(BUFPTR.FRAG_OFFSET);
  7246. --                                NEW_LINE;
  7247. --                                PUT("TTL := ");
  7248. --                INTEGER_IO.PUT(BUFPTR.TTL);
  7249. --                                NEW_LINE;
  7250. --                                PUT("PROTOCOL := ");
  7251. --                INTEGER_IO.PUT(BUFPTR.PROT);
  7252. --                                NEW_LINE;
  7253. --                                PUT("IP CHECKSUM := ");
  7254. --                INTEGER_IO.PUT(BUFPTR.IPCSUM);
  7255. --                                NEW_LINE;
  7256. --                                PUT("SOURCE := ");
  7257. --                LONG_INTEGER_IO.PUT(BUFPTR.SOURCE);
  7258. --                NEW_LINE;
  7259. --                PUT(" THE OPTION DATA IS");
  7260. --                NEW_LINE;
  7261. --                for I in 1..(BUFPTR.IHL - 5) * 4 loop
  7262. --                    X := BUFPTR.IP_OPTIONS(I);
  7263. --                    INTEGER_IO.PUT(X);
  7264. --                end loop;
  7265. --                -- provide for separation in output file
  7266. --                NEW_LINE;
  7267. --                NEW_LINE;
  7268. --            end if; -- TEST PRINTER
  7269.   OPTIONS_EXIST := BUFPTR.IP_OPTIONS(1) /= 0;
  7270.   if ADDRESS_LEGAL(BUFPTR.DEST) and 
  7271.    ADDRESS_LEGAL(BUFPTR.SOURCE) then
  7272.    if ADDRESS_FOR_ME(BUFPTR.DEST)  then    -- IT'S FOR ME.
  7273.     if BUFPTR.TTL > 0 then -- WE CAN PROCESS IT.
  7274.      -- ONLY IF WE ARE PASSING IT ON WHICH WE 
  7275.      --CURRENTLY DO NOT.
  7276.      --/ DECREMENT TTL BY THE TIME IT TAKES TO 
  7277.      --DO INTERNET PROCESSING /***
  7278.      -- DO ALL NECESSARY OPTION CHECKING
  7279.      while OPTIONS_EXIST loop
  7280.       case BUFPTR.IP_OPTIONS(I) is
  7281.        -- THE OPTION TYPE IS?
  7282.        when 0 => OPTIONS_EXIST := FALSE;
  7283.        when 1 => I := I + 1; -- A NO OPERATION.
  7284.        when 130 => 
  7285.         -- SECURITY, COMPARTMENTS, HANDLING 
  7286.         --RESTRICTIONS, AND
  7287.         -- TRANSMISSION CONTROL CODE OPTION.
  7288.         if BUFPTR.IP_OPTIONS(I + 1) = 11 and 
  7289.           (BUFPTR.IP_OPTIONS(I + 2) <= 7) and
  7290.           (BUFPTR.IP_OPTIONS(I + 3) <= 7) and 
  7291.           (BUFPTR.IP_OPTIONS(I + 2) >= 0) and
  7292.           (BUFPTR.IP_OPTIONS(I + 3) >= 0) and 
  7293.           (BUFPTR.IP_OPTIONS(I + 4) = 0)  and
  7294.           (BUFPTR.IP_OPTIONS(I + 5) = 0)  and
  7295.           (BUFPTR.IP_OPTIONS(I + 2) = 
  7296.           BUFPTR.IP_OPTIONS(I + 3)) then
  7297.          -- WE ARE OK. A GOOD OPTION
  7298.          -- SET UP SECURITY OPTION FOR TCP.
  7299.          for INDEX in I+2..I+10 loop
  7300.           SECURITY_OPTION(INDEX - I - 1) := 
  7301.             BUFPTR.IP_OPTIONS(INDEX);
  7302.          end loop;
  7303.          I := I + 11;
  7304.         else
  7305.          BAD_OPTION := TRUE;
  7306.          OPTIONS_EXIST := FALSE;
  7307.         end if;
  7308.        when 131 => -- LOOSE SOURCE AND RECORD 
  7309.                    -- ROUTE FROM THE SOURCE
  7310.                   -- ONLY FOR GATEWAYS OR RELAYS 
  7311.                -- AND WE ARE CURRENTLY NOT ONE.
  7312.         I := I + BUFPTR.IP_OPTIONS(I + 1);
  7313.        when 137 => -- STRICT SOURCE AND RECORD 
  7314.                 -- ROUTE. INFORMATION TO BE
  7315.                -- USED BY GATEWAYS AND TO 
  7316.                -- RECORD THE ROUTE INFORMATION
  7317.                -- WE ARE NOT A GATEWAY NOR DO 
  7318.                -- WE PASS STUFF ON.
  7319.         I := I + BUFPTR.IP_OPTIONS(I + 1);
  7320.        when 7  => -- SAVE THE RETURN ROUTE, 
  7321.               -- UNNECESSARY IF NOT A RELAY.
  7322.               -- PUT OUR ADDRESS IN AT PROPER 
  7323.               -- POINT. MOVE OTHER DATA 
  7324.               -- BEHIND ADDRESS TO ENABLE IT 
  7325.               -- TO BE PUT IN. IF THIS
  7326.               -- FORCES TO USE PART OF A 32 
  7327.               -- BIT FIELD THEN DO ANY
  7328.               -- PADDING NECESSARY.
  7329.         I := I + BUFPTR.IP_OPTIONS(I + 1);
  7330.        when 136 =>  -- STREAM IDENTIFIER
  7331.                 -- ACTION TBD.
  7332.         I := I + 4;
  7333.        when 68  => -- INTERNET TIMESTAMP
  7334.                -- ACTION TBD.
  7335.         I := I + BUFPTR.IP_OPTIONS(I + 1);
  7336.        when others => BAD_OPTION := TRUE;
  7337.               OPTIONS_EXIST := FALSE;
  7338.       end case;
  7339.      end loop;
  7340.      if not BAD_OPTION then
  7341.       if DESTINATION_FAKE_HOST then
  7342.        -- /PUT IN FAKE HOST QUEUE/
  7343.        null;
  7344.       else
  7345.        -- HERE WE GIVE THE DATAGRAM TO THE TO TCP 
  7346.        -- QUEUE TASK. THIS NOTIFIES
  7347.        -- THE TCP OF A DATAGRAM AS PER THE SPEC. 
  7348.        -- TCP TAKING IT OUT OF THE
  7349.        -- QUEUE IS DOING AN IMPLICIT CALL ON THE 
  7350.        -- IP. THE NECESSARY PARAMETERS
  7351.        -- WILL BE IN THE QUEUE RECORD.
  7352.        -- ALL REQUIRED FIELDS ARE IN THE BUFFER 
  7353.        -- EXCEPT FOR THE LENGTH WHICH
  7354.        -- IS EXPLICITLY RETURNED.
  7355.        -- SET THE BYTE COUNT. THIS IS THE TCP 
  7356.        -- LENGTH IN OCTETS.
  7357.        BYTE_COUNT := BUFPTR.TOT_LEN - (BUFPTR.IHL * 4);
  7358. --                if PRINT_FLAG /= 0 then
  7359. --                 PUT_LINE("THE POINTER FOR THE BUFFER TO TCP");
  7360. --                 INTEGER_IO.PUT(PACKED_BUFF.TCP_PTR);
  7361. --                end if;
  7362.        if BUFPTR.PROT =1 then
  7363.         UTILITIES_FOR_ICMP.ICMP_MESSAGE_PROCESSOR(PACKED_BUFF,BUFPTR);
  7364.        end if;
  7365.        if REASSEMBLY_UTILITIES.A_FRAG(PACKED_BUFF,BUFPTR) = 
  7366.                                          REASSEMBLY_UTILITIES.NO 
  7367.          then
  7368.         IP_PARAMS := ( PACKED_BUFF, 
  7369.                        BYTE_COUNT, 
  7370.                        BUFPTR.SOURCE, 
  7371.                        BUFPTR.DEST, 
  7372.                        BUFPTR.PROT, 
  7373.                        BUFPTR.TOS, 
  7374.                        SECURITY_OPTION);
  7375.         TASK_MESSAGE := (DATA_FROM_IP, IP_PARAMS);
  7376.         TCP_Q.Q_ADD( TASK_MESSAGE );--SEND TO THE TCP
  7377.        else
  7378.         REASSEMBLY_UTILITIES.REASSEMBLY
  7379.                 (PACKED_BUFF,REASSEMBLY_TABLE_ELEMENT,BUFPTR);
  7380.         if REASSEMBLY_UTILITIES.REASS_DONE(REASSEMBLY_TABLE_ELEMENT,BUFPTR) = 
  7381.                 REASSEMBLY_UTILITIES.YES then
  7382.          IP_PARAMS := ( PACKED_BUFF, 
  7383.                         BYTE_COUNT, 
  7384.                         BUFPTR.SOURCE, 
  7385.                         BUFPTR.DEST, 
  7386.                 BUFPTR.PROT, 
  7387.                         BUFPTR.TOS, 
  7388.                         SECURITY_OPTION);
  7389.          TASK_MESSAGE := (DATA_FROM_IP, IP_PARAMS);
  7390.           --SEND TO THE TCP.
  7391.          TCP_Q.Q_ADD( TASK_MESSAGE );--SEND TO THE TCP
  7392.         end if;
  7393.        end if;
  7394.       end if;
  7395.      else
  7396.       --/ERROR EXIT: ILLEGAL OPTION/
  7397.       -- DELETE DATAGRAM
  7398.       PUT("BAD OPTION");--**TESTING
  7399.       BUFFREE(PACKED_BUFF, BUFFTYPE);
  7400.      end if;
  7401.     else
  7402.      -- WE HAVE TIMED OUT SO DROP THE DATAGRAM.
  7403.      BUFFREE(PACKED_BUFF, BUFFTYPE);
  7404.     end if;
  7405.    else
  7406.     -- /ERROR EXIT: NOT FOR ME/ 
  7407.     -- DELETE DATAGRAM
  7408.     BUFFREE(PACKED_BUFF, BUFFTYPE);
  7409.    end if;
  7410.   else
  7411.    -- / ERROR: ILLEGAL DESTINATION/
  7412.    BUFFREE(PACKED_BUFF, BUFFTYPE);
  7413.   end if;
  7414.  else 
  7415.   -- BAD CHECKSUM. COUNT IT AND GET OUT
  7416.   BAD_CHECKSUM := BAD_CHECKSUM + 1;
  7417.   BUFFREE(PACKED_BUFF, BUFFTYPE);
  7418.  end if;
  7419. exception
  7420.     when CONSTRAINT_ERROR =>
  7421.         PUT_LINE("CONSTRAINT ERROR IN IPARRIVE");
  7422. --TEL        INTEGER_IO.PUT(I);
  7423.         INT_IO.PUT(I);
  7424.     when others =>
  7425.         PUT_LINE("ERROR IN IPARRIVE");---DEBUG
  7426.         raise;
  7427. end IP_DATAGRAM_ARRIVE;
  7428.  
  7429. END IP_ARRIVE_PROCESSING; -- PACKAGE
  7430. --::::::::::::::
  7431. --segarrive_.ada
  7432. --::::::::::::::
  7433. -----------------------------------------------------------------------
  7434. --
  7435. --         DoD Protocols    NA-00001-200       80-01008-100(-)
  7436. --         E-Systems, Inc.  August 07, 1985
  7437. --
  7438. --         SEGARRIVE_.ADA       Author : Jim Baldo
  7439. --
  7440. -----------------------------------------------------------------------
  7441. with WITH_TCP_COMMUNICATE;        use WITH_TCP_COMMUNICATE;
  7442. with BUFFER_DATA;            use BUFFER_DATA;
  7443. --with T_TCP_GLOBALS_DATA_STRUCTURES;    use T_TCP_GLOBALS_DATA_STRUCTURES;
  7444.  
  7445.         package    TCP_SEGMENT_ARRIVES_PROCESSING is
  7446.  
  7447.     -------------------------------------------------------------
  7448.     --This implementation is for use with the DEC/Ada          --
  7449.     --compiler .                                               --
  7450.     -------------------------------------------------------------
  7451.  
  7452. -------------------------------------------------------------------------------
  7453. -- THIS    PACKAGE    CONTAINS ALL THE PROCEDURES AND    FUNCTIONS NECESSARY FOR      --
  7454. -- PROCESSING ARRIVED SEGMENTS.    IT ALSO    CONTAINS THE HEADER FORMAT ROUTINE.  --
  7455. -------------------------------------------------------------------------------
  7456.  
  7457. procedure TCP_SEG_ARRIVE( PACKED_BUFFER    : in out PACKED_BUFFER_PTR; 
  7458.                       BYTE_COUNT : in SIXTEEN_BITS ;
  7459.                       SOURCE_FROM_IP, DEST : in THIRTYTWO_BITS ; 
  7460.                       PROT, TOS_IP : in SIXTEEN_BITS ;
  7461.                       SECURITY_OP : in SECURITY_OPTION_TYPE);
  7462.  
  7463.     --This procedure will take a segment and determine what LCN, if any it
  7464.     --belongs to. It will check if it is a valid segment in terms of 
  7465.     --sequence number and if the checksum is valid.  It will also determine
  7466.     --that the address is for us.  If so it will cause the required 
  7467.     --processing for the state to be done, by calling the proper routine.
  7468.  
  7469. end TCP_SEGMENT_ARRIVES_PROCESSING;
  7470.  
  7471. --::::::::::::::
  7472. --segarrive.ada
  7473. --::::::::::::::
  7474. -----------------------------------------------------------------------
  7475. --
  7476. --         DoD Protocols    NA-00001-200       80-01009-100(-)
  7477. --         E-Systems, Inc.  August 07, 1985
  7478. --
  7479. --         SEGARRIVE.ADA       Author : Jim Baldo
  7480. --
  7481. -----------------------------------------------------------------------
  7482. with T_TCP_GLOBALS_DATA_STRUCTURES;    use T_TCP_GLOBALS_DATA_STRUCTURES;
  7483. with QUEUES;                use QUEUES;
  7484. with TCP_GLOBALS;            use TCP_GLOBALS;
  7485. with IP_GLOBALS ;            use IP_GLOBALS ;
  7486. with IP_TCP ;                use IP_TCP ;
  7487. with TCP_TO_ULP_COMMUNICATE ;        use TCP_TO_ULP_COMMUNICATE ;
  7488. with TEXT_IO;                use TEXT_IO;
  7489. with TCP_ARRIVES_PERIPHERALS;        use TCP_ARRIVES_PERIPHERALS;
  7490. with MODULO;                use MODULO;
  7491. with TCB_ALLOCATOR;            use TCB_ALLOCATOR;
  7492.  
  7493.     package    body TCP_SEGMENT_ARRIVES_PROCESSING is
  7494.  
  7495. package INT_IO_16 is new INTEGER_IO ( SIXTEEN_BITS ) ;
  7496. package INT_IO_32 is new INTEGER_IO ( THIRTYTWO_BITS ) ;
  7497.  
  7498. procedure SEG_ARRIVED_IN_CLOSED_STATE( BUFPTR : in out 
  7499.                                        T_TCP_GLOBALS_DATA_STRUCTURES.
  7500.                                           BUFFER_POINTER;
  7501.                        BYTE_COUNT : in SIXTEEN_BITS ; 
  7502.                                        SOURCE, DESTINATION : 
  7503.                                         in THIRTYTWO_BITS ) is
  7504. --   THIS PROCEDURE IS CALLED BY THE SEGMENT ARRIVED CONTROLLER    WHEN A SEGMENT
  7505. --   ARRIVES WITH NO CONNECTION    AT ATTEMPT BY THE USER (I.E. THE CLOSED    STATE).
  7506. -- PROCESSING :
  7507. --
  7508. --   THIS PROCEDURE WILL IGNORE    A RESET    FROM THE REMOTE    HOST. IF THE SEGMENT
  7509. --   IS    NOT A RESET THEN A RESET WILL BE FORMED    AND SENT TO THE    REMOTE HOST.
  7510. --
  7511. BUFFTYPE : SIXTEEN_BITS ;
  7512. BEGIN
  7513. IF BUFPTR.RST =    BIT_SET     THEN -- THE SEGMENT IS    A RESET, IGNORE    IT.
  7514.   -- RELEASE BUFFER
  7515.  GLOBAL_PACKED_BUFFER.IN_USE := FALSE;
  7516.  GLOBAL_PACKED_BUFFER.STATUS := NONE;
  7517.  BUFFREE(GLOBAL_PACKED_BUFFER, BUFFTYPE);
  7518. ELSE --    SEND A RESET
  7519. -- USE THE SAME    BUFFER
  7520. -- SET UP THE RESERVE TCB (NUMBER 5)
  7521.   RESERVE.RCV_NXT := BUFPTR.ACK_NUM;
  7522.   RESERVE.SND_NXT := BUFPTR.SEQ_NUM;
  7523.   RESERVE.SOURCE_ADDRESS := DESTINATION;
  7524.   RESERVE.DESTINATION_ADDRESS := SOURCE;
  7525.   RESERVE.LOCAL_PORT := BUFPTR.DESTINATION_PORT;
  7526.   RESERVE.FOREIGN_PORT := BUFPTR.SOURCE_PORT;
  7527.   IF  BUFPTR.ACK = BIT_SET THEN    -- ACK BIT IS    ON.
  7528. -- SEND    A RESET    OF THE FORM <SEQ=SEG.ACK> <CTL=RST>
  7529.     RESERVE.SND_NXT := BUFPTR.ACK_NUM;
  7530.     SEND_A_RESET(RESERVE);
  7531.   ELSE
  7532.   -- SEND A RESET OF THE FORM <SEQ=0> <ACK=SEG.SEQ+SEG.LEN> <CTL=RST,ACK>
  7533.     RESERVE.SND_NXT := MODULAR_CONVERT(SIXTEEN_BITS(0));
  7534.     RESERVE.RCV_NXT := BUFPTR.SEQ_NUM + BYTE_COUNT - (BUFPTR.DATA_OFFSET *
  7535.                                     4);
  7536.                     -- BYTE_COUNT IS OF DATA AND HEADER
  7537.     SEND_A_RESET_AND_ACK(RESERVE);
  7538.   END IF;
  7539. END IF;
  7540. END SEG_ARRIVED_IN_CLOSED_STATE;
  7541.  
  7542. procedure SEG_ARRIVED_IN_LISTEN_STATE( BUFPTR : in out T_TCP_GLOBALS_DATA_STRUCTURES.
  7543.                                                 BUFFER_POINTER;
  7544.                        BYTE_COUNT : in SIXTEEN_BITS ; 
  7545.                                        SOURCE : in THIRTYTWO_BITS ) is
  7546. --   THIS PROCEDURE IS CALLED BY THE SEGMENT ARRIVE CONTROLLER WHEN A SEGMENT
  7547. --   HAS ARRIVED WITH THE TCB IN THE LISTEN STATE. IT PERFORMS THE NECESSARY
  7548. --   PROCESSING.
  7549. BUFFTYPE : SIXTEEN_BITS ;
  7550. Q_ITEM : STD_Q_ITEM;
  7551. BEGIN
  7552. IF BUFPTR.RST =    0 THEN -- RESET    BIT NOT    SET SO GO ON.
  7553.   IF BUFPTR.ACK    = BIT_SET THEN -- SEND A RESET
  7554.     RESERVE := LCN;
  7555.     RESERVE.SND_NXT := BUFPTR.ACK_NUM;
  7556.     SEND_A_RESET(RESERVE);
  7557.   ELSIF    BUFPTR.SYN = BIT_SET THEN
  7558.     IF LCN.SECURITY /= SECURITY OR    LCN.PRECEDENCE /= IP_TOS/2**5 THEN
  7559.       -- SET UP    THE TCB
  7560.       RESERVE := LCN;
  7561.       RESERVE.SND_NXT := BUFPTR.ACK_NUM;
  7562.       SEND_A_RESET(RESERVE);
  7563.     ELSE
  7564.       IF FOREIGN_SOCKET_UNSPECIFIED(LCN) THEN  -- FILL IN REMOTE HOST PARAMETERS
  7565.     LCN.FOREIGN_PORT := BUFPTR.SOURCE_PORT;
  7566.     LCN.DESTINATION_ADDRESS :=    SOURCE;
  7567.     -- DECODE THE NET AND HOST ADDRESSES AND PUT THEM IN THE TCB
  7568.         ADDRESS_DECODER(SOURCE);
  7569.       END IF;
  7570.       IF LCN.DESTINATION_ADDRESS =    SOURCE THEN -- IT MATCHES OUR
  7571.                              -- UNSPECIFIED    OR
  7572.                              -- SPECIFIED LISTEN.
  7573.         -- START THE CONNECTION TIMEOUT TIMER
  7574.         START_TIMER(LCN, TIMEOUT_TIMER);
  7575.     LCN.RCV_NXT := BUFPTR.SEQ_NUM + MODULAR_CONVERT(SIXTEEN_BITS(1));
  7576.     LCN.INIT_RCV_SEQ_NUM := BUFPTR.SEQ_NUM;
  7577.         LCN.SND_WND := BUFPTR.WINDOW;
  7578.         LCN.SND_WL1 := BUFPTR.SEQ_NUM;
  7579.         -- ACK NUMBER HERE IS MEANINGLESS. WE MIGHT ISS - 1 IN THERE.
  7580.     -- PUT ANY OTHER TEXT OR CONTROLS ON THE RECEIVE QUEUE FOR
  7581.     --  PROCESSING IN THE ESTABLISHED STATE.
  7582.     IF BYTE_COUNT > BUFPTR.DATA_OFFSET * 4   -- THEN DATA EXISTS.
  7583.            OR (BUFPTR.RST = BIT_SET) OR (BUFPTR.FIN = BIT_SET)   THEN
  7584.           -- RESET FIELDS.
  7585.       BUFPTR.ACK := 0;
  7586.           BUFPTR.SYN := 0;
  7587.       Q_ITEM := (NULL_BUFFER, BUFPTR, BYTE_COUNT);
  7588.       QUEUE_ADD(TCP_RECEIVED_SEGMENT_QUEUE, LCN, Q_ITEM); -- QUEUE IT
  7589.         END IF;
  7590.     -- GET INITIAL SEND SEQUENCE NUMBER (ISS)
  7591.         LCN.ISS := MODULAR_CONVERT(ISS);
  7592.     LCN.SND_NXT := LCN.ISS;
  7593. -- SET UP ACK SECTION OF WINDOWS.
  7594.         LCN.SND_WL2 := LCN.ISS;
  7595.     LCN.SND_UNA := LCN.SND_NXT;
  7596.     SEND_A_SYN_AND_ACK(LCN);
  7597.     LCN.STATE := SYN_RECEIVED;
  7598.       ELSE -- THE SEGMENT IS NOT THE ONE WE WANT SO IGNOR IT??
  7599.     TCP_ERROR(12);
  7600.       END IF;
  7601.     END    IF;
  7602.   END IF;
  7603. END IF;
  7604. -- RELEASE BUFFER
  7605. --PUT_LINE("BUFFREE SEG_ARRIVED_IN_LISTEN_STATE");-- DEBUG JB 7/3/85
  7606. GLOBAL_PACKED_BUFFER.IN_USE := FALSE;
  7607. GLOBAL_PACKED_BUFFER.STATUS := NONE;
  7608. BUFFREE(GLOBAL_PACKED_BUFFER, BUFFTYPE);
  7609. EXCEPTION
  7610.  WHEN OTHERS =>
  7611.     PUT_LINE(" AN ERROR HAS OCCURRED IN THE LISTEN STATE");
  7612. end SEG_ARRIVED_IN_LISTEN_STATE;
  7613.  
  7614. procedure SEG_ARRIVED_IN_SYN_SENT_STATE( BUFPTR : in out 
  7615.                           T_TCP_GLOBALS_DATA_STRUCTURES.BUFFER_POINTER;
  7616.                      BYTE_COUNT : in SIXTEEN_BITS ) is
  7617.  
  7618.     --THIS PROCEDURE IS CALLED BY THE SEGMENT ARRIVED CONTROLLER WHEN A 
  7619.     --SEGMENT ARRIVES IN THE SYN_SENT STATE. IT PROCESSES ACCORDING TO 
  7620.     --THE SPEC.
  7621.     --
  7622.     -- PROCESSING :
  7623.     --
  7624.     --THIS PROCEDURE IS RESPONSIBLE FOR THE PROCESSING OF A SEGMENT IN 
  7625.     --THE SYN_SENT STATE ACCORDING TO THE TCP SPECIFICATION.
  7626.  
  7627. BUFFTYPE : SIXTEEN_BITS ;
  7628. UMESSAGE : USER_MESSAGE;
  7629. NULL_Q_ITEM : STD_Q_ITEM := (NULL, NULL_UNPACKED_BUFFER, 0);
  7630. Q_ITEM : STD_Q_ITEM;
  7631. SOCKET_PARAMS : LCN_PTR_TYPE;
  7632.  
  7633. begin
  7634. if BUFPTR.ACK =    BIT_SET    and then ((BUFPTR.ACK_NUM <= LCN.ISS) OR 
  7635.      (BUFPTR.ACK_NUM > LCN.SND_NXT)) then
  7636.     LCN.SND_NXT :=    BUFPTR.ACK_NUM;
  7637.     SEND_A_RESET(LCN);
  7638. elsif BUFPTR.RST = BIT_SET then
  7639.   if BUFPTR.ACK    = BIT_SET then
  7640.     -- TELL USER
  7641.     -- ERROR: CONNECTION RESET
  7642.     SOCKET_PARAMS.LCN := LCN;
  7643.     SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  7644.     SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  7645.     UMESSAGE := ( 6,
  7646.                   SOCKET_PARAMS);
  7647.     MESSAGE_FOR_USER(UMESSAGE);
  7648.     -- MAY HAVE    TO ZERO    TCB
  7649.     LCN.STATE := CLOSED;
  7650.     TCB_CLEAR(LCN);
  7651.   end if;
  7652. elsif LCN.SECURITY /= SECURITY then
  7653.   -- SEND A RESET
  7654.   if BUFPTR.ACK    = BIT_SET then 
  7655.   -- USE RESERVE TCB FOR VALUES OF RESET TO BE SENT
  7656.     RESERVE := LCN;
  7657.     RESERVE.SND_NXT := BUFPTR.ACK_NUM;
  7658.     SEND_A_RESET(RESERVE);
  7659.   else
  7660.     -- USE RESERVE TCB FOR VALUES OF RESET TO BE SENT
  7661.     RESERVE := LCN;
  7662.     RESERVE.SND_NXT := MODULAR_CONVERT(SIXTEEN_BITS(0));
  7663.     RESERVE.RCV_NXT := BUFPTR.SEQ_NUM + BYTE_COUNT - (BUFPTR.DATA_OFFSET *
  7664.                                     4);
  7665.     SEND_A_RESET_AND_ACK(RESERVE);
  7666.   end if;
  7667. elsif LCN.PRECEDENCE /= IP_TOS/2**5 then
  7668. --    new_line;--for debug(JB 2/17/85)
  7669. --    put_line("PRECEDENCE");
  7670. --    new_line;
  7671.   if BUFPTR.ACK    = BIT_SET then 
  7672.   -- USE RESERVE TCB FOR VALUES OF RESET TO BE SENT
  7673.     RESERVE := LCN;
  7674.     RESERVE.SND_NXT := BUFPTR.ACK_NUM;
  7675.     SEND_A_RESET(RESERVE);
  7676.   elsif    IP_TOS/2**5 > LCN.PRECEDENCE then 
  7677.   -- HERE WE COULD RAISE THE TCB PRECEDENCE BUT WE WILL NOT CURRENTLY
  7678.   -- USE RESERVE TCB FOR VALUES OF RESET TO BE SENT
  7679.     RESERVE := LCN;
  7680.     RESERVE.SND_NXT := MODULAR_CONVERT(SIXTEEN_BITS(0));
  7681.     RESERVE.RCV_NXT := BUFPTR.SEQ_NUM + BYTE_COUNT - (BUFPTR.DATA_OFFSET *
  7682.                                     4);
  7683.     SEND_A_RESET_AND_ACK(RESERVE);
  7684.   end if;
  7685. elsif BUFPTR.SYN = BIT_SET then
  7686. --    new_line;--for debug(JB 2/17/85)
  7687. --    put_line("SYN = BIT_SET");
  7688. --    new_line;
  7689.   LCN.RCV_NXT := BUFPTR.SEQ_NUM + MODULAR_CONVERT(SIXTEEN_BITS(1));
  7690.   LCN.INIT_RCV_SEQ_NUM := BUFPTR.SEQ_NUM;
  7691. -- SET UP OUR SEND WINDOW MECHANISM IN THE TCB.
  7692.   LCN.SND_WND := BUFPTR.WINDOW;
  7693.   LCN.SND_WL1 := BUFPTR.SEQ_NUM;
  7694.   LCN.SND_WL2 := LCN.ISS;
  7695.   if BUFPTR.ACK    = BIT_SET then
  7696.    new_line;
  7697.    put_line("delete from retrans queue");
  7698.    new_line;
  7699.    LCN.SND_UNA := BUFPTR.ACK_NUM;
  7700.    -- REMOVE ALL ACKED SEGMENTS FROM THE RETRANSMISSION QUEUE
  7701.    DELETE_FROM_RETRANS_QUEUE(LCN, LCN.SND_UNA);
  7702.    -- CHANGE THE ACK NUMBER OF LAST SEG USED TO UPDATE THE WINDOW.
  7703.    LCN.SND_WL2 := BUFPTR.ACK_NUM;
  7704.   end if;
  7705.   if LCN.SND_UNA >    LCN.ISS then
  7706.     SEND_A_PIGGYBACKED_ACK(LCN);
  7707.     LCN.STATE := ESTABLISHED;
  7708.     -- TELL THE USER.
  7709.     SOCKET_PARAMS.LCN := LCN;
  7710.     SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  7711.     SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  7712.     UMESSAGE := ( 23,
  7713.                   SOCKET_PARAMS);
  7714.     MESSAGE_FOR_USER(UMESSAGE);
  7715.     -- HERE WE PROCESS ANY OTHER TEXT AND CONTROLS
  7716.     ENTER_ESTABLISHED_STATE_PROCESSING(LCN, BUFPTR);
  7717.   ELSE
  7718.     --    QUEUE ANY OTHER    TEXT OR    CONTROLS FOR LATER PROCESSING
  7719.     new_line;--for debug(JB 2/17/85)
  7720.     put_line("queue any other text or controls");
  7721.     new_line;
  7722.     IF BYTE_COUNT > BUFPTR.DATA_OFFSET * 4   -- THEN TEXT EXISTS    
  7723.        OR (BUFPTR.FIN = BIT_SET)   THEN
  7724.       -- CLEAR PREVIOUSLY PROCESSED FLAGS
  7725.       BUFPTR.ACK := 0;
  7726.       BUFPTR.SYN := 0;
  7727.       Q_ITEM := (NULL_BUFFER, BUFPTR, BYTE_COUNT);
  7728.       QUEUE_ADD(TCP_RECEIVED_SEGMENT_QUEUE, LCN, Q_ITEM);
  7729.     END IF;
  7730.     -- SEND A SYN, ACK
  7731.     -- THE SEQUENCE NUMBER MUST    BE ISS.
  7732.     LCN.SND_NXT :=    LCN.ISS;
  7733.     LCN.STATE := SYN_RECEIVED;
  7734.     SEND_A_SYN_AND_ACK(LCN);
  7735.   END IF;
  7736. end if;
  7737. -- RELEASE BUFFER
  7738. --PUT_LINE("BUFFREE SEGARRIVED_IN_SYN_SENT_STATE"); --DEBUG JB 7/3/85
  7739. GLOBAL_PACKED_BUFFER.IN_USE := FALSE;
  7740. GLOBAL_PACKED_BUFFER.STATUS := NONE;
  7741. BUFFREE(GLOBAL_PACKED_BUFFER, BUFFTYPE);
  7742. EXCEPTION
  7743. WHEN CONSTRAINT_ERROR =>
  7744.  PUT_LINE("CONSTRAINT ERROR IN SYN SENT STATE");  
  7745. WHEN OTHERS =>
  7746.  PUT_LINE("ERROR IN SYN SENT STATE");
  7747. end SEG_ARRIVED_IN_SYN_SENT_STATE;
  7748.  
  7749. procedure SEG_ARRIVED_IN_SYN_RECEIVED_STATE( BUFPTR : in out 
  7750.                                    T_TCP_GLOBALS_DATA_STRUCTURES.BUFFER_POINTER;
  7751.                              BYTE_COUNT : in SIXTEEN_BITS ) is
  7752.  
  7753. --   THIS PROCEDURE IS CALLED BY THE SEGMENT ARRIVE PROCESSOR WHEN A SEGMENT
  7754. --   ARRIVES IN THE SYN RECEIVED STATE.
  7755. -- PROCESSING :
  7756. --
  7757. --   THIS PROCEDURE DOES ALL THE NECESSARY PROCESSING FOR AN ARRIVED SEGMENT
  7758. --   IN THE SYN RECEIVED STATE ACCORDING TO THE TCP SPECIFICATION.
  7759. --
  7760. UMESSAGE : USER_MESSAGE;
  7761. NULL_Q_ITEM : STD_Q_ITEM := (NULL, NULL_UNPACKED_BUFFER, 0);
  7762. SOCKET_PARAMS : LCN_PTR_TYPE;
  7763.  
  7764. BEGIN
  7765. -- THE CHECKSUM AND THE SEQUENCE NUMBER HAVE ALREADY BEEN CHECKED.
  7766. IF BUFPTR.RST = BIT_SET THEN
  7767.   IF LCN.ACTIVE_PASSIVE = T_TCP_GLOBALS_DATA_STRUCTURES.PASSIVE THEN
  7768.   -- RETURN TO THE LISTEN STATE
  7769.     LCN.STATE := T_TCP_GLOBALS_DATA_STRUCTURES.LISTEN;
  7770.   ELSE
  7771.     -- TELL USER
  7772.     -- CONNECTION REFUSED
  7773.     SOCKET_PARAMS.LCN := LCN;
  7774.     SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  7775.     SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  7776.     UMESSAGE := ( 17, 
  7777.                   SOCKET_PARAMS);
  7778.     MESSAGE_FOR_USER(UMESSAGE);
  7779.     LCN.STATE := CLOSED;
  7780.     QUEUE_CLEAR(RECEIVE_QUEUE, LCN);
  7781.     -- THERE IS NO SEND Q ON THIS LEVEL. CLEAR_SEND_QUEUE(LCN);
  7782.   END IF;
  7783.   QUEUE_CLEAR(TCP_RECEIVED_SEGMENT_QUEUE, LCN);
  7784.   QUEUE_CLEAR(TCP_RETRANSMIT_QUEUE, LCN);
  7785. ELSIF LCN.SECURITY /= SECURITY OR LCN.PRECEDENCE /= IP_TOS/2**5 THEN
  7786. -- SEND A RESET
  7787.    SEND_A_RESET(LCN);
  7788. ELSIF BUFPTR.SYN = BIT_SET THEN
  7789.    BAD_SYN_HANDLER(LCN, BUFPTR);
  7790. ELSIF BUFPTR.ACK = BIT_SET THEN
  7791.    IF (LCN.SND_UNA > BUFPTR.ACK_NUM) OR
  7792.        (BUFPTR.ACK_NUM > LCN.SND_NXT)    THEN
  7793.      -- SEND A RESET
  7794.      RESERVE.SND_NXT := BUFPTR.ACK_NUM;
  7795.      SEND_A_RESET(RESERVE);
  7796.    ELSE
  7797.      LCN.STATE := ESTABLISHED;
  7798.      -- TELL THE USER CONNECTION OPEN.
  7799.      SOCKET_PARAMS.LCN := LCN;
  7800.      SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  7801.      SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  7802.      UMESSAGE := ( 23, 
  7803.                    SOCKET_PARAMS);
  7804.      MESSAGE_FOR_USER(UMESSAGE);
  7805.      LCN.SND_UNA := BUFPTR.ACK_NUM;  -- UPDATE UNACKNOWLEDGED NUMBER
  7806.      -- REMOVE ACKNOWLEDGED DATA FROM RETRANS QUEUE.
  7807.      DELETE_FROM_RETRANS_QUEUE(LCN, LCN.SND_UNA);
  7808.      -- DO NECESSARY ESTABLISHED STATE PROCESSING 
  7809.      ENTER_ESTABLISHED_STATE_PROCESSING(LCN, BUFPTR);
  7810.    END IF;
  7811. END IF;
  7812. -- RELEASE BUFFER
  7813. --PUT_LINE("BUFFREE SEG_ARRIVED_IN_SYN_RECEIVED_STATE"); --DEBUG JB 7/3/85
  7814. GLOBAL_PACKED_BUFFER.IN_USE := FALSE;
  7815. GLOBAL_PACKED_BUFFER.STATUS := NONE;
  7816. BUFFREE(GLOBAL_PACKED_BUFFER, BUFFTYPE);
  7817. END SEG_ARRIVED_IN_SYN_RECEIVED_STATE;
  7818.  
  7819. PROCEDURE SEG_ARRIVED_IN_ESTABLISHED_STATE( BUFPTR : in out 
  7820.                                   T_TCP_GLOBALS_DATA_STRUCTURES.BUFFER_POINTER;
  7821.                             BYTE_COUNT : in SIXTEEN_BITS ) is
  7822. -- INITIAL DESCRIPTION :
  7823. -- 
  7824. --   THIS PROCEDURE IS CALLED BY THE SEGMENT ARRIVE PROCESSOR WHEN A SEGMENT
  7825. --   ARRIVES IN THE ESTABLISHED STATE. IT WILL DO ALL THE NECESSARY PROCESSING
  7826. --   AS SPECIFIED IN THE SPEC.
  7827. -- PROCESSING :
  7828. --
  7829. --   THIS PROCEDURE DOES ALL THE NECESSARY PROCESSING FOR THE ESTABLISHED STATE
  7830. --   AS SPECIFIED IN THE TCP SPEC. IT THEN RELEASES THE BUFFER THE SEGMENT IS
  7831. --   IN. IT WILL QUEUE ANY DATA FOR THE USER TO BE ACCEPTED AT THE USERS
  7832. --   CONVENIENCE.
  7833. BUFFTYPE : SIXTEEN_BITS ;
  7834. RESULT : RES;
  7835. UMESSAGE : USER_MESSAGE;
  7836. SOCKET_PARAMS : LCN_PTR_TYPE;
  7837.  
  7838. begin
  7839. IF BUFPTR.RST = BIT_SET THEN
  7840.   PROCESS_RESET_IN_DATA_ACCEPTING_STATES(LCN);
  7841. ELSIF LCN.SECURITY /= SECURITY OR LCN.PRECEDENCE /= IP_TOS/2**5 THEN
  7842. -- CLEAR THE QUEUES
  7843.   QUEUE_CLEAR(RECEIVE_QUEUE, LCN);
  7844. -- THERE IS NO SEND QUEUE ON THIS LEVEL.  CLEAR_SEND_QUEUE(LCN);
  7845.   QUEUE_CLEAR(TCP_RETRANSMIT_QUEUE, LCN);
  7846.   QUEUE_CLEAR(TCP_RECEIVED_SEGMENT_QUEUE, LCN);
  7847.   QUEUE_CLEAR(TRANSMIT_QUEUE, LCN);
  7848.   QUEUE_CLEAR(PROCESSED_SEGMENTS_FOR_USER_QUEUE, LCN);
  7849.   -- TELL USER
  7850.   -- CONNECTION RESET
  7851.   SOCKET_PARAMS.LCN := LCN;
  7852.   SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  7853.   SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  7854.   UMESSAGE := ( 16,
  7855.                 SOCKET_PARAMS);
  7856.   MESSAGE_FOR_USER(UMESSAGE);
  7857.   LCN.STATE := CLOSED;
  7858.   -- MAY HAVE TO CLEAR THE TCB HERE
  7859.   TCB_CLEAR(LCN);
  7860. ELSIF BUFPTR.SYN = BIT_SET THEN
  7861.   BAD_SYN_HANDLER(LCN, BUFPTR);
  7862. ELSIF BUFPTR.ACK = BIT_SET THEN
  7863.   PROCESS_COMMON_ACK(LCN, BUFPTR, RESULT);
  7864.   IF RESULT = GOOD THEN
  7865.     PROCESS_URGENT_FLAG(LCN, BUFPTR);
  7866.     PROCESS_SEGMENT_TEXT(LCN, BUFPTR);
  7867.     FIN_CHECK_FOR_ESTAB_OR_SYN_RECEIVED_STATES(LCN, BUFPTR);
  7868.   END IF;
  7869. ELSE
  7870.   TCP_ERROR(14); -- NO ACK BIT SET
  7871. END IF;
  7872. -- RELEASE BUFFER
  7873. --PUT_LINE("BUFFREE SEG_ARRIVED_IN_ESTABLISHED_STATE"); --DEBUG JB 7/3/85
  7874. GLOBAL_PACKED_BUFFER.IN_USE := FALSE;
  7875. GLOBAL_PACKED_BUFFER.STATUS := NONE;
  7876. BUFFREE(GLOBAL_PACKED_BUFFER, BUFFTYPE);
  7877. EXCEPTION
  7878. WHEN OTHERS =>
  7879.  PUT_LINE("ERROR IN ESTABLISHED STATE ARRIVE PROCESSING!");
  7880.  RAISE;  
  7881. END SEG_ARRIVED_IN_ESTABLISHED_STATE;
  7882.  
  7883. PROCEDURE SEG_ARRIVED_IN_FIN_WAIT_1_STATE( BUFPTR : in out 
  7884.                                   T_TCP_GLOBALS_DATA_STRUCTURES.BUFFER_POINTER;
  7885.                            BYTE_COUNT : in SIXTEEN_BITS ) is
  7886. -- INITIAL DESCRIPTION :
  7887. -- 
  7888. --   THIS PROCEDURE IS CALLED BY THE SEGMENT ARRIVED PROCESSOR TO DO ALL
  7889. --   NECESSARY PROCESSING FOR A CONNECTION IN THE FIN-WAIT-1 STATE WHEN
  7890. --   A SEGMENT ARRIVES.
  7891. -- PROCESSING :
  7892. --
  7893. --   THIS PROCEDURE WILL DO ALL NECESSARY PROCESSING FOR A SEGMENT WHICH
  7894. --   ARRIVES IN THE FIN-WAIT-1 STATE (ACCORDING TO THE SPEC). IT WILL ALSO
  7895. --   CONTINUE THE PROCESSING IN THE FIN-WAIT-2 STATE WHEN AN ACK FOR THE
  7896. --   FIN ARRIVES.
  7897. RESULT : RES;
  7898. BEGIN
  7899. IF BUFPTR.RST = BIT_SET THEN
  7900.   PROCESS_RESET_IN_DATA_ACCEPTING_STATES(LCN);
  7901. ELSIF BUFPTR.SYN = BIT_SET THEN
  7902.   BAD_SYN_HANDLER(LCN, BUFPTR);
  7903. ELSIF BUFPTR.ACK = BIT_SET THEN
  7904.   PROCESS_COMMON_ACK(LCN, BUFPTR, RESULT);
  7905.   IF RESULT = GOOD THEN
  7906.     IF QUEUE_EMPTY(TCP_RETRANSMIT_QUEUE, LCN) THEN -- THE FIN IS ACKNOWLEDGED
  7907.       LCN.STATE := FIN_WAIT_2;
  7908.     -- *NOW DO THE SAME PROCESSING AS THE FIN-WAIT-2 STATE.*
  7909.       PROCESS_URGENT_FLAG(LCN, BUFPTR);
  7910.       PROCESS_SEGMENT_TEXT(LCN, BUFPTR);
  7911.       IF BUFPTR.FIN = BIT_SET THEN
  7912.         PROCESS_A_FIN(LCN, BUFPTR);
  7913.         LCN.STATE := TIME_WAIT;
  7914.         QUEUE_CLEAR(PROCESSED_SEGMENTS_FOR_USER_QUEUE, LCN); 
  7915.                                                -- DELETE UNEATEN DATA
  7916.         --START THE TIME-WAIT TIMER AND TURN OFF OTHER TIMERS
  7917.     START_TIMER(LCN, TIME_WAIT_TIMER);
  7918.       END IF;
  7919.     ELSE -- FIN NOT ACKED SO CONTINUE ON OUR WAY.
  7920.       PROCESS_URGENT_FLAG(LCN, BUFPTR);
  7921.       PROCESS_SEGMENT_TEXT(LCN, BUFPTR);
  7922.       IF BUFPTR.FIN = BIT_SET THEN
  7923.         PROCESS_A_FIN(LCN, BUFPTR);
  7924.         LCN.STATE := CLOSING;
  7925.         QUEUE_CLEAR(PROCESSED_SEGMENTS_FOR_USER_QUEUE, LCN); 
  7926.         -- GET RID OF UNEATEN DATA
  7927.       END IF;
  7928.     END IF;
  7929.   END IF;
  7930. END IF;
  7931. -- RELEASE BUFFER
  7932. --PUT_LINE("BUFFREE SEG_ARRIVED_IN_FIN_WAIT_1_STATE"); --DEBUG JB 7/3/85
  7933. GLOBAL_PACKED_BUFFER.IN_USE := FALSE;
  7934. GLOBAL_PACKED_BUFFER.STATUS := NONE;
  7935. BUFFREE(GLOBAL_PACKED_BUFFER, BUFFTYPE);
  7936. end SEG_ARRIVED_IN_FIN_WAIT_1_STATE;
  7937.  
  7938. procedure SEG_ARRIVED_IN_FIN_WAIT_2_STATE( BUFPTR : in out 
  7939.                                   T_TCP_GLOBALS_DATA_STRUCTURES.BUFFER_POINTER;
  7940.                            BYTE_COUNT : in SIXTEEN_BITS ) is
  7941.  
  7942. -- INITIAL DESCRIPTION :
  7943. -- 
  7944. --   THIS PROCEDURE IS CALLED BY THE SEGMENT ARRIVE CONTROLLER TO PROCESS A
  7945. --   SEGMENT WHEN THE CONNECTION IS IN THE FIN_WAIT_2 STATE.
  7946. -- PROCESSING :
  7947. --
  7948. --   THIS PROCEDURE DOES ALL THE PROCESSING ACCORDING TO THE SPEC FOR ARRIVED
  7949. --   SEGMENTS IN THE FIN-WAIT-2 STATE.
  7950.  
  7951. UMESSAGE : USER_MESSAGE;
  7952. RESULT : RES;
  7953.  
  7954. begin
  7955. IF BUFPTR.RST = BIT_SET THEN
  7956.   PROCESS_RESET_IN_DATA_ACCEPTING_STATES(LCN);
  7957. ELSIF BUFPTR.SYN = BIT_SET THEN
  7958.   BAD_SYN_HANDLER(LCN, BUFPTR);
  7959. ELSIF BUFPTR.ACK = BIT_SET THEN
  7960.   PROCESS_COMMON_ACK(LCN, BUFPTR, RESULT);
  7961.   IF RESULT = GOOD THEN
  7962.     PROCESS_URGENT_FLAG(LCN, BUFPTR);
  7963.     PROCESS_SEGMENT_TEXT(LCN, BUFPTR);
  7964.     IF BUFPTR.FIN = BIT_SET THEN
  7965.       PROCESS_A_FIN(LCN, BUFPTR); -- NOTE FIN IMPLIES PUSH
  7966.       LCN.STATE := TIME_WAIT;
  7967.       QUEUE_CLEAR(PROCESSED_SEGMENTS_FOR_USER_QUEUE, LCN); 
  7968.       -- DELETE UNEATEN DATA
  7969.       --START TIME_WAIT TIMER AND TURN OFF THE OTHER TIMERS
  7970.       START_TIMER(LCN, TIME_WAIT_TIMER);
  7971.     END IF;
  7972.   END IF;
  7973. END IF;
  7974. -- RELEASE BUFFER
  7975. --PUT_LINE("BUFFREE SEG_ARRIVED_IN_FIN_WAIT_2_STATE"); --DEBUG JB 7/3/85
  7976. GLOBAL_PACKED_BUFFER.IN_USE := FALSE;
  7977. GLOBAL_PACKED_BUFFER.STATUS := NONE;
  7978. BUFFREE(GLOBAL_PACKED_BUFFER, BUFFTYPE);
  7979. end SEG_ARRIVED_IN_FIN_WAIT_2_STATE;
  7980.  
  7981. procedure SEG_ARRIVED_IN_CLOSE_WAIT_STATE( BUFPTR : in out 
  7982.                                  T_TCP_GLOBALS_DATA_STRUCTURES.BUFFER_POINTER;
  7983.                            BYTE_COUNT : in SIXTEEN_BITS ) is
  7984.  
  7985. -- INITIAL DESCRIPTION :
  7986. -- 
  7987. --   THIS PROCEDURE IS CALLED BY THE SEGARIV PROCESSOR TO DO THE REQUIRED
  7988. --   PROCESSING FOR AN ARRIVED SEGMENT IN THIS STATE.
  7989. -- PROCESSING :
  7990. --
  7991. --   THIS PROCEDURE PERFORMS ALL NECESSARY PROCESSING FOR THE CLOSE_WAIT STATE
  7992. --   UPON SEGMENT ARRIVAL (ACCORDING TO THE TCP SPEC).
  7993.  
  7994. RESULT : RES;
  7995.  
  7996. begin
  7997. IF BUFPTR.RST = BIT_SET THEN
  7998.   PROCESS_RESET_IN_DATA_ACCEPTING_STATES(LCN);
  7999. ELSIF BUFPTR.SYN = BIT_SET THEN
  8000.   BAD_SYN_HANDLER(LCN, BUFPTR);
  8001. ELSIF BUFPTR.ACK = BIT_SET THEN
  8002.   PROCESS_COMMON_ACK(LCN, BUFPTR, RESULT);
  8003.   -- WE WILL IGNORE ANY URGENT BITS SET
  8004.   -- WE WILL (AS PER THE SPEC) IGNORE ANY TEXT
  8005.   -- WE WILL ALSO NOT WORRY IF THIS IS A REDUNDANT FIN.
  8006. END IF;
  8007. -- RELEASE BUFFER
  8008. --PUT_LINE("BUFFREE SEG_ARRIVED_IN_CLOSE_WAIT_STATE"); --DEBUG JB 7/3/85
  8009. GLOBAL_PACKED_BUFFER.IN_USE := FALSE;
  8010. GLOBAL_PACKED_BUFFER.STATUS := NONE;
  8011. BUFFREE(GLOBAL_PACKED_BUFFER, BUFFTYPE);
  8012. end SEG_ARRIVED_IN_CLOSE_WAIT_STATE;
  8013.  
  8014. procedure SEG_ARRIVED_IN_CLOSING_STATE( BUFPTR : in out 
  8015.                            T_TCP_GLOBALS_DATA_STRUCTURES.BUFFER_POINTER;
  8016.                          BYTE_COUNT : in SIXTEEN_BITS ) is
  8017.  
  8018. -- INITIAL DESCRIPTION :
  8019. -- 
  8020. --   THIS PROCEDURE IS CALLED BY THE SEGMENT ARRIVE PROCESSOR TO PROCESS AN
  8021. --   ARRIVED SEGMENT IN THE CLOSING STATE.
  8022. -- PROCESSING :
  8023. --
  8024. --   THIS PROCEDURE WILL DO ALL THE PROCESSING FOR AN ARRIVED SEGMENT,
  8025. --   ACCORDING TO THE SPEC, WHEN THE CONNECTION IS IN THE CLOSING STATE.
  8026.  
  8027. RESULT : RES;
  8028.  
  8029. begin
  8030. IF BUFPTR.RST = BIT_SET THEN
  8031.   LCN.STATE := CLOSED;
  8032.   -- HERE WE MAY HAVE TO CLEAR THE TCB.
  8033.   TCB_CLEAR(LCN);
  8034. ELSIF BUFPTR.SYN = BIT_SET THEN
  8035.   BAD_SYN_HANDLER(LCN, BUFPTR);
  8036. ELSIF BUFPTR.ACK = BIT_SET THEN
  8037.   PROCESS_COMMON_ACK(LCN, BUFPTR, RESULT);
  8038.   IF (RESULT = GOOD) AND QUEUE_EMPTY(TCP_RETRANSMIT_QUEUE, LCN) THEN 
  8039.   -- OUR FIN HAS BEEN ACKNOWLEDGED
  8040.     LCN.STATE := TIME_WAIT;
  8041.     QUEUE_CLEAR(PROCESSED_SEGMENTS_FOR_USER_QUEUE, LCN); -- DELETE UNEATEN DATA
  8042.     -- STOP OTHER TIMERS AND START TIME_WAIT TIMER
  8043.     START_TIMER(LCN, TIME_WAIT_TIMER);
  8044.   END IF;
  8045. -- ALL OTHER CONTROL BITS CAN BE IGNORED.
  8046. -- TEXT ALSO.
  8047. END IF;
  8048. GLOBAL_PACKED_BUFFER.IN_USE := FALSE;
  8049. GLOBAL_PACKED_BUFFER.STATUS := NONE;
  8050. BUFFREE(GLOBAL_PACKED_BUFFER, BUFFTYPE);
  8051. END SEG_ARRIVED_IN_CLOSING_STATE;
  8052.  
  8053. PROCEDURE SEG_ARRIVED_IN_LAST_ACK_STATE( BUFPTR : in out 
  8054.                              T_TCP_GLOBALS_DATA_STRUCTURES.BUFFER_POINTER;
  8055.                          BYTE_COUNT : in SIXTEEN_BITS ) is
  8056. -- INITIAL DESCRIPTION :
  8057. -- 
  8058. --   THIS PROCEDURE IS CALLED WHEN A SEGMENT ARRIVES WITH THE CONNECTION IN THE
  8059. --   LAST-ACK STATE.
  8060. -- PROCESSING :
  8061. --
  8062. --   THIS PROCEDURE DOES ALL THE PROCESSING FOR A SEGMENT THAT ARRIVES WITH A
  8063. --   CONNECTION IN THE LAST-ACK STATE. IF THE FIN IS ACKED THE CONNECTION IS
  8064. --   CLOSED.
  8065. UMESSAGE : USER_MESSAGE;
  8066. SOCKET_PARAMS : LCN_PTR_TYPE;
  8067.  
  8068. begin
  8069. if BUFPTR.RST = BIT_SET then
  8070.   LCN.STATE := CLOSED;
  8071.   -- THE TCB MAY HAVE TO BE CLEARED HERE.
  8072.   TCB_CLEAR(LCN);
  8073. elsif BUFPTR.SYN = BIT_SET then
  8074.   BAD_SYN_HANDLER(LCN, BUFPTR);
  8075. elsif BUFPTR.ACK = BIT_SET then
  8076.   -- DOES THIS ACK OUR FIN?
  8077.   if BUFPTR.ACK_NUM >= LCN.SND_NXT - 1 then
  8078.     -- TAKE SEGMENT(S) OFF THE RETRANSMISSION QUEUE.
  8079.     DELETE_FROM_RETRANS_QUEUE(LCN, BUFPTR.ACK_NUM);
  8080.     LCN.STATE := CLOSED;
  8081.     -- Tell ULP that "OK on close"
  8082.     SOCKET_PARAMS.LCN := LCN;
  8083.     SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  8084.     SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  8085.     UMESSAGE := ( 18,
  8086.                   SOCKET_PARAMS);
  8087.     MESSAGE_FOR_USER(UMESSAGE);
  8088.     -- HERE WE MAY HAVE TO CLEAR THE TCB
  8089.     QUEUE_CLEAR(RECEIVE_QUEUE, LCN);
  8090.     TCB_CLEAR(LCN);
  8091.     TCB_FREE( LCN );
  8092.   else
  8093.     -- THIS IS REALLY AN ERROR.
  8094.     TCP_ERROR(5);
  8095.   end if;
  8096. end if;
  8097. -- WE WILL IGNORE AS PER THE SPEC. ANYTHING ELSE.
  8098. GLOBAL_PACKED_BUFFER.IN_USE := FALSE;
  8099. GLOBAL_PACKED_BUFFER.STATUS := NONE;
  8100. BUFFREE(GLOBAL_PACKED_BUFFER, BUFFTYPE);
  8101. end SEG_ARRIVED_IN_LAST_ACK_STATE;
  8102.  
  8103. PROCEDURE SEG_ARRIVED_IN_TIME_WAIT_STATE( BUFPTR : in out 
  8104.                                 T_TCP_GLOBALS_DATA_STRUCTURES.BUFFER_POINTER;
  8105.                           BYTE_COUNT : in SIXTEEN_BITS ) IS
  8106. -- INITIAL DESCRIPTION :
  8107. -- 
  8108. --   THIS PROCEDURE IS CALLED BY THE SEGMENT ARRIVE PROCESSOR TO PROCESS A
  8109. --   SEGMENT IN THE TIME-WAIT STATE.
  8110. -- PROCESSING :
  8111. --
  8112. --   THIS PROCEDURE WILL ACCEPT A RESENT FIN, ACK IT AGAIN AND RESTART THE
  8113. --   TIME-WAIT TIMER.
  8114. BEGIN
  8115. IF BUFPTR.RST = BIT_SET THEN
  8116.   LCN.STATE := CLOSED;
  8117.   -- THE TCB MAY HAVE TO BE CLEARED HERE.
  8118.   TCB_CLEAR(LCN);
  8119. ELSIF BUFPTR.SYN = BIT_SET THEN
  8120.   BAD_SYN_HANDLER(LCN, BUFPTR);
  8121. ELSIF BUFPTR.ACK = BIT_SET THEN
  8122.   -- THIS SHOULD BE THE ACK WITH THE RETRANSMITTED FIN
  8123.   IF BUFPTR.FIN = BIT_SET THEN
  8124.     -- ACK THE FIN
  8125.     LCN.RCV_NXT := LCN.RCV_NXT + MODULAR_CONVERT(SIXTEEN_BITS(1)); --COVER THE FIN.
  8126.     SEND_A_PIGGYBACKED_ACK(LCN);
  8127.     -- RESTART THE 2 MSL (MAX SEG. LIFETIME TIMER)
  8128.     START_TIMER(LCN, TIME_WAIT_TIMER);
  8129.   END IF;
  8130. END IF;
  8131. -- WE WILL IGNORE AS PER THE SPEC. ANYTHING ELSE.
  8132. GLOBAL_PACKED_BUFFER.IN_USE := FALSE;
  8133. GLOBAL_PACKED_BUFFER.STATUS := NONE;
  8134. BUFFREE(GLOBAL_PACKED_BUFFER, BUFFTYPE);
  8135. END SEG_ARRIVED_IN_TIME_WAIT_STATE;
  8136.  
  8137. PROCEDURE TCP_SEG_ARRIVE(PACKED_BUFFER    : in out PACKED_BUFFER_PTR; 
  8138.              BYTE_COUNT : in SIXTEEN_BITS ;
  8139.                      SOURCE_FROM_IP, DEST : in THIRTYTWO_BITS ; 
  8140.                          PROT, TOS_IP : in SIXTEEN_BITS ;
  8141.                      SECURITY_OP : in SECURITY_OPTION_TYPE) is
  8142.  
  8143.     --This procedure is called by the TCP controller when it gets an 
  8144.     --arrived segment.  Here the appropriate processor is called.
  8145.  
  8146. LCN_LIST : TCB_PTR;
  8147. TCP_LENGTH, BUFFTYPE : SIXTEEN_BITS ;
  8148. NOT_VALID_ADDRESS : BOOLEAN := TRUE;
  8149. BUFPTR : T_TCP_GLOBALS_DATA_STRUCTURES.BUFFER_POINTER;
  8150.  
  8151. PROCEDURE SEQUENCE_NUMBER_CHECKER( LCN : in TCB_PTR; 
  8152.                                    BUFPTR : in 
  8153.                          T_TCP_GLOBALS_DATA_STRUCTURES.BUFFER_POINTER;
  8154.                    RESULT : in out RES; 
  8155.                                    TCP_LENGTH : in out SIXTEEN_BITS ) is
  8156.  
  8157. DATA_LENGTH : SIXTEEN_BITS ;
  8158.  
  8159. begin
  8160.  DATA_LENGTH := TCP_LENGTH - BUFPTR.DATA_OFFSET * 4;
  8161.  if LCN.RCV_WINDOW > 0 then
  8162.   if BUFPTR.SEQ_NUM = LCN.RCV_NXT then
  8163.    if BUFPTR.SEQ_NUM + DATA_LENGTH <= LCN.RCV_NXT + LCN.RCV_WINDOW
  8164.                                     then
  8165.     RESULT := GOOD;
  8166.    else
  8167.     RESULT := GOOD;
  8168.     DATA_LENGTH := LCN.RCV_WINDOW;
  8169.     TCP_LENGTH := DATA_LENGTH + BUFPTR.DATA_OFFSET * 4;
  8170.    end if;
  8171.   elsif (BUFPTR.SEQ_NUM < LCN.RCV_NXT) and 
  8172.          BUFPTR.SEQ_NUM + DATA_LENGTH > LCN.RCV_NXT then
  8173.    -- IT'S PARTLY IN THE WINDOW. THIS SHOULD NOT CURRENTLY HAPPEN!
  8174.    TCP_ERROR(6);
  8175.    RESULT := BAD;
  8176.   elsif BUFPTR.SEQ_NUM < LCN.RCV_NXT + LCN.RCV_WINDOW then
  8177.    -- SOME OF IT IS IN THE WINDOW IT JUST DOES NOT START IN THE WINDOW.
  8178.    -- WE CURRENTLY IGNORE THIS.
  8179.    RESULT := BAD;
  8180.   else
  8181.   RESULT := BAD;
  8182.   end if;
  8183.  elsif TCP_LENGTH = BUFPTR.DATA_OFFSET * 4 then
  8184.   -- A ZERO LENGTH SEGMENT PROBABLY AN ACK.
  8185.   RESULT := GOOD;
  8186.  else
  8187.   -- A SEGMENT WITH DATA ON AN EMPTY WINDOW.
  8188.   RESULT := BAD;
  8189.  end if;
  8190. end SEQUENCE_NUMBER_CHECKER;
  8191.  
  8192. procedure SEND_ACK_OF_UNACCEPTABLE_SEGMENT is
  8193.  
  8194. RESULT : RESULT_TYPE;
  8195. MESSAGE_FOR_IP : IP_MESSAGE ;
  8196.  
  8197. begin
  8198. -- WE WILL SEND OUT AN ACK IN THE SAME PACKED BUFFER IT ARRIVED IN.
  8199. OPTIONS := CLEAR;
  8200. TCP_HEADER_FORMAT(LCN, BUFPTR, ACK, OPTIONS);
  8201. -- REUSE THE BUFFER. SO WE MUST RESET ITS POINTER.
  8202. PACKED_BUFFER.TCP_PTR := 255;
  8203. -- ZERO OUT THE DATA LENGTH OF THE BUFFER.
  8204. BUFPTR.DATA_LEN := 0;
  8205. PACK_BUFFER_INTO_BIT_STREAM(BUFPTR, PACKED_BUFFER);
  8206. OPTIONS := TCP_SECURITY_OPTIONS;
  8207. MESSAGE_FOR_IP := ( FROM_TCP,
  8208.                     PACKED_BUFFER,
  8209.                     LCN.DESTINATION_ADDRESS,
  8210.                     TOS,
  8211.                     TTL,
  8212.                     BUFPTR.DATA_OFFSET * 4, 
  8213.                     IDENT,
  8214.                     DONT_FRAGMENT,
  8215.                     OPTIONS,
  8216.                     LCN.SOURCE_ADDRESS ) ;
  8217.    IP_FROM_TCP.Q_ADD( MESSAGE_FOR_IP ) ;
  8218. -- NO UPDATE OF THE SEQUENCE NUMBER
  8219. TCP_ERROR(13);-- NOTE AN INVALID SEQUENCE NUMBER ARRIVED
  8220. end SEND_ACK_OF_UNACCEPTABLE_SEGMENT;
  8221.  
  8222. begin
  8223. -- UNPACK THE BUFFER
  8224. BUFPTR := UNPACK(PACKED_BUFFER, BYTE_COUNT); -- NEEDS THE DATA COUNT.
  8225. -- DETERMINE WHETHER CHECKSUM IS VALID. 
  8226. IF BUFPTR.TCP_CSUM /= CHECKSUM(BYTE_COUNT, PACKED_BUFFER, DEST, SOURCE_FROM_IP,
  8227.                    PROT) THEN
  8228.   -- RELEASE BUFFER
  8229.   PUT_LINE("BAD CHECKSUM IN SEGARIV");---DEBUG
  8230.   INT_IO_32.PUT(SOURCE_FROM_IP);
  8231.   PUT_LINE(""); -- WHY 128 LOST ON ABORT.
  8232.   INT_IO_16.PUT(BUFPTR.TCP_CSUM);
  8233.   INT_IO_16.PUT( CHECKSUM(BYTE_COUNT, 
  8234.                   PACKED_BUFFER, 
  8235.                   DEST, 
  8236.                   SOURCE_FROM_IP,
  8237.           PROT));---DEBUG
  8238.   PUT_LINE("POINTER AND BYTE COUNT");
  8239.   INT_IO_16.PUT(PACKED_BUFFER.TCP_PTR);
  8240.   INT_IO_16.PUT(BYTE_COUNT);
  8241.   TCP_ERROR(15);
  8242.   PACKED_BUFFER.IN_USE := FALSE;
  8243.   PACKED_BUFFER.STATUS := NONE;
  8244.   BUFFREE(PACKED_BUFFER, BUFFTYPE);
  8245. ELSE
  8246.   -- SET UP THE GLOBAL PSEUDO HEADER
  8247.   FOR I IN 1..9 LOOP
  8248.     SECURITY(I) := SECURITY_OP ( SIXTEEN_BITS ( I ) ) ;
  8249.   END LOOP;
  8250.   IP_TOS := TOS_IP;
  8251.   SOURCE := SOURCE_FROM_IP;
  8252.   DESTINATION := DEST;
  8253.   --  MATCH UP    SEGMENT    WITH A LCN (HENCE A TCB)
  8254.   LCN_LIST := OBTAIN_HEAD_OF_LCN_IN_USE_QUEUE;
  8255.   while LCN_LIST /= null loop
  8256.    -- CHECK FOR A VALID SOCKET.
  8257.    if LCN_LIST.SOURCE_ADDRESS = DEST and 
  8258.        (BUFPTR.DESTINATION_PORT = LCN_LIST.LOCAL_PORT) then
  8259.     LCN := LCN_LIST; -- SET GLOBAL LCN
  8260.     NOT_VALID_ADDRESS := FALSE;
  8261.     exit;
  8262.    else --obtain next LCN
  8263.     LCN_LIST := LCN_LIST.NEXT;
  8264.    end if;
  8265.   end loop;
  8266. -- Determine if a connection is closing on the same host
  8267. --  if (LCN.STATE = T_TCP_GLOBALS_DATA_STRUCTURES.CLOSING) then
  8268. --   LCN_LIST := OBTAIN_HEAD_OF_LCN_IN_USE_QUEUE;
  8269. --   while LCN_LIST /= null loop
  8270.  
  8271. -- DETERMINE IF THE FOREIGN PORT AND SOURCE ARE THE ONE FOR THE OBSERVED LCN  
  8272.   if LCN /= null then
  8273.    if LCN.STATE /= T_TCP_GLOBALS_DATA_STRUCTURES.CLOSED and
  8274.        (LCN.STATE /= T_TCP_GLOBALS_DATA_STRUCTURES.LISTEN) then
  8275.     if LCN.DESTINATION_ADDRESS /= SOURCE_FROM_IP or (LCN.FOREIGN_PORT
  8276.        /= BUFPTR.SOURCE_PORT) then
  8277.       NOT_VALID_ADDRESS := TRUE;
  8278.     end if;
  8279.    end if;
  8280.   end if;
  8281.   if NOT_VALID_ADDRESS then -- NOT FOR US
  8282.     -- RELEASE BUFFER
  8283.     PUT_LINE("GOT A PACKET NOT FOR US IN SEGARIV");
  8284.     TCP_ERROR(16);
  8285.     PUT_LINE("BUFFREE SEG_ARRIVE"); --DEBUG JB 7/3/85
  8286.     PACKED_BUFFER.IN_USE := FALSE;
  8287.     PACKED_BUFFER.STATUS := NONE;
  8288.     BUFFREE(PACKED_BUFFER, BUFFTYPE);
  8289.   else
  8290.     -- RESTART THE CONNECTION TIMEOUT TIMER.
  8291.     START_TIMER(LCN, TIMEOUT_TIMER);
  8292.     -- SET UP GLOBAL BUFFER POINTER FOR DELETE PRIVLEDGE IN ALL ROUTINES
  8293.     GLOBAL_PACKED_BUFFER := PACKED_BUFFER;
  8294.     -- PUT DATA    LENGTH IN THE BUFFER
  8295.     BUFPTR.DATA_LEN := BYTE_COUNT - BUFPTR.DATA_OFFSET * 4;
  8296.     TCP_LENGTH := BYTE_COUNT; -- THE LENGTH OF SEGMENT AND DATA
  8297.     case LCN.STATE    is
  8298.       when CLOSED => SEG_ARRIVED_IN_CLOSED_STATE( BUFPTR, 
  8299.                                                   BYTE_COUNT,
  8300.                                           SOURCE_FROM_IP, 
  8301.                                                   DEST);
  8302.     
  8303.       when T_TCP_GLOBALS_DATA_STRUCTURES.LISTEN =>
  8304.             SEG_ARRIVED_IN_LISTEN_STATE( BUFPTR, 
  8305.                                              BYTE_COUNT,
  8306.                          SOURCE_FROM_IP);   
  8307.  
  8308.       when SYN_SENT => SEG_ARRIVED_IN_SYN_SENT_STATE( BUFPTR, 
  8309.                                                       BYTE_COUNT);
  8310.     
  8311.       when SYN_RECEIVED    => SEQUENCE_NUMBER_CHECKER( LCN,
  8312.                                                  BUFPTR,    
  8313.                                                     RESULTS, 
  8314.                                         TCP_LENGTH);
  8315.                if RESULTS =    GOOD then
  8316.                  SEG_ARRIVED_IN_SYN_RECEIVED_STATE( BUFPTR, 
  8317.                                                                 TCP_LENGTH);
  8318.                else
  8319.                  SEND_ACK_OF_UNACCEPTABLE_SEGMENT;
  8320.                end if;
  8321.     
  8322.        when ESTABLISHED => SEQUENCE_NUMBER_CHECKER( LCN, 
  8323.                                                     BUFPTR, 
  8324.                                                     RESULTS, 
  8325.                                                     TCP_LENGTH);
  8326.               if RESULTS = GOOD then
  8327.                            SEG_ARRIVED_IN_ESTABLISHED_STATE( BUFPTR, 
  8328.                                                              TCP_LENGTH);
  8329.               else
  8330.                  SEND_ACK_OF_UNACCEPTABLE_SEGMENT;
  8331.               end if;
  8332.     
  8333.       WHEN FIN_WAIT_1 => SEQUENCE_NUMBER_CHECKER( LCN, 
  8334.                                                   BUFPTR, 
  8335.                                                   RESULTS, 
  8336.                                                   TCP_LENGTH);
  8337.              IF RESULTS = GOOD THEN
  8338.                 SEG_ARRIVED_IN_FIN_WAIT_1_STATE(BUFPTR, TCP_LENGTH);
  8339.              ELSE
  8340.                  SEND_ACK_OF_UNACCEPTABLE_SEGMENT;
  8341.              END IF;
  8342.     
  8343.       WHEN FIN_WAIT_2 => SEQUENCE_NUMBER_CHECKER
  8344.                           (LCN, BUFPTR, RESULTS, TCP_LENGTH);
  8345.              IF RESULTS = GOOD THEN
  8346.                SEG_ARRIVED_IN_FIN_WAIT_2_STATE(BUFPTR, TCP_LENGTH);
  8347.              ELSE
  8348.                  SEND_ACK_OF_UNACCEPTABLE_SEGMENT;
  8349.              END IF;
  8350.     
  8351.       WHEN CLOSE_WAIT => SEQUENCE_NUMBER_CHECKER
  8352.                           (LCN, BUFPTR, RESULTS, TCP_LENGTH);
  8353.              IF RESULTS = GOOD THEN
  8354.                SEG_ARRIVED_IN_CLOSE_WAIT_STATE(BUFPTR, TCP_LENGTH);
  8355.              ELSE
  8356.                  SEND_ACK_OF_UNACCEPTABLE_SEGMENT;
  8357.              END IF;
  8358.       when CLOSING => SEQUENCE_NUMBER_CHECKER( LCN, 
  8359.                                                BUFPTR, 
  8360.                                                RESULTS, 
  8361.                                                TCP_LENGTH);
  8362.               if RESULTS = GOOD    then
  8363.                SEG_ARRIVED_IN_CLOSING_STATE( BUFPTR, 
  8364.                                                      TCP_LENGTH);
  8365.               else
  8366.                SEND_ACK_OF_UNACCEPTABLE_SEGMENT;
  8367.               end if;
  8368.     
  8369.       when LAST_ACK => SEQUENCE_NUMBER_CHECKER( LCN, 
  8370.                                                 BUFPTR, 
  8371.                                                 RESULTS, 
  8372.                                                 TCP_LENGTH);
  8373.                if RESULTS = GOOD then
  8374.             SEG_ARRIVED_IN_LAST_ACK_STATE( BUFPTR, 
  8375.                                                        TCP_LENGTH);
  8376.                else
  8377.                 SEND_ACK_OF_UNACCEPTABLE_SEGMENT;
  8378.                end if;
  8379.     
  8380.       when TIME_WAIT =>    SEQUENCE_NUMBER_CHECKER( LCN,
  8381.                                                  BUFPTR, 
  8382.                                                  RESULTS, 
  8383.                                                  TCP_LENGTH);
  8384.             if RESULTS = GOOD then
  8385.              SEG_ARRIVED_IN_TIME_WAIT_STATE( BUFPTR, 
  8386.                                                          TCP_LENGTH);
  8387.             else
  8388.              if BUFPTR.SEQ_NUM < LCN.RCV_NXT and
  8389.                  BUFPTR.FIN = BIT_SET then
  8390.                   -- RESTART THE TIMEOUT TIMER SINCE AN OLD FIN CAME 
  8391.                           -- IN
  8392.                   START_TIMER(LCN, TIMEOUT_TIMER);
  8393.                  end if;
  8394.                      SEND_ACK_OF_UNACCEPTABLE_SEGMENT;
  8395.             end if;
  8396.     end    case;
  8397.   end if;
  8398. end if;
  8399.     
  8400. EXCEPTION
  8401.   WHEN CONSTRAINT_ERROR =>
  8402.    PUT_LINE("CONSTRAINT ERROR OCCURRED IN SEGARIV PACKAGE");
  8403.   WHEN OTHERS =>
  8404.    PUT_LINE("PROBLEM IN SEGARIV");
  8405. END TCP_SEG_ARRIVE;
  8406. END TCP_SEGMENT_ARRIVES_PROCESSING;
  8407. --::::::::::::::
  8408. --ip_from_subnet_task_.ada
  8409. --::::::::::::::
  8410. -----------------------------------------------------------------------
  8411. --
  8412. --         DoD Protocols    NA-00001-200       80-00994-100(-)
  8413. --         E-Systems, Inc.  August 07, 1985
  8414. --
  8415. --         IP_FROM_SUBNET_TASK_.ADA       Author : Jim Baldo
  8416. --
  8417. -----------------------------------------------------------------------
  8418.                         package IP_FROM_SUBNET_TASK is
  8419.      
  8420.                 -----------------------------------------------
  8421.                 --This implementation is for the DEC/Ada     --
  8422.                 --compiler .                                 --
  8423.                 -----------------------------------------------
  8424.      
  8425. task IP_GET_FROM_SUBNET_TASK;
  8426.      
  8427.         --This task will check to see if the subnet protocol
  8428.         --has a message to send to IP.
  8429.      
  8430. end IP_FROM_SUBNET_TASK;
  8431. --::::::::::::::
  8432. --ip_from_subnet_task.ada
  8433. --::::::::::::::
  8434. -----------------------------------------------------------------------
  8435. --
  8436. --         DoD Protocols    NA-00001-200       80-00995-100(-)
  8437. --         E-Systems, Inc.  August 07, 1985
  8438. --
  8439. --         IP_FROM_SUBNET_TASK.ADA       Author : Jim Baldo
  8440. --
  8441. -----------------------------------------------------------------------
  8442. with TEXT_IO;                                   use TEXT_IO;
  8443. with SUBNET_CALLS;                              use SUBNET_CALLS;
  8444. with IP_ARRIVE_PROCESSING;                      use IP_ARRIVE_PROCESSING;
  8445. with IP_GLOBALS;                                use IP_GLOBALS;
  8446. with CALENDAR;                                  use CALENDAR;
  8447. with BUFFER_DATA;                               use BUFFER_DATA;
  8448.      
  8449.                         package body IP_FROM_SUBNET_TASK is
  8450.      
  8451.                 -----------------------------------------------
  8452.                 --This implementation is for the DEC/Ada     --
  8453.                 --compiler .                                 --
  8454.                 -----------------------------------------------
  8455.      
  8456. task body IP_GET_FROM_SUBNET_TASK is
  8457.      
  8458. TIME_OUT_DELAY : constant DAY_DURATION := 1.0;
  8459. DATAGRAM : PACKED_BUFFER_PTR := null;
  8460. MESSAGE_TO_IP : IP_MESSAGE;
  8461. BUFFTYPE : SIXTEEN_BITS := 0;
  8462.      
  8463. begin
  8464.  loop
  8465.   select
  8466.    SNP.DELIVER( DATAGRAM );
  8467.    MESSAGE_TO_IP := ( DATA_FROM_SUBNET, DATAGRAM, 0 );
  8468. --   PUT_LINE(" Just received a message from the SUBNET");--DEBUG JB 6/3/85
  8469.    IP_DATAGRAM_ARRIVE( MESSAGE_TO_IP.BUFPTR );
  8470.   or
  8471.    delay( TIME_OUT_DELAY );
  8472.   end select;
  8473.  end loop;
  8474. end IP_GET_FROM_SUBNET_TASK;
  8475.      
  8476. end IP_FROM_SUBNET_TASK;
  8477. --::::::::::::::
  8478. --tcp_utilities_.ada
  8479. --::::::::::::::
  8480. -----------------------------------------------------------------------
  8481. --
  8482. --         DoD Protocols    NA-00001-200       80-01027-100(-)
  8483. --         E-Systems, Inc.  August 07, 1985
  8484. --
  8485. --         TCP_UTILITIES_.ADA       Author : Jim Baldo
  8486. --
  8487. -----------------------------------------------------------------------
  8488. with WITH_TCP_COMMUNICATE ;             use WITH_TCP_COMMUNICATE ;
  8489. with MODULO;                            use MODULO;
  8490. with BUFFER_DATA;                       use BUFFER_DATA;
  8491. -- COMMUNICATE AND QUEUE CONTAINS THE NECESSARY FACILITIES FOR MESSAGES TO BE
  8492. -- QUEUED BETWEEN TASKS.
  8493. with T_TCP_GLOBALS_DATA_STRUCTURES;     USE T_TCP_GLOBALS_DATA_STRUCTURES;
  8494.      
  8495.                 package T_TCP_CONTROLLER_UTILITIES is
  8496.      
  8497.         --------------------------------------------------------------------
  8498.         --This implementation is for use with the DEC/Ada compiler        --
  8499.         --version .                                                       --
  8500.         --------------------------------------------------------------------
  8501.      
  8502.  function USER_ACCESS_CHECK( LCN : in TCB_PTR) return BOOLEAN;
  8503.      
  8504.  procedure SEND_A_SYN( LCN : in TCB_PTR);
  8505.      
  8506.  procedure TCP_SEND( LCN : in TCB_PTR;
  8507.                      PACKED_BUFF : in out PACKED_BUFFER_PTR;
  8508.                      BUFFLEN, PUSH_FLAG, URG_FLAG, TIMEOUT : in SIXTEEN_BITS );
  8509.      
  8510.  procedure TCP_RECEIVE( LCN : in TCB_PTR;
  8511.                         PACKED_BUFF : in out PACKED_BUFFER_PTR;
  8512.                         BYTE_COUNT : in SIXTEEN_BITS );
  8513.      
  8514.  procedure TCP_ABORT( LCN : in TCB_PTR);
  8515.      
  8516.  procedure TCP_CLOSE( LCN : in TCB_PTR);
  8517.      
  8518.  procedure TCP_OPEN(LOCAL_PORT, FOREIGN_PORT :in SIXTEEN_BITS ;
  8519.                     FOREIGN_NET_HOST : in THIRTYTWO_BITS ;
  8520.                     ACTIVE_PASSIVE : in WITH_TCP_COMMUNICATE.ACKPASS;
  8521.                     BUFFER_SIZE, TIMEOUT : in SIXTEEN_BITS ;
  8522.                     LOCAL_CONN_NAME : in out LCN_PTR_TYPE ;
  8523.                     SECURITY, PRECEDENCE : in SIXTEEN_BITS ;
  8524.                     OPTIONS : in TCP_OPTION_TYPE);
  8525.      
  8526.  procedure TCP_STATUS(LCN : in TCB_PTR);
  8527.      
  8528.  procedure RETRANS_TCP(LCN : in TCB_PTR);
  8529.      
  8530. end T_TCP_CONTROLLER_UTILITIES;
  8531.      
  8532. --::::::::::::::
  8533. --tcp_utilities.ada
  8534. --::::::::::::::
  8535. -----------------------------------------------------------------------
  8536. --
  8537. --         DoD Protocols    NA-00001-200       80-01028-100(-)
  8538. --         E-Systems, Inc.  August 07, 1985
  8539. --
  8540. --         TCP_UTILITIES.ADA       Author : Jim Baldo
  8541. --
  8542. -----------------------------------------------------------------------
  8543. with IP_TCP ;                           use IP_TCP ;
  8544. with TCP_TO_ULP_COMMUNICATE ;           use TCP_TO_ULP_COMMUNICATE ;
  8545. with SYSTEM;
  8546. with TEXT_IO;                           use TEXT_IO;
  8547. with UNCHECKED_CONVERSION;
  8548. -- COMMUNICATE AND QUEUE CONTAINS THE NECESSARY FACILITIES FOR MESSAGES TO BE
  8549. -- QUEUED BETWEEN TASKS.
  8550. with WITH_TCP_COMMUNICATE;              use WITH_TCP_COMMUNICATE;
  8551. with TCP_GLOBALS;                       use TCP_GLOBALS;
  8552. with QUEUES;                            use QUEUES;
  8553. with TCP_SEGMENT_ARRIVES_PROCESSING;    use TCP_SEGMENT_ARRIVES_PROCESSING;
  8554. with IP_GLOBALS;                        use IP_GLOBALS;
  8555. with TCB_ALLOCATOR;             use TCB_ALLOCATOR;
  8556.      
  8557.                 package body T_TCP_CONTROLLER_UTILITIES is
  8558.      
  8559. package INT_IO_16 is new INTEGER_IO ( SIXTEEN_BITS ) ;
  8560.      
  8561. function USER_ACCESS_CHECK( LCN : in TCB_PTR) return BOOLEAN is
  8562.      
  8563. RESULT : BOOLEAN := TRUE;
  8564. I : TCB_PTR := OBTAIN_HEAD_OF_LCN_IN_USE_QUEUE;
  8565.                            -- THE BEGINNING INDEX INTO THE LCN LIST!
  8566.      
  8567. begin
  8568.  while I /= null and RESULT loop
  8569.   if I = LCN then
  8570.    RESULT := FALSE;
  8571.   end if;
  8572.   I := I.NEXT;
  8573.  end loop;
  8574.  return RESULT;
  8575. exception
  8576.  when OTHERS =>
  8577.   PUT("PROBLEM IN USER ACCESS CHECK");
  8578. end USER_ACCESS_CHECK;
  8579.      
  8580.  procedure SEND_A_SYN( LCN : in TCB_PTR) is
  8581.      
  8582.         --This subprogram is called by the TCP_OPEN and the TCP_SEND in the
  8583.         --listen state to send out a SYN.  The LCN is passed to the subprogram
  8584.         --to calculate the appropiate address.  This subprogram will format
  8585.         --and send a SYN segment to the IP for transmission to the remote host.
  8586.      
  8587.  HEADER_LENGTH : SIXTEEN_BITS  := 20;
  8588.  BUFPTR : T_TCP_GLOBALS_DATA_STRUCTURES.BUFFER_POINTER;
  8589.  DEST : THIRTYTWO_BITS ;
  8590.  SOURCE : THIRTYTWO_BITS ;
  8591.  PACKED_BUFF : PACKED_BUFFER_PTR;
  8592.  BUFFLEN : SIXTEEN_BITS ; -- TEMPORARY
  8593.  Q_ITEM : STD_Q_ITEM;
  8594.  UMESSAGE : USER_MESSAGE;
  8595.   SOCKET_PARAMS : LCN_PTR_TYPE;
  8596.  MESSAGE_FOR_IP : IP_GLOBALS.IP_MESSAGE ;
  8597.      
  8598.  begin
  8599.   BUFFGET(PACKED_BUFF, BUFFLEN);
  8600.   if PACKED_BUFF = null then
  8601.    -- TELL USER
  8602.    -- ERROR: INSUFFICIENT RESOURCES
  8603.    SOCKET_PARAMS.LCN := LCN;
  8604.    SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  8605.    SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  8606.    UMESSAGE := ( 1,
  8607.                  SOCKET_PARAMS);
  8608.    MESSAGE_FOR_USER(UMESSAGE);
  8609.   else
  8610.    PACKED_BUFF.STATUS := OWNER_TCP;
  8611.    PACKED_BUFF.IN_USE := TRUE;
  8612.    LCN.ISS := MODULAR_CONVERT(ISS);--GET AN INTIAL SEND SEQUENCE NUMBER
  8613.                                         --(ISS)
  8614.    LCN.SND_NXT := LCN.ISS;-- SET UP THE INITIAL SEND NEXT.
  8615.    TYPE_FLAG := SYN;
  8616.    OPTIONS := CLEAR;--CLEAR THE OPTIONS ARRAY
  8617.                     --ADD ANY OPTIONS TO HEADER LENGTH HERE
  8618.    TCP_HEADER_FORMAT( LCN, BUFPTR, TYPE_FLAG, OPTIONS);
  8619.    DEST := LCN.DESTINATION_ADDRESS;
  8620.    -- HERE WE MUST PUT IN THE NECESSARY SECURITY OPTIONS FOR IP.
  8621.    OPTIONS := TCP_SECURITY_OPTIONS;
  8622.    PACK_BUFFER_INTO_BIT_STREAM(BUFPTR, PACKED_BUFF);-- PACK THE BUFFER
  8623.    SOURCE := IP_GLOBALS.WHOIAM;
  8624.    MESSAGE_FOR_IP := ( FROM_TCP,
  8625.                        PACKED_BUFF,
  8626.                        DEST,
  8627.                        TOS,
  8628.                        TTL,
  8629.                        HEADER_LENGTH,
  8630.                        IDENT,
  8631.                        DONT_FRAGMENT,
  8632.                        OPTIONS,
  8633.                        SOURCE ) ;
  8634.    IP_FROM_TCP.Q_ADD( MESSAGE_FOR_IP ) ;
  8635.    -- UPDATE SEND UNACKNOWLEDGED AND SND_NXT.
  8636.    LCN.SND_UNA :=       LCN.ISS;
  8637.    LCN.SND_NXT :=       LCN.ISS + MODULAR_CONVERT(SIXTEEN_BITS(1)); 
  8638.             -- SAME AS SEND NEXT + 1
  8639.    --  PUT BUFFER ON RETRANSMIT QUEUE WITH THE LENGTH IN OCTETS.
  8640.    Q_ITEM := (PACKED_BUFF, NULL_UNPACKED_BUFFER, HEADER_LENGTH);
  8641.    --  IT IS QUEUED UP WITH A TIME.
  8642.    QUEUE_ADD(TCP_RETRANSMIT_QUEUE, LCN, Q_ITEM);
  8643.   end if;
  8644.  end SEND_A_SYN;
  8645.      
  8646.  procedure TCP_SEND(LCN : in TCB_PTR;
  8647.                     PACKED_BUFF : in out PACKED_BUFFER_PTR;
  8648.                     BUFFLEN, PUSH_FLAG,URG_FLAG,TIMEOUT : in SIXTEEN_BITS ) is
  8649.      
  8650. --This subprogram is called by the TCP controller to process a users send
  8651. --request.  This subprogram will format the header and pass the buffer on to
  8652. --the IP for transmission.
  8653. --The following parameters are passed to the subprogram:
  8654. --      LCN
  8655. --      Buffer length
  8656. --      PUSH_FLAG : An indication of whether all data should be pushed through.
  8657. --      URG_FLAG : An indication of the urgency of the data.
  8658. --               (1 URGENT, 0 NORMAL).
  8659. --      TIMEOUT : The timeout interval for a connection. timeout occurs if
  8660. --              there is no response for that amount of time.
  8661. --      PACKED_BUFF : A packed buffer with user data.
  8662. --
  8663.      
  8664.  NULL_FLAG, NO_ROOM_ON_QUEUE : BOOLEAN;
  8665.  BUFFSIZE : SIXTEEN_BITS ;
  8666.  BUFPTR : T_TCP_GLOBALS_DATA_STRUCTURES.BUFFER_POINTER;
  8667.  Q_ITEM : STD_Q_ITEM;
  8668.  SEGMENT_LENGTH : SIXTEEN_BITS  := 255 - PACKED_BUFF.TCP_PTR;
  8669.    -- CORRECT UNTIL SIZE CHANGES
  8670.  UMESSAGE : USER_MESSAGE;
  8671.  SOCKET_PARAMS : LCN_PTR_TYPE;
  8672.  MESSAGE_FOR_IP : IP_GLOBALS.IP_MESSAGE ;
  8673.  DUMMY : CHARACTER;
  8674.      
  8675.  begin
  8676. --  PUT_LINE("HIT ANY CHARACTER TO CONTINUE");
  8677. --  GET(DUMMY);
  8678.   T_TCP_GLOBALS_DATA_STRUCTURES.LCN := LCN; -- FOR TEST***
  8679.   if TIMEOUT /= 0 then -- PUT IN THE NEW CONNECTION TIMEOUT.
  8680.    LCN.CONNECTION_TIMEOUT := TIMEOUT;
  8681.   end if;
  8682.   case LCN.STATE is
  8683.    when CLOSED =>
  8684.     if USER_ACCESS_CHECK(LCN) then
  8685.      -- TELL USER
  8686.      --  ERROR: CONNECTION ILLEGAL FOR THIS PROCESS
  8687.      SOCKET_PARAMS.LCN := LCN;
  8688.      SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  8689.      SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  8690.      UMESSAGE := ( 2,
  8691.                    SOCKET_PARAMS);
  8692.      MESSAGE_FOR_USER(UMESSAGE);
  8693.     else
  8694.      -- TELL USER
  8695.      -- ERROR: CONNECTION DOES NOT EXIST
  8696.      SOCKET_PARAMS.LCN := LCN;
  8697.      SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  8698.      SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  8699.      UMESSAGE := ( 3,
  8700.                    SOCKET_PARAMS);
  8701.      MESSAGE_FOR_USER(UMESSAGE);
  8702.     end if;
  8703.    when T_TCP_GLOBALS_DATA_STRUCTURES.LISTEN =>
  8704.    if FOREIGN_SOCKET_UNSPECIFIED(LCN) then
  8705.      -- TELL USER
  8706.      -- ERROR: FOREIGN SOCKET UNSPECIFIED
  8707.      SOCKET_PARAMS.LCN := LCN;
  8708.      SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  8709.      SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  8710.      UMESSAGE := ( 4,
  8711.                    SOCKET_PARAMS);
  8712.      MESSAGE_FOR_USER(UMESSAGE);
  8713.     else
  8714.      -- TCB STATE BECOMES ACTIVE
  8715.      LCN.ACTIVE_PASSIVE := ACTIVE;
  8716.      --  PUT ANY TEXT ON THE TEXT TRANSMIT QUEUE FOR LATER TRANSMISSION
  8717.      if BUFFLEN > 0 then -- THERE IS DATA.
  8718.      Q_ITEM := (PACKED_BUFF, NULL_UNPACKED_BUFFER, BUFFLEN);
  8719.      QUEUE_ADD(TRANSMIT_QUEUE, LCN, Q_ITEM, NO_ROOM_ON_QUEUE);
  8720.      if NO_ROOM_ON_QUEUE then
  8721.       -- TELL USER OR ERROR ROUTINE
  8722.       -- ERROR: INSUFFICIENT RESOURCES
  8723.       PUT_LINE("STATE IS LISTEN");--DEBUG
  8724.       PUT_LINE("NO Q RM IN SEND");-- DEBUG
  8725.       SOCKET_PARAMS.LCN := LCN;
  8726.       SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  8727.       SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  8728.       UMESSAGE := ( 5,
  8729.                     SOCKET_PARAMS);
  8730.       MESSAGE_FOR_USER(UMESSAGE);
  8731.      end if;
  8732.     end if;
  8733.     -- SEND OUT A SYN
  8734.     SEND_A_SYN(LCN);
  8735.     --  PUT TCB INTO SYN_SENT STATE.
  8736.     LCN.STATE := SYN_SENT;
  8737.    end if;
  8738.   when SYN_SENT | SYN_RECEIVED =>
  8739.    -- PUT THE TEXT ON THE TRANSMIT QUEUE FOR LATER TRANSMISSION
  8740.    if BUFFLEN > 0 then -- THERE IS DATA.
  8741.     Q_ITEM := (PACKED_BUFF, NULL_UNPACKED_BUFFER, BUFFLEN);
  8742.     QUEUE_ADD(TRANSMIT_QUEUE, LCN, Q_ITEM, NO_ROOM_ON_QUEUE);
  8743.     if NO_ROOM_ON_QUEUE then
  8744.      -- TELL USER
  8745.      -- ERROR: INSUFFICIENT RESOURCES
  8746.      PUT_LINE("NO Q RM IN SEND");-- DEBUG
  8747.      PUT_LINE("STATE IS SYN SENT OR SYN RECEIVED");--DEBUG
  8748.      SOCKET_PARAMS.LCN := LCN;
  8749.      SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  8750.      SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  8751.      UMESSAGE := ( 5,
  8752.                    SOCKET_PARAMS);
  8753.      MESSAGE_FOR_USER(UMESSAGE);
  8754.     end if;
  8755.    end if;
  8756.   when ESTABLISHED | CLOSE_WAIT =>
  8757.    -- HERE WE WOULD SEGMENTIZE A BUFFER FOR TRANSMISSON, WHICH WE
  8758.    -- ARE CURRENTLY NOT DOING.
  8759.    if LCN.SND_WND + LCN.SND_UNA >= (LCN.SND_NXT +
  8760.         SEGMENT_LENGTH) then
  8761.     -- USE THE SAME BUFFER ALL THE WAY
  8762.     TYPE_FLAG := SEGMENT;
  8763.     -- PUT THE DATA IN THE BUFFER
  8764.     for I in 1..SEGMENT_LENGTH loop
  8765.      BUFPTR.DATA(I) := PACKED_BUFF.BYTE(PACKED_BUFF.TCP_PTR+I);
  8766.     end loop;
  8767.     BUFPTR.DATA_LEN := SEGMENT_LENGTH;
  8768.     -- CLEAR OPTIONS ARRAY
  8769.     OPTIONS := CLEAR;
  8770.     TCP_HEADER_FORMAT(LCN, BUFPTR, TYPE_FLAG, OPTIONS);
  8771.     -- HERE WE MUST PUT IN THE NECESSARY SECURITY OPTIONS FOR IP.
  8772.     OPTIONS := TCP_SECURITY_OPTIONS;
  8773.     -- PACK THE BUFFER
  8774.     -- WE ASSUME THAT THE POINTER IS CORRECTLY SET.
  8775.     PACK_BUFFER_INTO_BIT_STREAM(BUFPTR, PACKED_BUFF);
  8776.     -- THE STANDARD HEADER LENGTH + DATA LENGTH
  8777.     LEN := BUFPTR.DATA_OFFSET * 4 + SEGMENT_LENGTH;
  8778.     PACKED_BUFF.STATUS := OWNER_TCP;
  8779.     MESSAGE_FOR_IP := ( FROM_TCP,
  8780.                         PACKED_BUFF,
  8781.                         LCN.DESTINATION_ADDRESS,
  8782.                         TOS,
  8783.                         TTL,
  8784.                         LEN,
  8785.                         IDENT,
  8786.                         DONT_FRAGMENT,
  8787.                         OPTIONS,
  8788.                         LCN.SOURCE_ADDRESS ) ;
  8789.     IP_FROM_TCP.Q_ADD( MESSAGE_FOR_IP ) ;
  8790.     -- PUT BUFFER IN RETRANSMISSION QUEUE AND SET THE TIMER
  8791.     -- LEN IS THE TOTAL NUM OF BYTES IN THE SEGMENT.
  8792.     Q_ITEM := (PACKED_BUFF, NULL_UNPACKED_BUFFER, LEN);
  8793.     -- TESTING
  8794.     NEW_LINE;
  8795. --    if QUEUE_FREE_LIST.NEXT = null then
  8796. --     PUT("QUEUE_FREE_LIST = null ");
  8797. --    else
  8798. --     Put("QUEUE_FREE_LIST /= null ");
  8799. --    end if;
  8800. --    NEW_LINE;
  8801.     QUEUE_ADD(TCP_RETRANSMIT_QUEUE, LCN, Q_ITEM);
  8802.     -- WECOULD MESS WITH OUR RECEIVE WINDOW HERE IF WE WISHED.
  8803. --    NEW_LINE;
  8804. --    PUT_LINE("AFTER QUEUE_ADD TCP_SEND");
  8805. --    if QUEUE_FREE_LIST.NEXT = null then
  8806. --     PUT("QUEUE_FREE_LIST = null ");
  8807. --    else
  8808. --     Put("QUEUE_FREE_LIST /= null ");
  8809. --    end if;
  8810. --    NEW_LINE;
  8811.     LCN.SND_NXT := LCN.SND_NXT + SEGMENT_LENGTH;
  8812.     if URG_FLAG = BIT_SET then
  8813.      LCN.SND_UP := LCN.SND_NXT - 1;
  8814.     end if;
  8815.    else
  8816.     -- PUT THE TEXT ON THE TRANSMIT QUEUE FOR PROCESSING WHEN AN ACK COMES
  8817.     -- IN AND WE CAN SEND IT.
  8818.     Q_ITEM := (PACKED_BUFF, NULL_UNPACKED_BUFFER, SEGMENT_LENGTH);
  8819.     QUEUE_ADD(TRANSMIT_QUEUE, LCN, Q_ITEM, NO_ROOM_ON_QUEUE);
  8820.     if NO_ROOM_ON_QUEUE then
  8821.      --TELL USER ERROR: INSUFFICIENT RESOURCES
  8822.      PUT_LINE("NO Q RM IN SEND");-- DEBUG
  8823.      PUT_LINE("STATE IS ESTAB");--DEBUG
  8824.      INT_IO_16.PUT(SEGMENT_LENGTH);
  8825.      SOCKET_PARAMS.LCN := LCN;
  8826.      SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  8827.      SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  8828.      UMESSAGE := ( 5,
  8829.                    SOCKET_PARAMS);
  8830.      MESSAGE_FOR_USER(UMESSAGE);
  8831.     end if;
  8832.    end if;
  8833.   when others =>
  8834.    -- TELL USER ERROR: CONNECTION CLOSING
  8835.    SOCKET_PARAMS.LCN := LCN;
  8836.    SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  8837.    SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  8838.    UMESSAGE :=( 6,
  8839.                 SOCKET_PARAMS);
  8840.    MESSAGE_FOR_USER(UMESSAGE);
  8841.  end case;
  8842. end TCP_SEND;
  8843.      
  8844.  procedure TCP_RECEIVE( LCN : in TCB_PTR;
  8845.                         PACKED_BUFF : in out PACKED_BUFFER_PTR;
  8846.                         BYTE_COUNT : in SIXTEEN_BITS ) is
  8847.      
  8848.         --This subprogram is called by the user via the TCP controller.
  8849.         --it will queue the request or if there is data to satisfy it, return
  8850.         --a buffer full of data if one is available.  Otherwise it will simply
  8851.         --queue the request until data becomes available.  The subprogram is
  8852.         --passed a LCN, BYTE_COUNT which represents the size of the buffer if
  8853.         --one is passed in, and PACKED_BUFF that contains the data to be
  8854.         --returned to the user.
  8855.      
  8856.  RECEIVE_QUEUE_FULL : BOOLEAN;
  8857.  PACKED_BUFFER : PACKED_BUFFER_PTR;
  8858.  BUFFTYPE, PROCESSED_BYTE_COUNT : SIXTEEN_BITS ;
  8859.  Q_ITEM : STD_Q_ITEM;
  8860.  UMESSAGE : USER_MESSAGE;
  8861.   SOCKET_PARAMS : LCN_PTR_TYPE;
  8862.  DUMMY : CHARACTER;
  8863.      
  8864.  begin
  8865.   T_TCP_GLOBALS_DATA_STRUCTURES.LCN := LCN; -- FOR TEST***
  8866.   -- ALL RECEIVE REQUESTS THAT WE CAN HANDLE WILL BE SATISIFIED OR QUEUED
  8867.   -- ON THE TCP RECEIVE QUEUE FOR LATER PROCESSING WHEN DATA COMES IN.
  8868.   case LCN.STATE is
  8869.    when T_TCP_GLOBALS_DATA_STRUCTURES.CLOSED =>
  8870.     if USER_ACCESS_CHECK(LCN) then
  8871.      -- TELL USER ERROR: CONNECTION ILLEGAL FOR THIS PROCESS
  8872.      SOCKET_PARAMS.LCN := LCN;
  8873.      SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  8874.      SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  8875.      UMESSAGE := ( 2,
  8876.                    SOCKET_PARAMS);
  8877.      MESSAGE_FOR_USER(UMESSAGE);
  8878.     else
  8879.      -- TELL USER ERROR: CONNECTION DOES NOT EXIST
  8880.      SOCKET_PARAMS.LCN := LCN;
  8881.      SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  8882.      SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  8883.      UMESSAGE := ( 3,
  8884.                    SOCKET_PARAMS);
  8885.      MESSAGE_FOR_USER(UMESSAGE);
  8886.     end if;
  8887.    when T_TCP_GLOBALS_DATA_STRUCTURES.LISTEN | SYN_SENT | SYN_RECEIVED =>
  8888.     -- PUT REQUEST ON QUEUE FOR LATER PROCESSING
  8889.     Q_ITEM := (PACKED_BUFF, NULL_UNPACKED_BUFFER, BYTE_COUNT);
  8890.     QUEUE_ADD(RECEIVE_QUEUE, LCN, Q_ITEM, RECEIVE_QUEUE_FULL);
  8891.     if RECEIVE_QUEUE_FULL then
  8892.      -- TELL USER ERROR: INSUFFICIENT RESOURCES
  8893.      PUT_LINE("NO Q RM IN RECEIVE");-- DEBUG
  8894.      SOCKET_PARAMS.LCN := LCN;
  8895.      SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  8896.      SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  8897.      UMESSAGE := ( 5,
  8898.                    SOCKET_PARAMS);
  8899.      MESSAGE_FOR_USER(UMESSAGE);
  8900.     end if;
  8901.    when ESTABLISHED | FIN_WAIT_1 | FIN_WAIT_2 =>
  8902.     -- NOTE THAT WE CONSIDER ANY DATA TO BE SUFFICIENT DATA FOR A BUFFER.
  8903.     -- WE DO NOTHING WITH THE PUSH FLAG SINCE WE CURRENTLY PUSH EVERYTHING.
  8904.     -- ALSO WE MAKE NO PROVISION FOR URGENT DATA AND DO NOT CHECK FOR IT.
  8905.     -- GET A BUNCH OF DATA IF WE CAN.
  8906.     if QUEUE_FREE_LIST.NEXT = null then
  8907.      NEW_LINE;
  8908.      PUT_LINE("QUEUE_FREE_LIST.NEXT TCP_RECEIVE = null");
  8909.      PUT_LINE("STRIKE ANY CHARACTER TO CONTINUE");
  8910.      GET(DUMMY);
  8911.     end if;
  8912.     QUEUE_GET(PROCESSED_SEGMENTS_FOR_USER_QUEUE, LCN, Q_ITEM);
  8913. --    if QUEUE_FREE_LIST.NEXT = null then
  8914. --     NEW_LINE;
  8915. --     PUT_LINE("QUEUE_FREE_LIST.NEXT TCP_RECEIVE = null");
  8916. --     PUT_LINE("STRIKE ANY CHARACTER TO CONTINUE");
  8917. --     GET(DUMMY);
  8918. --    end if;
  8919.     PROCESSED_BYTE_COUNT := Q_ITEM.LENGTH;
  8920. --    if QUEUE_FREE_LIST.NEXT = null then
  8921. --     NEW_LINE;
  8922. --     PUT_LINE("QUEUE_FREE_LIST.NEXT TCP_RECEIVE = null");
  8923. --     PUT_LINE("STRIKE ANY CHARACTER TO CONTINUE");
  8924. --     GET(DUMMY);
  8925. --    end if;
  8926.     PACKED_BUFFER := Q_ITEM.BUFFER;
  8927. --    if QUEUE_FREE_LIST.NEXT = null then
  8928. --     NEW_LINE;
  8929. --     PUT_LINE("QUEUE_FREE_LIST.NEXT TCP_RECEIVE = null");
  8930. --     PUT_LINE("STRIKE ANY CHARACTER TO CONTINUE");
  8931. --     GET(DUMMY);
  8932. --    end if;
  8933.     if PACKED_BUFFER = null then
  8934.     -- PUT REQUEST ON QUEUE FOR LATER PROCESSING
  8935. --    if QUEUE_FREE_LIST.NEXT = null then
  8936. --     NEW_LINE;
  8937. --     PUT_LINE("QUEUE_FREE_LIST.NEXT TCP_RECEIVE = null");
  8938. --     PUT_LINE("STRIKE ANY CHARACTER TO CONTINUE");
  8939. --     GET(DUMMY);
  8940. --    end if;
  8941.     Q_ITEM := (PACKED_BUFF, NULL_UNPACKED_BUFFER, BYTE_COUNT);
  8942. --    if QUEUE_FREE_LIST.NEXT = null then
  8943. --     NEW_LINE;
  8944. --     PUT_LINE("QUEUE_FREE_LIST.NEXT TCP_RECEIVE = null");
  8945. --     PUT_LINE("STRIKE ANY CHARACTER TO CONTINUE");
  8946. --     GET(DUMMY);
  8947. --    end if;
  8948.     QUEUE_ADD(RECEIVE_QUEUE, LCN, Q_ITEM, RECEIVE_QUEUE_FULL);
  8949. --    if QUEUE_FREE_LIST.NEXT = null then
  8950. --     NEW_LINE;
  8951. --     PUT_LINE("QUEUE_FREE_LIST.NEXT TCP_RECEIVE = null");
  8952. --     PUT_LINE("STRIKE ANY CHARACTER TO CONTINUE");
  8953. --     GET(DUMMY);
  8954. --    end if;
  8955.     if RECEIVE_QUEUE_FULL then
  8956.     -- TELL USER ERROR: INSUFFICIENT RESOURCES
  8957.     PUT_LINE("NO Q RM IN SEND");-- DEBUG
  8958.     SOCKET_PARAMS.LCN := LCN;
  8959.     SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  8960.     SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  8961.     UMESSAGE := ( 5,
  8962.                   SOCKET_PARAMS);
  8963.     MESSAGE_FOR_USER(UMESSAGE);
  8964.    end if;
  8965.   else
  8966.    -- FILL BUFFER WITH QUEUED INCOMING SEGMENTS
  8967.    INSERT_TEXT_IN_BUFFER(BYTE_COUNT, PACKED_BUFF,
  8968.         PROCESSED_BYTE_COUNT, PACKED_BUFFER);
  8969.    -- WE IGNORE A PUSH; WE IGNORE URGENT POINTER
  8970.    -- GIVE THE BUFFER TO THE USER
  8971.    SOCKET_PARAMS.LCN := LCN;
  8972.    SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  8973.    SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  8974.    UMESSAGE := ( 10,
  8975.                  SOCKET_PARAMS,
  8976.                  PACKED_BUFF);
  8977.    MESSAGE_FOR_USER(UMESSAGE);
  8978.    -- FREE UP THE PACKED BUFFER
  8979.    PACKED_BUFFER.STATUS := NONE;
  8980.    PACKED_BUFFER.IN_USE := FALSE;
  8981.    BUFFREE(PACKED_BUFFER, BUFFTYPE);
  8982.   end if;
  8983.  when CLOSE_WAIT =>
  8984.   QUEUE_GET(PROCESSED_SEGMENTS_FOR_USER_QUEUE, LCN, Q_ITEM);
  8985.   PROCESSED_BYTE_COUNT := Q_ITEM.LENGTH;
  8986.   PACKED_BUFFER := Q_ITEM.BUFFER;
  8987.   if PACKED_BUFFER = null then
  8988.    -- ERROR: CONNECTION CLOSING
  8989.    SOCKET_PARAMS.LCN := LCN;
  8990.    SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  8991.    SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  8992.    UMESSAGE := ( 6,
  8993.                  SOCKET_PARAMS);
  8994.    MESSAGE_FOR_USER(UMESSAGE);
  8995.   else
  8996.    -- FILL BUFFER WITH ANY REMAINING TEXT
  8997.    INSERT_TEXT_IN_BUFFER(BYTE_COUNT, PACKED_BUFF,
  8998.         PROCESSED_BYTE_COUNT, PACKED_BUFFER);
  8999.    -- RETURN BUFFER TO USER
  9000.    SOCKET_PARAMS.LCN := LCN;
  9001.    SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  9002.    SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  9003.    UMESSAGE := ( 10,
  9004.                  SOCKET_PARAMS,
  9005.                  PACKED_BUFF);
  9006.    MESSAGE_FOR_USER(UMESSAGE);
  9007.    -- FREE UP THE PACKED BUFFER
  9008.    PACKED_BUFFER.STATUS := NONE;
  9009.    PACKED_BUFFER.IN_USE := FALSE;
  9010.    BUFFREE(PACKED_BUFFER, BUFFTYPE);
  9011.   end if;
  9012.  when CLOSING | TIME_WAIT | LAST_ACK    =>
  9013.   -- TELL USER ERROR: CONNECTION CLOSING
  9014.   SOCKET_PARAMS.LCN := LCN;
  9015.   SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  9016.   SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  9017.   UMESSAGE := ( 6,
  9018.                 SOCKET_PARAMS);
  9019.   MESSAGE_FOR_USER(UMESSAGE);
  9020.  end case;
  9021. exception
  9022.  when constraint_error =>
  9023.   PUT_LINE("CONSTRAINT ERROR IN TCP RECEIVE");
  9024.  when others =>
  9025.   PUT_LINE("ERROR IN TCP RECEIVE");
  9026. end TCP_RECEIVE;
  9027.      
  9028.  procedure TCP_ABORT( LCN : in TCB_PTR) is
  9029.      
  9030.         --This subprogram is called by the user via the TCP controller to
  9031.         --abort a connection.  It does this by sending a reset to the remote
  9032.         --host and clearing the TCB associated with the particular local
  9033.         --connection name. All queues will have the items from this connection
  9034.         --removed from them.
  9035.      
  9036.  USER_SHOULD_NOT_HAVE_ACCESS : BOOLEAN;
  9037.  BUFFLEN : SIXTEEN_BITS ;
  9038.  BUFPTR : T_TCP_GLOBALS_DATA_STRUCTURES.BUFFER_POINTER;
  9039.  PACKED_BUFF : PACKED_BUFFER_PTR;
  9040.  UMESSAGE : USER_MESSAGE;
  9041.  SOCKET_PARAMS : LCN_PTR_TYPE;
  9042.  MESSAGE_FOR_IP : IP_GLOBALS.IP_MESSAGE ;
  9043.  TEMP_LCN : TCB_PTR ;
  9044.      
  9045.  begin
  9046.   TEMP_LCN := LCN; -- To contain modification locally*****
  9047.   T_TCP_GLOBALS_DATA_STRUCTURES.LCN := LCN; -- FOR TEST***
  9048.   case LCN.STATE is
  9049.    when T_TCP_GLOBALS_DATA_STRUCTURES.CLOSED =>
  9050.     if USER_ACCESS_CHECK(LCN) then
  9051.      -- TELL USER ERROR: CONNECTION ILLEGAL FOR THIS PROCESS
  9052.      SOCKET_PARAMS.LCN := LCN;
  9053.      SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  9054.      SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  9055.      UMESSAGE := ( 2,
  9056.                    SOCKET_PARAMS);
  9057.      MESSAGE_FOR_USER(UMESSAGE);
  9058.     else
  9059.      -- TELL USER ERROR: CONNECTION DOES NOT EXIST
  9060.      SOCKET_PARAMS.LCN := LCN;
  9061.      SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  9062.      SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  9063.      UMESSAGE := ( 3,
  9064.                    SOCKET_PARAMS);
  9065.      MESSAGE_FOR_USER(UMESSAGE);
  9066.     end if;
  9067.    when T_TCP_GLOBALS_DATA_STRUCTURES.LISTEN =>
  9068.     QUEUE_CLEAR(RECEIVE_QUEUE, LCN);
  9069.     -- CLEAR THE TCB AND ENTER THE CLOSED STATE
  9070.     LCN.STATE := CLOSED;
  9071.     -- TELL USER OK
  9072.     SOCKET_PARAMS.LCN := LCN;
  9073.     SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  9074.     SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  9075.     UMESSAGE := ( 8,
  9076.                   SOCKET_PARAMS);
  9077.     MESSAGE_FOR_USER(UMESSAGE);
  9078.     TCB_CLEAR(LCN);
  9079.     TCB_FREE( TEMP_LCN );
  9080.    when SYN_SENT =>
  9081.     QUEUE_CLEAR(RECEIVE_QUEUE, LCN);
  9082.     -- NONE ON THIS LEVEL. CLEAR_SEND_QUEUE(LCN);
  9083.     -- CLEAR THE TCB AND ENTER THE CLOSED STATE
  9084.     QUEUE_CLEAR(TCP_RETRANSMIT_QUEUE, LCN);
  9085.     QUEUE_CLEAR(TRANSMIT_QUEUE, LCN);
  9086.     -- TELL USER OK
  9087.     SOCKET_PARAMS.LCN := LCN;
  9088.     SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  9089.     SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  9090.     UMESSAGE := ( 8,
  9091.                   SOCKET_PARAMS);
  9092.     MESSAGE_FOR_USER(UMESSAGE);
  9093.     TCB_CLEAR(LCN);
  9094.     TCB_FREE( TEMP_LCN );
  9095.    when SYN_RECEIVED |  ESTABLISHED | FIN_WAIT_1 | FIN_WAIT_2
  9096.          | CLOSE_WAIT =>  -- SEND A RESET SEGMENT
  9097.     BUFFGET(PACKED_BUFF, BUFFLEN);
  9098.     if PACKED_BUFF = null then -- ERROR OUT OF  BUFFERS
  9099.      TCP_ERROR(1);
  9100.     else
  9101.      PACKED_BUFF.STATUS := OWNER_TCP;
  9102.      PACKED_BUFF.IN_USE := TRUE;
  9103.      TCP_HEADER_FORMAT( LCN, BUFPTR, RST, OPTIONS);
  9104.       -- HERE WE MUST PUT IN THE NECESSARY SECURITY OPTIONS FOR IP.
  9105.       OPTIONS := TCP_SECURITY_OPTIONS;
  9106.      
  9107.     -- TELL USER OK
  9108.     SOCKET_PARAMS.LCN := LCN;
  9109.     SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  9110.     SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  9111.     UMESSAGE := ( 8,
  9112.                   SOCKET_PARAMS);
  9113.     MESSAGE_FOR_USER(UMESSAGE);
  9114.      
  9115.       -- PACK THE BUFFER
  9116.       PACK_BUFFER_INTO_BIT_STREAM(BUFPTR, PACKED_BUFF);
  9117.       LEN := BUFPTR.DATA_OFFSET * 4;-- SINCE NO DATA SENT
  9118.       MESSAGE_FOR_IP := ( FROM_TCP,
  9119.                           PACKED_BUFF,
  9120.                           LCN.DESTINATION_ADDRESS,
  9121.                           TOS,
  9122.                           TTL,
  9123.                           LEN,
  9124.                           IDENT,
  9125.                           DONT_FRAGMENT,
  9126.                           OPTIONS,
  9127.                           LCN.SOURCE_ADDRESS ) ;
  9128.     IP_FROM_TCP.Q_ADD( MESSAGE_FOR_IP ) ;
  9129.     end if;
  9130.     QUEUE_CLEAR(RECEIVE_QUEUE, LCN);
  9131.     -- NONE ON THIS LEVEL. CLEAR_SEND_QUEUE(LCN);
  9132.     --  TRASH TRANSMIT AND RETRANSMIT QUEUES
  9133.     QUEUE_CLEAR(TRANSMIT_QUEUE, LCN);
  9134.     QUEUE_CLEAR(TCP_RETRANSMIT_QUEUE, LCN);
  9135.     QUEUE_CLEAR(PROCESSED_SEGMENTS_FOR_USER_QUEUE, LCN);
  9136.     -- CLEAR THE TCB AND ENTER  THE CLOSED STATE
  9137.     LCN.STATE := CLOSED;
  9138.     TCB_CLEAR(LCN);
  9139.    when CLOSING | LAST_ACK | TIME_WAIT =>
  9140.     -- CLEAR THE TCB AND ENTER THE CLOSED STATE
  9141.     QUEUE_CLEAR(RECEIVE_QUEUE, LCN);
  9142.     TCB_CLEAR(LCN); -- PUT IN A KNOWN STATE
  9143.     TCB_FREE ( TEMP_LCN );
  9144.    end case;
  9145.   end TCP_ABORT;
  9146.      
  9147.  procedure TCP_CLOSE(LCN : in TCB_PTR) is
  9148.      
  9149.         --This subprogram is called by the user via the TCP controller.
  9150.         --It will send a FIN to a remote host. This will cause the connection
  9151.         --to close down upon a FIN and/or an ACK from the remote host.
  9152.      
  9153.         UMESSAGE : USER_MESSAGE;
  9154.         SOCKET_PARAMS : LCN_PTR_TYPE;
  9155.      
  9156.  procedure SEND_A_FIN(LCN : in TCB_PTR) is
  9157.      
  9158.         --This subprogram formats and sends a FIN to the IP for transmission
  9159.         --to the remote host.
  9160.      
  9161.         BUFPTR : T_TCP_GLOBALS_DATA_STRUCTURES.BUFFER_POINTER;
  9162.         BUFFLEN : SIXTEEN_BITS ;
  9163.         PACKED_BUFF : PACKED_BUFFER_PTR;
  9164.         SEGMENT_DATA_LENGTH : CONSTANT SIXTEEN_BITS  := 1;
  9165.         TCP_HEAD_AND_DATA_LENGTH : CONSTANT SIXTEEN_BITS  := 20;
  9166.         -- THE LENGTH OF A FIN SEGMENT WITHOUT OPTIONS
  9167.         NO_ROOM : BOOLEAN;
  9168.         Q_ITEM : STD_Q_ITEM;
  9169.         UMESSAGE : USER_MESSAGE;
  9170.         MESSAGE_FOR_IP : IP_GLOBALS.IP_MESSAGE ;
  9171.      
  9172.         begin
  9173.          BUFFGET(PACKED_BUFF, BUFFLEN);
  9174.          if PACKED_BUFF = null then
  9175.           -- TELL USE ERROR: INSUFFICIENT RESOURCES
  9176.           SOCKET_PARAMS.LCN := LCN;
  9177.           SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  9178.           SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  9179.           UMESSAGE := ( 20,
  9180.                         SOCKET_PARAMS);
  9181.           MESSAGE_FOR_USER(UMESSAGE);
  9182.           SOCKET_PARAMS.LCN := LCN;
  9183.           SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  9184.           SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  9185.           UMESSAGE := ( 5,
  9186.                         SOCKET_PARAMS);
  9187.           MESSAGE_FOR_USER(UMESSAGE);
  9188.          elsif LCN.SND_WND + LCN.SND_UNA >= (LCN.SND_NXT +
  9189.             SEGMENT_DATA_LENGTH) then -- WE CAN SEND IT.
  9190.           PACKED_BUFF.STATUS := OWNER_TCP;
  9191.           PACKED_BUFF.IN_USE := TRUE;
  9192.           TYPE_FLAG := FIN;
  9193.           -- CLEAR THE OPTIONS ARRAY
  9194.           OPTIONS := CLEAR;
  9195.           TCP_HEADER_FORMAT(LCN, BUFPTR, TYPE_FLAG, OPTIONS);--FIN
  9196.           -- HERE WE MUST PUT IN THE NECESSARY SECURITY OPTIONS FOR IP.
  9197.           OPTIONS := TCP_SECURITY_OPTIONS;
  9198.           -- PACK THE BUFFER
  9199.           PACK_BUFFER_INTO_BIT_STREAM(BUFPTR, PACKED_BUFF);
  9200.           MESSAGE_FOR_IP := ( FROM_TCP,
  9201.                               PACKED_BUFF,
  9202.                               LCN.DESTINATION_ADDRESS,
  9203.                               TOS,
  9204.                               TTL,
  9205.                               TCP_HEAD_AND_DATA_LENGTH,
  9206.                               IDENT,
  9207.                               DONT_FRAGMENT,
  9208.                               OPTIONS,
  9209.                               LCN.SOURCE_ADDRESS ) ;
  9210.           IP_FROM_TCP.Q_ADD( MESSAGE_FOR_IP ) ;
  9211.           -- UPDATE THE SEND NEXT
  9212.           LCN.SND_NXT := LCN.SND_NXT + MODULAR_CONVERT ( SIXTEEN_BITS (1));
  9213.           --  PUT IT ON THE RETRANSMIT QUEUE IT IS QUEUED UP WITH A TIME.
  9214.           Q_ITEM :=
  9215.            (PACKED_BUFF, NULL_UNPACKED_BUFFER,TCP_HEAD_AND_DATA_LENGTH);
  9216.           QUEUE_ADD(TCP_RETRANSMIT_QUEUE, LCN, Q_ITEM);
  9217.          else
  9218.           -- PUT IT ON THE TRANSMIT QUEUE FOR LATER PROCESSING.
  9219.           Q_ITEM := (PACKED_BUFF, NULL_UNPACKED_BUFFER,
  9220.             TCP_HEAD_AND_DATA_LENGTH);
  9221.           QUEUE_ADD(TRANSMIT_QUEUE, LCN, Q_ITEM);
  9222.          end if;
  9223.         end SEND_A_FIN;
  9224.      
  9225.         begin -- TCP_CLOSE
  9226.          T_TCP_GLOBALS_DATA_STRUCTURES.LCN := LCN; -- FOR TEST
  9227.          case LCN.STATE is
  9228.           when T_TCP_GLOBALS_DATA_STRUCTURES.CLOSED =>
  9229.            if USER_ACCESS_CHECK(LCN) then
  9230.             -- TELL USER ERROR: CONNECTION ILLEGAL FOR THIS PROCESS
  9231.             SOCKET_PARAMS.LCN := LCN;
  9232.             SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  9233.             SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  9234.             UMESSAGE := ( 2,
  9235.                           SOCKET_PARAMS);
  9236.             MESSAGE_FOR_USER(UMESSAGE);
  9237.            else
  9238.             -- TELL USER ERROR: CONNECTION DOES NOT EXIST
  9239.             SOCKET_PARAMS.LCN := LCN;
  9240.             SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  9241.             SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  9242.             UMESSAGE := ( 3,
  9243.                           SOCKET_PARAMS);
  9244.             MESSAGE_FOR_USER(UMESSAGE);
  9245.            end if;
  9246.           when T_TCP_GLOBALS_DATA_STRUCTURES.LISTEN =>
  9247.                         QUEUE_CLEAR(RECEIVE_QUEUE, LCN);
  9248.            -- CLEAR TCB AND ENTER THE CLOSED STATE
  9249.            TCB_CLEAR(LCN);
  9250.            LCN.STATE := CLOSED;
  9251.           when SYN_SENT => -- NONE ON THIS LEVEL. CLEAR_SEND_QUEUE(LCN);
  9252.            QUEUE_CLEAR(RECEIVE_QUEUE, LCN);
  9253.            -- CLEAR THE TCB AND ENTER THE CLOSED STATE.
  9254.            TCB_CLEAR(LCN);
  9255.            LCN.STATE := CLOSED;
  9256.           when SYN_RECEIVED | ESTABLISHED =>
  9257.            if QUEUE_EMPTY(TRANSMIT_QUEUE, LCN) then
  9258.             SEND_A_FIN(LCN);
  9259.            else
  9260.             -- SET THE CLOSE PENDING FLAG IN THE TCB.
  9261.             LCN.CLOSE_PENDING := TRUE;
  9262.            end if;
  9263.            -- ENTER THE FIN-WAIT-1 STATE
  9264.            LCN.STATE := FIN_WAIT_1;
  9265.           when FIN_WAIT_1 | FIN_WAIT_2 =>
  9266.            --TELL USER ERROR: CONNECTION CLOSING
  9267.            SOCKET_PARAMS.LCN := LCN;
  9268.            SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  9269.            SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  9270.            UMESSAGE := ( 6,
  9271.                          SOCKET_PARAMS);
  9272.            MESSAGE_FOR_USER(UMESSAGE);
  9273.           when CLOSE_WAIT =>
  9274.            if QUEUE_EMPTY(TRANSMIT_QUEUE, LCN) then
  9275.             SEND_A_FIN(LCN);
  9276.             -- ENTER THE LAST ACK STATE
  9277.             LCN.STATE := LAST_ACK;
  9278.             QUEUE_CLEAR(PROCESSED_SEGMENTS_FOR_USER_QUEUE,LCN);
  9279.            else
  9280.             -- SET TH CLOSE PENDING FLAG IN THE TCB.
  9281.             LCN.CLOSE_PENDING := TRUE;
  9282.             -- WHEN THE FIN IS SENT DUE TO THE CLOSE PENDING
  9283.             -- FLAG THE STATE MUST BE CHANGED.
  9284.            end if;
  9285.           when CLOSING | LAST_ACK | TIME_WAIT   =>
  9286.            --TELL USER ERROR: CONNECTION CLOSING
  9287.            SOCKET_PARAMS.LCN := LCN;
  9288.            SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  9289.            SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  9290.            UMESSAGE := ( 6,
  9291.                          SOCKET_PARAMS);
  9292.            MESSAGE_FOR_USER(UMESSAGE);
  9293.          end case;
  9294.         end TCP_CLOSE;
  9295.      
  9296.  procedure TCP_OPEN( LOCAL_PORT, FOREIGN_PORT : in SIXTEEN_BITS ;
  9297.                      FOREIGN_NET_HOST : in THIRTYTWO_BITS ;
  9298.                      ACTIVE_PASSIVE : in WITH_TCP_COMMUNICATE.ACKPASS;
  9299.                      BUFFER_SIZE, TIMEOUT : in SIXTEEN_BITS ;
  9300.                      LOCAL_CONN_NAME : in out LCN_PTR_TYPE ;
  9301.                      SECURITY, PRECEDENCE : in SIXTEEN_BITS ;
  9302.                      OPTIONS : in TCP_OPTION_TYPE) is
  9303.      
  9304. --This subprogram will perform the actions necessary to do a passive or
  9305. --an active OPEN. If a passive OPEN is requested the listen state will
  9306. --entered. If an active OPEN is requested a SYN will be sent and the
  9307. --connection actively pursued.  The subprogram is called by the user layer
  9308. --via the TCP controller.  The following parameters are passed to the
  9309. --subprogram :
  9310. --      LOCAL_PORT : The local port identification number.
  9311. --      FOREIGN_NET_HOST : The foreign net address of the remote host we wish
  9312. --              to talk with and the address of the foreign host on the net.
  9313. --              they are concatenated in a format found in the IP spec.
  9314. --       FOREIGN_PORT : The port in the foreign host that we wish to send to.
  9315. --      ACTIVE_PASSIVE : indicates whether an active or passive OPEN is
  9316. --               desired.
  9317. --      TIMEOUT : The timeout for transmitting data. if some data does not get
  9318. --             through in the required time the connection is aborted.
  9319. --      SECURITY : The request for a level of security.  Which must be a
  9320. --              legal level.
  9321. --      PRECEDENCE : The precedence of the connection. Used in a multi-level,
  9322. --                secure environment.
  9323. --      OPTIONS :  This data structure will contain a request for any options
  9324. --             desired.  Currently none will be.
  9325. --
  9326. -- RESTRICTIONS :
  9327. --
  9328. --   CURRENTLY WE ALLOW ONLY ONE CONNECTION PER PORT.
  9329. --
  9330.         NO_ROOM_FOR_CONNECTION : BOOLEAN := FALSE;
  9331.         UMESSAGE : USER_MESSAGE;
  9332.         SOCKET_PARAMS : LCN_PTR_TYPE;
  9333.      
  9334.         begin
  9335. --         if ACTIVE_PASSIVE = WITH_TCP_COMMUNICATE.PASSIVE then
  9336.           LCN := TCB_GET; -- SEND THE LCN BACK TO THE USER.
  9337.           TCB_CLEAR( LCN ) ; -- Clear TCB.
  9338.           SOCKET_PARAMS.LCN := LCN ;
  9339.           LCN.TCP_CHANNEL_NAME := LOCAL_CONN_NAME.CHANNEL_NAME ;
  9340.           LCN.TCP_CHANNEL_PTR := LOCAL_CONN_NAME.CHANNEL_PTR ;
  9341.           SOCKET_PARAMS.CHANNEL_NAME := LOCAL_CONN_NAME.CHANNEL_NAME ;
  9342.           SOCKET_PARAMS.CHANNEL_PTR := LOCAL_CONN_NAME.CHANNEL_PTR ;
  9343.           LOCAL_CONN_NAME.LCN := LCN ;
  9344.           UMESSAGE := (14, SOCKET_PARAMS);
  9345.           MESSAGE_FOR_USER(UMESSAGE);
  9346.           LCN.LOCAL_PORT := LOCAL_PORT;
  9347. --         else --set lcn
  9348. --          LCN := LOCAL_CONN_NAME.LCN;
  9349. --         end if ;
  9350.          if LCN.STATE = T_TCP_GLOBALS_DATA_STRUCTURES.CLOSED then
  9351.           if USER_ACCESS_CHECK(LCN) then
  9352.            -- TELL USER ERROR: CONNECTION ILLEGAL FOR THIS PROCESS.
  9353.            SOCKET_PARAMS.LCN := LCN;
  9354.            SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  9355.            SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  9356.            UMESSAGE := ( 2,
  9357.                          SOCKET_PARAMS);
  9358.            MESSAGE_FOR_USER(UMESSAGE);
  9359.           elsif NO_ROOM_FOR_CONNECTION then -- THERE IS CURRENTLY ALWAYS ROOM
  9360.            -- TELL USER ERROR: INSUFFICIENT RESOURCES
  9361.            PUT_LINE("IN OPEN INSUF RESOURCES");-- DEBUG
  9362.            SOCKET_PARAMS.LCN := LCN;
  9363.            SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  9364.            SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  9365.            UMESSAGE := ( 5,
  9366.                          SOCKET_PARAMS);
  9367.            MESSAGE_FOR_USER(UMESSAGE);
  9368.           elsif ACTIVE_PASSIVE = WITH_TCP_COMMUNICATE.ACTIVE then
  9369.            if PRECEDENCE < 0 or (PRECEDENCE > 7) then
  9370.             -- TELL USER ERROR: PRECEDENCE NOT ALLOWED
  9371.             SOCKET_PARAMS.LCN := LCN;
  9372.             SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  9373.             SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  9374.             UMESSAGE := ( 9,
  9375.                           SOCKET_PARAMS);
  9376.             MESSAGE_FOR_USER(UMESSAGE);
  9377.            elsif SECURITY < 0 or (SECURITY > 7) then
  9378.             -- TELL USER ERROR: SECURITY/COMPARTMENT NOT ALLOWED
  9379.             SOCKET_PARAMS.LCN := LCN;
  9380.             SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  9381.             SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  9382.             UMESSAGE := ( 11,
  9383.                           SOCKET_PARAMS);
  9384.             MESSAGE_FOR_USER(UMESSAGE);
  9385.            elsif FOREIGN_NET_HOST = 0 then
  9386.             -- TELL USER ERROR: FOREIGN SOCKET  UNSPECIFIED
  9387.             SOCKET_PARAMS.LCN := LCN;
  9388.             SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  9389.             SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  9390.             UMESSAGE := ( 4,
  9391.                           SOCKET_PARAMS);
  9392.             MESSAGE_FOR_USER(UMESSAGE);
  9393.            else
  9394.             -- START THE TIMEOUT FOR CONNECTION TIMER
  9395.             if TIMEOUT /= 0 then -- PUT IN THE NEW CONNECTION TIMEOUT.
  9396.              LCN.CONNECTION_TIMEOUT := TIMEOUT;
  9397.             end if;
  9398.             START_TIMER(LCN, TIMEOUT_TIMER);
  9399.             -- SET UP THE TCB
  9400.             LCN.DESTINATION_ADDRESS := FOREIGN_NET_HOST;
  9401.             LCN.FOREIGN_PORT := FOREIGN_PORT;
  9402.             -- SET UP THE TCB NET AND HOST ADDRESSES BY
  9403.             -- DECODING THE CONCATENATION OF FOREIGN_NET AND
  9404.             --  FOREIGN HOST.
  9405.             ADDRESS_DECODER(FOREIGN_NET_HOST);
  9406.             SEND_A_SYN(LCN);
  9407.             LCN.STATE := SYN_SENT; -- ENTER THE SYN-SENT        STATE
  9408.            end if;
  9409.           else -- THIS IS A PASSIVE OPEN
  9410.            if FOREIGN_NET_HOST /= 0 then
  9411.             -- SET UP THE TCB.
  9412.             LCN.FOREIGN_PORT := FOREIGN_PORT;
  9413.             LCN.DESTINATION_ADDRESS := FOREIGN_NET_HOST ;
  9414.             -- DECODE THE TCB DESTINATION ADDRESS. A CONCATENATION
  9415.             -- OF FOREIGN_NET AND FOREIGN HOST AND PUT IT
  9416.             -- IN THE APPROPRIATE VARIABLES IN THE TCB.
  9417.             ADDRESS_DECODER(FOREIGN_NET_HOST);
  9418.            end if;
  9419.            if TIMEOUT /= 0 then -- PUT IN THE NEW CONNECTION TIMEOUT.
  9420.             LCN.CONNECTION_TIMEOUT := TIMEOUT;
  9421.            end if;
  9422.            LCN.ACTIVE_PASSIVE := T_TCP_GLOBALS_DATA_STRUCTURES.PASSIVE; 
  9423.         -- A PASSIVE OPEN
  9424.            LCN.STATE := T_TCP_GLOBALS_DATA_STRUCTURES.LISTEN;
  9425.            -- ENTER THE LISTEN STATE
  9426.           end if;
  9427.          elsif LCN.STATE = T_TCP_GLOBALS_DATA_STRUCTURES.LISTEN then
  9428.           if ACTIVE_PASSIVE = WITH_TCP_COMMUNICATE.ACTIVE then
  9429.            if FOREIGN_NET_HOST = 0 then
  9430.             -- TELL USER ERROR: FOREIGN SOCKET UNSPECIFIED
  9431.             SOCKET_PARAMS.LCN := LCN;
  9432.             SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  9433.             SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  9434.             UMESSAGE := ( 4,
  9435.                           SOCKET_PARAMS);
  9436.             MESSAGE_FOR_USER(UMESSAGE);
  9437.            else
  9438.             -- SET UP THE TCB
  9439.             LCN.ACTIVE_PASSIVE := T_TCP_GLOBALS_DATA_STRUCTURES.ACTIVE;
  9440.             -- CONNECTION NOW ACTIVE.
  9441.             LCN.FOREIGN_PORT := FOREIGN_PORT;
  9442.             LCN.DESTINATION_ADDRESS := FOREIGN_NET_HOST ;
  9443.             -- START THE CONNECTION TIMEOUT TIMER.
  9444.             START_TIMER(LCN, TIMEOUT_TIMER);--not used presently (JB 1/25/85)
  9445.             -- DECODE THE TCB DESTINATION ADDRESS. A CONCATENATION
  9446.             -- OF FOREIGN_NET AND FOREIGN HOST AND PUT IT IN
  9447.             -- THE APPROPRIATE VARIABLES IN THE TCB
  9448.             ADDRESS_DECODER(FOREIGN_NET_HOST);
  9449.             SEND_A_SYN(LCN);
  9450.             LCN.STATE := SYN_SENT; -- ENTER THE SYN_SENT STATE
  9451.            end if;
  9452.           end if;
  9453.           if TIMEOUT /= 0 then -- PUT IN THE NEW CONNECTION TIMEOUT.
  9454.            LCN.CONNECTION_TIMEOUT := TIMEOUT;
  9455.           end if;
  9456.          else -- THERE ALREADY IS A CONNECTION
  9457.           -- TELL USER ERROR: CONNECTION ALREADY EXISTS
  9458.          SOCKET_PARAMS.LCN := LCN;
  9459.          SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  9460.          SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  9461.          UMESSAGE := ( 12,
  9462.                        SOCKET_PARAMS);
  9463.          MESSAGE_FOR_USER(UMESSAGE);
  9464.         end if;
  9465.        end TCP_OPEN;
  9466.      
  9467.  procedure TCP_STATUS( LCN : in TCB_PTR) is
  9468.      
  9469.         --This subprogram returns the status of a connection, specified by the
  9470.         --LCN to the user layer.  It also returns a pointer to the TCB for the
  9471.         --connection, which will indicate the state of the connection(OPEN
  9472.         --or CLOSED).  The subprogram is called by the user interface via the
  9473.         --TCP controller.  LCN is passed as a parameter to the subprogram.
  9474.      
  9475. STATE : WITH_TCP_COMMUNICATE.STATUS_TYPE;
  9476. STATUS_REC : STATUS_RECORD;
  9477. UMESSAGE :USER_MESSAGE;
  9478. SOCKET_PARAMS : LCN_PTR_TYPE;
  9479.      
  9480. begin
  9481.  T_TCP_GLOBALS_DATA_STRUCTURES.LCN := LCN; -- FOR TEST
  9482.  if USER_ACCESS_CHECK(LCN) then
  9483.   -- TELL USER ERROR: CONNECTION ILLEGAL FOR THIS PROCESS
  9484.   SOCKET_PARAMS.LCN := LCN;
  9485.   SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  9486.   SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  9487.   UMESSAGE := ( 2,
  9488.                 SOCKET_PARAMS);
  9489.   MESSAGE_FOR_USER(UMESSAGE);
  9490.  elsif LCN.STATE = T_TCP_GLOBALS_DATA_STRUCTURES.CLOSED THEN
  9491.   -- TELL USER ERROR CONNECTION DOES NOT EXIST
  9492.   SOCKET_PARAMS.LCN := LCN;
  9493.   SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  9494.   SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  9495.   UMESSAGE := ( 3,
  9496.                 SOCKET_PARAMS);
  9497.   MESSAGE_FOR_USER(UMESSAGE);
  9498.  else
  9499.   NEW_LINE; --FOR DEBUG
  9500.   PUT_LINE("ULP just requested a STATUS");
  9501.   STATUS_REC.SOURCE_PORT := LCN.LOCAL_PORT;
  9502.   STATUS_REC.SOURCE_ADDRESS := LCN.SOURCE_ADDRESS;
  9503.   STATUS_REC.DESTINATION_PORT := LCN.FOREIGN_PORT;
  9504.   STATUS_REC.DESTINATION_ADDRESS := LCN.DESTINATION_ADDRESS;
  9505.   -- THE POSITIONS OF THE ENUMERATED DATA IN EACH RECORD IS THE SAME.
  9506.   -- THEREFORE THE VALUE OF THE CORRESPONDING TYPE GIVES YOU THE CORRECT
  9507.   -- ENUMERATION VALUE.
  9508.   STATUS_REC.CONNECTION_STATE :=
  9509.         STATE_TYPE'VAL(STATES'POS(LCN.STATE));
  9510.   STATUS_REC.STATUS:= WITH_TCP_COMMUNICATE.STATUS_TYPE'VAL(
  9511.     T_TCP_GLOBALS_DATA_STRUCTURES.STATUS_TYPE'POS(LCN.CONNECTION_STATUS));
  9512.   STATUS_REC.LOCAL_RCV_WINDOW := LCN.RCV_WINDOW;
  9513.   STATUS_REC.REMOTE_RCV_WINDOW := LCN.SND_WND;
  9514.   STATUS_REC.OCTETS_ON_RETRANSMIT_QUEUE :=
  9515.   LCN.QHEADS(TCP_RETRANSMIT_QUEUE).ELEMENT_COUNT;
  9516.   -- THIS IS SIMPLE
  9517.   -- UNTIL WE HAVE VARIABLE SIZE PACKETS ON THE QUEUE.
  9518.   STATUS_REC.URGENT_STATE := LCN.USER_NOTIFICATION;
  9519.   -- IF NOTIFIED OF URG.  DATA
  9520.   STATUS_REC.PRECEDENCE := LCN.PRECEDENCE;
  9521.   for I in 1..9 loop -- COPY SECURITY PARAMS
  9522.    STATUS_REC.SECURITY(I) :=  LCN.SECURITY(I);
  9523.   end loop;
  9524.   STATUS_REC.ULP_TIMEOUT := LCN.CONNECTION_TIMEOUT;
  9525.   -- NOW MESSAGE MUST GET BACK TO THE USER INTERFACE.
  9526.   SOCKET_PARAMS.LCN := LCN;
  9527.   SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  9528.   SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  9529.   UMESSAGE := ( 15,
  9530.                 SOCKET_PARAMS,
  9531.                 STATUS_REC);
  9532.   MESSAGE_FOR_USER(UMESSAGE);
  9533.  end if;
  9534. exception
  9535.  when others =>
  9536.   PUT_LINE(" ERROR IN TCP STATUS");
  9537. end TCP_STATUS;
  9538.      
  9539. procedure RETRANS_TCP( LCN : in TCB_PTR) is
  9540.      
  9541.         --This subprogram will get a segment off the retransmission queue and
  9542.         --send it to the IP for transmission to the remote host. It will
  9543.         --update the window in the segment.  This subprogram is called when
  9544.         --a retransmission timeout has occured. It will retransmit a segment
  9545.         --to the remote host.  A LCN is passed into the subprogram which pop
  9546.         --a segment off the retransmit to the IP for the remote host.
  9547.      
  9548.         -- ALLOWS US TO ADD TO THE IP ID MOD 2**16.
  9549.         Q_ITEM : STD_Q_ITEM;
  9550.         PACKED_BUFF : PACKED_BUFFER_PTR;
  9551.         BYTE_COUNT : SIXTEEN_BITS ; -- LENGTH OF BUFFER FROM RETRANSMIT QUEUE
  9552.         MESSAGE_FOR_IP : IP_GLOBALS.IP_MESSAGE ;
  9553.      
  9554.         begin
  9555.          --  GET A SEGMENT OFF THE RETRANS QUEUE.
  9556.          QUEUE_GET(TCP_RETRANSMIT_QUEUE, LCN, Q_ITEM);
  9557.          if Q_ITEM.BUFFER /= null then
  9558.           if not Q_ITEM.BUFFER.IN_USE then --its not still waiting
  9559.                                            --for transmission
  9560.            PACKED_BUFF := Q_ITEM.BUFFER;
  9561.            BYTE_COUNT := Q_ITEM.LENGTH;
  9562.            --Reset the IP pointer in the buffer
  9563.            PACKED_BUFF.IP_PTR := PACKED_BUFF.TCP_PTR - 1;
  9564.            --IT WILL NOT BE OUR RESPONSIBILITY TO DETERMINE THE MAX TIME FOR A
  9565.            --TRANS.  THAT WILL BELONG TO THE USER LAYER. THE DATAGRAM LAYER MAY
  9566.            --ALSO HAVE A TIME TO LIVE.  WE CAN ALWAYS SEND FROM THE RETRANSMIT
  9567.            --QUEUE WE WILL USE THE PREVIOUSLY PACKED BUFFER FROM THE RETRANS Q
  9568.            --AS IS.
  9569.      
  9570.            -- SET UP ID FOR IP
  9571.            IDENT := LCN.RETRANS_IDENT;
  9572.            --   LCN.IDENT := LCN.IDENT + 1;
  9573.            MESSAGE_FOR_IP := ( FROM_TCP,
  9574.                                PACKED_BUFF,
  9575.                                LCN.DESTINATION_ADDRESS,
  9576.                                TOS,
  9577.                                TTL,
  9578.                                BYTE_COUNT,
  9579.                                IDENT,
  9580.                                DONT_FRAGMENT,
  9581.                                OPTIONS,
  9582.                                LCN.SOURCE_ADDRESS ) ;
  9583.            IP_FROM_TCP.Q_ADD( MESSAGE_FOR_IP ) ;
  9584.           end if;
  9585.           QUEUE_ADD(TCP_RETRANSMIT_QUEUE, LCN, Q_ITEM);
  9586.          else
  9587.           TCP_ERROR(4);
  9588.          end if;
  9589.         end RETRANS_TCP;
  9590.      
  9591. end T_TCP_CONTROLLER_UTILITIES;
  9592.      
  9593. --::::::::::::::
  9594. --tcp_controller_.ada
  9595. --::::::::::::::
  9596. -----------------------------------------------------------------------
  9597. --
  9598. --         DoD Protocols    NA-00001-200       80-01014-100(-)
  9599. --         E-Systems, Inc.  August 07, 1985
  9600. --
  9601. --         TCP_CONTROLLER_.ADA       Author : Jim Baldo
  9602. --
  9603. -----------------------------------------------------------------------
  9604.      
  9605.                 package TCP_CONTROLLER_TASK is
  9606.      
  9607.         --------------------------------------------------------------
  9608.         --This implementation is for the DEC/Ada compiler .         --
  9609.         --------------------------------------------------------------
  9610.      
  9611. ------------------------------------------------------------------------------
  9612. -- This package contains the necessary procedures and functions to control  --
  9613. -- the transmission control protocol(TCP) activities in general and         --
  9614. -- specifically all activities associated with ULP commands to TCP.          --
  9615. ------------------------------------------------------------------------------
  9616.      
  9617.      
  9618. task TCP_CONTROLLER;
  9619.      
  9620. -- The TCP_CONTROLLER task  is responsible for the control and operation of
  9621. -- the TCP layer.   It  determines the necessary actions after it gets
  9622. --a message from the communications queue. It then calls the procedure
  9623. -- that will cause that task to be  performed.  A task message is
  9624. -- gotten via an entry into the communication task.  This message is
  9625. -- used to call a procedure to process the request for action made to the TCP.
  9626. --
  9627. --The following procedures are contained within the package body and
  9628. --are used by TCP_CONTROLLER to perform the specific processing for each
  9629. --event.  It should be noted that the event processing defined below
  9630. --is specifed by MIL-STD-1778.
  9631. --
  9632. --   TCP_SEND - This procedure will process a send request from the user.
  9633. --
  9634. --   TCP_ABORT - This procedure will cause a connection to be aborted. the
  9635. --               user requests this action.
  9636. --
  9637. --   TCP_RECEIVE - This procedure will cause any data from a remote site to
  9638. --                 the user to be returned to the user.
  9639. --
  9640. --   TCP_CLOSE - This procedure will cause a connection to be closed.
  9641. --
  9642. --   TCP_OPEN - This procedure will attempt to open an active or passive
  9643. --              connection to a remote host as required by the user.
  9644. --
  9645. --   TCP_STATUS - This procedure will return the status of a connection to
  9646. --                the user.
  9647. --
  9648. --   TCP_ERROR - This procedure will handle any errors that may come to the
  9649. --               attention of the TCP. They may be TCP errors or error
  9650. --               notifications from other layers of protocol.
  9651. --
  9652. --   RETRANS_TCP - This procedure will retransmit the first packet in the
  9653. --                 retransmit queue.
  9654. --
  9655. --   TCP_SEG_ARRIVE - This procedure determines the action to be taken upon
  9656. --                    reception of segment. It will then call a routine to
  9657. --                    perform the action. The action is based on the state of
  9658. --                    the connection.
  9659. --
  9660. --   MESSAGE_FOR_USER - Give a message to the user layer.
  9661.      
  9662.      
  9663. end TCP_CONTROLLER_TASK ;
  9664. --::::::::::::::
  9665. --tcp_controller.ada
  9666. --::::::::::::::
  9667. -----------------------------------------------------------------------
  9668. --
  9669. --         DoD Protocols    NA-00001-200       80-01015-100(-)
  9670. --         E-Systems, Inc.  August 07, 1985
  9671. --
  9672. --         TCP_CONTROLLER.ADA       Author : Jim Baldo
  9673. --
  9674. -----------------------------------------------------------------------
  9675. with TCP_GLOBALS ;                      use TCP_GLOBALS ;
  9676. with TCP_SEGMENT_ARRIVES_PROCESSING ;   use TCP_SEGMENT_ARRIVES_PROCESSING ;
  9677. with TCP_ARRIVES_PERIPHERALS ;          use TCP_ARRIVES_PERIPHERALS ;
  9678. with BUFFER_DATA ;                      use BUFFER_DATA ;
  9679. with T_TCP_CONTROLLER_UTILITIES ;       use T_TCP_CONTROLLER_UTILITIES ;
  9680. with QUEUES ;                           use QUEUES ;
  9681. with TCP_TO_ULP_COMMUNICATE ;           use TCP_TO_ULP_COMMUNICATE ;
  9682. with REAL_TIME_CLOCK_AND_DATE ;         use REAL_TIME_CLOCK_AND_DATE ;
  9683. with TCB_ALLOCATOR ;                            use TCB_ALLOCATOR ;
  9684. with T_TCP_GLOBALS_DATA_STRUCTURES ;    use T_TCP_GLOBALS_DATA_STRUCTURES ;
  9685. with WITH_TCP_COMMUNICATE ;                     use WITH_TCP_COMMUNICATE ;
  9686. with TEXT_IO ;                                  use TEXT_IO ;
  9687. with GET_MESSAGES_FROM_ULP ;                    use GET_MESSAGES_FROM_ULP ;
  9688. with TCP_Q_TASK ;                               use TCP_Q_TASK ;
  9689. with CALENDAR ;                                 use CALENDAR ;
  9690.      
  9691.                 package body TCP_CONTROLLER_TASK is
  9692.      
  9693.         --------------------------------------------------------------
  9694.         --This implementation is for the DEC/Ada compiler .         --
  9695.         --------------------------------------------------------------
  9696.      
  9697.      
  9698. task body TCP_CONTROLLER is
  9699.      
  9700. package int_io_32 is new integer_io (thirtytwo_bits);
  9701.      
  9702. MESSAGE_FROM_IP : MESSAGE ;
  9703. UMESSAGE : USER_MESSAGE;
  9704. TASK_MESSAGE :  MESSAGE;
  9705. FLAG : BOOLEAN := TRUE; -- for message
  9706. RETRANSMIT : BOOLEAN := TRUE;
  9707. MAX_TEMP : SIXTEEN_BITS ;
  9708. SOCKET_PARAMS : LCN_PTR_TYPE;
  9709. TIMEOUT : constant DAY_DURATION := 1.0 ;
  9710. DELETE_A_LCN : BOOLEAN := FALSE;
  9711. TEMP_HOLDER_LCN : TCB_PTR := null ;
  9712.      
  9713. function DETERMINE_VALID_LCN( LCN : TCB_PTR ) return BOOLEAN is
  9714.      
  9715. VALID_LCN : TCB_PTR := null ;
  9716. RESULT : BOOLEAN := FALSE ;
  9717.      
  9718. begin
  9719.  VALID_LCN := OBTAIN_HEAD_OF_LCN_IN_USE_QUEUE;
  9720.  while VALID_LCN /= null loop
  9721.   if VALID_LCN = LCN then
  9722.    RESULT := TRUE ;
  9723.    RETURN RESULT;
  9724.   end if;
  9725.   VALID_LCN := VALID_LCN.NEXT ;
  9726.  end loop;
  9727.  RETURN RESULT;
  9728. end DETERMINE_VALID_LCN;
  9729.      
  9730. begin -- TCP_CONTROLLER
  9731.  loop
  9732.   --determine if any timeouts have occurred
  9733.   LCN := OBTAIN_HEAD_OF_LCN_IN_USE_QUEUE;
  9734.   while LCN /= null loop
  9735. --   put("system time = ");
  9736. --   int_io_32.put(thirtytwo_bits(system_time));
  9737. --   new_line;
  9738.    --Note that we will have a problem when the local_time_now cycles
  9739.    --every 6 hours.  We simply make the types modular.
  9740.    if LCN.STATE /= T_TCP_GLOBALS_DATA_STRUCTURES.CLOSED and
  9741.       (LCN.STATE /= T_TCP_GLOBALS_DATA_STRUCTURES.LISTEN) then
  9742.     --Check appropriate times and call necessary routine for any timeouts.
  9743.     if THIRTYTWO_BITS(SYSTEM_TIME) >= LCN.NEXT_CONNECTION_TIMEOUT and
  9744.        (LCN.NEXT_CONNECTION_TIMEOUT > 0) then
  9745.      --trash the connection and notify the user
  9746.      SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  9747.      SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  9748.      SOCKET_PARAMS.LCN := LCN;
  9749.      UMESSAGE := ( 24,
  9750.                    SOCKET_PARAMS);
  9751.      MESSAGE_FOR_USER( UMESSAGE);
  9752.      QUEUE_CLEAR(TCP_RETRANSMIT_QUEUE, LCN);
  9753.      QUEUE_CLEAR(TRANSMIT_QUEUE);
  9754.      QUEUE_CLEAR(TCP_RECEIVED_SEGMENT_QUEUE);
  9755.      QUEUE_CLEAR(RECEIVE_QUEUE);
  9756.      QUEUE_CLEAR(PROCESSED_SEGMENTS_FOR_USER_QUEUE);
  9757.      DELETE_A_LCN := TRUE;
  9758.      FLAG := FALSE;
  9759.     elsif THIRTYTWO_BITS(SYSTEM_TIME) >= LCN.NEXT_TIME_WAIT_TIMEOUT and
  9760.           (LCN.NEXT_TIME_WAIT_TIMEOUT > 0) then
  9761.      --Close it up.  User will now be informed it is closed.
  9762.      SOCKET_PARAMS.CHANNEL_NAME := LCN.TCP_CHANNEL_NAME ;
  9763.      SOCKET_PARAMS.CHANNEL_PTR := LCN.TCP_CHANNEL_PTR ;
  9764.      SOCKET_PARAMS.LCN := LCN;
  9765.      UMESSAGE := ( 18,
  9766.                    SOCKET_PARAMS);
  9767.      MESSAGE_FOR_USER(UMESSAGE);
  9768.      QUEUE_CLEAR(RECEIVE_QUEUE, LCN);
  9769.      DELETE_A_LCN := TRUE;
  9770.      FLAG := FALSE;
  9771.     elsif QUEUE_SIZE(TCP_RETRANSMIT_QUEUE) > 0 then
  9772.      --a more sophisticated retransmission scheme is needed!!
  9773.      while RETRANSMIT loop
  9774.       if THIRTYTWO_BITS(SYSTEM_TIME) >=
  9775.           QUEUE_RETRANS_TIME(LCN) +
  9776.           15
  9777. --          THIRTYTWO_BITS (LCN.RETRANS_INTERVAL) *
  9778. --          THIRTYTWO_BITS (100) --for VAX
  9779.           then
  9780.        --retransmit a segment
  9781.        RETRANS_TCP(LCN);
  9782.        new_line;--for debug(JB 3/6/85)
  9783.        put_line("just sent a retrans message");
  9784.        new_line;
  9785.        FLAG := FALSE;
  9786.       else
  9787.        RETRANSMIT := FALSE;
  9788.       end if;
  9789.      end loop;
  9790.      --reset the retransmit flag for the next lcn
  9791.      RETRANSMIT := TRUE; --do it the first time
  9792.     end if;
  9793.    end if; --main if
  9794.    if LCN.STATE = T_TCP_GLOBALS_DATA_STRUCTURES.ESTABLISHED and then
  9795.        (not QUEUE_EMPTY(TRANSMIT_QUEUE, LCN)) then
  9796.     SEND_FROM_TRANSMIT_QUEUE(LCN);
  9797.    end if;
  9798.    TEMP_HOLDER_LCN := LCN;
  9799.    LCN := LCN.NEXT;--obtain next connection
  9800.    if DELETE_A_LCN then
  9801.     TCB_CLEAR( TEMP_HOLDER_LCN ) ;
  9802.     TCB_FREE( TEMP_HOLDER_LCN ) ;
  9803.     DELETE_A_LCN := FALSE ;
  9804.    end if;
  9805.   end loop;
  9806.   select
  9807.    TCP_Q.Q_GET ( TASK_MESSAGE ) ;
  9808.    -- NOTE THE TASK MESSAGE IS A VARIANT RECORD WHICH WILL BE DELETED FROM
  9809.    -- QUEUE BY QUEING ROUTINE.
  9810.    case TASK_MESSAGE.EVENT is
  9811.     when SEND  =>        -- SET LOCAL FIELDS FROM QUEUE RECORD
  9812.      if DETERMINE_VALID_LCN( TASK_MESSAGE.SEND_PARAMETERS.LCN_BLOCK.LCN ) then
  9813.       TCP_SEND( TASK_MESSAGE.SEND_PARAMETERS.LCN_BLOCK.LCN,
  9814.                 TASK_MESSAGE.SEND_PARAMETERS.BUFPTR,
  9815.                 TASK_MESSAGE.SEND_PARAMETERS.BYTE_COUNT,
  9816.                 TASK_MESSAGE.SEND_PARAMETERS.PUSH_FLAG,
  9817.                 TASK_MESSAGE.SEND_PARAMETERS.URG_FLAG,
  9818.                 TASK_MESSAGE.SEND_PARAMETERS.TIMEOUT );
  9819.       else
  9820.        PUT_LINE("BOGUS SEND LCN");
  9821.       end if;
  9822.      
  9823.     when RECEIVE => --SET LOCAL FIELDS FROM QUEUE MESSAGE RECORD
  9824.     if DETERMINE_VALID_LCN( TASK_MESSAGE.RECEIVE_PARAMETERS.LCN_BLOCK.LCN ) then
  9825.       TCP_RECEIVE( TASK_MESSAGE.RECEIVE_PARAMETERS.LCN_BLOCK.LCN,
  9826.                    TASK_MESSAGE.RECEIVE_PARAMETERS.BUFPTR,
  9827.                    TASK_MESSAGE.RECEIVE_PARAMETERS.BYTE_COUNT ) ;
  9828.      else
  9829.       PUT_LINE("BOGUS RECEIVE LCN");
  9830.      end if;
  9831.      
  9832.     when ABOR_T =>
  9833.      if DETERMINE_VALID_LCN( TASK_MESSAGE.ABORT_CLOSE_PARAMETERS.LCN_BLOCK.LCN)
  9834.                                                                 then
  9835.       TCP_ABORT( TASK_MESSAGE.ABORT_CLOSE_PARAMETERS.LCN_BLOCK.LCN ) ;
  9836.        -- ABORT THE CONNECTION
  9837.      else
  9838.       PUT_LINE("BOGUS ABORT LCN");
  9839.      end if;
  9840.      
  9841.     when WITH_TCP_COMMUNICATE.CLOSE =>
  9842.      if DETERMINE_VALID_LCN( TASK_MESSAGE.ABORT_CLOSE_PARAMETERS.LCN_BLOCK.LCN )
  9843.      then
  9844.       TCP_CLOSE( TASK_MESSAGE.ABORT_CLOSE_PARAMETERS.LCN_BLOCK.LCN ) ;
  9845.      else
  9846.       PUT_LINE("BOGUS CLOSE LCN");
  9847.      end if;
  9848.      
  9849.     when WITH_TCP_COMMUNICATE.OPEN =>
  9850.      -- WE WILL SET THE LOCAL CONNECTION NAME HERE. IT WILL
  9851.      -- BE THE LOCAL PORT NUMBER TEMPORARILY.
  9852.           TCP_OPEN( TASK_MESSAGE.OPEN_PARAMETERS.LOCAL_PORT,
  9853.                TASK_MESSAGE.OPEN_PARAMETERS.FOREIGN_PORT,
  9854.                TASK_MESSAGE.OPEN_PARAMETERS.FOREIGN_NET_HOST,
  9855.                TASK_MESSAGE.OPEN_PARAMETERS.ACTIVE_PASSIVE,
  9856.                TASK_MESSAGE.OPEN_PARAMETERS.BUFFER_SIZE,
  9857.                TASK_MESSAGE.OPEN_PARAMETERS.TIMEOUT,
  9858.                TASK_MESSAGE.OPEN_PARAMETERS.LCN_BLOCK,
  9859.                TASK_MESSAGE.OPEN_PARAMETERS.SECURITY,
  9860.                TASK_MESSAGE.OPEN_PARAMETERS.PRECEDENCE,
  9861.                TASK_MESSAGE.OPEN_PARAMETERS.OPTIONS ) ;
  9862.      
  9863.     when STATUS =>
  9864.      if DETERMINE_VALID_LCN( TASK_MESSAGE.STATUS_PARAMETERS.LCN_BLOCK.LCN ) then
  9865.       TCP_STATUS( TASK_MESSAGE.STATUS_PARAMETERS.LCN_BLOCK.LCN ) ;
  9866.       -- THIS CONDITION MODELS THE TIME-OUT IN THE TIME-WAIT STATE WHICH USES
  9867.       -- A TIMER TO ENSURE THE CONNECTION IS CLOSED.
  9868.      else
  9869.       PUT_LINE("BOGUS STATUS LCN");
  9870.      end if;
  9871.      
  9872.     when TIMEOUT_IN_TIME_WAIT =>
  9873.      -- checked by tcp controller
  9874.      null;
  9875.      
  9876.     when ERROR_MESSAGE =>
  9877.      TCP_ERROR( TASK_MESSAGE.ERROR_PARAMETERS.ERROR_INDICATOR ) ;
  9878.      
  9879.     when TIMEOUT_IN_RETRANS_QUEUE =>
  9880.      -- checked by tcp controller
  9881.      null;
  9882.      
  9883.     when DATA_FROM_IP =>
  9884.      TCP_SEG_ARRIVE( TASK_MESSAGE.DATA_FROM_IP_PARAMETERS.BUFPTR,
  9885.                      TASK_MESSAGE.DATA_FROM_IP_PARAMETERS.BYTE_COUNT,
  9886.                      TASK_MESSAGE.DATA_FROM_IP_PARAMETERS.SOURCE_ADDRESS,
  9887.                      TASK_MESSAGE.DATA_FROM_IP_PARAMETERS.DESTINATION_ADDRESS,
  9888.                      TASK_MESSAGE.DATA_FROM_IP_PARAMETERS.PROTOCOL,
  9889.                      TASK_MESSAGE.DATA_FROM_IP_PARAMETERS.TOS,
  9890.                      TASK_MESSAGE.DATA_FROM_IP_PARAMETERS.SECURITY);
  9891.      
  9892.     when TIMER_TIMEOUT =>
  9893.      null;
  9894.      
  9895.     when NO_TCP_ACTION =>
  9896.      -- put_line("NO_TCP_ACTION");--for debug (JB 1/31/85)
  9897.      null;
  9898.      
  9899.   end case;
  9900.  or
  9901.   DELAY ( TIMEOUT ) ;
  9902.  end select ;
  9903. end loop ;
  9904. exception
  9905.  when CONSTRAINT_ERROR =>
  9906.   PUT_LINE("A CONSTRAINT ERROR WAS UNHANDLED IN TCP");
  9907.  when others =>
  9908.   PUT_LINE("UNKNOWN ERROR IN UNKNOWN ROUTINE OF TCP");
  9909. end TCP_CONTROLLER;
  9910.      
  9911. end TCP_CONTROLLER_TASK ;
  9912. --::::::::::::::
  9913. --tcp_standalone.ada
  9914. --::::::::::::::
  9915. -----------------------------------------------------------------------
  9916. --
  9917. --         DoD Protocols    NA-00001-200       80-01022-100(-)
  9918. --         E-Systems, Inc.  August 07, 1985
  9919. --
  9920. --         TCP_STANDALONE.ADA       Author : Jim Baldo
  9921. --
  9922. -----------------------------------------------------------------------
  9923. with BUFFER_DATA;
  9924. with ip_tcp;
  9925. with SUBNET_CALLS;      use SUBNET_CALLS;
  9926. with TCP_Q_TASK;
  9927. with GET_MESSAGES_FROM_ULP;
  9928. with SEND_IP_TASK;
  9929. with IP_FROM_SUBNET_TASK;
  9930. with TCP_CONTROLLER_TASK;
  9931.      
  9932. procedure TCP_STANDALONE is
  9933.      
  9934. begin
  9935.  START_SUBNET_DRIVER ;
  9936. --  null;
  9937. end TCP_STANDALONE ;
  9938. --::::::::::::::
  9939. --delete_mailboxes.ada
  9940. --::::::::::::::
  9941. with SYSTEM ;                   use SYSTEM ;
  9942. with TASKING_SERVICES;          use TASKING_SERVICES;
  9943. with STARLET;                   use STARLET;
  9944. with CONDITION_HANDLING;        use CONDITION_HANDLING;
  9945. with TEXT_IO;                   use TEXT_IO;
  9946.      
  9947. procedure DELETE_MAILBOXES_FOR_TESTER is
  9948.      
  9949. -- This procedure is used to delete permanent mailboxes created by
  9950. -- test programs.
  9951.      
  9952. MAILBOX_NAMES_CHANNEL : CHANNEL_TYPE;
  9953. TO_TCP_CHANNEL : CHANNEL_TYPE;
  9954. RETURN_STATUS : COND_VALUE_TYPE;
  9955. MAILBOX_NAME : STRING(1..7) ;
  9956. TEMP_MAILBOX_NAME : STRING(1..4);
  9957. LENGTH : NATURAL ;
  9958.      
  9959. begin
  9960.  loop
  9961.   MAILBOX_NAME := "MBA    " ;
  9962.   TEMP_MAILBOX_NAME := "    ";
  9963.   PUT("Enter Mailbox Number := ") ;
  9964.   GET_LINE(TEMP_MAILBOX_NAME, LENGTH) ;
  9965.   if TEMP_MAILBOX_NAME(1) = '0' then
  9966.    exit ;
  9967.   end if ;
  9968.   for I in 1..4 loop
  9969.    if TEMP_MAILBOX_NAME(I) /= ' ' then
  9970.     MAILBOX_NAME(3 + I) := TEMP_MAILBOX_NAME(I);
  9971.    else
  9972.     MAILBOX_NAME(3 + I) := ':';
  9973.     exit;
  9974.    end if;
  9975.   end loop;
  9976.   ASSIGN( STATUS => RETURN_STATUS,
  9977.           CHAN   => TO_TCP_CHANNEL,
  9978.           DEVNAM => MAILBOX_NAME);
  9979.      
  9980.   if SUCCESS ( RETURN_STATUS ) then
  9981.    PUT_LINE ( "Successful assign TO MAILBOX " ) ;
  9982.   else
  9983.    PUT_LINE ( "Unsuccessful assign TO_MAILBOX " ) ;
  9984.   end if ;
  9985.      
  9986.   DELMBX( STATUS => RETURN_STATUS,
  9987.           CHAN   => TO_TCP_CHANNEL );
  9988.      
  9989.   if SUCCESS ( RETURN_STATUS ) then
  9990.    PUT_LINE ( "Successful delete TO_MAILBOX " ) ;
  9991.   else
  9992.    PUT_LINE ( "Unsuccessful delete TO_MAILBOX " ) ;
  9993.   end if ;
  9994.  end loop ;
  9995.      
  9996. end DELETE_MAILBOXES_FOR_TESTER ;
  9997.      
  9998.