smbbuffer.c 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597
  1. #include "headers.h"
  2. #define BUFFER 1
  3. #define STRUCT 2
  4. #define PUSHED 4
  5. struct SmbBuffer {
  6. uchar *buf;
  7. ulong realmaxlen;
  8. ulong maxlen;
  9. ulong rn;
  10. ulong wn;
  11. ulong savewn;
  12. int flags;
  13. };
  14. void
  15. smbbufferreset(SmbBuffer *s)
  16. {
  17. if (s == nil)
  18. return;
  19. s->rn = 0;
  20. s->wn = 0;
  21. s->flags &= ~PUSHED;
  22. }
  23. void
  24. smbbuffersetbuf(SmbBuffer *s, void *p, ulong maxlen)
  25. {
  26. s->realmaxlen = s->maxlen = maxlen;
  27. if (s->buf) {
  28. if (s->flags & BUFFER)
  29. free(s->buf);
  30. s->buf = nil;
  31. }
  32. s->flags &= ~BUFFER;
  33. if (p)
  34. s->buf = p;
  35. else {
  36. s->buf = smbemalloc(maxlen);
  37. s->flags |= BUFFER;
  38. }
  39. smbbufferreset(s);
  40. }
  41. SmbBuffer *
  42. smbbufferinit(void *base, void *bdata, ulong blen)
  43. {
  44. SmbBuffer *b;
  45. b = smbemalloc(sizeof(*b));
  46. b->buf = base;
  47. b->flags = STRUCT;
  48. b->rn = (uchar *)bdata - (uchar *)base;
  49. b->wn = b->rn + blen;
  50. b->realmaxlen = b->maxlen = b->wn;
  51. return b;
  52. }
  53. int
  54. smbbufferalignl2(SmbBuffer *s, int al2)
  55. {
  56. ulong mask, newn;
  57. mask = (1 << al2) - 1;
  58. newn = (s->wn + mask) & ~mask;
  59. if (newn != s->wn) {
  60. if (newn > s->maxlen)
  61. return 0;
  62. s->wn = newn;
  63. }
  64. return 1;
  65. }
  66. int
  67. smbbufferputb(SmbBuffer *s, uchar b)
  68. {
  69. if (s->wn >= s->maxlen)
  70. return 0;
  71. s->buf[s->wn++] = b;
  72. return 1;
  73. }
  74. ulong
  75. smbbufferspace(SmbBuffer *sess)
  76. {
  77. return sess->maxlen - sess->wn;
  78. }
  79. int
  80. smbbufferoffsetputs(SmbBuffer *sess, ulong offset, ushort s)
  81. {
  82. if (offset + 2 > sess->wn)
  83. return 0;
  84. smbhnputs(sess->buf + offset, s);
  85. return 1;
  86. }
  87. int
  88. smbbufferputs(SmbBuffer *sess, ushort s)
  89. {
  90. if (sess->wn + sizeof(ushort) > sess->maxlen)
  91. return 0;
  92. smbhnputs(sess->buf + sess->wn, s);
  93. sess->wn += sizeof(ushort);
  94. return 1;
  95. }
  96. int
  97. smbbufferputl(SmbBuffer *s, ulong l)
  98. {
  99. if (s->wn + sizeof(ulong) > s->maxlen)
  100. return 0;
  101. smbhnputl(s->buf + s->wn, l);
  102. s->wn += sizeof(ulong);
  103. return 1;
  104. }
  105. int
  106. smbbufferputv(SmbBuffer *s, vlong v)
  107. {
  108. if (s->wn + sizeof(vlong) > s->maxlen)
  109. return 0;
  110. smbhnputv(s->buf + s->wn, v);
  111. s->wn += sizeof(vlong);
  112. return 1;
  113. }
  114. int
  115. smbbufferputbytes(SmbBuffer *s, void *data, ulong datalen)
  116. {
  117. if (s->wn + datalen > s->maxlen)
  118. return 0;
  119. if (data)
  120. memcpy(s->buf + s->wn, data, datalen);
  121. s->wn += datalen;
  122. return 1;
  123. }
  124. int
  125. smbbufferputstring(SmbBuffer *b, SmbPeerInfo *p, ulong flags, char *string)
  126. {
  127. int n = smbstringput(p, flags, b->buf, b->wn, b->maxlen, string);
  128. if (n <= 0)
  129. return 0;
  130. b->wn += n;
  131. return 1;
  132. }
  133. int
  134. smbbufferputstrn(SmbBuffer *s, char *string, int size, int upcase)
  135. {
  136. int n = smbstrnput(s->buf, s->wn, s->maxlen, string, size, upcase);
  137. if (n <= 0)
  138. return 0;
  139. s->wn += n;
  140. return 1;
  141. }
  142. ulong
  143. smbbufferwriteoffset(SmbBuffer *s)
  144. {
  145. return s->wn;
  146. }
  147. ulong
  148. smbbufferwritemaxoffset(SmbBuffer *s)
  149. {
  150. return s->maxlen;
  151. }
  152. ulong
  153. smbbufferreadoffset(SmbBuffer *s)
  154. {
  155. return s->rn;
  156. }
  157. void *
  158. smbbufferreadpointer(SmbBuffer *s)
  159. {
  160. return s->buf + s->rn;
  161. }
  162. void *
  163. smbbufferwritepointer(SmbBuffer *s)
  164. {
  165. return s->buf + s->wn;
  166. }
  167. ulong
  168. smbbufferwritespace(SmbBuffer *b)
  169. {
  170. return b->maxlen - b->wn;
  171. }
  172. SmbBuffer *
  173. smbbuffernew(ulong maxlen)
  174. {
  175. SmbBuffer *b;
  176. b = smbemalloc(sizeof(SmbBuffer));
  177. b->buf = smbemalloc(maxlen);
  178. b->realmaxlen = b->maxlen = maxlen;
  179. b->rn = 0;
  180. b->wn = 0;
  181. b->flags = STRUCT | BUFFER;
  182. return b;
  183. }
  184. void
  185. smbbufferfree(SmbBuffer **bp)
  186. {
  187. SmbBuffer *b = *bp;
  188. if (b) {
  189. if (b->flags & BUFFER) {
  190. free(b->buf);
  191. b->buf = nil;
  192. b->flags &= ~BUFFER;
  193. }
  194. if (b->flags & STRUCT)
  195. free(b);
  196. *bp = nil;
  197. }
  198. }
  199. uchar *
  200. smbbufferbase(SmbBuffer *b)
  201. {
  202. return b->buf;
  203. }
  204. int
  205. smbbuffergetbytes(SmbBuffer *b, void *buf, ulong len)
  206. {
  207. if (b->rn + len > b->wn)
  208. return 0;
  209. if (buf)
  210. memcpy(buf, b->buf + b->rn, len);
  211. b->rn += len;
  212. return 1;
  213. }
  214. void
  215. smbbuffersetreadlen(SmbBuffer *b, ulong len)
  216. {
  217. b->wn = b->rn + len;
  218. }
  219. int
  220. smbbuffertrimreadlen(SmbBuffer *b, ulong len)
  221. {
  222. if (b->rn + len > b->wn)
  223. return 0;
  224. else if (b->rn + len < b->wn)
  225. b->wn = b->rn + len;
  226. return 1;
  227. }
  228. int
  229. smbbuffergets(SmbBuffer *b, ushort *sp)
  230. {
  231. if (b->rn + 2 > b->wn)
  232. return 0;
  233. *sp = smbnhgets(b->buf + b->rn);
  234. b->rn += 2;
  235. return 1;
  236. }
  237. int
  238. smbbuffergetstrn(SmbBuffer *b, ushort size, char **sp)
  239. {
  240. uchar *np;
  241. if (size > b->wn - b->rn)
  242. return 0;
  243. np = memchr(b->buf + b->rn, 0, size);
  244. if (np == nil)
  245. return 0;
  246. *sp = strdup((char *)b->buf + b->rn);
  247. b->rn += size;
  248. return 1;
  249. }
  250. int
  251. smbbuffergetstr(SmbBuffer *b, ulong flags, char **sp)
  252. {
  253. int c;
  254. char *p;
  255. uchar *np;
  256. np = memchr(b->buf + b->rn, 0, b->wn - b->rn);
  257. if (np == nil)
  258. return 0;
  259. *sp = strdup((char *)b->buf + b->rn);
  260. for (p = *sp; *p != 0; p++) {
  261. c = *p;
  262. if (c >= 'a' && c <= 'z' && (flags & SMB_STRING_UPCASE))
  263. *p = toupper(c);
  264. else if (c == '/' && (flags & SMB_STRING_REVPATH))
  265. *p = '\\';
  266. else if (c == '\\' && (flags & SMB_STRING_PATH))
  267. *p = '/';
  268. else if (smbglobals.convertspace){
  269. if (c == 0xa0 && (flags & SMB_STRING_REVPATH))
  270. *p = ' ';
  271. else if (c == ' ' && (flags & SMB_STRING_PATH))
  272. *p = 0xa0;
  273. }
  274. }
  275. b->rn = np - b->buf + 1;
  276. return 1;
  277. }
  278. int
  279. smbbuffergetstrinline(SmbBuffer *b, char **sp)
  280. {
  281. uchar *np;
  282. np = memchr(b->buf + b->rn, 0, b->wn - b->rn);
  283. if (np == nil)
  284. return 0;
  285. *sp = (char *)b->buf + b->rn;
  286. b->rn = np - b->buf + 1;
  287. return 1;
  288. }
  289. int
  290. smbbuffergetucs2(SmbBuffer *b, ulong flags, char **sp)
  291. {
  292. uchar *bdata = b->buf + b->rn;
  293. uchar *edata = b->buf + b->wn;
  294. Rune r;
  295. int l;
  296. char *p, *q;
  297. uchar *savebdata;
  298. int first;
  299. l = 0;
  300. if ((flags & SMB_STRING_UNALIGNED) == 0 && (bdata - b->buf) & 1)
  301. bdata++;
  302. savebdata = bdata;
  303. first = 1;
  304. do {
  305. if (bdata + 2 > edata) {
  306. l++;
  307. break;
  308. }
  309. r = smbnhgets(bdata); bdata += 2;
  310. if (first && (flags & SMB_STRING_PATH) && r != '\\')
  311. l++;
  312. first = 0;
  313. if (flags & SMB_STRING_CONVERT_MASK)
  314. r = smbruneconvert(r, flags);
  315. l += runelen(r);
  316. } while (r != 0);
  317. p = smbemalloc(l);
  318. bdata = savebdata;
  319. q = p;
  320. first = 1;
  321. do {
  322. if (bdata + 2 > edata) {
  323. *q = 0;
  324. break;
  325. }
  326. r = smbnhgets(bdata); bdata += 2;
  327. if (first && (flags & SMB_STRING_PATH) && r != '\\')
  328. *q++ = '/';
  329. first = 0;
  330. if (flags & SMB_STRING_CONVERT_MASK)
  331. r = smbruneconvert(r, flags);
  332. q += runetochar(q, &r);
  333. } while (r != 0);
  334. b->rn = bdata - b->buf;
  335. *sp = p;
  336. return 1;
  337. }
  338. int
  339. smbbuffergetstring(SmbBuffer *b, SmbHeader *h, ulong flags, char **sp)
  340. {
  341. if (flags & SMB_STRING_UNICODE)
  342. return smbbuffergetucs2(b, flags, sp);
  343. else if (flags & SMB_STRING_ASCII)
  344. return smbbuffergetstr(b, flags, sp);
  345. else if (h->flags2 & SMB_FLAGS2_UNICODE)
  346. return smbbuffergetucs2(b, flags, sp);
  347. else
  348. return smbbuffergetstr(b, flags, sp);
  349. }
  350. void *
  351. smbbufferpointer(SmbBuffer *b, ulong offset)
  352. {
  353. return b->buf + offset;
  354. }
  355. int
  356. smbbuffergetb(SmbBuffer *b, uchar *bp)
  357. {
  358. if (b->rn < b->wn) {
  359. *bp = b->buf[b->rn++];
  360. return 1;
  361. }
  362. return 0;
  363. }
  364. int
  365. smbbuffergetl(SmbBuffer *b, ulong *lp)
  366. {
  367. if (b->rn + 4 <= b->wn) {
  368. *lp = smbnhgetl(b->buf + b->rn);
  369. b->rn += 4;
  370. return 1;
  371. }
  372. return 0;
  373. }
  374. int
  375. smbbuffergetv(SmbBuffer *b, vlong *vp)
  376. {
  377. if (b->rn + 8 <= b->wn) {
  378. *vp = smbnhgetv(b->buf + b->rn);
  379. b->rn += 8;
  380. return 1;
  381. }
  382. return 0;
  383. }
  384. ulong
  385. smbbufferreadspace(SmbBuffer *b)
  386. {
  387. return b->wn - b->rn;
  388. }
  389. void
  390. smbbufferwritelimit(SmbBuffer *b, ulong limit)
  391. {
  392. if (b->rn + limit < b->maxlen)
  393. b->maxlen = b->rn + limit;
  394. }
  395. int
  396. smbbufferreadskipto(SmbBuffer *b, ulong offset)
  397. {
  398. if (offset < b->rn || offset >= b->wn)
  399. return 0;
  400. b->rn = offset;
  401. return 1;
  402. }
  403. int
  404. smbbufferpushreadlimit(SmbBuffer *b, ulong limit)
  405. {
  406. if (b->flags & PUSHED)
  407. return 0;
  408. if (limit > b->wn || limit < b->rn)
  409. return 0;
  410. b->savewn = b->wn;
  411. b->wn = limit;
  412. b->flags |= PUSHED;
  413. return 1;
  414. }
  415. int
  416. smbbufferpopreadlimit(SmbBuffer *b)
  417. {
  418. if ((b->flags & PUSHED) == 0)
  419. return 0;
  420. b->wn = b->savewn;
  421. b->flags &= ~PUSHED;
  422. return 1;
  423. }
  424. int
  425. smbbufferwritebackup(SmbBuffer *b, ulong offset)
  426. {
  427. if (offset >= b->rn && offset <= b->wn) {
  428. b->wn = offset;
  429. return 1;
  430. }
  431. return 0;
  432. }
  433. int
  434. smbbufferreadbackup(SmbBuffer *b, ulong offset)
  435. {
  436. if (offset <= b->rn) {
  437. b->rn = offset;
  438. return 1;
  439. }
  440. return 0;
  441. }
  442. int
  443. smbbufferfixuprelatives(SmbBuffer *b, ulong fixupoffset)
  444. {
  445. ulong fixval;
  446. if (fixupoffset < b->rn || fixupoffset > b->wn - 2)
  447. return 0;
  448. fixval = b->wn - fixupoffset - 2;
  449. if (fixval > 65535)
  450. return 0;
  451. smbhnputs(b->buf + fixupoffset, fixval);
  452. return 1;
  453. }
  454. int
  455. smbbufferfixuprelativel(SmbBuffer *b, ulong fixupoffset)
  456. {
  457. ulong fixval;
  458. if (fixupoffset < b->rn || fixupoffset > b->wn - 4)
  459. return 0;
  460. fixval = b->wn - fixupoffset - 4;
  461. smbhnputl(b->buf + fixupoffset, fixval);
  462. return 1;
  463. }
  464. int
  465. smbbufferfixupabsolutes(SmbBuffer *b, ulong fixupoffset)
  466. {
  467. if (fixupoffset < b->rn || fixupoffset > b->wn - 2)
  468. return 0;
  469. if (b->wn > 65535)
  470. return 0;
  471. smbhnputs(b->buf + fixupoffset, b->wn);
  472. return 1;
  473. }
  474. int
  475. smbbufferfixupl(SmbBuffer *b, ulong fixupoffset, ulong fixupval)
  476. {
  477. if (fixupoffset < b->rn || fixupoffset > b->wn - 4)
  478. return 0;
  479. smbhnputl(b->buf + fixupoffset, fixupval);
  480. return 1;
  481. }
  482. int
  483. smbbufferfixupabsolutel(SmbBuffer *b, ulong fixupoffset)
  484. {
  485. if (fixupoffset < b->rn || fixupoffset > b->wn - 2)
  486. return 0;
  487. smbhnputl(b->buf + fixupoffset, b->wn);
  488. return 1;
  489. }
  490. int
  491. smbbufferfixuprelativeinclusivel(SmbBuffer *b, ulong fixupoffset)
  492. {
  493. if (fixupoffset < b->rn || fixupoffset > b->wn - 4)
  494. return 0;
  495. smbhnputl(b->buf + fixupoffset, b->wn - fixupoffset);
  496. return 1;
  497. }
  498. int
  499. smbbufferfill(SmbBuffer *b, uchar val, ulong len)
  500. {
  501. if (b->maxlen - b->wn < len)
  502. return 0;
  503. memset(b->buf + b->wn, val, len);
  504. b->wn += len;
  505. return 1;
  506. }
  507. int
  508. smbbufferoffsetgetb(SmbBuffer *b, ulong offset, uchar *bp)
  509. {
  510. if (offset >= b->rn && offset + 1 <= b->wn) {
  511. *bp = b->buf[b->rn + offset];
  512. return 1;
  513. }
  514. return 0;
  515. }
  516. int
  517. smbbuffercopy(SmbBuffer *to, SmbBuffer *from, ulong amount)
  518. {
  519. if (smbbufferreadspace(from) < amount)
  520. return 0;
  521. if (smbbufferputbytes(to, smbbufferreadpointer(from), amount)) {
  522. assert(smbbuffergetbytes(from, nil, amount));
  523. return 1;
  524. }
  525. return 0;
  526. }
  527. int
  528. smbbufferoffsetcopystr(SmbBuffer *b, ulong offset, char *buf, int buflen, int *lenp)
  529. {
  530. uchar *np;
  531. if (offset < b->rn || offset >= b->wn)
  532. return 0;
  533. np = memchr(b->buf + offset, 0, b->wn - offset);
  534. if (np == nil)
  535. return 0;
  536. *lenp = np - (b->buf + offset) + 1;
  537. if (*lenp > buflen)
  538. return 0;
  539. memcpy(buf, b->buf + offset, *lenp);
  540. return 1;
  541. }