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