Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

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