1 #include <u.h> 2 #include <libc.h> 3 #include <ip.h> 4 #include <thread.h> 5 #include "netbios.h" 6 7 int 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