pack.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. /* packet packing and unpacking */
  10. #include <u.h>
  11. #include <libc.h>
  12. #include <ctype.h>
  13. #include "cifs.h"
  14. void *
  15. pmem(Pkt *p, void *v, int len)
  16. {
  17. uint8_t *str = v;
  18. void *s = p->pos;
  19. if(!len || !v)
  20. return s;
  21. while(len--)
  22. *p->pos++ = *str++;
  23. return s;
  24. }
  25. void *
  26. ppath(Pkt *p, char *str)
  27. {
  28. char c;
  29. Rune r;
  30. void *s = p->pos;
  31. if(!str)
  32. return s;
  33. if(p->s->caps & CAP_UNICODE){
  34. if(((p->pos - p->buf) % 2) != 0) /* pad to even offset */
  35. p8(p, 0);
  36. while(*str){
  37. str += chartorune(&r, str);
  38. if(r == L'/')
  39. r = L'\\';
  40. pl16(p, r);
  41. }
  42. pl16(p, 0);
  43. } else {
  44. while((c = *str++) != 0){
  45. if(c == '/')
  46. c = '\\';
  47. *p->pos++ = c;
  48. }
  49. *p->pos++ = 0;
  50. }
  51. return s;
  52. }
  53. void *
  54. pstr(Pkt *p, char *str)
  55. {
  56. void *s = p->pos;
  57. Rune r;
  58. if(!str)
  59. return s;
  60. if(p->s->caps & CAP_UNICODE){
  61. if(((p->pos - p->buf) % 2) != 0)
  62. p8(p, 0); /* pad to even offset */
  63. while(*str){
  64. str += chartorune(&r, str);
  65. pl16(p, r);
  66. }
  67. pl16(p, 0);
  68. } else {
  69. while(*str)
  70. *p->pos++ = *str++;
  71. *p->pos++ = 0;
  72. }
  73. return s;
  74. }
  75. void *
  76. pascii(Pkt *p, char *str)
  77. {
  78. void *s = p->pos;
  79. while(*str)
  80. *p->pos++ = *str++;
  81. *p->pos++ = 0;
  82. return s;
  83. }
  84. void *
  85. pl64(Pkt *p, uint64_t n)
  86. {
  87. void *s = p->pos;
  88. *p->pos++ = n;
  89. *p->pos++ = n >> 8;
  90. *p->pos++ = n >> 16;
  91. *p->pos++ = n >> 24;
  92. *p->pos++ = n >> 32;
  93. *p->pos++ = n >> 40;
  94. *p->pos++ = n >> 48;
  95. *p->pos++ = n >> 56;
  96. return s;
  97. }
  98. void *
  99. pb32(Pkt *p, uint n)
  100. {
  101. void *s = p->pos;
  102. *p->pos++ = n >> 24;
  103. *p->pos++ = n >> 16;
  104. *p->pos++ = n >> 8;
  105. *p->pos++ = n;
  106. return s;
  107. }
  108. void *
  109. pl32(Pkt *p, uint n)
  110. {
  111. void *s = p->pos;
  112. *p->pos++ = n;
  113. *p->pos++ = n >> 8;
  114. *p->pos++ = n >> 16;
  115. *p->pos++ = n >> 24;
  116. return s;
  117. }
  118. void *
  119. pb16(Pkt *p, uint n)
  120. {
  121. void *s = p->pos;
  122. *p->pos++ = n >> 8;
  123. *p->pos++ = n;
  124. return s;
  125. }
  126. void *
  127. pl16(Pkt *p, uint n)
  128. {
  129. void *s = p->pos;
  130. *p->pos++ = n;
  131. *p->pos++ = n >> 8;
  132. return s;
  133. }
  134. void *
  135. p8(Pkt *p, uint n)
  136. {
  137. void *s = p->pos;
  138. *p->pos++ = n;
  139. return s;
  140. }
  141. /*
  142. * Encode a Netbios name
  143. */
  144. void *
  145. pname(Pkt *p, char *name, char pad)
  146. {
  147. int i, done = 0;
  148. char c;
  149. void *s = p->pos;
  150. *p->pos++ = ' ';
  151. for(i = 0; i < 16; i++) {
  152. c = pad;
  153. if(!done && name[i] == '\0')
  154. done = 1;
  155. if(!done)
  156. c = islower(name[i])? toupper(name[i]): name[i];
  157. *p->pos++ = ((uint8_t)c >> 4) + 'A';
  158. *p->pos++ = (c & 0xf) + 'A';
  159. }
  160. *p->pos++ = '\0';
  161. return s;
  162. }
  163. void *
  164. pvtime(Pkt *p, uint64_t n)
  165. {
  166. void *s = p->pos;
  167. n += 11644473600LL;
  168. n *= 10000000LL;
  169. pl32(p, n);
  170. pl32(p, n >> 32);
  171. return s;
  172. }
  173. void *
  174. pdatetime(Pkt *p, int32_t utc)
  175. {
  176. void *s = p->pos;
  177. Tm *tm = localtime(utc);
  178. int t = tm->hour << 11 | tm->min << 5 | (tm->sec / 2);
  179. int d = (tm->year - 80) << 9 | (tm->mon + 1) << 5 | tm->mday;
  180. /*
  181. * bug in word swapping in Win95 requires this
  182. */
  183. if(p->s->caps & CAP_NT_SMBS){
  184. pl16(p, d);
  185. pl16(p, t);
  186. } else{
  187. pl16(p, t);
  188. pl16(p, d);
  189. }
  190. return s;
  191. }
  192. void
  193. gmem(Pkt *p, void *v, int n)
  194. {
  195. uint8_t *str = v;
  196. if(!n || !v)
  197. return;
  198. while(n-- && p->pos < p->eop)
  199. *str++ = *p->pos++;
  200. }
  201. /*
  202. * note len is the length of the source string in
  203. * in runes or bytes, in ASCII mode this is also the size
  204. * of the output buffer but this is not so in Unicode mode!
  205. */
  206. void
  207. gstr(Pkt *p, char *str, int n)
  208. {
  209. int i;
  210. Rune r;
  211. if(!n || !str)
  212. return;
  213. if(p->s->caps & CAP_UNICODE){
  214. i = 0;
  215. while(*p->pos && n && p->pos < p->eop){
  216. r = gl16(p);
  217. i += runetochar(str +i, &r);
  218. n -= 2;
  219. }
  220. *(str + i) = 0;
  221. while(*p->pos && p->pos < p->eop)
  222. gl16(p);
  223. /*
  224. * some versions of windows terminate a rune string
  225. * with a single nul so we do a dangerous hack...
  226. */
  227. if(p->pos[1])
  228. g8(p);
  229. else
  230. gl16(p);
  231. } else {
  232. while(*p->pos && n-- && p->pos < p->eop)
  233. *str++ = *p->pos++;
  234. *str = 0;
  235. while(*p->pos++ && p->pos < p->eop)
  236. continue;
  237. }
  238. }
  239. void
  240. gascii(Pkt *p, char *str, int n)
  241. {
  242. if(!n || !str)
  243. return;
  244. while(*p->pos && n-- && p->pos < p->eop)
  245. *str++ = *p->pos++;
  246. *str = 0;
  247. while(*p->pos++ && p->pos < p->eop)
  248. continue;
  249. }
  250. uint64_t
  251. gl64(Pkt *p)
  252. {
  253. uint64_t n;
  254. if(p->pos + 8 > p->eop)
  255. return 0;
  256. n = (uint64_t)*p->pos++;
  257. n |= (uint64_t)*p->pos++ << 8;
  258. n |= (uint64_t)*p->pos++ << 16;
  259. n |= (uint64_t)*p->pos++ << 24;
  260. n |= (uint64_t)*p->pos++ << 32;
  261. n |= (uint64_t)*p->pos++ << 40;
  262. n |= (uint64_t)*p->pos++ << 48;
  263. n |= (uint64_t)*p->pos++ << 56;
  264. return n;
  265. }
  266. uint64_t
  267. gb48(Pkt *p)
  268. {
  269. uint64_t n;
  270. if(p->pos + 6 > p->eop)
  271. return 0;
  272. n = (uint64_t)*p->pos++ << 40;
  273. n |= (uint64_t)*p->pos++ << 24;
  274. n |= (uint64_t)*p->pos++ << 32;
  275. n |= (uint64_t)*p->pos++ << 16;
  276. n |= (uint64_t)*p->pos++ << 8;
  277. n |= (uint64_t)*p->pos++;
  278. return n;
  279. }
  280. uint
  281. gb32(Pkt *p)
  282. {
  283. uint n;
  284. if(p->pos + 4 > p->eop)
  285. return 0;
  286. n = (uint)*p->pos++ << 24;
  287. n |= (uint)*p->pos++ << 16;
  288. n |= (uint)*p->pos++ << 8;
  289. n |= (uint)*p->pos++;
  290. return n;
  291. }
  292. uint
  293. gl32(Pkt *p)
  294. {
  295. uint n;
  296. if(p->pos + 4 > p->eop)
  297. return 0;
  298. n = (uint)*p->pos++;
  299. n |= (uint)*p->pos++ << 8;
  300. n |= (uint)*p->pos++ << 16;
  301. n |= (uint)*p->pos++ << 24;
  302. return n;
  303. }
  304. uint
  305. gb16(Pkt *p)
  306. {
  307. uint n;
  308. if(p->pos + 2 > p->eop)
  309. return 0;
  310. n = (uint)*p->pos++ << 8;
  311. n |= (uint)*p->pos++;
  312. return n;
  313. }
  314. uint
  315. gl16(Pkt *p)
  316. {
  317. uint n;
  318. if(p->pos + 2 > p->eop)
  319. return 0;
  320. n = (uint)*p->pos++;
  321. n |= (uint)*p->pos++ << 8;
  322. return n;
  323. }
  324. uint
  325. g8(Pkt *p)
  326. {
  327. if(p->pos + 1 > p->eop)
  328. return 0;
  329. return (uint)*p->pos++;
  330. }
  331. int32_t
  332. gdatetime(Pkt *p)
  333. {
  334. Tm tm;
  335. uint d, t;
  336. if(p->pos + 4 > p->eop)
  337. return 0;
  338. /*
  339. * bug in word swapping in Win95 requires this
  340. */
  341. if(p->s->caps & CAP_NT_SMBS){
  342. d = gl16(p);
  343. t = gl16(p);
  344. }else{
  345. t = gl16(p);
  346. d = gl16(p);
  347. }
  348. tm.year = 80 + (d >> 9);
  349. tm.mon = ((d >> 5) & 017) - 1;
  350. tm.mday = d & 037;
  351. tm.zone[0] = 0;
  352. tm.tzoff = p->s->tz;
  353. tm.hour = t >> 11;
  354. tm.min = (t >> 5) & 63;
  355. tm.sec = (t & 31) << 1;
  356. return tm2sec(&tm);
  357. }
  358. int32_t
  359. gvtime(Pkt *p)
  360. {
  361. uint64_t vl;
  362. if(p->pos + 8 > p->eop)
  363. return 0;
  364. vl = (uint64_t)gl32(p);
  365. vl |= (uint64_t)gl32(p) << 32;
  366. vl /= 10000000LL;
  367. vl -= 11644473600LL;
  368. return vl;
  369. }
  370. void
  371. gconv(Pkt *p, int conv, char *str, int n)
  372. {
  373. int off;
  374. uint8_t *pos;
  375. off = gl32(p) & 0xffff;
  376. if(off == 0 || p->tdata - conv + off > p->eop){
  377. memset(str, 0, n);
  378. return;
  379. }
  380. pos = p->pos;
  381. p->pos = p->tdata - conv + off;
  382. gascii(p, str, n);
  383. p->pos = pos;
  384. }
  385. void
  386. goff(Pkt *p, uint8_t *base, char *str, int n)
  387. {
  388. int off;
  389. uint8_t *pos;
  390. off = gl16(p);
  391. if(off == 0 || base + off > p->eop){
  392. memset(str, 0, n);
  393. return;
  394. }
  395. pos = p->pos;
  396. p->pos = base + off;
  397. gstr(p, str, n);
  398. p->pos = pos;
  399. }