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