Listing 1.11
Broadcast Name Query Revisited


#include <stdio.h>
#include <stdlib.h>
#include <sys/poll.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

#include "NS_Header.h"
#include "NS_Qrec.h"


#define uchar  unsigned char
#define ushort unsigned short


int BuildQuery( uchar         *msg,
                const int      bcast,
                const int      rdbit,
                const uchar   *name,
                const uchar    pad,
                const uchar    suffix,
                const uchar   *scope,
                const ushort   qtype )
  /* ---------------------------------------------------- **
   * Create a name query.
   *
   * This is much more flexible than the registration
   * example in listing 1.10.  There are also a lot more
   * parameters.  :-)
   * ---------------------------------------------------- **
   */
  {
  ushort *hdr = (ushort *)msg;
  ushort  flags;
  int     len;

  /* RD always set if B is set. */
  if( bcast )
    flags = NM_RD_BIT | NM_B_BIT;
  else
    flags = rdbit ? NM_RD_BIT : 0;

  Put_NS_TID( hdr, 1964 );
  Put_NS_Hdr_Flags( hdr, flags );
  Put_NS_Hdr_Rec_Counts( hdr, QUERYREC );
  len = 12;     /* Fixed size of header. */

  len += Put_Qrec( &msg[len], /* Query Rec Pointer */
                   name,      /* NetBIOS name      */
                   pad,       /* Padding char      */
                   suffix,    /* Suffix            */
                   scope,     /* Scope ID          */
                   qtype );   /* Query type        */

  return( len );
  } /* BuildQuery */


void ReadQueryReply( int sock )
  /* ---------------------------------------------------- **
   * Read the query reply message(s).
   * ---------------------------------------------------- **
   */
  {
  uchar  bufr[512];
  int    msglen;
  ushort flags;

  msglen = recv( sock, bufr, 512, 0 );
  if( msglen < 0 )
    {
    perror( "recv()" );
    exit( EXIT_FAILURE );
    }

  if( msglen < 12 )
    {
    printf( "Truncated reply received.\n" );
    exit( EXIT_FAILURE );
    }

  flags = Get_NS_Hdr_Flags( (ushort *)bufr );
  switch( RCODE_MASK & flags )
    {
    case RCODE_POS_RSP:
      printf( "Positive Name Query Response.\n" );
      break;
    case RCODE_FMT_ERR:
      printf( "RCODE_FMT_ERR: Format Error.\n" );
      break;
    case RCODE_SRV_ERR:
      printf( "RCODE_SRV_ERR: Server Error.\n" );
      break;
    case RCODE_NAM_ERR:
      printf( "RCODE_NAM_ERR: Name Not Found.\n" );
      break;
    default:
      printf( "Unexpected return code: 0x%.2x.\n",
              (RCODE_MASK & flags) );
      break;
    }
  
  } /* ReadQueryReply */


int main( int argc, char *argv[] )
  /* ---------------------------------------------------- **
   * This program demonstrates a Broadcast NBT Name Query.
   * ---------------------------------------------------- **
   */
  {
  int                i;
  int                result;
  int                ns_sock;
  int                msg_len;
  uchar              bufr[512];
  uchar             *name;

  if( argc != 2 )
    {
    printf( "Usage:  %s <name>\n", argv[0] );
    exit( EXIT_FAILURE );
    }

  name = (uchar *)argv[1];

  ns_sock = OpenSocket();

  msg_len = BuildQuery( bufr,  /* Target buffer.   */
                        1,     /* Broadcast true.  */
                        1,     /* RD bit true.     */
                        name,  /* NetBIOS Name.    */
                        ' ',   /* Padding (space). */
                        '\0',  /* Suffix (0x00).   */
                        "",    /* Scope ("").      */
                        QTYPE_NB ); /* Query type. */

  for( i = 0; i < 3; i++ )
    {
    printf( "Trying...\n" );
    SendBcastMsg( ns_sock, bufr, msg_len );
    result = AwaitResponse( ns_sock, 750 );
    if( result )
      {
      do
        {
        /* We may get multiple replies. */
        ReadQueryReply( ns_sock );
        } while( AwaitResponse( ns_sock, 750 ) );
      exit( EXIT_SUCCESS );
      }
    }
  printf( "No replies received.\n" );

  close( ns_sock );
  return( EXIT_FAILURE );
  } /* main */


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