[Search] [txt|pdf|bibtex] [Tracker] [Email] [Diff1] [Diff2] [Nits]

Versions: 00 01                                                         
INTERNET-DRAFT                                                  T. Davis
Expires: 15 Feb 1999
Tekelec <draft-davis-xdr-ext-01.txt>
August 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 August 1998


Table of Contents


   1.   Introduction   . . . . . . . . . . . . . . . . . . . . . .   3
   2.   XDR Data Types   . . . . . . . . . . . . . . . . . . . . .   3
   2.1  Discriminated Union  . . . . . . . . . . . . . . . . . . .   3
   2.2  Bit Fields   . . . . . . . . . . . . . . . . . . . . . . .   5
   2.3  Raw Integers . . . . . . . . . . . . . . . . . . . . . . .   6
   3.   Discussion   . . . . . . . . . . . . . . . . . . . . . . .   6
   4.   The XDR Language Specification   . . . . . . . . . . . . .   8
   4.1  Syntax Information   . . . . . . . . . . . . . . . . . . .   8
   5.   Bit Field Implementation Example   . . . . . . . . . . . .  10
   6.   References   . . . . . . . . . . . . . . . . . . . . . . .  13
   7.   Security Considerations  . . . . . . . . . . . . . . . . .  13
   8.   Author's Address   . . . . . . . . . . . . . . . . . . . .  13




































Davis                                                           [Page 2]


INTERNET-DRAFT               XDR Extensions               29 August 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 three 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.

      (3) The representation of byte oriented integers.

   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;



Davis                                                           [Page 3]


INTERNET-DRAFT               XDR Extensions               29 August 1998


         case discriminant-value-B:
            arm-declaration-B;
         ...
         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



Davis                                                           [Page 4]


INTERNET-DRAFT               XDR Extensions               29 August 1998


   therefore optional.  It is provided as an aid to pre-compilers.


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



Davis                                                           [Page 5]


INTERNET-DRAFT               XDR Extensions               29 August 1998


   structure or union.


2.3 Raw Integers

   A XDR raw integer is a special case of a signed or unsigned integer.
   They are very much like the opaque data type but fixed to a length of
   4 bytes.  Unlike the opaque data type these are represented as an
   integer instead of a byte array.  For example, an IP address is often
   coded as an integer but is really 4 bytes.  The numeric value of the
   IP address may change on different machines but the byte order does
   not. Raw integers are descibed as follows:

      raw int identifier;
      raw unsigned int identifier;

   Raw integers are encoded with the left most byte first, MSB on big
   endian and LSB if little endian.  This is exactly the same as the raw
   data reguardless of machine.

      Endian
      ------
      Big     MSB                             LSB
      Little  LSB                             MSB
             +--------+--------+--------+--------+
             | Byte 0 | Byte 1 | Byte 2 | Byte 3 +  RAW INTEGER
             +--------+--------+--------+--------+
             <--------------- 32 Bits ----------->


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



Davis                                                           [Page 6]


INTERNET-DRAFT               XDR Extensions               29 August 1998


   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.

   (3) Why add the raw integer data type?

   Consider an application that tranfers IP addresses from one host to
   another.  Also consider that the application keeps a list of IP
   addresses as a series of longs.  The IP address is not really a
   number at all, it is a series of bytes that is stored easily as a
   long integer.  On different machines the numeric value of the number
   may change because the byte order does not.  Now, how does this
   application send the data in the XDR stream?  If it sends this data
   as a integer then the byte order may change making the IP addresses
   backwards.  The only choice is to send it as a 4 byte opaque.
   However, this confuses the interpretation of it in the application.
   Naturally, the application could consider it a union for type casting
   but that makes it pretty ugly and adds 4 more bytes in the encoded
   XDR stream.  The application developer needs flexibilty in how he or
   she wants to represent the data.  This type provides a great deal of
   flexibilty without complexity.
















Davis                                                           [Page 7]


INTERNET-DRAFT               XDR Extensions               29 August 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:
           [ "raw" ] [ "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 8]


INTERNET-DRAFT               XDR Extensions               29 August 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 9]


INTERNET-DRAFT               XDR Extensions               29 August 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 10]


INTERNET-DRAFT               XDR Extensions               29 August 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 11]


INTERNET-DRAFT               XDR Extensions               29 August 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 12]


INTERNET-DRAFT               XDR Extensions               29 August 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



   <draft-davis-xdr-ext-01.txt>
   Expires: 15 Feb 1999
























Davis                                                          [Page 13]