1 #include <u.h>
2 #include <libc.h>
3 #include <ip.h>
4 #include <thread.h>
5 #include "netbios.h"
6
7 int
nbnsfindname(uchar * serveripaddr,NbName name,uchar * ipaddr,ulong * ttlp)8 nbnsfindname(uchar *serveripaddr, NbName name, uchar *ipaddr, ulong *ttlp)
9 {
10 NbnsMessage *nq;
11 Alt aa[3];
12 int tries = NbnsRetryBroadcast;
13 NbnsAlarm *a;
14 int rv;
15 NbnsMessage *response;
16
17 nq = nbnsmessagenamequeryrequestnew(0, serveripaddr == nil, name);
18 if (nq == nil)
19 return -1;
20 a = nbnsalarmnew();
21 if (a == nil) {
22 free(nq);
23 return -1;
24 }
25 aa[0].c = a->c;
26 aa[0].v = nil;
27 aa[0].op = CHANRCV;
28 aa[1].op = CHANRCV;
29 aa[2].op = CHANEND;
30 while (tries > 0) {
31 NbnsTransaction *t;
32 nq->id = nbnsnextid();
33 t = nbnstransactionnew(nq, serveripaddr);
34 aa[1].c = t->c;
35 aa[1].v = &response;
36 nbnsalarmset(a, NbnsTimeoutBroadcast);
37 for (;;) {
38 int i;
39 i = alt(aa);
40 if (i == 0) {
41 tries--;
42 break;
43 }
44 else if (i == 1) {
45 if (response->opcode == NbnsOpQuery) {
46 nbnstransactionfree(&t);
47 goto done;
48 }
49 nbnsmessagefree(&response);
50 }
51 }
52 nbnstransactionfree(&t);
53 }
54 done:
55 if (tries == 0)
56 rv = -1;
57 else {
58 if (response->rcode != 0)
59 rv = response->rcode;
60 else if (response->an == nil)
61 rv = -1;
62 else {
63 rv = 0;
64 v4tov6(ipaddr, response->an->rdata + 2);
65 if (ttlp)
66 *ttlp = response->an->ttl;
67 }
68 nbnsmessagefree(&response);
69 }
70 nbnsalarmfree(&a);
71 nbnsmessagefree(&nq);
72 return rv;
73 }
74