Blame | Last modification | View Log | RSS feed
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <netinet/in.h>
#include <sys/mbuf.h>
#include <sys/malloc.h>
#include <sys/vnode.h>
#include <sys/mount.h>
#include <9fs/bitstring.h>
#include <9fs/9p.h>
#include <9fs/9auth.h>
#include <9fs/9fs.h>
int u9p_usetcp = 0;
struct u9fs_reqq u9fs_reqq;
#define N2HCHAR(x) x = *p++
#define N2HSHORT(x) x = (p[0] | (p[1]<<8)); p += 2
#define N2HLONG(x) x = (p[0] | (p[1]<<8) |\
(p[2]<<16) | (p[3]<<24)); p += 4
#define N2HQUAD(x) x = (u_int64_t)(p[0] | (p[1]<<8) |\
(p[2]<<16) | (p[3]<<24)) |\
((u_int64_t)(p[4] | (p[5]<<8) |\
(p[6]<<16) | (p[7]<<24)) << 32); p += 8
#define N2HSTRING(x,n) bcopy(p, x, n); p += n
#define H2NCHAR(x) *p++ = x
#define H2NSHORT(x) p[0]=x; p[1]=x>>8; p += 2
#define H2NLONG(x) p[0]=x; p[1]=x>>8; p[2]=x>>16; p[3]=x>>24; p += 4
#define H2NQUAD(x) p[0]=x; p[1]=x>>8;\
p[2]=x>>16; p[3]=x>>24;\
p[4]=x>>32; p[5]=x>>40;\
p[6]=x>>48; p[7]=x>>56;\
p += 8
#define H2NSTRING(x,n) bcopy(x, p, n); p += n
static void u9p_print __P((u_char * m, int len, struct u9fsreq * f));
static char * u9p_types[] = {
"Tnop",
"Rnop",
"Tosession",
"Rosession",
"Terror",
"Rerror",
"Tflush",
"Rflush",
"Toattach",
"Roattach",
"Tclone",
"Rclone",
"Twalk",
"Rwalk",
"Topen",
"Ropen",
"Tcreate",
"Rcreate",
"Tread",
"Rread",
"Twrite",
"Rwrite",
"Tclunk",
"Rclunk",
"Tremove",
"Rremove",
"Tstat",
"Rstat",
"Twstat",
"Rwstat",
"Tclwalk",
"Rclwalk",
"Tauth",
"Rauth",
"Tsession",
"Rsession",
"Tattach",
"Rattach",
"Ttunnel",
"Rtunnel",
"Tmax"
};
int u9p_m2s(char *ap, int n, struct u9fsreq *f)
{
u_char *p;
p = (u_char*)ap;
N2HCHAR(f->r_type);
N2HSHORT(f->r_tag);
switch(f->r_type)
{
default:
return 0;
case Tnop:
case Tosession:
break;
case Tsession:
N2HSTRING(f->r_chal, sizeof(f->r_chal));
break;
case Tflush:
N2HSHORT(f->r_oldtag);
break;
case Tattach:
N2HSHORT(f->r_fid);
N2HSTRING(f->r_uname, sizeof(f->r_uname));
N2HSTRING(f->r_aname, sizeof(f->r_aname));
N2HSTRING(f->r_ticket, sizeof(f->r_ticket));
N2HSTRING(f->r_auth, sizeof(f->r_auth));
break;
case Toattach:
N2HSHORT(f->r_fid);
N2HSTRING(f->r_uname, sizeof(f->r_uname));
N2HSTRING(f->r_aname, sizeof(f->r_aname));
N2HSTRING(f->r_ticket, U9FS_NAMELEN);
break;
case Tauth:
N2HSHORT(f->r_fid);
N2HSTRING(f->r_uname, sizeof(f->r_uname));
N2HSTRING(f->r_ticket, 8+U9FS_NAMELEN);
break;
case Tclone:
N2HSHORT(f->r_fid);
N2HSHORT(f->r_newfid);
break;
case Twalk:
N2HSHORT(f->r_fid);
N2HSTRING(f->r_name, sizeof(f->r_name));
break;
case Topen:
N2HSHORT(f->r_fid);
N2HCHAR(f->r_mode);
break;
case Tcreate:
N2HSHORT(f->r_fid);
N2HSTRING(f->r_name, sizeof(f->r_name));
N2HLONG(f->r_perm);
N2HCHAR(f->r_mode);
break;
case Tread:
N2HSHORT(f->r_fid);
N2HQUAD(f->r_offset);
N2HSHORT(f->r_count);
break;
case Twrite:
N2HSHORT(f->r_fid);
N2HQUAD(f->r_offset);
N2HSHORT(f->r_count);
p++; /* pad(1) */
f->r_data = (char*)p; p += f->r_count;
break;
case Ttunnel:
N2HSHORT(f->r_fid);
break;
case Tclunk:
N2HSHORT(f->r_fid);
break;
case Tremove:
N2HSHORT(f->r_fid);
break;
case Tstat:
N2HSHORT(f->r_fid);
break;
case Twstat:
N2HSHORT(f->r_fid);
N2HSTRING(f->r_stat, sizeof(f->r_stat));
break;
case Tclwalk:
N2HSHORT(f->r_fid);
N2HSHORT(f->r_newfid);
N2HSTRING(f->r_name, sizeof(f->r_name));
break;
/*
*/
case Rnop:
case Rosession:
break;
case Rsession:
N2HSTRING(f->r_chal, sizeof(f->r_chal));
N2HSTRING(f->r_authid, sizeof(f->r_authid));
N2HSTRING(f->r_authdom, sizeof(f->r_authdom));
break;
case Rerror:
N2HSTRING(f->r_ename, sizeof(f->r_ename));
break;
case Rflush:
break;
case Rattach:
N2HSHORT(f->r_fid);
N2HLONG(f->r_qid.path);
N2HLONG(f->r_qid.vers);
N2HSTRING(f->r_rauth, sizeof(f->r_rauth));
break;
case Roattach:
N2HSHORT(f->r_fid);
N2HLONG(f->r_qid.path);
N2HLONG(f->r_qid.vers);
break;
case Rauth:
N2HSHORT(f->r_fid);
N2HSTRING(f->r_ticket, 8+8+7+7);
break;
case Rclone:
N2HSHORT(f->r_fid);
break;
case Rwalk:
case Rclwalk:
N2HSHORT(f->r_fid);
N2HLONG(f->r_qid.path);
N2HLONG(f->r_qid.vers);
break;
case Ropen:
N2HSHORT(f->r_fid);
N2HLONG(f->r_qid.path);
N2HLONG(f->r_qid.vers);
break;
case Rcreate:
N2HSHORT(f->r_fid);
N2HLONG(f->r_qid.path);
N2HLONG(f->r_qid.vers);
break;
case Rread:
N2HSHORT(f->r_fid);
N2HSHORT(f->r_count);
p++; /* pad(1) */
f->r_data = (char*)p; p += f->r_count;
break;
case Rwrite:
N2HSHORT(f->r_fid);
N2HSHORT(f->r_count);
break;
case Rtunnel:
N2HSHORT(f->r_fid);
break;
case Rclunk:
N2HSHORT(f->r_fid);
break;
case Rremove:
N2HSHORT(f->r_fid);
break;
case Rstat:
N2HSHORT(f->r_fid);
N2HSTRING(f->r_stat, sizeof(f->r_stat));
break;
case Rwstat:
N2HSHORT(f->r_fid);
break;
}
if((u_char*)ap+n == p)
return n;
return 0;
}
void u9p_print(u_char * m, int len, struct u9fsreq * f)
{
struct u9fsreq u9fsreq;
if( f == 0 )
f = & u9fsreq;
if( len < 3 ) {
printf("truncated-9p %d", len);
return;
}
if( u9p_m2s((char *)m, len, f) == 0 )
return;
printf("%s tag %d ", u9p_types[f->r_type-Tnop], f->r_tag);
switch( f->r_type ) {
default:
return;
case Tnop:
case Tosession:
case Toattach:
case Tauth:
break;
case Tsession:
case Rsession:
printf("chal 0x%x 0x%x", *(u_int *)&f->r_chal[0], *(u_int *)&f->r_chal[4]);
break;
case Tflush:
printf("oldtag %d", f->r_oldtag);
break;
case Tclone:
printf("fid %d newfid %d", f->r_fid, f->r_newfid);
break;
case Twalk:
printf("fid %d name %s", f->r_fid, f->r_name);
break;
case Topen:
printf("fid %d %c", f->r_fid, f->r_mode);
break;
case Tcreate:
printf("fid %d name %s perm 0x%x mode %c", f->r_fid,
f->r_name, f->r_perm, f->r_mode);
break;
case Tread:
case Twrite:
printf("fid %d offset 0x%llx count %d", f->r_fid,
f->r_offset, f->r_count);
break;
case Tattach:
case Ttunnel:
case Tclunk:
case Tremove:
case Tstat:
case Twstat:
case Rclone:
case Rtunnel:
case Rclunk:
case Rremove:
case Rstat:
case Rwstat:
printf("fid %d", f->r_fid);
break;
case Tclwalk:
printf("fid %d ", f->r_fid);
printf("newfid %d ", f->r_newfid);
printf("name %s", f->r_name);
break;
/*
*/
case Rnop:
case Rosession:
case Rflush:
case Roattach:
case Rauth:
break;
case Rerror:
printf("ename %s", f->r_ename);
break;
case Rattach:
case Rwalk:
case Rclwalk:
case Ropen:
case Rcreate:
printf("fid %d ", f->r_fid);
printf("qid 0x%x 0x%x", f->r_qid.path, f->r_qid.vers);
break;
case Rread:
printf("fid %d count %d ", f->r_fid, f->r_count);
break;
case Rwrite:
printf("fid %d count %d", f->r_fid, f->r_count);
break;
}
}
int
u9p_s2m(struct u9fsreq *f, char *ap, int copydata)
{
u_char *p;
p = (u_char*)ap;
H2NCHAR(f->r_type);
H2NSHORT(f->r_tag);
switch(f->r_type)
{
default:
return 0;
case Tosession:
case Tnop:
break;
case Tsession:
H2NSTRING(f->r_chal, sizeof(f->r_chal));
break;
case Tflush:
H2NSHORT(f->r_oldtag);
break;
case Tattach:
H2NSHORT(f->r_fid);
H2NSTRING(f->r_uname, sizeof(f->r_uname));
H2NSTRING(f->r_aname, sizeof(f->r_aname));
H2NSTRING(f->r_ticket, sizeof(f->r_ticket));
H2NSTRING(f->r_auth, sizeof(f->r_auth));
break;
case Toattach:
H2NSHORT(f->r_fid);
H2NSTRING(f->r_uname, sizeof(f->r_uname));
H2NSTRING(f->r_aname, sizeof(f->r_aname));
H2NSTRING(f->r_ticket, U9FS_NAMELEN);
break;
case Tauth:
H2NSHORT(f->r_fid);
H2NSTRING(f->r_uname, sizeof(f->r_uname));
H2NSTRING(f->r_ticket, 8+U9FS_NAMELEN);
break;
case Tclone:
H2NSHORT(f->r_fid);
H2NSHORT(f->r_newfid);
break;
case Twalk:
H2NSHORT(f->r_fid);
H2NSTRING(f->r_name, sizeof(f->r_name));
break;
case Topen:
H2NSHORT(f->r_fid);
H2NCHAR(f->r_mode);
break;
case Tcreate:
H2NSHORT(f->r_fid);
H2NSTRING(f->r_name, sizeof(f->r_name));
H2NLONG(f->r_perm);
H2NCHAR(f->r_mode);
break;
case Tread:
H2NSHORT(f->r_fid);
H2NQUAD(f->r_offset);
H2NSHORT(f->r_count);
break;
case Twrite:
H2NSHORT(f->r_fid);
H2NQUAD(f->r_offset);
H2NSHORT(f->r_count);
p++; /* pad(1) */
if( copydata ) {
H2NSTRING(f->r_data, f->r_count);
}
break;
case Ttunnel:
H2NSHORT(f->r_fid);
break;
case Tclunk:
H2NSHORT(f->r_fid);
break;
case Tremove:
H2NSHORT(f->r_fid);
break;
case Tstat:
H2NSHORT(f->r_fid);
break;
case Twstat:
H2NSHORT(f->r_fid);
H2NSTRING(f->r_stat, sizeof(f->r_stat));
break;
case Tclwalk:
H2NSHORT(f->r_fid);
H2NSHORT(f->r_newfid);
H2NSTRING(f->r_name, sizeof(f->r_name));
break;
/*
*/
case Rosession:
case Rnop:
break;
case Rsession:
H2NSTRING(f->r_chal, sizeof(f->r_chal));
H2NSTRING(f->r_authid, sizeof(f->r_authid));
H2NSTRING(f->r_authdom, sizeof(f->r_authdom));
break;
case Rerror:
H2NSTRING(f->r_ename, sizeof(f->r_ename));
break;
case Rflush:
break;
case Rattach:
H2NSHORT(f->r_fid);
H2NLONG(f->r_qid.path);
H2NLONG(f->r_qid.vers);
H2NSTRING(f->r_rauth, sizeof(f->r_rauth));
break;
case Roattach:
H2NSHORT(f->r_fid);
H2NLONG(f->r_qid.path);
H2NLONG(f->r_qid.vers);
break;
case Rauth:
H2NSHORT(f->r_fid);
H2NSTRING(f->r_ticket, 8+8+7+7);
break;
case Rclone:
H2NSHORT(f->r_fid);
break;
case Rwalk:
case Rclwalk:
H2NSHORT(f->r_fid);
H2NLONG(f->r_qid.path);
H2NLONG(f->r_qid.vers);
break;
case Ropen:
H2NSHORT(f->r_fid);
H2NLONG(f->r_qid.path);
H2NLONG(f->r_qid.vers);
break;
case Rcreate:
H2NSHORT(f->r_fid);
H2NLONG(f->r_qid.path);
H2NLONG(f->r_qid.vers);
break;
case Rread:
H2NSHORT(f->r_fid);
H2NSHORT(f->r_count);
p++; /* pad(1) */
if( copydata ) {
H2NSTRING(f->r_data, f->r_count);
}
break;
case Rwrite:
H2NSHORT(f->r_fid);
H2NSHORT(f->r_count);
break;
case Rtunnel:
H2NSHORT(f->r_fid);
break;
case Rclunk:
H2NSHORT(f->r_fid);
break;
case Rremove:
H2NSHORT(f->r_fid);
break;
case Rstat:
H2NSHORT(f->r_fid);
if( copydata )
H2NSTRING(f->r_stat, sizeof(f->r_stat));
break;
case Rwstat:
H2NSHORT(f->r_fid);
break;
}
return p - (u_char*)ap;
}
int
u9p_m2d(char *ap, struct u9fsdir *f)
{
u_char *p;
p = (u_char*)ap;
N2HSTRING(f->dir_name, sizeof(f->dir_name));
N2HSTRING(f->dir_uid, sizeof(f->dir_uid));
N2HSTRING(f->dir_gid, sizeof(f->dir_gid));
N2HLONG(f->dir_qid.path);
N2HLONG(f->dir_qid.vers);
N2HLONG(f->dir_mode);
N2HLONG(f->dir_atime);
N2HLONG(f->dir_mtime);
N2HQUAD(f->dir_length);
N2HSHORT(f->dir_type);
N2HSHORT(f->dir_dev);
return p - (u_char*)ap;
}
int
u9p_d2m(struct u9fsdir *f, char *ap)
{
u_char *p;
p = (u_char*)ap;
H2NSTRING(f->dir_name, sizeof(f->dir_name));
H2NSTRING(f->dir_uid, sizeof(f->dir_uid));
H2NSTRING(f->dir_gid, sizeof(f->dir_gid));
H2NLONG(f->dir_qid.path);
H2NLONG(f->dir_qid.vers);
H2NLONG(f->dir_mode);
H2NLONG(f->dir_atime);
H2NLONG(f->dir_mtime);
H2NQUAD(f->dir_length);
H2NSHORT(f->dir_type);
H2NSHORT(f->dir_dev);
return p - (u_char*)ap;
}
/* parse 9P types */
int u9p_type(char * t)
{
int i;
for(i = 0; i < sizeof(u9p_types)/sizeof(u9p_types[0]); i++) {
if( strcmp(u9p_types[i], t) == 0 )
return (i+Tnop);
}
return 0;
}
/* m is freed if shorter than s */
#if 1
#define U9P_PULLUP(m,s) if( (*(m))->m_len < (s) && ((*(m)) = m_pullup((*(m)),(s))) == 0 ) return 1; p = mtod((*(m)), u_char *)
#else
#define U9P_PULLUP(m,s) if( (*(m))->m_len < (s) && ((*(m)) = m_pullup((*(m)),(s))) == 0 ) panic("PULLUP"); p = mtod((*(m)), u_char *)
#endif
#define U9P_ADJ(m,s) (*(m))->m_len -= (s); (*(m))->m_data += (s)
u_short u9p_m_tag(struct mbuf ** m)
{
char * p;
u_short t;
U9P_PULLUP(m,3);
p = mtod(*m, char *);
p++;
N2HSHORT(t);
return t;
}
int
u9p_m_m2s(struct mbuf **m, struct u9fsreq *f)
{
u_char *p;
U9P_PULLUP(m,3);
N2HCHAR(f->r_type);
N2HSHORT(f->r_tag);
U9P_ADJ(m, sizeof(f->r_type)+sizeof(f->r_tag));
switch(f->r_type) {
default:
goto drop;
case Tnop:
break;
case Tsession:
U9P_PULLUP(m,sizeof(f->r_chal));
N2HSTRING(f->r_chal, sizeof(f->r_chal));
U9P_ADJ(m, sizeof(f->r_chal));
break;
case Tflush:
U9P_PULLUP(m,sizeof(f->r_oldtag));
N2HSHORT(f->r_oldtag);
U9P_ADJ(m, f->r_oldtag);
break;
case Tattach:
U9P_PULLUP(m, sizeof(f->r_fid)+sizeof(f->r_uname)+sizeof(f->r_aname));
N2HSHORT(f->r_fid);
N2HSTRING(f->r_uname, sizeof(f->r_uname));
N2HSTRING(f->r_aname, sizeof(f->r_aname));
U9P_ADJ(m, sizeof(f->r_fid)+sizeof(f->r_uname)+sizeof(f->r_aname));
U9P_PULLUP(m, sizeof(f->r_ticket)+sizeof(f->r_auth));
N2HSTRING(f->r_ticket, sizeof(f->r_ticket));
N2HSTRING(f->r_auth, sizeof(f->r_auth));
U9P_ADJ(m, sizeof(f->r_ticket)+sizeof(f->r_auth));
break;
case Tclone:
U9P_PULLUP(m, sizeof(f->r_fid)+sizeof(f->r_newfid));
N2HSHORT(f->r_fid);
N2HSHORT(f->r_newfid);
U9P_ADJ(m, sizeof(f->r_fid)+sizeof(f->r_newfid));
break;
case Twalk:
U9P_PULLUP(m, sizeof(f->r_fid)+sizeof(f->r_name));
N2HSHORT(f->r_fid);
N2HSTRING(f->r_name, sizeof(f->r_name));
U9P_ADJ(m, sizeof(f->r_fid)+sizeof(f->r_name));
break;
case Topen:
U9P_PULLUP(m, sizeof(f->r_fid)+sizeof(f->r_mode));
N2HSHORT(f->r_fid);
N2HCHAR(f->r_mode);
U9P_ADJ(m, sizeof(f->r_fid)+sizeof(f->r_mode));
break;
case Tcreate:
U9P_PULLUP(m, sizeof(f->r_fid)+sizeof(f->r_name)
+sizeof(f->r_perm)+sizeof(f->r_mode));
N2HSHORT(f->r_fid);
N2HSTRING(f->r_name, sizeof(f->r_name));
N2HLONG(f->r_perm);
N2HCHAR(f->r_mode);
U9P_ADJ(m, sizeof(f->r_fid)+sizeof(f->r_name)
+sizeof(f->r_perm)+sizeof(f->r_mode));
break;
case Tread:
U9P_PULLUP(m, sizeof(f->r_fid)+sizeof(f->r_offset)+sizeof(f->r_count));
N2HSHORT(f->r_fid);
N2HQUAD(f->r_offset);
N2HSHORT(f->r_count);
U9P_ADJ(m, sizeof(f->r_fid)+sizeof(f->r_offset)+sizeof(f->r_count));
break;
case Twrite:
U9P_PULLUP(m, sizeof(f->r_fid)+sizeof(f->r_offset)+sizeof(f->r_count));
N2HSHORT(f->r_fid);
N2HQUAD(f->r_offset);
N2HSHORT(f->r_count);
p++; /* pad(1) */
f->r_data = (char*)p; p += f->r_count;
U9P_ADJ(m, sizeof(f->r_fid)+sizeof(f->r_offset)+sizeof(f->r_count)+1);
break;
case Tclunk:
case Tremove:
case Tstat:
U9P_PULLUP(m, sizeof(f->r_fid));
N2HSHORT(f->r_fid);
U9P_ADJ(m, sizeof(f->r_fid));
break;
case Twstat:
U9P_PULLUP(m, sizeof(f->r_fid));
N2HSHORT(f->r_fid);
m_copydata(*m, sizeof(f->r_fid), sizeof(f->r_stat), f->r_stat);
m_adj(*m, sizeof(f->r_fid)+sizeof(f->r_stat));
break;
case Tclwalk:
U9P_PULLUP(m, sizeof(f->r_fid)+sizeof(f->r_newfid)+sizeof(f->r_name));
N2HSHORT(f->r_fid);
N2HSHORT(f->r_newfid);
N2HSTRING(f->r_name, sizeof(f->r_name));
U9P_ADJ(m, sizeof(f->r_fid)+sizeof(f->r_newfid)+sizeof(f->r_name));
break;
/*
*/
case Rnop:
break;
case Rsession:
U9P_PULLUP(m, sizeof(f->r_fid)+sizeof(f->r_authid)+sizeof(f->r_authdom));
N2HSTRING(f->r_chal, sizeof(f->r_chal));
N2HSTRING(f->r_authid, sizeof(f->r_authid));
N2HSTRING(f->r_authdom, sizeof(f->r_authdom));
U9P_ADJ(m, sizeof(f->r_fid)+sizeof(f->r_authid)+sizeof(f->r_authdom));
break;
case Rerror:
U9P_PULLUP(m, sizeof(f->r_ename));
N2HSTRING(f->r_ename, sizeof(f->r_ename));
U9P_ADJ(m, sizeof(f->r_ename));
break;
case Rflush:
break;
case Rattach:
U9P_PULLUP(m, sizeof(f->r_fid)+sizeof(f->r_qid.path)
+sizeof(f->r_qid.vers)+sizeof(f->r_rauth));
N2HSHORT(f->r_fid);
N2HLONG(f->r_qid.path);
N2HLONG(f->r_qid.vers);
N2HSTRING(f->r_rauth, sizeof(f->r_rauth));
U9P_ADJ(m, sizeof(f->r_fid)+sizeof(f->r_qid.path)
+sizeof(f->r_qid.vers)+sizeof(f->r_rauth));
break;
case Rclone:
U9P_PULLUP(m, sizeof(f->r_fid));
N2HSHORT(f->r_fid);
U9P_ADJ(m, sizeof(f->r_fid));
break;
case Rwalk:
case Rclwalk:
case Ropen:
case Rcreate:
U9P_PULLUP(m, sizeof(f->r_fid)+sizeof(f->r_qid.path)
+sizeof(f->r_qid.vers));
N2HSHORT(f->r_fid);
N2HLONG(f->r_qid.path);
N2HLONG(f->r_qid.vers);
U9P_ADJ(m, sizeof(f->r_fid)+sizeof(f->r_qid.path)
+sizeof(f->r_qid.vers));
break;
case Rread:
U9P_PULLUP(m, sizeof(f->r_fid)+sizeof(f->r_count));
N2HSHORT(f->r_fid);
N2HSHORT(f->r_count);
p++; /* pad(1) */
f->r_data = (char*)p; p += f->r_count;
U9P_ADJ(m, sizeof(f->r_fid)+sizeof(f->r_count)+1);
break;
case Rwrite:
U9P_PULLUP(m, sizeof(f->r_fid)+sizeof(f->r_count));
N2HSHORT(f->r_fid);
N2HSHORT(f->r_count);
U9P_ADJ(m, sizeof(f->r_fid)+sizeof(f->r_count));
break;
case Rclunk:
case Rremove:
case Rwstat:
U9P_PULLUP(m, sizeof(f->r_fid));
N2HSHORT(f->r_fid);
U9P_ADJ(m, sizeof(f->r_fid));
break;
case Rstat:
U9P_PULLUP(m, sizeof(f->r_fid));
N2HSHORT(f->r_fid);
m_copydata(*m, sizeof(f->r_fid), sizeof(f->r_stat), f->r_stat);
m_adj(*m, sizeof(f->r_fid)+sizeof(f->r_stat));
break;
}
return 0;
drop:
m_freem(*m);
return 1;
}
struct mbuf *
u9p_m_s2m (struct u9fsreq *f)
{
register struct mbuf * m;
struct mbuf * m0;
char * ap;
int sz;
/* we want one contiguous piece */
if( f->r_type == Tattach || f->r_type == Rstat || f->r_type == Twstat )
sz = 146; /* sizeof a Tattach */
else
sz = 87; /* sizeof a Tsession */
MGETHDR(m, M_WAIT, MT_DATA);
if( sz > MHLEN )
MCLGET(m, M_WAIT);
m->m_len = 0;
if ( M_TRAILINGSPACE(m) < sz )
panic("u9p_m_s2m");
ap = mtod(m, char *);
m->m_len = u9p_s2m(f, ap, 0);
m->m_pkthdr.len = m->m_len;
/* append data mbufs */
switch ( f->r_type ) {
default:
break;
case Twrite:
case Rread:
m0 = (struct mbuf *)f->r_data;
m->m_next = m0;
m->m_pkthdr.len += f->r_count;
break;
}
return m;
}
int
u9p_m_m2d (struct mbuf **m, struct u9fsdir *f)
{
u_char *p;
U9P_PULLUP(m, sizeof(f->dir_name)+sizeof(f->dir_uid)+sizeof(f->dir_gid));
N2HSTRING(f->dir_name, sizeof(f->dir_name));
N2HSTRING(f->dir_uid, sizeof(f->dir_uid));
N2HSTRING(f->dir_gid, sizeof(f->dir_gid));
U9P_ADJ(m, sizeof(f->dir_name)+sizeof(f->dir_uid)+sizeof(f->dir_gid));
U9P_PULLUP(m, sizeof(f->dir_qid)+sizeof(f->dir_mode)
+sizeof(f->dir_atime)+sizeof(f->dir_mtime)
+sizeof(f->dir_length)+sizeof(f->dir_type)+sizeof(f->dir_dev));
N2HLONG(f->dir_qid.path);
N2HLONG(f->dir_qid.vers);
N2HLONG(f->dir_mode);
N2HLONG(f->dir_atime);
N2HLONG(f->dir_mtime);
N2HQUAD(f->dir_length);
N2HSHORT(f->dir_type);
N2HSHORT(f->dir_dev);
U9P_ADJ(m, sizeof(f->dir_qid)+sizeof(f->dir_mode)
+sizeof(f->dir_atime)+sizeof(f->dir_mtime)
+sizeof(f->dir_length)+sizeof(f->dir_type)+sizeof(f->dir_dev));
return 0;
}
struct mbuf * u9p_m_d2m (struct u9fsdir *f)
{
char * ap;
struct mbuf * m;
MGET(m, M_WAIT, MT_DATA);
MCLGET(m, M_WAIT);
m->m_len = 0;
if ( M_TRAILINGSPACE(m) < sizeof(struct u9fsdir) )
panic("u9p_m_d2m");
ap = mtod(m, char *);
m->m_len = u9p_d2m(f, ap);
return m;
}