Listing 1.13
Node Status Request


void Hex_Print( uchar *src, int len )
  /* ---------------------------------------------------- **
   * Print len bytes of src.  Escape any non-printing
   * characters.
   * ---------------------------------------------------- **
   */
  {
  int i;

  for( i = 0; i < len; i++ )
    {
    if( isprint( src[i] ) )
      putchar( src[i] );
    else
      printf( "\\x%.2x", src[i] );
    }
  } /* Hex_Print */


void SendMsg( int            sock,
              uchar         *msg,
              int            msglen,
              struct in_addr address )
  /* ---------------------------------------------------- **
   * Send a message to port UDP/137 at the
   * specified IP address.
   * ---------------------------------------------------- **
   */
  {
  int                result;
  struct sockaddr_in to;
    
  to.sin_addr   = address;
  to.sin_family = AF_INET;
  to.sin_port   = htons( 137 );
  result = sendto( sock, (void *)msg, msglen, 0,
                   (struct sockaddr *)&to,
                   sizeof(struct sockaddr_in) );
  if( result < 0 )
    {
    perror( "sendto()" );
    exit( EXIT_FAILURE );
    }
  } /* SendMsg */


void ReadStatusReply( int sock )
  /* ---------------------------------------------------- **
   * Read the Node Status Response message, parse the
   * NODE_NAME[] entries, and print everything in a
   * readable format.
   * ---------------------------------------------------- **
   */
  {
  uchar  bufr[1024];
  ushort flags;
  int    msglen;
  int    offset;
  int    num_names;
  int    i;

  /* Read the message. */
  msglen = recv( sock, bufr, 1024, 0 );
  if( msglen < 0 )
    {
    perror( "recv()" );
    exit( EXIT_FAILURE );
    }

  /* Find start of RDATA (two bytes beyond RDLENGTH). */
  offset = 2 + Find_RDLength( bufr );

  /* The NUM_NAMES field is one byte long. */
  num_names = bufr[offset++];

  /* Now go through and print each name entry. */
  for( i = 0; i < num_names; i++, offset += 18 )
    {
    flags = (bufr[offset+16] << 8) | bufr[offset+17];

    printf( "NODE_NAME[%d]: ", i );
    Hex_Print( &bufr[offset], 15 );
    printf( "<%.2x>\t", bufr[offset+15] );

    /* Group or Unique. */
    printf( "[%c", ( GROUP_BIT & flags ) ? 'G' : 'U' );

    /* The owner node type. */
    switch( ONT_MASK & flags )
      {
      case ONT_B: printf( ",B" ); break;
      case ONT_P: printf( ",P" ); break;
      case ONT_M: printf( ",M" ); break;
      case ONT_H: printf( ",H" ); break;
      }

    /* Additional flags */
    if( DRG & flags )
      printf( ",DRG" );
    if( CNF & flags )
      printf( ",CNF" );
    if( ACT & flags )
      printf( ",ACT" );
    if( PRM & flags )
      printf( ",PRM" );

    printf( "]\n" );
    }

  /* Windows systems will also send the MAC address. */
  printf( "MAC: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
          bufr[offset], bufr[offset+1], bufr[offset+2],
          bufr[offset+3], bufr[offset+4], bufr[offset+5] );
  } /* ReadStatusReply */


int main( int argc, char *argv[] )
  /* ---------------------------------------------------- **
   * NBT Node Status Request.
   * ---------------------------------------------------- **
   */
  {
  int            i;
  int            result;
  int            ns_sock;
  int            msg_len;
  uchar          bufr[512];
  struct in_addr address;

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

  if( 0 == inet_aton( argv[1], &address ) )
    {
    printf( "Invalid IP.\n" );
    printf( "Usage:  %s <IP>\n", argv[0] );
    exit( EXIT_FAILURE );
    }

  ns_sock = OpenSocket();

  msg_len = BuildQuery( bufr,  /* Target buffer.   */
                        0,     /* Broadcast false. */
                        0,     /* RD bit false.    */
                        "*",   /* NetBIOS Name.    */
                        '\0',  /* Padding (nul).   */
                        '\0',  /* Suffix (0x00).   */
                        "",    /* Scope ("").      */
                        QTYPE_NBSTAT );

  for( i = 0; i < 3; i++ )
    {
    printf( "Sending NODE STATUS query to %s...\n", argv[1] );
    SendMsg( ns_sock, bufr, msg_len, address );
    result = AwaitResponse( ns_sock, 750 );
    if( result )
      {
      ReadStatusReply( ns_sock );
      exit( EXIT_SUCCESS );
      }
    }
  printf( "No replies received.\n" );

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


$Revision: 1.5 $
$Date: 2004/09/16 17:13:15 $
[W3C Validated] Copyright © 2001-2003 Christopher R. Hertel 
Released under the terms of the LGPL