xref: /plan9/sys/src/cmd/aquarela/client.c (revision ea58ad6fbee60d5a3fca57ac646881779dd8f0ea)
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
warning(char * fmt,...)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
udpannounce(void)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
listen137(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
usage(void)97 usage(void)
98 {
99 	fprint(2, "usage: %s [-u ipaddr] name\n", argv0);
100 	exits("usage");
101 }
102 
103 void
threadmain(int argc,char ** argv)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 }
146