Network Working Group Peter Kremer, Ericsson INTERNET-DRAFT November, 2001 Expires: June 2002 ROHC Implementer's Guide Status of this memo This document is an Internet-Draft and is in full conformance with all provisions of Section 10 of RFC2026. Internet-Drafts are working documents of the Internet Engineering Task Force (IETF), its areas, and its working groups. Note that other groups may also distribute working documents as Internet-Drafts. Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or cite them other than as "work in progress". The list of current Internet-Drafts can be accessed at http://www.ietf.org/ietf/lid-abstracts.txt The list of Internet-Draft Shadow Directories can be accessed at http://www.ietf.org/shadow.html This document is an individual submission to the IETF. Comments should be directed to the authors. Abstract This document is an extension to the ROHC standard [RFC 3095] and contains useful information for everyone who intends to implement ROHC. Kremer [Page 1] INTERNET-DRAFT ROHC Implementer's Guide November, 2001 Table of Contents 1. Introduction...................................................2 2. CRC Calculation................................................2 3. Inefficiency in mode transitions...............................2 4. Other clarifications...........................................3 5. Test configuration.............................................4 6. References.....................................................5 7. Author's address...............................................5 Appendix A. Sample CRC algorithm .................................6 1. Introduction This document describes common misinterpretations and some ambiguous points of the ROHC standard [RFC 3095] (i. e. CRC calculation). The problems were discovered by the members of the ROHC working group during interoperability tests. 2. CRC Calculation Section 5.2.5.2. describes the segmentation protocol and a CRC algorithm for 32 bit long checksums. However, Section 5.9 only defines the polynomials for 3, 7 and 8-bit long checksum, the same algorithm [RFC 1662] can be used in these cases as well. A PERL implementation of the algorithm can be found in Appendix A. 3. Inefficiency in mode transitions It is inefficient and unnecessary to send CRC options in all the feedback packets during mode transition. However, the figures in chapter 5.6.5. and 5.6.6. does not show it is safe (and more efficient) to set the value of D_TRANS to P as soon as the decompressor receives an appropriate IR/IR-DYN/UOR-2 packet. The transition procedure from Reliable to Optimistic mode is described below: Kremer [Page 2] INTERNET-DRAFT ROHC Implementer's Guide November, 2001 Compressor Decompressor ---------------------------------------------- | | | ACK(O)/NACK(O) +-<-<-<-| D_TRANS = I | +-<-<-<-<-<-<-<-+ | C_TRANS = P |-<-<-<-+ | C_MODE = O | | |->->->-+ IR/IR-DYN/UOR-2(SN,O) | | +->->->->->->->-+ | |->-.. +->->->-| D_TRANS = P |->-.. | D_MODE = O | ACK(SN,O) +-<-<-<-| | +-<-<-<-<-<-<-<-+ | C_TRANS = D |-<-<-<-+ | | | |->->->-+ UO-0, UO-1* | | +->->->->->->->-+ | | +->->->-| D_TRANS = D | | The transition procedure to Unidirectional mode is described below: Compressor Decompressor ---------------------------------------------- | | | ACK(U)/NACK(U) +-<-<-<-| D_TRANS = I | +-<-<-<-<-<-<-<-+ | C_TRANS = P |-<-<-<-+ | C_MODE = U | | |->->->-+ IR/IR-DYN/UOR-2(SN,U) | | +->->->->->->->-+ | |->-.. +->->->-| D_TRANS = P |->-.. | | ACK(SN,U) +-<-<-<-| | +-<-<-<-<-<-<-<-+ | C_TRANS = D |-<-<-<-+ | | | |->->->-+ UO-0, UO-1* | | +->->->->->->->-+ | | +->->->-| D_TRANS = D | | D_MODE= U 4. Other clarifications * According to Section 5.9.1, in case of IR and IR-DYN packets the CRC "is calculated over the entire IR or IR-DYN packet, excluding Payload and including CID or Add-CID octet". However, a padding octet looks like an Add-CID octet for CID 0, padding is not included in CRC. Kremer [Page 3] INTERNET-DRAFT ROHC Implementer's Guide November, 2001 * During transition from window-based compression to timer-based compression it is necessary to keep k large enough to cover both interpretation intervals. * The length of the generic extension header list in the IPv4 dynamic chain is at least one octet (or two octets if GP bit is set) even if it is empty (RFC 3095, Section 5.7.7.4. and Section 5.8.6.1.). * The length of the generic CSRC list in the RTP dynamic chain is at least one octet (or two octets if GP bit is set) even if it is empty (RFC 3095, Section 5.7.7.6. and Section 5.8.6.1.). * There is two CC fields in the RTP dynamic chain (the first octet in the dynamic part in Section 5.7.7.6. and the first octet of the generic CSRC list in Section 5.8.6.1.). * NBO = 1 means network byte order. In general, if a flag is set, it indicates something that is not normal. Since network byte order is the more common byte alignment this notation could cause confusion. * SN updates with CRC also update TS and ID implicitly, unless there are explicit TS and ID fields in the packet. * It is obvious that packets have different meanings in different modes. That's why it is necessary to decode packets according to the appropriate mode even during mode transition. It implies that packet decoders must be changed before the mode transition completes (i.e. while D_TRANS = P). 5. Test Configuration ROHC is used to compress IP/UDP/RTP, IP/UDP and IP/ESP headers, thus every ROHC implementation has an interface that can send and receive IP packets (i.e. Ethernet). On the other hand, there must be an interface (a serial link for example) or other means of transport (an IP/UDP flow), which can transmit ROHC packets. Having these two interfaces several configurations can be set up. The figure below shows sample configurations that can be used for testing a ROHC implementation: IP/UDP/RTP +------------+ ROHC +--------------+ IP/UDP/RTP packets | ROHC | packets | ROHC | packets ---------->| Compressor |-----> ----->| Decompressor |----------> +------------+ +--------------+ Unfortunately, comparing the IP/UDP/RTP packets at the endpoints can only show whether the reconstructed stream differs from the original or not. In order to identify the place of the error more detailed tests are needed. The next figure shows another possible scenario: Kremer [Page 4] INTERNET-DRAFT ROHC Implementer's Guide November, 2001 IP/UDP/RTP +------------+ ROHC IP/UDP/RTP +--------------+ ROHC packets | ROHC | packets packets | ROHC | packets +----->| Compressor |----->+ +<-----| Decompressor |<-----+ | +------------+ | | +--------------+ | | | | | | +------------+ | | +------------+ | | | Test | | | | Test | | +<-----| Equipment |<-----+ +------>| Equipment |------>+ +------------+ +------------+ In the first case, the test equipment generates the RTP stream and also acts as a ROHC decompressor. The tester must recognize if the original RTP stream was compressed in a bad way and gives an alarm. In the second case, it is the test equipment that sends the compressed ROHC packets and the Decompressor reconstructs the RTP stream. Since the tester knows the ROHC packets and the reconstructed RTP stream it can detect if the Decompressor makes a mistake. 6. References [RFC-3095] C. Bormann, Editor, RObust Header Compression (ROHC), RFC 3095, July 2001. [RFC-1662] W. Simpson, Editor, PPP in HDLC-like Framing, RFC 1662, July 1994. 7. Author's Addresses Peter Kremer Ericsson Research, Conformance and Software Test Laboratory H-1300 Bp. 3., P.O. Box 107, HUNGARY Phone: +36-1-437-7033 Email: Peter.Kremer@ericsson.com Kremer [Page 5] INTERNET-DRAFT ROHC Implementer's Guide November, 2001 Appendix A. Sample CRC algorithm #!/usr/bin/perl -w use strict; #================================= # # ROHC CRC demo - Carsten Bormann cabo@tzi.org 2001-08-02 # # This little demo shows the three types of CRC in use in RFC 3095, # the robust header compression standard. Type your data in # hexadecimal form and the press Control+D. # #--------------------------------- # # utility # sub dump_bytes($) { my $x = shift; my $i; for ($i = 0; $i < length($x); ) { printf("%02x ", ord(substr($x, $i, 1))); printf("\n") if (++$i % 16 == 0); } printf("\n") if ($i % 16 != 0); } #--------------------------------- # # The CRC calculation algorithm. # sub do_crc($$$) { my $nbits = shift; my $poly = shift; my $string = shift; my $crc = ($nbits == 32 ? 0xffffffff : (1 << $nbits) - 1); for (my $i = 0; $i < length($string); ++$i) { my $byte = ord(substr($string, $i, 1)); for( my $b = 0; $b < 8; $b++ ) { if (($crc & 1) ^ ($byte & 1)) { $crc >>= 1; $crc ^= $poly; } else { $crc >>= 1; } $byte >>= 1; } } printf "%2d bits, ", $nbits; printf "CRC: %02x\n", $crc; } Kremer [Page 6] INTERNET-DRAFT ROHC Implementer's Guide November, 2001 #--------------------------------- # # Test harness # $/ = undef; $_ = <>; # read until EOF my $string = ""; # extract all that looks hex: s/([0-9a fA - -F][0-9a-fA-F])/$string .= chr(hex($1)), ""/eg; dump_bytes($string); #--------------------------------- # # 32-bit segmentation CRC # Note that the text implies this is complemented like for PPP # (this differs from 8, 7, and 3-bit CRC) # # C(x) = x^0 + x^1 + x^2 + x^4 + x^5 + x^7 + x^8 + x^10 + # x^11 + x^12 + x^16 + x^22 + x^23 + x^26 + x^32 # do_crc(32, 0xedb88320, $string); #--------------------------------- # # 8-bit IR/IR-DYN CRC # # C(x) = x^0 + x^1 + x^2 + x^8 # do_crc(8, 0xe0, $string); #--------------------------------- # # 7-bit FO/SO CRC # # C(x) = x^0 + x^1 + x^2 + x^3 + x^6 + x^7 # do_crc(7, 0x79, $string); #--------------------------------- # # 3-bit FO/SO CRC # # C(x) = x^0 + x^1 + x^3 # do_crc(3, 0x6, $string); Kremer [Page 7]