draft-ietf-rohc-rfc3095bis-rohcv2-profiles-00.txt   draft-ietf-rohc-rfc3095bis-rohcv2-profiles-01.txt 
Robust Header Compression G. Pelletier Robust Header Compression G. Pelletier
Internet-Draft K. Sandlund Internet-Draft K. Sandlund
Intended status: Standards Track Ericsson Expires: November 26, 2007 Ericsson
Expires: March 10, 2007 September 6, 2006 May 25, 2007
RObust Header Compression Version 2 (RoHCv2): Profiles for RTP, UDP, IP, RObust Header Compression Version 2 (RoHCv2): Profiles for RTP, UDP, IP,
ESP and UDP Lite ESP and UDP Lite
draft-ietf-rohc-rfc3095bis-rohcv2-profiles-00.txt draft-ietf-rohc-rfc3095bis-rohcv2-profiles-01
Status of this Memo Status of this Memo
By submitting this Internet-Draft, each author represents that any By submitting this Internet-Draft, each author represents that any
applicable patent or other IPR claims of which he or she is aware applicable patent or other IPR claims of which he or she is aware
have been or will be disclosed, and any of which he or she becomes have been or will be disclosed, and any of which he or she becomes
aware will be disclosed, in accordance with Section 6 of BCP 79. aware will be disclosed, in accordance with Section 6 of BCP 79.
Internet-Drafts are working documents of the Internet Engineering Internet-Drafts are working documents of the Internet Engineering
Task Force (IETF), its areas, and its working groups. Note that Task Force (IETF), its areas, and its working groups. Note that
skipping to change at page 1, line 35 skipping to change at page 1, line 35
and may be updated, replaced, or obsoleted by other documents at any and may be updated, replaced, or obsoleted by other documents at any
time. It is inappropriate to use Internet-Drafts as reference time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as "work in progress." material or to cite them other than as "work in progress."
The list of current Internet-Drafts can be accessed at The list of current Internet-Drafts can be accessed at
http://www.ietf.org/ietf/1id-abstracts.txt. http://www.ietf.org/ietf/1id-abstracts.txt.
The list of Internet-Draft Shadow Directories can be accessed at The list of Internet-Draft Shadow Directories can be accessed at
http://www.ietf.org/shadow.html. http://www.ietf.org/shadow.html.
This Internet-Draft will expire on March 10, 2007. This Internet-Draft will expire on November 26, 2007.
Copyright Notice Copyright Notice
Copyright (C) The Internet Society (2006). Copyright (C) The IETF Trust (2007).
Abstract Abstract
This document specifies ROHC (Robust Header Compression) profiles This document specifies ROHC (Robust Header Compression) profiles
that efficiently compress RTP/UDP/IP (Real-Time Transport Protocol, that efficiently compress RTP/UDP/IP (Real-Time Transport Protocol,
User Datagram Protocol, Internet Protocol), RTP/UDP-Lite/IP (User User Datagram Protocol, Internet Protocol), RTP/UDP-Lite/IP (User
Datagram Protocol Lite), UDP/IP, UDP-Lite/IP, IP and ESP/IP Datagram Protocol Lite), UDP/IP, UDP-Lite/IP, IP and ESP/IP
(Encapsulating Security Payload) headers. (Encapsulating Security Payload) headers.
This specification update the profiles defined in RFC 3095, RFC 3843 This specification defines a second version of the profiles found in
and RFC 4019 to their second version (RoHCv2 profiles). The profiles RFC 3095, RFC 3843 and RFC 4019; it supersedes their definition, but
herein thus supersede their earlier definition, but they do not does not obsolete them.
obsolete them.
The RoHCv2 specification introduce a number of simplifications to the The RoHCv2 profiles introduce a number of simplifications to the
rules and algorithms that govern the behavior of the compression rules and algorithms that govern the behavior of the compression
endpoints. It also defines robustness mechanisms that may be used by endpoints. It also defines robustness mechanisms that may be used by
a compressor implementation to increase the probability of a compressor implementation to increase the probability of
decompression success when packets can be lost and/or reordered on decompression success when packets can be lost and/or reordered on
the ROHC channel. Finally, the RoHCv2 profiles define its own the ROHC channel. Finally, the RoHCv2 profiles define its own
specific set of packet formats, using the ROHC formal notation. specific set of packet formats, using the ROHC formal notation.
Table of Contents Table of Contents
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 5 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 5
2. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 5 2. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 5
3. Acronyms . . . . . . . . . . . . . . . . . . . . . . . . . . 7 3. Acronyms . . . . . . . . . . . . . . . . . . . . . . . . . . 7
4. Background . . . . . . . . . . . . . . . . . . . . . . . . . 7 4. Background (Informative) . . . . . . . . . . . . . . . . . . 7
4.1. Classification of header fields . . . . . . . . . . . . . 8 4.1. Classification of header fields . . . . . . . . . . . . . 7
4.2. Operational Characteristics of RoHCv2 Profiles . . . . . 9 4.2. Operational Characteristics of RoHCv2 Profiles . . . . . 8
5. Overview of the RoHCv2 Profiles . . . . . . . . . . . . . . . 9 5. Overview of the RoHCv2 Profiles (Informative) . . . . . . . . 9
5.1. General Concepts . . . . . . . . . . . . . . . . . . . . 10 5.1. General Concepts . . . . . . . . . . . . . . . . . . . . 9
5.1.1. Control Fields and Context Updates . . . . . . . . . 10 5.1.1. Control Fields and Context Updates . . . . . . . . . 9
5.2. Compressor Concepts . . . . . . . . . . . . . . . . . . . 10 5.2. Compressor Concepts . . . . . . . . . . . . . . . . . . . 10
5.2.1. Optimistic Approach . . . . . . . . . . . . . . . . . 10 5.2.1. Optimistic Approach . . . . . . . . . . . . . . . . . 10
5.2.2. Tradeoff between robustness to losses and to 5.2.2. Tradeoff between robustness to losses and to
reordering . . . . . . . . . . . . . . . . . . . . . 11 reordering . . . . . . . . . . . . . . . . . . . . . 10
5.2.3. Interactions with the Decompressor Context . . . . . 12 5.2.3. Interactions with the Decompressor Context . . . . . 12
5.3. Decompressor Concepts . . . . . . . . . . . . . . . . . . 13 5.3. Decompressor Concepts . . . . . . . . . . . . . . . . . . 13
5.3.1. Decompressor State Machine . . . . . . . . . . . . . 14 5.3.1. Decompressor State Machine . . . . . . . . . . . . . 13
5.3.2. Decompressor Context Management . . . . . . . . . . . 16 5.3.2. Decompressor Context Management . . . . . . . . . . . 16
5.3.3. Feedback logic . . . . . . . . . . . . . . . . . . . 17 5.3.3. Feedback logic . . . . . . . . . . . . . . . . . . . 17
6. RoHCv2 Profiles (Normative) . . . . . . . . . . . . . . . . . 18 6. RoHCv2 Profiles (Normative) . . . . . . . . . . . . . . . . . 18
6.1. Profile Operation, per-context . . . . . . . . . . . . . 18 6.1. Profile Operation, per-context . . . . . . . . . . . . . 18
6.2. Control Fields . . . . . . . . . . . . . . . . . . . . . 19 6.2. Control Fields . . . . . . . . . . . . . . . . . . . . . 19
6.2.1. Master Sequence Number (MSN) . . . . . . . . . . . . 19 6.2.1. Master Sequence Number (MSN) . . . . . . . . . . . . 19
6.2.2. IP-ID behavior . . . . . . . . . . . . . . . . . . . 20 6.2.2. IP-ID behavior . . . . . . . . . . . . . . . . . . . 20
6.3. Reconstruction and Verification . . . . . . . . . . . . . 20 6.3. Reconstruction and Verification . . . . . . . . . . . . . 20
6.4. Compressed Header Chains . . . . . . . . . . . . . . . . 21 6.4. Reordering and Segmentation . . . . . . . . . . . . . . . 20
6.5. Packet Formats and Encoding Methods . . . . . . . . . . . 22 6.4.1. Optimistic Approach . . . . . . . . . . . . . . . . . 21
6.5.1. baseheader_extension_headers . . . . . . . . . . . . 22 6.5. Compressed Header Chains . . . . . . . . . . . . . . . . 21
6.5.2. baseheader_outer_headers . . . . . . . . . . . . . . 22 6.6. Packet Formats and Encoding Methods . . . . . . . . . . . 22
6.5.3. inferred_udp_length . . . . . . . . . . . . . . . . . 23 6.6.1. baseheader_extension_headers . . . . . . . . . . . . 22
6.5.4. inferred_ip_v4_header_checksum . . . . . . . . . . . 23 6.6.2. baseheader_outer_headers . . . . . . . . . . . . . . 23
6.5.5. inferred_mine_header_checksum . . . . . . . . . . . . 23 6.6.3. inferred_udp_length . . . . . . . . . . . . . . . . . 23
6.5.6. inferred_ip_v4_length . . . . . . . . . . . . . . . . 24 6.6.4. inferred_ip_v4_header_checksum . . . . . . . . . . . 23
6.5.7. inferred_ip_v6_length . . . . . . . . . . . . . . . . 24 6.6.5. inferred_mine_header_checksum . . . . . . . . . . . . 24
6.5.8. Scaled RTP Timestamp Encoding . . . . . . . . . . . . 25 6.6.6. inferred_ip_v4_length . . . . . . . . . . . . . . . . 24
6.5.9. inferred_scaled_field . . . . . . . . . . . . . . . . 26 6.6.7. inferred_ip_v6_length . . . . . . . . . . . . . . . . 25
6.5.10. control_crc3 . . . . . . . . . . . . . . . . . . . . 26 6.6.8. Scaled RTP Timestamp Encoding . . . . . . . . . . . . 25
6.5.11. inferred_sequential_ip_id . . . . . . . . . . . . . . 27 6.6.9. Timer-Based RTP Timestamp Encoding . . . . . . . . . 26
6.5.12. list_csrc(cc_value) . . . . . . . . . . . . . . . . . 27 6.6.10. inferred_scaled_field . . . . . . . . . . . . . . . . 26
6.6. Packet Formats . . . . . . . . . . . . . . . . . . . . . 31 6.6.11. control_crc3_encoding . . . . . . . . . . . . . . . . 27
6.6.1. Initialization and Refresh Packet (IR) . . . . . . . 31 6.6.12. inferred_sequential_ip_id . . . . . . . . . . . . . . 28
6.6.2. IR Packet Payload Discard (IR-PD) . . . . . . . . . 32 6.6.13. list_csrc(cc_value) . . . . . . . . . . . . . . . . . 28
6.6.3. IR Dynamic Packet (IR-DYN) . . . . . . . . . . . . . 33 6.7. Encoding Methods With External Parameters . . . . . . . . 32
6.6.4. Compressed Packet Formats (CO) . . . . . . . . . . . 34 6.8. Packet Formats . . . . . . . . . . . . . . . . . . . . . 36
6.7. Feedback Formats and Options . . . . . . . . . . . . . . 85 6.8.1. Initialization and Refresh Packet (IR) . . . . . . . 36
6.7.1. Feedback Formats . . . . . . . . . . . . . . . . . . 85 6.8.2. IR Packet Payload Discard (IR-PD) . . . . . . . . . 37
6.7.2. Feedback Options . . . . . . . . . . . . . . . . . . 87 6.8.3. Compressed Packet Formats (CO) . . . . . . . . . . . 38
7. Security Considerations . . . . . . . . . . . . . . . . . . . 89 6.9. Feedback Formats and Options . . . . . . . . . . . . . . 100
8. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 89 6.9.1. Feedback Formats . . . . . . . . . . . . . . . . . . 100
9. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 90 6.9.2. Feedback Options . . . . . . . . . . . . . . . . . . 101
10. References . . . . . . . . . . . . . . . . . . . . . . . . . 90 7. Security Considerations . . . . . . . . . . . . . . . . . . . 104
10.1. Normative References . . . . . . . . . . . . . . . . . . 90 8. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 104
10.2. Informative References . . . . . . . . . . . . . . . . . 92 9. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 106
Appendix A. Detailed classification of header fields . . . . 92 10. References . . . . . . . . . . . . . . . . . . . . . . . . . 106
Appendix A.1. General classification . . . . . . . . . . . . . 93 10.1. Normative References . . . . . . . . . . . . . . . . . . 106
Appendix A.1.1. IPv4 header fields . . . . . . . . . . . . . . . 93 10.2. Informative References . . . . . . . . . . . . . . . . . 107
Appendix A.1.2. IPv6 header fields . . . . . . . . . . . . . . . 95 Appendix A. Detailed classification of header fields . . . . 107
Appendix A.1.3. UDP header fields . . . . . . . . . . . . . . . 96 Appendix A.1. General classification . . . . . . . . . . . . . 108
Appendix A.1.4. UDP-Lite header fields . . . . . . . . . . . . . 96 Appendix A.1.1. IPv4 header fields . . . . . . . . . . . . . . . 108
Appendix A.1.5. RTP header fields . . . . . . . . . . . . . . . 97 Appendix A.1.2. IPv6 header fields . . . . . . . . . . . . . . . 110
Appendix A.2. Analysis of change patterns of header fields . . 98 Appendix A.1.3. UDP header fields . . . . . . . . . . . . . . . 111
Appendix A.2.1. IPv4 Identification . . . . . . . . . . . . . . 100 Appendix A.1.4. UDP-Lite header fields . . . . . . . . . . . . . 111
Appendix A.2.2. IP Traffic Class / Type-Of-Service . . . . . . . 101 Appendix A.1.5. RTP header fields . . . . . . . . . . . . . . . 112
Appendix A.2.3. IP Hop-limit / Time-To-Live . . . . . . . . . . 101 Appendix A.1.6. ESP header fields . . . . . . . . . . . . . . . 113
Appendix A.2.4. IPv4 Don't Fragment . . . . . . . . . . . . . . 102 Appendix A.2. Analysis of change patterns of header fields . . 113
Appendix A.2.5. UDP Checksum . . . . . . . . . . . . . . . . . . 102 Appendix A.2.1. IPv4 Identification . . . . . . . . . . . . . . 116
Appendix A.2.6. UDP-Lite Checksum Coverage . . . . . . . . . . . 102 Appendix A.2.2. IP Traffic Class / Type-Of-Service . . . . . . . 117
Appendix A.2.7. UDP-Lite Checksum . . . . . . . . . . . . . . . 102 Appendix A.2.3. IP Hop-limit / Time-To-Live . . . . . . . . . . 117
Appendix A.2.8. RTP CSRC Counter . . . . . . . . . . . . . . . . 102 Appendix A.2.4. IPv4 Don't Fragment . . . . . . . . . . . . . . 117
Appendix A.2.9. RTP Marker . . . . . . . . . . . . . . . . . . . 102 Appendix A.2.5. UDP Checksum . . . . . . . . . . . . . . . . . . 117
Appendix A.2.10. RTP Padding . . . . . . . . . . . . . . . . . . 103 Appendix A.2.6. UDP-Lite Checksum Coverage . . . . . . . . . . . 117
Appendix A.2.11. RTP Extension . . . . . . . . . . . . . . . . . 103 Appendix A.2.7. UDP-Lite Checksum . . . . . . . . . . . . . . . 117
Appendix A.2.12. RTP Payload Type . . . . . . . . . . . . . . . . 103 Appendix A.2.8. RTP CSRC Counter . . . . . . . . . . . . . . . . 117
Appendix A.2.13. RTP Sequence Number . . . . . . . . . . . . . . 103 Appendix A.2.9. RTP Marker . . . . . . . . . . . . . . . . . . . 118
Appendix A.2.14. RTP Timestamp . . . . . . . . . . . . . . . . . 103 Appendix A.2.10. RTP Padding . . . . . . . . . . . . . . . . . . 118
Appendix A.2.15. RTP Contributing Sources (CSRC) . . . . . . . . 104 Appendix A.2.11. RTP Extension . . . . . . . . . . . . . . . . . 118
Appendix A.3. Header compression strategies . . . . . . . . . 104 Appendix A.2.12. RTP Payload Type . . . . . . . . . . . . . . . . 118
Appendix A.3.1. Do not send at all . . . . . . . . . . . . . . . 104 Appendix A.2.13. RTP Sequence Number . . . . . . . . . . . . . . 118
Appendix A.3.2. Transmit only initially . . . . . . . . . . . . 104 Appendix A.2.14. RTP Timestamp . . . . . . . . . . . . . . . . . 118
Appendix A.3.3. Transmit initially, be prepared to update . . . 105 Appendix A.2.15. RTP Contributing Sources (CSRC) . . . . . . . . 119
Appendix A.3.4. Be prepared to update, or send as-is Appendix A.2.16. ESP Sequence Number . . . . . . . . . . . . . . 119
frequently . . . . . . . . . . . . . . . . . . . 105
Appendix A.3.5. Guarantee continuous robustness . . . . . . . . 105
Appendix A.3.6. Transmit as-is in all packets . . . . . . . . . 105
Appendix A.3.7. Establish and be prepared to update delta . . . 106
Appendix B. Differences between RoHCv2 and RFC3095 Appendix B. Differences between RoHCv2 and RFC3095
profiles . . . . . . . . . . . . . . . . . . . . 106 profiles . . . . . . . . . . . . . . . . . . . . 119
Appendix C. Sample CRC algorithm . . . . . . . . . . . . . . 106 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 120
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 108 Intellectual Property and Copyright Statements . . . . . . . . . 121
Intellectual Property and Copyright Statements . . . . . . . . . 110
1. Introduction 1. Introduction
The ROHC WG has developed a header compression framework on top of The ROHC WG has developed a header compression framework on top of
which various profiles can be defined for different protocol sets or which various profiles can be defined for different protocol sets or
compression requirements. The ROHC framework was first documented in compression requirements. The ROHC framework was first documented in
[RFC3095], together with profiles for compression of RTP/UDP/IP [RFC3095], together with profiles for compression of RTP/UDP/IP
(Real-Time Transport Protocol, User Datagram Protocol, Internet (Real-Time Transport Protocol, User Datagram Protocol, Internet
Protocol), UDP/IP, IP and ESP/IP (Encapsulating Security Payload) Protocol), UDP/IP, IP and ESP/IP (Encapsulating Security Payload)
headers. Additional profiles for compression of IP headers [RFC3843] headers. Additional profiles for compression of IP headers [RFC3843]
and UDP-Lite (User Datagram Protocol Lite) headers [RFC4019] were and UDP-Lite (User Datagram Protocol Lite) headers [RFC4019] were
later specified to complete the initial set of ROHC profiles. later specified to complete the initial set of ROHC profiles.
This document defines an updated version for each of the above This document defines an updated version for each of the above
mentionned profiles, and its definition is based on the specification mentioned profiles, and its definition is based on the specification
of the RoHC framework as found in of the RoHC framework as found in
[I-D.ietf-rohc-rfc3095bis-framework]. [I-D.ietf-rohc-rfc3095bis-framework].
Specifically, this document defines header compression schemes for: Specifically, this document defines header compression schemes for:
o RTP/UDP/IP : profile 0x0101 (updates profile 0x0001 [RFC3095]) o RTP/UDP/IP : profile 0x0101
o UDP/IP : profile 0x0102 (updates profile 0x0002 [RFC3095]) o UDP/IP : profile 0x0102
o ESP/IP : profile 0x0103 (updates profile 0x0003 [RFC3095]) o ESP/IP : profile 0x0103
o IP : profile 0x0104 (updates profile 0x0004 [RFC3843]) o IP : profile 0x0104
o RTP/UDP-Lite/IP : profile 0x0107 (updates profile 0x0007 [RFC4019]) o RTP/UDP-Lite/IP : profile 0x0107
o UDP-Lite/IP : profile 0x0108 (updates profile 0x0008 [RFC4019]) o UDP-Lite/IP : profile 0x0108
ROHCv2 compresses the following type of extension headers: ROHCv2 compresses the following type of extension headers:
o AH [RFC4302] o AH [RFC4302]
o GRE [RFC2784][RFC2890] o GRE [RFC2784][RFC2890]
o MINE [RFC2004] o MINE [RFC2004]
o NULL-encrupted ESP [RFC4303] o NULL-encrupted ESP [RFC4303]
o IPv6 Destination Options header[RFC2460] o IPv6 Destination Options header[RFC2460]
o IPv6 Hop-by-hop Options header[RFC2460] o IPv6 Hop-by-hop Options header[RFC2460]
o IPv6 Routing header [RFC2460]. o IPv6 Routing header [RFC2460].
skipping to change at page 6, line 15 skipping to change at page 6, line 15
Chaining of Items Chaining of Items
A chain groups fields based on similar characteristics. ROHCv2 A chain groups fields based on similar characteristics. ROHCv2
defines chain items for static, dynamic and irregular fields. defines chain items for static, dynamic and irregular fields.
Chaining is done by appending an item for e.g. each header to the Chaining is done by appending an item for e.g. each header to the
chain in their order of appearance in the uncompressed packet. chain in their order of appearance in the uncompressed packet.
Chaining is useful to construct compressed headers from an Chaining is useful to construct compressed headers from an
arbitrary number of any of the protocol headers for which a ROHCv2 arbitrary number of any of the protocol headers for which a ROHCv2
profile defines a compressed format. profile defines a compressed format.
CRC-8 validation
The CRC-8 validation refers to the validation of the integrity
against bit error(s) of the received IR and in the IR-DYN header,
using the 8-bit CRC that is included in the header.
CRC verification
The CRC verification refers to the verification of the result of a
decompression attempt, using the 3-bit CRC or 7-bit CRC included
in the header of a compressed packet format (CO).
Delta Delta
The delta refers to the difference in terms of the absolute value The delta refers to the difference in terms of the absolute value
of a field between two consecutive packets and processed by the of a field between two consecutive packets and processed by the
same compression endpoint. same compression endpoint.
Reordering Depth Reordering Depth
The number of packets by which a packet made late in its sequence. The number of packets by which a packet made late in its sequence.
See definition of sequentially late packet below. See definition of sequentially late packet below.
skipping to change at page 7, line 42 skipping to change at page 7, line 35
ROHCv2 Set of header compression profiles defined in this document ROHCv2 Set of header compression profiles defined in this document
RTP Real-time Transport Protocol. RTP Real-time Transport Protocol.
SSRC Synchronization source. Field in RTP header. SSRC Synchronization source. Field in RTP header.
CSRC Contributing source. Optional list of CSRCs in RTP header. CSRC Contributing source. Optional list of CSRCs in RTP header.
TC Traffic Class. Octet in IPv6 header. See also TOS. TC Traffic Class. Octet in IPv6 header. See also TOS.
TOS Type Of Service. Octet in IPv4 header. See also TC. TOS Type Of Service. Octet in IPv4 header. See also TC.
TS RTP Timestamp. TS RTP Timestamp.
UDP User Datagram Protocol. UDP User Datagram Protocol.
UDP-Lite User Datagram Protocol Lite. UDP-Lite User Datagram Protocol Lite.
4. Background 4. Background (Informative)
This section provides background information on the compression This section provides background information on the compression
profiles defined in this document. The fundamentals of general profiles defined in this document. The fundamentals of general
header compression and of the ROHC framework may be found in section header compression and of the ROHC framework may be found in section
3 and 4 of [I-D.ietf-rohc-rfc3095bis-framework], respectively. The 3 and 4 of [I-D.ietf-rohc-rfc3095bis-framework], respectively. The
fundamentals of the formal notation for ROHC are defined in fundamentals of the formal notation for ROHC are defined in
[I-D.ietf-rohc-formal-notation]. [RFC4224] describes the impacts of [I-D.ietf-rohc-formal-notation]. [RFC4224] describes the impacts of
out-of-order delivery on profiles based on [RFC3095]. out-of-order delivery on profiles based on [RFC3095].
4.1. Classification of header fields 4.1. Classification of header fields
skipping to change at page 8, line 28 skipping to change at page 8, line 21
The main conclusion is that most of the header fields can easily be The main conclusion is that most of the header fields can easily be
compressed away since they never or seldom change. A small number of compressed away since they never or seldom change. A small number of
fields however need more sophisticated mechanisms. fields however need more sophisticated mechanisms.
These fields are: These fields are:
- IPv4 Identification (16 bits) - IP-ID - IPv4 Identification (16 bits) - IP-ID
- ESP Sequence Number (32 bits) - ESP SN - ESP Sequence Number (32 bits) - ESP SN
- UDP Checksum (16 bits) - Checksum - UDP Checksum (16 bits) - Checksum
- UDP-Lite Checksum (16 bits) - Checksum - UDP-Lite Checksum (16 bits) - Checksum
- UDP-Lite Checksum Coverage (16 bits) - CC - UDP-Lite Checksum Coverage (16 bits) - CCov
- RTP Marker ( 1 bit ) - M-bit - RTP Marker ( 1 bit ) - M-bit
- RTP Sequence Number (16 bits) - RTP SN - RTP Sequence Number (16 bits) - RTP SN
- RTP Timestamp (32 bits) - TS - RTP Timestamp (32 bits) - TS
In particular, for RTP, the analysis in Appendix A reveals that the In particular, for RTP, the analysis in Appendix A reveals that the
values of the RTP Timestamp (TS) field usually have a strong values of the RTP Timestamp (TS) field usually have a strong
correlation to the RTP Sequence Number (SN), which increments by one correlation to the RTP Sequence Number (SN), which increments by one
for each packet emitted by an RTP source. The RTP M-bit is expected for each packet emitted by an RTP source. The RTP M-bit is expected
to have the same value most of the time, but it needs to be to have the same value most of the time, but it needs to be
communicated explicitly on occasion. communicated explicitly on occasion.
skipping to change at page 9, line 25 skipping to change at page 9, line 16
ROHCv2 profiles assume that the lower layer indicates the length ROHCv2 profiles assume that the lower layer indicates the length
of a compressed packet. ROHCv2 compressed headers do not contain of a compressed packet. ROHCv2 compressed headers do not contain
length information for the payload. length information for the payload.
Out-of-order delivery between compression endpoints Out-of-order delivery between compression endpoints
The definition of the RoHCv2 profiles places no strict requirement The definition of the RoHCv2 profiles places no strict requirement
on the delivery sequence between the compression endpoints, i.e. on the delivery sequence between the compression endpoints, i.e.
packets may be received in a different order than the compressor packets may be received in a different order than the compressor
sent them with a fair chance of successfully be decompressed. sent them and still have a fair probability to be successfully
decompressed.
However, frequent out-of-order delivery and/or significant However, frequent out-of-order delivery and/or significant
reordering depth will negatively impact the compression reordering depth will negatively impact the compression
efficiency. More specifically, if the channel state includes efficiency. More specifically, if the compressor can operate
parameters that provide a proper estimate of such significant out- using a proper estimate of the reordering characteristics of the
of-order delivery, larger headers can be sent more often to path between the compression endpoints, larger headers can be sent
increase the robustness against decompression failures due to more often to increase the robustness against decompression
reordering. Otherwise if the compressor cannot operate with failures due to out-of-order delivery. Otherwise, the compression
sufficient knowledge for such reordering, the efficiency will be efficiency will be impaired from an increase in the frequency of
impaired from an increase in the frequency of decompression decompression failures and recovery attempts.
failures and recovery attempts.
5. Overview of the RoHCv2 Profiles 5. Overview of the RoHCv2 Profiles (Informative)
This section provides an overview of important and useful concepts of This section provides an overview of important and useful concepts of
ROHCv2 profiles. These concepts may be used as guidelines for ROHCv2 profiles. These concepts may be used as guidelines for
implementations but they are not part of the normative definition of implementations but they are not part of the normative definition of
the profiles, as these concepts relates to the compression efficiency the profiles, as these concepts relates to the compression efficiency
of the protocol without impacting the interoperability of the protocol without impacting the interoperability
characteristics of an implementation. characteristics of an implementation.
5.1. General Concepts 5.1. General Concepts
skipping to change at page 10, line 19 skipping to change at page 10, line 4
Control fields have the same attributes and properties as Control fields have the same attributes and properties as
uncompressed fields [I-D.ietf-rohc-formal-notation]. These fields uncompressed fields [I-D.ietf-rohc-formal-notation]. These fields
are used for compression and decompression of some of the are used for compression and decompression of some of the
uncompressed header fields. Updating the value of one or more uncompressed header fields. Updating the value of one or more
control field(s) is thus no less important than updating context control field(s) is thus no less important than updating context
values for header fields. Control fields are defined in values for header fields. Control fields are defined in
[I-D.ietf-rohc-formal-notation]. [I-D.ietf-rohc-formal-notation].
Packet types that initialize or update the value of one or more Packet types that initialize or update the value of one or more
control field(s) thus include an additional 3-bit CRC, as defined by control field(s) thus include an additional 3-bit CRC, as defined by
the packet formats in Section 6.6. The CRC is calculated using the the packet formats in Section 6.8. The CRC is calculated using the
UVALUE of the control field(s) that it covers. UVALUE of the control field(s) that it covers.
This CRC validates all the control fields that are updated. Failure This CRC validates all the control fields that are updated. Failure
to verify this CRC should be interpreted by the decompressor as a to verify this CRC should be interpreted by the decompressor as a
decompression failure, in the algorithm it implements to assess the decompression failure, in the algorithm it implements to assess the
validity of its context. validity of its context.
5.2. Compressor Concepts 5.2. Compressor Concepts
Header compression can be conceptually characterized as the Header compression can be conceptually characterized as the
interaction of a compressor with a decompressor state machine, one interaction of a compressor with a decompressor state machine, one
per context. The responsability of the compressor is to minimally per context. The responsability of the compressor is to convey the
send the information needed to successfully decompress a packet, information needed to successfully decompress a packet, based on a
based on a certain confidence regarding the state of the decompressor certain confidence regarding the state of the decompressor context.
context.
This confidence is obtained from the frequency and the type of This confidence is obtained from the frequency and the type of
information the compressor sends when updating the decompressor information the compressor sends when updating the decompressor
context, from the optimistic approach and optionally from feedback context, from the optimistic approach (Section 5.2.1) and optionally
messages received from the decompressor. from feedback messages received from the decompressor.
5.2.1. Optimistic Approach 5.2.1. Optimistic Approach
A compressor always uses the optimistic approach when it performs A compressor always uses the optimistic approach when it performs
context updates. The compressor normally repeats the same type of context updates. The compressor normally repeats the same type of
update until it is fairly confident that the decompressor has update until it is fairly confident that the decompressor has
successfully received the information. If the decompressor successfully received the information. If the decompressor
successfully receives any of the headers containing this update, successfully receives any of the headers containing this update,
state will be available for the decompressor to process smaller state will be available for the decompressor to process smaller
compressed headers. compressed headers.
If field X in the uncompressed header changes value, the compressor If field X in the uncompressed header changes value, the compressor
uses a packet type that contains an encoding of field X until it has uses a packet type that contains an encoding of field X until it has
gained confidence that the decompressor has received at least one gained confidence that the decompressor has received at least one
packet containing the new value for X. The compressor normally packet containing the new value for X. The compressor normally
selects a compressed format with the smallest header that can convey selects a compressed format with the smallest header that can convey
the changes needed to achieve confidence. the changes needed to achieve confidence.
The number N of repetitions for the optimistic approach that is The number N of repetitions for the optimistic approach that is
needed to obtain this confidence is normally related to the packet needed to obtain this confidence is normally related to the packet
loss and to the out-of-order delivery characteristics of the link loss and out-of-order delivery characteristics of the link where
where header compression is used; it is thus not defined in this header compression is used; it is thus not defined in this document
document and is left open to implementations. and is left open to implementations.
5.2.2. Tradeoff between robustness to losses and to reordering 5.2.2. Tradeoff between robustness to losses and to reordering
The ability of a header compression algorithm to handle sequentially The ability of a header compression algorithm to handle sequentially
late packets is mainly limited by two factors: the interpretation late packets is mainly limited by two factors: the interpretation
interval offset of the sliding window used for LSB encoded fields interval offset of the sliding window used for LSB encoded fields
[I-D.ietf-rohc-formal-notation], and the optimistic approach [I-D.ietf-rohc-formal-notation], and the optimistic approach
Section 5.2.1 for seldom changing fields. Section 5.2.1 for seldom changing fields.
The interpretation interval offset specifies an upper limit for the The interpretation interval offset specifies an upper limit for the
skipping to change at page 12, line 7 skipping to change at page 11, line 37
where delta(SN) = p is the maximum negative delta, corresponding where delta(SN) = p is the maximum negative delta, corresponding
to the maximum reordering depth for which the lsb encoding can to the maximum reordering depth for which the lsb encoding can
recover the original value of the field; recover the original value of the field;
where delta(SN) = (2^k-1) - p is the maximum positive delta, where delta(SN) = (2^k-1) - p is the maximum positive delta,
corresponding to the maximum number of consecutive losses for corresponding to the maximum number of consecutive losses for
which the lsb encoding can recover the original value of the which the lsb encoding can recover the original value of the
field; field;
where v_ref is the reference value, as defined in the lsb encoding where v_ref is the reference value, as defined in the lsb encoding
method in [I-D.ietf-rohc-formal-notation]. method in [I-D.ietf-rohc-formal-notation].
The optimistic approach Section 5.2.1 provides the upper limit for The optimistic approach (Section 5.2.1) provides the upper limit for
the maximum reordering depth for seldom changing fields. the maximum reordering depth for seldom changing fields.
There is thus a tradeoff between the robustness against reordering There is thus a tradeoff between the robustness against reordering
and the robustness against packet losses, with respect to the number and the robustness against packet losses, with respect to the number
of MSN bits needed and the distribution of the interpretation of MSN bits needed and the distribution of the interpretation
interval between negative and positive deltas in the MSN. interval between negative and positive deltas in the MSN.
There is also a tradeoff between compression efficiency and There is also a tradeoff between compression efficiency and
robustness. When only information on the MSN needs to be conveyed to robustness. When only information on the MSN needs to be conveyed to
the decompressor, the tradeoff relates to the number of compressed the decompressor, the tradeoff relates to the number of compressed
MSN bits in the compressed header format. Otherwise, the tradeoff MSN bits in the compressed header format. Otherwise, the tradeoff
relates to the implementation of the optimistic approach. relates to the implementation of the optimistic approach.
5.2.3. Interactions with the Decompressor Context 5.2.3. Interactions with the Decompressor Context
The compressor normally starts compression with the initial The compressor normally starts compression with the initial
assumption that the decompressor has no useful information to process assumption that the decompressor has no useful information to process
the new flow, and sends Initialization and Refresh (IR) packets. the new flow, and sends Initialization and Refresh (IR) packets.
Initially, when sending the first IR packet for a compressed flow,
the compressor does not expect to receive feedback for that flow,
until such feedback is first received. At this point, the compressor
may then assume that the decompressor will continue to send feedback
in order to repair its context when necessary. The former is
referred to as unidirectional operation, while the latter is called
bidirectional operation.
The compressor can then adjust the compression level based on its The compressor can then adjust the compression level based on its
confidence that the decompressor has the necessary information to confidence that the decompressor has the necessary information to
successfully process the compressed headers that it selects. In successfully process the compressed headers that it selects. In
other words, the responsability of the compressor is to ensure that other words, the responsibility of the compressor is to ensure that
the decompressor operates with state information that is sufficient the decompressor operates with state information that is sufficient
to allow decompression of the most efficient compressed header(s), to allow decompression of the most efficient compressed header(s),
and to allow the decompressor to successfully recover that state and to allow the decompressor to successfully recover that state
information as soon as possible otherwise. information as soon as possible otherwise.
The compressor thus has the entire responsability to ensure that the The compressor thus has the entire responsability to ensure that the
decompressor has the proper information to decompress the type of decompressor has the proper information to decompress the type of
compressed header that it sends. In other words, the choice of compressed header that it sends. In other words, the choice of
compressed header depends on the following factors: compressed header depends on the following factors:
o the outcome of the encoding method applied to each field; o the outcome of the encoding method applied to each field;
o the optimistic approach, with respect to the characteristics of o the optimistic approach, with respect to the characteristics of
the channel; the channel;
o the presence or not of an established feedback channel, and if o the type of operation (unidirectional or bidirectional), and if in
present, feedback received from the decompressor (ACKs, NACKs, birectional operation, feedback received from the decompressor
Static-NACK and options). (ACKs, NACKs, Static-NACK, and options).
Encoding methods normally use previous value(s) from a history of Encoding methods normally use previous value(s) from a history of
packets whose headers it has previously compressed. The optimistic packets whose headers it has previously compressed. The optimistic
approach is meant to ensure that at least one compressed header approach is meant to ensure that at least one compressed header
containing the information to update the state for a field is containing the information to update the state for a field is
received. Finally, feedback indicates what actions the decompressor received. Finally, feedback indicates what actions the decompressor
has taken with respect its assumptions regarding the validity of its has taken with respect its assumptions regarding the validity of its
context Section 5.3.2; it indicates what type of compressed header context (Section 5.3.2); it indicates what type of compressed header
the decompressor can or cannot decompress. the decompressor can or cannot decompress.
The decompressor has the means to detect decompression failures for The decompressor has the means to detect decompression failures for
any type of compressed (CO) header, using the CRC verification. any type of compressed (CO) header, using the CRC verification.
Depending on the frequency and/or on the type of the failure, it Depending on the frequency and/or on the type of the failure, it
might send a negative acknowledgement (NACK) or an explicit request might send a negative acknowledgement (NACK) or an explicit request
for a complete context update (Static-NACK). However, the for a complete context update (Static-NACK). However, the
decompressor does not have the means to identify the cause of the decompressor does not have the means to identify the cause of the
failure, and in particular decompression of what field(s) is failure, and in particular decompression of what field(s) is
responsible for the failure. The compressor is thus always responsible for the failure. The compressor is thus always
reponsible to figure out what is the most suitable response to a reponsible to figure out what is the most suitable response to a
negative acknowledgement, using the confidence it has in the state of negative acknowledgement, using the confidence it has in the state of
the decompressor context, when selecting the type of compressed the decompressor context, when selecting the type of compressed
header it will use when compressing a header. header it will use when compressing a header.
5.3. Decompressor Concepts 5.3. Decompressor Concepts
Initially, when sending the first IR packet for a compressed flow,
the compressor does not expect to receive feedback for that flow,
until such feedback is first received. At this point, the compressor
may then assume that the decompressor will continue to send feedback
in order to repair its context when necessary. The former is
referred to as unidirectional operation, while the latter is called
bidirectional operation.
The decompressor normally always uses the last received and The decompressor normally always uses the last received and
successfully validated (IR or IR-DYN packets) or verified (CO successfully validated (IR packets) or verified (CO packets) header
packets) header as the reference for future decompression. If the as the reference for future decompression. If the received packet is
received packet is older than the current reference packet based on older than the current reference packet based on the MSN in the
the MSN in the compressed header, the decompressor may refrain from compressed header, the decompressor may refrain from using this
using this packet as the new reference packet, even if the packet as the new reference packet, even if the correctness of its
correctness of its header was successfully verified. header was successfully verified.
The decompressor's responsability is thus to minimally consistently The decompressor's responsibility is thus to minimally and
verify the outcome of the decompression attempt, update its context consistently verify the outcome of the decompression attempt, update
when successful and finally to request context repairs by making its context when successful and finally to request context repairs by
coherent usage of feedback, once it starts using it. making coherent usage of feedback, once it starts using it.
Specifically, the outcome of every decompression attempt is verified Specifically, the outcome of every decompression attempt is verified
using the CRC present in the compressed header; the decompressor using the CRC present in the compressed header; the decompressor
updates the context information when this outcome is successfully updates the context information when this outcome is successfully
verified; finally if the decompressor uses feedback once for a verified; finally if the decompressor uses feedback once for a
compressed flow then it will continue to do so for as long as the compressed flow then it will continue to do so for as long as the
corresponding context is associated with the same profile. corresponding context is associated with the same profile.
5.3.1. Decompressor State Machine 5.3.1. Decompressor State Machine
The decompressor operation may be represented as a state machine The decompressor operation may be represented as a state machine
defining three states: No Context (NC), Initial Context (IC) and Full defining three states: No Context (NC), Initial Context (IC) and Full
Context (FC). Context (FC).
The decompressor starts with no valid context, the NC state. The decompressor starts with no valid context, the NC state.
Successful CRC-8 validation of an IR packet moves the decompressor to Successful CRC-8 validation of an IR packet moves the decompressor to
the IC state, where it stays until it successfully verifies a the IC state, where it stays until it successfully verifies a
decompression attempt for compressed header with a 7-bit CRC. The decompression attempt for a compressed header with a 7-bit CRC. The
decompressor state machine normally does not leave the FC state once decompressor state machine normally does not leave the FC state once
it has entered this state; only repeated decompression failures will it has entered this state; only repeated decompression failures will
force the decompressor to transit downwards to a lower state. force the decompressor to transit downwards to a lower state.
Below is the state machine for the decompressor. Details of the Below is the state machine for the decompressor. Details of the
transitions between states and decompression logic are given in the transitions between states and decompression logic are given in the
sub-sections following the figure. sub-sections following the figure.
CRC-8(IR) or CRC-8(IR) or
CRC-8(IR-DYN) CRC-8(IR)
Validation Validation
CRC-8(IR) or CRC-7(CO) or CRC-7(CO) or
CRC-8(IR) CRC-8(IR) CRC-8(IR-DYN) CRC-7(CO) CRC-3(CO) CRC-8(IR) CRC-8(IR) CRC-8(IR) CRC-7(CO) CRC-3(CO)
Failure Validation Validation Verification Verification Failure Validation Validation Verification Verification
+--->---+ +-->---->--+ +-->----->--+ +-->---->--+ +-->---->--+ +--->---+ +-->---->--+ +-->----->--+ +-->---->--+ +-->---->--+
| | | | | | | | | | | | | | | | | | | |
| v | v | v | v | v | v | v | v | v | v
+-----------------+ +----------------------+ +-------------------+ +-----------------+ +----------------------+ +-------------------+
| No Context (NC) | | Initial Context (IC) | | Full Context (FC) | | No Context (NC) | | Initial Context (IC) | | Full Context (FC) |
+-----------------+ +----------------------+ +-------------------+ +-----------------+ +----------------------+ +-------------------+
^ | ^ CRC-7(CO) | ^ | ^ | ^ CRC-7(CO) | ^ |
| Static Context | | Failure or | | Context Damage | | Static Context | | Failure or | | Context Damage |
| Damage Detected | | PT not allowed | | Detected | | Damage Detected | | PT not allowed | | Detected |
+--<-----<-----<--+ +----<------<----+ +--<-----<-----<--+ +--<-----<-----<--+ +----<------<----+ +--<-----<-----<--+
where: where:
CRC-8(IR) and/or CRC-8(IR-DYN) validation: successful CRC-8 CRC-8(IR) validation: successful CRC-8 validation for the IR
validation for the IR header and the IR-DYN header, respectively. header.
CRC-7(CO) and/or CRC-3(CO) verification: successful CRC CRC-7(CO) and/or CRC-3(CO) verification: successful CRC
verification for the CO header, based on the number of CRC bits verification for the CO header, based on the number of CRC bits
carried in the CO header. carried in the CO header.
CRC-7(CO) failure: failure to CRC verify the decompression of a CO CRC-7(CO) failure: failure to CRC verify the decompression of a CO
header carrying a 7-bit CRC. header carrying a 7-bit CRC.
PT not allowed: the decompressor has received a packet type (PT) PT not allowed: the decompressor has received a packet type (PT)
for which the decopressor's current context does not provide for which the decopressor's current context does not provide
enough valid state information for that packet to be decompressed. enough valid state information for that packet to be decompressed.
Static Context Damaged Detected: see definition in Section 5.3.2. Static Context Damaged Detected: see definition in Section 5.3.2.
Context Damage Detected: see definition in Section 5.3.2. Context Damage Detected: see definition in Section 5.3.2.
5.3.1.1. No Context (NC) State 5.3.1.1. No Context (NC) State
Initially, while working in the No Context (NC) state, the Initially, while working in the No Context (NC) state, the
decompressor has not yet successfully validated an IR packet. decompressor has not yet successfully validated an IR packet.
Attempting decompression: Attempting decompression:
skipping to change at page 15, line 35 skipping to change at page 15, line 14
Feedback logic: Feedback logic:
In the No Context state, the decompressor should send a STATIC- In the No Context state, the decompressor should send a STATIC-
NACK if a packet of a type other than IR is received, or if an IR NACK if a packet of a type other than IR is received, or if an IR
packet has failed the CRC-8 validation, subject to the feedback packet has failed the CRC-8 validation, subject to the feedback
rate limitation as described in Section 5.3.3. rate limitation as described in Section 5.3.3.
5.3.1.2. Initial Context (IC) State 5.3.1.2. Initial Context (IC) State
In the IC state, the decompressor has successfully validated a IR In the IC state, the decompressor has successfully validated an IR
packet. packet.
Attempting decompression: Attempting decompression:
In the Initial Context state, only packets carrying sufficient In the Initial Context state, only packets carrying sufficient
information on the dynamic fields covered by an 8-bit CRC (e.g. information on the dynamic fields covered by an 8-bit CRC (i.e.
IR and IR-DYN) or CO packets carrying a 7-bit CRC can be IR) or CO packets carrying a 7-bit CRC can be decompressed.
decompressed.
Upward transition: Upward transition:
The decompressor can move to the Full Context (FC) state when the The decompressor can move to the Full Context (FC) state when the
CRC verification succeeds for a CO header carrying a 7-bit CRC. CRC verification succeeds for a CO header carrying a 7-bit CRC.
Downward transition: Downward transition:
The decompressor moves back to the NC state if it assumes static The decompressor moves back to the NC state if it assumes static
context damage. context damage.
Feedback logic: Feedback logic:
In the IC state, the decompressor should send a STATIC-NACK when In the IC state, the decompressor should send a STATIC-NACK when
CRC-8 validation of an IR/IR-DYN fails, or when a CO header CRC-8 validation of an IR fails, or when a CO header carrying a
carrying a 7-bit CRC fails and if static context damage is 7-bit CRC fails and if static context damage is assumed, subject
assumed, subject to the feedback rate limitation as described to the feedback rate limitation as described in Section 5.3.3. If
Section 5.3.3. If any other packet type is received, the any other packet type is received, the decompressor should treat
decompressor should treat it as a CRC verification failure when it as a CRC verification failure when deciding if a NACK is to be
deciding if a NACK is to be sent. sent.
5.3.1.3. Full Context (FC) State 5.3.1.3. Full Context (FC) State
In the FC state, the decompressor has successfully verified a CO In the FC state, the decompressor has successfully verified a CO
header with a 7-bit CRC. header with a 7-bit CRC.
Attempting decompression: Attempting decompression:
In the Full Context state, decompression can be attempted In the Full Context state, decompression can be attempted
regardless of the type of packet received. regardless of the type of packet received.
skipping to change at page 16, line 27 skipping to change at page 16, line 7
5.3.1.3. Full Context (FC) State 5.3.1.3. Full Context (FC) State
In the FC state, the decompressor has successfully verified a CO In the FC state, the decompressor has successfully verified a CO
header with a 7-bit CRC. header with a 7-bit CRC.
Attempting decompression: Attempting decompression:
In the Full Context state, decompression can be attempted In the Full Context state, decompression can be attempted
regardless of the type of packet received. regardless of the type of packet received.
Downward transition: Downward transition:
I. The decompressor moves back to the IC state if it assumes context
damage, and back to the NC state if it assumes static context
damage.
Feedback logic: Feedback logic:
In the Full Context state, the decompressor should send a NACK In the Full Context state, the decompressor should send a NACK
when CRC-8 validation or CRC verification of any packet type fails when CRC-8 validation or CRC verification of any packet type fails
and if context damage is assumed, subject to the feedback rate and if context damage is assumed, subject to the feedback rate
limitation as described in Section 5.3.3. limitation as described in Section 5.3.3.
5.3.2. Decompressor Context Management 5.3.2. Decompressor Context Management
All header formats carry a CRC and are context updating. A packet All header formats carry a CRC and are context updating. A packet
for which the CRC succeeds updates the reference values of all header for which the CRC succeeds updates the reference values of all header
fields, either explicitly (from the information about a field carried fields, either explicitly (from the information about a field carried
within the compressed header) or implicitly (fields that are inferred within the compressed header) or implicitly (fields that are inferred
from other fields). from other fields).
The decompressor may assume that some or the entire context is The decompressor may assume that some or the entire context is
invalid, following one or more failures to validate or verify a invalid, following one or more failures to validate or verify a
header using the CRC. Because the decompressor cannot know the exact header using the CRC. Because the decompressor cannot know the exact
reason(s) of a CRC failure or what field caused it, the validity of reason(s) for a CRC failure or what field caused it, the validity of
the context hence does not refer to what exact context entry is the context hence does not refer to what exact context entry is
deemed valid or not. deemed valid or not.
Validity of the context rather relates to the detection of a problem Validity of the context rather relates to the detection of a problem
with the context. The decompressor first assume that the type of with the context. The decompressor first assume that the type of
information that most likely caused the failure(s) is the state that information that most likely caused the failure(s) is the state that
normally changes for each packet, i.e. context damage of the dynamic normally changes for each packet, i.e. context damage of the dynamic
part of the context. Upon repeated failures and unsuccessful part of the context. Upon repeated failures and unsuccessful
repairs, the decompressor then assume that the entire context, repairs, the decompressor then assume that the entire context,
including the static part, needs to be repaired, i.e. static context including the static part, needs to be repaired, i.e. static context
damage. damage.
Context Damage Detection Context Damage Detection
The assumption of context damage means that the decompressor will The assumption of context damage means that the decompressor will
not attemp decompression of a CO headers that carries a 3-bit CRC, not attemp decompression of a CO headers that carries a 3-bit CRC,
and only attempt decompression of IR or IR-DYN headers, or CO and only attempt decompression of IR headers, or CO headers
headers protected by a CRC-7. protected by a CRC-7.
Static Context Damage Detection Static Context Damage Detection
The assumption of static context damage means that the The assumption of static context damage means that the
decompressor refrains from attempting decompression of any type of decompressor refrains from attempting decompression of any type of
header other than the IR header, as it cannot know what part of header other than the IR header, as it cannot know what part of
its context can be relied upon after first assuming context damage its context can be relied upon after first assuming context damage
and failed to repair its context, and as a result of too many and failed to repair its context, and as a result of too many
failures. failures.
How these assumptions are made, i.e. how context damage is detected, How these assumptions are made, i.e. how context damage is detected,
is open to implementations. It can be based on the residual error is open to implementations. It can be based on the residual error
rate, where a low error rate makes the decompressor assume damage rate, where a low error rate makes the decompressor assume damage
more often than on a high rate link. more often than on a high rate link.
The decompressor implements these assumptions by selecting the type The decompressor implements these assumptions by selecting the type
of compressed header for it may attempt decompression. In other of compressed header for it may attempt decompression. In other
words, validity of the context refers to the ability of a words, validity of the context refers to the ability of a
decompressor to attempt or not decompression of specific packet decompressor to attempt or not decompression of specific packet
types. types.
skipping to change at page 17, line 40 skipping to change at page 17, line 22
is open to implementations. It can be based on the residual error is open to implementations. It can be based on the residual error
rate, where a low error rate makes the decompressor assume damage rate, where a low error rate makes the decompressor assume damage
more often than on a high rate link. more often than on a high rate link.
The decompressor implements these assumptions by selecting the type The decompressor implements these assumptions by selecting the type
of compressed header for it may attempt decompression. In other of compressed header for it may attempt decompression. In other
words, validity of the context refers to the ability of a words, validity of the context refers to the ability of a
decompressor to attempt or not decompression of specific packet decompressor to attempt or not decompression of specific packet
types. types.
When RoHCv2 profiles are used over a channel that cannot guarantee
in-order delivery, the decompressor may refrain to update its context
with the content of a sequentially late packet that is successfully
decompressed. This is to avoid updating the context with information
that is older than what the decompressor already has in its context.
How the decompressor detects a sequentially late packet is outside
the scope of this specification, but it can for example use the MSN
to this purpose.
5.3.3. Feedback logic 5.3.3. Feedback logic
RoHCv2 profiles may be used in environments with or without feedback RoHCv2 profiles may be used in environments with or without feedback
capabilities from decompressor to compressor. RoHCv2 however assumes capabilities from decompressor to compressor. RoHCv2 however assumes
that if a ROHC feedback channel is available and if this channel is that if a ROHC feedback channel is available and if this channel is
used at least once by the decompressor for a specific context, this used at least once by the decompressor for a specific context, this
channel will be used during the entire compression operation for that channel will be used during the entire compression operation for that
context. If the connection is broken and the feedback channel context (i.e. bidirectional operation).
disappears, compression should be restarted.
The RoHC framework defines 3 types of feedback messages: ACKs, NACKs The RoHC framework defines 3 types of feedback messages: ACKs, NACKs
and STATIC-NACKs. The semantics of each message if defined insection and STATIC-NACKs. The semantics of each message if defined in
5.2.3.1. [I-D.ietf-rohc-rfc3095bis-framework] What feedback to send section 5.2.3.1. of [I-D.ietf-rohc-rfc3095bis-framework] What
is coupled to the context management of the decompressor, i.e. to the feedback to send is coupled to the context management of the
implementation of the context damage detection algorithms as decompressor, i.e. to the implementation of the context damage
described in Section 5.3.2. detection algorithms as described in Section 5.3.2.
The decompressor should send a NACK when it assumes context damage, The decompressor should send a NACK when it assumes context damage,
and it should send a STATIC-NACK when it assumes static context and it should send a STATIC-NACK when it assumes static context
damage. The decompressor is not strictly expected to send ACK damage. The decompressor is not strictly expected to send ACK
feedback upon successful decompression, other than for the purpose of feedback upon successful decompression, other than for the purpose of
improving compression efficiency. improving compression efficiency.
When RoHCv2 profiles are used over a channel that cannot guarantee
in-order delivery, the decompressor may refrain to send ACK feedback
for a sequentially late packet that is successfully decompressed.
How the decompressor detects a sequentially late packet is outside
the scope of this specification, but it can for example use the MSN
to this purpose.
The decompressor should limit the rate at which it sends feedback , The decompressor should limit the rate at which it sends feedback ,
for both ACKs and STATIC-NACK/NACKs, and should avoid sending for both ACKs and STATIC-NACK/NACKs, and should avoid sending
unnecessary duplicates of the same type of feedback message that may unnecessary duplicates of the same type of feedback message that may
be associated to the same event. be associated to the same event.
6. RoHCv2 Profiles (Normative) 6. RoHCv2 Profiles (Normative)
6.1. Profile Operation, per-context 6.1. Profile Operation, per-context
RoHCv2 profiles operates differently, per context, depending on how RoHCv2 profiles operates differently, per context, depending on how
the decompressor uses of a feedback channel. Once the decompressor the decompressor makes use of the feedback channel, if any. Once the
uses the feedback channel for a context, it establishes the feedback decompressor uses the feedback channel for a context, it establishes
channel for that CID. the feedback channel for that CID.
The compressor always start assuming that the decompressor will not The compressor always start assuming that the decompressor will not
send feedback when it initializes a new context (see also , section send feedback when it initializes a new context (see also , section
5.1.1.) [I-D.ietf-rohc-rfc3095bis-framework], i.e. there is no 5.1.1. of [I-D.ietf-rohc-rfc3095bis-framework]), i.e. there is no
established feedback channel for the new context. There will always established feedback channel for the new context. There will always
be a possibility of decompression failure with the optimistic be a possibility of decompression failure with the optimistic
approach, because the decompressor may not have received sufficient approach, because the decompressor may not have received sufficient
information for correct decompression. Therefore, until the information for correct decompression. Therefore, until the
decompressor has established a feedback channel, the compressor decompressor has established a feedback channel, the compressor
SHOULD periodically send IR packets. The periodicity can be based on SHOULD periodically send IR packets. The periodicity can be based on
timeouts, on the number of compressed packets sent for the flow, or timeouts, on the number of compressed packets sent for the flow, or
any other strategy the implementer chooses. any other strategy the implementer chooses.
The reception of either positive feedback (ACKs) or negative feedback The reception of either positive feedback (ACKs) or negative feedback
skipping to change at page 19, line 48 skipping to change at page 19, line 45
profile compresses (e.g. RTP SN), or alternatively it is created at profile compresses (e.g. RTP SN), or alternatively it is created at
the compressor. the compressor.
The MSN field has the following two functions: The MSN field has the following two functions:
o Differentiating between packets when sending feedback data. o Differentiating between packets when sending feedback data.
o Inferring the value of incrementing fields (e.g. IPv4 o Inferring the value of incrementing fields (e.g. IPv4
Identifier). Identifier).
The MSN field is present in every packet sent by the compressor. The The MSN field is present in every packet sent by the compressor. The
MSN is sent in full in IR and IR-DYN packets, while it is sent LSB MSN is sent in full in IR packets, while it is sent LSB encoded
encoded within CO header formats. The decompressor always sends the within CO header formats. The decompressor always sends the MSN as
MSN as part of the feedback information. The compressor can later part of the feedback information. The compressor can later use the
use the MSN to infer which packet the decompressor is acknowledging. MSN to infer which packet the decompressor is acknowledging.
When the MSN is initialized, it is initialized to a random value.
The compressor should only initialize a new MSN for the initial IR
packet sent for a new context, i.e. for a CID that corresponds to a
context that is not already associated with the profile used in the
IR header. In other words, if the compressor reuses the same CID
with the same profile to compress many flows one after the other, the
MSN is not reinitialized but rather continues to increment
monotonically.
For profiles for which the MSN is created by the compressor, the For profiles for which the MSN is created by the compressor, the
following rules applies: following rules applies:
o The compressor should only initialize a new MSN for the initial IR o The compressor should only initialize a new MSN for the initial IR
sent for a CID that corresponds to a context that is not already sent for a CID that corresponds to a context that is not already
associated with this profile; associated with this profile;
o When the MSN is initialized, it is initialized to a random value; o When the MSN is initialized, it is initialized to a random value;
o The value of the MSN is incremented by one for each packet that o The value of the MSN is incremented by one for each packet that
the compressor sends. the compressor sends.
6.2.2. IP-ID behavior 6.2.2. IP-ID behavior
The IP-ID field of the IPv4 header can have different change The IP-ID field of the IPv4 header can have different change
patterns: sequential in network byte order, sequential byte-swapped, patterns: sequential in network byte order, sequential byte-swapped,
random and constant (a constant value of zero, although not random or constant (a constant value of zero, although not conformant
conformant with [RFC0791], as been observed in practice).The control with [RFC0791], as been observed in practice). The control field for
field for the IP-ID behavior determines which set of packet formats the IP-ID behavior determines which set of packet formats will be
will be used. Note that these control fields are also used to used. Note that these control fields are also used to determine the
determine the contents of the irregular chain item for each IP contents of the irregular chain item for each IP header.
header.
If more than one level of IP headers is present, RoHCv2 profiles can If more than one level of IP headers is present, RoHCv2 profiles can
assign a sequential behavior (network byte order or byte-swapped) assign a sequential behavior (network byte order or byte-swapped)
only to the IP-ID of innermost IP header. This is because only this only to the IP-ID of innermost IP header. This is because only this
IP-ID can possibly have a sufficiently close correlation with the MSN IP-ID can possibly have a sufficiently close correlation with the MSN
to compress it as a sequentially changing field. Therefore, a to compress it as a sequentially changing field. Therefore, a
compressor MUST assign either the constant zero IP-ID or the random compressor MUST assign either the constant zero IP-ID or the random
IP-ID behavior to tunneling headers. IP-ID behavior to tunneling headers.
6.3. Reconstruction and Verification 6.3. Reconstruction and Verification
skipping to change at page 21, line 9 skipping to change at page 20, line 45
the current header; otherwise if the reconstructed header fails the the current header; otherwise if the reconstructed header fails the
CRC verification, these updates MUST NOT be performed. CRC verification, these updates MUST NOT be performed.
A packet for which the decompression attempt cannot be verified using A packet for which the decompression attempt cannot be verified using
the CRC MUST NOT be delivered to upper layers. the CRC MUST NOT be delivered to upper layers.
Note: Decompressor implementations may attempt corrective or repair Note: Decompressor implementations may attempt corrective or repair
measures prior to performing the above actions, and the result of any measures prior to performing the above actions, and the result of any
decompression attempt MUST be verified using the CRC. decompression attempt MUST be verified using the CRC.
6.4. Compressed Header Chains 6.4. Reordering and Segmentation
When ROHCv2 profiles are used on a channel that may reorder packets,
the compressor should take into account some extra considerations
compared to when used on a channel that guarantees in-order
delivery.ROHC Segmentation (see [I-D.ietf-rohc-rfc3095bis-framework]
section 5.2.5) must not be used, i.e. MRRU MUST be set to 0).
6.4.1. Optimistic Approach
The optimistic approach is affected by the reordering characteristics
of the channel when operating over a reordering channel. Compressor
implementations should therefore adjust their optimistic approach
strategy to match both packet loss and reordering characteristics.
For example, the number of repetitions for each update of a non-LSB
encoded field can be increased. The compressor should ensure that
each such update is repeated until it is reasonably confident that at
least one packet containing this change has reached the decompressor
before the first packet sent after this sequence.
6.5. Compressed Header Chains
Some packet types use one or more chains containing sub-header Some packet types use one or more chains containing sub-header
information. The function of a chain is to group fields based on information. The function of a chain is to group fields based on
similar characteristics, such as static, dynamic or irregular fields. similar characteristics, such as static, dynamic or irregular fields.
Chaining is done by appending an item for each header to the chain in Chaining is done by appending an item for each header to the chain in
their order of appearance in the uncompressed packet, starting from their order of appearance in the uncompressed packet, starting from
the fields in the outermost header. the fields in the outermost header.
Static chain: Static chain:
skipping to change at page 21, line 34 skipping to change at page 21, line 43
static chain item for each header type is labelled static chain item for each header type is labelled
<protocol_name>_static. The static chain is only used in IR <protocol_name>_static. The static chain is only used in IR
packets. packets.
Dynamic chain: Dynamic chain:
The dynamic chain consists of one item for each header of the The dynamic chain consists of one item for each header of the
chain of protocol headers to be compressed, starting from the chain of protocol headers to be compressed, starting from the
outermost IP header. In the formal description of the packet outermost IP header. In the formal description of the packet
formats, the dynamic chain item for each header type is labelled formats, the dynamic chain item for each header type is labelled
<protocol_name>_dynamic. The dynamic chain is used both in IR and <protocol_name>_dynamic. The dynamic chain is used in IR packet
IR-DYN packet format
Irregular chain: Irregular chain:
The structure of the irregular chain is analogous to the structure The structure of the irregular chain is analogous to the structure
of the static chain. For each compressed packet, the irregular of the static chain. For each compressed packet, the irregular
chain is appended at the specified location in the general format chain is appended at the specified location in the general format
of the compressed packets as defined in Section 6.6. The of the compressed packets as defined in Section 6.8. The
irregular chain is used for all CO packets. irregular chain is used for all CO packets.
The format of the irregular chain for the innermost IP header The format of the irregular chain for the innermost IP header
differs from the format of the one for the outer IP headers, since differs from the format of the one for the outer IP headers, since
this header is part of the compressed base header. What irregular this header is part of the compressed base header. What irregular
chain items to use is determined by the argument "is_innermost", chain items to use is determined by the argument "is_innermost",
which is passed as an argument to the corresponding encoding which is passed as an argument to the corresponding encoding
method (ipv4 or ipv6). The format of the irregular chain item for method (ipv4 or ipv6). The format of the irregular chain item for
the outer IP headers is also determined using one flag for TTL/Hop the outer IP headers is also determined using one flag for TTL/Hop
Limit and one for TOS/TC. These flags are defined in the format Limit and one for TOS/TC. These flags are defined in the format
of some of the compressed base headers. of some of the compressed base headers.
skipping to change at page 22, line 17 skipping to change at page 22, line 30
thus extension headers have a static chain, a dynamic chain and an thus extension headers have a static chain, a dynamic chain and an
irregular chain. irregular chain.
Chains are defined for all headers compressed by RoHCv2 profiles, Chains are defined for all headers compressed by RoHCv2 profiles,
i.e. RTP [RFC3550], UDP [RFC0768], UDP Lite [RFC3828], IPv4 i.e. RTP [RFC3550], UDP [RFC0768], UDP Lite [RFC3828], IPv4
[RFC0791], IPv6 [RFC2460], AH [RFC4302], GRE [RFC2784][RFC2890], MINE [RFC0791], IPv6 [RFC2460], AH [RFC4302], GRE [RFC2784][RFC2890], MINE
[RFC2004], NULL-encrupted ESP [RFC4303], IPv6 Destination Options [RFC2004], NULL-encrupted ESP [RFC4303], IPv6 Destination Options
header[RFC2460], IPv6 Hop-by-hop Options header[RFC2460] and IPv6 header[RFC2460], IPv6 Hop-by-hop Options header[RFC2460] and IPv6
Routing header [RFC2460]. Routing header [RFC2460].
6.5. Packet Formats and Encoding Methods 6.6. Packet Formats and Encoding Methods
The packet formats used for are defined using the ROHC formal The packet formats used for are defined using the ROHC formal
notation. Some of the encoding methods used in the packet formats notation. Some of the encoding methods used in the packet formats
are defined in [I-D.ietf-rohc-formal-notation], while other methods are defined in [I-D.ietf-rohc-formal-notation], while other methods
are defined in this section. are defined in this section.
6.5.1. baseheader_extension_headers 6.6.1. baseheader_extension_headers
In CO packets (see Section 6.6.4), the innermost IP header can be In CO packets (see Section 6.8.3), the innermost IP header can be
combined with other header(s) (i.e. UDP, UDP Lite, RTP) to create combined with other header(s) (i.e. UDP, UDP Lite, RTP) to create
the compressed base header. In such case, the IP header may have a the compressed base header. In such case, the IP header may have a
number of extension headers between itself and the other headers. number of extension headers between itself and the other headers.
The base header defines some representation of these extension The base header defines some representation of these extension
headers, to comply with the syntax of the formal notation; this headers, to comply with the syntax of the formal notation; this
encoding method provides this representation. The encoding method provides this representation. The
baseheader_extension_headers encoding method skips over all fields of baseheader_extension_headers encoding method skips over all fields of
the extension headers of the innermost IP header, without encoding the extension headers of the innermost IP header, without encoding
any of the them. Fields in these extension headers are instead any of the them. Fields in these extension headers are instead
encoded in the irregular chain. encoded in the irregular chain.
6.5.2. baseheader_outer_headers 6.6.2. baseheader_outer_headers
This encoding method, similarly to the baseheader_extension_headers This encoding method, similarly to the baseheader_extension_headers
encoding method above, is needed to keep the definition of the packet encoding method above, is needed to keep the definition of the packet
formats syntactically correct. It describe tunneling IP headers and formats syntactically correct. It describe tunneling IP headers and
their respective extension headers (i.e. all headers located before their respective extension headers (i.e. all headers located before
the innermost IP header) for CO headers (see Section 6.6.4). The the innermost IP header) for CO headers (see Section 6.8.3). The
baseheader_outer_headers encoding method skips over all the fields of baseheader_outer_headers encoding method skips over all the fields of
the extension header(s) that do not belong to the innermost IP the extension header(s) that do not belong to the innermost IP
header, without encoding any of them. Changed fields in outer header, without encoding any of them. Changed fields in outer
headers are instead handled by the irregular chain. headers are instead handled by the irregular chain.
6.5.3. inferred_udp_length 6.6.3. inferred_udp_length
The UDP length field is inferred by the decompressor to be the size The UDP length field is inferred by the decompressor to be the size
of the UDP payload. This also means that the compressor MUST make of the UDP payload. This also means that the compressor MUST make
sure that the UDP length field is consistent with the length field(s) sure that the UDP length field is consistent with the length field(s)
of preceeding subheaders, i.e., there must not be any padding after of preceeding subheaders, i.e., there must not be any padding after
the UDP payload that is covered by the IP Length. the UDP payload that is covered by the IP Length.
6.5.4. inferred_ip_v4_header_checksum 6.6.4. inferred_ip_v4_header_checksum
This encoding method compresses the header checksum field of the IPv4 This encoding method compresses the header checksum field of the IPv4
header. This checksum is defined in RFC 791 [RFC0791] as follows: header. This checksum is defined in RFC 791 [RFC0791] as follows:
Header Checksum: 16 bits Header Checksum: 16 bits
A checksum on the header only. Since some header fields change A checksum on the header only. Since some header fields change
(e.g., time to live), this is recomputed and verified at each (e.g., time to live), this is recomputed and verified at each
point that the internet header is processed. point that the internet header is processed.
skipping to change at page 23, line 48 skipping to change at page 24, line 11
The "inferred_ip_v4_header_checksum" encoding method thus compresses The "inferred_ip_v4_header_checksum" encoding method thus compresses
the IPv4 header checksum down to a size of zero bit, i.e. no bits are the IPv4 header checksum down to a size of zero bit, i.e. no bits are
transmitted in compressed headers for this field. Using this transmitted in compressed headers for this field. Using this
encoding method, the decompressor infers the value of this field encoding method, the decompressor infers the value of this field
using the computation above. using the computation above.
The compressor MAY use the header checksum to validate the The compressor MAY use the header checksum to validate the
correctness of the header before compressing it, to avoid compressing correctness of the header before compressing it, to avoid compressing
a corrupted header. a corrupted header.
6.5.5. inferred_mine_header_checksum 6.6.5. inferred_mine_header_checksum
This encoding method compresses the minimal encapsulation header This encoding method compresses the minimal encapsulation header
checksum. This checksum is defined in RFC 2004 [RFC2004] as follows: checksum. This checksum is defined in RFC 2004 [RFC2004] as follows:
Header Checksum Header Checksum
The 16-bit one's complement of the one's complement sum of all The 16-bit one's complement of the one's complement sum of all
16-bit words in the minimal forwarding header. For purposes of 16-bit words in the minimal forwarding header. For purposes of
computing the checksum, the value of the checksum field is 0. computing the checksum, the value of the checksum field is 0.
The IP header and IP payload (after the minimal forwarding The IP header and IP payload (after the minimal forwarding
header) are not included in this checksum computation. header) are not included in this checksum computation.
The "inferred_mine_header_checksum" encoding method compresses the The "inferred_mine_header_checksum" encoding method compresses the
minimal encapsulation header checksum down to a size of zero bit, minimal encapsulation header checksum down to a size of zero bit,
i.e. no bits are transmitted in compressed headers for this field. i.e. no bits are transmitted in compressed headers for this field.
Using this encoding method, the decompressor infers the value of this Using this encoding method, the decompressor infers the value of this
field using the above computation. field using the above computation.
The motivations for inferring this checksum are similar to the ones The motivations for inferring this checksum are similar to the ones
explained above in Section 6.5.4. explained above in Section 6.6.4.
The compressor MAY use the minimal encapsulation header checksum to The compressor MAY use the minimal encapsulation header checksum to
validate the correctness of the header before compressing it, to validate the correctness of the header before compressing it, to
avoid compressing a corrupted header. avoid compressing a corrupted header.
6.5.6. inferred_ip_v4_length 6.6.6. inferred_ip_v4_length
This encoding method compresses the total length field of the IPv4 This encoding method compresses the total length field of the IPv4
header. The total length field of the IPv4 header is defined in RFC header. The total length field of the IPv4 header is defined in RFC
791 [RFC0791] as follows: 791 [RFC0791] as follows:
Total Length: 16 bits Total Length: 16 bits
Total Length is the length of the datagram, measured in octets, Total Length is the length of the datagram, measured in octets,
including internet header and data. This field allows the including internet header and data. This field allows the
length of a datagram to be up to 65,535 octets. length of a datagram to be up to 65,535 octets.
The "inferred_ip_v4_length" encoding method compresses the IPv4 The "inferred_ip_v4_length" encoding method compresses the IPv4
header checksum down to a size of zero bit, i.e. no bits are header checksum down to a size of zero bit, i.e. no bits are
transmitted in compressed headers for this field. Using this transmitted in compressed headers for this field. Using this
encoding method, the decompressor infers the value of this field by encoding method, the decompressor infers the value of this field by
counting in octets the length of the entire packet after counting in octets the length of the entire packet after
decompression. decompression.
6.5.7. inferred_ip_v6_length 6.6.7. inferred_ip_v6_length
This encoding method compresses the payload length field in the IPv6 This encoding method compresses the payload length field in the IPv6
header. This length field is defined in RFC 2460 [RFC2460] as header. This length field is defined in RFC 2460 [RFC2460] as
follows: follows:
Payload Length: 16-bit unsigned integer Payload Length: 16-bit unsigned integer
Length of the IPv6 payload, i.e., the rest of the packet Length of the IPv6 payload, i.e., the rest of the packet
following this IPv6 header, in octets. (Note that any following this IPv6 header, in octets. (Note that any
extension headers present are considered part of the payload, extension headers present are considered part of the payload,
i.e., included in the length count.) i.e., included in the length count.)
The "inferred_ip_v6_length" encoding method compresses the payload The "inferred_ip_v6_length" encoding method compresses the payload
length field of the IPv6 header down to a size of zero bit, i.e. no length field of the IPv6 header down to a size of zero bit, i.e. no
bits are transmitted in compressed headers for this field. Using bits are transmitted in compressed headers for this field. Using
this encoding method, the decompressor infers the value of this field this encoding method, the decompressor infers the value of this field
by counting in octets the length of the entire packet after by counting in octets the length of the entire packet after
decompression. decompression.
6.5.8. Scaled RTP Timestamp Encoding 6.6.8. Scaled RTP Timestamp Encoding
The RTP timestamp usually increases by a multiple of the RTP Sequence The RTP timestamp (TS) usually increases by a multiple of the RTP
Number's increase and is therefore a suitable candidate for scaled Sequence Number's (SN) increase and is therefore a suitable candidate
encoding. The scaling factor is decided by the compressor by for scaled encoding. This scaling factor is labeled ts_stride in the
observing the increase in Timestamp compared to the RTP Sequence definition of the profile in ROHC-FN Section 6.8. The compressor
Number. This scaling factor is labeled ts_stride in the definition sets the scaling factor based on the change in TS with respect to the
of the profile in ROHC-FNSection 6.6. change in the RTP SN.
For the compressor to use the scaled timestamps, it MUST first The initial value of the scaling factor ts_stride is always set to 1
explicitly transmit the value of ts_stride to the decompressor, using [NOTE: define what is initial? New context with this profile?].
one of the packet types that can carry this information. Once the When ts_stride is set to 1, scaling is not applied on the field for
value of the scaling factor is established, before using this scaled any format.
encoding the compressor must have enough confidence that the
Initially, the scaling factor is set to 1, meaning that no actual
scaling is performed even in the scaled packet formats. For the
compressor to use a different scaling value, it must first explicitly
transmit the new value of ts_stride to the decompressor, using one of
the packet types that can carry this information. Once the new value
of the scaling factor is established, before using the new scaling
factor, the compressor must have enough confidence that the
decompressor has successfully calculated the residue (ts_offset) of decompressor has successfully calculated the residue (ts_offset) of
the scaling function for the timestamp. This is done by sending the scaling function for the timestamp. This is done by sending
unscaled timestamp values to allow the compressor to establish the unscaled timestamp values to allow the decompressor to establish the
residue based on the ts_stride established. residue based on the current ts_stride. The compressor MAY send the
unscaled timestamp in the same packets as the ones establishing the
new ts_stride value.
Once the compressor has gained enough confidence that both the value Once the compressor has gained enough confidence that both the value
of the scaling factor and the value of the residue have been of the scaling factor and the value of the residue have been
established in the decompressor, the compressor can start compressing established in the decompressor, the compressor can start compressing
packets using the scaled representation of the timestamp. The packets using the new scaling factor.
compressor MUST NOT use the scaled timestamp encoding with the value
of the ts_stride is set to zero.
If the compressor notices that the residue (ts_offset) value changes, If the compressor notices that the residue (ts_offset) value changes,
the compressor cannot use scaled timestamp packet formats until it the compressor cannot use scaled timestamp packet formats until it
has re-established the residue as described above. has re-established the residue as described above.
If the decompressor receives a packet containing scaled timestamp
bits while the ts_stride equals zero, it MUST NOT deliver the packet
to upper layers.
When the value of the timestamp field wraps around, the value of the When the value of the timestamp field wraps around, the value of the
residue of the scaling function is likely to change. When this residue of the scaling function is likely to change. When this
occurs, the compressor re-establishes the new residue value, e.g. occurs, the compressor re-establishes the new residue value as
using the unscaled representation of the field as described above. described above.
The compressor MAY use the scaled timestamp encoding; what value it The compressor MAY use the scaled timestamp encoding; what value it
will use as the scaling factor is up to the compressor will use as the scaling factor is up to the compressor
implementation, but to achive any gains from the scaling, the implementation, but to achive any gains from the scaling, the
ts_stride should be set to the value of the expected incease in ts_stride should be set to the value of the expected incease in
timestamp between consecutive sequence numbers. timestamp between consecutive sequence numbers.
When scaled timestamp encoding is used for packet formats that do not When scaled timestamp encoding is used for packet formats that do not
transmit any LSB-encoded timestamp bits at all, the Section 6.5.9 is transmit any LSB-encoded timestamp bits at all, the Section 6.6.10 is
used for encoding the timestamp. used for encoding the timestamp.
6.5.9. inferred_scaled_field 6.6.9. Timer-Based RTP Timestamp Encoding
Text to be added. Same encoding method as in RFC 3095, section
4.5.4.
6.6.10. inferred_scaled_field
The "inferred_scaled_field" encoding method is used to encode a field The "inferred_scaled_field" encoding method is used to encode a field
that is defined as changing in relation to the MSN but for each that is defined as changing in relation to the MSN but for each
increase is scaled by an established scaling factor. This encoding increase is scaled by an established scaling factor. This encoding
method is to be used in the case when a packet format contains MSN method is to be used in the case when a packet format contains MSN
bits, but does not contain any bits for the scaled field. In this bits, but does not contain any bits for the scaled field. In this
case, the new value for the field being scaled is calculated case, the new value for the field being scaled is calculated
according to the following formula: according to the following formula:
unscaled_value = delta_msn * stride + previous_unscaled_value unscaled_value = delta_msn * stride + previous_unscaled_value
Where "delta_msn" is the difference is MSN between the previous value Where "delta_msn" is the difference is MSN between the previous value
of MSN in the context and the value of the MSN decompressed from this of MSN in the context and the value of the MSN decompressed from this
packet, "previous_unscaled_value" is the value of the field being packet, "previous_unscaled_value" is the value of the field being
scaled in the context, and "stride" is the scaling value for this scaled in the context, and "stride" is the scaling value for this
field. field.
For example, when this encoding method is applied to the RTP For example, when this encoding method is applied to the RTP
timestamp in the RTP profile, the calculation above becomes: timestamp in the RTP profile, the calculation above becomes:
timestamp = delta_msn * ts_stride + previous_timestamp timestamp = delta_msn * ts_stride + previous_timestamp
skipping to change at page 26, line 35 skipping to change at page 27, line 16
Where "delta_msn" is the difference is MSN between the previous value Where "delta_msn" is the difference is MSN between the previous value
of MSN in the context and the value of the MSN decompressed from this of MSN in the context and the value of the MSN decompressed from this
packet, "previous_unscaled_value" is the value of the field being packet, "previous_unscaled_value" is the value of the field being
scaled in the context, and "stride" is the scaling value for this scaled in the context, and "stride" is the scaling value for this
field. field.
For example, when this encoding method is applied to the RTP For example, when this encoding method is applied to the RTP
timestamp in the RTP profile, the calculation above becomes: timestamp in the RTP profile, the calculation above becomes:
timestamp = delta_msn * ts_stride + previous_timestamp timestamp = delta_msn * ts_stride + previous_timestamp
6.5.10. control_crc3 6.6.11. control_crc3_encoding
Some control fields that can be transmit by the co_common packet type The "control_crc3_encoding" method provides a CRC calculated over a
of each profile might not be used when decompressing this packet, and number of control fields. The definition of this encoding method is
therefore will not be covered by the included 7-bit CRC. If such a the same as for the "crc" encoding method specified in section 4.11.6
control field has been corrupted on the link between compressor and of [I-D.ietf-rohc-formal-notation], with the difference that the data
decompressor, the decompressor might send an ACK for this packet that is covered by the CRC is given by a concatenated list of control
which would be interpreted by the compressor as if the control fields fields.
included in this packet were successfully decompressed. To avoid
such a situation, an additional 3-bit CRC is included in the
co_common packets.
This 3-bit CRC uses the same polynomial as the crc3 encoding method In other words, the definition of the control_crc3_encoding method is
defined in the formal notation, but has a different coverage. This equivalent to the following definition:
CRC should be calculated over the following field, in the order that
they are listed below:
o reorder_ratio, padded by 6 MSB of zeroes control_crc_encoding(data_value, data_length)
o ts_stride, 16 bits (if applicable for this profile) {
UNCOMPRESSED {
}
6.5.11. inferred_sequential_ip_id COMPRESSED {
control_crc3 =:=
crc(3, 0x06, 0x07, ctrl_data_value, ctrl_data_length) [ 3 ];
}
}
where the parameter "ctrl_data_value" binds to the concatenated
values of the following control fields, in the order listed below:
o reorder_ratio, 2 bits padded by 6 MSB of zeroes
o ts_stride, 16 bits (applicable only for profiles 0x0101 and
0x0107)
o msn,16 bits (not applicable for profiles 0x0101 and 0x0107)
The "ctrl_data_length" binds to the sum of the length of the control
field(s) that are applicable.
A 3-bit CRC is used to validate the control fields that are updated
by the co_common and co_repair packet types; it cannot verify the
outcome of a decompression attempt. The definition of this CRC comes
from the fact that the decompression of a header that carries and
updates control fields does not necessarily make use of these control
fields, and the update to the control fields is thus not protected by
the CRC-7 validation.
For example, without a verification of the updates to the control
fields, there would be a possibility that a decompression attempt
succeeds for a co_common or for a co_repair packet for which the
decompressor would send a positive feedback, even in the case where
one of the control fields had been corrupted on the link between the
compression endpoints.
6.6.12. inferred_sequential_ip_id
This encoding method is used when a sequential IP-ID behavior is used This encoding method is used when a sequential IP-ID behavior is used
(sequential or sequential byte-swapped) and no coded IP-ID bits are (sequential or sequential byte-swapped) and no coded IP-ID bits are
present in the compressed header. When these packet types are used, present in the compressed header. When these packet types are used,
the IP-ID offset from the MSN will be constant, and therefore, the the IP-ID offset from the MSN will be constant, and therefore, the
IP-ID will increase by the same amount as the MSN increases by IP-ID will increase by the same amount as the MSN increases by
(similar to the inferred_scaled_field encoding method). (similar to the inferred_scaled_field encoding method).
Therefore, the new value for the IP-ID is calculated according to the Therefore, the new value for the IP-ID is calculated according to the
following formula: following formula:
IP-ID = delta_msn + previous_IP_ID_value IP-ID = delta_msn + previous_IP_ID_value
Where "delta_msn" is the difference is MSN between the previous value Where "delta_msn" is the difference is MSN between the previous value
of MSN in the context and the value of the MSN decompressed from this of MSN in the context and the value of the MSN decompressed from this
packet, "previous_IP_ID_value" is the value of the IP-ID in the packet, "previous_IP_ID_value" is the value of the IP-ID in the
context. context.
If the IP-ID behavior is random or zero, this encoding method does If the IP-ID behavior is random or zero, this encoding method does
not update any fields. not update any fields.
6.5.12. list_csrc(cc_value) 6.6.13. list_csrc(cc_value)
This encoding method describes how the list of CSRC identifiers can This encoding method describes how the list of CSRC identifiers can
be compressed using list compression. This list compression operates be compressed using list compression. This list compression operates
by establishing content for the different CSRC identifiers (items) by establishing content for the different CSRC identifiers (items)
and list describing the order that they appear. and list describing the order that they appear.
The argument to this encoding method (cc_value) is the CC field from The argument to this encoding method (cc_value) is the CC field from
the RTP header which the compressor passes to this encoding method. the RTP header which the compressor passes to this encoding method.
The decompressor is reuired to bind the value of this argument to the The decompressor is required to bind the value of this argument to
number of items in the list, which will allow the decompressor to the number of items in the list, which will allow the decompressor to
corectly reconstruct the CC field. corectly reconstruct the CC field.
6.5.12.1. List Compression 6.6.13.1. List Compression
The CSRC identifiers in the uncompressed packet can be represented as The CSRC identifiers in the uncompressed packet can be represented as
an ordered list, whose order and presence are usually constant an ordered list, whose order and presence are usually constant
between packets. The generic structure of such a list is as follows: between packets. The generic structure of such a list is as follows:
+--------+--------+--...--+--------+ +--------+--------+--...--+--------+
list: | item 1 | item 2 | | item n | list: | item 1 | item 2 | | item n |
+--------+--------+--...--+--------+ +--------+--------+--...--+--------+
When performing list compression on a CSRC list, each item is the When performing list compression on a CSRC list, each item is the
skipping to change at page 28, line 22 skipping to change at page 29, line 35
Then, once the context has been initialized: Then, once the context has been initialized:
2) When the structure of the list is unchanged no information 2) When the structure of the list is unchanged no information
about the list is sent in compressed headers. about the list is sent in compressed headers.
3) When the structure of the list changes, a compressed list is 3) When the structure of the list changes, a compressed list is
sent in the compressed header, including a representation of its sent in the compressed header, including a representation of its
structure and order. Previously unknown items are sent structure and order. Previously unknown items are sent
uncompressed in the list, while previously known items are only uncompressed in the list, while previously known items are only
represented by an index pointing to the context. represented by an index pointing to the context.
6.5.12.2. Table-based Item Compression 6.6.13.2. Table-based Item Compression
The Table-based item compression compresses individual items sent in The Table-based item compression compresses individual items sent in
compressed lists. The compressor assigns a unique identifier, compressed lists. The compressor assigns a unique identifier,
"Index", to each item "Item" of a list. "Index", to each item "Item" of a list.
Compressor Logic Compressor Logic
The compressor conceptually maintains an Item Table containing all The compressor conceptually maintains an Item Table containing all
items, indexed using "Index". The (Index, Item) pair is sent items, indexed using "Index". The (Index, Item) pair is sent
together in compressed lists until the compressor gains enough together in compressed lists until the compressor gains enough
skipping to change at page 29, line 9 skipping to change at page 30, line 21
contains all (Index, Item) pairs received. The Item Table is contains all (Index, Item) pairs received. The Item Table is
updated whenever an (Index, Item) pair is received and updated whenever an (Index, Item) pair is received and
decompression is successfully verified using the CRC. The decompression is successfully verified using the CRC. The
decompressor retrieves the item from the table whenever an Index decompressor retrieves the item from the table whenever an Index
without an accompanying Item is received. without an accompanying Item is received.
If an index without an accompanying item is received and the If an index without an accompanying item is received and the
decompressor does not have any context for this index, the packet decompressor does not have any context for this index, the packet
MUST NOT be delivered to upper layers. MUST NOT be delivered to upper layers.
6.5.12.3. Encoding of Compressed Lists 6.6.13.3. Encoding of Compressed Lists
Each item present in a compressed list is represented by: Each item present in a compressed list is represented by:
o an index into the table of items, and o an index into the table of items, and
o a presence bit indicating if a compressed representation of the o a presence bit indicating if a compressed representation of the
item is present in the list. item is present in the list.
o an item (if the presence bit is set) o an item (if the presence bit is set)
If the presence bit is not set, the item must already be known by the If the presence bit is not set, the item must already be known by the
decompressor. decompressor.
skipping to change at page 30, line 25 skipping to change at page 31, line 36
X: Indicates whether the item present in the list: X: Indicates whether the item present in the list:
X = 1 indicates that the item corresponding to the Index is X = 1 indicates that the item corresponding to the Index is
sent in the item_1, ..., item_n list; sent in the item_1, ..., item_n list;
X = 0 indicates that the item corresponding to the Index is X = 0 indicates that the item corresponding to the Index is
not sent. not sent.
Reserved: Set to zero when sending, ignored when received. Reserved: Set to zero when sending, ignored when received.
Index: An index into the item table. See Section 6.5.12.4 Index: An index into the item table. See Section 6.6.13.4
When 4-bit XI items are used and, the XI items are placed in When 4-bit XI items are used and, the XI items are placed in
octets in the following manner: octets in the following manner:
0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
+---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
| XI_k | XI_k + 1 | | XI_k | XI_k + 1 |
+---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
Padding: A 4-bit padding field is present when PS = 0 and the Padding: A 4-bit padding field is present when PS = 0 and the
number of XIs is odd. The Padding field is set to zero when number of XIs is odd. The Padding field is set to zero when
sending and ignored when receiving. sending and ignored when receiving.
Item 1, ..., item n: Each item corresponds to an XI with X = 1 in Item 1, ..., item n: Each item corresponds to an XI with X = 1 in
XI 1, ..., XI m. Each entry in the item list is the uncompressed XI 1, ..., XI m. Each entry in the item list is the uncompressed
representation of one CSRC identifier. representation of one CSRC identifier.
6.5.12.4. Item Table Mappings 6.6.13.4. Item Table Mappings
The item table for list compression is limited to 16 different items, The item table for list compression is limited to 16 different items,
since the RTP header can only carry at most 15 simultaneous CSRC since the RTP header can only carry at most 15 simultaneous CSRC
identifiers. The effect of having more than 16 items will only cause identifiers. The effect of having more than 16 items will only cause
a slight overhead to the compressor when items are swappen in/out of a slight overhead to the compressor when items are swappen in/out of
the item table. the item table.
6.5.12.5. Compressed Lists in Dynamic Chain 6.6.13.5. Compressed Lists in Dynamic Chain
A compressed list that is part of the dynamic chain (e.g. in IR or A compressed list that is part of the dynamic chain (e.g. in IR
IR-DYN packets) must have all its list items present, i.e. all X-bits packets) must have all its list items present, i.e. all X-bits in the
in the XI list MUST be set. XI list MUST be set. All items previously established in the item
table that are not present in the list decompressed from this packet
MUST also be retained in the decompressor context.
6.6. Packet Formats 6.7. Encoding Methods With External Parameters
A number of encoding methods in Section 6.8.3.2 have one or more
arguments for which the derivation of the parameter's value is
outside the scope of the ROHC-FN specification of the header formats.
This section lists the encoding methods together with a definition of
each of their parameters.
o ip_dest_opt(repair_flag):
repair_flag: This parameter must be set to the value that was
used for the corresponding "repair_flag" parameter of the
"[profilename]_baseheader" encoding method when extracting the
irregular chain for a compressed header; otherwise it is set to
zero and ignored for other types of chains.
o ip_hop_opt(repair_flag):
See definition of arguments for "ip_dest_opt" above.
o gre(repair_flag):
See definition of arguments for "ip_dest_opt" above.
o ah(repair_flag):
See definition of arguments for "ip_dest_opt" above.
o esp_null(next_header_value, repair_flag):
next_header_value: Set to the value of the Next Header field
located in the ESP trailer, usually 12 octets from the end of
the packet. Compression of null-encrypted ESP headers should
only be performed when the compressor has prior knowledge of
the exact location of the next header field.
repair_flag: This parameter must be set to the value that was
used for the corresponding "repair_flag" parameter of the
"[profilename]_baseheader" encoding method when extracting the
irregular chain for a compressed header; otherwise it is set to
zero and ignored for other types of chains.
o ipv6(profile, is_innermost, ip_outer_flag, repair_flag)):
profile: Set to the profile number of the profile used to
compress this packet.
is_innermost: This boolean flag is set to 1 when processing the
innermost IP header; otherwise it is set to 0.
repair_flag: This parameter must be set to the value that was
used for the corresponding "repair_flag" parameter of the
"[profilename]_baseheader" encoding method when extracting the
irregular chain for a compressed header; otherwise it is set to
zero and ignored for other types of chains.
o ipv4(profile, is_innermost, ip_outer_flag, repair_flag)
See definition of arguments for "ipv6" above.
o udp(profile)
profile: Set to the profile number of the profile used to
compress this packet.
o rtp(profile, ts_stride_value, time_stride_value)
profile: Set to the profile number of the profile used to
compress this packet.
ts_stride_value: This parameter is set to a user-selected value
that is the expected increase in the RTP Timestamp between
consecutive sequence numbers. See also Section 6.6.8.
time_stride_value: This parameter is set to a user-selected
value that is the expected inter-arrival time between
consecutive packets for this flow. See also Section 6.6.9.
o esp(profile)
profile: Set to the profile number of the profile used to
compress this packet.
o udp_lite(profile)
profile: Set to the profile number of the profile used to
compress this packet.
o rtp_baseheader(profile, ts_stride_value, time_stride_value,
outer_ip_flag, repair_flag):
profile: Set to the profile number of the profile used to
compress this packet.
ts_stride_value: This parameter is set to a user-selected value
that is the expected increase in the RTP Timestamp between
consecutive sequence numbers. See also Section 6.6.8.
time_stride_value: This parameter is set to a user-selected
value that is the expected inter-arrival time between
consecutive packets for this flow. See also Section 6.6.9.
outer_ip_flag: This parameter is set to 1 of one or more of a a
number of semi-static fields in outer IP headers have changed
compared to their reference values in the context, otherwise it
is set to 0. The value used for this parameter is also used
for the "outer_ip_flag" argument for a number of encoding
methods defined above, when these are processing the irregular
chain. This flag may only be set to 1 either for the
"co_common" or the "co_repair" packet formats in the different
profiles.
repair_flag: This parameter is set to 1 if the certain fields
in extension headers or outer IP headers have changed compared
to their reference values in the context, otherwise it is set
to 0. The value used for this parameter is also used for the
"repair_flag" argument for a number of encoding methods defined
above, when these are processing the irregular chain. This may
only be set to 1 for the "co_repair" packet formats in the
different profiles.
o udp_baseheader(profile, outer_ip_flag, repair_flag):
profile: Set to the profile number of the profile used to
compress this packet.
outer_ip_flag: This parameter is set to 1 of one or more of a a
number of semi-static fields in outer IP headers have changed
compared to their reference values in the context, otherwise it
is set to 0. The value used for this parameter is also used
for the "outer_ip_flag" argument for a number of encoding
methods defined above, when these are processing the irregular
chain. This flag may only be set to 1 either for the
"co_common" or the "co_repair" packet formats in the different
profiles.
repair_flag: This parameter is set to 1 if the certain fields
in extension headers or outer IP headers have changed compared
to their reference values in the context, otherwise it is set
to 0. The value used for this parameter is also used for the
"repair_flag" argument for a number of encoding methods defined
above, when these are processing the irregular chain. This may
only be set to 1 for the "co_repair" packet formats in the
different profiles.
o esp_baseheader(profile, outer_ip_flag, repair_flag):
See definition of arguments for "udp_baseheader" above.
o iponly_baseheader(profile, outer_ip_flag, repair_flag):
See definition of arguments for "udp_baseheader" above.
o udplite_rtp_baseheader(profile, ts_stride_value,
time_stride_value, outer_ip_flag, repair_flag):
See definition of arguments for "rtp_baseheader" above.
o udplite_baseheader(profile, outer_ip_flag, repair_flag):
See definition of arguments for "udp_baseheader" above.
6.8. Packet Formats
ROHCv2 profiles use two different packet types: the Initialization ROHCv2 profiles use two different packet types: the Initialization
and Refresh (IR) packet type, and the Compressed packet type (CO). and Refresh (IR) packet type, and the Compressed packet type (CO).
Each packet type defines a number of packet formats: two packet Each packet type defines a number of packet formats: two packet
formats are defined for the IR type, and two sets base header formats formats are defined for the IR type, and two sets base header formats
are defined for the CO type with one additional format that is common are defined for the CO type with one additional format that is common
to both sets. to both sets.
When the number of bits available in compressed header fields exceeds When the number of bits available in compressed header fields exceeds
the number of bits in the value, the most significant field is padded the number of bits in the value, the most significant field is padded
with zeroes in its most significant bits. with zeroes in its most significant bits.
Updating Properties: all packet types carry a CRC and are context Updating Properties: all packet types carry a CRC and are context
updating. Packets update the entire context besides the fields for updating. Packets update the entire context besides the fields for
which they explicitly convey information for, since the context can which they explicitly convey information for, since the context can
be expressed as the collection of the reference value of each field be expressed as the collection of the reference value of each field
together with the function established with respect to the MSN. together with the function established with respect to the MSN.
6.6.1. Initialization and Refresh Packet (IR) 6.8.1. Initialization and Refresh Packet (IR)
The IR packet format uses the structure of the ROHC IR packet as The IR packet format uses the structure of the ROHC IR packet as
defined in [I-D.ietf-rohc-rfc3095bis-framework], section 5.2.2.1. defined in [I-D.ietf-rohc-rfc3095bis-framework], section 5.2.2.1.
Packet type: IR Packet type: IR
This packet type communicates the static part and the dynamic part This packet type communicates the static part and the dynamic part
of the context. of the context.
The ROHCv2 IR packet has the following format: The ROHCv2 IR packet has the following format:
skipping to change at page 32, line 34 skipping to change at page 37, line 34
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| | | |
/ Dynamic chain / variable length / Dynamic chain / variable length
| | | |
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| | | |
/ Payload / variable length / Payload / variable length
| | | |
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Static chain: See Section 6.4. Static chain: See Section 6.5.
Dynamic chain: See Section 6.4. Dynamic chain: See Section 6.5.
Payload: The payload of the corresponding original packet, if any. Payload: The payload of the corresponding original packet, if any.
The presence of a payload is inferred from the packet length. The presence of a payload is inferred from the packet length.
6.6.2. IR Packet Payload Discard (IR-PD) 6.8.2. IR Packet Payload Discard (IR-PD)
The IR-PD packet format uses the structure of the ROHC IR packet as The IR-PD packet format uses the structure of the ROHC IR packet as
defined in [I-D.ietf-rohc-rfc3095bis-framework], section 5.2.2.1. defined in [I-D.ietf-rohc-rfc3095bis-framework], section 5.2.2.1.
Packet type: IR-PD Packet type: IR-PD
This packet type communicates the static part and the dynamic part This packet type communicates the static part and the dynamic part
of the context, but without the payload of the original packet for of the context, but without the payload of the original packet for
which it carries the header information. which it carries the header information.
The ROHCv2 IR packet has the following format: The ROHCv2 IR packet has the following format:
skipping to change at page 33, line 33 skipping to change at page 38, line 33
+---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
| | | |
/ Static chain / variable length / Static chain / variable length
| | | |
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| | | |
/ Dynamic chain / variable length / Dynamic chain / variable length
| | | |
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Static chain: See Section 6.4. Static chain: See Section 6.5.
Dynamic chain: See Section 6.4.
6.6.3. IR Dynamic Packet (IR-DYN)
The IR-DYN packet format uses the structure of the ROHC IR-DYN packet
as defined in [I-D.ietf-rohc-rfc3095bis-framework], section 5.2.2.2.
Packet type: IR-DYN
This packet type communicates the dynamic chains of the header(s)
that it compresses.
The RoHCv2 IR-DYN packet has the following format:
0 1 2 3 4 5 6 7
--- --- --- --- --- --- --- ---
: Add-CID octet : if for small CIDs and (CID != 0)
+---+---+---+---+---+---+---+---+
| 1 1 1 1 1 0 0 0 | IR-DYN type octet
+---+---+---+---+---+---+---+---+
: :
/ 0-2 octets of CID / 1-2 octets if for large CIDs
: :
+---+---+---+---+---+---+---+---+
| Profile | 1 octet
+---+---+---+---+---+---+---+---+
| CRC | 1 octet
+---+---+---+---+---+---+---+---+
| |
/ Dynamic chain / variable length
| |
- - - - - - - - - - - - - - - -
| |
/ Payload / variable length
| |
- - - - - - - - - - - - - - - -
Dynamic chain: See Section 6.4.
Payload: The payload of the corresponding original packet, if any. Dynamic chain: See Section 6.5.
The presence of a payload is inferred from the packet length.
6.6.4. Compressed Packet Formats (CO) 6.8.3. Compressed Packet Formats (CO)
6.6.4.1. Design rationale for compressed base headers 6.8.3.1. Design rationale for compressed base headers
The compressed packet formats are defined as two separate sets for The compressed packet formats are defined as two separate sets for
each profile: one set for the packets where the innermost IP header each profile: one set for the packets where the innermost IP header
contains a sequential IP-ID (either network byte order or byte contains a sequential IP-ID (either network byte order or byte
swapped), and one set for the packets without sequential IP-ID swapped), and one set for the packets without sequential IP-ID
(either random, zero, or no IP-ID). (either random, zero, or no IP-ID).
The design of the packet formats is derived from the field behavior The design of the packet formats is derived from the field behavior
analysis found in Appendix A. analysis found in Appendix A.
All of the compressed base headers transmit LSB-encoded MSN bits and All of the compressed base headers transmit LSB-encoded MSN bits and
a CRC. In addition, each base header in the sequential packet format a CRC.
set contains LSB encoded IP-ID bits.
The following packet formats exist in both the sequential and random The following packet formats exist for all profiles defined in this
packet format sets: document, both for the sequential and random packet format sets:
o Format 1: This packet format transmits changes [Author's note: o co_common: The common packet format is designed so that it can be
TBW] used for chagnes to all the dynamic fields in the context, but can
not always transmit all these fields uncompressed can be used. It
is therefore useful for when some of the more rarely changing
fields in the headers change. Since this packet format may modify
the value of the control fields that determine how the
decompressor interprets different compressed header format, it
carries a 7-bit CRC to reduce the probability of context
corruption. This packet format uses a large set of flags to
provide information about which fields are present in the packet
format and can therefore be of very varied size.
o Format 2: This packet format transmits changes [Author's note: o co_repair: This format is very similar to the co_common format
TBW] described above. The difference is that this packet is intended
to be used when context damage has been assumed, and therefore
changing fields are transmit uncompressed when present in this
format. This format also contains some options to transmit semi-
static fields from extension headers which cannot be transmit with
the co_common format. This packet format should be considered a
replacement for the IR-DYN packet format which is not defined for
the profiles defined in this document.
o Common packet format: The common packet format can be used o pt_0_crc3: This packet format only transmit the MSN, and can
indenpendently of the type of IP-ID behavior. It should also be therefore only be used to update the MSN and fields that are
useful when some of the more rarely changing fields in the IP derived from the MSN, such as IP-ID and the RTP Timestamp (where
header changes. Since this packet format modify the value of the applicable). This packet format is equivalent to the UO-0 packet
control fields that determine how the decompressor interprets format in [RFC3095]
different compressed header format, it carries a 7-bit CRC to
reduce the probability of context corruption. This packet can
change most of the dynamic fields in the IP header, and it uses a
large set of flags to provide information about which fields are
present in the packet format.
6.6.4.2. General CO Header Format o pt_0_crc7: This packet has the same properties as pt_0_crc3, but
is instead protected by a 7-bit CRC and contains a larger amount
of LSB-encoded MSN bits. This format is intended to be used for
the compressor to transmit from IC state to FC state (see
Section 5.3.1 or it can be used on ROHC channels that expect a
high amount of reordering.
The following packet formats exist exclusively for profiles 0x101 and
0x107.
o pt_1_rnd: This format is a replacement for the UO-1 packet format
in [RFC3095] and can be used to transmit changes in the MSN, RTP
Marker bit and it can update the RTP timestamp using scaled
timestamp encoding.
o pt_1_seq_id: This format is a replacement for the UO-1-ID packet
format in [RFC3095] and can be used to transmit changes in the MSN
and IP-ID.
o pt_1_seq_ts: This format is a replacement for the UO-1-TS packet
format in [RFC3095] and can be used to transmit changes in the
MSN, RTP Marker bit and can update the RTP Timestamp using scaled
timestamp encoding.
o pt_2_rnd: This format is a replacement for the UOR-2 packet format
in [RFC3095] and can be used to transmit changes in the MSN, RTP
Marker bit and the RTP Timestamp, and is protected by a 7-bit CRC.
o pt_2_seq_id: This format is a replacement for the UO-2-ID packet
format in [RFC3095] and can be used to transmit changes in the MSN
and IP-ID. This format is also protected by a 7-bit CRC.
o pt_2_seq_ts: This format is a replacement for the UO-2-TS packet
format in [RFC3095] and can be used to transmit changes in the
MSN, RTP Marker bit and can update the RTP Timestamp using scaled
timestamp encoding. This format is also protected by a 7-bit CRC.
o pt_2_seq_both: This format is replaces the UOR-2-ID extension 1
format in [RFC3095] and can carry changes in both the RTP
Timestamp and IP-ID in addition to the MSN and Marker bit.
The following packet formats exist exclusively for profiles 0x102,
0x103, 0x104 and 0x108.
o pt_1_seq_id: This format is a replacement for the UO-1-ID packet
format in [RFC3095] and can be used to transmit changes in the MSN
and IP-ID.
o pt_2_rnd: This format is a replacement for the UOR-2 packet format
in [RFC3095] and can be used to transmit changes in the MSN and is
protected by a 7-bit CRC.
o pt_2_seq_id: This format is a replacement for the UO-2-ID packet
format in [RFC3095] and can be used to transmit changes in the MSN
and IP-ID. This format is also protected by a 7-bit CRC.
6.8.3.2. General CO Header Format
The CO packets communicate irregularities in the packet header. All The CO packets communicate irregularities in the packet header. All
CO packets carry a CRC and can update the context. CO packets carry a CRC and can update the context.
The general format for a compressed header is as follows: The general format for a compressed header is as follows:
0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
--- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
: Add-CID octet : if for small CIDs and CID 1-15 : Add-CID octet : if for small CIDs and CID 1-15
+---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
| first octet of base header | (with type indication) | first octet of base header | (with type indication)
skipping to change at page 36, line 9 skipping to change at page 41, line 34
of the innermost IP header and other header(s), if any, in the of the innermost IP header and other header(s), if any, in the
uncompressed packet. uncompressed packet.
Upon receiving other types of packet, the decompressor will Upon receiving other types of packet, the decompressor will
decompress it. The decompressor MUST verify the correctness of the decompress it. The decompressor MUST verify the correctness of the
decompressed packet by CRC check. If this verification succeeds, the decompressed packet by CRC check. If this verification succeeds, the
decompressor passes the decompressed packet to the system's network decompressor passes the decompressed packet to the system's network
layer. The decompressor will then use this packet as the reference layer. The decompressor will then use this packet as the reference
packet. packet.
The entire set of base headers are described in the remainder of this The entire set of base headers are defined using the ROHC Formal
notation [I-D.ietf-rohc-formal-notation] in the remainder of this
section. section.
// TODO:
// - PT_0/PT_1 packets? Use "tbc-optimized" or "msn-optimized"
//////////////////////////////////////////// ////////////////////////////////////////////
// Constants // Constants
//////////////////////////////////////////// ////////////////////////////////////////////
// IP-ID behavior constants // IP-ID behavior constants
IP_ID_BEHAVIOR_SEQUENTIAL = 0; IP_ID_BEHAVIOR_SEQUENTIAL = 0;
IP_ID_BEHAVIOR_SEQUENTIAL_SWAPPED = 1; IP_ID_BEHAVIOR_SEQUENTIAL_SWAPPED = 1;
IP_ID_BEHAVIOR_RANDOM = 2; IP_ID_BEHAVIOR_RANDOM = 2;
IP_ID_BEHAVIOR_ZERO = 3; IP_ID_BEHAVIOR_ZERO = 3;
skipping to change at page 36, line 35 skipping to change at page 42, line 17
UDP_LITE_COVERAGE_IRREGULAR = 2; UDP_LITE_COVERAGE_IRREGULAR = 2;
UDP_LITE_COVERAGE_RESERVED = 3; UDP_LITE_COVERAGE_RESERVED = 3;
// Variable reordering offset // Variable reordering offset
REORDERING_NONE = 0; REORDERING_NONE = 0;
REORDERING_QUARTER = 1; REORDERING_QUARTER = 1;
REORDERING_HALF = 2; REORDERING_HALF = 2;
REORDERING_THREEQUARTERS = 3; REORDERING_THREEQUARTERS = 3;
// Profile names and versions // Profile names and versions
PROFILE_RTP_0101 = 1; PROFILE_RTP_0101 = 0x0101;
PROFILE_UDP_0102 = 2; PROFILE_UDP_0102 = 0x0102;
PROFILE_ESP_0103 = 3; PROFILE_ESP_0103 = 0x0103;
PROFILE_IP_0104 = 4; PROFILE_IP_0104 = 0x0104;
PROFILE_RTP_0107 = 7; // With UDP-LITE PROFILE_RTP_0107 = 0x0107; // With UDP-LITE
PROFILE_UDPLITE_0108 = 8; // Without RTP PROFILE_UDPLITE_0108 = 0x0108; // Without RTP
//////////////////////////////////////////// ////////////////////////////////////////////
// Global control fields // Global control fields
//////////////////////////////////////////// ////////////////////////////////////////////
CONTROL { CONTROL {
msn [ 16 ]; msn [ 16 ];
reorder_ratio [ 2 ]; reorder_ratio [ 2 ];
} }
skipping to change at page 37, line 17 skipping to change at page 42, line 47
baseheader_extension_headers "defined in Section X.Y.Z"; baseheader_extension_headers "defined in Section X.Y.Z";
baseheader_outer_headers "defined in Section X.Y.Z"; baseheader_outer_headers "defined in Section X.Y.Z";
inferred_udp_length "defined in Section X.Y.Z"; inferred_udp_length "defined in Section X.Y.Z";
inferred_ip_v4_header_checksum "defined in Section X.Y.Z"; inferred_ip_v4_header_checksum "defined in Section X.Y.Z";
inferred_mine_header_checksum "defined in Section X.Y.Z"; inferred_mine_header_checksum "defined in Section X.Y.Z";
inferred_ip_v4_length "defined in Section X.Y.Z"; inferred_ip_v4_length "defined in Section X.Y.Z";
inferred_ip_v6_length "defined in Section X.Y.Z"; inferred_ip_v6_length "defined in Section X.Y.Z";
list_csrc(cc_value) "defined in Section X.Y.Z"; list_csrc(cc_value) "defined in Section X.Y.Z";
inferred_scaled_field "defined in Section X.Y.Z"; inferred_scaled_field "defined in Section X.Y.Z";
inferred_sequential_ip_id "defined in Section X.Y.Z"; inferred_sequential_ip_id "defined in Section X.Y.Z";
control_crc3 "defined in Section X.Y.Z"; control_crc3_encoding "defined in Section X.Y.Z";
timer_based_lsb(time_stride, k, p) "defined in Section X.Y.Z";
//////////////////////////////////////////// ////////////////////////////////////////////
// General encoding methods // General encoding methods
//////////////////////////////////////////// ////////////////////////////////////////////
reorder_ratio_choice reorder_choice
{ {
UNCOMPRESSED { UNCOMPRESSED {
ratio [ 2 ]; ratio [ 2 ];
} }
DEFAULT { DEFAULT {
ratio =:= irregular(2); ratio =:= irregular(2);
} }
COMPRESSED none { COMPRESSED none {
ratio [ 2 ];
ENFORCE(ratio.UVALUE == REORDERING_NONE); ENFORCE(ratio.UVALUE == REORDERING_NONE);
ratio [ 2 ];
} }
COMPRESSED quarter { COMPRESSED quarter {
ratio [ 2 ];
ENFORCE(ratio.UVALUE == REORDERING_QUARTER); ENFORCE(ratio.UVALUE == REORDERING_QUARTER);
ratio [ 2 ];
} }
COMPRESSED half { COMPRESSED half {
ratio [ 2 ];
ENFORCE(ratio.UVALUE == REORDERING_HALF); ENFORCE(ratio.UVALUE == REORDERING_HALF);
ratio [ 2 ];
} }
COMPRESSED three_quarters { COMPRESSED three_quarters {
ratio [ 2 ];
ENFORCE(ratio.UVALUE == REORDERING_THREEQUARTERS); ENFORCE(ratio.UVALUE == REORDERING_THREEQUARTERS);
ratio [ 2 ];
} }
} }
static_or_irreg(flag, width) static_or_irreg(flag, width)
{ {
UNCOMPRESSED { UNCOMPRESSED {
field [ width ]; field [ width ];
} }
COMPRESSED irreg_enc { COMPRESSED irreg_enc {
field =:= irregular(width) [ width ];
ENFORCE(flag == 1); ENFORCE(flag == 1);
field =:= irregular(width) [ width ];
} }
COMPRESSED static_enc { COMPRESSED static_enc {
field =:= static [ 0 ];
ENFORCE(flag == 0); ENFORCE(flag == 0);
field =:= static [ 0 ];
} }
} }
optional32(flag) optional_32(flag)
{ {
UNCOMPRESSED { UNCOMPRESSED {
item [ 0, 32 ]; item [ 0, 32 ];
} }
COMPRESSED present { COMPRESSED present {
item =:= irregular(32) [ 32 ];
ENFORCE(flag == 1); ENFORCE(flag == 1);
item =:= irregular(32) [ 32 ];
} }
COMPRESSED not_present { COMPRESSED not_present {
item =:= compressed_value(0, 0) [ 0 ];
ENFORCE(flag == 0); ENFORCE(flag == 0);
item =:= compressed_value(0, 0) [ 0 ];
} }
} }
// Self-describing variable length encoding sdvl_or_static(flag)
sdvl(field_width)
{ {
UNCOMPRESSED { UNCOMPRESSED {
field [ field_width ]; field [ 32 ];
} }
COMPRESSED lsb7 { COMPRESSED present_7bit {
ENFORCE(flag == 1);
ENFORCE(field.UVALUE < 2^7);
ENFORCE(field.CVALUE == field.UVALUE);
discriminator =:= '0' [ 1 ]; discriminator =:= '0' [ 1 ];
field =:= lsb(7, 63) [ 7 ]; field [ 7 ];
}
COMPRESSED lsb14 {
discriminator =:= '10' [ 2 ];
field =:= lsb(14, 16383) [ 14 ];
} }
COMPRESSED lsb21 { COMPRESSED present_14bit {
discriminator =:= '110' [ 3 ]; ENFORCE(flag == 1);
field =:= lsb(21, 65535) [ 21 ]; ENFORCE(field.UVALUE < 2^14);
ENFORCE(field.CVALUE == field.UVALUE);
discriminator =:= '10' [ 2 ];
field [ 14 ];
} }
COMPRESSED lsb29 { COMPRESSED present_21bit {
ENFORCE(flag == 1);
ENFORCE(field.UVALUE < 2^21);
ENFORCE(field.CVALUE == field.UVALUE);
discriminator =:= '110' [ 3 ]; discriminator =:= '110' [ 3 ];
field =:= lsb(29, 65535) [ 29 ]; field [ 21 ];
}
} }
optional_stride(flag, value) COMPRESSED present_28bit {
{ ENFORCE(flag == 1);
UNCOMPRESSED { ENFORCE(field.UVALUE < 2^28);
field [ 32 ]; ENFORCE(field.CVALUE == field.UVALUE);
discriminator =:= '1110' [ 4 ];
field [ 28 ];
} }
COMPRESSED present { COMPRESSED present_32bit {
field =:= sdvl(32);
ENFORCE(flag == 1); ENFORCE(flag == 1);
ENFORCE(field.CVALUE == field.UVALUE);
discriminator =:= '11111111' [ 8 ];
field [ 32 ];
} }
COMPRESSED not_present { COMPRESSED not_present {
field =:= static;
ENFORCE(flag == 0); ENFORCE(flag == 0);
} field =:= static;
}
optional_scaled_timestamp(tss_flag, tsc_flag)
{
UNCOMPRESSED {
timestamp [ 32 ];
}
COMPRESSED present {
timestamp =:= sdvl(32);
ENFORCE((tss_flag == 0) && (tsc_flag == 1));
}
COMPRESSED not_present {
ENFORCE(((tss_flag == 1) && (tsc_flag == 0)) ||
((tss_flag == 0) && (tsc_flag == 0)));
}
}
optional_unscaled_timestamp(tss_flag, tsc_flag)
{
UNCOMPRESSED {
timestamp [ 32 ];
}
COMPRESSED present {
timestamp =:= sdvl(32);
ENFORCE(((tss_flag == 1) && (tsc_flag == 0)) ||
((tss_flag == 0) && (tsc_flag == 0)));
}
COMPRESSED not_present {
ENFORCE((tss_flag == 0) && (tsc_flag == 1));
} }
} }
lsb_7_or_31 lsb_7_or_31
{ {
UNCOMPRESSED { UNCOMPRESSED {
item [ 32 ]; item [ 32 ];
} }
COMPRESSED lsb_7 { COMPRESSED lsb_7 {
discriminator =:= '0' [ 1 ]; discriminator =:= '0' [ 1 ];
item =:= lsb(7, 8) [ 7 ]; item =:= lsb(7, ((2^7) / 4) - 1) [ 7 ];
} }
COMPRESSED lsb_31 { COMPRESSED lsb_31 {
discriminator =:= '1' [ 1 ]; discriminator =:= '1' [ 1 ];
item =:= lsb(31, 256) [ 31 ]; item =:= lsb(31, ((2^31) / 4) - 1) [ 31 ];
}
}
opt_lsb_7_or_31(flag)
{
UNCOMPRESSED {
item [ 0, 32 ];
}
COMPRESSED present {
item =:= lsb_7_or_31 [ 8, 32 ];
ENFORCE(flag == 1);
}
COMPRESSED not_present {
item =:= compressed_value(0, 0) [ 0 ];
ENFORCE(flag == 0);
} }
} }
crc3(data_value, data_length) crc3(data_value, data_length)
{ {
UNCOMPRESSED { UNCOMPRESSED {
} }
COMPRESSED { COMPRESSED {
crc_value =:= crc_value =:= crc(3, 0x06, 0x07, data_value, data_length) [ 3 ];
crc(3, 0x06, 0x07, data_value, data_length) [ 3 ];
} }
} }
crc7(data_value, data_length) crc7(data_value, data_length)
{
UNCOMPRESSED {
}
COMPRESSED {
crc_value =:=
crc(7, 0x79, 0x7f, data_value, data_length) [ 7 ];
}
}
optional_pt(flag)
{ {
UNCOMPRESSED { UNCOMPRESSED {
payload_type [ 7 ];
}
COMPRESSED not_present {
payload_type =:= static [ 0 ];
ENFORCE(flag == 0);
}
COMPRESSED present {
reserved =:= compressed_value(1, 0) [ 1 ];
payload_type =:= irregular(7) [ 7 ];
ENFORCE(flag == 1);
}
}
csrc_list_presence(presence, cc_value)
{
UNCOMPRESSED {
csrc_list;
}
COMPRESSED no_list {
csrc_list =:= static [ 0 ];
ENFORCE(presence == 0);
}
COMPRESSED list_present {
csrc_list =:= list_csrc(cc_value) [ VARIABLE ];
ENFORCE(presence == 1);
}
}
// Variable reordering offset used for MSN
msn_lsb(k)
{
UNCOMPRESSED {
master [ 16 ];
}
COMPRESSED none {
master =:= lsb(k, -1);
ENFORCE(reorder_ratio.UVALUE == REORDERING_NONE);
}
COMPRESSED quarter {
master =:= lsb(k, ((2^k) / 4) - 1);
ENFORCE(reorder_ratio.UVALUE == REORDERING_QUARTER);
} }
COMPRESSED half { COMPRESSED {
master =:= lsb(k, ((2^k) / 2) - 1); crc_value =:= crc(7, 0x79, 0x7f, data_value, data_length) [ 7 ];
ENFORCE(reorder_ratio.UVALUE == REORDERING_HALF);
}
COMPRESSED threequarters {
master =:= lsb(k, (((2^k) * 3) / 4) - 1);
ENFORCE(reorder_ratio.UVALUE == REORDERING_THREEQUARTERS);
} }
} }
// Encoding method for updating a scaled field and its associated // Encoding method for updating a scaled field and its associated
// control fields. Should be used both when the value is scaled // control fields. Should be used both when the value is scaled
// or unscaled in a compressed format. // or unscaled in a compressed format.
field_scaling(stride_value, scaled_value, unscaled_value) field_scaling(stride_value, scaled_value, unscaled_value)
{ {
UNCOMPRESSED { UNCOMPRESSED {
residue_field [ 32 ]; residue_field [ 32 ];
skipping to change at page 43, line 25 skipping to change at page 46, line 41
ENFORCE(residue_field.UVALUE == (unscaled_value % stride_value)); ENFORCE(residue_field.UVALUE == (unscaled_value % stride_value));
ENFORCE(unscaled_value == ENFORCE(unscaled_value ==
scaled_value * stride_value + residue_field.UVALUE); scaled_value * stride_value + residue_field.UVALUE);
} }
} }
//////////////////////////////////////////// ////////////////////////////////////////////
// IPv6 Destination options header // IPv6 Destination options header
//////////////////////////////////////////// ////////////////////////////////////////////
ip_dest_opt ip_dest_opt(repair_flag)
{ {
UNCOMPRESSED { UNCOMPRESSED {
next_header [ 8 ]; next_header [ 8 ];
length [ 8 ]; length [ 8 ];
value [ VARIABLE ]; value [ length.UVALUE * 64 + 48 ];
} }
DEFAULT { DEFAULT {
length =:= static; length =:= static;
next_header =:= static; next_header =:= static;
value =:= static; value =:= static;
} }
COMPRESSED dest_opt_static { COMPRESSED dest_opt_static {
next_header =:= irregular(8) [ 8 ]; next_header =:= irregular(8) [ 8 ];
length =:= irregular(8) [ 8 ]; length =:= irregular(8) [ 8 ];
} }
COMPRESSED dest_opt_dynamic { COMPRESSED dest_opt_dynamic {
value =:= irregular(length.UVALUE * 64 + 48) [ VARIABLE ]; value =:=
irregular(length.UVALUE * 64 + 48) [ length.UVALUE * 64 + 48 ];
}
COMPRESSED dest_opt_irregular {
ENFORCE(repair_flag == 0);
}
COMPRESSED dest_opt_repair_irregular {
ENFORCE(repair_flag == 1);
value =:=
irregular(length.UVALUE * 64 + 48) [ length.UVALUE * 64 + 48 ];
} }
} }
//////////////////////////////////////////// ////////////////////////////////////////////
// IPv6 Hop-by-Hop options header // IPv6 Hop-by-Hop options header
//////////////////////////////////////////// ////////////////////////////////////////////
ip_hop_opt
ip_hop_opt(repair_flag)
{ {
UNCOMPRESSED { UNCOMPRESSED {
next_header [ 8 ]; next_header [ 8 ];
length [ 8 ]; length [ 8 ];
value [ VARIABLE ]; value [ length.UVALUE * 64 + 48 ];
} }
DEFAULT { DEFAULT {
length =:= static; length =:= static;
next_header =:= static; next_header =:= static;
value =:= static; value =:= static;
} }
COMPRESSED hop_opt_static { COMPRESSED hop_opt_static {
next_header =:= irregular(8) [ 8 ]; next_header =:= irregular(8) [ 8 ];
length =:= irregular(8) [ 8 ]; length =:= irregular(8) [ 8 ];
} }
COMPRESSED hop_opt_dynamic { COMPRESSED hop_opt_dynamic {
value =:= irregular(length.UVALUE*64+48) [ VARIABLE ]; value =:=
irregular(length.UVALUE*64+48) [ length.UVALUE * 64 + 48 ];
}
COMPRESSED hop_opt_irregular {
ENFORCE(repair_flag == 0);
}
COMPRESSED hop_opt_repair_irregular {
ENFORCE(repair_flag == 1);
value =:=
irregular(length.UVALUE * 64 + 48) [ length.UVALUE * 64 + 48 ];
} }
} }
//////////////////////////////////////////// ////////////////////////////////////////////
// IPv6 Routing header // IPv6 Routing header
//////////////////////////////////////////// ////////////////////////////////////////////
ip_rout_opt ip_rout_opt
{ {
UNCOMPRESSED { UNCOMPRESSED {
next_header [ 8 ]; next_header [ 8 ];
length [ 8 ]; length [ 8 ];
value [ VARIABLE ]; value [ length.UVALUE * 64 + 48 ];
} }
DEFAULT { DEFAULT {
length =:= static; length =:= static;
next_header =:= static; next_header =:= static;
value =:= static; value =:= static;
} }
COMPRESSED rout_opt_static { COMPRESSED rout_opt_static {
next_header =:= irregular(8) [ 8 ]; next_header =:= irregular(8) [ 8 ];
length =:= irregular(8) [ 8 ]; length =:= irregular(8) [ 8 ];
value =:= irregular(length.UVALUE*64+48) [ VARIABLE ]; value =:=
irregular(length.UVALUE*64+48) [ length.UVALUE * 64 + 48 ];
} }
COMPRESSED rout_opt_dynamic { COMPRESSED rout_opt_dynamic {
} }
COMPRESSED rout_opt_irregular {
}
} }
//////////////////////////////////////////// ////////////////////////////////////////////
// GRE Header // GRE Header
//////////////////////////////////////////// ////////////////////////////////////////////
optional_lsb_7_or_31(flag)
{
UNCOMPRESSED {
item [ 0, 32 ];
}
COMPRESSED present {
ENFORCE(flag == 1);
item =:= lsb_7_or_31 [ 8, 32 ];
}
COMPRESSED not_present {
ENFORCE(flag == 0);
item =:= compressed_value(0, 0) [ 0 ];
}
}
optional_checksum(flag_value) optional_checksum(flag_value)
{ {
UNCOMPRESSED { UNCOMPRESSED {
value [ 0, 16 ]; value [ 0, 16 ];
reserved1 [ 0, 16 ]; reserved1 [ 0, 16 ];
} }
COMPRESSED cs_present { COMPRESSED cs_present {
ENFORCE(flag_value == 1);
value =:= irregular(16) [ 16 ]; value =:= irregular(16) [ 16 ];
reserved1 =:= uncompressed_value(16, 0) [ 0 ]; reserved1 =:= uncompressed_value(16, 0) [ 0 ];
ENFORCE(flag_value == 1);
} }
COMPRESSED not_present { COMPRESSED not_present {
ENFORCE(flag_value == 0);
value =:= compressed_value(0, 0) [ 0 ]; value =:= compressed_value(0, 0) [ 0 ];
reserved1 =:= compressed_value(0, 0) [ 0 ]; reserved1 =:= compressed_value(0, 0) [ 0 ];
ENFORCE(flag_value == 0);
} }
} }
gre_proto gre_proto
{ {
UNCOMPRESSED { UNCOMPRESSED {
protocol [ 16 ]; protocol [ 16 ];
} }
COMPRESSED ether_v4 { COMPRESSED ether_v4 {
discriminator =:= compressed_value(1, 0) [ 1 ]; discriminator =:= compressed_value(1, 0) [ 1 ];
protocol =:= uncompressed_value(16, 0x0800); protocol =:= uncompressed_value(16, 0x0800) [ 0 ];
} }
COMPRESSED ether_v6 { COMPRESSED ether_v6 {
discriminator =:= compressed_value(1, 1) [ 1 ]; discriminator =:= compressed_value(1, 1) [ 1 ];
protocol =:= uncompressed_value(16, 0x86DD); protocol =:= uncompressed_value(16, 0x86DD) [ 0 ];
} }
} }
gre gre(repair_flag)
{ {
UNCOMPRESSED { UNCOMPRESSED {
c_flag [ 1 ]; c_flag [ 1 ];
r_flag =:= uncompressed_value(1, 0) [ 1 ]; r_flag =:= uncompressed_value(1, 0) [ 1 ];
k_flag [ 1 ]; k_flag [ 1 ];
s_flag [ 1 ]; s_flag [ 1 ];
reserved0 =:= uncompressed_value(9, 0) [ 9 ]; reserved0 =:= uncompressed_value(9, 0) [ 9 ];
version =:= uncompressed_value(3, 0) [ 3 ]; version =:= uncompressed_value(3, 0) [ 3 ];
protocol [ 16 ]; protocol [ 16 ];
checksum_and_res [ 0, 32 ]; checksum_and_res [ 0, 32 ];
skipping to change at page 46, line 31 skipping to change at page 50, line 42
key =:= static; key =:= static;
sequence_number =:= static; sequence_number =:= static;
} }
COMPRESSED gre_static { COMPRESSED gre_static {
protocol =:= gre_proto [ 1 ]; protocol =:= gre_proto [ 1 ];
c_flag =:= irregular(1) [ 1 ]; c_flag =:= irregular(1) [ 1 ];
k_flag =:= irregular(1) [ 1 ]; k_flag =:= irregular(1) [ 1 ];
s_flag =:= irregular(1) [ 1 ]; s_flag =:= irregular(1) [ 1 ];
padding =:= compressed_value(4, 0) [ 4 ]; padding =:= compressed_value(4, 0) [ 4 ];
key =:= optional32(k_flag.UVALUE) [ 0, 32 ]; key =:= optional_32(k_flag.UVALUE) [ 0, 32 ];
} }
COMPRESSED gre_dynamic { COMPRESSED gre_dynamic {
checksum_and_res =:= checksum_and_res =:=
optional_checksum(c_flag.UVALUE) [ 0, 16 ]; optional_checksum(c_flag.UVALUE) [ 0, 16 ];
sequence_number =:= optional32(s_flag.UVALUE) [ 0, 32 ]; sequence_number =:= optional_32(s_flag.UVALUE) [ 0, 32 ];
} }
COMPRESSED gre_irregular { COMPRESSED gre_irregular {
checksum_and_res =:= ENFORCE(repair_flag == 0);
optional_checksum(c_flag.UVALUE) [ 0, 16 ]; checksum_and_res =:= optional_checksum(c_flag.UVALUE) [ 0, 16 ];
sequence_number =:= sequence_number =:=
opt_lsb_7_or_31(s_flag.UVALUE) [ 0, 8, 32 ]; optional_lsb_7_or_31(s_flag.UVALUE) [ 0, 8, 32 ];
}
COMPRESSED gre_repair_irregular {
ENFORCE(repair_flag == 1);
checksum_and_res =:= optional_checksum(c_flag.UVALUE) [ 0, 16 ];
sequence_number =:= optional_32(s_flag.UVALUE) [ 0, 32 ];
} }
} }
///////////////////////////////////////////// /////////////////////////////////////////////
// MINE header // MINE header
///////////////////////////////////////////// /////////////////////////////////////////////
mine mine
{ {
UNCOMPRESSED { UNCOMPRESSED {
next_header [ 8 ]; next_header [ 8 ];
s_bit [ 1 ]; s_bit [ 1 ];
res_bits [ 7 ]; res_bits [ 7 ];
checksum [ 16 ]; checksum [ 16 ];
orig_dest [ 32 ]; orig_dest [ 32 ];
orig_src [ 0, 32 ]; orig_src [ 0, 32 ];
} }
skipping to change at page 47, line 27 skipping to change at page 51, line 44
s_bit =:= static; s_bit =:= static;
res_bits =:= static; res_bits =:= static;
checksum =:= inferred_mine_header_checksum; checksum =:= inferred_mine_header_checksum;
orig_dest =:= static; orig_dest =:= static;
orig_src =:= static; orig_src =:= static;
} }
COMPRESSED mine_static { COMPRESSED mine_static {
next_header =:= irregular(8) [ 8 ]; next_header =:= irregular(8) [ 8 ];
s_bit =:= irregular(1) [ 1 ]; s_bit =:= irregular(1) [ 1 ];
// Reserved are included - no benefit in removing them // Reserved bits are included to achieve byte-alignment
res_bits =:= irregular(7) [ 7 ]; res_bits =:= irregular(7) [ 7 ];
orig_dest =:= irregular(32) [ 32 ]; orig_dest =:= irregular(32) [ 32 ];
orig_src =:= optional32(s_bit.UVALUE) [ 0, 32 ]; orig_src =:= optional_32(s_bit.UVALUE) [ 0, 32 ];
} }
COMPRESSED mine_dynamic { COMPRESSED mine_dynamic {
} }
COMPRESSED mine_irregular {
}
} }
///////////////////////////////////////////// /////////////////////////////////////////////
// Authentication Header (AH) // Authentication Header (AH)
///////////////////////////////////////////// /////////////////////////////////////////////
ah ah(repair_flag)
{ {
UNCOMPRESSED { UNCOMPRESSED {
next_header [ 8 ]; next_header [ 8 ];
length [ 8 ]; length [ 8 ];
res_bits [ 16 ]; res_bits [ 16 ];
spi [ 32 ]; spi [ 32 ];
sequence_number [ 32 ]; sequence_number [ 32 ];
auth_data [ VARIABLE ]; auth_data [ length.UVALUE*32-32 ];
} }
DEFAULT { DEFAULT {
next_header =:= static; next_header =:= static;
length =:= static; length =:= static;
res_bits =:= static; res_bits =:= static;
spi =:= static; spi =:= static;
sequence_number =:= static; sequence_number =:= static;
} }
COMPRESSED ah_static { COMPRESSED ah_static {
next_header =:= irregular(8) [ 8 ]; next_header =:= irregular(8) [ 8 ];
skipping to change at page 48, line 19 skipping to change at page 52, line 38
sequence_number =:= static; sequence_number =:= static;
} }
COMPRESSED ah_static { COMPRESSED ah_static {
next_header =:= irregular(8) [ 8 ]; next_header =:= irregular(8) [ 8 ];
length =:= irregular(8) [ 8 ]; length =:= irregular(8) [ 8 ];
spi =:= irregular(32) [ 32 ]; spi =:= irregular(32) [ 32 ];
} }
COMPRESSED ah_dynamic { COMPRESSED ah_dynamic {
res_bits =:= irregular(16) [ 16 ];
sequence_number =:= irregular(32) [ 32 ]; sequence_number =:= irregular(32) [ 32 ];
auth_data =:= auth_data =:=
irregular(length.UVALUE*32-32) [ VARIABLE ]; irregular(length.UVALUE*32-32) [ length.UVALUE*32-32 ];
} }
COMPRESSED ah_irregular { COMPRESSED ah_irregular {
ENFORCE(repair_flag == 0);
sequence_number =:= lsb_7_or_31 [ 8, 32 ]; sequence_number =:= lsb_7_or_31 [ 8, 32 ];
auth_data =:= auth_data =:=
irregular(length.UVALUE*32-32) [ VARIABLE ]; irregular(length.UVALUE*32-32) [ length.UVALUE*32-32 ];
}
COMPRESSED ah_repair_irregular {
ENFORCE(repair_flag == 1);
res_bits =:= irregular(16) [ 16 ];
sequence_number =:= irregular(32) [ 32 ];
auth_data =:=
irregular(length.UVALUE*32-32) [ length.UVALUE*32-32 ];
} }
} }
///////////////////////////////////////////// /////////////////////////////////////////////
// ESP header (NULL encrypted) // ESP header (NULL encrypted)
///////////////////////////////////////////// /////////////////////////////////////////////
// Since the "next header" field is located in the packet trailer // The value of the next header field from the trailer
// and ROHC-FN requires all UNCOMPRESSED fields to be contiguous, // part of the packet is passed as a parameter.
// the values of the next header field is passed as a parameter. esp_null(next_header_value, repair_flag)
// To avoid forcing the decompression to access the trailer part of
// the packet, the next header is istead handled with a control field
esp_null(next_header_value)
{ {
UNCOMPRESSED { UNCOMPRESSED {
spi [ 32 ]; spi [ 32 ];
sequence_number [ 32 ]; sequence_number [ 32 ];
} }
CONTROL { CONTROL {
nh_field [ 8 ]; nh_field [ 8 ];
} }
DEFAULT { DEFAULT {
spi =:= static; spi =:= static;
sequence_number =:= static; sequence_number =:= static;
nh_field =:= static; nh_field =:= static;
} }
COMPRESSED esp_static { COMPRESSED esp_static {
nh_field =:= compressed_value(8, next_header_value) [ 8 ]; nh_field =:= compressed_value(8, next_header_value) [ 8 ];
spi =:= irregular(32) [ 32 ]; spi =:= irregular(32) [ 32 ];
} }
skipping to change at page 49, line 20 skipping to change at page 53, line 44
COMPRESSED esp_static { COMPRESSED esp_static {
nh_field =:= compressed_value(8, next_header_value) [ 8 ]; nh_field =:= compressed_value(8, next_header_value) [ 8 ];
spi =:= irregular(32) [ 32 ]; spi =:= irregular(32) [ 32 ];
} }
COMPRESSED esp_dynamic { COMPRESSED esp_dynamic {
sequence_number =:= irregular(32) [ 32 ]; sequence_number =:= irregular(32) [ 32 ];
} }
COMPRESSED esp_irregular { COMPRESSED esp_irregular {
ENFORCE(repair_flag == 0);
sequence_number =:= lsb_7_or_31 [ 8, 32 ]; sequence_number =:= lsb_7_or_31 [ 8, 32 ];
} }
COMPRESSED esp_repair_irregular {
ENFORCE(repair_flag == 1);
sequence_number =:= irregular(32) [ 32 ];
}
} }
///////////////////////////////////////////// /////////////////////////////////////////////
// IPv6 Header // IPv6 Header
///////////////////////////////////////////// /////////////////////////////////////////////
fl_enc fl_enc
{ {
UNCOMPRESSED { UNCOMPRESSED {
flow_label [ 20 ]; flow_label [ 20 ];
skipping to change at page 49, line 46 skipping to change at page 54, line 29
flow_label =:= uncompressed_value(20, 0) [ 0 ]; flow_label =:= uncompressed_value(20, 0) [ 0 ];
reserved =:= '0000' [ 4 ]; reserved =:= '0000' [ 4 ];
} }
COMPRESSED fl_non_zero { COMPRESSED fl_non_zero {
discriminator =:= '1' [ 1 ]; discriminator =:= '1' [ 1 ];
flow_label =:= irregular(20) [ 20 ]; flow_label =:= irregular(20) [ 20 ];
} }
} }
// The is_innermost flag should be true if this is the innermost ipv6(profile, is_innermost, ip_outer_flag, repair_flag)
// IP header to be compressed.
// If extracting the irregular chain for an compressed packet,
// the TTL&TOS arguments must have the same value as it had when
// processing co_baseheader. If extracting any other chain
// items, this argument is not used.
ipv6(profile, is_innermost,
ttl_irregular_chain_flag, tos_irregular_chain_flag)
{ {
UNCOMPRESSED { UNCOMPRESSED {
version =:= uncompressed_value(4, 6) [ 4 ]; version =:= uncompressed_value(4, 6) [ 4 ];
tos_tc [ 8 ]; tos_tc [ 8 ];
flow_label [ 20 ]; flow_label [ 20 ];
payload_length [ 16 ]; payload_length [ 16 ];
next_header [ 8 ]; next_header [ 8 ];
ttl_hopl [ 8 ]; ttl_hopl [ 8 ];
src_addr [ 128 ]; src_addr [ 128 ];
dst_addr [ 128 ]; dst_addr [ 128 ];
skipping to change at page 50, line 38 skipping to change at page 55, line 12
COMPRESSED ipv6_static { COMPRESSED ipv6_static {
version_flag =:= '1' [ 1 ]; version_flag =:= '1' [ 1 ];
reserved =:= '00' [ 2 ]; reserved =:= '00' [ 2 ];
flow_label =:= fl_enc [ 5, 21 ]; flow_label =:= fl_enc [ 5, 21 ];
next_header =:= irregular(8) [ 8 ]; next_header =:= irregular(8) [ 8 ];
src_addr =:= irregular(128) [ 128 ]; src_addr =:= irregular(128) [ 128 ];
dst_addr =:= irregular(128) [ 128 ]; dst_addr =:= irregular(128) [ 128 ];
} }
COMPRESSED ipv6_endpoint_static {
ENFORCE((is_innermost == 1) &&
(profile == PROFILE_IP_0104));
version_flag =:= '1' [ 1 ];
innermost_indicator =:= compressed_value(1, 1) [ 1 ];
reserved =:= '0' [ 1 ];
flow_label =:= fl_enc [ 5, 21 ];
next_header =:= irregular(8) [ 8 ];
src_addr =:= irregular(128) [ 128 ];
dst_addr =:= irregular(128) [ 128 ];
}
COMPRESSED ipv6_endpoint_dynamic { COMPRESSED ipv6_endpoint_dynamic {
ENFORCE((is_innermost == 1) &&
(profile == PROFILE_IP_0104));
tos_tc =:= irregular(8) [ 8 ]; tos_tc =:= irregular(8) [ 8 ];
ttl_hopl =:= irregular(8) [ 8 ]; ttl_hopl =:= irregular(8) [ 8 ];
reserved =:= compressed_value(6, 0) [ 6 ]; reserved =:= compressed_value(6, 0) [ 6 ];
reorder_ratio =:= reorder_choice [ 2 ]; reorder_ratio =:= reorder_choice [ 2 ];
ENFORCE((is_innermost == true) && msn =:= irregular(16) [ 16 ];
(profile == PROFILE_IP_0104));
} }
COMPRESSED ipv6_regular_dynamic { COMPRESSED ipv6_regular_dynamic {
ENFORCE((is_innermost == 0) ||
(profile != PROFILE_IP_0104));
tos_tc =:= irregular(8) [ 8 ]; tos_tc =:= irregular(8) [ 8 ];
ttl_hopl =:= irregular(8) [ 8 ]; ttl_hopl =:= irregular(8) [ 8 ];
ENFORCE((is_innermost == false) ||
(profile != PROFILE_IP_0104));
} }
COMPRESSED ipv6_outer_irregular { COMPRESSED ipv6_outer_irregular {
ENFORCE(repair_flag == 0);
ENFORCE(is_innermost == 0);
tos_tc =:= tos_tc =:=
static_or_irreg(tos_irregular_chain_flag) [ 0, 8 ]; static_or_irreg(ip_outer_flag, 8) [ 0, 8 ];
ttl_hopl =:= ttl_hopl =:=
static_or_irreg(ttl_irregular_chain_flag) [ 0, 8 ]; static_or_irreg(ip_outer_flag, 8) [ 0, 8 ];
ENFORCE(is_innermost == false);
} }
COMPRESSED ipv6_innermost_irregular { COMPRESSED ipv6_innermost_irregular {
ENFORCE(is_innermost == true); ENFORCE(repair_flag == 0);
ENFORCE(is_innermost == 1);
}
COMPRESSED ipv6_outer_repair_irregular {
ENFORCE(repair_flag == 1);
ENFORCE(is_innermost == 0);
tos_tc =:= static_or_irreg(ip_outer_flag, 8) [ 0, 8 ];
ttl_hopl =:= static_or_irreg(ip_outer_flag, 8) [ 0, 8 ];
}
COMPRESSED ipv6_innermost_repair_irregular {
ENFORCE(repair_flag == 1);
ENFORCE(is_innermost == 1);
} }
} }
///////////////////////////////////////////// /////////////////////////////////////////////
// IPv4 Header // IPv4 Header
///////////////////////////////////////////// /////////////////////////////////////////////
ip_id_enc_dyn(behavior) ip_id_enc_dyn(behavior)
{ {
UNCOMPRESSED { UNCOMPRESSED {
ip_id [ 16 ]; ip_id [ 16 ];
} }
COMPRESSED ip_id_seq { COMPRESSED ip_id_seq {
ip_id =:= irregular(16) [ 16 ];
ENFORCE((behavior == IP_ID_BEHAVIOR_SEQUENTIAL) || ENFORCE((behavior == IP_ID_BEHAVIOR_SEQUENTIAL) ||
(behavior == IP_ID_BEHAVIOR_SEQUENTIAL_SWAPPED) || (behavior == IP_ID_BEHAVIOR_SEQUENTIAL_SWAPPED) ||
(behavior == IP_ID_BEHAVIOR_RANDOM)); (behavior == IP_ID_BEHAVIOR_RANDOM));
ip_id =:= irregular(16) [ 16 ];
} }
COMPRESSED ip_id_zero { COMPRESSED ip_id_zero {
ip_id =:= uncompressed_value(16, 0) [ 0 ];
ENFORCE(behavior == IP_ID_BEHAVIOR_ZERO); ENFORCE(behavior == IP_ID_BEHAVIOR_ZERO);
ip_id =:= uncompressed_value(16, 0) [ 0 ];
} }
} }
ip_id_enc_irreg(behavior) ip_id_enc_irreg(behavior)
{ {
UNCOMPRESSED { UNCOMPRESSED {
ip_id [ 16 ]; ip_id [ 16 ];
} }
COMPRESSED ip_id_seq { COMPRESSED ip_id_seq {
skipping to change at page 51, line 49 skipping to change at page 57, line 4
ip_id_enc_irreg(behavior) ip_id_enc_irreg(behavior)
{ {
UNCOMPRESSED { UNCOMPRESSED {
ip_id [ 16 ]; ip_id [ 16 ];
} }
COMPRESSED ip_id_seq { COMPRESSED ip_id_seq {
ENFORCE(behavior == IP_ID_BEHAVIOR_SEQUENTIAL); ENFORCE(behavior == IP_ID_BEHAVIOR_SEQUENTIAL);
} }
COMPRESSED ip_id_seq_swapped { COMPRESSED ip_id_seq_swapped {
ENFORCE(behavior == IP_ID_BEHAVIOR_SEQUENTIAL_SWAPPED); ENFORCE(behavior == IP_ID_BEHAVIOR_SEQUENTIAL_SWAPPED);
} }
COMPRESSED ip_id_rand { COMPRESSED ip_id_rand {
ip_id =:= irregular(16) [ 16 ];
ENFORCE(behavior == IP_ID_BEHAVIOR_RANDOM); ENFORCE(behavior == IP_ID_BEHAVIOR_RANDOM);
ip_id =:= irregular(16) [ 16 ];
} }
COMPRESSED ip_id_zero { COMPRESSED ip_id_zero {
ip_id =:= uncompressed_value(16, 0) [ 0 ];
ENFORCE(behavior == IP_ID_BEHAVIOR_ZERO); ENFORCE(behavior == IP_ID_BEHAVIOR_ZERO);
ip_id =:= uncompressed_value(16, 0) [ 0 ];
} }
} }
ip_id_behavior_choice ip_id_behavior_choice(is_inner)
{ {
UNCOMPRESSED { UNCOMPRESSED {
behavior [ 2 ]; behavior [ 2 ];
} }
DEFAULT { DEFAULT {
behavior =:= irregular(2); behavior =:= irregular(2);
} }
COMPRESSED sequential { COMPRESSED sequential {
behavior [ 2 ]; ENFORCE(is_inner == 1);
ENFORCE(behavior.UVALUE == IP_ID_BEHAVIOR_SEQUENTIAL); ENFORCE(behavior.UVALUE == IP_ID_BEHAVIOR_SEQUENTIAL);
behavior [ 2 ];
} }
COMPRESSED sequential_swapped { COMPRESSED sequential_swapped {
behavior [ 2 ]; ENFORCE(is_inner == 1);
ENFORCE(behavior.UVALUE == ENFORCE(behavior.UVALUE ==
IP_ID_BEHAVIOR_SEQUENTIAL_SWAPPED); IP_ID_BEHAVIOR_SEQUENTIAL_SWAPPED);
behavior [ 2 ];
} }
COMPRESSED random { COMPRESSED random {
behavior [ 2 ];
ENFORCE(behavior.UVALUE == IP_ID_BEHAVIOR_RANDOM); ENFORCE(behavior.UVALUE == IP_ID_BEHAVIOR_RANDOM);
behavior [ 2 ];
} }
COMPRESSED zero { COMPRESSED zero {
behavior [ 2 ];
ENFORCE(behavior.UVALUE == IP_ID_BEHAVIOR_ZERO); ENFORCE(behavior.UVALUE == IP_ID_BEHAVIOR_ZERO);
behavior [ 2 ];
} }
} }
// The is_innermost flag should be true if this is the innermost variable_ipv4_fields(flag)
// IP header to be compressed. {
UNCOMPRESSED {
df [ 1 ];
ip_id_behavior [ 2 ];
}
// If extracting the irregular chain for an compressed packet, COMPRESSED not_present {
// the TTL&TOS arguments must have the same value as it had when ENFORCE(flag == 0);
// processing co_baseheader. If extracting any other chain df =:= static;
// items, this argument is not used. ip_id_behavior =:= static;
ipv4(profile, is_innermost, }
ttl_irregular_chain_flag, tos_irregular_chain_flag)
COMPRESSED present {
ENFORCE(flag == 1);
reserved =:= '00000' [ 5 ];
df =:= irregular(1) [ 1 ];
ip_id_behavior =:= ip_id_behavior_choice(0) [ 2 ];
}
}
ipv4(profile, is_innermost, ip_outer_flag, repair_flag)
{ {
UNCOMPRESSED { UNCOMPRESSED {
version =:= uncompressed_value(4, 4) [ 4 ]; version =:= uncompressed_value(4, 4) [ 4 ];
hdr_length =:= uncompressed_value(4, 5) [ 4 ]; hdr_length =:= uncompressed_value(4, 5) [ 4 ];
tos_tc [ 8 ]; tos_tc [ 8 ];
length [ 16 ]; length =:= inferred_ip_v4_length [ 16 ];
ip_id [ 16 ]; ip_id [ 16 ];
rf =:= uncompressed_value(1, 0) [ 1 ]; rf =:= uncompressed_value(1, 0) [ 1 ];
df [ 1 ]; df [ 1 ];
mf =:= uncompressed_value(1, 0) [ 1 ]; mf =:= uncompressed_value(1, 0) [ 1 ];
frag_offset =:= uncompressed_value(13, 0) [ 13 ]; frag_offset =:= uncompressed_value(13, 0) [ 13 ];
ttl_hopl [ 8 ]; ttl_hopl [ 8 ];
protocol [ 8 ]; protocol [ 8 ];
checksum [ 16 ]; checksum =:= inferred_ip_v4_header_checksum [ 16 ];
src_addr [ 32 ]; src_addr [ 32 ];
dst_addr [ 32 ]; dst_addr [ 32 ];
} }
CONTROL { CONTROL {
ip_id_behavior [ 2 ]; ip_id_behavior [ 2 ];
} }
DEFAULT { DEFAULT {
tos_tc =:= static; tos_tc =:= static;
length =:= inferred_ip_v4_length;
df =:= static; df =:= static;
ttl_hopl =:= static; ttl_hopl =:= static;
protocol =:= static; protocol =:= static;
checksum =:= inferred_ip_v4_header_checksum;
src_addr =:= static; src_addr =:= static;
dst_addr =:= static; dst_addr =:= static;
ip_id_behavior =:= static; ip_id_behavior =:= static;
} }
COMPRESSED ipv4_static { COMPRESSED ipv4_static {
version_flag =:= '0' [ 1 ]; version_flag =:= '0' [ 1 ];
reserved =:= '0000000' [ 7 ]; reserved =:= '0000000' [ 7 ];
protocol =:= irregular(8) [ 8 ]; protocol =:= irregular(8) [ 8 ];
src_addr =:= irregular(32) [ 32 ]; src_addr =:= irregular(32) [ 32 ];
dst_addr =:= irregular(32) [ 32 ]; dst_addr =:= irregular(32) [ 32 ];
} }
COMPRESSED ipv4_endpoint_static {
ENFORCE((is_innermost == 1) &&
(profile == PROFILE_IP_0104));
version_flag =:= '0' [ 1 ];
innermost_indicator =:= compressed_value(1, 1) [ 1 ];
reserved =:= '000000' [ 6 ];
protocol =:= irregular(8) [ 8 ];
src_addr =:= irregular(32) [ 32 ];
dst_addr =:= irregular(32) [ 32 ];
}
COMPRESSED ipv4_endpoint_dynamic { COMPRESSED ipv4_endpoint_dynamic {
reserved =:= '000' [ 5 ]; ENFORCE((is_innermost == 1) &&
(profile == PROFILE_IP_0104));
reserved =:= '000' [ 3 ];
reorder_ratio =:= reorder_choice [ 2 ]; reorder_ratio =:= reorder_choice [ 2 ];
df =:= irregular(1) [ 1 ]; df =:= irregular(1) [ 1 ];
ip_id_behavior =:= ip_id_behavior_choice [ 2 ]; ip_id_behavior =:= ip_id_behavior_choice(is_innermost) [ 2 ];
tos_tc =:= irregular(8) [ 8 ]; tos_tc =:= irregular(8) [ 8 ];
ttl_hopl =:= irregular(8) [ 8 ]; ttl_hopl =:= irregular(8) [ 8 ];
ip_id =:= ip_id =:= ip_id_enc_dyn(ip_id_behavior.UVALUE) [ 0, 16 ];
ip_id_enc_dyn(ip_id_behavior.UVALUE) [ 0, 16 ]; msn =:= irregular(16) [ 16 ];
ENFORCE((is_innermost == true) &&
(profile == PROFILE_IP_0104));
} }
COMPRESSED ipv4_regular_dynamic { COMPRESSED ipv4_regular_dynamic {
ENFORCE((is_innermost == 0) ||
(profile != PROFILE_IP_0104));
reserved =:= '00000' [ 5 ]; reserved =:= '00000' [ 5 ];
df =:= irregular(1) [ 1 ]; df =:= irregular(1) [ 1 ];
ip_id_behavior =:= ip_id_behavior_choice [ 2 ]; ip_id_behavior =:= ip_id_behavior_choice(is_innermost) [ 2 ];
tos_tc =:= irregular(8) [ 8 ]; tos_tc =:= irregular(8) [ 8 ];
ttl_hopl =:= irregular(8) [ 8 ]; ttl_hopl =:= irregular(8) [ 8 ];
ip_id =:= ip_id =:= ip_id_enc_dyn(ip_id_behavior.UVALUE) [ 0, 16 ];
ip_id_enc_dyn(ip_id_behavior.UVALUE) [ 0, 16 ];
ENFORCE((is_innermost == false) ||
(profile != PROFILE_IP_0104));
} }
COMPRESSED ipv4_outer_irregular { COMPRESSED ipv4_outer_irregular {
ip_id =:= ENFORCE(repair_flag == 0);
ip_id_enc_irreg(ip_id_behavior.UVALUE) [ 0, 16 ]; ENFORCE(is_innermost == 0);
tos_tc =:= ip_id =:= ip_id_enc_irreg(ip_id_behavior.UVALUE) [ 0, 16 ];
static_or_irreg(tos_irregular_chain_flag) [ 0, 8 ]; tos_tc =:= static_or_irreg(ip_outer_flag, 8) [ 0, 8 ];
ttl_hopl =:= ttl_hopl =:= static_or_irreg(ip_outer_flag, 8) [ 0, 8 ];
static_or_irreg(ttl_irregular_chain_flag) [ 0, 8 ];
ENFORCE(is_innermost == false);
} }
COMPRESSED ipv4_innermost_irregular { COMPRESSED ipv4_innermost_irregular {
ip_id =:= // Same format for repair and non-repair
ip_id_enc_irreg(ip_id_behavior.UVALUE) [ 0, 16 ]; ip_id =:= ip_id_enc_irreg(ip_id_behavior.UVALUE) [ 0, 16 ];
ENFORCE(is_innermost == true); ENFORCE(is_innermost == 1);
} }
COMPRESSED ipv4_outer_repair_irregular {
ENFORCE(repair_flag == 1);
ENFORCE(is_innermost == 0);
df : ip_id_behavior =:=
variable_ipv4_fields(outer_flag) [ 0, 8 ];
ip_id =:= ip_id_enc_irreg(ip_id_behavior.UVALUE) [ 0, 16 ];
tos_tc =:= static_or_irreg(ip_outer_flag, 8) [ 0, 8 ];
ttl_hopl =:= static_or_irreg(ip_outer_flag, 8) [ 0, 8 ];
}
} }
///////////////////////////////////////////// /////////////////////////////////////////////
// UDP Header // UDP Header
///////////////////////////////////////////// /////////////////////////////////////////////
udp(profile) udp(profile)
{ {
UNCOMPRESSED { UNCOMPRESSED {
ENFORCE((profile == PROFILE_RTP_0101) ||
(profile == PROFILE_UDP_0102));
src_port [ 16 ]; src_port [ 16 ];
dst_port [ 16 ]; dst_port [ 16 ];
udp_length [ 16 ]; udp_length =:= inferred_udp_length [ 16 ];
checksum [ 16 ]; checksum [ 16 ];
ENFORCE((profile == PROFILE_RTP_0101) ||
(profile == PROFILE_UDP_0102));
} }
DEFAULT { DEFAULT {
src_port =:= static; src_port =:= static;
dst_port =:= static; dst_port =:= static;
udp_length =:= inferred_udp_length;
checksum =:= irregular(16); checksum =:= irregular(16);
} }
COMPRESSED udp_static { COMPRESSED udp_static {
src_port =:= irregular(16) [ 16 ]; src_port =:= irregular(16) [ 16 ];
dst_port =:= irregular(16) [ 16 ]; dst_port =:= irregular(16) [ 16 ];
} }
COMPRESSED udp_endpoint_dynamic { COMPRESSED udp_endpoint_dynamic {
ENFORCE(profile == PROFILE_UDP_0102);
checksum [ 16 ]; checksum [ 16 ];
msn =:= irregular(16) [ 16 ]; msn =:= irregular(16) [ 16 ];
reserved =:= uncompressed_value(6, 0); reserved =:= compressed_value(6, 0) [ 6 ];
reorder_ratio =:= reorder_choice [ 2 ]; reorder_ratio =:= reorder_choice [ 2 ];
ENFORCE(profile == PROFILE_UDP_0102);
} }
COMPRESSED udp_regular_dynamic { COMPRESSED udp_regular_dynamic {
ENFORCE(profile == PROFILE_RTP_0101);
checksum [ 16 ]; checksum [ 16 ];
} }
COMPRESSED udp_zero_checksum_irregular { COMPRESSED udp_zero_checksum_irregular {
ENFORCE(checksum.UVALUE == 0); ENFORCE(checksum.UVALUE == 0);
checksum =:= uncompressed_value(16, 0); checksum =:= uncompressed_value(16, 0) [ 0 ];
} }
COMPRESSED udp_with_checksum_irregular { COMPRESSED udp_with_checksum_irregular {
ENFORCE(checksum.UVALUE == 1); ENFORCE(checksum.UVALUE != 0);
checksum [ 16 ]; checksum [ 16 ];
} }
} }
///////////////////////////////////////////// /////////////////////////////////////////////
// RTP Header // RTP Header
///////////////////////////////////////////// /////////////////////////////////////////////
csrc_list_dynchain(presence, cc_value) csrc_list_dynchain(presence, cc_value)
{ {
UNCOMPRESSED { UNCOMPRESSED {
csrc_list; csrc_list;
} }
COMPRESSED no_list { COMPRESSED no_list {
csrc_list =:= uncompressed_value(0, 0) [ 0 ];
ENFORCE(cc_value == 0); ENFORCE(cc_value == 0);
ENFORCE(presence == 0); ENFORCE(presence == 0);
csrc_list =:= uncompressed_value(0, 0) [ 0 ];
} }
COMPRESSED list_present { COMPRESSED list_present {
csrc_list =:= list_csrc(cc_value) [ VARIABLE ];
ENFORCE(presence == 1); ENFORCE(presence == 1);
csrc_list =:= list_csrc(cc_value) [ VARIABLE ];
} }
} }
rtp(profile, ts_stride_value) rtp(profile, ts_stride_value, time_stride_value)
{ {
UNCOMPRESSED { UNCOMPRESSED {
ENFORCE((profile == PROFILE_RTP_0101) ||
(profile == PROFILE_RTP_0107));
rtp_version =:= uncompressed_value(2, 0) [ 2 ]; rtp_version =:= uncompressed_value(2, 0) [ 2 ];
pad_bit [ 1 ]; pad_bit [ 1 ];
extension [ 1 ]; extension [ 1 ];
cc [ 4 ]; cc [ 4 ];
marker [ 1 ]; marker [ 1 ];
payload_type [ 7 ]; payload_type [ 7 ];
sequence_number [ 16 ]; sequence_number [ 16 ];
timestamp [ 32 ]; timestamp [ 32 ];
ssrc [ 32 ]; ssrc [ 32 ];
csrc_list [ VARIABLE ]; csrc_list [ cc.UVALUE * 32 ];
ENFORCE((profile == PROFILE_RTP_0101) ||
(profile == PROFILE_RTP_0107));
} }
CONTROL { CONTROL {
// The ts_stride has an initial UVALUE=1, which means that it ENFORCE(time_stride_value == time_stride.UVALUE);
// can be encoded with 'static' even if it has not been ENFORCE(ts_stride_value == ts_stride.UVALUE);
// previously established in the context.
ts_stride [ 32 ]; ts_stride [ 32 ];
time_stride [ 32 ];
ts_scaled [ 32 ]; ts_scaled [ 32 ];
ts_offset =:= ts_offset =:=
field_scaling(ts_stride.UVALUE, ts_scaled.UVALUE, field_scaling(ts_stride.UVALUE, ts_scaled.UVALUE,
timestamp.UVALUE) [ 32 ]; timestamp.UVALUE) [ 32 ];
} }
INITIAL {
ts_stride =:= uncompressed_value(32, 0);
time_stride =:= uncompressed_value(32, 0);
}
DEFAULT { DEFAULT {
ENFORCE(msn.UVALUE == sequence_number.UVALUE);
pad_bit =:= static; pad_bit =:= static;
extension =:= static; extension =:= static;
cc =:= static; cc =:= static;
marker =:= static; marker =:= static;
payload_type =:= static; payload_type =:= static;
sequence_number =:= static; sequence_number =:= static;
timestamp =:= static; timestamp =:= static;
ssrc =:= static; ssrc =:= static;
csrc_list =:= static; csrc_list =:= static;
} }
skipping to change at page 57, line 13 skipping to change at page 63, line 4
pad_bit =:= static; pad_bit =:= static;
extension =:= static; extension =:= static;
cc =:= static; cc =:= static;
marker =:= static; marker =:= static;
payload_type =:= static; payload_type =:= static;
sequence_number =:= static; sequence_number =:= static;
timestamp =:= static; timestamp =:= static;
ssrc =:= static; ssrc =:= static;
csrc_list =:= static; csrc_list =:= static;
} }
COMPRESSED rtp_static { COMPRESSED rtp_static {
ssrc =:= irregular(32) [ 32 ]; ssrc =:= irregular(32) [ 32 ];
} }
COMPRESSED rtp_dynamic { COMPRESSED rtp_dynamic {
reserved =:= compressed_value(1, 0) [ 1 ]; reserved =:= compressed_value(1, 0) [ 1 ];
reorder_ratio =:= reorder_choice [ 2 ]; reorder_ratio =:= reorder_choice [ 2 ];
list_present =:= irregular(1) [ 1 ]; list_present =:= irregular(1) [ 1 ];
tss_indicator =:= irregular(1) [ 1 ]; tss_indicator =:= irregular(1) [ 1 ];
tis_indicator =:= irregular(1) [ 1 ];
pad_bit =:= irregular(1) [ 1 ]; pad_bit =:= irregular(1) [ 1 ];
extension =:= irregular(1) [ 1 ]; extension =:= irregular(1) [ 1 ];
marker =:= irregular(1) [ 1 ]; marker =:= irregular(1) [ 1 ];
payload_type =:= irregular(7) [ 7 ]; payload_type =:= irregular(7) [ 7 ];
sequence_number =:= irregular(16) [ 16 ]; sequence_number =:= irregular(16) [ 16 ];
timestamp =:= irregular(32) [ 32 ]; timestamp =:= irregular(32) [ 32 ];
ts_stride =:= ts_stride =:= sdvl_or_static(tss_indicator) [ VARIABLE ];
optional_stride(tss_indicator, time_stride =:= sdvl_or_static(tis_indicator) [ VARIABLE ];
ts_stride_value) [ VARIABLE ];
csrc_list =:= csrc_list =:=
csrc_list_dynchain(list_present, cc.UVALUE) [ VARIABLE ]; csrc_list_dynchain(list_present, cc.UVALUE) [ VARIABLE ];
} }
COMPRESSED rtp_irregular { COMPRESSED rtp_irregular {
} }
} }
///////////////////////////////////////////// /////////////////////////////////////////////
// UDP-Lite Header // UDP-Lite Header
///////////////////////////////////////////// /////////////////////////////////////////////
checksum_coverage_dynchain(behavior) checksum_coverage_dynchain(behavior)
{ {
UNCOMPRESSED { UNCOMPRESSED {
checksum_coverage [ 16 ]; checksum_coverage [ 16 ];
} }
COMPRESSED inferred_coverage { COMPRESSED inferred_coverage {
checksum_coverage =:= inferred_udp_length [ 0 ];
ENFORCE(behavior == UDP_LITE_COVERAGE_INFERRED); ENFORCE(behavior == UDP_LITE_COVERAGE_INFERRED);
checksum_coverage =:= inferred_udp_length [ 0 ];
} }
COMPRESSED static_coverage { COMPRESSED static_coverage {
checksum_coverage =:= irregular(16) [ 16 ];
ENFORCE(behavior == UDP_LITE_COVERAGE_STATIC); ENFORCE(behavior == UDP_LITE_COVERAGE_STATIC);
checksum_coverage =:= irregular(16) [ 16 ];
} }
COMPRESSED irregular_coverage { COMPRESSED irregular_coverage {
checksum_coverage =:= irregular(16) [ 16 ];
ENFORCE(behavior == UDP_LITE_COVERAGE_IRREGULAR); ENFORCE(behavior == UDP_LITE_COVERAGE_IRREGULAR);
checksum_coverage =:= irregular(16) [ 16 ];
} }
} }
checksum_coverage_irregular(behavior) checksum_coverage_irregular(behavior)
{ {
UNCOMPRESSED { UNCOMPRESSED {
checksum_coverage [ 16 ]; checksum_coverage [ 16 ];
} }
COMPRESSED inferred_coverage { COMPRESSED inferred_coverage {
checksum_coverage =:= inferred_udp_length [ 0 ];
ENFORCE(behavior == UDP_LITE_COVERAGE_INFERRED); ENFORCE(behavior == UDP_LITE_COVERAGE_INFERRED);
checksum_coverage =:= inferred_udp_length [ 0 ];
} }
COMPRESSED static_coverage { COMPRESSED static_coverage {
checksum_coverage =:= static [ 0 ];
ENFORCE(behavior == UDP_LITE_COVERAGE_STATIC); ENFORCE(behavior == UDP_LITE_COVERAGE_STATIC);
checksum_coverage =:= static [ 0 ];
} }
COMPRESSED irregular_coverage { COMPRESSED irregular_coverage {
checksum_coverage =:= irregular(16) [ 16 ];
ENFORCE(behavior == UDP_LITE_COVERAGE_IRREGULAR); ENFORCE(behavior == UDP_LITE_COVERAGE_IRREGULAR);
checksum_coverage =:= irregular(16) [ 16 ];
} }
} }
udp_lite(profile) udp_lite(profile)
{ {
UNCOMPRESSED { UNCOMPRESSED {
ENFORCE((profile == PROFILE_RTP_0107) ||
(profile == PROFILE_UDPLITE_0108));
src_port [ 16 ]; src_port [ 16 ];
dst_port [ 16 ]; dst_port [ 16 ];
checksum_coverage [ 16 ]; checksum_coverage [ 16 ];
checksum [ 16 ]; checksum [ 16 ];
ENFORCE((profile == PROFILE_RTP_0107) ||
(profile == PROFILE_UDPLITE_0108));
} }
CONTROL { CONTROL {
coverage_behavior [ 2 ]; coverage_behavior [ 2 ];
} }
DEFAULT { DEFAULT {
src_port =:= static; src_port =:= static;
dst_port =:= static; dst_port =:= static;
checksum_coverage =:= irregular(16); checksum_coverage =:= irregular(16);
skipping to change at page 59, line 13 skipping to change at page 65, line 4
CONTROL { CONTROL {
coverage_behavior [ 2 ]; coverage_behavior [ 2 ];
} }
DEFAULT { DEFAULT {
src_port =:= static; src_port =:= static;
dst_port =:= static; dst_port =:= static;
checksum_coverage =:= irregular(16); checksum_coverage =:= irregular(16);
checksum =:= irregular(16); checksum =:= irregular(16);
} }
COMPRESSED udp_lite_static { COMPRESSED udp_lite_static {
src_port =:= irregular(16) [ 16 ]; src_port =:= irregular(16) [ 16 ];
dst_port =:= irregular(16) [ 16 ]; dst_port =:= irregular(16) [ 16 ];
} }
COMPRESSED udp_lite_endpoint_dynamic { COMPRESSED udp_lite_endpoint_dynamic {
ENFORCE(profile == PROFILE_UDPLITE_0108);
reserved =:= compressed_value(4, 0) [ 4 ]; reserved =:= compressed_value(4, 0) [ 4 ];
coverage_behavior =:= irregular(2) [ 2 ]; coverage_behavior =:= irregular(2) [ 2 ];
reorder_ratio =:= reorder_choice [ 2 ]; reorder_ratio =:= reorder_choice [ 2 ];
checksum_coverage =:= checksum_coverage =:=
checksum_coverage_dynchain(coverage_behavior.UVALUE) [ 16 ]; checksum_coverage_dynchain(coverage_behavior.UVALUE) [ 16 ];
checksum [ 16 ]; checksum [ 16 ];
msn =:= irregular(16) [ 16 ]; msn =:= irregular(16) [ 16 ];
ENFORCE(profile == PROFILE_UDPLITE_0108);
} }
COMPRESSED udp_lite_regular_dynamic { COMPRESSED udp_lite_regular_dynamic {
coverage_behavior =:= irregular(2) [ 2 ]; coverage_behavior =:= irregular(2) [ 2 ];
reserved =:= compressed_value(6, 0) [ 6 ]; reserved =:= compressed_value(6, 0) [ 6 ];
checksum_coverage =:= checksum_coverage =:=
checksum_coverage_dynchain(coverage_behavior.UVALUE) [ 16 ]; checksum_coverage_dynchain(coverage_behavior.UVALUE) [ 16 ];
checksum [ 16 ]; checksum [ 16 ];
} }
COMPRESSED udp_lite_irregular { COMPRESSED udp_lite_irregular {
checksum_coverage =:= checksum_coverage =:=
checksum_coverage_dynchain(coverage_behavior.UVALUE) [ 0, 16 ]; checksum_coverage_dynchain(coverage_behavior.UVALUE) [ 0, 16 ];
checksum [ 16 ]; checksum [ 16 ];
} }
} }
///////////////////////////////////////////// /////////////////////////////////////////////
// ESP Header (Non-NULL encrypted // ESP Header (Non-NULL encrypted
// i.e. only used for the ESP profile // i.e. only used for the ESP profile)
///////////////////////////////////////////// /////////////////////////////////////////////
esp(profile) esp(profile)
{ {
UNCOMPRESSED { UNCOMPRESSED {
ENFORCE(profile == PROFILE_ESP_0103);
spi [ 32 ]; spi [ 32 ];
sequence_number [ 32 ]; sequence_number [ 32 ];
ENFORCE(profile == PROFILE_ESP_0103);
} }
DEFAULT { DEFAULT {
ENFORCE(msn.UVALUE == sequence_number.UVALUE % 65536);
spi =:= static; spi =:= static;
sequence_number =:= static; sequence_number =:= static;
} }
COMPRESSED esp_static { COMPRESSED esp_static {
// Needs to be discriminated from ESP NULL headers,
// and therefore we have a dummy protocol field here.
discriminator =:= uncompressed_value(8, 255) [ 8 ];
spi =:= irregular(32) [ 32 ]; spi =:= irregular(32) [ 32 ];
} }
COMPRESSED esp_dynamic { COMPRESSED esp_dynamic {
sequence_number =:= irregular(32) [ 32 ]; sequence_number =:= irregular(32) [ 32 ];
msn =:= irregular(16) [ 16 ]; reserved =:= compressed_value(6, 0) [ 6 ];
reserved =:= uncompressed_value(6, 0) [ 6 ];
reorder_ratio =:= reorder_choice [ 2 ]; reorder_ratio =:= reorder_choice [ 2 ];
} }
COMPRESSED esp_irregular { COMPRESSED esp_irregular {
} }
} }
/////////////////////////////////////////////////// ///////////////////////////////////////////////////
// Encoding methods used in the profiles' CO packets // Encoding methods used in the profiles' CO packets
/////////////////////////////////////////////////// ///////////////////////////////////////////////////
ip_id_lsb(behavior, k, p) // Variable reordering offset used for MSN
msn_lsb(k)
{
UNCOMPRESSED {
master [ 16 ];
}
COMPRESSED none {
ENFORCE(reorder_ratio.UVALUE == REORDERING_NONE);
master =:= lsb(k, 1);
}
COMPRESSED quarter {
ENFORCE(reorder_ratio.UVALUE == REORDERING_QUARTER);
master =:= lsb(k, ((2^k) / 4) - 1);
}
COMPRESSED half {
ENFORCE(reorder_ratio.UVALUE == REORDERING_HALF);
master =:= lsb(k, ((2^k) / 2) - 1);
}
COMPRESSED threequarters {
ENFORCE(reorder_ratio.UVALUE == REORDERING_THREEQUARTERS);
master =:= lsb(k, (((2^k) * 3) / 4) - 1);
}
}
ip_id_lsb(behavior, k)
{ {
UNCOMPRESSED { UNCOMPRESSED {
ip_id [ 16 ]; ip_id [ 16 ];
} }
CONTROL { CONTROL {
ip_id_offset [ 16 ]; ip_id_offset [ 16 ];
ip_id_nbo [ 16 ]; ip_id_nbo [ 16 ];
} }
COMPRESSED nbo { COMPRESSED nbo {
ip_id_offset =:= lsb(k, p) [ VARIABLE ];
ENFORCE(behavior == IP_ID_BEHAVIOR_SEQUENTIAL); ENFORCE(behavior == IP_ID_BEHAVIOR_SEQUENTIAL);
ENFORCE(ip_id_offset.UVALUE == ip_id.UVALUE - msn.UVALUE); ENFORCE(ip_id_offset.UVALUE == ip_id.UVALUE - msn.UVALUE);
ip_id_offset =:= lsb(k, ((2^k) / 4) - 1) [ k ];
} }
COMPRESSED non_nbo { COMPRESSED non_nbo {
ip_id_offset =:= lsb(k, p) [ VARIABLE ];
ENFORCE(behavior == IP_ID_BEHAVIOR_SEQUENTIAL_SWAPPED); ENFORCE(behavior == IP_ID_BEHAVIOR_SEQUENTIAL_SWAPPED);
ENFORCE(ip_id_nbo.UVALUE == ENFORCE(ip_id_nbo.UVALUE ==
(ip_id.UVALUE / 256) + (ip_id.UVALUE % 256) * 256); (ip_id.UVALUE / 256) + (ip_id.UVALUE % 256) * 256);
ENFORCE(ip_id_nbo.ULENGTH == 16); ENFORCE(ip_id_nbo.ULENGTH == 16);
ENFORCE(ip_id_offset.UVALUE == ip_id_nbo.UVALUE - msn.UVALUE); ENFORCE(ip_id_offset.UVALUE == ip_id_nbo.UVALUE - msn.UVALUE);
ip_id_offset =:= lsb(k, ((2^k) / 4) - 1) [ k ];
} }
} }
optional_ip_id_lsb(behavior, indicator) optional_ip_id_lsb(behavior, indicator)
{ {
UNCOMPRESSED { UNCOMPRESSED {
ip_id [ 16 ]; ip_id [ 16 ];
} }
COMPRESSED short { COMPRESSED short {
ip_id =:= ip_id_lsb(behavior, 8, 3) [ 8 ];
ENFORCE((behavior == IP_ID_BEHAVIOR_SEQUENTIAL) || ENFORCE((behavior == IP_ID_BEHAVIOR_SEQUENTIAL) ||
(behavior == IP_ID_BEHAVIOR_SEQUENTIAL_SWAPPED)); (behavior == IP_ID_BEHAVIOR_SEQUENTIAL_SWAPPED));
ENFORCE(indicator == 0); ENFORCE(indicator == 0);
ip_id =:= ip_id_lsb(behavior, 8) [ 8 ];
} }
COMPRESSED long { COMPRESSED long {
ip_id =:= irregular(16) [ 16 ];
ENFORCE((behavior == IP_ID_BEHAVIOR_SEQUENTIAL) || ENFORCE((behavior == IP_ID_BEHAVIOR_SEQUENTIAL) ||
(behavior == IP_ID_BEHAVIOR_SEQUENTIAL_SWAPPED)); (behavior == IP_ID_BEHAVIOR_SEQUENTIAL_SWAPPED));
ENFORCE(indicator == 1); ENFORCE(indicator == 1);
ip_id =:= irregular(16) [ 16 ];
} }
COMPRESSED not_present { COMPRESSED not_present {
ENFORCE((behavior == IP_ID_BEHAVIOR_RANDOM) || ENFORCE((behavior == IP_ID_BEHAVIOR_RANDOM) ||
(behavior == IP_ID_BEHAVIOR_ZERO)); (behavior == IP_ID_BEHAVIOR_ZERO));
} }
} }
dont_fragment(version) dont_fragment(version)
{ {
UNCOMPRESSED { UNCOMPRESSED {
df [ 1 ]; df [ 1 ];
} }
COMPRESSED v4 { COMPRESSED v4 {
df =:= irregular(1) [ 1 ];
ENFORCE(version == 4); ENFORCE(version == 4);
df =:= irregular(1) [ 1 ];
} }
COMPRESSED v6 { COMPRESSED v6 {
df =:= compressed_value(1, 0) [ 1 ];
ENFORCE(version == 6); ENFORCE(version == 6);
df =:= compressed_value(1, 0) [ 1 ];
}
}
optional_pt(flag)
{
UNCOMPRESSED {
payload_type [ 7 ];
}
COMPRESSED not_present {
ENFORCE(flag == 0);
payload_type =:= static [ 0 ];
}
COMPRESSED present {
ENFORCE(flag == 1);
reserved =:= compressed_value(1, 0) [ 1 ];
payload_type =:= irregular(7) [ 7 ];
}
}
csrc_list_presence(presence, cc_value)
{
UNCOMPRESSED {
csrc_list;
}
COMPRESSED no_list {
ENFORCE(presence == 0);
csrc_list =:= static [ 0 ];
}
COMPRESSED list_present {
ENFORCE(presence == 1);
csrc_list =:= list_csrc(cc_value) [ VARIABLE ];
}
}
scaled_ts_lsb(time_stride_value, k)
{
UNCOMPRESSED {
timestamp [ 32 ];
}
COMPRESSED timerbased {
ENFORCE(time_stride_value != 0);
timestamp =:= timer_based_lsb(time_stride_value, k,
((2^k) / 4) - 1);
}
COMPRESSED regular {
ENFORCE(time_stride_value == 0);
timestamp =:= lsb(k, ((2^k) / 4) - 1);
}
}
irregular_or_nothing(flag)
{
UNCOMPRESSED {
field [ 32 ];
}
COMPRESSED not_present {
ENFORCE(flag == 0);
}
COMPRESSED present {
ENFORCE(flag == 1);
field =:= irregular(32);
}
}
// Self-describing variable length encoding
sdvl_lsb(field_width)
{
UNCOMPRESSED {
field [ field_width ];
}
COMPRESSED lsb7 {
discriminator =:= '0' [ 1 ];
field =:= lsb(7, ((2^7) / 4) - 1) [ 7 ];
}
COMPRESSED lsb14 {
discriminator =:= '10' [ 2 ];
field =:= lsb(14, ((2^14) / 4) - 1) [ 14 ];
}
COMPRESSED lsb21 {
discriminator =:= '110' [ 3 ];
field =:= lsb(21, ((2^21) / 4) - 1) [ 21 ];
}
COMPRESSED lsb28 {
discriminator =:= '1110' [ 4 ];
field =:= lsb(28, ((2^28) / 4) - 1) [ 28 ];
}
COMPRESSED lsb32 {
discriminator =:= '11111111' [ 8 ];
field =:= irregular(field_width) [ field_width ];
}
}
variable_scaled_timestamp(tss_flag, tsc_flag, ts_stride)
{
UNCOMPRESSED {
timestamp [ 32 ];
}
COMPRESSED present {
ENFORCE((tss_flag == 0) && (tsc_flag == 1));
ENFORCE(ts_stride != 0);
timestamp =:= sdvl_lsb(32) [ VARIABLE ];
}
COMPRESSED not_present {
ENFORCE(((tss_flag == 1) && (tsc_flag == 0)) ||
((tss_flag == 0) && (tsc_flag == 0)));
}
}
variable_unscaled_timestamp(tss_flag, tsc_flag)
{
UNCOMPRESSED {
timestamp [ 32 ];
}
COMPRESSED present {
ENFORCE(((tss_flag == 1) && (tsc_flag == 0)) ||
((tss_flag == 0) && (tsc_flag == 0)));
timestamp =:= sdvl_lsb(32);
}
COMPRESSED not_present {
ENFORCE((tss_flag == 0) && (tsc_flag == 1));
}
}
profile_1_7_flags1_enc(flag)
{
UNCOMPRESSED {
ip_outer_indicator [ 1 ];
repair_indicator [ 1 ];
ttl_hopl_indicator [ 1 ];
tos_tc_indicator [ 1 ];
ip_id_behavior [ 2 ];
reorder_ratio [ 2 ];
}
COMPRESSED not_present {
ENFORCE(flag == 0);
ENFORCE(ip_outer_indicator.CVALUE == 0);
ENFORCE(repair_indicator.CVALUE == 0);
ENFORCE(ttl_hopl_indicator.CVALUE == 0);
ENFORCE(tos_tc_indicator.CVALUE == 0);
ip_id_behavior =:= static;
reorder_ratio =:= static;
}
COMPRESSED present {
ENFORCE(flag == 1);
ip_outer_indicator =:= irregular(1) [ 1 ];
repair_indicator =:= irregular(1) [ 1 ];
ttl_hopl_indicator =:= irregular(1) [ 1 ];
tos_tc_indicator =:= irregular(1) [ 1 ];
ip_id_behavior =:= ip_id_behavior_choice(1) [ 2 ];
reorder_ratio =:= reorder_choice [ 2 ];
}
}
profile_1_flags2_enc(flag, ip_version)
{
UNCOMPRESSED {
list_indicator [ 1 ];
pt_indicator [ 1 ];
pad_bit [ 1 ];
extension [ 1 ];
df [ 1 ];
time_stride_indicator [ 1 ];
}
COMPRESSED not_present{
ENFORCE(flag == 0);
ENFORCE(list_indicator.UVALUE == 0);
ENFORCE(pt_indicator.UVALUE == 0);
ENFORCE(time_stride_indicator.UVALUE == 0);
pad_bit =:= static;
extension =:= static;
df =:= static;
}
COMPRESSED present {
ENFORCE(flag == 1);
list_indicator =:= irregular(1) [ 1 ];
pt_indicator =:= irregular(1) [ 1 ];
time_stride_indicator =:= irregular(1) [ 1 ];
pad_bit =:= irregular(1) [ 1 ];
extension =:= irregular(1) [ 1 ];
df =:= dont_fragment(ip_version) [ 1 ];
reserved =:= compressed_value(2, 0) [ 2 ];
}
}
profile_2_3_4_flags_enc(flag, ip_version)
{
UNCOMPRESSED {
ip_outer_indicator [ 1 ];
repair_indicator [ 1 ];
df [ 1 ];
ip_id_behavior [ 2 ];
}
COMPRESSED not_present {
ENFORCE(flag == 0);
ENFORCE(ip_outer_indicator.CVALUE == 0);
ENFORCE(repair_indicator.CVALUE == 0);
df =:= static;
ip_id_behavior =:= static;
}
COMPRESSED present {
ENFORCE(flag == 1);
ip_outer_indicator =:= irregular(1) [ 1 ];
repair_indicator =:= irregular(1) [ 1 ];
df =:= dont_fragment(ip_version) [ 1 ];
ip_id_behavior =:= ip_id_behavior_choice(1) [ 2 ];
reserved =:= compressed_value(3, 0) [ 3 ];
}
}
profile_8_flags_enc(flag)
{
UNCOMPRESSED {
ip_outer_indicator [ 1 ];
repair_indicator [ 1 ];
df [ 1 ];
ip_id_behavior [ 2 ];
coverage_behavior [ 2 ];
}
COMPRESSED not_present {
ENFORCE(flag == 0);
ENFORCE(ip_outer_indicator.CVALUE == 0);
ENFORCE(repair_indicator.CVALUE == 0);
df =:= static;
ip_id_behavior =:= static;
coverage_behavior =:= static;
}
COMPRESSED present {
ENFORCE(flag == 1);
reserved =:= compressed_value(1, 0) [ 1 ];
ip_outer_indicator =:= irregular(1) [ 1 ];
repair_indicator =:= irregular(1) [ 1 ];
df =:= dont_fragment(ip_version) [ 1 ];
ip_id_behavior =:= ip_id_behavior_choice(1) [ 2 ];
coverage_behavior =:= irregular(2) [ 2 ];
}
}
profile_7_flags2_enc(flag, ip_version)
{
UNCOMPRESSED {
list_indicator [ 1 ];
pt_indicator [ 1 ];
time_stride_indicator [ 1 ];
pad_bit [ 1 ];
extension [ 1 ];
df [ 1 ];
coverage_behavior [ 2 ];
}
COMPRESSED not_present{
ENFORCE(flag == 0);
ENFORCE(list_indicator.CVALUE == 0);
ENFORCE(pt_indicator.CVALUE == 0);
ENFORCE(time_stride_indicator.CVALUE == 0);
pad_bit =:= static;
extension =:= static;
df =:= static;
coverage_behavior =:= static;
}
COMPRESSED present {
ENFORCE(flag == 1);
list_indicator =:= irregular(1) [ 1 ];
pt_indicator =:= irregular(1) [ 1 ];
time_stride_indicator =:= irregular(1) [ 1 ];
pad_bit =:= irregular(1) [ 1 ];
extension =:= irregular(1) [ 1 ];
df =:= dont_fragment(ip_version) [ 1 ];
coverage_behavior =:= irregular(2) [ 2 ];
} }
} }
//////////////////////////////////////////// ////////////////////////////////////////////
// RTP profile // RTP profile
//////////////////////////////////////////// ////////////////////////////////////////////
// ttl_irregular_chain_flag is set by the user if the TTL/Hop Limit rtp_baseheader(profile, ts_stride_value, time_stride_value,
// of an outer header. The same value must be passed as an argument outer_ip_flag, repair_flag)
// to the ipv4/ipv6 encoding methods when extracting the irregular
// chain items. The same applies to the tos_irregular_chain_flag
rtp_baseheader(profile, ts_stride_value,
ttl_irregular_chain_flag, tos_irregular_chain_flag)
{ {
UNCOMPRESSED v4 { UNCOMPRESSED v4 {
ENFORCE(msn.UVALUE == sequence_number.UVALUE);
outer_headers =:= baseheader_outer_headers [ VARIABLE ]; outer_headers =:= baseheader_outer_headers [ VARIABLE ];
version =:= uncompressed_value(4, 4) [ 4 ]; ip_version =:= uncompressed_value(4, 4) [ 4 ];
header_length =:= uncompressed_value(4, 5) [ 4 ]; header_length =:= uncompressed_value(4, 5) [ 4 ];
tos_tc [ 8 ]; tos_tc [ 8 ];
length [ 16 ]; length =:= inferred_ip_v4_length [ 16 ];
ip_id [ 16 ]; ip_id [ 16 ];
rf =:= uncompressed_value(1, 0) [ 1 ]; rf =:= uncompressed_value(1, 0) [ 1 ];
df [ 1 ]; df [ 1 ];
mf =:= uncompressed_value(1, 0) [ 1 ]; mf =:= uncompressed_value(1, 0) [ 1 ];
frag_offset =:= uncompressed_value(13, 0) [ 13 ]; frag_offset =:= uncompressed_value(13, 0) [ 13 ];
ttl_hopl [ 8 ]; ttl_hopl [ 8 ];
next_header [ 8 ]; next_header [ 8 ];
checksum [ 16 ]; ip_checksum =:= inferred_ip_v4_header_checksum [ 16 ];
src_addr [ 32 ]; src_addr [ 32 ];
dest_addr [ 32 ]; dest_addr [ 32 ];
extension_headers =:= baseheader_extension_headers [ VARIABLE ]; extension_headers =:= baseheader_extension_headers [ VARIABLE ];
src_port [ 16 ]; src_port [ 16 ];
dst_port [ 16 ]; dst_port [ 16 ];
udp_length [ 16 ]; udp_length =:= inferred_udp_length [ 16 ];
checksum [ 16 ]; udp_checksum [ 16 ];
rtp_version =:= uncompressed_value(2, 0) [ 2 ]; rtp_version =:= uncompressed_value(2, 2) [ 2 ];
pad_bit [ 1 ]; pad_bit [ 1 ];
extension [ 1 ]; extension [ 1 ];
cc [ 4 ]; cc [ 4 ];
marker [ 1 ]; marker [ 1 ];
payload_type [ 7 ]; payload_type [ 7 ];
sequence_number [ 16 ]; sequence_number [ 16 ];
timestamp [ 32 ]; timestamp [ 32 ];
ssrc [ 32 ]; ssrc [ 32 ];
csrc_list [ VARIABLE ]; csrc_list [ VARIABLE ];
ENFORCE(msn.UVALUE == sequence_number.UVALUE);
} }
UNCOMPRESSED v6 { UNCOMPRESSED v6 {
ENFORCE(ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_RANDOM);
ENFORCE(msn.UVALUE == sequence_number.UVALUE);
outer_headers =:= baseheader_outer_headers [ VARIABLE ]; outer_headers =:= baseheader_outer_headers [ VARIABLE ];
version =:= uncompressed_value(4, 6) [ 4 ]; ip_version =:= uncompressed_value(4, 6) [ 4 ];
tos_tc [ 8 ]; tos_tc [ 8 ];
flow_label [ 20 ]; flow_label [ 20 ];
payload_length [ 16 ]; payload_length =:= inferred_ip_v6_length [ 16 ];
next_header [ 8 ]; next_header [ 8 ];
ttl_hopl [ 8 ]; ttl_hopl [ 8 ];
src_addr [ 128 ]; src_addr [ 128 ];
dest_addr [ 128 ]; dest_addr [ 128 ];
extension_headers =:= baseheader_extension_headers [ VARIABLE ]; extension_headers =:= baseheader_extension_headers [ VARIABLE ];
src_port [ 16 ]; src_port [ 16 ];
dst_port [ 16 ]; dst_port [ 16 ];
udp_length [ 16 ]; udp_length =:= inferred_udp_length [ 16 ];
checksum [ 16 ]; udp_checksum [ 16 ];
rtp_version =:= uncompressed_value(2, 0) [ 2 ]; rtp_version =:= uncompressed_value(2, 2) [ 2 ];
pad_bit [ 1 ]; pad_bit [ 1 ];
extension [ 1 ]; extension [ 1 ];
cc [ 4 ]; cc [ 4 ];
marker [ 1 ]; marker [ 1 ];
payload_type [ 7 ]; payload_type [ 7 ];
sequence_number [ 16 ]; sequence_number [ 16 ];
timestamp [ 32 ]; timestamp [ 32 ];
ssrc [ 32 ]; ssrc [ 32 ];
csrc_list [ VARIABLE ]; csrc_list [ VARIABLE ];
ENFORCE(ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_RANDOM);
ENFORCE(msn.UVALUE == sequence_number.UVALUE);
} }
CONTROL { CONTROL {
// The ts_stride has an initial UVALUE=1, which means that it ENFORCE(time_stride_value == time_stride.UVALUE);
// can be encoded with 'static' even if it has not been ENFORCE(ts_stride.UVALUE == ts_stride_value);
// previously established in the context. ENFORCE(profile == PROFILE_RTP_0101);
ts_stride [ 32 ]; ts_stride [ 32 ];
time_stride [ 32 ];
ts_scaled [ 32 ]; ts_scaled [ 32 ];
ts_offset =:= ts_offset =:= field_scaling(ts_stride.UVALUE, ts_scaled.UVALUE,
field_scaling(ts_stride.UVALUE, ts_scaled.UVALUE,
timestamp.UVALUE) [ 32 ]; timestamp.UVALUE) [ 32 ];
ip_id_behavior [ 2 ]; ip_id_behavior [ 2 ];
ENFORCE(ts_stride.UVALUE == ts_stride_value); }
ENFORCE(profile == PROFILE_RTP_0101);
INITIAL {
ts_stride =:= uncompressed_value(32, 0);
time_stride =:= uncompressed_value(32, 0);
} }
DEFAULT { DEFAULT {
ENFORCE(outer_ip_flag == 0);
ENFORCE(repair_flag == 0);
tos_tc =:= static; tos_tc =:= static;
dest_addr =:= static; dest_addr =:= static;
version =:= static;
ttl_hopl =:= static; ttl_hopl =:= static;
src_addr =:= static; src_addr =:= static;
df =:= static; df =:= static;
ip_id_behavior =:= static; ip_id_behavior =:= static;
payload_length =:= inferred_ip_v6_length;
checksum =:= inferred_ip_v4_header_checksum;
length =:= inferred_ip_v4_length;
flow_label =:= static; flow_label =:= static;
next_header =:= static; next_header =:= static;
src_port =:= static; src_port =:= static;
dst_port =:= static; dst_port =:= static;
udp_length =:= inferred_udp_length; udp_checksum =:= irregular(16);
checksum =:= irregular(16);
pad_bit =:= static; pad_bit =:= static;
extension =:= static; extension =:= static;
cc =:= static; cc =:= static;
// When marker not present in packets, it is assumed 0 // When marker not present in packets, it is assumed 0
marker =:= uncompressed_value(1, 0); marker =:= uncompressed_value(1, 0);
payload_type =:= static; payload_type =:= static;
sequence_number =:= static; sequence_number =:= static;
timestamp =:= static; timestamp =:= static;
ssrc =:= static; ssrc =:= static;
csrc_list =:= static; csrc_list =:= static;
ENFORCE(ttl_irregular_chain_flag == 0);
ENFORCE(tos_irregular_chain_flag == 0);
} }
// Replacement for UOR-2-ext3 // Replacement for UOR-2-ext3
COMPRESSED co_common { COMPRESSED co_common {
discriminator =:= '1111101' [ 7 ]; ENFORCE(repair_flag == 0);
ENFORCE(outer_ip_flag == outer_ip_indicator.CVALUE);
ENFORCE(repair_flag == repair_indicator.CVALUE);
discriminator =:= '11111010' [ 8 ];
marker =:= irregular(1) [ 1 ]; marker =:= irregular(1) [ 1 ];
header_crc =:= crc7(THIS.UVALUE, THIS.ULENGTH) [ 7 ]; header_crc =:= crc7(THIS.UVALUE, THIS.ULENGTH) [ 7 ];
flags1_indicator =:= irregular(1) [ 1 ];
flags2_indicator =:= irregular(1) [ 1 ];
tsc_indicator =:= irregular(1) [ 1 ];
tss_indicator =:= irregular(1) [ 1 ];
ip_id_indicator =:= irregular(1) [ 1 ]; ip_id_indicator =:= irregular(1) [ 1 ];
ip_id_behavior =:= ip_id_behavior_choice [ 2 ]; control_crc3 =:= control_crc3_encoding [ 3 ];
reorder_ratio =:= reorder_choice [ 2 ];
df =:= dont_fragment(version.UVALUE) [ 1 ]; outer_ip_indicator : repair_indicator : ttl_hopl_indicator :
control_crc3 =:= control_crc3 [ 3 ]; tos_tc_indicator : ip_id_behavior : reorder_ratio =:=
ttl_hopl_outer_flag =:= irregular(1) [ 1 ]; profile_1_7_flags1_enc(flags1_indicator.CVALUE) [ 0, 8 ];
ttl_hopl_present =:= irregular(1) [ 1 ]; list_indicator : pt_indicator : tis_indicator :pad_bit :
tos_tc_outer_flag =:= irregular(1) [ 1 ]; extension : df =:= profile_1_flags2_enc(flags2_indicator.CVALUE,
tos_tc_present =:= irregular(1) [ 1 ]; ip_version.UVALUE) [ 0, 8 ];
ts_indicator =:= irregular(1) [ 1 ]; ip_id =:= optional_ip_id_lsb(ip_id_behavior.UVALUE,
ip_id_indicator.CVALUE) [ 0, 8, 16 ];
tos_tc =:= static_or_irreg(tos_tc_indicator.CVALUE, 8) [ 0, 8 ];
ttl_hopl =:= static_or_irreg(ttl_hopl_indicator.CVALUE,
ttl_hopl.ULENGTH) [ 0, 8 ];
payload_type =:= optional_pt(pt_indicator) [ 0, 8 ];
sequence_number =:= sdvl_lsb(sequence_number.ULENGTH) [ VARIABLE ];
ts_scaled =:= variable_scaled_timestamp(tss_indicator.CVALUE,
tsc_indicator, ts_stride.UVALUE) [ VARIABLE ];
timestamp =:= variable_unscaled_timestamp(tss_indicator.CVALUE,
tsc_indicator) [ VARIABLE ];
ts_stride =:= sdvl_or_static(tss_indicator.CVALUE) [ VARIABLE ];
time_stride =:= sdvl_or_static(tis_indicator.CVALUE) [ VARIABLE ];
csrc_list =:= csrc_list_presence(list_indicator.CVALUE,
cc.UVALUE) [ VARIABLE ];
}
// Context repair (IR-DYN replacement).
COMPRESSED co_repair {
ENFORCE(outer_ip_flag == outer_ip_indicator.CVALUE);
ENFORCE(repair_flag == repair_indicator.CVALUE);
discriminator =:= '11111011' [ 8 ];
marker =:= irregular(1) [ 1 ];
header_crc =:= crc7(THIS.UVALUE, THIS.ULENGTH) [ 7 ];
flags1_indicator =:= irregular(1) [ 1 ];
flags2_indicator =:= irregular(1) [ 1 ];
timestamp_indicator =:= irregular(1) [ 1 ];
tss_indicator =:= irregular(1) [ 1 ]; tss_indicator =:= irregular(1) [ 1 ];
pt_present =:= irregular(1) [ 1 ]; ip_id_indicator =:= irregular(1) [ 1 ];
list_present =:= irregular(1) [ 1 ]; control_crc3 =:= control_crc3_encoding [ 3 ];
pad_bit =:= irregular(1) [ 1 ];
extension =:= irregular(1) [ 1 ]; outer_ip_indicator : repair_indicator : ttl_hopl_indicator :
reserved =:= compressed_value(6, 0) [ 6 ]; tos_tc_indicator : ip_id_behavior : reorder_ratio =:=
ip_id =:= profile_1_7_flags1_enc(flags1_indicator.CVALUE) [ 0, 8 ];
optional_ip_id_lsb(ip_id_behavior.UVALUE, list_indicator : pt_indicator : pad_bit : extension : df :
tis_indicator =:= profile_1_flags2_enc(flags2_indicator.CVALUE,
ip_version.UVALUE) [ 0, 8 ];
ip_id =:= optional_ip_id_lsb(ip_id_behavior.UVALUE,
ip_id_indicator.CVALUE) [ 0, 8, 16 ]; ip_id_indicator.CVALUE) [ 0, 8, 16 ];
tos_tc =:= tos_tc =:=
tos_tc_enc(tos_tc_present.CVALUE) [ 0, 8 ]; static_or_irreg(tos_tc_indicator.CVALUE, 8) [ 0, 8 ];
ttl_hopl =:= ttl_hopl =:= static_or_irreg(ttl_hopl_indicator.CVALUE,
static_or_irreg(ttl_hopl_present.CVALUE,
ttl_hopl.ULENGTH) [ 0, 8 ]; ttl_hopl.ULENGTH) [ 0, 8 ];
sequence_number =:= sdvl(sequence_number.ULENGTH) [ 8, 16 ]; payload_type =:= optional_pt(pt_indicator) [ 0, 8 ];
// Either scaled or unscaled timestamp sequence_number =:= irregular(16) [ 16 ];
ts_scaled =:= timestamp =:=
optional_scaled_timestamp(tss_indicator, irregular_or_nothing(timestamp_indicator) [ 0, 32 ];
tsc_indicator) [ VARIABLE ];
ts_scaled =:=
optional_scaled_timestamp(tss_indicator,
tsc_indicator) [ VARIABLE ];
payload_type =:= optional_pt(pt_present) [ 0, 8 ];
ts_stride =:= ts_stride =:=
optional_stride(tss_indicator, sdvl_or_static(tss_indicator) [ VARIABLE ];
ts_stride_value) [ VARIABLE ]; time_stride =:=
csrc_list =:= list_csrc(cc.UVALUE) [ VARIABLE ]; sdvl_or_static(tis_indicator) [ VARIABLE ];
csrc_list =:=
ENFORCE(ttl_irregular_chain_flag == ttl_hopl_outer_flag.UVALUE); csrc_list_presence(list_indicator.CVALUE, cc.UVALUE) [ VARIABLE ];
ENFORCE(tos_irregular_chain_flag == tos_tc_outer_flag.UVALUE);
} }
// UO-0 // UO-0
COMPRESSED pt_0_crc3 { COMPRESSED pt_0_crc3 {
discriminator =:= '0' [ 1 ]; discriminator =:= '0' [ 1 ];
msn =:= msn_lsb(4, 4) [ 4 ]; msn =:= msn_lsb(4) [ 4 ];
header_crc =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ]; header_crc =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ];
timestamp =:= inferred_scaled_field [ 0 ]; timestamp =:= inferred_scaled_field [ 0 ];
ip_id =:= inferred_sequential_ip_id [ 0 ]; ip_id =:= inferred_sequential_ip_id [ 0 ];
} }
// New format, Type 0 with strong CRC and more SN bits // New format, Type 0 with strong CRC and more SN bits
COMPRESSED pt_0_crc7 { COMPRESSED pt_0_crc7 {
discriminator =:= '100' [ 3 ]; discriminator =:= '100' [ 3 ];
msn =:= msn_lsb(6, 16) [ 6 ]; msn =:= msn_lsb(6) [ 6 ];
header_crc =:= crc7(THIS.UVALUE, THIS.ULENGTH) [ 7 ]; header_crc =:= crc7(THIS.UVALUE, THIS.ULENGTH) [ 7 ];
timestamp =:= inferred_scaled_field [ 0 ]; timestamp =:= inferred_scaled_field [ 0 ];
ip_id =:= inferred_sequential_ip_id [ 0 ]; ip_id =:= inferred_sequential_ip_id [ 0 ];
} }
// UO-1 replacement // UO-1 replacement
COMPRESSED pt_1_rnd { COMPRESSED pt_1_rnd {
ENFORCE(ts_stride.UVALUE != 0);
ENFORCE((ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_RANDOM) ||
(ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_ZERO));
discriminator =:= '101' [ 3 ]; discriminator =:= '101' [ 3 ];
msn =:= msn_lsb(5, 8) [ 5 ]; msn =:= msn_lsb(5) [ 5 ];
marker =:= irregular(1) [ 1 ]; marker =:= irregular(1) [ 1 ];
ts_scaled =:= lsb(4, 3) [ 4 ]; ts_scaled =:= scaled_ts_lsb(time_stride.UVALUE, 4) [ 4 ];
header_crc =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ]; 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));
} }
// UO-1-ID replacement // UO-1-ID replacement
COMPRESSED pt_1_seq_id { COMPRESSED pt_1_seq_id {
discriminator =:= '1010' [ 4 ];
header_crc =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ];
msn =:= msn_lsb(5, 8) [ 5 ];
ip_id =:= ip_id_lsb(ip_id_behavior.UVALUE, 4, 3) [ 4 ];
timestamp =:= inferred_scaled_field [ 0 ];
ENFORCE((ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_SEQUENTIAL) || ENFORCE((ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_SEQUENTIAL) ||
(ip_id_behavior.UVALUE == (ip_id_behavior.UVALUE ==
IP_ID_BEHAVIOR_SEQUENTIAL_SWAPPED)); IP_ID_BEHAVIOR_SEQUENTIAL_SWAPPED));
discriminator =:= '1010' [ 4 ];
header_crc =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ];
msn =:= msn_lsb(5) [ 5 ];
ip_id =:= ip_id_lsb(ip_id_behavior.UVALUE, 4) [ 4 ];
timestamp =:= inferred_scaled_field [ 0 ];
} }
// UO-1-TS replacement // UO-1-TS replacement
COMPRESSED pt_1_seq_ts { COMPRESSED pt_1_seq_ts {
discriminator =:= '1011' [ 4 ]; ENFORCE(ts_stride.UVALUE != 0);
marker =:= irregular(1) [ 1 ];
header_crc =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ];
msn =:= msn_lsb(4, 4) [ 4 ];
ts_scaled =:= lsb(4, 3) [ 4 ];
ENFORCE((ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_SEQUENTIAL) || ENFORCE((ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_SEQUENTIAL) ||
(ip_id_behavior.UVALUE == (ip_id_behavior.UVALUE ==
IP_ID_BEHAVIOR_SEQUENTIAL_SWAPPED)); IP_ID_BEHAVIOR_SEQUENTIAL_SWAPPED));
discriminator =:= '1011' [ 4 ];
marker =:= irregular(1) [ 1 ];
header_crc =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ];
msn =:= msn_lsb(4) [ 4 ];
ts_scaled =:= scaled_ts_lsb(time_stride.UVALUE, 4) [ 4 ];
} }
// UOR-2 replacement // UOR-2 replacement
COMPRESSED pt_2_rnd { COMPRESSED pt_2_rnd {
ENFORCE(ts_stride.UVALUE != 0);
ENFORCE((ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_RANDOM) ||
(ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_ZERO));
discriminator =:= '110' [ 3 ]; discriminator =:= '110' [ 3 ];
msn =:= msn_lsb(7, 32) [ 7 ]; msn =:= msn_lsb(7) [ 7 ];
ts_scaled =:= lsb(6, 15) [ 6 ]; ts_scaled =:= scaled_ts_lsb(time_stride.UVALUE, 6) [ 6 ];
marker =:= irregular(1) [ 1 ]; marker =:= irregular(1) [ 1 ];
header_crc =:= crc7(THIS.UVALUE, THIS.ULENGTH) [ 7 ]; header_crc =:= crc7(THIS.UVALUE, THIS.ULENGTH) [ 7 ];
ENFORCE((ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_RANDOM) ||
(ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_ZERO));
} }
// UOR-2-ID replacement // UOR-2-ID replacement
COMPRESSED pt_2_seq_id { COMPRESSED pt_2_seq_id {
discriminator =:= '1100' [ 4 ]; ENFORCE((ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_SEQUENTIAL) ||
msn =:= msn_lsb(7, 32) [ 7 ]; (ip_id_behavior.UVALUE ==
ip_id =:= ip_id_lsb(ip_id_behavior.UVALUE, 6, 3) [ 6 ]; IP_ID_BEHAVIOR_SEQUENTIAL_SWAPPED));
discriminator =:= '11000' [ 5 ];
msn =:= msn_lsb(7) [ 7 ];
ip_id =:= ip_id_lsb(ip_id_behavior.UVALUE, 5) [ 5 ];
header_crc =:= crc7(THIS.UVALUE, THIS.ULENGTH) [ 7 ]; header_crc =:= crc7(THIS.UVALUE, THIS.ULENGTH) [ 7 ];
timestamp =:= inferred_scaled_field [ 0 ]; timestamp =:= inferred_scaled_field [ 0 ];
}
// UOR-2-ID-ext1 replacement (both TS and IP-ID)
COMPRESSED pt_2_seq_both {
ENFORCE(ts_stride.UVALUE != 0);
ENFORCE((ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_SEQUENTIAL) || ENFORCE((ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_SEQUENTIAL) ||
(ip_id_behavior.UVALUE == (ip_id_behavior.UVALUE ==
IP_ID_BEHAVIOR_SEQUENTIAL_SWAPPED)); IP_ID_BEHAVIOR_SEQUENTIAL_SWAPPED));
discriminator =:= '11001' [ 5 ];
msn =:= msn_lsb(7) [ 7 ];
ip_id =:= ip_id_lsb(ip_id_behavior.UVALUE, 5) [ 5 ];
header_crc =:= crc7(THIS.UVALUE, THIS.ULENGTH) [ 7 ];
ts_scaled =:= scaled_ts_lsb(time_stride.UVALUE, 8) [ 8 ];
} }
// UOR-2-TS replacement // UOR-2-TS replacement
COMPRESSED pt_2_seq_ts { COMPRESSED pt_2_seq_ts {
discriminator =:= '1101' [ 4 ]; ENFORCE(ts_stride.UVALUE != 0);
msn =:= msn_lsb(7, 32) [ 7 ];
ts_scaled =:= lsb(5, 7) [ 5 ];
marker =:= irregular(1) [ 1 ];
header_crc =:= crc7(THIS.UVALUE, THIS.ULENGTH) [ 7 ];
ENFORCE((ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_SEQUENTIAL) || ENFORCE((ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_SEQUENTIAL) ||
(ip_id_behavior.UVALUE == (ip_id_behavior.UVALUE ==
IP_ID_BEHAVIOR_SEQUENTIAL_SWAPPED)); IP_ID_BEHAVIOR_SEQUENTIAL_SWAPPED));
discriminator =:= '1101' [ 4 ];
msn =:= msn_lsb(7) [ 7 ];
ts_scaled =:= scaled_ts_lsb(time_stride.UVALUE, 5) [ 5 ];
marker =:= irregular(1) [ 1 ];
header_crc =:= crc7(THIS.UVALUE, THIS.ULENGTH) [ 7 ];
} }
} }
//////////////////////////////////////////// ////////////////////////////////////////////
// UDP profile // UDP profile
//////////////////////////////////////////// ////////////////////////////////////////////
// ttl_irregular_chain_flag is set by the user if the TTL/Hop Limit udp_baseheader(profile, outer_ip_flag, repair_flag)
// of an outer header. The same value must be passed as an argument
// to the ipv4/ipv6 encoding methods when extracting the irregular
// chain items. The same applies to the tos_irregular_chain_flag
udp_baseheader(profile,
ttl_irregular_chain_flag, tos_irregular_chain_flag)
{ {
UNCOMPRESSED v4 { UNCOMPRESSED v4 {
outer_headers =:= baseheader_outer_headers [ VARIABLE ]; outer_headers =:= baseheader_outer_headers [ VARIABLE ];
version =:= uncompressed_value(4, 4) [ 4 ]; ip_version =:= uncompressed_value(4, 4) [ 4 ];
header_length =:= uncompressed_value(4, 5) [ 4 ]; header_length =:= uncompressed_value(4, 5) [ 4 ];
tos_tc [ 8 ]; tos_tc [ 8 ];
length [ 16 ]; length =:= inferred_ip_v4_length [ 16 ];
ip_id [ 16 ]; ip_id [ 16 ];
rf =:= uncompressed_value(1, 0) [ 1 ]; rf =:= uncompressed_value(1, 0) [ 1 ];
df [ 1 ]; df [ 1 ];
mf =:= uncompressed_value(1, 0) [ 1 ]; mf =:= uncompressed_value(1, 0) [ 1 ];
frag_offset =:= uncompressed_value(13, 0) [ 13 ]; frag_offset =:= uncompressed_value(13, 0) [ 13 ];
ttl_hopl [ 8 ]; ttl_hopl [ 8 ];
next_header [ 8 ]; next_header [ 8 ];
checksum [ 16 ]; ip_checksum =:= inferred_ip_v4_header_checksum [ 16 ];
src_addr [ 32 ]; src_addr [ 32 ];
dest_addr [ 32 ]; dest_addr [ 32 ];
extension_headers =:= baseheader_extension_headers [ VARIABLE ]; extension_headers =:= baseheader_extension_headers [ VARIABLE ];
src_port [ 16 ]; src_port [ 16 ];
dst_port [ 16 ]; dst_port [ 16 ];
udp_length [ 16 ]; udp_length =:= inferred_udp_length [ 16 ];
checksum [ 16 ]; udp_checksum [ 16 ];
} }
UNCOMPRESSED v6 { UNCOMPRESSED v6 {
ENFORCE(ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_RANDOM);
outer_headers =:= baseheader_outer_headers [ VARIABLE ]; outer_headers =:= baseheader_outer_headers [ VARIABLE ];
version =:= uncompressed_value(4, 6) [ 4 ]; ip_version =:= uncompressed_value(4, 6) [ 4 ];
version [ 4 ];
tos_tc [ 8 ]; tos_tc [ 8 ];
flow_label [ 20 ]; flow_label [ 20 ];
payload_length [ 16 ]; payload_length =:= inferred_ip_v6_length [ 16 ];
next_header [ 8 ]; next_header [ 8 ];
ttl_hopl [ 8 ]; ttl_hopl [ 8 ];
src_addr [ 128 ]; src_addr [ 128 ];
dest_addr [ 128 ]; dest_addr [ 128 ];
extension_headers =:= baseheader_extension_headers [ VARIABLE ]; extension_headers =:= baseheader_extension_headers [ VARIABLE ];
src_port [ 16 ]; src_port [ 16 ];
dst_port [ 16 ]; dst_port [ 16 ];
udp_length [ 16 ]; udp_length =:= inferred_udp_length [ 16 ];
checksum [ 16 ]; udp_checksum [ 16 ];
ENFORCE(ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_RANDOM);
} }
CONTROL { CONTROL {
ip_id_behavior [ 2 ];
ENFORCE(profile == PROFILE_UDP_0102); ENFORCE(profile == PROFILE_UDP_0102);
ip_id_behavior [ 2 ];
} }
DEFAULT { DEFAULT {
ENFORCE(outer_ip_flag == 0);
ENFORCE(repair_flag == 0);
tos_tc =:= static; tos_tc =:= static;
dest_addr =:= static; dest_addr =:= static;
version =:= static; ip_version =:= static;
ttl_hopl =:= static; ttl_hopl =:= static;
src_addr =:= static; src_addr =:= static;
df =:= static; df =:= static;
ip_id_behavior =:= static; ip_id_behavior =:= static;
payload_length =:= inferred_ip_v6_length;
checksum =:= inferred_ip_v4_header_checksum;
length =:= inferred_ip_v4_length;
flow_label =:= static; flow_label =:= static;
next_header =:= static; next_header =:= static;
src_port =:= static; src_port =:= static;
dst_port =:= static; dst_port =:= static;
udp_length =:= inferred_udp_length; udp_checksum =:= irregular(16);
checksum =:= irregular(16);
ENFORCE(ttl_irregular_chain_flag == 0);
ENFORCE(tos_irregular_chain_flag == 0);
} }
// Replacement for UOR-2-ext3 // Replacement for UOR-2-ext3
COMPRESSED co_common { COMPRESSED co_common {
discriminator =:= '1111101' [ 7 ]; ENFORCE(repair_flag == 0);
ENFORCE(outer_ip_flag == outer_ip_indicator.CVALUE);
ENFORCE(repair_flag == repair_indicator.CVALUE);
discriminator =:= '11111010' [ 8 ];
ip_id_indicator =:= irregular(1) [ 1 ]; ip_id_indicator =:= irregular(1) [ 1 ];
reorder_ratio =:= reorder_choice [ 2 ];
msn =:= msn_lsb(6, 16) [ 6 ];
df =:= dont_fragment(version.UVALUE) [ 1 ];
header_crc =:= crc7(THIS.UVALUE, THIS.ULENGTH) [ 7 ]; header_crc =:= crc7(THIS.UVALUE, THIS.ULENGTH) [ 7 ];
ttl_hopl_outer_flag =:= irregular(1) [ 1 ]; flags_indicator =:= irregular(1) [ 1 ];
ttl_hopl_present =:= irregular(1) [ 1 ]; ttl_hopl_indicator =:= irregular(1) [ 1 ];
tos_tc_outer_flag =:= irregular(1) [ 1 ]; tos_tc_indicator =:= irregular(1) [ 1 ];
ip_id_behavior =:= ip_id_behavior_choice [ 2 ]; reorder_ratio =:= reorder_choice [ 2 ];
control_crc3 =:= control_crc3 [ 3 ]; control_crc3 =:= control_crc3_encoding [ 3 ];
tos_tc_present =:= irregular(1) [ 1 ]; outer_ip_indicator : repair_indicator : df :
reserved =:= compressed_value(7, 0) [ 7 ]; ip_id_behavior =:= profile_2_3_4_flags_enc(
ip_id =:= flags_indicator.CVALUE, ip_version.UVALUE) [ 0, 8 ];
optional_ip_id_lsb(ip_id_behavior.UVALUE, ip_id =:= optional_ip_id_lsb(ip_id_behavior.UVALUE,
ip_id_indicator.CVALUE) [ 0, 8, 16 ]; ip_id_indicator.CVALUE) [ 0, 8, 16 ];
tos_tc =:= tos_tc =:= static_or_irreg(tos_tc_indicator.CVALUE, 8) [ 0, 8 ];
tos_tc_enc(tos_tc_present.CVALUE) [ 0, 8 ]; ttl_hopl =:= static_or_irreg(ttl_hopl_indicator.CVALUE,
ttl_hopl =:=
static_or_irreg(ttl_hopl_present.CVALUE,
ttl_hopl.ULENGTH) [ 0, 8 ]; ttl_hopl.ULENGTH) [ 0, 8 ];
msn =:= msn_lsb(8) [ 8 ];
}
ENFORCE(ttl_irregular_chain_flag == ttl_hopl_outer_flag.UVALUE); // Context repair (IR-DYN replacement).
ENFORCE(tos_irregular_chain_flag == tos_tc_outer_flag.UVALUE); COMPRESSED co_repair {
ENFORCE(outer_ip_flag == outer_ip_indicator.CVALUE);
ENFORCE(repair_flag == repair_indicator.CVALUE);
discriminator =:= '11111011' [ 8 ];
ip_id_indicator =:= irregular(1) [ 1 ];
header_crc =:= crc7(THIS.UVALUE, THIS.ULENGTH) [ 7 ];
flags_indicator =:= irregular(1) [ 1 ];
ttl_hopl_indicator =:= irregular(1) [ 1 ];
tos_tc_indicator =:= irregular(1) [ 1 ];
reorder_ratio =:= reorder_choice [ 2 ];
control_crc3 =:= control_crc3_encoding [ 3 ];
outer_ip_indicator : repair_indicator : df :
ip_id_behavior =:= profile_2_3_4_flags_enc(
flags_indicator.CVALUE, ip_version.UVALUE) [ 0, 8 ];
ip_id =:= optional_ip_id_lsb(ip_id_behavior.UVALUE,
ip_id_indicator.CVALUE) [ 0, 8, 16 ];
tos_tc =:= static_or_irreg(tos_tc_indicator.CVALUE, 8) [ 0, 8 ];
ttl_hopl =:= static_or_irreg(ttl_hopl_indicator.CVALUE,
ttl_hopl.ULENGTH) [ 0, 8 ];
msn =:= irregular(16) [ 16 ];
} }
// UO-0 // UO-0
COMPRESSED pt_0_crc3 { COMPRESSED pt_0_crc3 {
discriminator =:= '0' [ 1 ]; discriminator =:= '0' [ 1 ];
msn =:= msn_lsb(4, 4) [ 4 ]; msn =:= msn_lsb(4) [ 4 ];
header_crc =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ]; header_crc =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ];
ip_id =:= inferred_sequential_ip_id [ 0 ]; ip_id =:= inferred_sequential_ip_id [ 0 ];
} }
// New format, Type 0 with strong CRC and more SN bits // New format, Type 0 with strong CRC and more SN bits
COMPRESSED pt_0_crc7 { COMPRESSED pt_0_crc7 {
discriminator =:= '100' [ 3 ]; discriminator =:= '100' [ 3 ];
msn =:= msn_lsb(6, 16) [ 6 ]; msn =:= msn_lsb(6) [ 6 ];
header_crc =:= crc7(THIS.UVALUE, THIS.ULENGTH) [ 7 ]; header_crc =:= crc7(THIS.UVALUE, THIS.ULENGTH) [ 7 ];
ip_id =:= inferred_sequential_ip_id [ 0 ]; ip_id =:= inferred_sequential_ip_id [ 0 ];
} }
// UO-1-ID replacement (PT-1 only used for sequential) // UO-1-ID replacement (PT-1 only used for sequential)
COMPRESSED pt_1_seq_id { COMPRESSED pt_1_seq_id {
discriminator =:= '101' [ 3 ];
header_crc =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ];
msn =:= msn_lsb(6, 16) [ 6 ];
ip_id =:= ip_id_lsb(ip_id_behavior.UVALUE, 4, 3) [ 4 ];
ENFORCE((ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_SEQUENTIAL) || ENFORCE((ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_SEQUENTIAL) ||
(ip_id_behavior.UVALUE == (ip_id_behavior.UVALUE ==
IP_ID_BEHAVIOR_SEQUENTIAL_SWAPPED)); IP_ID_BEHAVIOR_SEQUENTIAL_SWAPPED));
discriminator =:= '101' [ 3 ];
header_crc =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ];
msn =:= msn_lsb(6) [ 6 ];
ip_id =:= ip_id_lsb(ip_id_behavior.UVALUE, 4) [ 4 ];
} }
// UOR-2 replacement // UOR-2 replacement
COMPRESSED pt_2_rnd { COMPRESSED pt_2_rnd {
discriminator =:= '110' [ 3 ];
msn =:= msn_lsb(6, 16) [ 6 ];
header_crc =:= crc7(THIS.UVALUE, THIS.ULENGTH) [ 7 ];
ENFORCE((ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_RANDOM) || ENFORCE((ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_RANDOM) ||
(ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_ZERO)); (ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_ZERO));
discriminator =:= '110' [ 3 ];
msn =:= msn_lsb(6) [ 6 ];
header_crc =:= crc7(THIS.UVALUE, THIS.ULENGTH) [ 7 ];
} }
// UOR-2-ID replacement // UOR-2-ID replacement
COMPRESSED pt_2_seq_id { COMPRESSED pt_2_seq_id {
discriminator =:= '1100' [ 4 ];
ip_id =:= ip_id_lsb(ip_id_behavior.UVALUE, 5, 3) [ 5 ];
header_crc =:= crc7(THIS.UVALUE, THIS.ULENGTH) [ 7 ];
msn =:= msn_lsb(8, 64) [ 8 ];
ENFORCE((ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_SEQUENTIAL) || ENFORCE((ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_SEQUENTIAL) ||
(ip_id_behavior.UVALUE == (ip_id_behavior.UVALUE ==
IP_ID_BEHAVIOR_SEQUENTIAL_SWAPPED)); IP_ID_BEHAVIOR_SEQUENTIAL_SWAPPED));
discriminator =:= '1100' [ 4 ];
ip_id =:= ip_id_lsb(ip_id_behavior.UVALUE, 5) [ 5 ];
header_crc =:= crc7(THIS.UVALUE, THIS.ULENGTH) [ 7 ];
msn =:= msn_lsb(8) [ 8 ];
} }
} }
//////////////////////////////////////////// ////////////////////////////////////////////
// ESP profile // ESP profile
//////////////////////////////////////////// ////////////////////////////////////////////
// ttl_irregular_chain_flag is set by the user if the TTL/Hop Limit esp_baseheader(profile, outer_ip_flag, repair_flag)
// of an outer header. The same value must be passed as an argument
// to the ipv4/ipv6 encoding methods when extracting the irregular
// chain items. The same applies to the tos_irregular_chain_flag
esp_baseheader(profile,
ttl_irregular_chain_flag, tos_irregular_chain_flag)
{ {
UNCOMPRESSED v4 { UNCOMPRESSED v4 {
ENFORCE(msn.UVALUE == sequence_number.UVALUE % 65536);
outer_headers =:= baseheader_outer_headers [ VARIABLE ]; outer_headers =:= baseheader_outer_headers [ VARIABLE ];
version =:= uncompressed_value(4, 4) [ 4 ]; ip_version =:= uncompressed_value(4, 4) [ 4 ];
header_length =:= uncompressed_value(4, 5) [ 4 ]; header_length =:= uncompressed_value(4, 5) [ 4 ];
tos_tc [ 8 ]; tos_tc [ 8 ];
length [ 16 ]; length =:= inferred_ip_v4_length [ 16 ];
ip_id [ 16 ]; ip_id [ 16 ];
rf =:= uncompressed_value(1, 0) [ 1 ]; rf =:= uncompressed_value(1, 0) [ 1 ];
df [ 1 ]; df [ 1 ];
mf =:= uncompressed_value(1, 0) [ 1 ]; mf =:= uncompressed_value(1, 0) [ 1 ];
frag_offset =:= uncompressed_value(13, 0) [ 13 ]; frag_offset =:= uncompressed_value(13, 0) [ 13 ];
ttl_hopl [ 8 ]; ttl_hopl [ 8 ];
next_header [ 8 ]; next_header [ 8 ];
checksum [ 16 ]; ip_checksum =:= inferred_ip_v4_header_checksum [ 16 ];
src_addr [ 32 ]; src_addr [ 32 ];
dest_addr [ 32 ]; dest_addr [ 32 ];
extension_headers =:= baseheader_extension_headers [ VARIABLE ]; extension_headers =:= baseheader_extension_headers [ VARIABLE ];
spi [ 32 ]; spi [ 32 ];
sequence_number [ 32 ]; sequence_number [ 32 ];
ENFORCE(msn.UVALUE == sequence_number.UVALUE);
} }
UNCOMPRESSED v6 { UNCOMPRESSED v6 {
ENFORCE(msn.UVALUE == (sequence_number.UVALUE % 65536));
ENFORCE(ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_RANDOM);
outer_headers =:= baseheader_outer_headers [ VARIABLE ]; outer_headers =:= baseheader_outer_headers [ VARIABLE ];
version =:= uncompressed_value(4, 6) [ 4 ]; ip_version =:= uncompressed_value(4, 6) [ 4 ];
version [ 4 ];
tos_tc [ 8 ]; tos_tc [ 8 ];
flow_label [ 20 ]; flow_label [ 20 ];
payload_length [ 16 ]; payload_length =:= inferred_ip_v6_length [ 16 ];
next_header [ 8 ]; next_header [ 8 ];
ttl_hopl [ 8 ]; ttl_hopl [ 8 ];
src_addr [ 128 ]; src_addr [ 128 ];
dest_addr [ 128 ]; dest_addr [ 128 ];
extension_headers =:= baseheader_extension_headers [ VARIABLE ]; extension_headers =:= baseheader_extension_headers [ VARIABLE ];
spi [ 32 ]; spi [ 32 ];
sequence_number [ 32 ]; sequence_number [ 32 ];
ENFORCE(msn.UVALUE == (sequence_number.UVALUE % 65536));
ENFORCE(ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_RANDOM);
} }
CONTROL { CONTROL {
ip_id_behavior [ 2 ];
ENFORCE(profile == PROFILE_ESP_0103); ENFORCE(profile == PROFILE_ESP_0103);
ip_id_behavior [ 2 ];
} }
DEFAULT { DEFAULT {
ENFORCE(outer_ip_indicator == 0);
ENFORCE(repair_flag == 0);
tos_tc =:= static; tos_tc =:= static;
dest_addr =:= static; dest_addr =:= static;
version =:= static;
ttl_hopl =:= static; ttl_hopl =:= static;
src_addr =:= static; src_addr =:= static;
df =:= static; df =:= static;
ip_id_behavior =:= static; ip_id_behavior =:= static;
payload_length =:= inferred_ip_v6_length;
checksum =:= inferred_ip_v4_header_checksum;
length =:= inferred_ip_v4_length;
flow_label =:= static; flow_label =:= static;
next_header =:= static; next_header =:= static;
spi =:= static; spi =:= static;
sequence_number =:= static; sequence_number =:= static;
ENFORCE(ttl_irregular_chain_flag == 0);
ENFORCE(tos_irregular_chain_flag == 0);
} }
// Replacement for UOR-2-ext3 // Replacement for UOR-2-ext3
COMPRESSED co_common { COMPRESSED co_common {
discriminator =:= '1111101' [ 7 ]; ENFORCE(repair_flag == 0);
ENFORCE(outer_ip_flag == outer_ip_indicator.CVALUE);
ENFORCE(repair_flag == repair_indicator.CVALUE);
discriminator =:= '11111010' [ 8 ];
ip_id_indicator =:= irregular(1) [ 1 ]; ip_id_indicator =:= irregular(1) [ 1 ];
df =:= dont_fragment(version.UVALUE) [ 1 ];
header_crc =:= crc7(THIS.UVALUE, THIS.ULENGTH) [ 7 ]; header_crc =:= crc7(THIS.UVALUE, THIS.ULENGTH) [ 7 ];
ttl_hopl_outer_flag =:= irregular(1) [ 1 ]; flags_indicator =:= irregular(1) [ 1 ];
ttl_hopl_present =:= irregular(1) [ 1 ]; ttl_hopl_indicator =:= irregular(1) [ 1 ];
tos_tc_outer_flag =:= irregular(1) [ 1 ]; tos_tc_indicator =:= irregular(1) [ 1 ];
tos_tc_present =:= irregular(1) [ 1 ];
reorder_ratio =:= reorder_choice [ 2 ]; reorder_ratio =:= reorder_choice [ 2 ];
ip_id_behavior =:= ip_id_behavior_choice [ 2 ]; control_crc3 =:= control_crc3_encoding [ 3 ];
control_crc3 =:= control_crc3 [ 3 ];
reserved =:= compressed_value(5, 0) [ 5 ]; outer_ip_indicator : repair_indicator : df :
sequence_number =:= ip_id_behavior =:= profile_2_3_4_flags_enc(
sdvl(sequence_number.ULENGTH) [ 8, 16, 24, 32 ]; flags_indicator.CVALUE, ip_version.UVALUE) [ 0, 8 ];
ip_id =:= ip_id =:= optional_ip_id_lsb(ip_id_behavior.UVALUE,
optional_ip_id_lsb(ip_id_behavior.UVALUE,
ip_id_indicator.CVALUE) [ 0, 8, 16 ]; ip_id_indicator.CVALUE) [ 0, 8, 16 ];
tos_tc =:= tos_tc =:= static_or_irreg(tos_tc_indicator.CVALUE, 8) [ 0, 8 ];
tos_tc_enc(tos_tc_present.CVALUE) [ 0, 8 ]; ttl_hopl =:= static_or_irreg(ttl_hopl_indicator.CVALUE,
ttl_hopl =:=
static_or_irreg(ttl_hopl_present.CVALUE,
ttl_hopl.ULENGTH) [ 0, 8 ]; ttl_hopl.ULENGTH) [ 0, 8 ];
ENFORCE(ttl_irregular_chain_flag == ttl_hopl_outer_flag.UVALUE); sequence_number =:= sdvl_lsb(sequence_number.ULENGTH) [ VARIABLE ];
ENFORCE(tos_irregular_chain_flag == tos_tc_outer_flag.UVALUE); }
// Context repair (IR-DYN replacement).
COMPRESSED co_repair {
ENFORCE(outer_ip_flag == outer_ip_indicator.CVALUE);
ENFORCE(repair_flag == repair_indicator.CVALUE);
discriminator =:= '11111011' [ 8 ];
discriminator =:= '11111010' [ 8 ];
ip_id_indicator =:= irregular(1) [ 1 ];
header_crc =:= crc7(THIS.UVALUE, THIS.ULENGTH) [ 7 ];
flags_indicator =:= irregular(1) [ 1 ];
ttl_hopl_indicator =:= irregular(1) [ 1 ];
tos_tc_indicator =:= irregular(1) [ 1 ];
reorder_ratio =:= reorder_choice [ 2 ];
control_crc3 =:= control_crc3_encoding [ 3 ];
outer_ip_indicator : repair_indicator : df :
ip_id_behavior =:= profile_2_3_4_flags_enc(
flags_indicator.CVALUE, ip_version.UVALUE) [ 0, 8 ];
ip_id =:= optional_ip_id_lsb(ip_id_behavior.UVALUE,
ip_id_indicator.CVALUE) [ 0, 8, 16 ];
tos_tc =:= static_or_irreg(tos_tc_indicator.CVALUE, 8) [ 0, 8 ];
ttl_hopl =:= static_or_irreg(ttl_hopl_indicator.CVALUE,
ttl_hopl.ULENGTH) [ 0, 8 ];
sequence_number =:= irregular(32) [ 32 ];
} }
// UO-0 // UO-0
COMPRESSED pt_0_crc3 { COMPRESSED pt_0_crc3 {
discriminator =:= '0' [ 1 ]; discriminator =:= '0' [ 1 ];
msn =:= msn_lsb(4, 4) [ 4 ]; msn =:= msn_lsb(4) [ 4 ];
header_crc =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ]; header_crc =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ];
ip_id =:= inferred_sequential_ip_id [ 0 ]; ip_id =:= inferred_sequential_ip_id [ 0 ];
} }
// New format, Type 0 with strong CRC and more SN bits // New format, Type 0 with strong CRC and more SN bits
COMPRESSED pt_0_crc7 { COMPRESSED pt_0_crc7 {
discriminator =:= '100' [ 3 ]; discriminator =:= '100' [ 3 ];
msn =:= msn_lsb(6, 16) [ 6 ]; msn =:= msn_lsb(6) [ 6 ];
header_crc =:= crc7(THIS.UVALUE, THIS.ULENGTH) [ 7 ]; header_crc =:= crc7(THIS.UVALUE, THIS.ULENGTH) [ 7 ];
ip_id =:= inferred_sequential_ip_id [ 0 ]; ip_id =:= inferred_sequential_ip_id [ 0 ];
} }
// UO-1-ID replacement (PT-1 only used for sequential) // UO-1-ID replacement (PT-1 only used for sequential)
COMPRESSED pt_1_seq_id { COMPRESSED pt_1_seq_id {
discriminator =:= '101' [ 3 ];
header_crc =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ];
msn =:= msn_lsb(6, 16) [ 6 ];
ip_id =:= ip_id_lsb(ip_id_behavior.UVALUE, 4, 3) [ 4 ];
ENFORCE((ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_SEQUENTIAL) || ENFORCE((ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_SEQUENTIAL) ||
(ip_id_behavior.UVALUE == (ip_id_behavior.UVALUE ==
IP_ID_BEHAVIOR_SEQUENTIAL_SWAPPED)); IP_ID_BEHAVIOR_SEQUENTIAL_SWAPPED));
discriminator =:= '101' [ 3 ];
header_crc =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ];
msn =:= msn_lsb(6) [ 6 ];
ip_id =:= ip_id_lsb(ip_id_behavior.UVALUE, 4) [ 4 ];
} }
// UOR-2 replacement // UOR-2 replacement
COMPRESSED pt_2_rnd { COMPRESSED pt_2_rnd {
discriminator =:= '110' [ 3 ];
msn =:= msn_lsb(6, 16) [ 6 ];
header_crc =:= crc7(THIS.UVALUE, THIS.ULENGTH) [ 7 ];
ENFORCE((ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_RANDOM) || ENFORCE((ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_RANDOM) ||
(ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_ZERO)); (ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_ZERO));
discriminator =:= '110' [ 3 ];
msn =:= msn_lsb(6) [ 6 ];
header_crc =:= crc7(THIS.UVALUE, THIS.ULENGTH) [ 7 ];
} }
// UOR-2-ID replacement // UOR-2-ID replacement
COMPRESSED pt_2_seq_id { COMPRESSED pt_2_seq_id {
discriminator =:= '1100' [ 4 ];
ip_id =:= ip_id_lsb(ip_id_behavior.UVALUE, 5, 3) [ 5 ];
header_crc =:= crc7(THIS.UVALUE, THIS.ULENGTH) [ 7 ];
msn =:= msn_lsb(8, 64) [ 8 ];
ENFORCE((ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_SEQUENTIAL) || ENFORCE((ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_SEQUENTIAL) ||
(ip_id_behavior.UVALUE == (ip_id_behavior.UVALUE ==
IP_ID_BEHAVIOR_SEQUENTIAL_SWAPPED)); IP_ID_BEHAVIOR_SEQUENTIAL_SWAPPED));
discriminator =:= '1100' [ 4 ];
ip_id =:= ip_id_lsb(ip_id_behavior.UVALUE, 5) [ 5 ];
header_crc =:= crc7(THIS.UVALUE, THIS.ULENGTH) [ 7 ];
msn =:= msn_lsb(8) [ 8 ];
} }
} }
//////////////////////////////////////////// ////////////////////////////////////////////
// IP-only profile // IP-only profile
//////////////////////////////////////////// ////////////////////////////////////////////
// ttl_irregular_chain_flag is set by the user if the TTL/Hop Limit iponly_baseheader(profile, outer_ip_flag, repair_flag)
// of an outer header. The same value must be passed as an argument
// to the ipv4/ipv6 encoding methods when extracting the irregular
// chain items. The same applies to the tos_irregular_chain_flag
iponly_baseheader(profile,
ttl_irregular_chain_flag, tos_irregular_chain_flag)
{ {
UNCOMPRESSED v4 { UNCOMPRESSED v4 {
outer_headers =:= baseheader_outer_headers [ VARIABLE ]; outer_headers =:= baseheader_outer_headers [ VARIABLE ];
version =:= uncompressed_value(4, 4) [ 4 ]; ip_version =:= uncompressed_value(4, 4) [ 4 ];
header_length =:= uncompressed_value(4, 5) [ 4 ]; header_length =:= uncompressed_value(4, 5) [ 4 ];
tos_tc [ 8 ]; tos_tc [ 8 ];
length [ 16 ]; length =:= inferred_ip_v4_length [ 16 ];
ip_id [ 16 ]; ip_id [ 16 ];
rf =:= uncompressed_value(1, 0) [ 1 ]; rf =:= uncompressed_value(1, 0) [ 1 ];
df [ 1 ]; df [ 1 ];
mf =:= uncompressed_value(1, 0) [ 1 ]; mf =:= uncompressed_value(1, 0) [ 1 ];
frag_offset =:= uncompressed_value(13, 0) [ 13 ]; frag_offset =:= uncompressed_value(13, 0) [ 13 ];
ttl_hopl [ 8 ]; ttl_hopl [ 8 ];
next_header [ 8 ]; next_header [ 8 ];
checksum [ 16 ]; ip_checksum =:= inferred_ip_v4_header_checksum [ 16 ];
src_addr [ 32 ]; src_addr [ 32 ];
dest_addr [ 32 ]; dest_addr [ 32 ];
extension_headers =:= baseheader_extension_headers [ VARIABLE ]; extension_headers =:= baseheader_extension_headers [ VARIABLE ];
} }
UNCOMPRESSED v6 { UNCOMPRESSED v6 {
ENFORCE(ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_RANDOM);
outer_headers =:= baseheader_outer_headers [ VARIABLE ]; outer_headers =:= baseheader_outer_headers [ VARIABLE ];
version =:= uncompressed_value(4, 6) [ 4 ]; ip_version =:= uncompressed_value(4, 6) [ 4 ];
version [ 4 ];
tos_tc [ 8 ]; tos_tc [ 8 ];
flow_label [ 20 ]; flow_label [ 20 ];
payload_length [ 16 ]; payload_length =:= inferred_ip_v6_length [ 16 ];
next_header [ 8 ]; next_header [ 8 ];
ttl_hopl [ 8 ]; ttl_hopl [ 8 ];
src_addr [ 128 ]; src_addr [ 128 ];
dest_addr [ 128 ]; dest_addr [ 128 ];
extension_headers =:= baseheader_extension_headers [ VARIABLE ]; extension_headers =:= baseheader_extension_headers [ VARIABLE ];
ENFORCE(ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_RANDOM);
} }
CONTROL { CONTROL {
ip_id_behavior [ 2 ];
ENFORCE(profile == PROFILE_IP_0104); ENFORCE(profile == PROFILE_IP_0104);
ip_id_behavior [ 2 ];
} }
DEFAULT { DEFAULT {
ENFORCE(outer_ip_indicator == 0);
ENFORCE(repair_flag == 0);
tos_tc =:= static; tos_tc =:= static;
dest_addr =:= static; dest_addr =:= static;
version =:= static;
ttl_hopl =:= static; ttl_hopl =:= static;
src_addr =:= static; src_addr =:= static;
df =:= static; df =:= static;
ip_id_behavior =:= static; ip_id_behavior =:= static;
payload_length =:= inferred_ip_v6_length;
checksum =:= inferred_ip_v4_header_checksum;
length =:= inferred_ip_v4_length;
flow_label =:= static; flow_label =:= static;
next_header =:= static; next_header =:= static;
ENFORCE(ttl_irregular_chain_flag == 0);
ENFORCE(tos_irregular_chain_flag == 0);
} }
// Replacement for UOR-2-ext3 // Replacement for UOR-2-ext3
COMPRESSED co_common { COMPRESSED co_common {
discriminator =:= '1111101' [ 7 ]; ENFORCE(repair_flag == 0);
ENFORCE(outer_ip_flag == outer_ip_indicator.CVALUE);
ENFORCE(repair_flag == repair_indicator.CVALUE);
discriminator =:= '11111010' [ 8 ];
ip_id_indicator =:= irregular(1) [ 1 ]; ip_id_indicator =:= irregular(1) [ 1 ];
reorder_ratio =:= reorder_choice [ 2 ];
msn =:= msn_lsb(6, 16) [ 6 ];
df =:= dont_fragment(version.UVALUE) [ 1 ];
header_crc =:= crc7(THIS.UVALUE, THIS.ULENGTH) [ 7 ]; header_crc =:= crc7(THIS.UVALUE, THIS.ULENGTH) [ 7 ];
ttl_hopl_outer_flag =:= irregular(1) [ 1 ]; flags_indicator =:= irregular(1) [ 1 ];
ttl_hopl_present =:= irregular(1) [ 1 ]; ttl_hopl_indicator =:= irregular(1) [ 1 ];
tos_tc_outer_flag =:= irregular(1) [ 1 ]; tos_tc_indicator =:= irregular(1) [ 1 ];
ip_id_behavior =:= ip_id_behavior_choice [ 2 ]; reorder_ratio =:= reorder_choice [ 2 ];
control_crc3 =:= control_crc3 [ 3 ]; control_crc3 =:= control_crc3_encoding [ 3 ];
tos_tc_present =:= irregular(1) [ 1 ]; outer_ip_indicator : repair_indicator : df :
reserved =:= compressed_value(7, 0) [ 7 ]; ip_id_behavior =:= profile_2_3_4_flags_enc(
ip_id =:= flags_indicator.CVALUE, ip_version.UVALUE) [ 0, 8 ];
optional_ip_id_lsb(ip_id_behavior.UVALUE, ip_id =:= optional_ip_id_lsb(ip_id_behavior.UVALUE,
ip_id_indicator.CVALUE) [ 0, 8, 16 ]; ip_id_indicator.CVALUE) [ 0, 8, 16 ];
tos_tc =:= tos_tc =:= static_or_irreg(tos_tc_indicator.CVALUE, 8) [ 0, 8 ];
tos_tc_enc(tos_tc_present.CVALUE) [ 0, 8 ]; ttl_hopl =:= static_or_irreg(ttl_hopl_indicator.CVALUE,
ttl_hopl =:=
static_or_irreg(ttl_hopl_present.CVALUE,
ttl_hopl.ULENGTH) [ 0, 8 ]; ttl_hopl.ULENGTH) [ 0, 8 ];
msn =:= msn_lsb(8) [ 8 ];
}
ENFORCE(ttl_irregular_chain_flag == ttl_hopl_outer_flag.UVALUE); // Context repair (IR-DYN replacement).
ENFORCE(tos_irregular_chain_flag == tos_tc_outer_flag.UVALUE); COMPRESSED co_repair {
ENFORCE(outer_ip_flag == outer_ip_indicator.CVALUE);
ENFORCE(repair_flag == repair_indicator.CVALUE);
discriminator =:= '11111011' [ 8 ];
ip_id_indicator =:= irregular(1) [ 1 ];
header_crc =:= crc7(THIS.UVALUE, THIS.ULENGTH) [ 7 ];
flags_indicator =:= irregular(1) [ 1 ];
ttl_hopl_indicator =:= irregular(1) [ 1 ];
tos_tc_indicator =:= irregular(1) [ 1 ];
reorder_ratio =:= reorder_choice [ 2 ];
control_crc3 =:= control_crc3_encoding [ 3 ];
outer_ip_indicator : repair_indicator : df :
ip_id_behavior =:= profile_2_3_4_flags_enc(
flags_indicator.CVALUE, ip_version.UVALUE) [ 0, 8 ];
ip_id =:= optional_ip_id_lsb(ip_id_behavior.UVALUE,
ip_id_indicator.CVALUE) [ 0, 8, 16 ];
tos_tc =:= static_or_irreg(tos_tc_indicator.CVALUE, 8) [ 0, 8 ];
ttl_hopl =:= static_or_irreg(ttl_hopl_indicator.CVALUE,
ttl_hopl.ULENGTH) [ 0, 8 ];
msn =:= irregular(16) [ 16 ];
} }
// UO-0 // UO-0
COMPRESSED pt_0_crc3 { COMPRESSED pt_0_crc3 {
discriminator =:= '0' [ 1 ]; discriminator =:= '0' [ 1 ];
msn =:= msn_lsb(4, 4) [ 4 ]; msn =:= msn_lsb(4) [ 4 ];
header_crc =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ]; header_crc =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ];
ip_id =:= inferred_sequential_ip_id [ 0 ]; ip_id =:= inferred_sequential_ip_id [ 0 ];
} }
// New format, Type 0 with strong CRC and more SN bits // New format, Type 0 with strong CRC and more SN bits
COMPRESSED pt_0_crc7 { COMPRESSED pt_0_crc7 {
discriminator =:= '100' [ 3 ]; discriminator =:= '100' [ 3 ];
msn =:= msn_lsb(6, 16) [ 6 ]; msn =:= msn_lsb(6) [ 6 ];
header_crc =:= crc7(THIS.UVALUE, THIS.ULENGTH) [ 7 ]; header_crc =:= crc7(THIS.UVALUE, THIS.ULENGTH) [ 7 ];
ip_id =:= inferred_sequential_ip_id [ 0 ]; ip_id =:= inferred_sequential_ip_id [ 0 ];
} }
// UO-1-ID replacement (PT-1 only used for sequential) // UO-1-ID replacement (PT-1 only used for sequential)
COMPRESSED pt_1_seq_id { COMPRESSED pt_1_seq_id {
discriminator =:= '101' [ 3 ];
header_crc =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ];
msn =:= msn_lsb(6, 16) [ 6 ];
ip_id =:= ip_id_lsb(ip_id_behavior.UVALUE, 4, 3) [ 4 ];
ENFORCE((ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_SEQUENTIAL) || ENFORCE((ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_SEQUENTIAL) ||
(ip_id_behavior.UVALUE == (ip_id_behavior.UVALUE ==
IP_ID_BEHAVIOR_SEQUENTIAL_SWAPPED)); IP_ID_BEHAVIOR_SEQUENTIAL_SWAPPED));
discriminator =:= '101' [ 3 ];
header_crc =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ];
msn =:= msn_lsb(6) [ 6 ];
ip_id =:= ip_id_lsb(ip_id_behavior.UVALUE, 4) [ 4 ];
} }
// UOR-2 replacement // UOR-2 replacement
COMPRESSED pt_2_rnd { COMPRESSED pt_2_rnd {
discriminator =:= '110' [ 3 ];
msn =:= msn_lsb(6, 16) [ 6 ];
header_crc =:= crc7(THIS.UVALUE, THIS.ULENGTH) [ 7 ];
ENFORCE((ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_RANDOM) || ENFORCE((ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_RANDOM) ||
(ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_ZERO)); (ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_ZERO));
discriminator =:= '110' [ 3 ];
msn =:= msn_lsb(6) [ 6 ];
header_crc =:= crc7(THIS.UVALUE, THIS.ULENGTH) [ 7 ];
} }
// UOR-2-ID replacement // UOR-2-ID replacement
COMPRESSED pt_2_seq_id { COMPRESSED pt_2_seq_id {
discriminator =:= '1100' [ 4 ];
ip_id =:= ip_id_lsb(ip_id_behavior.UVALUE, 5, 3) [ 5 ];
header_crc =:= crc7(THIS.UVALUE, THIS.ULENGTH) [ 7 ];
msn =:= msn_lsb(8, 64) [ 8 ];
ENFORCE((ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_SEQUENTIAL) || ENFORCE((ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_SEQUENTIAL) ||
(ip_id_behavior.UVALUE == (ip_id_behavior.UVALUE ==
IP_ID_BEHAVIOR_SEQUENTIAL_SWAPPED)); IP_ID_BEHAVIOR_SEQUENTIAL_SWAPPED));
discriminator =:= '1100' [ 4 ];
ip_id =:= ip_id_lsb(ip_id_behavior.UVALUE, 5) [ 5 ];
header_crc =:= crc7(THIS.UVALUE, THIS.ULENGTH) [ 7 ];
msn =:= msn_lsb(8) [ 8 ];
} }
} }
//////////////////////////////////////////// ////////////////////////////////////////////
// UDP-lite/RTP profile // UDP-lite/RTP profile
//////////////////////////////////////////// ////////////////////////////////////////////
// ttl_irregular_chain_flag is set by the user if the TTL/Hop Limit udplite_rtp_baseheader(profile, ts_stride_value, time_stride_value,
// of an outer header. The same value must be passed as an argument outer_ip_flag, repair_flag)
// to the ipv4/ipv6 encoding methods when extracting the irregular
// chain items. The same applies to the tos_irregular_chain_flag
udplite_rtp_baseheader(profile, ts_stride_value,
ttl_irregular_chain_flag, tos_irregular_chain_flag)
{ {
UNCOMPRESSED v4 { UNCOMPRESSED v4 {
ENFORCE(msn.UVALUE == sequence_number.UVALUE);
outer_headers =:= baseheader_outer_headers [ VARIABLE ]; outer_headers =:= baseheader_outer_headers [ VARIABLE ];
version =:= uncompressed_value(4, 4) [ 4 ]; ip_version =:= uncompressed_value(4, 4) [ 4 ];
header_length =:= uncompressed_value(4, 5) [ 4 ]; header_length =:= uncompressed_value(4, 5) [ 4 ];
tos_tc [ 8 ]; tos_tc [ 8 ];
length [ 16 ]; length =:= inferred_ip_v4_length [ 16 ];
ip_id [ 16 ]; ip_id [ 16 ];
rf =:= uncompressed_value(1, 0) [ 1 ]; rf =:= uncompressed_value(1, 0) [ 1 ];
df [ 1 ]; df [ 1 ];
mf =:= uncompressed_value(1, 0) [ 1 ]; mf =:= uncompressed_value(1, 0) [ 1 ];
frag_offset =:= uncompressed_value(13, 0) [ 13 ]; frag_offset =:= uncompressed_value(13, 0) [ 13 ];
ttl_hopl [ 8 ]; ttl_hopl [ 8 ];
next_header [ 8 ]; next_header [ 8 ];
checksum [ 16 ]; ip_checksum =:= inferred_ip_v4_header_checksum [ 16 ];
src_addr [ 32 ]; src_addr [ 32 ];
dest_addr [ 32 ]; dest_addr [ 32 ];
extension_headers =:= baseheader_extension_headers [ VARIABLE ]; extension_headers =:= baseheader_extension_headers [ VARIABLE ];
src_port [ 16 ]; src_port [ 16 ];
dst_port [ 16 ]; dst_port [ 16 ];
checksum_coverage [ 16 ]; checksum_coverage [ 16 ];
checksum [ 16 ]; udp_checksum [ 16 ];
version =:= uncompressed_value(2, 0) [ 2 ]; rtp_version =:= uncompressed_value(2, 2) [ 2 ];
pad_bit [ 1 ]; pad_bit [ 1 ];
extension [ 1 ]; extension [ 1 ];
cc [ 4 ]; cc [ 4 ];
marker [ 1 ]; marker [ 1 ];
payload_type [ 7 ]; payload_type [ 7 ];
sequence_number [ 16 ]; sequence_number [ 16 ];
timestamp [ 32 ]; timestamp [ 32 ];
ssrc [ 32 ]; ssrc [ 32 ];
csrc_list [ VARIABLE ]; csrc_list [ VARIABLE ];
ENFORCE(msn.UVALUE == sequence_number.UVALUE);
} }
UNCOMPRESSED v6 { UNCOMPRESSED v6 {
ENFORCE(ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_RANDOM);
outer_headers =:= baseheader_outer_headers [ VARIABLE ]; outer_headers =:= baseheader_outer_headers [ VARIABLE ];
version =:= uncompressed_value(4, 6) [ 4 ]; ip_version =:= uncompressed_value(4, 6) [ 4 ];
version [ 4 ];
tos_tc [ 8 ]; tos_tc [ 8 ];
flow_label [ 20 ]; flow_label [ 20 ];
payload_length [ 16 ]; payload_length =:= inferred_ip_v6_length [ 16 ];
next_header [ 8 ]; next_header [ 8 ];
ttl_hopl [ 8 ]; ttl_hopl [ 8 ];
src_addr [ 128 ]; src_addr [ 128 ];
dest_addr [ 128 ]; dest_addr [ 128 ];
extension_headers =:= baseheader_extension_headers [ VARIABLE ]; extension_headers =:= baseheader_extension_headers [ VARIABLE ];
src_port [ 16 ]; src_port [ 16 ];
dst_port [ 16 ]; dst_port [ 16 ];
checksum_coverage [ 16 ]; checksum_coverage [ 16 ];
checksum [ 16 ]; udp_checksum [ 16 ];
version =:= uncompressed_value(2, 0) [ 2 ]; rtp_version =:= uncompressed_value(2, 2) [ 2 ];
pad_bit [ 1 ]; pad_bit [ 1 ];
extension [ 1 ]; extension [ 1 ];
cc [ 4 ]; cc [ 4 ];
marker [ 1 ]; marker [ 1 ];
payload_type [ 7 ]; payload_type [ 7 ];
sequence_number [ 16 ]; sequence_number [ 16 ];
timestamp [ 32 ]; timestamp [ 32 ];
ssrc [ 32 ]; ssrc [ 32 ];
csrc_list [ VARIABLE ]; csrc_list [ VARIABLE ];
ENFORCE(ip_id_behavior.UVALUE == IP_ID_BEHAVIOR_RANDOM);
} }
CONTROL { CONTROL {
ENFORCE(time_stride_value == time_stride.UVALUE);
ENFORCE(ts_stride.UVALUE == ts_stride_value);
ENFORCE(profile == PROFILE_RTP_0107);
ip_id_behavior [ 2 ]; ip_id_behavior [ 2 ];
coverage_behavior [ 2 ]; coverage_behavior [ 2 ];
ts_stride [ 32 ]; ts_stride [ 32 ];
time_stride [ 32 ];
ts_scaled [ 32 ]; ts_scaled [ 32 ];
ts_offset =:= ts_offset =:= field_scaling(ts_stride.UVALUE, ts_scaled.UVALUE,
field_scaling(ts_stride.UVALUE, ts_scaled.UVALUE,
timestamp.UVALUE) [ 32 ]; timestamp.UVALUE) [ 32 ];
ENFORCE(ts_stride.UVALUE == ts_stride_value);
ENFORCE(profile == PROFILE_RTP_0107);
} }
DEFAULT { DEFAULT {
ENFORCE(outer_ip_indicator == 0);
ENFORCE(repair_flag == 0);
tos_tc =:= static; tos_tc =:= static;
dest_addr =:= static; dest_addr =:= static;
version =:= static;
ttl_hopl =:= static; ttl_hopl =:= static;
src_addr =:= static; src_addr =:= static;
df =:= static; df =:= static;
ip_id_behavior =:= static; ip_id_behavior =:= static;
payload_length =:= inferred_ip_v6_length;
checksum =:= inferred_ip_v4_header_checksum;
length =:= inferred_ip_v4_length;
flow_label =:= static; flow_label =:= static;
next_header =:= static; next_header =:= static;
src_port =:= static; src_port =:= static;
dst_port =:= static; dst_port =:= static;
checksum_coverage =:= irregular(16); checksum_coverage =:= irregular(16);
checksum =:= irregular(16); udp_checksum =:= irregular(16);
pad_bit =:= static; pad_bit =:= static;
extension =:= static; extension =:= static;
cc =:= static; cc =:= static;
// When marker not present in packets, it is assumed 0 // When marker not present in packets, it is assumed 0
marker =:= uncompressed_value(1, 0); marker =:= uncompressed_value(1, 0);
payload_type =:= static; payload_type =:= static;
sequence_number =:= static; sequence_number =:= static;
timestamp =:= static; timestamp =:= static;
ssrc =:= static; ssrc =:= static;
csrc_list =:= static; csrc_list =:= static;
ENFORCE(ttl_irregular_chain_flag == 0);
ENFORCE(tos_irregular_chain_flag == 0);
} }
// Replacement for UOR-2-ext3 // Replacement for UOR-2-ext3
COMPRESSED co_common { COMPRESSED co_common {
discriminator =:= '1111101' [ 7 ]; ENFORCE(repair_flag == 0);
ENFORCE(outer_ip_flag == outer_ip_indicator.CVALUE);