Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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
}