tech-invite   World Map     

IETF     RFCs     Groups     SIP     ABNFs    |    3GPP     Specs     Glossaries     Architecture     IMS     UICC    |    search     info

RFC 4996

 
 
 

RObust Header Compression (ROHC): A Profile for TCP/IP (ROHC-TCP)

Part 4 of 4, p. 65 to 94
Prev RFC Part

 


prevText      Top      Up      ToC       Page 65 
 tcp_opt_wscale
 {
   UNCOMPRESSED {
     type   =:= uncompressed_value(8, 3) [ 8 ];
     length =:= uncompressed_value(8, 3) [ 8 ];
     wscale                              [ 8 ];
   }

   COMPRESSED wscale_list_item {
     wscale =:= irregular(8) [ 8 ];
   }

   COMPRESSED wscale_irregular {
     wscale =:= static;
   }
 }

 ts_lsb
 {
   UNCOMPRESSED {
     tsval [ 32 ];
   }

   COMPRESSED tsval_7 {
     discriminator =:= '0'        [ 1 ];
     tsval         =:= lsb(7, -1) [ 7 ];
   }

   COMPRESSED tsval_14 {
     discriminator =:= '10'        [ 2 ];
     tsval         =:= lsb(14, -1) [ 14 ];
   }

   COMPRESSED tsval_21 {
     discriminator =:= '110'               [ 3 ];
     tsval         =:= lsb(21, 0x00040000) [ 21 ];
   }

   COMPRESSED tsval_29 {
     discriminator =:= '111'               [ 3 ];
     tsval         =:= lsb(29, 0x04000000) [ 29 ];
   }
 }

 tcp_opt_ts
 {
   UNCOMPRESSED {
     type   =:= uncompressed_value(8, 8)  [ 8 ];

Top      Up      ToC       Page 66 
     length =:= uncompressed_value(8, 10) [ 8 ];
     tsval                                [ 32 ];
     tsecho                               [ 32 ];
   }

   COMPRESSED tsopt_list_item {
     tsval  =:= irregular(32) [ 32 ];
     tsecho =:= irregular(32) [ 32 ];
   }

   COMPRESSED tsopt_irregular {
     tsval  =:= ts_lsb [ 8, 16, 24, 32 ];
     tsecho =:= ts_lsb [ 8, 16, 24, 32 ];
   }
 }

 sack_var_length_enc(base)
 {
   UNCOMPRESSED {
     sack_field [ 32 ];
   }

   CONTROL {
     sack_offset [ 32 ];
     ENFORCE(sack_offset.UVALUE == (sack_field.UVALUE - base));
   }


   COMPRESSED lsb_15 {
     discriminator =:= '0'         [ 1 ];
     sack_offset   =:= lsb(15, -1) [ 15 ];
   }

   COMPRESSED lsb_22 {
     discriminator =:= '10'        [ 2 ];
     sack_offset   =:= lsb(22, -1) [ 22 ];
   }

   COMPRESSED lsb_30 {
     discriminator =:= '11'        [ 2 ];
     sack_offset   =:= lsb(30, -1) [ 30 ];
   }
 }

 sack_block(prev_block_end)
 {
   UNCOMPRESSED {
     block_start [ 32 ];

Top      Up      ToC       Page 67 
     block_end   [ 32 ];
   }

   COMPRESSED {
     block_start =:=
       sack_var_length_enc(prev_block_end) [ 16, 24, 32 ];
     block_end   =:=
       sack_var_length_enc(block_start)    [ 16, 24, 32 ];
   }
 }

 // The value of the parameter is set to the ack_number value
 // of the TCP header
 tcp_opt_sack(ack_value)
 {

   UNCOMPRESSED {
     type    =:= uncompressed_value(8, 5) [ 8 ];
     length                               [ 8 ];
     block_1                              [ 64 ];
     block_2                              [ 0, 64 ];
     block_3                              [ 0, 64 ];
     block_4                              [ 0, 64 ];
   }

   DEFAULT {
     length  =:= static;
     block_2 =:= uncompressed_value(0, 0);
     block_3 =:= uncompressed_value(0, 0);
     block_4 =:= uncompressed_value(0, 0);
   }

   COMPRESSED sack1_list_item {
     discriminator =:= '00000001';
     block_1       =:= sack_block(ack_value);
     ENFORCE(length.UVALUE == 10);
   }

   COMPRESSED sack2_list_item {
     discriminator =:= '00000010';
     block_1       =:= sack_block(ack_value);
     block_2       =:= sack_block(block_1_end.UVALUE);
     ENFORCE(length.UVALUE == 18);
   }

   COMPRESSED sack3_list_item {
     discriminator =:= '00000011';
     block_1       =:= sack_block(ack_value);

Top      Up      ToC       Page 68 
     block_2       =:= sack_block(block_1_end.UVALUE);
     block_3       =:= sack_block(block_2_end.UVALUE);
     ENFORCE(length.UVALUE == 26);
   }

   COMPRESSED sack4_list_item {
     discriminator =:= '00000100';
     block_1       =:= sack_block(ack_value);
     block_2       =:= sack_block(block_1_end.UVALUE);
     block_3       =:= sack_block(block_2_end.UVALUE);
     block_4       =:= sack_block(block_3_end.UVALUE);
     ENFORCE(length.UVALUE == 34);
   }

   COMPRESSED sack_unchanged_irregular {
     discriminator =:= '00000000';
     block_1       =:= static;
     block_2       =:= static;
     block_3       =:= static;
     block_4       =:= static;
   }

   COMPRESSED sack1_irregular {
     discriminator =:= '00000001';
     block_1       =:= sack_block(ack_value);
     ENFORCE(length.UVALUE == 10);
   }

   COMPRESSED sack2_irregular {
     discriminator =:= '00000010';
     block_1       =:= sack_block(ack_value);
     block_2       =:= sack_block(block_1_end.UVALUE);
     ENFORCE(length.UVALUE == 18);
   }

   COMPRESSED sack3_irregular {
     discriminator =:= '00000011';
     block_1       =:= sack_block(ack_value);
     block_2       =:= sack_block(block_1_end.UVALUE);
     block_3       =:= sack_block(block_2_end.UVALUE);
     ENFORCE(length.UVALUE == 26);
   }

   COMPRESSED sack4_irregular {
     discriminator =:= '00000100';
     block_1       =:= sack_block(ack_value);
     block_2       =:= sack_block(block_1_end.UVALUE);
     block_3       =:= sack_block(block_2_end.UVALUE);

Top      Up      ToC       Page 69 
     block_4       =:= sack_block(block_3_end.UVALUE);
     ENFORCE(length.UVALUE == 34);
   }
 }

 tcp_opt_sack_permitted
 {
   UNCOMPRESSED {
     type   =:= uncompressed_value(8, 4) [ 8 ];
     length =:= uncompressed_value(8, 2) [ 8 ];
   }

   COMPRESSED sack_permitted_list_item {
   }

   COMPRESSED sack_permitted_irregular {
   }
 }

 tcp_opt_generic
 {
   UNCOMPRESSED {
     type                                    [ 8 ];
     length_msb =:= uncompressed_value(1, 0) [ 1 ];
     length_lsb                              [ 7 ];
     contents                           [ length_len.UVALUE*8-16 ];
   }

   CONTROL {
     option_static [ 1 ];
   }

   DEFAULT {
     type       =:= static;
     length_lsb =:= static;
     contents   =:= static;
   }

   COMPRESSED generic_list_item {
     type          =:= irregular(8)      [ 8 ];
     option_static =:= one_bit_choice    [ 1 ];
     length_lsb    =:= irregular(7)      [ 7 ];
     contents      =:=
       irregular(length_lsb.UVALUE*8-16) [ length_len.UVALUE*8-16 ];
   }

   // Used when context of option has option_static set to one
   COMPRESSED generic_static_irregular {

Top      Up      ToC       Page 70 
     ENFORCE(option_static.UVALUE == 1);
   }

   // An item that can change, but currently is unchanged
   COMPRESSED generic_stable_irregular {
     discriminator =:= '11111111' [ 8 ];
     ENFORCE(option_static.UVALUE == 0);
   }

   // An item that is assumed to change constantly.
   // Length is not allowed to change here, since a length change is
   // most likely to cause new NOPs or an EOL length change.
   COMPRESSED generic_full_irregular {
     discriminator =:= '00000000'        [ 8 ];
     contents      =:=
       irregular(length_lsb.UVALUE*8-16) [ length_lsb.UVALUE*8-16 ];
     ENFORCE(option_static.UVALUE == 0);
   }
 }

 tcp_list_presence_enc(presence)
 {
   UNCOMPRESSED {
     tcp_options;
   }

   COMPRESSED list_not_present {
     tcp_options =:= static [ 0 ];
     ENFORCE(presence == 0);
   }

   COMPRESSED list_present {
     tcp_options =:= list_tcp_options [ VARIABLE ];
     ENFORCE(presence == 1);
   }
 }

 /////////////////////////////////////////////
 // TCP Header
 /////////////////////////////////////////////

 port_replicate(flags)
 {
   UNCOMPRESSED {
     port [ 16 ];
   }

   COMPRESSED port_static_enc {

Top      Up      ToC       Page 71 
     port =:= static [ 0 ];
     ENFORCE(flags == 0b00);
   }

   COMPRESSED port_lsb8 {
     port =:= lsb(8, 64) [ 8 ];
     ENFORCE(flags == 0b01);
   }

   COMPRESSED port_irr_enc {
     port =:= irregular(16) [ 16 ];
     ENFORCE(flags == 0b10);
   }
 }

 tcp_irreg_ip_ecn(ip_inner_ecn)
 {
   UNCOMPRESSED {
     ip_ecn_flags [ 2 ];
   }

   COMPRESSED ecn_present {
     // This field does not exist in the uncompressed header
     // and therefore cannot use uncompressed_value.
     ip_ecn_flags =:=
       compressed_value(2, ip_inner_ecn) [ 2 ];
     ENFORCE(ecn_used.UVALUE == 1);
   }

   COMPRESSED ecn_not_present {
     ip_ecn_flags =:= static [ 0 ];
     ENFORCE(ecn_used.UVALUE == 0);
   }
 }

 rsf_index_enc
 {
   UNCOMPRESSED {
     rsf_flag [ 3 ];
   }

   COMPRESSED none {
     rsf_idx  =:= '00' [ 2 ];
     rsf_flag =:= uncompressed_value(3, 0x00);
   }

   COMPRESSED rst_only {
     rsf_idx  =:= '01' [ 2 ];

Top      Up      ToC       Page 72 
     rsf_flag =:= uncompressed_value(3, 0x04);
   }

   COMPRESSED syn_only {
     rsf_idx  =:= '10' [ 2 ];
     rsf_flag =:= uncompressed_value(3, 0x02);
   }

   COMPRESSED fin_only {
     rsf_idx  =:= '11' [ 2 ];
     rsf_flag =:= uncompressed_value(3, 0x01);
   }
 }

 optional_2bit_padding(used_flag)
 {
   UNCOMPRESSED {
   }

   COMPRESSED used {
     padding =:= compressed_value(2, 0x0) [ 2 ];
     ENFORCE(used_flag == 1);
   }

   COMPRESSED unused {
     padding =:= compressed_value(0, 0x0);
     ENFORCE(used_flag == 0);
   }
 }

 // ack_stride_value is the user-selected stride for scaling the
 // TCP ack_number
 // ip_inner_ecn is the value bound when processing the innermost
 // IP header (ipv4 or ipv6 encoding method)
 tcp(payload_size, ack_stride_value, ip_inner_ecn)
 {
   UNCOMPRESSED {
     src_port      [ 16 ];
     dst_port      [ 16 ];
     seq_number    [ 32 ];
     ack_number    [ 32 ];
     data_offset   [ 4 ];
     tcp_res_flags [ 4 ];
     tcp_ecn_flags [ 2 ];
     urg_flag      [ 1 ];
     ack_flag      [ 1 ];
     psh_flag      [ 1 ];
     rsf_flags     [ 3 ];

Top      Up      ToC       Page 73 
     window        [ 16 ];
     checksum      [ 16 ];
     urg_ptr       [ 16 ];
     options       [ (data_offset.UVALUE-5)*32 ];
   }

   CONTROL {
     seq_number_scaled                    [ 32 ];
     seq_number_residue =:=
         field_scaling(payload_size, seq_number_scaled.UVALUE,
                       seq_number.UVALUE) [ 32 ];
     ack_stride                           [ 16 ];
     ack_number_scaled                    [ 32 ];
     ack_number_residue =:=
         field_scaling(ack_stride.UVALUE, ack_number_scaled.UVALUE,
                       ack_number.UVALUE) [ 32 ];
     ENFORCE(ack_stride.UVALUE == ack_stride_value);
   }

   INITIAL {
     ack_stride     =:= uncompressed_value(16, 0);
   }

   DEFAULT {
     src_port      =:= static;
     dst_port      =:= static;
     seq_number    =:= static;
     ack_number    =:= static;
     data_offset   =:= inferred_offset;
     tcp_res_flags =:= static;
     tcp_ecn_flags =:= static;
     urg_flag      =:= static;
     ack_flag      =:= uncompressed_value(1, 1);
     rsf_flags     =:= uncompressed_value(3, 0);
     window        =:= static;
     urg_ptr       =:= static;
   }

   COMPRESSED tcp_static {
     src_port =:= irregular(16) [ 16 ];
     dst_port =:= irregular(16) [ 16 ];
   }

   COMPRESSED tcp_dynamic {
     ecn_used        =:= one_bit_choice          [ 1 ];
     ack_stride_flag =:= irregular(1)            [ 1 ];
     ack_zero        =:= irregular(1)            [ 1 ];
     urp_zero        =:= irregular(1)            [ 1 ];

Top      Up      ToC       Page 74 
     tcp_res_flags   =:= irregular(4)            [ 4 ];
     tcp_ecn_flags   =:= irregular(2)            [ 2 ];
     urg_flag        =:= irregular(1)            [ 1 ];
     ack_flag        =:= irregular(1)            [ 1 ];
     psh_flag        =:= irregular(1)            [ 1 ];
     rsf_flags       =:= irregular(3)            [ 3 ];
     msn             =:= irregular(16)           [ 16 ];
     seq_number      =:= irregular(32)           [ 32 ];
     ack_number      =:=
       zero_or_irreg(ack_zero.CVALUE, 32)        [ 0, 32 ];
     window          =:= irregular(16)           [ 16 ];
     checksum        =:= irregular(16)           [ 16 ];
     urg_ptr         =:=
       zero_or_irreg(urp_zero.CVALUE, 16)        [ 0, 16 ];
     ack_stride      =:=
       static_or_irreg(ack_stride_flag.CVALUE, 16) [ 0, 16 ];
     options         =:= list_tcp_options        [ VARIABLE ];
   }

   COMPRESSED tcp_replicate {
     reserved          =:= '0'                      [ 1 ];
     window_presence   =:= irregular(1)             [ 1 ];
     list_present      =:= irregular(1)             [ 1 ];
     src_port_presence =:= irregular(2)             [ 2 ];
     dst_port_presence =:= irregular(2)             [ 2 ];
     ack_stride_flag   =:= irregular(1)             [ 1 ];
     ack_presence      =:= irregular(1)             [ 1 ];
     urp_presence      =:= irregular(1)             [ 1 ];
     urg_flag          =:= irregular(1)             [ 1 ];
     ack_flag          =:= irregular(1)             [ 1 ];
     psh_flag          =:= irregular(1)             [ 1 ];
     rsf_flags         =:= rsf_index_enc            [ 2 ];
     ecn_used          =:= one_bit_choice           [ 1 ];
     msn               =:= irregular(16)            [ 16 ];
     seq_number        =:= irregular(32)            [ 32 ];
     src_port          =:=
       port_replicate(src_port_presence)      [ 0, 8, 16 ];
     dst_port          =:=
       port_replicate(dst_port_presence)      [ 0, 8, 16 ];
     window            =:=
       static_or_irreg(window_presence, 16)   [ 0, 16 ];
     urg_point         =:=
       static_or_irreg(urp_presence, 16)    [ 0, 16 ];
     ack_number        =:=
       static_or_irreg(ack_presence, 32)    [ 0, 32 ];
     ecn_padding       =:=
       optional_2bit_padding(ecn_used.CVALUE)     [ 0, 2 ];
     tcp_res_flags =:=

Top      Up      ToC       Page 75 
       static_or_irreg(ecn_used.CVALUE, 4)        [ 0, 4 ];
     tcp_ecn_flags     =:=
       static_or_irreg(ecn_used.CVALUE, 2)        [ 0, 2 ];
     checksum          =:= irregular(16)            [ 16 ];
     ack_stride        =:=
       static_or_irreg(ack_stride_flag.CVALUE, 16)  [ 0, 16 ];
     options           =:=
       tcp_list_presence_enc(list_present.CVALUE) [ VARIABLE ];
   }

   COMPRESSED tcp_irregular {
     ip_ecn_flags  =:= tcp_irreg_ip_ecn(ip_inner_ecn)  [ 0, 2 ];
     tcp_res_flags =:=
       static_or_irreg(ecn_used.CVALUE, 4)            [ 0, 4 ];
     tcp_ecn_flags =:=
       static_or_irreg(ecn_used.CVALUE, 2)             [ 0, 2 ];
     checksum      =:= irregular(16)                   [ 16 ];
   }
 }

 ///////////////////////////////////////////////////
 // Encoding methods used in compressed base headers
 ///////////////////////////////////////////////////

 dscp_enc(flag)
 {
   UNCOMPRESSED {
     dscp [ 6 ];
   }

   COMPRESSED static_enc {
     dscp =:= static [ 0 ];
     ENFORCE(flag == 0);
   }

   COMPRESSED irreg {
     dscp    =:= irregular(6)           [ 6 ];
     padding =:= compressed_value(2, 0) [ 2 ];
     ENFORCE(flag == 1);
   }
 }

 ip_id_lsb(behavior, k, p)
 {
   UNCOMPRESSED {
     ip_id [ 16 ];
   }

Top      Up      ToC       Page 76 
   CONTROL {
     ip_id_offset [ 16 ];
     ip_id_nbo    [ 16 ];
   }

   COMPRESSED nbo {
     ip_id_offset =:= lsb(k, p) [ k ];
     ENFORCE(behavior == IP_ID_BEHAVIOR_SEQUENTIAL);
     ENFORCE(ip_id_offset.UVALUE == ip_id.UVALUE - msn.UVALUE);
   }

   COMPRESSED non_nbo {
     ip_id_offset =:= lsb(k, p) [ k ];
     ENFORCE(behavior == IP_ID_BEHAVIOR_SEQUENTIAL_SWAPPED);
     ENFORCE(ip_id_nbo.UVALUE ==
             (ip_id.UVALUE / 256) + (ip_id.UVALUE % 256) * 256);
     ENFORCE(ip_id_nbo.ULENGTH == 16);
     ENFORCE(ip_id_offset.UVALUE == ip_id_nbo.UVALUE - msn.UVALUE);
   }
 }

 optional_ip_id_lsb(behavior, indicator)
 {
   UNCOMPRESSED {
     ip_id [ 16 ];
   }

   COMPRESSED short {
     ip_id =:= ip_id_lsb(behavior, 8, 3) [ 8 ];
     ENFORCE((behavior == IP_ID_BEHAVIOR_SEQUENTIAL) ||
             (behavior == IP_ID_BEHAVIOR_SEQUENTIAL_SWAPPED));
     ENFORCE(indicator == 0);
   }

   COMPRESSED long {
     ip_id =:= irregular(16)  [ 16 ];
     ENFORCE((behavior == IP_ID_BEHAVIOR_SEQUENTIAL) ||
             (behavior == IP_ID_BEHAVIOR_SEQUENTIAL_SWAPPED));
     ENFORCE(indicator == 1);
   }

   COMPRESSED not_present {
     ENFORCE((behavior == IP_ID_BEHAVIOR_RANDOM) ||
             (behavior == IP_ID_BEHAVIOR_ZERO));
   }
 }

 dont_fragment(version)

Top      Up      ToC       Page 77 
 {
   UNCOMPRESSED {
     df [ 1 ];
   }

   COMPRESSED v4 {
     df =:= irregular(1) [ 1 ];
     ENFORCE(version == 4);
   }

   COMPRESSED v6 {
     df =:= compressed_value(1, 0) [ 1 ];
     ENFORCE(version == 6);
   }
 }

 //////////////////////////////////
 // Actual start of compressed packet formats
 // Important note:
 //   The base header is the compressed representation
 //   of the innermost IP header AND the TCP header.
 //////////////////////////////////

 // ttl_irregular_chain_flag is set by the user if the TTL/Hop Limit
 // of an outer header has changed.  The same value must be passed as
 // an argument to the ipv4/ipv6 encoding methods when extracting
 // the irregular chain items.
 co_baseheader(payload_size, ack_stride_value,
               ttl_irregular_chain_flag)
 {
   UNCOMPRESSED v4 {
     outer_headers  =:= baseheader_outer_headers        [ VARIABLE ];
     version        =:= uncompressed_value(4, 4)        [ 4 ];
     header_length  =:= uncompressed_value(4, 5)        [ 4 ];
     dscp                                               [ 6 ];
     ip_ecn_flags                                       [ 2 ];
     length                                             [ 16 ];
     ip_id                                              [ 16 ];
     rf             =:= uncompressed_value(1, 0)        [ 1 ];
     df                                                 [ 1 ];
     mf             =:= uncompressed_value(1, 0)        [ 1 ];
     frag_offset    =:= uncompressed_value(13, 0)       [ 13 ];
     ttl_hopl                                           [ 8 ];
     next_header                                        [ 8 ];
     checksum                                           [ 16 ];
     src_addr                                           [ 32 ];
     dest_addr                                          [ 32 ];
     extension_headers =:= baseheader_extension_headers [ VARIABLE ];

Top      Up      ToC       Page 78 
     src_port                                           [ 16 ];
     dest_port                                          [ 16 ];
     seq_number                                         [ 32 ];
     ack_number                                         [ 32 ];
     data_offset                                        [ 4 ];
     tcp_res_flags                                      [ 4 ];
     tcp_ecn_flags                                      [ 2 ];
     urg_flag                                           [ 1 ];
     ack_flag                                           [ 1 ];
     psh_flag                                           [ 1 ];
     rsf_flags                                          [ 3 ];
     window                                             [ 16 ];
     tcp_checksum                                       [ 16 ];
     urg_ptr                                            [ 16 ];
     options                           [ (data_offset.UVALUE-5)*32 ];
   }

   UNCOMPRESSED v6 {
     outer_headers  =:= baseheader_outer_headers        [ VARIABLE ];
     version =:= uncompressed_value(4, 6)               [ 4 ];
     dscp                                               [ 6 ];
     ip_ecn_flags                                       [ 2 ];
     flow_label                                         [ 20 ];
     payload_length                                     [ 16 ];
     next_header                                        [ 8 ];
     ttl_hopl                                           [ 8 ];
     src_addr                                           [ 128 ];
     dest_addr                                          [ 128 ];
     extension_headers =:= baseheader_extension_headers [ VARIABLE ];
     src_port                                           [ 16 ];
     dest_port                                          [ 16 ];
     seq_number                                         [ 32 ];
     ack_number                                         [ 32 ];
     data_offset                                        [ 4 ];
     tcp_res_flags                                      [ 4 ];
     tcp_ecn_flags                                      [ 2 ];
     urg_flag                                           [ 1 ];
     ack_flag                                           [ 1 ];
     psh_flag                                           [ 1 ];
     rsf_flags                                          [ 3 ];
     window                                             [ 16 ];
     tcp_checksum                                       [ 16 ];
     urg_ptr                                            [ 16 ];
     options                           [ (data_offset.UVALUE-5)*32 ];
     ENFORCE(ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_RANDOM);
   }

   CONTROL {

Top      Up      ToC       Page 79 
     ip_id_behavior                       [ 2 ];
     seq_number_scaled                    [ 32 ];
     seq_number_residue =:=
         field_scaling(payload_size, seq_number_scaled.UVALUE,
                       seq_number.UVALUE) [ 32 ];
     ack_stride                           [ 16 ];
     ack_number_scaled                    [ 32 ];
     ack_number_residue =:=
         field_scaling(ack_stride.UVALUE, ack_number_scaled.UVALUE,
                       ack_number.UVALUE) [ 32 ];
     ENFORCE(ack_stride_value == ack_stride.UVALUE);
   }

   INITIAL {
     ack_stride     =:= uncompressed_value(16, 0);
   }

   DEFAULT {
     tcp_ecn_flags  =:= static;
     data_offset    =:= inferred_offset;
     tcp_res_flags  =:= static;
     rsf_flags      =:= uncompressed_value(3, 0);
     dest_port      =:= static;
     dscp           =:= static;
     src_port       =:= static;
     urg_flag       =:= uncompressed_value(1, 0);
     window         =:= static;
     dest_addr      =:= static;
     version        =:= static;
     ttl_hopl       =:= static;
     src_addr       =:= static;
     df             =:= static;
     ack_number     =:= static;
     urg_ptr        =:= static;
     seq_number     =:= static;
     ack_flag       =:= uncompressed_value(1, 1);
     // The default for "options" is case 2) and 3) from
     // the list in section 6.3.1 (i.e. nothing present in the
     // baseheader itself).
     payload_length =:= inferred_ip_v6_length;
     checksum       =:= inferred_ip_v4_header_checksum;
     length         =:= inferred_ip_v4_length;
     flow_label     =:= static;
     next_header    =:= static;
     ip_ecn_flags   =:= static;
     // The tcp_checksum has no default,
     // it is considered a part of tcp_irregular
     ip_id_behavior =:= static;

Top      Up      ToC       Page 80 
     ecn_used       =:= static;

     // Default is to have no TTL in irregular chain
     // Can only be nonzero if co_common is used
     ENFORCE(ttl_irregular_chain_flag == 0);
   }

   ////////////////////////////////////////////
   // Common compressed packet format
   ////////////////////////////////////////////

   COMPRESSED co_common {
     discriminator        =:= '1111101'                [ 7 ];
     ttl_hopl_outer_flag  =:=
         compressed_value(1, ttl_irregular_chain_flag) [ 1 ];
     ack_flag             =:= irregular(1)             [ 1 ];
     psh_flag             =:= irregular(1)             [ 1 ];
     rsf_flags            =:= rsf_index_enc            [ 2 ];
     msn                  =:= lsb(4, 4)                [ 4 ];
     seq_indicator        =:= irregular(2)             [ 2 ];
     ack_indicator        =:= irregular(2)             [ 2 ];
     ack_stride_indicator =:= irregular(1)             [ 1 ];
     window_indicator     =:= irregular(1)             [ 1 ];
     ip_id_indicator      =:= irregular(1)             [ 1 ];
     urg_ptr_present      =:= irregular(1)             [ 1 ];
     reserved             =:= compressed_value(1, 0)   [ 1 ];
     ecn_used             =:= one_bit_choice           [ 1 ];
     dscp_present         =:= irregular(1)             [ 1 ];
     ttl_hopl_present     =:= irregular(1)             [ 1 ];
     list_present         =:= irregular(1)             [ 1 ];
     ip_id_behavior       =:= ip_id_behavior_choice(true)     [ 2 ];
     urg_flag             =:= irregular(1)             [ 1 ];
     df                   =:= dont_fragment(version.UVALUE)   [ 1 ];
     header_crc           =:= crc7(THIS.UVALUE, THIS.ULENGTH) [ 7 ];
     seq_number           =:=
       variable_length_32_enc(seq_indicator.CVALUE) [ 0, 8, 16, 32 ];
     ack_number           =:=
       variable_length_32_enc(ack_indicator.CVALUE) [ 0, 8, 16, 32 ];
     ack_stride           =:=
       static_or_irreg(ack_stride_indicator.CVALUE, 16)  [ 0, 16 ];
     window               =:=
       static_or_irreg(window_indicator.CVALUE, 16)      [ 0, 16 ];
     ip_id                =:=
       optional_ip_id_lsb(ip_id_behavior.UVALUE,
                          ip_id_indicator.CVALUE)      [ 0, 8, 16 ];
     urg_ptr              =:=
       static_or_irreg(urg_ptr_present.CVALUE, 16)     [ 0, 16 ];
     dscp                 =:=

Top      Up      ToC       Page 81 
       dscp_enc(dscp_present.CVALUE)                   [ 0, 8 ];
     ttl_hopl             =:=
       static_or_irreg(ttl_hopl_present.CVALUE, 8)     [ 0, 8 ];
     options              =:=
       tcp_list_presence_enc(list_present.CVALUE)      [ VARIABLE ];
   }

   // Send LSBs of sequence number
   COMPRESSED rnd_1 {
     discriminator =:= '101110'                        [ 6 ];
     seq_number    =:= lsb(18, 65535)                  [ 18 ];
     msn           =:= lsb(4, 4)                       [ 4 ];
     psh_flag      =:= irregular(1)                    [ 1 ];
     header_crc    =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ];
     ENFORCE((ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_RANDOM) ||
             (ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_ZERO));
   }

   // Send scaled sequence number LSBs
   COMPRESSED rnd_2 {
     discriminator      =:= '1100'                          [ 4 ];
     seq_number_scaled  =:= lsb(4, 7)                       [ 4 ];
     msn                =:= lsb(4, 4)                       [ 4 ];
     psh_flag           =:= irregular(1)                    [ 1 ];
     header_crc         =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ];
     ENFORCE(payload_size != 0);
     ENFORCE((ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_RANDOM) ||
             (ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_ZERO));
   }

   // Send acknowledgment number LSBs
   COMPRESSED rnd_3 {
     discriminator =:= '0'                             [ 1 ];
     ack_number    =:= lsb(15, 8191)                   [ 15 ];
     msn           =:= lsb(4, 4)                       [ 4 ];
     psh_flag      =:= irregular(1)                    [ 1 ];
     header_crc    =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ];
     ENFORCE((ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_RANDOM) ||
             (ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_ZERO));
   }

   // Send acknowledgment number scaled
   COMPRESSED rnd_4 {
     discriminator      =:= '1101'                          [ 4 ];
     ack_number_scaled  =:= lsb(4, 3)                       [ 4 ];
     msn                =:= lsb(4, 4)                       [ 4 ];
     psh_flag           =:= irregular(1)                    [ 1 ];
     header_crc         =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ];

Top      Up      ToC       Page 82 
     ENFORCE(ack_stride.UVALUE != 0);
     ENFORCE((ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_RANDOM) ||
             (ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_ZERO));
   }

   // Send ACK and sequence number
   COMPRESSED rnd_5 {
     discriminator =:= '100'                           [ 3 ];
     psh_flag      =:= irregular(1)                    [ 1 ];
     msn           =:= lsb(4, 4)                       [ 4 ];
     header_crc    =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ];
     seq_number    =:= lsb(14, 8191)                   [ 14 ];
     ack_number    =:= lsb(15, 8191)                   [ 15 ];
     ENFORCE((ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_RANDOM) ||
             (ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_ZERO));
   }

   // Send both ACK and scaled sequence number LSBs
   COMPRESSED rnd_6 {
     discriminator      =:= '1010'                          [ 4 ];
     header_crc         =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ];
     psh_flag           =:= irregular(1)                    [ 1 ];
     ack_number         =:= lsb(16, 16383)                  [ 16 ];
     msn                =:= lsb(4, 4)                       [ 4 ];
     seq_number_scaled  =:= lsb(4, 7)                       [ 4 ];
     ENFORCE(payload_size != 0);
     ENFORCE((ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_RANDOM) ||
             (ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_ZERO));
   }

   // Send ACK and window
   COMPRESSED rnd_7 {
     discriminator =:= '101111'                        [ 6 ];
     ack_number    =:= lsb(18, 65535)                  [ 18 ];
     window        =:= irregular(16)                   [ 16 ];
     msn           =:= lsb(4, 4)                       [ 4 ];
     psh_flag      =:= irregular(1)                    [ 1 ];
     header_crc    =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ];
     ENFORCE((ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_RANDOM) ||
             (ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_ZERO));
   }

   // An extended packet type for seldom-changing fields
   // Can send LSBs of TTL, RSF flags, change ECN behavior, and
   // options list
   COMPRESSED rnd_8 {
     discriminator =:= '10110'                         [ 5 ];
     rsf_flags     =:= rsf_index_enc                   [ 2 ];

Top      Up      ToC       Page 83 
     list_present  =:= irregular(1)                    [ 1 ];
     header_crc    =:= crc7(THIS.UVALUE, THIS.ULENGTH) [ 7 ];
     msn           =:= lsb(4, 4)                       [ 4 ];
     psh_flag      =:= irregular(1)                    [ 1 ];
     ttl_hopl      =:= lsb(3, 3)                       [ 3 ];
     ecn_used      =:= one_bit_choice                  [ 1 ];
     seq_number    =:= lsb(16, 65535)                  [ 16 ];
     ack_number    =:= lsb(16, 16383)                  [ 16 ];
     options       =:=
       tcp_list_presence_enc(list_present.CVALUE)      [ VARIABLE ];
     ENFORCE((ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_RANDOM) ||
             (ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_ZERO));
   }

   // Send LSBs of sequence number
   COMPRESSED seq_1 {
     discriminator =:= '1010'                                 [ 4 ];
     ip_id         =:= ip_id_lsb(ip_id_behavior.UVALUE, 4, 3) [ 4 ];
     seq_number    =:= lsb(16, 32767)                         [ 16 ];
     msn           =:= lsb(4, 4)                              [ 4 ];
     psh_flag      =:= irregular(1)                           [ 1 ];
     header_crc    =:= crc3(THIS.UVALUE, THIS.ULENGTH)        [ 3 ];
     ENFORCE((ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_SEQUENTIAL) ||
             (ip_id_behavior.UVALUE ==
              IP_ID_BEHAVIOR_SEQUENTIAL_SWAPPED));
   }

   // Send scaled sequence number LSBs
   COMPRESSED seq_2 {
     discriminator      =:= '11010'                         [ 5 ];
     ip_id              =:=
       ip_id_lsb(ip_id_behavior.UVALUE, 7, 3)               [ 7 ];
     seq_number_scaled  =:= lsb(4, 7)                       [ 4 ];
     msn                =:= lsb(4, 4)                       [ 4 ];
     psh_flag           =:= irregular(1)                    [ 1 ];
     header_crc         =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ];
     ENFORCE(payload_size != 0);
     ENFORCE((ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_SEQUENTIAL) ||
             (ip_id_behavior.UVALUE ==
              IP_ID_BEHAVIOR_SEQUENTIAL_SWAPPED));
   }

   // Send acknowledgment number LSBs
   COMPRESSED seq_3 {
     discriminator =:= '1001'                                 [ 4 ];
     ip_id         =:= ip_id_lsb(ip_id_behavior.UVALUE, 4, 3) [ 4 ];
     ack_number    =:= lsb(16, 16383)                         [ 16 ];
     msn           =:= lsb(4, 4)                              [ 4 ];

Top      Up      ToC       Page 84 
     psh_flag      =:= irregular(1)                           [ 1 ];
     header_crc    =:= crc3(THIS.UVALUE, THIS.ULENGTH)        [ 3 ];
     ENFORCE((ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_SEQUENTIAL) ||
             (ip_id_behavior.UVALUE ==
              IP_ID_BEHAVIOR_SEQUENTIAL_SWAPPED));
   }

   // Send scaled acknowledgment number scaled
   COMPRESSED seq_4 {
     discriminator     =:= '0'                             [ 1 ];
     ack_number_scaled =:= lsb(4, 3)                       [ 4 ];
     // Due to having very few ip_id bits, no negative offset
     ip_id      =:= ip_id_lsb(ip_id_behavior.UVALUE, 3, 1) [ 3 ];
     msn               =:= lsb(4, 4)                       [ 4 ];
     psh_flag          =:= irregular(1)                    [ 1 ];
     header_crc        =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ];
     ENFORCE(ack_stride.UVALUE != 0);
     ENFORCE((ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_SEQUENTIAL) ||
             (ip_id_behavior.UVALUE ==
              IP_ID_BEHAVIOR_SEQUENTIAL_SWAPPED));
   }

   // Send ACK and sequence number
   COMPRESSED seq_5 {
     discriminator =:= '1000'                                 [ 4 ];
     ip_id         =:= ip_id_lsb(ip_id_behavior.UVALUE, 4, 3) [ 4 ];
     ack_number    =:= lsb(16, 16383)                         [ 16 ];
     seq_number    =:= lsb(16, 32767)                         [ 16 ];
     msn           =:= lsb(4, 4)                              [ 4 ];
     psh_flag      =:= irregular(1)                           [ 1 ];
     header_crc    =:= crc3(THIS.UVALUE, THIS.ULENGTH)        [ 3 ];
     ENFORCE((ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_SEQUENTIAL) ||
             (ip_id_behavior.UVALUE ==
              IP_ID_BEHAVIOR_SEQUENTIAL_SWAPPED));
   }

   // Send both ACK and scaled sequence number LSBs
   COMPRESSED seq_6 {
     discriminator      =:= '11011'                          [ 5 ];
     seq_number_scaled  =:= lsb(4, 7)                        [ 4 ];
     ip_id        =:= ip_id_lsb(ip_id_behavior.UVALUE, 7, 3) [ 7 ];
     ack_number         =:= lsb(16, 16383)                   [ 16 ];
     msn                =:= lsb(4, 4)                        [ 4 ];
     psh_flag           =:= irregular(1)                     [ 1 ];
     header_crc         =:= crc3(THIS.UVALUE, THIS.ULENGTH)  [ 3 ];
     ENFORCE(payload_size != 0);
     ENFORCE((ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_SEQUENTIAL) ||
             (ip_id_behavior.UVALUE ==

Top      Up      ToC       Page 85 
              IP_ID_BEHAVIOR_SEQUENTIAL_SWAPPED));
   }

   // Send ACK and window
   COMPRESSED seq_7 {
     discriminator =:= '1100'                                 [ 4 ];
     window        =:= lsb(15, 16383)                         [ 15 ];
     ip_id         =:= ip_id_lsb(ip_id_behavior.UVALUE, 5, 3) [ 5 ];
     ack_number    =:= lsb(16, 32767)                         [ 16 ];
     msn           =:= lsb(4, 4)                              [ 4 ];
     psh_flag      =:= irregular(1)                           [ 1 ];
     header_crc    =:= crc3(THIS.UVALUE, THIS.ULENGTH)        [ 3 ];
     ENFORCE((ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_SEQUENTIAL) ||
             (ip_id_behavior.UVALUE ==
              IP_ID_BEHAVIOR_SEQUENTIAL_SWAPPED));
   }

   // An extended packet type for seldom-changing fields
   // Can send LSBs of TTL, RSF flags, change ECN behavior, and
   // options list
   COMPRESSED seq_8 {
     discriminator =:= '1011'                                 [ 4 ];
     ip_id         =:= ip_id_lsb(ip_id_behavior.UVALUE, 4, 3) [ 4 ];
     list_present  =:= irregular(1)                           [ 1 ];
     header_crc    =:= crc7(THIS.UVALUE, THIS.ULENGTH)        [ 7 ];
     msn           =:= lsb(4, 4)                              [ 4 ];
     psh_flag      =:= irregular(1)                           [ 1 ];
     ttl_hopl      =:= lsb(3, 3)                              [ 3 ];
     ecn_used      =:= one_bit_choice                         [ 1 ];
     ack_number    =:= lsb(15, 8191)                          [ 15 ];
     rsf_flags     =:= rsf_index_enc                          [ 2 ];
     seq_number    =:= lsb(14, 8191)                          [ 14 ];
     options       =:=
       tcp_list_presence_enc(list_present.CVALUE)       [ VARIABLE ];
     ENFORCE((ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_SEQUENTIAL) ||
             (ip_id_behavior.UVALUE ==
              IP_ID_BEHAVIOR_SEQUENTIAL_SWAPPED));
   }
 }

Top      Up      ToC       Page 86 
8.3.  Feedback Formats and Options

8.3.1.  Feedback Formats

   This section describes the feedback formats for the ROHC-TCP profile,
   following the general ROHC feedback format described in Section 5.2.3
   of [RFC4995].

   All feedback formats carry a field labeled MSN.  The MSN field
   contains LSBs of the MSN control field described in Section 6.1.1.
   The sequence number to use is the MSN corresponding to the last
   header that was successfully CRC-8 validated or CRC verified.

   FEEDBACK-1

        0   1   2   3   4   5   6   7
      +---+---+---+---+---+---+---+---+
      |              MSN              |
      +---+---+---+---+---+---+---+---+

      MSN: The LSB-encoded master sequence number.

   A FEEDBACK-1 is an ACK.  In order to send a NACK or a STATIC-NACK,
   FEEDBACK-2 must be used.

   FEEDBACK-2

        0   1   2   3   4   5   6   7
      +---+---+---+---+---+---+---+---+
      |Acktype|          MSN          |
      +---+---+---+---+---+---+---+---+
      |              MSN              |
      +---+---+---+---+---+---+---+---+
      |              CRC              |
      +---+---+---+---+---+---+---+---+
      /       Feedback options        /
      +---+---+---+---+---+---+---+---+

      Acktype:

         0 = ACK

         1 = NACK

         2 = STATIC-NACK

         3 is reserved (MUST NOT be used for parsability)

Top      Up      ToC       Page 87 
      MSN: The LSB-encoded master sequence number.

      CRC: 8-bit CRC computed over the entire feedback element (as
      defined in Section 5.3.1.1 of [RFC4995]).  For the purpose of
      computing the CRC, the CRC field is zero.  The CRC is calculated
      using the polynomial defined in [RFC4995].

      Feedback options: A variable number of feedback options, see
      Section 8.3.2.  Options may appear in any order.

   A FEEDBACK-2 of type NACK or STATIC-NACK is always implicitly an
   acknowledgment for a successfully decompressed packet, which packet
   corresponds to the MSN of the feedback element, unless the MSN-NOT-
   VALID option (Section 8.3.2.2) appears in the feedback element.

   The FEEDBACK-2 format always carries a CRC and is thus more robust
   than the FEEDBACK-1 format.  When receiving FEEDBACK-2, the
   compressor MUST verify the information by computing the CRC and by
   comparing the result with the CRC carried in the feedback format.  If
   the two are not identical, the feedback element MUST be discarded.

8.3.2.  Feedback Options

   A ROHC-TCP feedback option has variable length and the following
   general format:

        0   1   2   3   4   5   6   7
      +---+---+---+---+---+---+---+---+
      |   Opt Type    |    Opt Len    |
      +---+---+---+---+---+---+---+---+
      /          option data          /  Opt Length (octets)
      +---+---+---+---+---+---+---+---+

   Each ROHC-TCP feedback option can appear at most once within a
   FEEDBACK-2.

8.3.2.1.  The REJECT Option

   The REJECT option informs the compressor that the decompressor does
   not have sufficient resources to handle the flow.

      +---+---+---+---+---+---+---+---+
      |  Opt Type = 2 |  Opt Len = 0  |
      +---+---+---+---+---+---+---+---+

   When receiving a REJECT option, the compressor MUST stop compressing
   the packet flow, and SHOULD refrain from attempting to increase the
   number of compressed packet flows for some time.  The REJECT option

Top      Up      ToC       Page 88 
   MUST NOT appear more than once in the FEEDBACK-2 format; otherwise,
   the compressor MUST discard the entire feedback element.

8.3.2.2.  The MSN-NOT-VALID Option

   The MSN-NOT-VALID option indicates that the MSN of the feedback is
   not valid.

      +---+---+---+---+---+---+---+---+
      |  Opt Type = 3 |  Opt Len = 0  |
      +---+---+---+---+---+---+---+---+

   A compressor MUST ignore the MSN of the feedback element when this
   option is present.  Consequently, a NACK or a STATIC-NACK feedback
   type sent with the MSN-NOT-VALID option is equivalent to a STATIC-
   NACK with respect to the semantics of the feedback message.

   The MSN-NOT-VALID option MUST NOT appear more than once in the
   FEEDBACK-2 format and MUST NOT appear in the same feedback element as
   the MSN option; otherwise, the compressor MUST discard the entire
   feedback element.

8.3.2.3.  The MSN Option

   The MSN option provides 2 additional bits of MSN.

      +---+---+---+---+---+---+---+---+
      |  Opt Type = 4 |  Opt Len = 1  |
      +---+---+---+---+---+---+---+---+
      |  MSN  |        Reserved       |
      +---+---+---+---+---+---+---+---+

   These 2 bits are the least significant bits of the MSN and are thus
   concatenated with the 14 bits already present in the FEEDBACK-2
   format.

   The MSN option MUST NOT appear more than once in the FEEDBACK-2
   format and MUST NOT appear in the same feedback element as the MSN-
   NOT-VALID option; otherwise, the compressor MUST discard the entire
   feedback element.

8.3.2.4.  The CONTEXT_MEMORY Feedback Option

   The CONTEXT_MEMORY option means that the decompressor does not have
   sufficient memory resources to handle the context of the packet flow,
   as the flow is currently compressed.

Top      Up      ToC       Page 89 
        0   1   2   3   4   5   6   7
      +---+---+---+---+---+---+---+---+
      |  Opt Type = 9 |  Opt Len = 0  |
      +---+---+---+---+---+---+---+---+

   When receiving a CONTEXT_MEMORY option, the compressor SHOULD take
   actions to compress the packet flow in a way that requires less
   decompressor memory resources, or stop compressing the packet flow.

   The CONTEXT_MEMORY option MUST NOT appear more than once in the
   FEEDBACK-2 format; otherwise, the compressor MUST discard the entire
   feedback element.

8.3.2.5.  Unknown Option Types

   If an option type unknown to the compressor is encountered, the
   compressor MUST continue parsing the rest of the FEEDBACK element,
   which is possible since the length of the option is explicit, but
   MUST otherwise ignore the unknown option.

9.  Security Considerations

   A malfunctioning or malicious header compressor could cause the
   header decompressor to reconstitute packets that do not match the
   original packets but still have valid IP and TCP headers, and
   possibly also valid TCP checksums.  Such corruption may be detected
   with end-to-end authentication and integrity mechanisms that will not
   be affected by the compression.  Moreover, this header compression
   scheme uses an internal checksum for verification of reconstructed
   headers.  This reduces the probability of producing decompressed
   headers not matching the original ones without this being noticed.

   Denial-of-service attacks are possible if an intruder can introduce
   (for example) bogus IR, CO, or FEEDBACK packets onto the link and
   thereby cause compression efficiency to be reduced.  However, an
   intruder having the ability to inject arbitrary packets at the link
   layer in this manner raises additional security issues that dwarf
   those related to the use of header compression.

10.  IANA Considerations

   The ROHC profile identifier 0x0006 has been reserved by the IANA for
   the profile defined in this document.

   A ROHC profile identifier has been reserved by the IANA for the
   profile defined in this document.  Profiles 0x0000-0x0005 have
   previously been reserved; this profile is 0x0006.  As for previous

Top      Up      ToC       Page 90 
   ROHC profiles, profile numbers 0xnn06 have been reserved for future
   updates of this profile.

        Profile             Usage            Document
        identifier

        0x0006              ROHC TCP         [RFC4996]
        0xnn06              Reserved

11.  Acknowledgments

   The authors would like to thank Qian Zhang, Hong Bin Liao, Richard
   Price, and Fredrik Lindstroem for their work with early versions of
   this specification.  Thanks also to Robert Finking and Carsten
   Bormann for valuable input.

   Additional thanks: this document was reviewed during working group
   last-call by committed reviewers Joe Touch and Ted Faber, as well as
   by Sally Floyd, who provided a review at the request of the Transport
   Area Directors.

12.  References

12.1.  Normative References

   [RFC0791]  Postel, J., "Internet Protocol", STD 5, RFC 791,
              September 1981.

   [RFC0793]  Postel, J., "Transmission Control Protocol", STD 7,
              RFC 793, September 1981.

   [RFC2004]  Perkins, C., "Minimal Encapsulation within IP", RFC 2004,
              October 1996.

   [RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
              Requirement Levels", BCP 14, RFC 2119, March 1997.

   [RFC2460]  Deering, S. and R. Hinden, "Internet Protocol, Version 6
              (IPv6) Specification", RFC 2460, December 1998.

   [RFC2784]  Farinacci, D., Li, T., Hanks, S., Meyer, D., and P.
              Traina, "Generic Routing Encapsulation (GRE)", RFC 2784,
              March 2000.

   [RFC2890]  Dommety, G., "Key and Sequence Number Extensions to GRE",
              RFC 2890, September 2000.

Top      Up      ToC       Page 91 
   [RFC4164]  Pelletier, G., "RObust Header Compression (ROHC): Context
              Replication for ROHC Profiles", RFC 4164, August 2005.

   [RFC4302]  Kent, S., "IP Authentication Header", RFC 4302,
              December 2005.

   [RFC4303]  Kent, S., "IP Encapsulating Security Payload (ESP)",
              RFC 4303, December 2005.

   [RFC4995]  Jonsson, L-E., Pelletier, G., and K. Sandlund, "The RObust
              Header Compression (ROHC) Framework", RFC 4995, July 2007.

   [RFC4997]  Finking, R. and G. Pelletier, "Formal Notation for Robust
              Header Compression (ROHC-FN)", RFC 4997, July 2007.

12.2.  Informative References

   [RFC1144]  Jacobson, V., "Compressing TCP/IP headers for low-speed
              serial links", RFC 1144, February 1990.

   [RFC1323]  Jacobson, V., Braden, B., and D. Borman, "TCP Extensions
              for High Performance", RFC 1323, May 1992.

   [RFC2018]  Mathis, M., Mahdavi, J., Floyd, S., and A. Romanow, "TCP
              Selective Acknowledgment Options", RFC 2018, October 1996.

   [RFC2507]  Degermark, M., Nordgren, B., and S. Pink, "IP Header
              Compression", RFC 2507, February 1999.

   [RFC2581]  Allman, M., Paxson, V., and W. Stevens, "TCP Congestion
              Control", RFC 2581, April 1999.

   [RFC2883]  Floyd, S., Mahdavi, J., Mathis, M., and M. Podolsky, "An
              Extension to the Selective Acknowledgement (SACK) Option
              for TCP", RFC 2883, July 2000.

   [RFC3095]  Bormann, C., Burmeister, C., Degermark, M., Fukushima, H.,
              Hannu, H., Jonsson, L-E., Hakenberg, R., Koren, T., Le,
              K., Liu, Z., Martensson, A., Miyazaki, A., Svanbro, K.,
              Wiebke, T., Yoshimura, T., and H. Zheng, "RObust Header
              Compression (ROHC): Framework and four profiles: RTP, UDP,
              ESP, and uncompressed", RFC 3095, July 2001.

   [RFC3168]  Ramakrishnan, K., Floyd, S., and D. Black, "The Addition
              of Explicit Congestion Notification (ECN) to IP",
              RFC 3168, September 2001.

Top      Up      ToC       Page 92 
   [RFC3759]  Jonsson, L-E., "RObust Header Compression (ROHC):
              Terminology and Channel Mapping Examples", RFC 3759,
              April 2004.

   [RFC4163]  Jonsson, L-E., "RObust Header Compression (ROHC):
              Requirements on TCP/IP Header Compression", RFC 4163,
              August 2005.

   [RFC4224]  Pelletier, G., Jonsson, L-E., and K. Sandlund, "RObust
              Header Compression (ROHC): ROHC over Channels That Can
              Reorder Packets", RFC 4224, January 2006.

   [RFC4413]  West, M. and S. McCann, "TCP/IP Field Behavior", RFC 4413,
              March 2006.

Top      Up      ToC       Page 93 
Authors' Addresses

   Ghyslain Pelletier
   Ericsson
   Box 920
   Lulea  SE-971 28
   Sweden

   Phone: +46 (0) 8 404 29 43
   EMail: ghyslain.pelletier@ericsson.com


   Kristofer Sandlund
   Ericsson
   Box 920
   Lulea  SE-971 28
   Sweden

   Phone: +46 (0) 8 404 41 58
   EMail: kristofer.sandlund@ericsson.com


   Lars-Erik Jonsson
   Optand 737
   Ostersund  SE-831 92
   Sweden

   Phone: +46 70 365 20 58
   EMail: lars-erik@lejonsson.com


   Mark A West
   Siemens/Roke Manor
   Roke Manor Research Ltd.
   Romsey, Hampshire  SO51 0ZN
   UK

   Phone: +44 1794 833311
   EMail: mark.a.west@roke.co.uk
   URI:   http://www.roke.co.uk

Top      Up      ToC       Page 94 
Full Copyright Statement

   Copyright (C) The IETF Trust (2007).

   This document is subject to the rights, licenses and restrictions
   contained in BCP 78, and except as set forth therein, the authors
   retain all their rights.

   This document and the information contained herein are provided on an
   "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
   OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY, THE IETF TRUST AND
   THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF
   THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
   WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.

Intellectual Property

   The IETF takes no position regarding the validity or scope of any
   Intellectual Property Rights or other rights that might be claimed to
   pertain to the implementation or use of the technology described in
   this document or the extent to which any license under such rights
   might or might not be available; nor does it represent that it has
   made any independent effort to identify any such rights.  Information
   on the procedures with respect to rights in RFC documents can be
   found in BCP 78 and BCP 79.

   Copies of IPR disclosures made to the IETF Secretariat and any
   assurances of licenses to be made available, or the result of an
   attempt made to obtain a general license or permission for the use of
   such proprietary rights by implementers or users of this
   specification can be obtained from the IETF on-line IPR repository at
   http://www.ietf.org/ipr.

   The IETF invites any interested party to bring to its attention any
   copyrights, patents or patent applications, or other proprietary
   rights that may cover technology that may be required to implement
   this standard.  Please address the information to the IETF at
   ietf-ipr@ietf.org.

Acknowledgement

   Funding for the RFC Editor function is currently provided by the
   Internet Society.