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 ) {
19 *(dest++) = 32; /* Length is always 32 */
21 /* Name encoding is as follows: pad the name with spaces to
22 * length 15, and add a NUL. Take this 16-byte string, split
23 * it into nibbles and add 0x41 to each nibble to form a byte
24 * of the resulting name string.
26 memset ( nb_name, ' ', 15 );
28 memcpy ( nb_name, name, strlen ( name ) ); /* Do not copy NUL */
29 for ( i = 0 ; i < 16 ; i++ ) {
31 *( ( ( uint16_t * ) dest ) ++ ) =
32 htons ( ( ( c | ( c << 4 ) ) & 0x0f0f ) + 0x4141 );
35 *(dest++) = 0; /* Terminating 0-length name component */
40 * Resolve a name using NMB
43 static int nmb_resolv ( struct in_addr *addr, const char *name ) {
44 struct dns_query query;
45 struct dns_query_info *query_info;
46 struct dns_header *reply;
47 struct dns_rr_info *rr_info;
48 struct dns_rr_info_nb *rr_info_nb;
49 struct sockaddr_in nameserver;
51 DBG ( "NMB resolving %s\n", name );
53 /* Set up the query data */
54 nameserver.sin_addr.s_addr = IP_BROADCAST;
55 nameserver.sin_port = NBNS_UDP_PORT;
56 memset ( &query, 0, sizeof ( query ) );
57 query.dns.id = htons ( 1 );
58 query.dns.flags = htons ( DNS_FLAG_QUERY | DNS_FLAG_OPCODE_QUERY |
59 DNS_FLAG_RD | DNS_FLAG_BROADCAST );
60 query.dns.qdcount = htons ( 1 );
61 query_info = ( void * ) nbns_make_name ( query.payload, name );
62 query_info->qtype = htons ( DNS_TYPE_NB );
63 query_info->qclass = htons ( DNS_CLASS_IN );
65 /* Issue query, wait for reply */
66 reply = dns_query ( &query,
67 ( ( ( char * ) query_info )
68 + sizeof ( *query_info )
69 - ( ( char * ) &query ) ),
72 DBG ( "NMB got no response via %@ (port %d)\n",
73 nameserver.sin_addr.s_addr,
74 nameserver.sin_port );
78 /* Search through response for useful answers. */
79 rr_info = dns_find_rr ( &query, reply );
81 DBG ( "NMB got invalid response\n" );
85 /* Check type of response */
86 if ( ntohs ( rr_info->type ) != DNS_TYPE_NB ) {
87 DBG ( "NMB got answer type %hx (wanted %hx)\n",
88 ntohs ( rr_info->type ), DNS_TYPE_NB );
93 rr_info_nb = ( struct dns_rr_info_nb * ) rr_info;
94 *addr = rr_info_nb->nb_address;
95 DBG ( "NMB found address %@\n", addr->s_addr );
100 static struct resolver nmb_resolver __resolver = {
102 .resolv = nmb_resolv,