xref: /plan9-contrib/sys/src/cmd/aquarela/client.c (revision ea58ad6fbee60d5a3fca57ac646881779dd8f0ea)
18ccd4a63SDavid du Colombier #include <u.h>
28ccd4a63SDavid du Colombier #include <libc.h>
38ccd4a63SDavid du Colombier #include <ip.h>
48ccd4a63SDavid du Colombier #include <thread.h>
58ccd4a63SDavid du Colombier #include "netbios.h"
68ccd4a63SDavid du Colombier 
78ccd4a63SDavid du Colombier static char *hmsg = "headers";
88ccd4a63SDavid du Colombier int chatty = 1;
98ccd4a63SDavid du Colombier 
108ccd4a63SDavid du Colombier void
warning(char * fmt,...)118ccd4a63SDavid du Colombier warning(char *fmt, ...)
128ccd4a63SDavid du Colombier {
138ccd4a63SDavid du Colombier 	char err[128];
148ccd4a63SDavid du Colombier 	va_list arg;
158ccd4a63SDavid du Colombier 
168ccd4a63SDavid du Colombier 	va_start(arg, fmt);
178ccd4a63SDavid du Colombier 	vseprint(err, err+sizeof(err), fmt, arg);
188ccd4a63SDavid du Colombier 	va_end(arg);
198ccd4a63SDavid du Colombier 	syslog(1, "netbios-ns", err);
208ccd4a63SDavid du Colombier 	if (chatty)
218ccd4a63SDavid du Colombier 		print("%s\n", err);
228ccd4a63SDavid du Colombier }
238ccd4a63SDavid du Colombier 
248ccd4a63SDavid du Colombier static int
udpannounce(void)258ccd4a63SDavid du Colombier udpannounce(void)
268ccd4a63SDavid du Colombier {
278ccd4a63SDavid du Colombier 	int data, ctl;
288ccd4a63SDavid du Colombier 	char dir[64];
298ccd4a63SDavid du Colombier 	char datafile[64+6];
308ccd4a63SDavid du Colombier 
318ccd4a63SDavid du Colombier 	/* get a udp port */
328ccd4a63SDavid du Colombier 	ctl = announce("udp!*!netbios-ns", dir);
338ccd4a63SDavid du Colombier 	if(ctl < 0){
348ccd4a63SDavid du Colombier 		warning("can't announce on netbios-ns udp port");
358ccd4a63SDavid du Colombier 		return -1;
368ccd4a63SDavid du Colombier 	}
378ccd4a63SDavid du Colombier 	snprint(datafile, sizeof(datafile), "%s/data", dir);
388ccd4a63SDavid du Colombier 
398ccd4a63SDavid du Colombier 	/* turn on header style interface */
408ccd4a63SDavid du Colombier 	if(write(ctl, hmsg, strlen(hmsg)) , 0)
418ccd4a63SDavid du Colombier 		abort(); /* hmsg */;
428ccd4a63SDavid du Colombier 	data = open(datafile, ORDWR);
438ccd4a63SDavid du Colombier 	if(data < 0){
448ccd4a63SDavid du Colombier 		close(ctl);
458ccd4a63SDavid du Colombier 		warning("can't announce on dns udp port");
468ccd4a63SDavid du Colombier 		return -1;
478ccd4a63SDavid du Colombier 	}
488ccd4a63SDavid du Colombier 
498ccd4a63SDavid du Colombier 	close(ctl);
508ccd4a63SDavid du Colombier 	return data;
518ccd4a63SDavid du Colombier }
528ccd4a63SDavid du Colombier 
538ccd4a63SDavid du Colombier #define BROADCAST 1
548ccd4a63SDavid du Colombier 
558ccd4a63SDavid du Colombier 
568ccd4a63SDavid du Colombier void
listen137(void *)578ccd4a63SDavid du Colombier listen137(void *)
588ccd4a63SDavid du Colombier {
598ccd4a63SDavid du Colombier 	for (;;) {
608ccd4a63SDavid du Colombier 		uchar msg[Udphdrsize + 576];
618ccd4a63SDavid du Colombier 		int len = read(fd137, msg, sizeof(msg));
628ccd4a63SDavid du Colombier 		if (len < 0)
638ccd4a63SDavid du Colombier 			break;
648ccd4a63SDavid du Colombier 		if (len >= Udphdrsize) {
658ccd4a63SDavid du Colombier 			NbnsMessage *s;
668ccd4a63SDavid du Colombier 			Udphdr *uh;
678ccd4a63SDavid du Colombier 			uchar *p;
688ccd4a63SDavid du Colombier 
698ccd4a63SDavid du Colombier 			uh = (Udphdr*)msg;
708ccd4a63SDavid du Colombier 			p = msg + Udphdrsize;
718ccd4a63SDavid du Colombier 			len -= Udphdrsize;
728ccd4a63SDavid du Colombier 			s = nbnsconvM2S(p, len);
738ccd4a63SDavid du Colombier 			if (s) {
748ccd4a63SDavid du Colombier 				print("%I:%d -> %I:%d\n", uh->raddr, nhgets(uh->rport), uh->laddr, nhgets(uh->lport));
758ccd4a63SDavid du Colombier 				nbnsdumpmessage(s);
768ccd4a63SDavid du Colombier 				if (s->response) {
778ccd4a63SDavid du Colombier 					NbnsTransaction *t;
788ccd4a63SDavid du Colombier 					qlock(&transactionlist);
798ccd4a63SDavid du Colombier 					for (t = transactionlist.head; t; t = t->next)
808ccd4a63SDavid du Colombier 						if (t->id == s->id)
818ccd4a63SDavid du Colombier 							break;
828ccd4a63SDavid du Colombier 					if (t) {
838ccd4a63SDavid du Colombier 						sendp(t->c, s);
848ccd4a63SDavid du Colombier 					}
858ccd4a63SDavid du Colombier 					else
868ccd4a63SDavid du Colombier 						nbnsmessagefree(&s);
878ccd4a63SDavid du Colombier 					qunlock(&transactionlist);
888ccd4a63SDavid du Colombier 				}
898ccd4a63SDavid du Colombier 				else
908ccd4a63SDavid du Colombier 					nbnsmessagefree(&s);
918ccd4a63SDavid du Colombier 			}
928ccd4a63SDavid du Colombier 		}
938ccd4a63SDavid du Colombier 	}
948ccd4a63SDavid du Colombier }
958ccd4a63SDavid du Colombier 
968ccd4a63SDavid du Colombier void
usage(void)978ccd4a63SDavid du Colombier usage(void)
988ccd4a63SDavid du Colombier {
99*ea58ad6fSDavid du Colombier 	fprint(2, "usage: %s [-u ipaddr] name\n", argv0);
100*ea58ad6fSDavid du Colombier 	exits("usage");
1018ccd4a63SDavid du Colombier }
1028ccd4a63SDavid du Colombier 
1038ccd4a63SDavid du Colombier void
threadmain(int argc,char ** argv)1048ccd4a63SDavid du Colombier threadmain(int argc, char **argv)
1058ccd4a63SDavid du Colombier {
106*ea58ad6fSDavid du Colombier 	int broadcast = 1, i, listen137thread, rv;
107*ea58ad6fSDavid du Colombier 	char *ip;
108*ea58ad6fSDavid du Colombier 	uchar ipaddr[IPaddrlen], serveripaddr[IPaddrlen];
1098ccd4a63SDavid du Colombier 	NbName nbname;
1108ccd4a63SDavid du Colombier 
1118ccd4a63SDavid du Colombier 	ARGBEGIN {
1128ccd4a63SDavid du Colombier 	case 'u':
1138ccd4a63SDavid du Colombier 		broadcast = 0;
114*ea58ad6fSDavid du Colombier 		ip = EARGF(usage());
115*ea58ad6fSDavid du Colombier 		if (parseip(serveripaddr, ip) == -1)
116*ea58ad6fSDavid du Colombier 			sysfatal("bad ip address %s", ip);
1178ccd4a63SDavid du Colombier 		break;
1188ccd4a63SDavid du Colombier 	default:
1198ccd4a63SDavid du Colombier 		usage();
1208ccd4a63SDavid du Colombier 	} ARGEND;
1218ccd4a63SDavid du Colombier 
1228ccd4a63SDavid du Colombier 	if (argc == 0)
123*ea58ad6fSDavid du Colombier 		usage();
1248ccd4a63SDavid du Colombier 
1258ccd4a63SDavid du Colombier 	nbmknamefromstring(nbname, argv[0]);
1268ccd4a63SDavid du Colombier 
1278ccd4a63SDavid du Colombier 	ipifc = readipifc("/net", nil, 0);
128*ea58ad6fSDavid du Colombier 	if (ipifc == nil || ipifc->lifc == nil)
129*ea58ad6fSDavid du Colombier 		sysfatal("no network interface");
1308ccd4a63SDavid du Colombier 	fmtinstall('I', eipfmt);
1318ccd4a63SDavid du Colombier 	ipmove(bcastaddr, ipifc->lifc->ip);
1328ccd4a63SDavid du Colombier 	for (i = 0; i < IPaddrlen; i++)
1338ccd4a63SDavid du Colombier 		bcastaddr[i] |= ~ipifc->lifc->mask[i];
1348ccd4a63SDavid du Colombier 	print("broadcasting to %I\n", bcastaddr);
1358ccd4a63SDavid du Colombier //	setnetmtpt("/net");
1368ccd4a63SDavid du Colombier 	fd137 = udpannounce();
1378ccd4a63SDavid du Colombier 	listen137thread = proccreate(listen137, nil, 16384);
1388ccd4a63SDavid du Colombier 	rv = nbnsaddname(broadcast ? nil : serveripaddr, nbname, 3000, ipifc->lifc->ip);
1398ccd4a63SDavid du Colombier 	if (rv != 0)
1408ccd4a63SDavid du Colombier 		print("error code %d\n", rv);
1418ccd4a63SDavid du Colombier 	else
1428ccd4a63SDavid du Colombier 		print("%I\n", ipaddr);
1438ccd4a63SDavid du Colombier 	nbnsalarmend();
1448ccd4a63SDavid du Colombier 	threadint(listen137thread);
1458ccd4a63SDavid du Colombier }
146