2 * netbios dial, read, write
14 MAXNBPKT = 8096, /* max netbios packet size */
15 NBquery = 0, /* packet type - query */
17 NBAdapterStatus = 0x21, /* get host interface info */
18 NBInternet = 1, /* scope for info */
20 NBmessage = 0x00, /* Netbios packet types */
31 static char *NBerr[] = {
32 [0] "not listening on called name",
33 [1] "not listening for calling name",
34 [2] "called name not present",
35 [3] "insufficient resources",
36 [15] "unspecified error"
63 Gmem(uchar **p, void *v, int n)
88 PB16(uchar **p, uint n)
102 nbname(uchar **p, char *name, char pad)
109 for(i = 0; i < 16; i++) {
111 if(!done && name[i] == '\0')
114 c = toupper(name[i]);
115 *(*p)++ = ((uchar)c >> 4) + 'A';
116 *(*p)++ = (c & 0xf) + 'A';
122 calledname(char *host, char *name)
127 int num, flg, svs, j, i, fd, trn;
129 trn = (getpid() ^ time(0)) & 0xffff;
130 if((addr = netmkaddr(host, "udp", "137")) == nil)
133 if((fd = dial(addr, "137", 0, 0)) < 0)
137 PB16(&p, trn); /* TRNid */
138 P8(&p, 0); /* flags */
139 P8(&p, 0x10); /* type */
140 PB16(&p, 1); /* # questions */
141 PB16(&p, 0); /* # answers */
142 PB16(&p, 0); /* # authority RRs */
143 PB16(&p, 0); /* # Aditional RRs */
145 PB16(&p, NBAdapterStatus);
146 PB16(&p, NBInternet);
148 if(Debug && strstr(Debug, "dump"))
151 if(write(fd, buf, p-buf) != p-buf)
155 for(i = 0; i < 3; i++){
156 memset(buf, 0, sizeof(buf));
158 read(fd, buf, sizeof(buf));
168 num = G8(&p); /* number of names */
170 for(i = 0; i < num; i++){
171 memset(tmp, 0, sizeof(tmp));
175 for(j = 14; j >= 0 && tmp[j] == ' '; j--)
177 if(svs == 0 && !(flg & ISgroup))
185 nbtdial(char *addr, char *called, char *sysname)
188 uchar *p, *lenp, buf[1024];
189 int type, len, err, fd, nkeepalive, nretarg;
194 if((addr = netmkaddr(addr, "tcp", "139")) == nil ||
195 (fd = dial(addr, 0, 0, 0)) < 0)
198 memset(buf, 0, sizeof(buf));
201 P8(&p, NBrequest); /* type */
202 P8(&p, 0); /* flags */
203 lenp = p; PB16(&p, 0); /* length placeholder */
204 nbname(&p, called, ' '); /* remote NetBios name */
205 nbname(&p, sysname, ' '); /* our machine name */
206 PB16(&lenp, p-lenp -2); /* length re-write */
208 if(Debug && strstr(Debug, "dump"))
210 if(write(fd, buf, p-buf) != p-buf)
214 memset(buf, 0, sizeof(buf));
215 if(readn(fd, buf, 4) < 4)
222 if(readn(fd, buf +4, len -4) < len -4)
225 if(Debug && strstr(Debug, "dump"))
233 werrstr("nbdial: bad error pkt");
237 if(err < 0 || err > nelem(NBerr) || NBerr[err] == nil)
238 werrstr("NBT: %d - unknown error", err);
240 werrstr("NBT: %s", NBerr[err]);
244 if(++nkeepalive >= 16){
245 werrstr("nbdial: too many keepalives");
251 if(++nretarg >= 16) {
252 werrstr("nbdial: too many redirects");
256 werrstr("nbdial: bad redirect pkt");
259 sprint(redir, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
264 werrstr("nbdial: 0x%x - unknown packet in netbios handshake", type);
276 memset(p->buf, 0xa5, MTU);
278 p8(p, NBmessage); /* type */
279 p8(p, 0); /* flags */
280 pb16(p, 0); /* length (filled in later) */
286 int len, got, type, nkeep;
288 len = p->pos - p->buf;
291 pb16(p, len - NBHDRLEN); /* length */
293 if(Debug && strstr(Debug, "dump"))
294 xd("tx", p->buf, len);
297 if(write(p->s->fd, p->buf, len) != len){
298 werrstr("nbtrpc: write failed - %r");
306 memset(p->buf, 0xa5, MTU);
308 got = readn(p->s->fd, p->buf, NBHDRLEN);
311 werrstr("nbtrpc: short read - %r");
315 p->eop = p->buf + got;
317 type = g8(p); /* NBT type (session) */
318 if(type == NBkeepalive){
320 werrstr("nbtrpc: too many keepalives (%d attempts)", nkeep);
327 g8(p); /* NBT flags (none) */
329 len = gb16(p); /* NBT payload length */
330 if((len +NBHDRLEN) > MTU){
331 werrstr("nbtrpc: packet bigger than MTU, (%d > %d)", len, MTU);
336 got = readn(p->s->fd, p->buf +NBHDRLEN, len);
339 if(Debug && strstr(Debug, "dump"))
340 xd("rx", p->buf, got +NBHDRLEN);
344 p->eop = p->buf + got +NBHDRLEN;
350 xd(char *str, void *buf, int n)
352 int fd, flg, flags2, cmd;
361 end = (uchar *)buf +n;
363 if(Debug && strstr(Debug, "log") != nil){
364 if((fd = open("pkt.log", ORDWR)) == -1)
367 fprint(fd, "%d ", 0);
369 fprint(fd, "%02x ", *p++);
378 p = (uchar *)buf + 4;
379 if(GL32(&p) == 0x424d53ff){
380 buf = (uchar *)buf + 4;
383 end = (uchar *)buf + n;
391 fprint(2, "%s : len=%ud sum=%d\n", str, n, sum);
393 fprint(2, "mag=0x%ulx ", GL32(&p));
394 fprint(2, "cmd=0x%ux ", cmd = G8(&p));
395 fprint(2, "err=0x%ulx ", err=GL32(&p));
396 fprint(2, "flg=0x%02ux ", flg = G8(&p));
397 fprint(2, "flg2=0x%04ux\n", flags2= GL16(&p));
398 fprint(2, "dfs=%s\n", (flags2 & FL2_DFS)? "y": "n");
400 fprint(2, "pidl=%ud ", GL16(&p));
401 fprint(2, "res=%uld ", GL32(&p));
402 fprint(2, "sid=%ud ", GL16(&p));
403 fprint(2, "seq=0x%ux ", GL16(&p));
404 fprint(2, "pad=%ud ", GL16(&p));
406 fprint(2, "tid=%ud ", GL16(&p));
407 fprint(2, "pid=%ud ", GL16(&p));
408 fprint(2, "uid=%ud ", GL16(&p));
409 fprint(2, "mid=%ud\n", GL16(&p));
411 if(cmd == 0x32 && (flg & 0x80) == 0){ /* TRANS 2, TX */
412 fprint(2, "words=%ud ", G8(&p));
413 fprint(2, "totparams=%ud ", GL16(&p));
414 fprint(2, "totdata=%ud ", GL16(&p));
415 fprint(2, "maxparam=%ud ", GL16(&p));
416 fprint(2, "maxdata=%ud\n", GL16(&p));
417 fprint(2, "maxsetup=%ud ", G8(&p));
418 fprint(2, "reserved=%ud ", G8(&p));
419 fprint(2, "flags=%ud ", GL16(&p));
420 fprint(2, "timeout=%uld\n", GL32(&p));
421 fprint(2, "reserved=%ud ", GL16(&p));
422 fprint(2, "paramcnt=%ud ", GL16(&p));
423 fprint(2, "paramoff=%ud ", GL16(&p));
424 fprint(2, "datacnt=%ud ", GL16(&p));
425 fprint(2, "dataoff=%ud ", GL16(&p));
426 fprint(2, "setupcnt=%ud ", G8(&p));
427 fprint(2, "reserved=%ud\n", G8(&p));
428 fprint(2, "trans2=0x%02x ", GL16(&p));
429 fprint(2, "data-words=%d ", G8(&p));
430 fprint(2, "padding=%d\n", G8(&p));
432 if(cmd == 0x32 && (flg & 0x80) == 0x80){ /* TRANS 2, RX */
433 fprint(2, "words=%ud ", G8(&p));
434 fprint(2, "totparams=%ud ", GL16(&p));
435 fprint(2, "totdata=%ud ", GL16(&p));
436 fprint(2, "reserved=%ud ", GL16(&p));
437 fprint(2, "paramcnt=%ud\n", GL16(&p));
438 fprint(2, "paramoff=%ud ", GL16(&p));
439 fprint(2, "paramdisp=%ud ", GL16(&p));
440 fprint(2, "datacnt=%ud\n", GL16(&p));
441 fprint(2, "dataoff=%ud ", GL16(&p));
442 fprint(2, "datadisp=%ud ", GL16(&p));
443 fprint(2, "setupcnt=%ud ", G8(&p));
444 fprint(2, "reserved=%ud\n", G8(&p));
447 if(flags2 & FL2_NT_ERRCODES)
448 fprint(2, "err=%s\n", nterrstr(err));
450 fprint(2, "err=%s\n", doserrstr(err));
454 if((p - (uchar *)buf) % 16 == 0)
455 fprint(2, "\n%06zx\t", p - (uchar *)buf);
456 if(isprint((char)*p))
457 fprint(2, "%c ", (char )*p);
459 fprint(2, "%02ux ", *p);