Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
68 7u83 1
#include <sys/param.h>
2
#include <sys/systm.h>
3
#include <sys/socket.h>
4
#include <sys/socketvar.h>
5
#include <netinet/in.h>
6
#include <sys/mbuf.h>
7
#include <sys/malloc.h>
8
#include <sys/vnode.h>
9
#include <sys/mount.h>
10
 
11
#include <9fs/bitstring.h>
12
#include <9fs/9p.h>
13
#include <9fs/9auth.h>
14
#include <9fs/9fs.h>
15
 
16
int u9p_usetcp = 0;
17
struct u9fs_reqq u9fs_reqq;
18
 
19
#define	N2HCHAR(x)		x = *p++
20
#define	N2HSHORT(x)	x = (p[0] | (p[1]<<8)); p += 2
21
#define	N2HLONG(x)		x = (p[0] | (p[1]<<8) |\
22
				(p[2]<<16) | (p[3]<<24)); p += 4
23
#define	N2HQUAD(x)	x = (u_int64_t)(p[0] | (p[1]<<8) |\
24
					(p[2]<<16) | (p[3]<<24)) |\
25
				((u_int64_t)(p[4] | (p[5]<<8) |\
26
					(p[6]<<16) | (p[7]<<24)) << 32); p += 8
27
#define	N2HSTRING(x,n)	bcopy(p, x, n); p += n
28
 
29
#define	H2NCHAR(x)	*p++ = x
30
#define	H2NSHORT(x)	p[0]=x; p[1]=x>>8; p += 2
31
#define	H2NLONG(x)		p[0]=x; p[1]=x>>8; p[2]=x>>16; p[3]=x>>24; p += 4
32
#define	H2NQUAD(x)	p[0]=x;	p[1]=x>>8;\
33
			p[2]=x>>16;	p[3]=x>>24;\
34
			p[4]=x>>32;	p[5]=x>>40;\
35
			p[6]=x>>48;	p[7]=x>>56;\
36
			p += 8
37
#define	H2NSTRING(x,n)	bcopy(x, p, n); p += n
38
 
39
static void u9p_print __P((u_char * m, int len, struct u9fsreq * f));
40
 
41
static char * u9p_types[] = {
42
  "Tnop",
43
  "Rnop",
44
  "Tosession",
45
  "Rosession",
46
  "Terror",
47
  "Rerror",
48
  "Tflush",
49
  "Rflush",
50
  "Toattach",
51
  "Roattach",
52
  "Tclone",
53
  "Rclone",
54
  "Twalk",
55
  "Rwalk",
56
  "Topen",
57
  "Ropen",
58
  "Tcreate",
59
  "Rcreate",
60
  "Tread",
61
  "Rread",
62
  "Twrite",
63
  "Rwrite",
64
  "Tclunk",
65
  "Rclunk",
66
  "Tremove",
67
  "Rremove",
68
  "Tstat",
69
  "Rstat",
70
  "Twstat",
71
  "Rwstat",
72
  "Tclwalk",
73
  "Rclwalk",
74
  "Tauth",
75
  "Rauth",
76
  "Tsession",
77
  "Rsession",
78
  "Tattach",
79
  "Rattach",
80
  "Ttunnel",
81
  "Rtunnel",
82
  "Tmax"
83
};
84
 
85
int u9p_m2s(char *ap, int n, struct u9fsreq *f)
86
{
87
	u_char *p;
88
 
89
	p = (u_char*)ap;
90
	N2HCHAR(f->r_type);
91
	N2HSHORT(f->r_tag);
92
	switch(f->r_type)
93
	{
94
	default:
95
		return 0;
96
 
97
	case Tnop:
98
	case Tosession:
99
		break;
100
 
101
	case Tsession:
102
		N2HSTRING(f->r_chal, sizeof(f->r_chal));
103
		break;
104
 
105
	case Tflush:
106
		N2HSHORT(f->r_oldtag);
107
		break;
108
 
109
	case Tattach:
110
		N2HSHORT(f->r_fid);
111
		N2HSTRING(f->r_uname, sizeof(f->r_uname));
112
		N2HSTRING(f->r_aname, sizeof(f->r_aname));
113
		N2HSTRING(f->r_ticket, sizeof(f->r_ticket));
114
		N2HSTRING(f->r_auth, sizeof(f->r_auth));
115
		break;
116
 
117
	case Toattach:
118
		N2HSHORT(f->r_fid);
119
		N2HSTRING(f->r_uname, sizeof(f->r_uname));
120
		N2HSTRING(f->r_aname, sizeof(f->r_aname));
121
		N2HSTRING(f->r_ticket, U9FS_NAMELEN);
122
		break;
123
 
124
	case Tauth:
125
		N2HSHORT(f->r_fid);
126
		N2HSTRING(f->r_uname, sizeof(f->r_uname));
127
		N2HSTRING(f->r_ticket, 8+U9FS_NAMELEN);
128
		break;
129
 
130
	case Tclone:
131
		N2HSHORT(f->r_fid);
132
		N2HSHORT(f->r_newfid);
133
		break;
134
 
135
	case Twalk:
136
		N2HSHORT(f->r_fid);
137
		N2HSTRING(f->r_name, sizeof(f->r_name));
138
		break;
139
 
140
	case Topen:
141
		N2HSHORT(f->r_fid);
142
		N2HCHAR(f->r_mode);
143
		break;
144
 
145
	case Tcreate:
146
		N2HSHORT(f->r_fid);
147
		N2HSTRING(f->r_name, sizeof(f->r_name));
148
		N2HLONG(f->r_perm);
149
		N2HCHAR(f->r_mode);
150
		break;
151
 
152
	case Tread:
153
		N2HSHORT(f->r_fid);
154
		N2HQUAD(f->r_offset);
155
		N2HSHORT(f->r_count);
156
		break;
157
 
158
	case Twrite:
159
		N2HSHORT(f->r_fid);
160
		N2HQUAD(f->r_offset);
161
		N2HSHORT(f->r_count);
162
		p++;	/* pad(1) */
163
		f->r_data = (char*)p; p += f->r_count;
164
		break;
165
 
166
	case Ttunnel:
167
		N2HSHORT(f->r_fid);
168
		break;
169
 
170
	case Tclunk:
171
		N2HSHORT(f->r_fid);
172
		break;
173
 
174
	case Tremove:
175
		N2HSHORT(f->r_fid);
176
		break;
177
 
178
	case Tstat:
179
		N2HSHORT(f->r_fid);
180
		break;
181
 
182
	case Twstat:
183
		N2HSHORT(f->r_fid);
184
		N2HSTRING(f->r_stat, sizeof(f->r_stat));
185
		break;
186
 
187
	case Tclwalk:
188
		N2HSHORT(f->r_fid);
189
		N2HSHORT(f->r_newfid);
190
		N2HSTRING(f->r_name, sizeof(f->r_name));
191
		break;
192
/*
193
 */
194
	case Rnop:
195
	case Rosession:
196
		break;
197
 
198
	case Rsession:
199
		N2HSTRING(f->r_chal, sizeof(f->r_chal));
200
		N2HSTRING(f->r_authid, sizeof(f->r_authid));
201
		N2HSTRING(f->r_authdom, sizeof(f->r_authdom));
202
		break;
203
 
204
	case Rerror:
205
		N2HSTRING(f->r_ename, sizeof(f->r_ename));
206
		break;
207
 
208
	case Rflush:
209
		break;
210
 
211
	case Rattach:
212
		N2HSHORT(f->r_fid);
213
		N2HLONG(f->r_qid.path);
214
		N2HLONG(f->r_qid.vers);
215
		N2HSTRING(f->r_rauth, sizeof(f->r_rauth));
216
		break;
217
 
218
	case Roattach:
219
		N2HSHORT(f->r_fid);
220
		N2HLONG(f->r_qid.path);
221
		N2HLONG(f->r_qid.vers);
222
		break;
223
 
224
	case Rauth:
225
		N2HSHORT(f->r_fid);
226
		N2HSTRING(f->r_ticket, 8+8+7+7);
227
		break;
228
 
229
	case Rclone:
230
		N2HSHORT(f->r_fid);
231
		break;
232
 
233
	case Rwalk:
234
	case Rclwalk:
235
		N2HSHORT(f->r_fid);
236
		N2HLONG(f->r_qid.path);
237
		N2HLONG(f->r_qid.vers);
238
		break;
239
 
240
	case Ropen:
241
		N2HSHORT(f->r_fid);
242
		N2HLONG(f->r_qid.path);
243
		N2HLONG(f->r_qid.vers);
244
		break;
245
 
246
	case Rcreate:
247
		N2HSHORT(f->r_fid);
248
		N2HLONG(f->r_qid.path);
249
		N2HLONG(f->r_qid.vers);
250
		break;
251
 
252
	case Rread:
253
		N2HSHORT(f->r_fid);
254
		N2HSHORT(f->r_count);
255
		p++;	/* pad(1) */
256
		f->r_data = (char*)p; p += f->r_count;
257
		break;
258
 
259
	case Rwrite:
260
		N2HSHORT(f->r_fid);
261
		N2HSHORT(f->r_count);
262
		break;
263
 
264
	case Rtunnel:
265
		N2HSHORT(f->r_fid);
266
		break;
267
 
268
	case Rclunk:
269
		N2HSHORT(f->r_fid);
270
		break;
271
 
272
	case Rremove:
273
		N2HSHORT(f->r_fid);
274
		break;
275
 
276
	case Rstat:
277
		N2HSHORT(f->r_fid);
278
		N2HSTRING(f->r_stat, sizeof(f->r_stat));
279
		break;
280
 
281
	case Rwstat:
282
		N2HSHORT(f->r_fid);
283
		break;
284
	}
285
	if((u_char*)ap+n == p)
286
		return n;
287
	return 0;
288
}
289
 
290
void u9p_print(u_char * m, int len, struct u9fsreq * f)
291
{
292
  struct u9fsreq u9fsreq;
293
 
294
  if( f == 0 )
295
    f = & u9fsreq;
296
 
297
  if( len < 3 ) {
298
    printf("truncated-9p %d", len);
299
    return;
300
  }
301
 
302
  if( u9p_m2s((char *)m, len, f) == 0 )
303
    return;
304
 
305
  printf("%s tag %d ", u9p_types[f->r_type-Tnop], f->r_tag);
306
 
307
  switch( f->r_type ) {
308
	default:
309
	  return;
310
 
311
	case Tnop:
312
	case Tosession:
313
	case Toattach:
314
	case Tauth:
315
		break;
316
 
317
	case Tsession:
318
	case Rsession:
319
	  printf("chal 0x%x 0x%x", *(u_int *)&f->r_chal[0], *(u_int *)&f->r_chal[4]);
320
		break;
321
 
322
	case Tflush:
323
	  printf("oldtag %d", f->r_oldtag);
324
		break;
325
 
326
	case Tclone:
327
	  printf("fid %d newfid %d", f->r_fid, f->r_newfid);
328
		break;
329
 
330
	case Twalk:
331
	  printf("fid %d name %s", f->r_fid, f->r_name);
332
		break;
333
 
334
	case Topen:
335
	  printf("fid %d %c", f->r_fid, f->r_mode);
336
		break;
337
 
338
	case Tcreate:
339
	  printf("fid %d name %s perm 0x%x mode %c", f->r_fid,
340
		 f->r_name, f->r_perm, f->r_mode);
341
		break;
342
 
343
	case Tread:
344
	case Twrite:
345
	  printf("fid %d offset 0x%llx count %d", f->r_fid,
346
		 f->r_offset, f->r_count);
347
		break;
348
 
349
	case Tattach:
350
	case Ttunnel:
351
	case Tclunk:
352
	case Tremove:
353
	case Tstat:
354
	case Twstat:
355
	case Rclone:
356
	case Rtunnel:
357
	case Rclunk:
358
	case Rremove:
359
	case Rstat:
360
	case Rwstat:
361
	  printf("fid %d", f->r_fid);
362
		break;
363
 
364
	case Tclwalk:
365
	  printf("fid %d ", f->r_fid);
366
	  printf("newfid  %d ", f->r_newfid);
367
	  printf("name %s", f->r_name);
368
		break;
369
/*
370
 */
371
	case Rnop:
372
	case Rosession:
373
	case Rflush:
374
	case Roattach:
375
	case Rauth:
376
		break;
377
 
378
	case Rerror:
379
	  printf("ename %s", f->r_ename);
380
		break;
381
 
382
	case Rattach:
383
	case Rwalk:
384
	case Rclwalk:
385
	case Ropen:
386
	case Rcreate:
387
	  printf("fid %d ", f->r_fid);
388
	  printf("qid 0x%x 0x%x", f->r_qid.path, f->r_qid.vers);
389
		break;
390
 
391
	case Rread:
392
	  printf("fid %d count %d ", f->r_fid, f->r_count);
393
	  break;
394
 
395
	case Rwrite:
396
	  printf("fid %d count %d", f->r_fid, f->r_count);
397
		break;
398
  }
399
}
400
 
401
int
402
u9p_s2m(struct u9fsreq *f, char *ap, int copydata)
403
{
404
	u_char *p;
405
 
406
	p = (u_char*)ap;
407
	H2NCHAR(f->r_type);
408
	H2NSHORT(f->r_tag);
409
	switch(f->r_type)
410
	{
411
	default:
412
		return 0;
413
 
414
	case Tosession:
415
	case Tnop:
416
		break;
417
 
418
	case Tsession:
419
		H2NSTRING(f->r_chal, sizeof(f->r_chal));
420
		break;
421
 
422
	case Tflush:
423
		H2NSHORT(f->r_oldtag);
424
		break;
425
 
426
	case Tattach:
427
		H2NSHORT(f->r_fid);
428
		H2NSTRING(f->r_uname, sizeof(f->r_uname));
429
		H2NSTRING(f->r_aname, sizeof(f->r_aname));
430
		H2NSTRING(f->r_ticket, sizeof(f->r_ticket));
431
		H2NSTRING(f->r_auth, sizeof(f->r_auth));
432
		break;
433
 
434
	case Toattach:
435
		H2NSHORT(f->r_fid);
436
		H2NSTRING(f->r_uname, sizeof(f->r_uname));
437
		H2NSTRING(f->r_aname, sizeof(f->r_aname));
438
		H2NSTRING(f->r_ticket, U9FS_NAMELEN);
439
		break;
440
 
441
	case Tauth:
442
		H2NSHORT(f->r_fid);
443
		H2NSTRING(f->r_uname, sizeof(f->r_uname));
444
		H2NSTRING(f->r_ticket, 8+U9FS_NAMELEN);
445
		break;
446
 
447
	case Tclone:
448
		H2NSHORT(f->r_fid);
449
		H2NSHORT(f->r_newfid);
450
		break;
451
 
452
	case Twalk:
453
		H2NSHORT(f->r_fid);
454
		H2NSTRING(f->r_name, sizeof(f->r_name));
455
		break;
456
 
457
	case Topen:
458
		H2NSHORT(f->r_fid);
459
		H2NCHAR(f->r_mode);
460
		break;
461
 
462
	case Tcreate:
463
		H2NSHORT(f->r_fid);
464
		H2NSTRING(f->r_name, sizeof(f->r_name));
465
		H2NLONG(f->r_perm);
466
		H2NCHAR(f->r_mode);
467
		break;
468
 
469
	case Tread:
470
		H2NSHORT(f->r_fid);
471
		H2NQUAD(f->r_offset);
472
		H2NSHORT(f->r_count);
473
		break;
474
 
475
	case Twrite:
476
		H2NSHORT(f->r_fid);
477
		H2NQUAD(f->r_offset);
478
		H2NSHORT(f->r_count);
479
		p++;	/* pad(1) */
480
		if( copydata ) {
481
		  H2NSTRING(f->r_data, f->r_count);
482
		}
483
		break;
484
 
485
	case Ttunnel:
486
		H2NSHORT(f->r_fid);
487
		break;
488
 
489
	case Tclunk:
490
		H2NSHORT(f->r_fid);
491
		break;
492
 
493
	case Tremove:
494
		H2NSHORT(f->r_fid);
495
		break;
496
 
497
	case Tstat:
498
		H2NSHORT(f->r_fid);
499
		break;
500
 
501
	case Twstat:
502
		H2NSHORT(f->r_fid);
503
		H2NSTRING(f->r_stat, sizeof(f->r_stat));
504
		break;
505
 
506
	case Tclwalk:
507
		H2NSHORT(f->r_fid);
508
		H2NSHORT(f->r_newfid);
509
		H2NSTRING(f->r_name, sizeof(f->r_name));
510
		break;
511
/*
512
 */
513
	case Rosession:
514
	case Rnop:
515
		break;
516
 
517
	case Rsession:
518
		H2NSTRING(f->r_chal, sizeof(f->r_chal));
519
		H2NSTRING(f->r_authid, sizeof(f->r_authid));
520
		H2NSTRING(f->r_authdom, sizeof(f->r_authdom));
521
		break;
522
 
523
	case Rerror:
524
		H2NSTRING(f->r_ename, sizeof(f->r_ename));
525
		break;
526
 
527
	case Rflush:
528
		break;
529
 
530
	case Rattach:
531
		H2NSHORT(f->r_fid);
532
		H2NLONG(f->r_qid.path);
533
		H2NLONG(f->r_qid.vers);
534
		H2NSTRING(f->r_rauth, sizeof(f->r_rauth));
535
		break;
536
 
537
	case Roattach:
538
		H2NSHORT(f->r_fid);
539
		H2NLONG(f->r_qid.path);
540
		H2NLONG(f->r_qid.vers);
541
		break;
542
 
543
	case Rauth:
544
		H2NSHORT(f->r_fid);
545
		H2NSTRING(f->r_ticket, 8+8+7+7);
546
		break;
547
 
548
	case Rclone:
549
		H2NSHORT(f->r_fid);
550
		break;
551
 
552
	case Rwalk:
553
	case Rclwalk:
554
		H2NSHORT(f->r_fid);
555
		H2NLONG(f->r_qid.path);
556
		H2NLONG(f->r_qid.vers);
557
		break;
558
 
559
	case Ropen:
560
		H2NSHORT(f->r_fid);
561
		H2NLONG(f->r_qid.path);
562
		H2NLONG(f->r_qid.vers);
563
		break;
564
 
565
	case Rcreate:
566
		H2NSHORT(f->r_fid);
567
		H2NLONG(f->r_qid.path);
568
		H2NLONG(f->r_qid.vers);
569
		break;
570
 
571
	case Rread:
572
		H2NSHORT(f->r_fid);
573
		H2NSHORT(f->r_count);
574
		p++;	/* pad(1) */
575
		if( copydata ) {
576
		  H2NSTRING(f->r_data, f->r_count);
577
		}
578
		break;
579
 
580
	case Rwrite:
581
		H2NSHORT(f->r_fid);
582
		H2NSHORT(f->r_count);
583
		break;
584
 
585
	case Rtunnel:
586
		H2NSHORT(f->r_fid);
587
		break;
588
 
589
	case Rclunk:
590
		H2NSHORT(f->r_fid);
591
		break;
592
 
593
	case Rremove:
594
		H2NSHORT(f->r_fid);
595
		break;
596
 
597
	case Rstat:
598
		H2NSHORT(f->r_fid);
599
		if( copydata )
600
		  H2NSTRING(f->r_stat, sizeof(f->r_stat));
601
		break;
602
 
603
	case Rwstat:
604
		H2NSHORT(f->r_fid);
605
		break;
606
	}
607
	return p - (u_char*)ap;
608
}
609
 
610
int
611
u9p_m2d(char *ap, struct u9fsdir *f)
612
{
613
	u_char *p;
614
 
615
	p = (u_char*)ap;
616
	N2HSTRING(f->dir_name, sizeof(f->dir_name));
617
	N2HSTRING(f->dir_uid, sizeof(f->dir_uid));
618
	N2HSTRING(f->dir_gid, sizeof(f->dir_gid));
619
	N2HLONG(f->dir_qid.path);
620
	N2HLONG(f->dir_qid.vers);
621
	N2HLONG(f->dir_mode);
622
	N2HLONG(f->dir_atime);
623
	N2HLONG(f->dir_mtime);
624
	N2HQUAD(f->dir_length);
625
	N2HSHORT(f->dir_type);
626
	N2HSHORT(f->dir_dev);
627
	return p - (u_char*)ap;
628
}
629
 
630
int
631
u9p_d2m(struct u9fsdir *f, char *ap)
632
{
633
	u_char *p;
634
 
635
	p = (u_char*)ap;
636
	H2NSTRING(f->dir_name, sizeof(f->dir_name));
637
	H2NSTRING(f->dir_uid, sizeof(f->dir_uid));
638
	H2NSTRING(f->dir_gid, sizeof(f->dir_gid));
639
	H2NLONG(f->dir_qid.path);
640
	H2NLONG(f->dir_qid.vers);
641
	H2NLONG(f->dir_mode);
642
	H2NLONG(f->dir_atime);
643
	H2NLONG(f->dir_mtime);
644
	H2NQUAD(f->dir_length);
645
	H2NSHORT(f->dir_type);
646
	H2NSHORT(f->dir_dev);
647
	return p - (u_char*)ap;
648
}
649
 
650
/* parse 9P types */
651
int u9p_type(char * t)
652
{
653
  int i;
654
 
655
  for(i = 0; i < sizeof(u9p_types)/sizeof(u9p_types[0]); i++) {
656
    if( strcmp(u9p_types[i], t) == 0 )
657
      return (i+Tnop);
658
  }
659
  return 0;
660
}
661
 
662
/* m is freed if shorter than s */
663
#if 1
664
#define U9P_PULLUP(m,s)  if( (*(m))->m_len < (s) && ((*(m)) = m_pullup((*(m)),(s))) == 0 ) return 1; p = mtod((*(m)), u_char *)
665
#else
666
#define U9P_PULLUP(m,s)  if( (*(m))->m_len < (s) && ((*(m)) = m_pullup((*(m)),(s))) == 0 ) panic("PULLUP"); p = mtod((*(m)), u_char *)
667
#endif
668
 
669
#define U9P_ADJ(m,s) (*(m))->m_len -= (s); (*(m))->m_data += (s)
670
 
671
u_short u9p_m_tag(struct mbuf ** m)
672
{
673
  char * p;
674
  u_short t;
675
 
676
  U9P_PULLUP(m,3);
677
  p = mtod(*m, char *);
678
  p++;
679
  N2HSHORT(t);
680
 
681
  return t;
682
}
683
 
684
int 
685
u9p_m_m2s(struct mbuf **m, struct u9fsreq *f)
686
{
687
  u_char *p;
688
 
689
  U9P_PULLUP(m,3);
690
  N2HCHAR(f->r_type);
691
  N2HSHORT(f->r_tag);
692
  U9P_ADJ(m, sizeof(f->r_type)+sizeof(f->r_tag));
693
 
694
  switch(f->r_type) {
695
  default:
696
    goto drop;
697
 
698
  case Tnop:
699
    break;
700
 
701
  case Tsession:
702
    U9P_PULLUP(m,sizeof(f->r_chal));
703
    N2HSTRING(f->r_chal, sizeof(f->r_chal));
704
    U9P_ADJ(m, sizeof(f->r_chal));
705
    break;
706
 
707
  case Tflush:
708
    U9P_PULLUP(m,sizeof(f->r_oldtag));
709
    N2HSHORT(f->r_oldtag);
710
    U9P_ADJ(m, f->r_oldtag);
711
    break;
712
 
713
  case Tattach:
714
    U9P_PULLUP(m, sizeof(f->r_fid)+sizeof(f->r_uname)+sizeof(f->r_aname));
715
    N2HSHORT(f->r_fid);
716
    N2HSTRING(f->r_uname, sizeof(f->r_uname));
717
    N2HSTRING(f->r_aname, sizeof(f->r_aname));
718
    U9P_ADJ(m, sizeof(f->r_fid)+sizeof(f->r_uname)+sizeof(f->r_aname));
719
 
720
    U9P_PULLUP(m, sizeof(f->r_ticket)+sizeof(f->r_auth));
721
    N2HSTRING(f->r_ticket, sizeof(f->r_ticket));
722
    N2HSTRING(f->r_auth, sizeof(f->r_auth));
723
    U9P_ADJ(m, sizeof(f->r_ticket)+sizeof(f->r_auth));
724
    break;
725
 
726
  case Tclone:
727
    U9P_PULLUP(m, sizeof(f->r_fid)+sizeof(f->r_newfid));
728
    N2HSHORT(f->r_fid);
729
    N2HSHORT(f->r_newfid);
730
    U9P_ADJ(m, sizeof(f->r_fid)+sizeof(f->r_newfid));
731
    break;
732
 
733
  case Twalk:
734
    U9P_PULLUP(m, sizeof(f->r_fid)+sizeof(f->r_name));
735
    N2HSHORT(f->r_fid);
736
    N2HSTRING(f->r_name, sizeof(f->r_name));
737
    U9P_ADJ(m, sizeof(f->r_fid)+sizeof(f->r_name));
738
    break;
739
 
740
  case Topen:
741
    U9P_PULLUP(m, sizeof(f->r_fid)+sizeof(f->r_mode));
742
    N2HSHORT(f->r_fid);
743
    N2HCHAR(f->r_mode);
744
    U9P_ADJ(m, sizeof(f->r_fid)+sizeof(f->r_mode));
745
    break;
746
 
747
  case Tcreate:
748
    U9P_PULLUP(m, sizeof(f->r_fid)+sizeof(f->r_name)
749
	       +sizeof(f->r_perm)+sizeof(f->r_mode));
750
    N2HSHORT(f->r_fid);
751
    N2HSTRING(f->r_name, sizeof(f->r_name));
752
    N2HLONG(f->r_perm);
753
    N2HCHAR(f->r_mode);
754
    U9P_ADJ(m, sizeof(f->r_fid)+sizeof(f->r_name)
755
	    +sizeof(f->r_perm)+sizeof(f->r_mode));
756
    break;
757
 
758
  case Tread:
759
    U9P_PULLUP(m, sizeof(f->r_fid)+sizeof(f->r_offset)+sizeof(f->r_count));
760
    N2HSHORT(f->r_fid);
761
    N2HQUAD(f->r_offset);
762
    N2HSHORT(f->r_count);
763
    U9P_ADJ(m, sizeof(f->r_fid)+sizeof(f->r_offset)+sizeof(f->r_count));
764
    break;
765
 
766
  case Twrite:
767
    U9P_PULLUP(m, sizeof(f->r_fid)+sizeof(f->r_offset)+sizeof(f->r_count));
768
    N2HSHORT(f->r_fid);
769
    N2HQUAD(f->r_offset);
770
    N2HSHORT(f->r_count);
771
    p++;	/* pad(1) */
772
    f->r_data = (char*)p; p += f->r_count;
773
    U9P_ADJ(m, sizeof(f->r_fid)+sizeof(f->r_offset)+sizeof(f->r_count)+1);
774
    break;
775
 
776
  case Tclunk:
777
  case Tremove:
778
  case Tstat: 
779
   U9P_PULLUP(m, sizeof(f->r_fid));
780
    N2HSHORT(f->r_fid);
781
    U9P_ADJ(m, sizeof(f->r_fid));
782
    break;
783
 
784
  case Twstat:
785
    U9P_PULLUP(m, sizeof(f->r_fid));
786
    N2HSHORT(f->r_fid);
787
    m_copydata(*m, sizeof(f->r_fid), sizeof(f->r_stat), f->r_stat);
788
    m_adj(*m, sizeof(f->r_fid)+sizeof(f->r_stat));
789
    break;
790
 
791
  case Tclwalk:
792
     U9P_PULLUP(m, sizeof(f->r_fid)+sizeof(f->r_newfid)+sizeof(f->r_name));
793
     N2HSHORT(f->r_fid);
794
     N2HSHORT(f->r_newfid);
795
     N2HSTRING(f->r_name, sizeof(f->r_name));
796
     U9P_ADJ(m, sizeof(f->r_fid)+sizeof(f->r_newfid)+sizeof(f->r_name));
797
     break;
798
/*
799
 */
800
  case Rnop:
801
    break;
802
 
803
  case Rsession:
804
    U9P_PULLUP(m, sizeof(f->r_fid)+sizeof(f->r_authid)+sizeof(f->r_authdom));
805
    N2HSTRING(f->r_chal, sizeof(f->r_chal));
806
    N2HSTRING(f->r_authid, sizeof(f->r_authid));
807
    N2HSTRING(f->r_authdom, sizeof(f->r_authdom));
808
    U9P_ADJ(m, sizeof(f->r_fid)+sizeof(f->r_authid)+sizeof(f->r_authdom));
809
    break;
810
 
811
  case Rerror:
812
    U9P_PULLUP(m, sizeof(f->r_ename));
813
    N2HSTRING(f->r_ename, sizeof(f->r_ename));
814
    U9P_ADJ(m, sizeof(f->r_ename));
815
    break;
816
 
817
  case Rflush:
818
    break;
819
 
820
  case Rattach:
821
    U9P_PULLUP(m, sizeof(f->r_fid)+sizeof(f->r_qid.path)
822
	       +sizeof(f->r_qid.vers)+sizeof(f->r_rauth));
823
    N2HSHORT(f->r_fid);
824
    N2HLONG(f->r_qid.path);
825
    N2HLONG(f->r_qid.vers);
826
    N2HSTRING(f->r_rauth, sizeof(f->r_rauth));
827
    U9P_ADJ(m, sizeof(f->r_fid)+sizeof(f->r_qid.path)
828
	    +sizeof(f->r_qid.vers)+sizeof(f->r_rauth));
829
    break;
830
 
831
  case Rclone:
832
    U9P_PULLUP(m, sizeof(f->r_fid));
833
    N2HSHORT(f->r_fid);
834
    U9P_ADJ(m, sizeof(f->r_fid));
835
    break;
836
 
837
  case Rwalk:
838
  case Rclwalk:
839
  case Ropen:
840
  case Rcreate:
841
    U9P_PULLUP(m, sizeof(f->r_fid)+sizeof(f->r_qid.path)
842
               +sizeof(f->r_qid.vers));
843
    N2HSHORT(f->r_fid);
844
    N2HLONG(f->r_qid.path);
845
    N2HLONG(f->r_qid.vers);
846
    U9P_ADJ(m, sizeof(f->r_fid)+sizeof(f->r_qid.path)
847
            +sizeof(f->r_qid.vers));
848
    break;
849
 
850
  case Rread:
851
    U9P_PULLUP(m, sizeof(f->r_fid)+sizeof(f->r_count));
852
    N2HSHORT(f->r_fid);
853
    N2HSHORT(f->r_count);
854
    p++;	/* pad(1) */
855
    f->r_data = (char*)p; p += f->r_count;
856
    U9P_ADJ(m, sizeof(f->r_fid)+sizeof(f->r_count)+1);
857
    break;
858
 
859
  case Rwrite:
860
    U9P_PULLUP(m, sizeof(f->r_fid)+sizeof(f->r_count));
861
    N2HSHORT(f->r_fid);
862
    N2HSHORT(f->r_count);
863
    U9P_ADJ(m, sizeof(f->r_fid)+sizeof(f->r_count));
864
    break;
865
 
866
  case Rclunk:
867
  case Rremove:
868
  case Rwstat:
869
    U9P_PULLUP(m, sizeof(f->r_fid));
870
    N2HSHORT(f->r_fid);
871
    U9P_ADJ(m, sizeof(f->r_fid));
872
    break;
873
 
874
  case Rstat:
875
    U9P_PULLUP(m, sizeof(f->r_fid));
876
    N2HSHORT(f->r_fid);
877
    m_copydata(*m, sizeof(f->r_fid), sizeof(f->r_stat), f->r_stat);
878
    m_adj(*m, sizeof(f->r_fid)+sizeof(f->r_stat));
879
    break;
880
 
881
  }
882
  return 0;
883
 
884
 drop:
885
  m_freem(*m);
886
  return 1;
887
}
888
 
889
struct mbuf * 
890
u9p_m_s2m (struct u9fsreq *f)
891
{
892
  register struct mbuf * m;
893
  struct mbuf * m0;
894
  char * ap;
895
  int sz;
896
 
897
  /* we want one contiguous piece */
898
  if( f->r_type == Tattach || f->r_type == Rstat || f->r_type == Twstat )
899
    sz = 146; /* sizeof a Tattach */
900
  else
901
    sz = 87; /* sizeof a Tsession */
902
 
903
  MGETHDR(m, M_WAIT, MT_DATA);  
904
  if( sz > MHLEN )
905
    MCLGET(m, M_WAIT);
906
  m->m_len = 0;
907
 
908
  if ( M_TRAILINGSPACE(m) < sz )
909
    panic("u9p_m_s2m");
910
 
911
  ap = mtod(m, char *);
912
  m->m_len = u9p_s2m(f, ap, 0);
913
  m->m_pkthdr.len = m->m_len;
914
 
915
  /* append data mbufs  */
916
  switch ( f->r_type ) {
917
  default:
918
    break;
919
  case Twrite:
920
  case Rread:
921
    m0 = (struct mbuf *)f->r_data;
922
    m->m_next = m0;
923
    m->m_pkthdr.len += f->r_count;
924
    break;
925
  }
926
 
927
  return m;
928
}
929
 
930
int 
931
u9p_m_m2d (struct mbuf **m, struct u9fsdir *f)
932
{
933
  u_char *p;
934
 
935
  U9P_PULLUP(m, sizeof(f->dir_name)+sizeof(f->dir_uid)+sizeof(f->dir_gid));
936
  N2HSTRING(f->dir_name, sizeof(f->dir_name));
937
  N2HSTRING(f->dir_uid, sizeof(f->dir_uid));
938
  N2HSTRING(f->dir_gid, sizeof(f->dir_gid));
939
  U9P_ADJ(m, sizeof(f->dir_name)+sizeof(f->dir_uid)+sizeof(f->dir_gid));
940
 
941
  U9P_PULLUP(m, sizeof(f->dir_qid)+sizeof(f->dir_mode)
942
	     +sizeof(f->dir_atime)+sizeof(f->dir_mtime)
943
	     +sizeof(f->dir_length)+sizeof(f->dir_type)+sizeof(f->dir_dev));
944
  N2HLONG(f->dir_qid.path);
945
  N2HLONG(f->dir_qid.vers);
946
  N2HLONG(f->dir_mode);
947
  N2HLONG(f->dir_atime);
948
  N2HLONG(f->dir_mtime);
949
  N2HQUAD(f->dir_length);
950
  N2HSHORT(f->dir_type);
951
  N2HSHORT(f->dir_dev);
952
  U9P_ADJ(m, sizeof(f->dir_qid)+sizeof(f->dir_mode)
953
	     +sizeof(f->dir_atime)+sizeof(f->dir_mtime)
954
	     +sizeof(f->dir_length)+sizeof(f->dir_type)+sizeof(f->dir_dev));
955
 
956
  return 0;
957
}
958
 
959
struct mbuf * u9p_m_d2m (struct u9fsdir *f)
960
{
961
  char * ap;
962
  struct mbuf * m;
963
  MGET(m, M_WAIT, MT_DATA);
964
  MCLGET(m, M_WAIT);
965
  m->m_len = 0;
966
 
967
  if ( M_TRAILINGSPACE(m) < sizeof(struct u9fsdir) )
968
    panic("u9p_m_d2m");
969
 
970
  ap = mtod(m, char *);
971
  m->m_len = u9p_d2m(f, ap);  
972
 
973
  return m;
974
}