pack.c 6.3 KB

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