Subject: [rohc] TCP packet formats - more design questions

From: Kristofer Sandlund <[email-masked]>
Date: Wed, 08 Dec 2004 13:54:41 +0100

Hi all!

During the Washington meeting offline discussions, we decided to produce a new 
set for the base header part of the ROHC-TCP packet formats. These new formats 
are hand-generated headers instead of the old machine-generated ones. This to 
get a better overview of what the different packet formats are actually used 
for. These packet formats contains co_common + 10 seq-IPID headers + 10 rnd-IPID 
headers. The file with the latest FN code for that is attached to this mail 
(also includes box notation for all of us who like ascii pictures).

The current "design rationale" for these are as follows (_similar_ text will be 
added to the next revision of the tcp draft, but it will be edited to make a bit 
more sense).

    1: This packet format transmits changes to the TCP sequence number
    and its principal use should be on the downstream of a data transfer.

    2: Transmits the TCP sequence number in scaled form, and will
    normally be used on the downstream of a data transfer where the
    payload size is constant for multiple packets.

    3: Is used to transmit changes in the TCP acknowledgement number, and
    will be used in acknowledgement direction of data transfer.

    4: Is similar to 3, but sends only a few bits of ACK number. The
    format is expected to have its principle use on the acknowledgement
    stream interactive data connections such as Telnet.

    5: Transmits both TCP sequence number and acknowledgement number, and
    has its largest use on streams that send data in both directions.

    6: Is similar to 5, but sends the sequence number in scaled form to
    be used when the payload size is static for certain intervals in a
    data stream.

    7: Is used to transmit changes to both TCP sequence number and TCP
    window, and is expected to be used on all data transfers.

    8: Is used to transmit changes to both TCP acknowledgement number and
    TCP window, and is expected to be used on acknowledgement streams of
    data connections.

    9: Similar to 7, but sends the sequence number in scaled form to
    allow higher compression rates on streams with a constant payload
    size,

    10: This packet is used to transmit changes to some of the more
    seldom changing fields in the streams, such as ECN behaviour,
    Reset/SYN/FIN flags, the TTL/Hop Limit and the TCP options list. This
    packet is protected by a 7-bit CRC, since it can change contents of
    the irregular chain in later packets. Note that this can be seen as a
    reduced form of the common packet format.

So, to try to get these closer to finalizing, I'm going to summarize some issues 
and changes that might be done to them (or not).

Issue 1: We do not have any way to transmit changes in TTL/Hoplimit fields of 
outer IP headers except to use IR-DYN packets. This seems a bit weak, but how do 
we add this to the packet formats since we have to do it for an arbitrary number 
of IP headers?
My suggestion would be to do this semi-well and add a flag to co_common, and if 
this is set, we transmit the TTL of all outer IP headers inside this packet. 
This means that a change in one TTL field will mean that we have to send 
co_common and that this packet has to contain multiple TTL fields even if they 
are unchanged (only costs extra if we have more than 2 IP headers).
Another alternative (even less efficient) is to set up a control field and say 
that if this ttl-is-present bit is set, then the TTL of all headers is added to 
the irregular chain. So that some streams always send these while otehrs never 
sent this.
Also, we _could_ do both the alternatives listed above.
We don't want to spend too much effort on this case, but I feel that a TTL 
change to the tunnel header should not have ot back off to IR-DYNs. But if 
others feel that would be ok, then we can leave it as it is now.

Issue 2: Do we keep packet format 4? Do we expect to see a large enough number 
of small changes to the ACK number to warrant this packet format? If we drop it, 
we _could_ replace it with a scaled ACK number format (see other mail thread).

Issue 3: Is packet format 10 useful enough? We _could_ drop this and say that 
co_common is good enough. I don't really know what would be the best approach.

Issue 4: Do we have any kind of zero-division issue with the scaled sequence 
numbers? (since the residue is established when sending unscaled seq, is there 
some wierd worst-case where we the current FN could tell decompressors to divide 
by zero?).

Comments appreciated.

Rgds,
	Kristofer Sandlund, Effnet AB

% just the base header packet formats for TCP-ROHC
%
% $Id: baseheaders.txt,v 1.6 2004/11/12 14:23:39 eilert Exp $

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Common compressed packet format
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

   format_co_common             =   discriminator,       %[ 4 ]
                                    ack_flag,            %[ 1 ]
                                    psh_flag,            %[ 1 ]
                                    rsf_flags,           %[ 2 ]

                                    msn,                 %[ 8 ]

                                    seq_indicator,       %[ 2 ]
                                    ack_indicator,       %[ 2 ]
				    ip_id_indicator,     %[ 2 ]
				    window_indicator,    %[ 2 ]

                                    urg_ptr_present,     %[ 1 ]
                                    ecn_used,            %[ 1 ]
				    tos_tc_present,      %[ 1 ]
                                    ttl_hopl_present,    %[ 1 ]
				    list_present,        %[ 1 ]

                                    ip_id_behavior,      %[ 2 ]

                                    urg_flag,            %[ 1 ]
                                    df,                  %[ 1 ]

                                    header_crc,          %[ 7 ]

                                    seq_number,          % 0, 8, 16, 32 bits
                                    ack_number,          % 0, 8, 16, 32 bits
                                    ip_id,               % 0, 8, 16 bits
                                    window,              % 0, 8, 16 bits
                                    urg_ptr,             % 0 or 16 bits
                                    ip_ecn_flags,        % 0 or 2 bits
                                    tcp_ecn_flags,       % 0 or 2 bits
                                    tcp_res_flags,       % 0 or 4 bits
                                    tos_tc,              % 0 or 8 bits
                                    ttl_hopl,            % 0 or 8 bits
                                    options_list,        % n bits
   {
             discriminator      ::= '1110';
             tos_tc_present     ::= irregular(1);
             ttl_hopl_present   ::= irregular(1);
             ack_flag           ::= irregular(1);
             psh_flag           ::= irregular(1);
             msn                ::= lsb (8, 64); % this could be fewer bits
             df                 ::= dont_fragment(version:uncomp_value);
             header_crc         ::= crc7(this:uncomp_value,
                                         this:uncomp_length);
             urg_flag           ::= irregular(1);
             urg_ptr_present    ::= irregular(1);
             ecn_used           ::= irregular(1);
             list_present       ::= irregular(1);
             ip_id_behavior     ::= ip_id_behavior_enc;
             rsf_flags          ::= rsf_index_enc;

             window_indicator   ::= irregular(2);
             ip_id_indicator    ::= irregular(2);
             seq_indicator      ::= irregular(2);
             ack_indicator      ::= irregular(2);

             seq_number         ::= variable_length_32_enc(seq_indicator);
             ack_number         ::= variable_length_32_enc(ack_indicator);
             window             ::= variable_length_16_enc(window_indicator);
             ip_id              ::= variable_length_16_enc(ip_id_indicator);
             urg_ptr            ::= static_or_irreg16(urg_ptr_present);
             ttl_hops           ::= static_or_irreg8(ttl_hopl_present);
             ip_ecn_flags       ::= ip_irreg_ecn(ecn_used_flag);
             tcp_ecn_flags      ::= tcp_ecn_flags_enc(ecn_used_flag);
             tcp_res_flags      ::= tcp_res_flags_enc(ecn_used_flag);
             tos_tc             ::= tos_tc_enc(tos_tc_present);
             options_list       ::= tcp_list_presence_enc
                                           ((data_offset:uncomp_value + 20) / 4,
                                            list_present);
   };

%   0   1   2   3   4   5   6   7
% +---+---+---+---+---+---+---+---+
% | 1   1   1   0 |ACK|PSH|  RSF  |
% +===+===+===+===+===+===+===+===+
% |              MSN              |
% +---+---+---+---+---+---+---+---+
% |  sn   | a_sn  | ip_id |  win  |
% +---+---+---+---+---+---+---+---+
% |urg|ecn|tos|ttl|lst|IPIDbeh|URG|
% +---+---+---+---+---+---+---+---+
% |DF |            CRC            |
% +---+---+---+---+---+---+---+---+
% /              SN               /  0, 8, 16, 32 bits, indicated by sn
%  --- --- --- --- --- --- --- ---
% /            ACK_SN             /  0, 8, 16, 32 bits, indicated by a_sn
%  --- --- --- --- --- --- --- ---
% /             IP-ID             /  0, 8, 16 bits, indicated by ip_id
%  --- --- --- --- --- --- --- ---
% /            WINDOW             /  0, 8, 16 bits, indicated by win
%  --- --- --- --- --- --- --- ---
% /            URG-PTR            /  16 bits, if urg=1
%  --- --- --- --- --- --- --- ---
% /IP-ECN |TCP-ECN|    TCP_RES    /  8 bits, if ecn=1
%  --- --- --- --- --- --- --- ---
% /              TOS              /  8 bits, if tos=1
%  --- --- --- --- --- --- --- ---
% /              TTL              /  8 bits, if ttl=1
%  --- --- --- --- --- --- --- ---
% /         options_list          /  n*8 bits, if lst=1
%  --- --- --- --- --- --- --- ---

% NON-SEQUENTIAL PACKET FORMATS

% +------+-------+-----+-----+-----+---------+---------+
% |Name  |Disc   |MSN  |SN   |ACK  |Window   |Comment  |
% +------+-------+-----+-----+-----+---------+---------+
% |_1    |100    |4    |13   |0    |         |         |
% +------+-------+-----+-----+-----+---------+---------+
% |_2    |01     |4    |*6   |0    |         |         |
% +------+-------+-----+-----+-----+---------+---------+
% |_3    |101    |4    |0    |13   |         |         |
% +------+-------+-----+-----+-----+---------+---------+
% |_4    |110    |4    |0    |5    |         |         |
% +------+-------+-----+-----+-----+---------+---------+
% |_5    |00100  |4    |15   |12   |         |         |
% +------+-------+-----+-----+-----+---------+---------+
% |_6    |0011   |4    |*7   |13   |         |         |
% +------+-------+-----+-----+-----+---------+---------+
% |_7    |00101  |4    |11   |0    |16       |         |
% +------+-------+-----+-----+-----+---------+---------+
% |_8    |00011  |4    |0    |11   |16       |         |
% +------+-------+-----+-----+-----+---------+---------+
% |_9    |00000  |4    |*8   |0    |11       |         |
% +------+-------+-----+-----+-----+---------+---------+
% |_10   |00001  |4    |12   |12   |         |and more |
% +------+-------+-----+-----+-----+---------+---------+

   % Send LSBs of sequence number
   format_rnd_1 = discriminator, %[ 3 ]
		  seq_number,	 %[ 13 ]
		  msn,		 %[ 4 ]
		  psh_flag,      %[ 1 ]
		  header_crc,	 %[ 3 ]
   {
      let ((ip_id_behavior:uncomp_value == 2) ||
           (ip_id_behavior:uncomp_value == 3));
      discriminator       ::= '100';
      msn                 ::= lsb(4, 4);
      header_crc          ::= crc3 (this:uncomp_value,
                                    this:uncomp_length);
      psh_flag            ::= irregular (1);
      seq_number	  ::= lsb(13, 4095);
   };

%   0   1   2   3   4   5   6   7
% +---+---+---+---+---+---+---+---+
% | 1   0   0 |        SN...      |
% +===+===+===+===+===+===+===+===+
% |           ...SN               |
% +---+---+---+---+---+---+---+---+
% |      MSN      |PSH|    CRC    |
% +---+---+---+---+---+---+---+---+

   % Send scaled sequence number LSBs
   format_rnd_2 = discriminator, %[ 2 ]
		  seq_number_scaled, %[ 6 ]
		  msn,		 %[ 4 ]
		  psh_flag,      %[ 1 ]
		  header_crc,	 %[ 3 ]
   {
      let ((ip_id_behavior:uncomp_value == 2) ||
           (ip_id_behavior:uncomp_value == 3));
      discriminator       ::= '01';
      msn                 ::= lsb(4, 4);
      header_crc          ::= crc3 (this:uncomp_value,
                                    this:uncomp_length);
      psh_flag            ::= irregular (1);
      seq_number_scaled   ::= lsb(6, 31);
      seq_number_residue  ::= static;
   };

%   0   1   2   3   4   5   6   7
% +---+---+---+---+---+---+---+---+
% | 0   1 |       SN_SCALED       |
% +===+===+===+===+===+===+===+===+
% |      MSN      |PSH|    CRC    |
% +---+---+---+---+---+---+---+---+

   % Send acknowledgement number LSBs
   format_rnd_3 = discriminator, %[ 3 ]
		  ack_number,    %[ 13 ]
		  msn,		 %[ 4 ]
		  psh_flag,      %[ 1 ]
		  header_crc,	 %[ 3 ]
   {
      let ((ip_id_behavior:uncomp_value == 2) ||
           (ip_id_behavior:uncomp_value == 3));
      discriminator       ::= '101';
      msn                 ::= lsb(4, 4);
      header_crc          ::= crc3 (this:uncomp_value,
                                    this:uncomp_length);
      psh_flag            ::= irregular (1);
      ack_number	  ::= lsb(13, 2047);
   };

%   0   1   2   3   4   5   6   7
% +---+---+---+---+---+---+---+---+
% | 1   0   1 |      ACK_SN...    |
% +===+===+===+===+===+===+===+===+
% |         ...ACK_SN             |
% +---+---+---+---+---+---+---+---+
% |      MSN      |PSH|    CRC    |
% +---+---+---+---+---+---+---+---+

   % Send small ACK numbers for small packet ACK streams (telnet/ssh etc).
   format_rnd_4 = discriminator, %[ 3 ]
		  ack_number,	 %[ 5 ]
		  msn,		 %[ 4 ]
		  psh_flag,      %[ 1 ]
		  header_crc,	 %[ 3 ]
   {
      let ((ip_id_behavior:uncomp_value == 2) ||
           (ip_id_behavior:uncomp_value == 3));
      discriminator       ::= '110';
      msn                 ::= lsb(4, 4);
      header_crc          ::= crc3 (this:uncomp_value,
                                    this:uncomp_length);
      psh_flag            ::= irregular (1);
      ack_number	  ::= lsb(5, 7);
   };

%   0   1   2   3   4   5   6   7
% +---+---+---+---+---+---+---+---+
% | 1   1   0 |      ACK_SN       |
% +===+===+===+===+===+===+===+===+
% |      MSN      |PSH|    CRC    |
% +---+---+---+---+---+---+---+---+

   % Send ACK and sequence number
   format_rnd_5 = discriminator, %[ 5 ]
		  header_crc,	 %[ 3 ]
		  msn,		 %[ 4 ]
		  ack_number,    %[ 12 ]
		  psh_flag,      %[ 1 ]
		  seq_number,    %[ 15 ]
   {
      let ((ip_id_behavior:uncomp_value == 2) ||
           (ip_id_behavior:uncomp_value == 3));
      discriminator       ::= '00100';
      msn                 ::= lsb(4, 4);
      header_crc          ::= crc3 (this:uncomp_value,
                                    this:uncomp_length);
      psh_flag            ::= irregular (1);
      ack_number	  ::= lsb(12, 1023);
      seq_number	  ::= lsb(15, 16383);
   };

%   0   1   2   3   4   5   6   7
% +---+---+---+---+---+---+---+---+
% | 0   0   1   0   0 |    CRC    |
% +===+===+===+===+===+===+===+===+
% |      MSN      |    ACK_SN...  |
% +---+---+---+---+---+---+---+---+
% |         ...ACK_SN             |
% +---+---+---+---+---+---+---+---+
% |PSH|            SN...          |
% +---+---+---+---+---+---+---+---+
% |           ...SN               |
% +---+---+---+---+---+---+---+---+

   % Send both ACK and scaled sequence number LSBs
   format_rnd_6 = discriminator, %[ 4 ]
		  psh_flag,      %[ 1 ]
		  header_crc,	 %[ 3 ]
		  msn,		 %[ 4 ]
		  ack_number,    %[ 13 ]
		  seq_number_scaled, %[ 7 ],
   {
      let ((ip_id_behavior:uncomp_value == 2) ||
           (ip_id_behavior:uncomp_value == 3));
      discriminator       ::= '0011';
      msn                 ::= lsb(4, 4);
      header_crc          ::= crc3 (this:uncomp_value,
                                    this:uncomp_length);
      psh_flag            ::= irregular (1);
      ack_number	  ::= lsb(13, 2047);
      seq_number_scaled   ::= lsb(7, 63);
      seq_number_residue  ::= static;
   };

% +---+---+---+---+---+---+---+---+
% | 0   0   1   1 |PSH|    CRC    |
% +===+===+===+===+===+===+===+===+
% |  MSN          | ACK_SN...
% +---+---+---+---+---+---+---+---+
% |  ...ACK_SN...                 |
% +---+---+---+---+---+---+---+---+
% |..A|        ...SN              |
% +---+---+---+---+---+---+---+---+

   % Send sequence number and window
   format_rnd_7 = discriminator, %[ 5 ]
		  header_crc,	 %[ 3 ]
		  msn,		 %[ 4 ]
		  psh_flag,      %[ 1 ]
		  seq_number,    %[ 11 ]
		  window,	 %[ 16 ]
   {
      let ((ip_id_behavior:uncomp_value == 2) ||
           (ip_id_behavior:uncomp_value == 3));
      discriminator       ::= '00101';
      msn                 ::= lsb(4, 4);
      header_crc          ::= crc3 (this:uncomp_value,
                                    this:uncomp_length);
      psh_flag            ::= irregular (1);
      seq_number	  ::= lsb(11, 1023);
      window		  ::= irregular(16);
   };

% +---+---+---+---+---+---+---+---+
% | 0   0   1   0   1 |    CRC    |
% +===+===+===+===+===+===+===+===+
% |      MSN      |PSH|    SN...  |
% +---+---+---+---+---+---+---+---+
% |           ...SN               |
% +---+---+---+---+---+---+---+---+
% |                               |
% +            WINDOW             +
% |                               |
% +---+---+---+---+---+---+---+---+

   % Send ACK and window
   format_rnd_8 = discriminator, %[ 5 ]
		  header_crc,	 %[ 3 ]
		  msn,		 %[ 4 ]
		  psh_flag,      %[ 1 ]
		  ack_number,	 %[ 11 ]
		  window,	 %[ 16 ]
   {
      let ((ip_id_behavior:uncomp_value == 2) ||
           (ip_id_behavior:uncomp_value == 3));
      discriminator       ::= '00011';
      msn                 ::= lsb(4, 4);
      header_crc          ::= crc3 (this:uncomp_value,
                                    this:uncomp_length);
      psh_flag            ::= irregular (1);
      ack_number	  ::= lsb(11, 1023);
      window		  ::= irregular(16);
   };

% +---+---+---+---+---+---+---+---+
% | 0   0   0   1   1 |    CRC    |
% +===+===+===+===+===+===+===+===+
% |      MSN      |PSH|  ACK_SN...|
% +---+---+---+---+---+---+---+---+
% |         ...ACK_SN             |
% +---+---+---+---+---+---+---+---+
% |                               |
% +            WINDOW             +
% |                               |
% +---+---+---+---+---+---+---+---+

   % Send scaled sequence number and window.
   format_rnd_9 = discriminator, %[ 5 ]
		  header_crc,	 %[ 3 ]
		  msn,		 %[ 4 ]
		  psh_flag,      %[ 1 ]
		  window,	 %[ 14 ]
		  seq_number_scaled, %[ 5 ]
   {
      let ((ip_id_behavior:uncomp_value == 2) ||
           (ip_id_behavior:uncomp_value == 3));
      discriminator       ::= '00000';
      msn                 ::= lsb(4, 4);
      header_crc          ::= crc3 (this:uncomp_value,
                                    this:uncomp_length);
      psh_flag            ::= irregular (1);
      window		  ::= lsb(14, 8191);
      seq_number_scaled	  ::= lsb(5, 15);
      seq_number_residue  ::= static;
   };

% +---+---+---+---+---+---+---+---+
% | 0   0   0   0   0 |    CRC    |
% +===+===+===+===+===+===+===+===+
% |      MSN      |PSH|SN_SCALED..|
% +---+---+---+---+---+---+---+---+
% |SN_SC..|      WINDOW...        |
% +---+---+---+---+---+---+---+---+
% |           ...WINDOW           |
% +---+---+---+---+---+---+---+---+

   % A packet halfway between co_common and compressed packets
   % Can send LSBs of TTL, RSF flags, change ECN behavior and options list
   format_rnd_10 = discriminator, %[ 5 ]
		   ecn_used,	  %[ 1 ]
		   rsf_flags,	  %[ 2 ]
		   psh_flag,      %[ 1 ]
		   ttl_hopl,	  %[ 3 ]
		   msn,		  %[ 4 ]
		   list_present,  %[ 1 ]
		   header_crc,	  %[ 7 ]
		   ack_number,	  %[ 12 ]
		   seq_number,	  %[ 12 ]
		   options_list,  % 0 or X bits
   {
      let ((ip_id_behavior:uncomp_value == 2) ||
           (ip_id_behavior:uncomp_value == 3));
      discriminator       ::= '00001';
      msn                 ::= lsb(4, 4);
      header_crc          ::= crc7 (this:uncomp_value,
                                    this:uncomp_length);
      psh_flag            ::= irregular (1);
      list_present        ::= irregular(1);
      options_list        ::= tcp_list_presence_enc
                                      ((data_offset:uncomp_value + 20) / 4,
                                       list_present);
      rsf_flags           ::= rsf_index_enc;
      ecn_used		  ::= irregular(1);
      ttl_hopl		  ::= lsb(3, 3);
      seq_number	  ::= lsb(12, 2047);
      ack_number	  ::= lsb(12, 1023);
   };

% +---+---+---+---+---+---+---+---+
% | 0   0   0   0   1 |ECN|  RSF  |
% +===+===+===+===+===+===+===+===+
% |PSH|    TTL    |      MSN      |
% +---+---+---+---+---+---+---+---+
% |lst|            CRC            |
% +---+---+---+---+---+---+---+---+
% |            ACK_SN...          |
% +---+---+---+---+---+---+---+---+
% | ...ACK_SN     |      SN...    |
% +---+---+---+---+---+---+---+---+
% |           ...SN               |
% +---+---+---+---+---+---+---+---+
% /         options_list          /  n*8 bits, if lst=1
%  --- --- --- --- --- --- --- ---

% SEQUENTIAL PACKET FORMATS

% +------+-----+-----+-----+-----+-----+-----+---------+
% |Name  |Disc |MSN  |ID   |SN   |ACK  |Win  |Comment  |
% +------+-----+-----+-----+-----+-----+-----+---------+
% |_1    |100  |4    |5    |16   |0    |     |         |
% +------+-----+-----+-----+-----+-----+-----+---------+
% |_2    |0011 |4    |6    |*6   |0    |     |         |
% +------+-----+-----+-----+-----+-----+-----+---------+
% |_3    |00100|4    |3    |0    |16   |     |         |
% +------+-----+-----+-----+-----+-----+-----+---------+
% |_4    |01   |4    |2    |0    |4    |     |         |
% +------+-----+-----+-----+-----+-----+-----+---------+
% |_5    |00000|4    |3    |12   |12   |     |         |
% +------+-----+-----+-----+-----+-----+-----+---------+
% |_6    |101  |4    |4    |*5   |12   |     |         |
% +------+-----+-----+-----+-----+-----+-----+---------+
% |_7    |00001|4    |3    |16   |0    |16   |         |
% +------+-----+-----+-----+-----+-----+-----+---------+
% |_8    |110  |4    |5    |0    |16   |16   |         |
% +------+-----+-----+-----+-----+-----+-----+---------+
% |_9    |00101|4    |3    |*5   |0    |11   |         |
% +------+-----+-----+-----+-----+-----+-----+---------+
% |_10   |00011|4    |4    |14   |14   |     |and more |
% +------+-----+-----+-----+-----+-----+-----+---------+

   % Send LSBs of sequence number
   format_seq_1 = discriminator, %[ 3 ]
		  ip_id,         %[ 5 ]
		  seq_number,	 %[ 16 ]
		  msn,		 %[ 4 ]
		  psh_flag,      %[ 1 ]
		  header_crc,	 %[ 3 ]
   {
      let ((ip_id_behavior:uncomp_value == 2) ||
           (ip_id_behavior:uncomp_value == 3));
      discriminator       ::= '100';
      msn                 ::= lsb(4, 4);
      ip_id               ::= ip_id_lsb (ip_id_behavior, msn, 5, 3);
      header_crc          ::= crc3 (this:uncomp_value,
                                    this:uncomp_length);
      psh_flag            ::= irregular (1);
      seq_number	  ::= lsb(16, 32767);
   };

% +---+---+---+---+---+---+---+---+
% | 1   0   0 |       IP-ID       |
% +===+===+===+===+===+===+===+===+
% |                               |
% +              SN               +
% |                               |
% +---+---+---+---+---+---+---+---+
% |      MSN      |PSH|    CRC    |
% +---+---+---+---+---+---+---+---+

   % Send scaled sequence number LSBs
   format_seq_2 = discriminator, %[ 4 ]
		  ip_id,         %[ 6 ]
		  seq_number_scaled, %[ 6 ]
		  msn,		 %[ 4 ]
		  psh_flag,      %[ 1 ]
		  header_crc,	 %[ 3 ]
   {
      let ((ip_id_behavior:uncomp_value == 2) ||
           (ip_id_behavior:uncomp_value == 3));
      discriminator       ::= '0011';
      msn                 ::= lsb(4, 4);
      ip_id               ::= ip_id_lsb (ip_id_behavior, msn, 6, 3);
      header_crc          ::= crc3 (this:uncomp_value,
                                    this:uncomp_length);
      psh_flag            ::= irregular (1);
      seq_number_scaled   ::= lsb(6, 31);
      seq_number_residue  ::= static;
   };

% +---+---+---+---+---+---+---+---+
% | 0   0   1   1 |     IP-ID...  |
% +===+===+===+===+===+===+===+===+
% | ...ID |      SN               |
% +---+---+---+---+---+---+---+---+
% |      MSN      |PSH|    CRC    |
% +---+---+---+---+---+---+---+---+

   % Send acknowledgement number LSBs
   format_seq_3 = discriminator, %[ 5 ]
		  ip_id,         %[ 3 ]
		  ack_number,	 %[ 16 ]
		  msn,		 %[ 4 ]
		  psh_flag,      %[ 1 ]
		  header_crc,	 %[ 3 ]
   {
      let ((ip_id_behavior:uncomp_value == 2) ||
           (ip_id_behavior:uncomp_value == 3));
      discriminator       ::= '00100';
      msn                 ::= lsb(4, 4);
      ip_id               ::= ip_id_lsb (ip_id_behavior, msn, 3, 3);
      header_crc          ::= crc3 (this:uncomp_value,
                                    this:uncomp_length);
      psh_flag            ::= irregular (1);
      ack_number	  ::= lsb(16, 16383);
   };

% +---+---+---+---+---+---+---+---+
% | 0   0   1   0   0 |   IP-ID   |
% +===+===+===+===+===+===+===+===+
% |                               |
% +            ACK_SN             +
% |                               |
% +---+---+---+---+---+---+---+---+
% |      MSN      |PSH|    CRC    |
% +---+---+---+---+---+---+---+---+

   % Send small ACK numbers for small packet ACK streams (telnet/ssh etc).
   format_seq_4 = discriminator, %[ 2 ]
		  ack_number,    %[ 4 ]
		  ip_id,         %[ 2 ]
   		  msn,		 %[ 4 ]
		  psh_flag,      %[ 1 ]
		  header_crc,	 %[ 3 ]
   {
      let ((ip_id_behavior:uncomp_value == 2) ||
           (ip_id_behavior:uncomp_value == 3));
      discriminator       ::= '01';
      msn                 ::= lsb(4, 4);
      % Note that due to having very few msn bits, no reordering offset
      ip_id               ::= ip_id_lsb (ip_id_behavior, msn, 2, 1);
      header_crc          ::= crc3 (this:uncomp_value,
                                    this:uncomp_length);
      psh_flag            ::= irregular (1);
      ack_number	  ::= lsb(4, 3);
   };

% +---+---+---+---+---+---+---+---+
% | 0   1 |    ACK_SN     | IP-ID |
% +===+===+===+===+===+===+===+===+
% |      MSN      |PSH|    CRC    |
% +---+---+---+---+---+---+---+---+

   % Send ACK and sequence number
   format_seq_5 = discriminator, %[ 5 ]
		  ip_id,         %[ 3 ]
		  ack_number,    %[ 12 ]
		  seq_number,    %[ 12 ]
		  msn,		 %[ 4 ]
		  psh_flag,      %[ 1 ]
		  header_crc,	 %[ 3 ]
   {
      let ((ip_id_behavior:uncomp_value == 2) ||
           (ip_id_behavior:uncomp_value == 3));
      discriminator       ::= '00000';
      msn                 ::= lsb(4, 4);
      ip_id               ::= ip_id_lsb (ip_id_behavior, msn, 3, 3);
      header_crc          ::= crc3 (this:uncomp_value,
                                    this:uncomp_length);
      psh_flag            ::= irregular (1);
      ack_number	  ::= lsb(12, 1023);
      seq_number	  ::= lsb(12, 2047);
   };

% +---+---+---+---+---+---+---+---+
% | 0   0   0   0   0 |   IP-ID   |
% +===+===+===+===+===+===+===+===+
% |            ACK_SN...          |
% +---+---+---+---+---+---+---+---+
% | ...ACK_SN     |      SN...    |
% +---+---+---+---+---+---+---+---+
% |           ...SN               |
% +---+---+---+---+---+---+---+---+
% |      MSN      |PSH|    CRC    |
% +---+---+---+---+---+---+---+---+

   % Send both ACK and scaled sequence number LSBs
   format_seq_6 = discriminator, %[ 3 ]
		  psh_flag,      %[ 1 ]
		  msn,		 %[ 4 ]
		  ip_id,         %[ 4 ]
  		  ack_number,    %[ 12 ]
		  seq_number_scaled, %[ 5 ]
		  header_crc,	 %[ 3 ]
   {
      let ((ip_id_behavior:uncomp_value == 2) ||
           (ip_id_behavior:uncomp_value == 3));
      discriminator       ::= '101';
      seq_number_scaled   ::= lsb(5, 15);
      seq_number_residue  ::= static;
      ip_id               ::= ip_id_lsb (ip_id_behavior, msn, 4, 3);
      ack_number	  ::= lsb(12, 1023);
      msn                 ::= lsb(4, 4);
      psh_flag            ::= irregular (1);
      header_crc          ::= crc3 (this:uncomp_value,
                                    this:uncomp_length);
   };

% +---+---+---+---+---+---+---+---+
% | 1   0   1 |     SN_SCALED     |
% +===+===+===+===+===+===+===+===+
% |     IP-ID     |    ACK_SN...  |
% +---+---+---+---+---+---+---+---+
% |         ...ACK_SN             |
% +---+---+---+---+---+---+---+---+
% |      MSN      |PSH|    CRC    |
% +---+---+---+---+---+---+---+---+

   % Send sequence number and window
   format_seq_7 = discriminator, %[ 5 ]
		  ip_id,         %[ 3 ]
		  seq_number,    %[ 16 ]
		  window,	 %[ 16 ]
		  msn,		 %[ 4 ]
		  psh_flag,      %[ 1 ]
		  header_crc,	 %[ 3 ]
   {
      let ((ip_id_behavior:uncomp_value == 2) ||
           (ip_id_behavior:uncomp_value == 3));
      discriminator       ::= '00001';
      msn                 ::= lsb(4, 4);
      ip_id               ::= ip_id_lsb (ip_id_behavior, msn, 3, 3);
      header_crc          ::= crc3 (this:uncomp_value,
                                    this:uncomp_length);
      psh_flag            ::= irregular (1);
      seq_number	  ::= lsb(16, 32767);
      window		  ::= irregular(16);
   };

% +---+---+---+---+---+---+---+---+
% | 0   0   0   0   1 |   IP-ID   |
% +===+===+===+===+===+===+===+===+
% |                               |
% +            ACK_SN             +
% |                               |
% +---+---+---+---+---+---+---+---+
% |                               |
% +              SN               +
% |                               |
% +---+---+---+---+---+---+---+---+
% |      MSN      |PSH|    CRC    |
% +---+---+---+---+---+---+---+---+

   % Send ACK and window
   format_seq_8 = discriminator, %[ 3 ]
		  ip_id,         %[ 5 ]
		  ack_number,    %[ 16 ]
		  window,	 %[ 16 ]
		  msn,		 %[ 4 ]
		  psh_flag,      %[ 1 ]
		  header_crc,	 %[ 3 ]
   {
      let ((ip_id_behavior:uncomp_value == 2) ||
           (ip_id_behavior:uncomp_value == 3));
      discriminator       ::= '110';
      msn                 ::= lsb(4, 4);
      ip_id               ::= ip_id_lsb (ip_id_behavior, msn, 5, 3);
      header_crc          ::= crc3 (this:uncomp_value,
                                    this:uncomp_length);
      psh_flag            ::= irregular (1);
      ack_number	  ::= lsb(16, 32767);
      window		  ::= irregular(16);
   };

% +---+---+---+---+---+---+---+---+
% | 1   1   0 |       IP-ID       |
% +===+===+===+===+===+===+===+===+
% |                               |
% +            ACK_SN             +
% |                               |
% +---+---+---+---+---+---+---+---+
% |                               |
% +            WINDOW             +
% |                               |
% +---+---+---+---+---+---+---+---+
% |      MSN      |PSH|    CRC    |
% +---+---+---+---+---+---+---+---+

   % Send scaled sequence number and window.
   format_seq_9 = discriminator, %[ 5 ]
		  ip_id,         %[ 3 ]
		  window,	 %[ 11 ]
		  seq_number_scaled, %[ 5 ]
		  msn,		 %[ 4 ]
		  psh_flag,      %[ 1 ]
		  header_crc,	 %[ 3 ]
   {
      let ((ip_id_behavior:uncomp_value == 2) ||
           (ip_id_behavior:uncomp_value == 3));
      discriminator       ::= '00101';
      msn                 ::= lsb(4, 4);
      ip_id               ::= ip_id_lsb (ip_id_behavior, msn, 3, 3);
      header_crc          ::= crc3 (this:uncomp_value,
                                    this:uncomp_length);
      psh_flag            ::= irregular (1);
      window		  ::= lsb(11, 1023);
      seq_number_scaled	  ::= lsb(5, 31);
      seq_number_residue  ::= static;
   };

% +---+---+---+---+---+---+---+---+
% | 0   0   1   0   1 |   IP-ID   |
% +===+===+===+===+===+===+===+===+
% |            WINDOW...          |
% +---+---+---+---+---+---+---+---+
% |...WINDOW  |     SN_SCALED     |
% +---+---+---+---+---+---+---+---+
% |      MSN      |PSH|    CRC    |
% +---+---+---+---+---+---+---+---+

   % A packet halfway between co_common and compressed packets
   % Can send LSBs of TTL, RSF flags, change ECN behavior and options list
   format_seq_10 = discriminator, %[ 5 ]
		   ttl_hopl,	  %[ 3 ]
		   ip_id,	  %[ 4 ]
		   msn,		  %[ 4 ]
		   ack_number,	  %[ 14 ]
		   rsf_flags,	  %[ 2 ]
		   seq_number,	  %[ 14 ]
		   psh_flag,      %[ 1 ]
		   ecn_used,	  %[ 1 ]
		   list_present,  %[ 1 ]
		   header_crc,	  %[ 7 ]
		   options_list,  % Nx8 bits
   {
      let ((ip_id_behavior:uncomp_value == 2) ||
           (ip_id_behavior:uncomp_value == 3));
      discriminator       ::= '00011';
      msn                 ::= lsb(4, 4);
      ip_id               ::= ip_id_lsb (ip_id_behavior, msn, 4, 3);
      header_crc          ::= crc7 (this:uncomp_value,
                                    this:uncomp_length);
      psh_flag            ::= irregular (1);
      list_present        ::= irregular(1);
      options_list        ::= tcp_list_presence_enc
                                      ((data_offset:uncomp_value + 20) / 4,
                                       list_present);
      rsf_flags           ::= rsf_index_enc;
      ecn_used		  ::= irregular(1);
      ttl_hopl		  ::= lsb(3, 3);
      seq_number	  ::= lsb(14, 8191);
      ack_number	  ::= lsb(14, 4095);
   };

% +---+---+---+---+---+---+---+---+
% | 0   0   0   1   1 |    TTL    |
% +===+===+===+===+===+===+===+===+
% |     IP-ID     |      MSN      |
% +---+---+---+---+---+---+---+---+
% |            ACK_SN...          |
% +---+---+---+---+---+---+---+---+
% |     ...ACK_SN         |  RSF  |
% +---+---+---+---+---+---+---+---+
% |              SN...            |
% +---+---+---+---+---+---+---+---+
% |       ...SN           |PSH|ECN|
% +---+---+---+---+---+---+---+---+
% |lst|            CRC            |
% +---+---+---+---+---+---+---+---+
% /         options_list          /  n*8 bits, if lst=1
%  --- --- --- --- --- --- --- ---
_______________________________________________
Rohc mailing list
[email-masked]
https://www1.ietf.org/mailman/listinfo/rohc