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)
101 PB16(uchar **p, uint n)
108 P8(uchar **p, uint n)
115 nbname(uchar **p, char *name, char pad)
122 for(i = 0; i < 16; i++) {
124 if(!done && name[i] == '\0')
127 c = toupper(name[i]);
128 *(*p)++ = ((uchar)c >> 4) + 'A';
129 *(*p)++ = (c & 0xf) + 'A';
135 calledname(char *host, char *name)
140 int num, flg, svs, j, i, fd, trn;
142 trn = (getpid() ^ time(0)) & 0xffff;
143 if((addr = netmkaddr(host, "udp", "137")) == nil)
146 if((fd = dial(addr, "137", 0, 0)) < 0)
150 PB16(&p, trn); /* TRNid */
151 P8(&p, 0); /* flags */
152 P8(&p, 0x10); /* type */
153 PB16(&p, 1); /* # questions */
154 PB16(&p, 0); /* # answers */
155 PB16(&p, 0); /* # authority RRs */
156 PB16(&p, 0); /* # Aditional RRs */
158 PB16(&p, NBAdapterStatus);
159 PB16(&p, NBInternet);
161 if(Debug && strstr(Debug, "dump"))
164 if(write(fd, buf, p-buf) != p-buf)
168 for(i = 0; i < 3; i++){
169 memset(buf, 0, sizeof(buf));
171 read(fd, buf, sizeof(buf));
181 num = G8(&p); /* number of names */
183 for(i = 0; i < num; i++){
184 memset(tmp, 0, sizeof(tmp));
188 for(j = 14; j >= 0 && tmp[j] == ' '; j--)
190 if(svs == 0 && !(flg & ISgroup))
198 nbtdial(char *addr, char *called, char *sysname)
201 uchar *p, *lenp, buf[1024];
202 int type, len, err, fd, nkeepalive, nretarg;
207 if((addr = netmkaddr(addr, "tcp", "139")) == nil ||
208 (fd = dial(addr, 0, 0, 0)) < 0)
211 memset(buf, 0, sizeof(buf));
214 P8(&p, NBrequest); /* type */
215 P8(&p, 0); /* flags */
216 lenp = p; PB16(&p, 0); /* length placeholder */
217 nbname(&p, called, ' '); /* remote NetBios name */
218 nbname(&p, sysname, ' '); /* our machine name */
219 PB16(&lenp, p-lenp -2); /* length re-write */
221 if(Debug && strstr(Debug, "dump"))
223 if(write(fd, buf, p-buf) != p-buf)
227 memset(buf, 0, sizeof(buf));
228 if(readn(fd, buf, 4) < 4)
235 if(readn(fd, buf +4, len -4) < len -4)
238 if(Debug && strstr(Debug, "dump"))
246 werrstr("nbdial: bad error pkt");
250 if(err < 0 || err > nelem(NBerr) || NBerr[err] == nil)
251 werrstr("NBT: %d - unknown error", err);
253 werrstr("NBT: %s", NBerr[err]);
257 if(++nkeepalive >= 16){
258 werrstr("nbdial: too many keepalives");
264 if(++nretarg >= 16) {
265 werrstr("nbdial: too many redirects");
269 werrstr("nbdial: bad redirect pkt");
272 sprint(redir, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
277 werrstr("nbdial: 0x%x - unknown packet in netbios handshake", type);
289 memset(p->buf, 0xa5, MTU);
291 p8(p, NBmessage); /* type */
292 p8(p, 0); /* flags */
293 pb16(p, 0); /* length (filled in later) */
299 int len, got, type, nkeep;
301 len = p->pos - p->buf;
304 pb16(p, len - NBHDRLEN); /* length */
306 if(Debug && strstr(Debug, "dump"))
307 xd("tx", p->buf, len);
310 if(write(p->s->fd, p->buf, len) != len){
311 werrstr("nbtrpc: write failed - %r");
319 memset(p->buf, 0xa5, MTU);
321 got = readn(p->s->fd, p->buf, NBHDRLEN);
324 werrstr("nbtrpc: short read - %r");
328 p->eop = p->buf + got;
330 type = g8(p); /* NBT type (session) */
331 if(type == NBkeepalive){
333 werrstr("nbtrpc: too many keepalives (%d attempts)", nkeep);
340 g8(p); /* NBT flags (none) */
342 len = gb16(p); /* NBT payload length */
343 if((len +NBHDRLEN) > MTU){
344 werrstr("nbtrpc: packet bigger than MTU, (%d > %d)", len, MTU);
349 got = readn(p->s->fd, p->buf +NBHDRLEN, len);
352 if(Debug && strstr(Debug, "dump"))
353 xd("rx", p->buf, got +NBHDRLEN);
357 p->eop = p->buf + got +NBHDRLEN;
363 xd(char *str, void *buf, int n)
365 int fd, flg, flags2, cmd;
374 end = (uchar *)buf +n;
376 if(Debug && strstr(Debug, "log") != nil){
377 if((fd = open("pkt.log", ORDWR)) == -1)
380 fprint(fd, "%d ", 0);
382 fprint(fd, "%02x ", *p++);
391 p = (uchar *)buf + 4;
392 if(GL32(&p) == 0x424d53ff){
393 buf = (uchar *)buf + 4;
396 end = (uchar *)buf + n;
404 fprint(2, "%s : len=%ud sum=%d\n", str, n, sum);
406 fprint(2, "mag=0x%ulx ", GL32(&p));
407 fprint(2, "cmd=0x%ux ", cmd = G8(&p));
408 fprint(2, "err=0x%ulx ", err=GL32(&p));
409 fprint(2, "flg=0x%02ux ", flg = G8(&p));
410 fprint(2, "flg2=0x%04ux\n", flags2= GL16(&p));
411 fprint(2, "dfs=%s\n", (flags2 & FL2_DFS)? "y": "n");
413 fprint(2, "pidl=%ud ", GL16(&p));
414 fprint(2, "res=%uld ", GL32(&p));
415 fprint(2, "sid=%ud ", GL16(&p));
416 fprint(2, "seq=0x%ux ", GL16(&p));
417 fprint(2, "pad=%ud ", GL16(&p));
419 fprint(2, "tid=%ud ", GL16(&p));
420 fprint(2, "pid=%ud ", GL16(&p));
421 fprint(2, "uid=%ud ", GL16(&p));
422 fprint(2, "mid=%ud\n", GL16(&p));
424 if(cmd == 0x32 && (flg & 0x80) == 0){ /* TRANS 2, TX */
425 fprint(2, "words=%ud ", G8(&p));
426 fprint(2, "totparams=%ud ", GL16(&p));
427 fprint(2, "totdata=%ud ", GL16(&p));
428 fprint(2, "maxparam=%ud ", GL16(&p));
429 fprint(2, "maxdata=%ud\n", GL16(&p));
430 fprint(2, "maxsetup=%ud ", G8(&p));
431 fprint(2, "reserved=%ud ", G8(&p));
432 fprint(2, "flags=%ud ", GL16(&p));
433 fprint(2, "timeout=%uld\n", GL32(&p));
434 fprint(2, "reserved=%ud ", GL16(&p));
435 fprint(2, "paramcnt=%ud ", GL16(&p));
436 fprint(2, "paramoff=%ud ", GL16(&p));
437 fprint(2, "datacnt=%ud ", GL16(&p));
438 fprint(2, "dataoff=%ud ", GL16(&p));
439 fprint(2, "setupcnt=%ud ", G8(&p));
440 fprint(2, "reserved=%ud\n", G8(&p));
441 fprint(2, "trans2=0x%02x ", GL16(&p));
442 fprint(2, "data-words=%d ", G8(&p));
443 fprint(2, "padding=%d\n", G8(&p));
445 if(cmd == 0x32 && (flg & 0x80) == 0x80){ /* TRANS 2, RX */
446 fprint(2, "words=%ud ", G8(&p));
447 fprint(2, "totparams=%ud ", GL16(&p));
448 fprint(2, "totdata=%ud ", GL16(&p));
449 fprint(2, "reserved=%ud ", GL16(&p));
450 fprint(2, "paramcnt=%ud\n", GL16(&p));
451 fprint(2, "paramoff=%ud ", GL16(&p));
452 fprint(2, "paramdisp=%ud ", GL16(&p));
453 fprint(2, "datacnt=%ud\n", GL16(&p));
454 fprint(2, "dataoff=%ud ", GL16(&p));
455 fprint(2, "datadisp=%ud ", GL16(&p));
456 fprint(2, "setupcnt=%ud ", G8(&p));
457 fprint(2, "reserved=%ud\n", G8(&p));
460 if(flags2 & FL2_NT_ERRCODES)
461 fprint(2, "err=%s\n", nterrstr(err));
463 fprint(2, "err=%s\n", doserrstr(err));
467 if((p - (uchar *)buf) % 16 == 0)
468 fprint(2, "\n%06zx\t", p - (uchar *)buf);
469 if(isprint((char)*p))
470 fprint(2, "%c ", (char )*p);
472 fprint(2, "%02ux ", *p);