HTTP/1.1 200 OK Date: Mon, 08 Apr 2002 23:30:18 GMT Server: Apache/1.3.20 (Unix) Last-Modified: Fri, 14 Aug 1998 13:04:00 GMT ETag: "2e97c5-47ab-35d435c0" Accept-Ranges: bytes Content-Length: 18347 Connection: close Content-Type: text/plain INTERNET-DRAFT T. Davis Expires: 3 Feb 1999 Tekelec July 1998 XDR Extensions Status of this Memo This document is an Internet-Draft. 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 to cite them other than as "work in progress." To view the entire list of current Internet-Drafts, please check the "1id-abstracts.txt" listing contained in the Internet-Drafts Shadow Directories on ftp.is.co.za (Africa), ftp.nordu.net (Northern Europe), ftp.nis.garr.it (Southern Europe), munnari.oz.au (Pacific Rim), ftp.ietf.org (US East Coast), or ftp.isi.edu (US West Coast). ABSTRACT This document describes extensions to the External Data Representation Standard (XDR) protocol as it is currently deployed and accepted. Davis [Page 1] INTERNET-DRAFT XDR Extensions 29 July 1998 Table of Contents 1. Introduction . . . . . . . . . . . . . . . . . . . . . . 3 2. XDR Data Types . . . . . . . . . . . . . . . . . . . . . 3 2.1 Discriminated Union . . . . . . . . . . . . . . . . . . . 3 2.2 Bit Fields . . . . . . . . . . . . . . . . . . . . . . . 5 3. Discussion . . . . . . . . . . . . . . . . . . . . . . . 6 4. The XDR Language Specification . . . . . . . . . . . . . 7 4.1 Syntax Information . . . . . . . . . . . . . . . . . . . 7 5. Bit Field Implementation Example . . . . . . . . . . . . 9 6. References . . . . . . . . . . . . . . . . . . . . . . . 11 7. Security Considerations . . . . . . . . . . . . . . . . . 11 8. Author's Address . . . . . . . . . . . . . . . . . . . . 11 Davis [Page 2] INTERNET-DRAFT XDR Extensions 29 July 1998 1. Introduction The XDR is a standard for the description and encoding of data in a machine architecture independent form. Full details of the XDR standard can be found in RFC 1832 [1]. It is the focus of this memo to recommend enhancements to the existing specification [1]. This memo addresses two primary issues: (1) The limitations of the discriminated union in representing existing message protocols. (2) The unresolved issue of representing bit fields in a space efficient manor. The overall intention of this memo is to improve the existing standard for use with a broader scope of applications. All assumptions and constraints implied in [1] still remain implied in this memo. 2. XDR Data Types 2.1 Discriminated Union As described in RFC 1832 [1], a discriminated union is a type composed of a discriminant followed by a type selected from a set of prearranged types according to the value of the discriminant. The type of discriminant is either "int", "unsigned int", or an enumerated type, such as "bool". The component types are called "arms" of the union, and are preceded by the value of the discriminant which implies their encoding. However, different from [1] is addition of the structure component declarations which if any must precede the first "arm" declaration and the optional union identifier declaration. The difference is small and therefore allows the interpretation of the union type described in [1] without change. Discriminated unions are declared as follows: union switch (discriminant-declaration, union-identifier) { component-declaration-A; component-declaration-B; ... case discriminant-value-A: arm-declaration-A; case discriminant-value-B: arm-declaration-B; ... Davis [Page 3] INTERNET-DRAFT XDR Extensions 29 July 1998 default: default-declaration; } identifier; Each "case" keyword is followed by a legal value of the discriminant. The default arm is optional. If it is not specified, then a valid encoding of the union cannot take on unspecified discriminant values. The size of the implied arm is always a multiple of four bytes. The discriminated union is encoded as its discriminant followed by the encoding of the implied arm if no components are specified. 0 1 2 3 +---+---+---+---+---+---+---+---+ | discriminant | implied arm | DISCRIMINATED UNION +---+---+---+---+---+---+---+---+ |<---4 bytes--->| If any components are specified then the components follow the discriminant and precede the implied arm in order as if they were a sub-structure. 0 1 2 3 +---+---+---+---+---+---+---+---+---+---+---+---+ | discriminant | components | implied arm | +---+---+---+---+---+---+---+---+---+---+---+---+ |<---4 bytes--->| The second form provides for cleaner interpretation on addition data when translated into programming languages. For example, in the C programming language the data could be represented by the following structure. struct { discriminant-declaration; component-declaration-A; component-declaration-B; ... union { arm-declaration-A; arm-declaration-B; ... } union-identifier; } identifier; The union-identifier is not part of the encoded data stream and is therefore optional. It is provided as an aid to pre-compilers. Davis [Page 4] INTERNET-DRAFT XDR Extensions 29 July 1998 2.2 Bit Fields A XDR bit field is a special case of a signed or unsigned integer from 1 to 32 bits wide. Bit fields can only exist inside a XDR structure or union; however, they can be mixed inside the same structure or union with non-bit field types. The only part of a union where bit fields are permitted is the structure like component section not the union arms. Bit fields are described as follows: int identifier : n; unsigned int identifier : n; where the constant n indicates the width from 1 to 32 bits. Solo bit fields are packed to 32 bits wide starting with the most significant bit. All remaining bits (padding) are zero filled. +---------+---------+---------+---------+---------+ | Bit n-1 | ... | Bit 1 | Bit 0 | Padding + BIT FIELD +---------+---------+---------+---------+---------+ <---------------------- 32 Bits ------------------> Consecutive bit fields are packed into 32 bit blocks. A bit field is never split across the 32 bit blocks. In this case, the previous block is zero padded to 32 bits and the bit field starts in the next 32 bit block. The order of consecutive bit fields is determined be the order of declaration as are all other XDR types. For example: struct { int i : 4; int j : 8; unsigned int k : 16; int l : 16; int m : 4; }; 0 4 12 28 32/0 16 20 31 +---+-------+---------------+---+---------------+---+-----------+ | i | j | k | | l | m | | +---+-------+---------------+---+---------------+---+-----------+ <----- Block 0, 32 Bits ------> <----- Block 1, 32 Bits ------> <-------------------------- 64 Bits --------------------------> The term "consecutive" refers to adjacent bit fields in the same structure or union. Davis [Page 5] INTERNET-DRAFT XDR Extensions 29 July 1998 3. Discussion (1) Why change the discriminated union? The proposed type allows for easier application with existing protocols. For example, many protocols place the message type in the first 4 bytes of each message and it is common place for that type to be followed by other data common the all messages of that protocol in a header. The union data in this event usually follows this header. RFC 1832 [1] does not directly handle this situation. However, it can be shown that if the encoding does not follow the order of the non-encoded data members the same effect can be reached with the previous XDR discriminated union. Secondly, if existing protocols need to transfer machine independent data, having the machine independent data be able to model existing data will make the transition less costly. While it is not possible to seamlessly convert existing data types to a XDR syntax, it is possible to reassemble existing data into XDR format and seamlessly convert it into most language formats by a pre-compiler. The more closely the XDR syntax can resemble existing data types the easier the transition of existing applications will be. (2) Why add the bit field data type? Although the bit fields are little more than integers. They represent a common part of programming languages today. Perhaps the most common use of bit fields is to describe data in a packed format for efficiency. It is a good idea to allow that description and purpose to be passed along in a machine independent style. Consider the situation in [1], if 32 separately but consecutively described bit fields of width 1 are encoded, exactly 128 bytes in the encoded stream are used. Where in this style exactly 4 bytes are used. That is a 99.97% reduction in the encoded data stream for the best case and a 0% reduction in the worst case. Davis [Page 6] INTERNET-DRAFT XDR Extensions 29 July 1998 4. The XDR Language Specification Only the "Syntax Information" section of part of the language specification has changed and is there for the only part included in this memo. Are other parts from [1] still apply without correction. 4.1 Syntax Information The following diagram includes the diagram in RFC 1832 [1] for completeness. The same lexical and syntax notes apply from [1]. declaration: type-specifier identifier | type-specifier identifier "[" value "]" | type-specifier identifier "<" [ value ] ">" | "opaque" identifier "[" value "]" | "opaque" identifier "<" [ value ] ">" | "string" identifier "<" [ value ] ">" | type-specifier "*" identifier | "void" bitfield-inclusive-declaration: [ "unsigned" ] "int" identifier ":" value | declaration value: constant | identifier type-specifier: [ "unsigned" ] "int" | [ "unsigned" ] "hyper" | "float" | "double" | "quadruple" | "bool" | enum-type-spec | struct-type-spec | union-type-spec | identifier enum-type-spec: "enum" enum-body enum-body: "{" ( identifier "=" value ) Davis [Page 7] INTERNET-DRAFT XDR Extensions 29 July 1998 ( "," identifier "=" value )* "}" struct-type-spec: "struct" struct-body struct-body: "{" ( bitfield-inclusive-declaration ";" ) ( bitfield-inclusive-declaration ";" )* "}" union-type-spec: "union" union-body union-body: "switch" "(" declaration [ "," identifier ] ")" "{" ( bitfield-inclusive-declaration ";" )* ( "case" value ":" declaration ";" ) ( "case" value ":" declaration ";" )* [ "default" ":" declaration ";" ] "}" constant-def: "const" identifier "=" constant ";" type-def: "typedef" declaration ";" | "enum" identifier enum-body ";" | "struct" identifier struct-body ";" | "union" identifier union-body ";" definition: type-def | constant-def specification: definition * Davis [Page 8] INTERNET-DRAFT XDR Extensions 29 July 1998 5. Bit Field Implementation Example The following code segment illustrates one possible implementation of bit field packing and unpacking of the XDR stream. The style implied follows the currently implemented style of XDR coding. This function returns FALSE on failure and TRUE on success. This function does not take the actual structure members as its arguments because machine independent packing of the bits may vary. It is the assumption of the function that a complete list of the "consecutive" bit fields are provided in the arguments. /* * The following define simply masks out bits that should not * be present the a current bitfield. */ #define MASK_WIDTH(value, width) ( \ ((u_long)0xffffffff) >> ( 32 - (width) ) \ & ((u_long)(value)) \ ) bool_t xdr_bitfields( register XDR *xdr, /* XDR stream pointer */ u_int num_fields, /* Number of bit fields */ u_char *widths, /* Bit field widths */ u_long *values /* Bit field values */ ) { u_long val; /* Temporary storage of packed bit fields */ u_int i; /* Loop counter */ i_int offset; /* Current offset in 32-bit block */ if ( num_fields <= 0 ) return TRUE; switch ( xdrs->x_op ) { case XDR_ENCODE: /* * ENCODING: For each bit field, if there is Davis [Page 9] INTERNET-DRAFT XDR Extensions 29 July 1998 * room in the current 32-bit block, pack it; * otherwise, encode the current block and pack * the bit field into the next block. * * When all bit fields are packed encode the final * 32-bit block. */ val = 0; offset = 0; for ( i = 0; i < num_fields; i++ ) { if ( widths[i] < 1 || widths[i] > 32 ) return ERROR; if ( offset + widths[i] > 32 ) { if ( xdr_u_long( xdrs, &val ) == FALSE ) return FALSE; offset = 0; val = 0; } offset += widths[i]; val |= ( MASK_WIDTH( values[i], widths[i] ) \ << ( 32 - offset ) ); } if ( xdr_u_long( xdrs, &val ) == FALSE ) return FALSE; return TRUE; case XDR_DECODE: /* * DECODING: Decode the first block. For each * bit field, if there is enough space in the * current 32-bit block, unpack it; otherwise, * decode the next block and unpack the bit * field from it. */ Davis [Page 10] INTERNET-DRAFT XDR Extensions 29 July 1998 if ( xdr_u_long( xdrs, &val ) == FALSE ) return FALSE; offset = 0; for ( i = 0; i < num_fields; i++ ) { if ( widths[i] < 1 || widths[i] > 32 ) return ERROR; if ( offset + widths[i] > 32 ) { if ( xdr_u_long( xdrs, &val ) == FALSE ) return FALSE; offset = 0; } offset += widths[i]; values[i] = MASK_WIDTH( val >> (32 - offset), \ widths[i]); } return TRUE; case XDR_FREE: return TRUE; } return FALSE; } Davis [Page 11] INTERNET-DRAFT XDR Extensions 29 July 1998 6. References [1] Srinivasan, R., "XDR: External Data Representation Standard", STD 1, RFC 1832, Sun Microsystems, Inc., August 1995. 7. Security Considerations Security issues are not discussed in this memo. 8. Author's Address Thomas Davis Tekelec, Inc. 5151 McCrimmon Parkway Suite 216 Morrisville, NC 27560 Phone: 919-380-2066 Fax: 919-380-2060 EMail: tom.davis@tekelec.com Expires: 3 Feb 1999 Davis [Page 12]