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