Subversion Repositories planix.SVN

Rev

Details | 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
static char *hmsg = "headers";
8
int chatty = 1;
9
 
10
void
11
warning(char *fmt, ...)
12
{
13
	char err[128];
14
	va_list arg;
15
 
16
	va_start(arg, fmt);
17
	vseprint(err, err+sizeof(err), fmt, arg);
18
	va_end(arg);
19
	syslog(1, "netbios-ns", err);
20
	if (chatty)
21
		print("%s\n", err);
22
}
23
 
24
static int
25
udpannounce(void)
26
{
27
	int data, ctl;
28
	char dir[64];
29
	char datafile[64+6];
30
 
31
	/* get a udp port */
32
	ctl = announce("udp!*!netbios-ns", dir);
33
	if(ctl < 0){
34
		warning("can't announce on netbios-ns udp port");
35
		return -1;
36
	}
37
	snprint(datafile, sizeof(datafile), "%s/data", dir);
38
 
39
	/* turn on header style interface */
40
	if(write(ctl, hmsg, strlen(hmsg)) , 0)
41
		abort(); /* hmsg */;
42
	data = open(datafile, ORDWR);
43
	if(data < 0){
44
		close(ctl);
45
		warning("can't announce on dns udp port");
46
		return -1;
47
	}
48
 
49
	close(ctl);
50
	return data;
51
}
52
 
53
#define BROADCAST 1
54
 
55
 
56
void
57
listen137(void *)
58
{	
59
	for (;;) {
60
		uchar msg[Udphdrsize + 576];
61
		int len = read(fd137, msg, sizeof(msg));
62
		if (len < 0)
63
			break;
64
		if (len >= Udphdrsize) {
65
			NbnsMessage *s;
66
			Udphdr *uh;
67
			uchar *p;
68
 
69
			uh = (Udphdr*)msg;
70
			p = msg + Udphdrsize;
71
			len -= Udphdrsize;
72
			s = nbnsconvM2S(p, len);
73
			if (s) {
74
				print("%I:%d -> %I:%d\n", uh->raddr, nhgets(uh->rport), uh->laddr, nhgets(uh->lport));
75
				nbnsdumpmessage(s);
76
				if (s->response) {
77
					NbnsTransaction *t;
78
					qlock(&transactionlist);
79
					for (t = transactionlist.head; t; t = t->next)
80
						if (t->id == s->id)
81
							break;
82
					if (t) {
83
						sendp(t->c, s);
84
					}
85
					else
86
						nbnsmessagefree(&s);
87
					qunlock(&transactionlist);
88
				}
89
				else
90
					nbnsmessagefree(&s);
91
			}
92
		}
93
	}
94
}
95
 
96
void
97
usage(void)
98
{
99
	fprint(2, "usage: %s [-u ipaddr] name\n", argv0);
100
	exits("usage");
101
}
102
 
103
void
104
threadmain(int argc, char **argv)
105
{
106
	int broadcast = 1, i, listen137thread, rv;
107
	char *ip;
108
	uchar ipaddr[IPaddrlen], serveripaddr[IPaddrlen];
109
	NbName nbname;
110
 
111
	ARGBEGIN {
112
	case 'u':
113
		broadcast = 0;
114
		ip = EARGF(usage());
115
		if (parseip(serveripaddr, ip) == -1)
116
			sysfatal("bad ip address %s", ip);
117
		break;
118
	default:
119
		usage();
120
	} ARGEND;
121
 
122
	if (argc == 0)
123
		usage();
124
 
125
	nbmknamefromstring(nbname, argv[0]);
126
 
127
	ipifc = readipifc("/net", nil, 0);
128
	if (ipifc == nil || ipifc->lifc == nil)
129
		sysfatal("no network interface");
130
	fmtinstall('I', eipfmt);
131
	ipmove(bcastaddr, ipifc->lifc->ip);
132
	for (i = 0; i < IPaddrlen; i++)
133
		bcastaddr[i] |= ~ipifc->lifc->mask[i];
134
	print("broadcasting to %I\n", bcastaddr);
135
//	setnetmtpt("/net");
136
	fd137 = udpannounce();
137
	listen137thread = proccreate(listen137, nil, 16384);
138
	rv = nbnsaddname(broadcast ? nil : serveripaddr, nbname, 3000, ipifc->lifc->ip);
139
	if (rv != 0)
140
		print("error code %d\n", rv);
141
	else
142
		print("%I\n", ipaddr);
143
	nbnsalarmend();
144
	threadint(listen137thread);
145
}