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