home *** CD-ROM | disk | FTP | other *** search
/ Unix System Administration Handbook 1997 October / usah_oct97.iso / rfc / 900s / rfc963.txt < prev    next >
Text File  |  1992-09-22  |  44KB  |  1,084 lines

  1.  
  2.  
  3. Network Working Group                                 Deepinder P. Sidhu
  4. Request for Comments: 963                          Iowa State University
  5.                                                            November 1985
  6.  
  7.               SOME PROBLEMS WITH THE SPECIFICATION OF THE
  8.                   MILITARY STANDARD INTERNET PROTOCOL
  9.  
  10.  
  11. STATUS OF THIS MEMO
  12.  
  13.    The purpose of this RFC is to provide helpful information on the
  14.    Military Standard Internet Protocol (MIL-STD-1777) so that one can
  15.    obtain a reliable implementation of this protocol standard.
  16.    Distribution of this note is unlimited.
  17.  
  18. ABSTRACT
  19.  
  20.    This paper points out several significant problems in the
  21.    specification of the Military Standard Internet Protocol
  22.    (MIL-STD-1777, dated August 1983 [MILS83a]).  These results are based
  23.    on an initial investigation of this protocol standard.  The problems
  24.    are: (1) a failure to reassemble fragmented messages completely; (2)
  25.    a missing state transition; (3) errors in testing for reassembly
  26.    completion; (4) errors in computing fragment sizes; (5) minor errors
  27.    in message reassembly; (6) incorrectly computed length for certain
  28.    datagrams.  This note also proposes solutions to these problems.
  29.  
  30. 1.  Introduction
  31.  
  32.    In recent years, much progress has been made in creating an
  33.    integrated set of tools for developing reliable communication
  34.    protocols.  These tools provide assistance in the specification,
  35.    verification, implementation and testing of protocols.  Several
  36.    protocols have been analyzed and developed using such tools.
  37.    Examples of automated verification and implementation of several real
  38.    world protocols are discussed in [BLUT82] [BLUT83] [SIDD83] [SIDD84].
  39.  
  40.    We are currently working on the automatic implementation of the
  41.    Military Standard Internet Protocol (IP).  This analysis will be
  42.    based on the published specification [MILS83a] of IP dated 12 August
  43.    1983.
  44.  
  45.    While studying the MIL Standard IP specification, we have noticed
  46.    numerous errors in the specification of this protocol.  One
  47.    consequence of these errors is that the protocol will never deliver
  48.    fragmented incoming datagrams; if this error is corrected, such
  49.    datagrams will be missing some data and their lengths will be
  50.    incorrectly reported.  In addition, outgoing datagrams that are
  51.    divided into fragments will be missing some data.  The proof of these
  52.    statements follows from the specification of IP [MILS83a] as
  53.    discussed below.
  54.  
  55.  
  56. Sidhu                                                           [Page 1]
  57.  
  58.  
  59.  
  60. RFC 963                                                    November 1985
  61. Some Problems with MIL-STD IP
  62.  
  63.  
  64. 2.  Internet Protocol
  65.  
  66.    The Internet Protocol (IP) is a network layer protocol in the DoD
  67.    protocol hierarchy which provides communication across interconnected
  68.    packet-switched networks in an internetwork environment.  IP provides
  69.    a pure datagram service with no mechanism for reliability, flow
  70.    control, sequencing, etc.  Instead, these features are provided by a
  71.    connection-oriented protocol, DoD Transmission Control Protocol (TCP)
  72.    [MILS83b], which is implemented in the layer above IP.  TCP is
  73.    designed to operate successfully over channels that are inherently
  74.    unreliable, i.e., which can lose, damage, duplicate, and reorder
  75.    packets.
  76.  
  77.    Over the years, DARPA has supported specifications of several
  78.    versions of IP; the last one appeared in [POSJ81].  A few years ago,
  79.    the Defense Communications Agency decided to standardize IP for use
  80.    in DoD networks.  For this purpose, the DCA supported formal
  81.    specification of this protocol, following the design discussed in
  82.    [POSJ81] and the technique and organization defined in [SDC82].  A
  83.    detailed specification of this protocol, given in [MILS83a], has been
  84.    adopted as the DoD standard for the Internet Protocol.
  85.  
  86.    The specification of IP state transitions is organized into decision
  87.    tables; the decision functions and action procedures are specified in
  88.    a subset of Ada[1], and may employ a set of machine-specific data
  89.    structures.  Decision tables are supplied for the pairs <state name,
  90.    interface event> as follows: <inactive, send from upper layer>,
  91.    <inactive, receive from lower layer>, and <reassembling, receive from
  92.    lower layer>.  To provide an error indication in the case that some
  93.    fragments of a datagram are received but some are missing, a decision
  94.    table is also supplied for the pair <reassembling, reassembly time
  95.    limit elapsed>.  (The event names are English descriptions and not
  96.    the names employed by [MILS83a].)
  97.  
  98. 3.  Problems with MIL Standard IP
  99.  
  100.    One of the major functions of IP is the fragmentation of datagrams
  101.    that cannot be transmitted over a subnetwork in one piece, and their
  102.    subsequent reassembly.  The specification has several problems in
  103.    this area.  One of the most significant is the failure to insert the
  104.    last fragment of an incoming datagram; this would cause datagrams to
  105.    be delivered to the upper-level protocol (ULP) with some data
  106.    missing. Another error in this area is that an incorrect value of the
  107.    data length for reassembled datagrams is passed to the ULP, with
  108.    unpredictable consequences.
  109.  
  110.    As the specification [MILS83a] is now written, these errors are of
  111.  
  112.  
  113. Sidhu                                                           [Page 2]
  114.  
  115.  
  116.  
  117. RFC 963                                                    November 1985
  118. Some Problems with MIL-STD IP
  119.  
  120.  
  121.    little consequence, since the test for reassembly completion will
  122.    always fail, with the result that reassembled datagrams would never
  123.    be delivered at all.
  124.  
  125.    In addition, a missing row in one of the decision tables creates the
  126.    problem that network control (ICMP) messages that arrive in fragments
  127.    will never be processed.  Among the other errors are the possibility
  128.    that a few bytes will be discarded from each fragment transmitted and
  129.    certain statements that will create run-time exceptions instead of
  130.    performing their intended functions.
  131.  
  132.    A general problem with this specification is that the program
  133.    language and action table portions of the specification were clearly
  134.    not checked by any automatic syntax checking process.  Variable and
  135.    procedure names are occasionally misspelled, and the syntax of the
  136.    action statements is often incorrect.  We have enumerated some of
  137.    these problems below as a set of cautionary notes to implementors,
  138.    but we do not claim to have listed them all.  In particular, syntax
  139.    errors are only discussed when they occur in conjunction with other
  140.    problems.
  141.  
  142.    The following section discusses some of the serious errors that we
  143.    have discovered with the MIL standard IP [MIL83a] during our initial
  144.    study of this protocol.  We also propose corrections to each of these
  145.    problems.
  146.  
  147. 4.  Detailed Discussion of the Problems
  148.  
  149.    Problem 1: Failure to Insert Last Fragment
  150.  
  151.       This problem occurs in the decision table corresponding to the
  152.       state reassembling and the input "receive from lower layer"
  153.       [MILS83a, sec 9.4.6.1.3].  The problem occurs in the following row
  154.       of this table:[2]
  155.  
  156.       ________________________________________________________
  157.       check-    SNP      TTL    where    a     reass    ICMP
  158.        sum     params   valid    to     frag   done    check-
  159.       valid?   valid?     ?       ?      ?       ?      sum?
  160.       __________________________________________________________________
  161.       YES      YES      YES     ULP    YES     YES      d      reass_
  162.                                                                delivery;
  163.                                                                state :=
  164.                                                                 INACTIVE
  165.       __________________________________________________________________
  166.  
  167.       The reass_done function, as will be seen below, returns YES if the
  168.  
  169.  
  170. Sidhu                                                           [Page 3]
  171.  
  172.  
  173.  
  174. RFC 963                                                    November 1985
  175. Some Problems with MIL-STD IP
  176.  
  177.  
  178.       fragment just received is the last fragment needed to assemble a
  179.       complete datagram and NO otherwise.  The action procedure
  180.       reass_delivery simply delivers a completely reassembled datagram
  181.       to the upper-level protocol.  It is the action procedure
  182.       reassemble that inserts an incoming fragment into the datagram
  183.       being assembled.  Since this row does not call reassemble, the
  184.       result will be that every incoming fragmented datagram will be
  185.       delivered to the upper layer with one fragment missing.  The
  186.       solution is to rewrite this row of the table as follows:
  187.  
  188.       ________________________________________________________
  189.       check-    SNP      TTL    where    a     reass    ICMP
  190.        sum     params   valid    to     frag   done    check-
  191.       valid?   valid?     ?       ?      ?       ?      sum?
  192.       __________________________________________________________________
  193.       YES      YES      YES     ULP    YES     YES      d    reassemble;
  194.                                                                reass_
  195.                                                                delivery;
  196.                                                                state :=
  197.                                                                 INACTIVE
  198.       __________________________________________________________________
  199.  
  200.       Incidentally, the mnemonic value of the name of the reass_done
  201.       function is questionable, since at the moment this function is
  202.       called datagram reassembly cannot possibly have been completed.  A
  203.       better name for this function might be last_fragment.
  204.  
  205.    Problem 2: Missing State Transition
  206.  
  207.       This problem is the omission of a row of the same decision table
  208.       [MILS83a, sec 9.4.6.1.3].  Incoming packets may be directed to an
  209.       upper-level protocol (ULP), or they may be network control
  210.       messages, which are marked ICMP (Internet Control Message
  211.       Protocol).  When control messages have been completely assembled,
  212.       they are processed by an IP procedure called analyze.  The
  213.       decision table contains the row
  214.  
  215.       ________________________________________________________
  216.       check-    SNP      TTL    where    a     reass    ICMP
  217.        sum     params   valid    to     frag   done    check-
  218.       valid?   valid?     ?       ?      ?       ?      sum?
  219.       __________________________________________________________________
  220.       YES      YES      YES    ICMP    YES     NO       d    reassemble;
  221.       __________________________________________________________________
  222.  
  223.  
  224.  
  225.  
  226.  
  227. Sidhu                                                           [Page 4]
  228.  
  229.  
  230.  
  231. RFC 963                                                    November 1985
  232. Some Problems with MIL-STD IP
  233.  
  234.  
  235.       but makes no provision for the case in which where_to returns
  236.       ICMP, a_frag returns YES, and reass_done returns YES.  An
  237.       additional row should be inserted, which reads as follows:
  238.  
  239.       ________________________________________________________
  240.       check-    SNP      TTL    where    a     reass    ICMP
  241.        sum     params   valid    to     frag   done    check-
  242.       valid?   valid?     ?       ?      ?       ?      sum?
  243.       __________________________________________________________________
  244.       YES      YES      YES    ICMP    YES     YES      d    reassemble;
  245.                                                                analyze;
  246.                                                                state :=
  247.                                                                 INACTIVE
  248.       __________________________________________________________________
  249.  
  250.       Omitting this row means that incoming fragmented ICMP messages
  251.       will never be analyzed, since the state machine does not have any
  252.       action specified when the last fragment is received.
  253.  
  254.    Problem 3: Errors in reass_done
  255.  
  256.       The function reass_done, as can be seen from the above, determines
  257.       whether the incoming subnetwork packet contains the last fragment
  258.       needed to complete the reassembly of an IP datagram.  In order to
  259.       understand the errors in this function, we must first understand
  260.       how it employs its data structures.
  261.  
  262.       The reassembly of incoming fragments is accomplished by means of a
  263.       bit map maintained separately for each state machine.  Since all
  264.       fragments are not necessarily the same length, each bit in the map
  265.       represents not a fragment, but a block, that is, a unit of eight
  266.       octets.  Each fragment, with the possible exception of the "tail"
  267.       fragment (we shall define this term below), is an integral number
  268.       of consecutive blocks. Each fragment's offset from the beginning
  269.       of the datagram is given, in units of blocks, by a field in the
  270.       packet header of each incoming packet.  The total length of each
  271.       fragment, including the fragment's header, is specified in the
  272.       header field total_length; this length is given in octets.  The
  273.       length of the header is specified in the field header_length; this
  274.       length is given in words, that is, units of four octets.
  275.  
  276.       In analyzing this subroutine, we must distinguish between the
  277.       "tail" fragment and the "last" fragment.  We define the last
  278.       fragment as the one which is received last in time, that is, the
  279.       fragment that permits reassembly to be completed.  The tail
  280.       fragment is the fragment that is spatially last, that is, the
  281.       fragment that is spatially located after any other fragment.  The
  282.  
  283.  
  284. Sidhu                                                           [Page 5]
  285.  
  286.  
  287.  
  288. RFC 963                                                    November 1985
  289. Some Problems with MIL-STD IP
  290.  
  291.  
  292.       length and offset of the tail fragment make it possible to compute
  293.       the length of the entire datagram.  This computation is actually
  294.       done in the action procedure reassembly, and the result is saved
  295.       in the state vector field total_data_length; if the tail fragment
  296.       has not been received, this value is assumed to be zero.
  297.  
  298.       It is the task of the reass_done function [MILS83a, sec 9.4.6.2.6]
  299.       to determine whether the incoming fragment is the last fragment.
  300.       This determination is made as follows:
  301.  
  302.          1) If the tail fragment has not been received previously and
  303.          the incoming fragment is not the tail fragment, then return NO.
  304.  
  305.          2) Otherwise, if the tail fragment has not been received, but
  306.          the incoming fragment is the tail fragment, determine whether
  307.          all fragments spatially preceding the tail fragment have also
  308.          been received.
  309.  
  310.          3) Otherwise, if the tail fragment has been received earlier,
  311.          determine whether the incoming fragment is the last one needed
  312.          to complete reassembly.
  313.  
  314.       The evaluation of case (2) is accomplished by the following
  315.       statment:
  316.  
  317.          if (state_vector.reassembly_map from 0 to
  318.            (((from_SNP.dtgm.total_length -
  319.                (from_SNP.dtgm.header_length * 4) + 7) / 8)
  320.            + 7) / 8 is set)
  321.          then return YES;
  322.  
  323.       The double occurrence of the subexpression " + 7 ) / 8" is
  324.       apparently a misprint.  The function f(x) = (x + 7) / 8 will
  325.       convert x from octets to blocks, rounding any remainder upward.
  326.       There is no need for this function to be performed twice.  The
  327.       second problem is that the fragment_offset field of the incoming
  328.       packet is ignored.  The tail fragment specifies only its own
  329.       length, not the length of the entire datagram; to determine the
  330.       latter, the tail fragment's offset must be added to the tail
  331.       fragment's own length.  The third problem hinges on the meaning of
  332.       the English "... from ... to ..." phrase.  If this phrase has the
  333.       same meaning as the ".." range indication in Ada [ADA83, sec 3.6],
  334.       that is, includes both the upper and lower bounds, then it is
  335.       necessary to subtract 1 from the final expression.
  336.  
  337.       The expression following the word to, above, should thus be
  338.       changed to read
  339.  
  340.  
  341. Sidhu                                                           [Page 6]
  342.  
  343.  
  344.  
  345. RFC 963                                                    November 1985
  346. Some Problems with MIL-STD IP
  347.  
  348.  
  349.          from_SNP.dtgm.fragment_offset +
  350.              ((from_SNP.dtgm.total_length -
  351.                  (from_SNP.dtgm.header_length * 4) + 7) / 8) - 1
  352.  
  353.       Another serious problem with this routine occurs when evaluating
  354.       case (3).  In this case, the relevant statement is
  355.  
  356.          if (all reassembly map from 0 to
  357.            (state_vector.total_data_length + 7)/8 is set
  358.          then return YES
  359.  
  360.       If the tail fragment was received earlier, the code asks, in
  361.       effect, whether all the bits in the reassembly map have been set.
  362.       This, however, will not be the case even if the incoming fragment
  363.       is the last fragment, since the routine reassembly, which actually
  364.       sets these bits, has not yet been called for this fragment.  This
  365.       statement must therefore skip the bits corresponding to the
  366.       incoming fragment.  In specifying the range to be tested,
  367.       allowance must be made for whether these bits fall at the
  368.       beginning of the bit map or in the middle (the case where they
  369.       fall at the end has already been tested). The statement must
  370.       therefore be changed to read
  371.  
  372.          if from_SNP.dtgm.fragment_offset = 0 then
  373.            if (all reassembly map from
  374.              from_SNP.dtgm.fragment_offset +
  375.                ((from_SNP.dtgm.total_length -
  376.                  from_SNP.dtgm.header_length * 4) + 7) / 8
  377.              to ((state_vector.total_data_length + 7) / 8 - 1) is set)
  378.            then return YES;
  379.            else return NO;
  380.            end if;
  381.  
  382.            else
  383.            if (all reassembly map from 0 to
  384.              (from_SNP.dtgm.fragment_offset - 1) is set)
  385.              and (all reassembly map from
  386.                from_SNP.dtgm.fragment_offset +
  387.                  ((from_SNP.dtgm.total_length -
  388.                    from_SNP.dtgm.header_length * 4) + 7) / 8
  389.                to ((state_vector.total_data_length + 7) / 8 - 1) is set)
  390.            then return YES;
  391.            else return NO;
  392.            end if;
  393.            end if;
  394.  
  395.  
  396.  
  397.  
  398. Sidhu                                                           [Page 7]
  399.  
  400.  
  401.  
  402. RFC 963                                                    November 1985
  403. Some Problems with MIL-STD IP
  404.  
  405.  
  406.       Note that here again it is necessary to subtract 1 from the upper
  407.       bound.
  408.  
  409.    Problem 4: Errors in fragment_and_send
  410.  
  411.       The action procedure fragment_and_send [MILS83a, sec 9.4.6.3.7] is
  412.       used to break up datagrams that are too large to be sent through
  413.       the subnetwork as a single packet.  The specification requires
  414.       [MILS83a sec 9.2.2, sec 9.4.6.3.7] each fragment, except possibly
  415.       the "tail" fragment, to contain a whole number of 8-octet groups
  416.       (called "blocks"); moreover, each fragment must begin at a block
  417.       boundary.
  418.  
  419.       In the algorithm set forth in fragment_and_send, all fragments
  420.       except the tail fragment are set to the same size; the procedure
  421.       begins by calculating this size.  This is done by the following
  422.       statement:
  423.  
  424.          data_per_fragment := maximum subnet transmission unit
  425.                                 - (20 + number of bytes of option data);
  426.  
  427.       Besides the failure to allow for header padding, which is
  428.       discussed in the next section, this statement makes the serious
  429.       error of not assuring that the result is an integral multiple of
  430.       the block size, i.e., a multiple of eight octets.  The consequence
  431.       of this would be that as many as seven octets per fragment would
  432.       never be sent at all. To correct this problem, and to allow for
  433.       header padding, this statement must be changed to
  434.  
  435.          data_per_fragment := (maximum subnet transmission unit
  436.                   - (((20 + number of bytes of option data)+3)/4*4)/8*8;
  437.  
  438.       Another problem in this procedure is the failure to provide for
  439.       the case in which the length of the data is an exact multiple of
  440.       eight.  The procedure contains the statements
  441.  
  442.          number_of fragments := (from_ULP.length +
  443.                            (data_per_fragment - 1)) / data_per_fragment;
  444.  
  445.          data_in_last_frag := from_ULP.length modulo data_per_fragment;
  446.  
  447.       (Note that in our terminology we would rename data_in_last_frag as
  448.       data_in_tail_frag; notice, also, that the proper spelling of the
  449.       Ada operator is mod [ADA83, sec 4.5.5].)
  450.  
  451.       If data_in_last_frag is zero, some serious difficulties arise.
  452.       One result might be that the datagram will be broken into one more
  453.  
  454.  
  455. Sidhu                                                           [Page 8]
  456.  
  457.  
  458.  
  459. RFC 963                                                    November 1985
  460. Some Problems with MIL-STD IP
  461.  
  462.  
  463.       fragment than necessary, with the tail fragment containing no data
  464.       bytes.  The assignment of data into the tail fragment will succeed
  465.       even though it will now take the form
  466.  
  467.          output_data [i..i-1] := input_data [j..j-1];
  468.  
  469.       because Ada makes provision for so-called "null slices" [ADA83,
  470.       sec 4.1.2] and will treat this assignment as a no-op [ADA83, sec
  471.       5.2.1].
  472.  
  473.       This does, however, cause the transmission of an unnecessary
  474.       packet, and also creates difficulties for the reassembly
  475.       procedure, which must now be prepared to handle empty packets, for
  476.       which not even one bit of the reassembly map should be set.
  477.       Moreover, as the procedure is now written, even this will not
  478.       occur.  This is because the calculation of the number of fragments
  479.       is incorrect.
  480.  
  481.       A numerical example will clarify this point.  Suppose that the
  482.       total datagram length is 16 bytes and that the number of bytes per
  483.       fragment is to be 8.  Then the above statements will compute
  484.       number_of_fragments = (16 + 7)/8 = 2 and data_in_last_frag = 16
  485.       mod 8 = 0.  The result of the inconsistency between
  486.       number_of_fragments and data_in_last_frag will be that instead of
  487.       sending three fragments, of lengths 8, 8, and 0, the procedure
  488.       will send only two fragments, of lengths 8 and 0; the last eight
  489.       octets will never be sent.
  490.  
  491.       To avoid these difficulties, the specification should add the
  492.       following statement, immediately after computing
  493.       data_in_last_frag:
  494.  
  495.          if data_in_last_frag = 0 then
  496.                                  data_in_last_frag := data_per_fragment;
  497.          end if;
  498.  
  499.       This procedure also contains several minor errors.  In addition to
  500.       failures to account for packet header padding, which are
  501.       enumerated in the next section, there is a failure to convert the
  502.       header length from words (four octets) to octets in one statement.
  503.       This statement, which calculates the total length of the non-tail
  504.       fragments, is
  505.  
  506.          to_SNP.dtgm.total_length := to_SNP.dtgm.header_length
  507.                                                     + data_per_fragment;
  508.  
  509.  
  510.  
  511.  
  512. Sidhu                                                           [Page 9]
  513.  
  514.  
  515.  
  516. RFC 963                                                    November 1985
  517. Some Problems with MIL-STD IP
  518.  
  519.  
  520.       Since header length is expressed  in  units  of  words,  this
  521.       statement should read
  522.  
  523.          to_SNP.dtgm.total_length := to_SNP.dtgm.header_length * 4
  524.                                                     + data_per_fragment;
  525.  
  526.       This is apparently no more than a misprint, since the
  527.       corresponding calculation for the tail fragment is done correctly.
  528.  
  529.    Problem 5: Errors in reassembly
  530.  
  531.       The action procedure reassembly [MILS83a, sec 9.4.6.3.9], which is
  532.       referred to as reassemble elsewhere in the specification [MILS83a,
  533.       sec 9.4.6.1.2, sec 9.4.6.1.3], inserts an incoming fragment into a
  534.       datagram being reassembled.  This procedure contains several
  535.       relatively minor errors.
  536.  
  537.       In two places in this procedure, a range is written to contain one
  538.       more member than it ought to have.  In the first, data from the
  539.       fragment is to be inserted into the datagram being reassembled:
  540.  
  541.          state_vector.data [from_SNP.dtgm.fragment_offset*8 ..
  542.              from_SNP.dtgm.fragment_offset*8 + data_in_frag] :=
  543.                      from_SNP.dtgm.data [0..data_in_frag-1];
  544.  
  545.       In this statement, the slice on the left contains one more byte
  546.       than the slice on the right.  This will cause a run-time exception
  547.       to be raised [ADA83, sec 5.2.1].  The statement should read
  548.  
  549.          state_vector.data [from_SNP.dtgm.fragment_offset*8 ..
  550.              from_SNP.dtgm.fragment_offset*8 + data_in_frag - 1] :=
  551.                      from_SNP.dtgm.data [0..data_in_frag-1];
  552.  
  553.       A similar problem occurs in the computation of the range of bits
  554.       in the reassembly map that corresponds to the incoming fragment.
  555.       This statement begins
  556.  
  557.          for j in (from_SNP.dtgm.fragment_offset) ..
  558.                   ((from_SNP.dtgm.fragment_offset +
  559.                  data_in_frag + 7)/8) loop
  560.  
  561.       Not only are the parentheses in this statement located incorrectly
  562.       (because the function f(x) = (x + 7) / 8 should be executed only
  563.       on the argument data_in_frag), but also this range contains one
  564.       extra member.  The statement should read
  565.  
  566.  
  567.  
  568.  
  569. Sidhu                                                          [Page 10]
  570.  
  571.  
  572.  
  573. RFC 963                                                    November 1985
  574. Some Problems with MIL-STD IP
  575.  
  576.  
  577.          for j in (from_SNP.dtgm.fragment_offset) ..
  578.                   (from_SNP.dtgm.fragment_offset +
  579.                  (data_in_frag + 7)/8) - 1 loop
  580.  
  581.       Note that if the statement is corrected in this manner it will
  582.       also handle the case of a zero-length fragment, mentioned above,
  583.       since the loop will not be executed even once [ADA83, sS 5.5].
  584.  
  585.       Another minor problem occurs when this procedure attempts to save
  586.       the header of the leading fragment.  The relevant statement is
  587.  
  588.          state_vector.header := from_SNP.dtgm;
  589.  
  590.       This statement attempts to transfer the entire incoming fragment
  591.       into a record that is big enough to contain only the header.  The
  592.       result, in Ada, is not truncation, but a run-time exception
  593.       [ADA83, sec 5.2]. The correction should be something like
  594.  
  595.          state_vector.header := from_SNP.dtgm.header;
  596.  
  597.       This correction cannot be made without also defining the header
  598.       portion of the datagram as a subrecord in [MILS83a, sec 9.4.4.6];
  599.       such a definition would also necessitate changing many other
  600.       statements. For example, from_SNP.dtgm.fragment_offset would now
  601.       have to be written as from_SNP.dtgm.header.fragment_offset.
  602.       Another possible solution is to write the above statement as a
  603.       series of assignments for each field in the header, in the
  604.       following fashion:
  605.  
  606.          state_vector.header.version :=
  607.                                                   from_SNP.dtgm.version;
  608.          state_vector.header.header_length :=
  609.                                             from_SNP.dtgm.header_length;
  610.          state_vector.header.type_of_service :=
  611.                                           from_SNP.dtgm.type_of_service;
  612.  
  613.          -- etc.
  614.  
  615.       Note also that this procedure will fail if an incoming fragment,
  616.       other than the tail fragment, does not contain a multiple of eight
  617.       characters.  Implementors must be careful to check for this in the
  618.       decision function SNP_params_valid [MILS83a, sec 9.4.6.2.7].
  619.  
  620.  
  621.  
  622.  
  623.  
  624.  
  625.  
  626. Sidhu                                                          [Page 11]
  627.  
  628.  
  629.  
  630. RFC 963                                                    November 1985
  631. Some Problems with MIL-STD IP
  632.  
  633.  
  634.    Problem 6: Incorrect Data Length for Fragmented Datagrams
  635.  
  636.       The procedure reassembled_delivery [MILS83a, sec 9.4.6.3.10] does
  637.       not deliver the proper data length to the upper-level protocol.
  638.       This is because the assignment is
  639.  
  640.          to_ULP.length := state_vector.header.total_length
  641.                                 - state_vector.header.header_length * 4;
  642.  
  643.       The fields in state_vector.header have been filled in by the
  644.       reassembly procedure, discussed above, by copying the header of
  645.       the leading fragment.  The field total_length in this fragment,
  646.       however, refers only to this particular fragment, and not to the
  647.       entire datagram (this is not entirely clear from it definition in
  648.       [MILS83a, sec 9.3.4], but the fragment_and_send procedure
  649.       [MILS83a, sec 9.4.6.3.7] insures that this is the case).
  650.  
  651.       The length of the entire datagram can only be computed from the
  652.       length and offset of the tail fragment.  This computation is
  653.       actually done in the reassembly procedure [MILS83a, sec
  654.       9.4.6.3.9], and the result saved in state_vector.total_data_length
  655.       (see above).  It is impossible, however, for reassembly to fill in
  656.       state_vector.header.total_length at this time, because
  657.       state_vector.header.header_length is filled in from the lead
  658.       fragment, which may not yet have been received.
  659.  
  660.       Therefore, reassembled_delivery must replace the above statement
  661.       with
  662.  
  663.          to_ULP.length := state_vector.total_data_length;
  664.  
  665.       The consequence of leaving this error uncorrected is that the
  666.       upper-level protocol will be informed only of the delivery of as
  667.       many octets as there are in the lead fragment.
  668.  
  669. 5.  Implementation Difficulties of MIL Standard IP
  670.  
  671.    In addition to the problems discussed above, there are several
  672.    features of the MIL standard IP specification [MILS83a] which lead to
  673.    difficulties for the implementor.  These difficulties, while not
  674.    actually errors in the specification, take the form of assumptions
  675.    which are not explicitly stated, but of which implementors must be
  676.    aware.
  677.  
  678.  
  679.  
  680.  
  681.  
  682.  
  683. Sidhu                                                          [Page 12]
  684.  
  685.  
  686.  
  687. RFC 963                                                    November 1985
  688. Some Problems with MIL-STD IP
  689.  
  690.  
  691.    5.1  Header Padding
  692.  
  693.       In several places, the specification makes a computation of the
  694.       length of a packet header without explicitly allowing for padding.
  695.       The padding is needed because the specification requires [MILS83a,
  696.       sec 9.3.14] that each header end on a 32-bit boundary.
  697.  
  698.       One place this problem arises is in the need_to_frag decision
  699.       function [MILS83a, sec 9.4.6.2.5].  This function is used to
  700.       determine whether fragmentation is required for an outgoing
  701.       datagram. It consists of the single statement
  702.  
  703.          if ((from_ULP.length + (number of bytes of option data)
  704.                + 20) > maximum transmission unit of the local subnetwork
  705.          then return YES
  706.          else return NO;
  707.          end if;
  708.  
  709.       (A minor syntax error results from not terminating the first
  710.       return statement with a semicolon [ADA83, sec 5.1, sec 5.3, sec
  711.       5.9].) In order to allow for padding, the expression for the
  712.       length of the outgoing datagram should be
  713.  
  714.          (((from_ULP.length + (number of bytes of option data) + 20)
  715.                                                              + 3)/4 * 4)
  716.  
  717.       Another place that this problem arises is in the action procedure
  718.       build_and_send [MILS83a, sec 9.4.6.3.2], which prepares
  719.       unfragmented datagrams for transmission.  To compute the header
  720.       field header_length, which is expressed in words, i.e., units of
  721.       four octets [MILS83a, sec 9.3.2], this procedure contains the
  722.       statement
  723.  
  724.          to_SNP.dtgm.header_length := 5 +
  725.                                      (number of bytes of option data)/4;
  726.  
  727.       In order to allow for padding, this statement should read
  728.  
  729.          to_SNP.dtgm.header_length :=
  730.                              5 + ((number of bytes of option data)+3)/4;
  731.  
  732.       The identical statement appears in the action procedure
  733.       fragment_and_send [MILS83a, sec 9.4.6.3.7], which prepares
  734.       datagram fragments for transmission, and requires the same
  735.       correction.
  736.  
  737.  
  738.  
  739.  
  740. Sidhu                                                          [Page 13]
  741.  
  742.  
  743.  
  744. RFC 963                                                    November 1985
  745. Some Problems with MIL-STD IP
  746.  
  747.  
  748.       The procedure fragment_and_send also has this problem in two other
  749.       places.  In the first, the number of octets in each fragment is
  750.       computed by
  751.  
  752.          data_per_fragment := maximum subnet transmission unit
  753.                                 - (20 + number of bytes of option data);
  754.  
  755.       In order to allow for padding, this statement should read
  756.  
  757.          data_per_fragment := maximum subnet transmission unit
  758.                       - (((20 + number of bytes of option data)+3)/4*4);
  759.  
  760.       (Actually, this statement must be changed to
  761.  
  762.          data_per_fragment := (maximum subnet transmission unit
  763.                   - (((20 + number of bytes of option data)+3)/4*4)/8*8;
  764.  
  765.       in order to accomplish its intended purpose, for reasons which
  766.       have been discussed above.)
  767.  
  768.       A similar problem occurs in the statement which computes the
  769.       header length for individual fragments:
  770.  
  771.          to_SNP.dtgm.header_length := 5 +
  772.                                       (number of copy options octets/4);
  773.  
  774.       To allow for padding, this should be changed to
  775.  
  776.          to_SNP.dtgm.header_length := 5 +
  777.                                     (number of copy options octets+3/4);
  778.  
  779.       Notice that all of these errors can also be corrected if the
  780.       English phrase "number of bytes of option data", and similar
  781.       phrases, are always understood to include any necessary padding.
  782.  
  783.    5.2  Subnetworks with Small Transmission Sizes
  784.  
  785.       When an outgoing datagram is too large to be transmitted as a
  786.       single packet, it must be fragmented.  On certain subnetworks, the
  787.       possibility exists that the maximum number of bytes that may be
  788.       transmitted at a time is less than the size of an IP packet header
  789.       for a given datagram.  In this case, the datagram cannot be sent,
  790.       even in fragmented form.  Note that this does not necessarily mean
  791.       that the subnetwork cannot send any datagrams at all, since the
  792.       size of the header may be highly variable.  When this problem
  793.       arises, it should be detected by IP.  The proper place to detect
  794.       this situation is in the function can_frag.
  795.  
  796.  
  797. Sidhu                                                          [Page 14]
  798.  
  799.  
  800.  
  801. RFC 963                                                    November 1985
  802. Some Problems with MIL-STD IP
  803.  
  804.  
  805.       The can_frag decision function [MILS83a, sec 9.4.6.2.2] is used to
  806.       determine whether a particular outgoing datagram, which is too
  807.       long to be transmitted as a single fragment, is allowed to be
  808.       fragmented. In the current specification, this function consists
  809.       of the single statement
  810.  
  811.          if (from_ULP.dont_fragment = TRUE)
  812.          then return NO
  813.          else return YES
  814.          end if;
  815.  
  816.       (A minor syntax error is that the return statements should be
  817.       terminated by semicolons; see [ADA83, sec 5.1, sec 5.3, sec 5.9].)
  818.  
  819.       If the above problem occurs, the procedure fragment_and_send will
  820.       obtain negative numbers for fragment sizes, with unpredictable
  821.       results.  This should be prevented by assuring that the subnetwork
  822.       can send the datagram header and at least one block (eight octets)
  823.       of data.  The can_frag function should be recoded as
  824.  
  825.          if ((8 + ((number of bytes of option data)+3)/4*4 + 20)
  826.                     > maximum transmission unit of the local subnetwork)
  827.          then return NO;
  828.          elsif (from_ULP.dont_fragment = TRUE)
  829.          then return NO
  830.          else return YES
  831.          end if;
  832.  
  833.       This is similar to the logic of the function need_to_frag,
  834.       discussed above.
  835.  
  836.    5.3  Subnetwork Interface
  837.  
  838.       Provision is made for the subnetwork to report errors to IP
  839.       [MILS83a, sec 6.3.6.2], but no provision is made for the IP entity
  840.       to take any action when such errors occur.
  841.  
  842.       In addition, the specification [MILS83a, sec 8.2.1.1] calls for
  843.       the subnetwork to accept type-of-service indicators (precedence,
  844.       reliability, delay, and throughput), which may be difficult to
  845.       implement on many local networks.
  846.  
  847.  
  848.  
  849.  
  850.  
  851.  
  852.  
  853.  
  854. Sidhu                                                          [Page 15]
  855.  
  856.  
  857.  
  858. RFC 963                                                    November 1985
  859. Some Problems with MIL-STD IP
  860.  
  861.  
  862.    5.4  ULP Errors
  863.  
  864.       The IP specification [MILS83a, sec 9.4.6.3.6] states
  865.  
  866.          The format of error reports to a ULP is implementation
  867.          dependent. However, included in the report should be a value
  868.          indicating the type of error, and some information to identify
  869.          the associated data or datagram.
  870.  
  871.       The most natural way to provide the latter information would be to
  872.       return the datagram identifier to the upper-level protocol, since
  873.       this identifier is normally supplied by the sending ULP [MILS83a,
  874.       sec 9.3.5].  However, the to_ULP data structure makes no provision
  875.       for this information [MILS83a, sec 9.4.4.3], probably because this
  876.       information is irrelevant for datagrams received from the
  877.       subnetwork. Implementors may feel a need to add this field to the
  878.       to_ULP data structure.
  879.  
  880.    5.5  Initialization of Data Structures
  881.  
  882.       The decision function reass_done [MILS83a, sec 9.4.6.2.6] makes
  883.       the implicit assumption that data structures within each finite
  884.       state machine are initialized to zero when the machine is created.
  885.       In particular, this routine will not function properly unless
  886.       state_vector.reassembly_map and state_vector.total_data_length are
  887.       so initialized.  Since this assumption is not stated explicitly,
  888.       implementors should be aware of it.  There may be other
  889.       initialization assumptions that we have not discovered.
  890.  
  891.    5.6  Locally Defined Types
  892.  
  893.       The procedures error_to_source [MILS83a, sec 9.4.6.3.5] and
  894.       error_to_ULP [MILS83a, sec 9.4.6.3.6] define enumeration types in
  895.       comments.  The former contains the comment
  896.  
  897.          error_param : (PARAM_PROBLEM, EXPIRED_TTL, PROTOCOL_UNREACH);
  898.  
  899.       and the latter
  900.  
  901.          error_param : (PARAM_PROBLEM, CAN'T_FRAGMENT, NET_UNREACH,
  902.                                         PROTOCOL_UNREACH, PORT_UNREACH);
  903.  
  904.       These enumerated values are used before they are encountered
  905.       [MILS83a, sec 9.4.6.1.1, sec 9.4.6.1.2, sec 9.4.6.1.3, et al.];
  906.       implementors will probably wish to define some error type
  907.       globally.
  908.  
  909.  
  910.  
  911. Sidhu                                                          [Page 16]
  912.  
  913.  
  914.  
  915. RFC 963                                                    November 1985
  916. Some Problems with MIL-STD IP
  917.  
  918.  
  919.    5.7  Miscellaneous Difficulties
  920.  
  921.       The specification contains many Ada syntax errors, some of which
  922.       have been shown above.  We have only mentioned syntax errors
  923.       above, however, when they occurred in conjunction with other
  924.       problems.  One of the main syntactic difficulties that we have not
  925.       mentioned is that the specification frequently creates unnamed
  926.       types, by declaring records within records; such declarations are
  927.       legal in Pascal, but not in Ada [ADA83, sec 3.7].
  928.  
  929.       Another problem is that slice assignments frequently do not
  930.       contain the same number of elements on the left and right sides,
  931.       which will raise a run-time exception [ADA83, sec 5.2.1].  While
  932.       we have mentioned some of these, there are others which are not
  933.       enumerated above.
  934.  
  935.       In particular, the procedure error_to_source [MILS83a, sec
  936.       9.4.6.3.5] contains the statement
  937.  
  938.          to_SNP.dtgm.data [8..N+3] := from_SNP.dtgm.data [0..N-1];
  939.  
  940.       We believe that N+3 is a misprint for N+8, but even so the left
  941.       side contains one more byte than the right.  Implementors should
  942.       carefully check every slice assignment.
  943.  
  944. 6.  An Implementation of MIL Standard IP
  945.  
  946.    In our discussion above, we have pointed out several serious problems
  947.    with the Military Standard IP [MILS83a] specification which must be
  948.    corrected to produce a running implementation conforming to this
  949.    standard.  We have produced a running C implementation for the MIL
  950.    Standard IP, after problems discussed above were fixed in the IP
  951.    specification.  An important feature of this implementation is that
  952.    it was generated semi-automatically from the IP specification with
  953.    the help of a protocol development system [BLUT82] [BLUT83] [SIDD83].
  954.    Since this implementation was derived directly from the IP
  955.    specification with the help of tools, it conforms to the IP standard
  956.    better that any handed-coded IP implementation can do.
  957.  
  958.    The problems pointed out in this paper with the current specification
  959.    of the MIL Standard IP [MILS83a] are based on an initial
  960.    investigation of the protocol.
  961.  
  962.  
  963.  
  964.  
  965.  
  966.  
  967.  
  968. Sidhu                                                          [Page 17]
  969.  
  970.  
  971.  
  972. RFC 963                                                    November 1985
  973. Some Problems with MIL-STD IP
  974.  
  975.  
  976. NOTES
  977.  
  978.    [1] Ada is a registered trademark of the U.S. Government - Ada Joint
  979.    Program Office.
  980.  
  981.    [2] d indicates a "don't care" condition.
  982.  
  983. ACKNOWLEDGEMENTS
  984.  
  985.    The author extends his gratitude to Tom Blumer Michael Breslin, Bob
  986.    Pollack and Mark J. Vincenzes, for many helpful discussions.  Thanks
  987.    are also due to B. Simon and M. Bernstein for bringing to author's
  988.    attention a specification of the DoD Internet Protocol during 1981-82
  989.    when a detailed study of this protocol began.  The author is also
  990.    grateful to Jon Postel and Carl Sunshine for several informative
  991.    discussions about DoD IP/TCP during the last few years.
  992.  
  993. REFERENCES
  994.  
  995.    [ADA83]   Military Standard Ada(R) Programming Language, United
  996.              States Department of Defense, ANSI/MIL-STD-1815A-1983, 22
  997.              January 1983
  998.  
  999.    [BLUT83]  Blumer, T. P., and Sidhu, D. P., "Mechanical Verification
  1000.              and Automatic Implementation of Communication Protocols,"
  1001.              to appear in IEEE Trans. Softw. Eng.
  1002.  
  1003.    [BLUT82]  Blumer, T. P., and Tenney, R. L., "A Formal Specification
  1004.              Technique and Implementation Method for Protocols,"
  1005.              Computer Networks, Vol. 6, No. 3, July 1982, pp. 201-217.
  1006.  
  1007.    [MILS83a] "Military Standard Internet Protocol," United States
  1008.              Department of Defense, MIL-STD-1777, 12 August 1983.
  1009.  
  1010.    [MILS83b] "Military Standard Transmission Control Protocol," United
  1011.              States Department of Defense, MIL-STD-1778, 12 August 1983.
  1012.  
  1013.    [POSJ81]  Postel, J. (ed.), "DoD Standard Internet Protocol," Defense
  1014.              Advanced Research Projects Agency, Information Processing
  1015.              Techniques Office, RFC-791, September 1981.
  1016.  
  1017.    [SDC82]   DCEC Protocol Standardization Program: Protocol
  1018.              Specification Report, System Development Corporation,
  1019.              TM-7172/301/00, 29 March 1982
  1020.  
  1021.    [SIDD83]  Sidhu, D. P., and Blumer, T. P., "Verification of NBS Class
  1022.              4 Transport Protocol," to appear in IEEE Trans. Comm.
  1023.  
  1024.  
  1025. Sidhu                                                          [Page 18]
  1026.  
  1027.  
  1028.  
  1029. RFC 963                                                    November 1985
  1030. Some Problems with MIL-STD IP
  1031.  
  1032.  
  1033.    [SIDD84]  Sidhu, D. P., and Blumer, T. P., "Some Problems with the
  1034.              Specification of the Military Standard Transmission Control
  1035.              Protocol," in Protocol Specification, Testing and
  1036.              Verification IV, (ed.) Y. Yemini et al (1984).
  1037.  
  1038.  
  1039.  
  1040.  
  1041.  
  1042.  
  1043.  
  1044.  
  1045.  
  1046.  
  1047.  
  1048.  
  1049.  
  1050.  
  1051.  
  1052.  
  1053.  
  1054.  
  1055.  
  1056.  
  1057.  
  1058.  
  1059.  
  1060.  
  1061.  
  1062.  
  1063.  
  1064.  
  1065.  
  1066.  
  1067.  
  1068.  
  1069.  
  1070.  
  1071.  
  1072.  
  1073.  
  1074.  
  1075.  
  1076.  
  1077.  
  1078.  
  1079.  
  1080.  
  1081.  
  1082. Sidhu                                                          [Page 19]
  1083.  
  1084.