|
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 $
|
Copyright © 2001-2003 Christopher R. Hertel
Released under the terms of the
LGPL
|
|