static void tcpreader(void *a) { Session *s = a; uint8_t *buf; int buflen = smbglobals.maxreceive + 4; buf = nbemalloc(buflen); for (;;) { int n; uint8_t flags; uint16_t length; n = readn(s->fd, buf, 4); if (n != 4) { die: free(buf); if (s->state == Connected) (*s->write)(s, nil, -1); deletesession(s); return; } flags = buf[1]; length = nhgets(buf + 2) | ((flags & 1) << 16); if (length > buflen - 4) { print("nbss: too much data (%ud)\n", length); goto die; } n = readn(s->fd, buf + 4, length); if (n != length) goto die; if (s->state == Connected) { if ((*s->write)(s, buf + 4, length) != 0) { s->state = Dead; goto die; } } } }
static void tcpreader(void *a) { Session *s = a; uchar *buf; int buflen = 0x1ffff + 4; buf = nbemalloc(buflen); for (;;) { int n; uchar flags; ushort length; n = readn(s->fd, buf, 4); if (n != 4) { die: free(buf); if (s->state == Connected) (*s->write)(s, nil, -1); deletesession(s); return; } flags = buf[1]; length = nhgets(buf + 2) | ((flags & 1) << 16); n = readn(s->fd, buf + 4, length); if (n != length) goto die; if (flags & 0xfe) { print("nbss: invalid flags field 0x%.2ux\n", flags); goto die; } switch (buf[0]) { case 0: /* session message */ if (s->state != Connected && s->state != Dead) { print("nbss: unexpected session message\n"); goto die; } if (s->state == Connected) { if ((*s->write)(s, buf + 4, length) != 0) { s->state = Dead; goto die; } } break; case 0x81: /* session request */ { uchar *p, *ep; Listen *l; int k; int called_found; uchar error_code; if (s->state == Connected) { print("nbss: unexpected session request\n"); goto die; } p = buf + 4; ep = p + length; k = nbnamedecode(p, p, ep, s->to); if (k == 0) { print("nbss: malformed called name in session request\n"); goto die; } p += k; k = nbnamedecode(p, p, ep, s->from); if (k == 0) { print("nbss: malformed calling name in session request\n"); goto die; } /* p += k; if (p != ep) { print("nbss: extra data at end of session request\n"); goto die; } */ called_found = 0; //print("nbss: called %B calling %B\n", s->to, s->from); qlock(&listens); for (l = listens.head; l; l = l->next) if (nbnameequal(l->to, s->to)) { called_found = 1; if (nbnameequal(l->from, s->from)) break; } if (l == nil) { qunlock(&listens); error_code = called_found ? 0x81 : 0x80; replydie: buf[0] = 0x83; buf[1] = 0; hnputs(buf + 2, 1); buf[4] = error_code; write(s->fd, buf, 5); goto die; } if (!(*l->accept)(l->magic, s, &s->write)) { qunlock(&listens); error_code = 0x83; goto replydie; } buf[0] = 0x82; buf[1] = 0; hnputs(buf + 2, 0); if (write(s->fd, buf, 4) != 4) { qunlock(&listens); goto die; } s->state = Connected; qunlock(&listens); break; } case 0x85: /* keep awake */ break; default: print("nbss: opcode 0x%.2ux unexpected\n", buf[0]); goto die; } } }
void nbssfree(NbSession *s) { deletesession((Session *)s); }