9 * Convert a standard NUL-terminated string to an NBNS query name.
11 * Returns a pointer to the character following the constructed NBNS
15 static inline char * nbns_make_name ( char *dest, const char *name ) {
21 *(dest++) = 32; /* Length is always 32 */
23 /* Name encoding is as follows: pad the name with spaces to
24 * length 15, and add a NUL. Take this 16-byte string, split
25 * it into nibbles and add 0x41 to each nibble to form a byte
26 * of the resulting name string.
28 memset ( nb_name, ' ', 15 );
30 memcpy ( nb_name, name, strlen ( name ) ); /* Do not copy NUL */
32 d = ( uint16_t * ) dest;
33 for ( i = 0 ; i < 16 ; i++ ) {
35 *( d++ ) = htons ( ( ( c | ( c << 4 ) ) & 0x0f0f ) + 0x4141 );
39 *(dest++) = 0; /* Terminating 0-length name component */
44 * Resolve a name using NMB
47 static int nmb_resolv ( struct in_addr *addr, const char *name ) {
48 struct dns_query query;
49 struct dns_query_info *query_info;
50 struct dns_header *reply;
51 struct dns_rr_info *rr_info;
52 struct dns_rr_info_nb *rr_info_nb;
53 struct sockaddr_in nameserver;
55 DBG ( "NMB resolving %s\n", name );
57 /* Set up the query data */
58 nameserver.sin_addr.s_addr = INADDR_BROADCAST;
59 nameserver.sin_port = NBNS_UDP_PORT;
60 memset ( &query, 0, sizeof ( query ) );
61 query.dns.id = htons ( 1 );
62 query.dns.flags = htons ( DNS_FLAG_QUERY | DNS_FLAG_OPCODE_QUERY |
63 DNS_FLAG_RD | DNS_FLAG_BROADCAST );
64 query.dns.qdcount = htons ( 1 );
65 query_info = ( void * ) nbns_make_name ( query.payload, name );
66 query_info->qtype = htons ( DNS_TYPE_NB );
67 query_info->qclass = htons ( DNS_CLASS_IN );
69 /* Issue query, wait for reply */
70 reply = dns_query ( &query,
71 ( ( ( char * ) query_info )
72 + sizeof ( *query_info )
73 - ( ( char * ) &query ) ),
76 DBG ( "NMB got no response via %@ (port %d)\n",
77 nameserver.sin_addr.s_addr,
78 nameserver.sin_port );
82 /* Search through response for useful answers. */
83 rr_info = dns_find_rr ( &query, reply );
85 DBG ( "NMB got invalid response\n" );
89 /* Check type of response */
90 if ( ntohs ( rr_info->type ) != DNS_TYPE_NB ) {
91 DBG ( "NMB got answer type %hx (wanted %hx)\n",
92 ntohs ( rr_info->type ), DNS_TYPE_NB );
97 rr_info_nb = ( struct dns_rr_info_nb * ) rr_info;
98 *addr = rr_info_nb->nb_address;
99 DBG ( "NMB found address %@\n", addr->s_addr );
104 struct resolver nmb_resolver __resolver = {
106 .resolv = nmb_resolv,