Listing 1.8
Name Service Resource Records

NS_Rrec.h
/* Label String Pointer. */
#define LSP           0xC00C  /* Pointer to offset 12 */

/* Resource Record Type. */
#define RRTYPE_A      0x0001  /* IP Addr RR (unused)  */
#define RRTYPE_NS     0x0002  /* Name Server (unused) */
#define RRTYPE_NULL   0x000A  /* NULL RR (unused)     */
#define RRTYPE_NB     0x0020  /* NetBIOS              */
#define RRTYPE_NBSTAT 0x0021  /* NB Status Response   */

/* Resource Record Class. */
#define RRCLASS_IN    0x0001  /* Internet Class       */


NS_Rrec.c
#include <string.h>     /* For memcpy() */
#include <netinet/in.h> /* htons(), ntohs(), etc. */

#include "NS_Rrec.h"


int Put_RRec_Name( uchar       *rrec,
                   const uchar *name,
                   const uchar  pad,
                   const uchar  sfx,
                   const uchar *scope,
                   const ushort rrtype )
  /* ---------------------------------------------------- **
   * Create and store the fully qualified NBT name in the
   * destination buffer.  Also store the RR_TYPE and
   * RR_CLASS values.
   * Return the number of bytes written.
   * ---------------------------------------------------- **
   */
  {
  int    len;
  ushort tmp;
  ushort rrclass_in;

  /* Validate the rrtype.
   * Note that we exclude the A, NS, and NULL RRTYPEs
   * as these are never used.
   */
  if( (RRTYPE_NB != rrtype)
   && (RRTYPE_NBSTAT != rrtype ) )
    return( -1 );

  len = L2_Encode( rrec, name, pad, sfx, scope );
  if( len < 0 )
    return( len );

  tmp = htons( rrtype );
  (void)memcpy( &(rrec[len]), &tmp, 2 );
  len += 2;

  rrclass_in = htons( RRCLASS_IN );
  (void)memcpy( &(rrec[len]), &rrclass_in, 2 );
  return( len + 2 );
  } /* Put_RRec_Name */

int Put_RRec_LSP( uchar *rrec, const ushort rrtype )
  /* ---------------------------------------------------- **
   * Write a Label String Pointer (LSP) instead of an NBT
   * name.  RR_TYPE and RR_CLASS are also written.
   * Return the number of bytes written (always 6).
   * ---------------------------------------------------- **
   */
  {
  ushort tmp;
  ushort lsp;
  ushort rrclass_in;

  lsp = htons( 0xC00C );
  (void)memcpy( rrec, &lsp, 2 );

  tmp = htons( rrtype );
  (void)memcpy( &(rrec[2]), &tmp, 2 );

  rrclass_in = htons( RRCLASS_IN );
  (void)memcpy( &(rrec[4]), &rrclass_in, 2 );
  return( 6 );
  } /* Put_RRec_LSP */

int Put_RRec_TTL( uchar *rrec, int offset, ulong ttl )
  /* ---------------------------------------------------- **
   * Write the TTL value at rrec[offset].
   *
   * By this point it should be obvious that functions or
   * macros for transferring long and short integers to
   * and from packet buffers would be a good idea.
   * ---------------------------------------------------- **
   */
  {
  ttl = htonl( ttl );

  (void)memcpy( &(rrec[offset]), &ttl, 4 );
  return( 4 );
  } /* Put_RRec_TTL */


int Is_RRec_LSP( const uchar *rrec )
  /* ---------------------------------------------------- **
   * Check the Resource Record to see if the name field
   * is actually a Label String Pointer.
   *
   * If the name is not an LSP, the function returns 0.
   *
   * If the name is a valid LSP, the function returns 12
   * (which is the offset into the received packet at
   * which the QUERY_NAME can be found).
   *
   * If the name contains an invalid label length, or
   * an invalid LSP, the function will return -1.
   * ---------------------------------------------------- **
   */
  {
  if( 0 == (0xC0 & rrec[0]) )
    return( 0 );  /* Not an LSP */

  if( (0xC0 == rrec[0]) && (0x0C == rrec[1]) )
    return( 12 ); /* Valid LSP */

  return( -1 );   /* Bogon */
  } /* Is_RRec_LSP */


ushort Get_RR_type( const uchar *rrec, int offset )
  /* ---------------------------------------------------- **
   * Read the RR_TYPE value.  The offset can be
   * determined by decoding the NBT name using the
   * L2_Decode() function from listing 1.4.
   * ---------------------------------------------------- **
   */
  {
  ushort tmp;

  /* Read the two bytes from the packet.
   */
  (void)memcpy( &tmp, &(rrec[offset]), 2 );

  /* Convert to host byte order and return. */
  return( ntohs( tmp ) );
  } /* Get_RR_type */

ulong Get_RRec_TTL( const uchar *rrec, int offset )
  /* ---------------------------------------------------- **
   * Read the TTL value.
   * ---------------------------------------------------- **
   */
  {
  ulong tmp;

  (void)memcpy( &tmp, &(rrec[offset]), 4 );
  return( ntohl( tmp ) );
  } /* Get_RRec_TTL */


$Revision: 1.12 $
$Date: 2003/02/18 21:43:58 $
[W3C Validated] Copyright © 1999-2003 Christopher R. Hertel 
Released under the terms of the LGPL