|
Listing 1.3 Simple Broadcast Name Query
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <ctype.h>
#define NBT_BCAST_ADDR "255.255.255.255"
#ifndef uchar
#define uchar unsigned char
#endif /* uchar */
uchar header[] =
{
0x07, 0xAC, /* 1964 == 0x07AC. */
0x01, 0x10, /* Binary 0 0000 0010001 0000 */
0x00, 0x01, /* One name query. */
0x00, 0x00, /* Zero answers. */
0x00, 0x00, /* Zero authorities. */
0x00, 0x00 /* Zero additional. */
};
uchar query_tail[] =
{
0x00, 0x20,
0x00, 0x01
};
uchar *L1_Encode( uchar *dst,
const uchar *name,
const uchar pad,
const uchar sfx )
{
int i = 0;
int j = 0;
int k = 0;
while( ('\0' != name[i]) && (i < 15) )
{
k = toupper( name[i++] );
dst[j++] = 'A' + ((k & 0xF0) >> 4);
dst[j++] = 'A' + (k & 0x0F);
}
i = 'A' + ((pad & 0xF0) >> 4);
k = 'A' + (pad & 0x0F);
while( j < 30 )
{
dst[j++] = i;
dst[j++] = k;
}
dst[30] = 'A' + ((sfx & 0xF0) >> 4);
dst[31] = 'A' + (sfx & 0x0F);
dst[32] = '\0';
return( dst );
} /* L1_Encode */
int L2_Encode( uchar *dst,
const uchar *name,
const uchar pad,
const uchar sfx,
const uchar *scope )
{
int lenpos;
int i;
int j;
if( NULL == L1_Encode( &dst[1], name, pad, sfx ) )
return( -1 );
dst[0] = 0x20;
lenpos = 33;
if( '\0' != *scope )
{
do
{
for( i = 0, j = (lenpos + 1);
('.' != scope[i]) && ('\0' != scope[i]);
i++, j++)
dst[j] = toupper( scope[i] );
dst[lenpos] = (uchar)i;
lenpos += i + 1;
scope += i;
} while( '.' == *(scope++) );
dst[lenpos] = '\0';
}
return( lenpos + 1 );
} /* L2_Encode */
void Send_Nbtn_Bcast( uchar *msg, int msglen )
{
int s;
int true = 1;
struct sockaddr_in sox;
s = socket( PF_INET, SOCK_DGRAM, IPPROTO_UDP );
if( s < 0 )
{
perror( "Socket()" );
exit( 0 );
}
if( setsockopt( s, SOL_SOCKET, SO_BROADCAST,
&true, sizeof(int) ) < 0 )
{
perror( "Setsockopt()" );
exit( 0 );
}
if( 0 == inet_aton( NBT_BCAST_ADDR, &(sox.sin_addr) ) )
{
printf( "Invalid IP address.\n" );
exit( 0 );
}
sox.sin_family = AF_INET;
sox.sin_port = htons( 137 );
if( sendto( s,
(void *)msg,
msglen,
0,
(struct sockaddr *)&sox,
sizeof(struct sockaddr_in) ) < 0 )
{
perror( "Sendto()" );
exit( 0 );
}
close( s );
} /* Send_Nbtn_Bcast */
int main( int argc, char *argv[] )
{
uchar bufr[512];
int len;
int total_len;
uchar *name;
uchar *scope;
if( argc > 1 )
name = (uchar *)argv[1];
else
exit( EXIT_FAILURE );
if( argc > 2 )
scope = (uchar *)argv[2];
else
scope = "";
(void)memcpy( bufr, header, (total_len = sizeof(header)) );
len = L2_Encode( &bufr[total_len], name, ' ', '\0', scope );
if( len < 0 )
return( EXIT_FAILURE );
total_len += len;
(void)memcpy( &bufr[total_len], query_tail, sizeof( query_tail ) );
total_len += sizeof( query_tail );
Send_Nbtn_Bcast( bufr, total_len );
return( EXIT_SUCCESS );
} /* main */
$Revision: 1.24 $
$Date: 2007/10/14 18:21:27 $
|
Copyright © 1999-2003 Christopher R. Hertel
Released under the terms of the
LGPL
|
|