int nbdgramsend(NbDgramSendParameters *p, uint8_t *data, int32_t datalen) { NbDgram s; uint8_t dstip[IPaddrlen]; s.type = p->type; switch (p->type) { case NbDgramBroadcast: case NbDgramDirectGroup: ipmove(dstip, nbglobals.bcastaddr); break; case NbDgramDirectUnique: if (!nbnameresolve(p->to, dstip)) { werrstr("nbdgramsend: name resolution failed"); return 0; } break; default: werrstr("nbdgramsend: illegal datagram type"); return 0; } s.flags = NbDgramFirst; s.id = nextdgramid(); ipmove(s.srcip, nbglobals.myipaddr); s.srcport = NbDgramPort; s.datagram.offset = 0; s.datagram.data = data; s.datagram.length = datalen; nbnamecpy(s.datagram.dstname, p->to); nbnamecpy(s.datagram.srcname, nbglobals.myname); return nbdgramsendto(dstip, NbDgramPort, &s); }
NbSession * nbssconnect(NbName to, NbName from) { Session *s; uchar ipaddr[IPaddrlen]; char dialaddress[100]; char dir[NETPATHLEN]; uchar msg[576]; int fd; long o; uchar flags; long length; if (!nbnameresolve(to, ipaddr)) return nil; fmtinstall('I', eipfmt); snprint(dialaddress, sizeof(dialaddress), "tcp!%I!netbios", ipaddr); fd = dial(dialaddress, nil, dir, nil); if (fd < 0) return nil; msg[0] = 0x81; msg[1] = 0; o = 4; o += nbnameencode(msg + o, msg + sizeof(msg) - o, to); o += nbnameencode(msg + o, msg + sizeof(msg) - o, from); hnputs(msg + 2, o - 4); if (write(fd, msg, o) != o) { close(fd); return nil; } if (readn(fd, msg, 4) != 4) { close(fd); return nil; } flags = msg[1]; length = nhgets(msg + 2) | ((flags & 1) << 16); switch (msg[0]) { default: close(fd); werrstr("unexpected session message code 0x%.2ux", msg[0]); return nil; case 0x82: if (length != 0) { close(fd); werrstr("length not 0 in positive session response"); return nil; } break; case 0x83: if (length != 1) { close(fd); werrstr("length not 1 in negative session response"); return nil; } if (readn(fd, msg + 4, 1) != 1) { close(fd); return nil; } close(fd); werrstr("negative session response 0x%.2ux", msg[4]); return nil; } s = nbemalloc(sizeof(Session)); s->fd = fd; s->state = Connected; qlock(&sessions); s->next = sessions.head; sessions.head = s; qunlock(&sessions); return s; }