Introduce files for new e1000 driver
[gpxe.git] / src / proto / nmb.c
blobe1fc911e4bbd51bf4511df2606cccdce237944f6
1 #if 0
3 #include "resolv.h"
4 #include "string.h"
5 #include <gpxe/dns.h>
6 #include "nic.h"
7 #include "nmb.h"
9 /*
10 * Convert a standard NUL-terminated string to an NBNS query name.
12 * Returns a pointer to the character following the constructed NBNS
13 * query name.
16 static inline char * nbns_make_name ( char *dest, const char *name ) {
17 char nb_name[16];
18 char c;
19 int i;
20 uint16_t *d;
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 );
30 nb_name[15] = '\0';
31 memcpy ( nb_name, name, strlen ( name ) ); /* Do not copy NUL */
33 d = ( uint16_t * ) dest;
34 for ( i = 0 ; i < 16 ; i++ ) {
35 c = nb_name[i];
36 *( d++ ) = htons ( ( ( c | ( c << 4 ) ) & 0x0f0f ) + 0x4141 );
38 dest = ( char * ) d;
40 *(dest++) = 0; /* Terminating 0-length name component */
41 return dest;
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 ) ),
75 &nameserver );
76 if ( ! reply ) {
77 DBG ( "NMB got no response via %@ (port %d)\n",
78 nameserver.sin_addr.s_addr,
79 nameserver.sin_port );
80 return 0;
83 /* Search through response for useful answers. */
84 rr_info = dns_find_rr ( &query, reply );
85 if ( ! rr_info ) {
86 DBG ( "NMB got invalid response\n" );
87 return 0;
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 );
94 return 0;
97 /* Read response */
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 );
102 return 1;
105 struct resolver nmb_resolver __resolver = {
106 .name = "NMB",
107 .resolv = nmb_resolv,
110 #endif