1/*
2 * Copyright 2016 Jakub Klama <jceel@FreeBSD.org>
3 * All rights reserved
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted providing that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
22 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
23 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 * POSSIBILITY OF SUCH DAMAGE.
25 *
26 */
27
28/*
29 * Based on libixp code: ��2007-2010 Kris Maglione <maglione.k at Gmail>
30 */
31
32#include <stdlib.h>
33#include <string.h>
34#include <assert.h>
35#include <sys/types.h>
36#include <sys/param.h>
37#ifdef __APPLE__
38# include "apple_endian.h"
39#else
40# include <sys/endian.h>
41#endif
42#include <sys/uio.h>
43#include "lib9p.h"
44#include "lib9p_impl.h"
45#include "log.h"
46
47#define N(ary)          (sizeof(ary) / sizeof(*ary))
48#define STRING_SIZE(s)  (L9P_WORD + (s != NULL ? (uint16_t)strlen(s) : 0))
49#define QID_SIZE        (L9P_BYTE + L9P_DWORD + L9P_QWORD)
50
51static ssize_t l9p_iov_io(struct l9p_message *, void *, size_t);
52static inline ssize_t l9p_pu8(struct l9p_message *, uint8_t *);
53static inline ssize_t l9p_pu16(struct l9p_message *, uint16_t *);
54static inline ssize_t l9p_pu32(struct l9p_message *, uint32_t *);
55static inline ssize_t l9p_pu64(struct l9p_message *, uint64_t *);
56static ssize_t l9p_pustring(struct l9p_message *, char **s);
57static ssize_t l9p_pustrings(struct l9p_message *, uint16_t *, char **, size_t);
58static ssize_t l9p_puqid(struct l9p_message *, struct l9p_qid *);
59static ssize_t l9p_puqids(struct l9p_message *, uint16_t *, struct l9p_qid *q);
60
61/*
62 * Transfer data from incoming request, or to outgoing response,
63 * using msg to track position and direction within request/response.
64 *
65 * Returns the number of bytes actually transferred (which is always
66 * just len itself, converted to signed), or -1 if we ran out of space.
67 *
68 * Note that if we return -1, subsequent l9p_iov_io() calls with
69 * the same (and not-reset) msg and len > 0 will also return -1.
70 * This means most users can just check the *last* call for failure.
71 */
72static ssize_t
73l9p_iov_io(struct l9p_message *msg, void *buffer, size_t len)
74{
75	size_t done = 0;
76	size_t left = len;
77
78	assert(msg != NULL);
79
80	if (len == 0)
81		return (0);
82
83	if (msg->lm_cursor_iov >= msg->lm_niov)
84		return (-1);
85
86	assert(buffer != NULL);
87
88	while (left > 0) {
89		size_t idx = msg->lm_cursor_iov;
90		size_t space = msg->lm_iov[idx].iov_len - msg->lm_cursor_offset;
91		size_t towrite = MIN(space, left);
92
93		if (msg->lm_mode == L9P_PACK) {
94			memcpy((char *)msg->lm_iov[idx].iov_base +
95			    msg->lm_cursor_offset, (char *)buffer + done,
96			    towrite);
97		}
98
99		if (msg->lm_mode == L9P_UNPACK) {
100			memcpy((char *)buffer + done,
101			    (char *)msg->lm_iov[idx].iov_base +
102			    msg->lm_cursor_offset, towrite);
103		}
104
105		msg->lm_cursor_offset += towrite;
106
107		done += towrite;
108		left -= towrite;
109
110		if (space - towrite == 0) {
111			/* Advance to next iov */
112			msg->lm_cursor_iov++;
113			msg->lm_cursor_offset = 0;
114
115			if (msg->lm_cursor_iov >= msg->lm_niov && left > 0)
116				return (-1);
117		}
118	}
119
120	msg->lm_size += done;
121	return ((ssize_t)done);
122}
123
124/*
125 * Pack or unpack a byte (8 bits).
126 *
127 * Returns 1 (success, 1 byte) or -1 (error).
128 */
129static inline ssize_t
130l9p_pu8(struct l9p_message *msg, uint8_t *val)
131{
132
133	return (l9p_iov_io(msg, val, sizeof (uint8_t)));
134}
135
136/*
137 * Pack or unpack 16-bit value.
138 *
139 * Returns 2 or -1.
140 */
141static inline ssize_t
142l9p_pu16(struct l9p_message *msg, uint16_t *val)
143{
144#if _BYTE_ORDER != _LITTLE_ENDIAN
145	/*
146	 * The ifdefs are annoying, but there is no need
147	 * for all of this foolery on little-endian hosts,
148	 * and I don't expect the compiler to optimize it
149	 * all away.
150	 */
151	uint16_t copy;
152	ssize_t ret;
153
154	if (msg->lm_mode == L9P_PACK) {
155		copy = htole16(*val);
156		return (l9p_iov_io(msg, &copy, sizeof (uint16_t)));
157	}
158	ret = l9p_iov_io(msg, val, sizeof (uint16_t));
159	*val = le16toh(*val);
160	return (ret);
161#else
162	return (l9p_iov_io(msg, val, sizeof (uint16_t)));
163#endif
164}
165
166/*
167 * Pack or unpack 32-bit value.
168 *
169 * Returns 4 or -1.
170 */
171static inline ssize_t
172l9p_pu32(struct l9p_message *msg, uint32_t *val)
173{
174#if _BYTE_ORDER != _LITTLE_ENDIAN
175	uint32_t copy;
176	ssize_t ret;
177
178	if (msg->lm_mode == L9P_PACK) {
179		copy = htole32(*val);
180		return (l9p_iov_io(msg, &copy, sizeof (uint32_t)));
181	}
182	ret = l9p_iov_io(msg, val, sizeof (uint32_t));
183	*val = le32toh(*val);
184	return (ret);
185#else
186	return (l9p_iov_io(msg, val, sizeof (uint32_t)));
187#endif
188}
189
190/*
191 * Pack or unpack 64-bit value.
192 *
193 * Returns 8 or -1.
194 */
195static inline ssize_t
196l9p_pu64(struct l9p_message *msg, uint64_t *val)
197{
198#if _BYTE_ORDER != _LITTLE_ENDIAN
199	uint64_t copy;
200	ssize_t ret;
201
202	if (msg->lm_mode == L9P_PACK) {
203		copy = htole64(*val);
204		return (l9p_iov_io(msg, &copy, sizeof (uint64_t)));
205	}
206	ret = l9p_iov_io(msg, val, sizeof (uint32_t));
207	*val = le64toh(*val);
208	return (ret);
209#else
210	return (l9p_iov_io(msg, val, sizeof (uint64_t)));
211#endif
212}
213
214/*
215 * Pack or unpack a string, encoded as 2-byte length followed by
216 * string bytes.  The returned length is 2 greater than the
217 * length of the string itself.
218 *
219 * When unpacking, this allocates a new string (NUL-terminated).
220 *
221 * Return -1 on error (not space, or failed to allocate string,
222 * or illegal string).
223 *
224 * Note that pustring (and hence pustrings) can return an error
225 * even when l9p_iov_io succeeds.
226 */
227static ssize_t
228l9p_pustring(struct l9p_message *msg, char **s)
229{
230	uint16_t len;
231
232	if (msg->lm_mode == L9P_PACK)
233		len = *s != NULL ? (uint16_t)strlen(*s) : 0;
234
235	if (l9p_pu16(msg, &len) < 0)
236		return (-1);
237
238	if (msg->lm_mode == L9P_UNPACK) {
239		*s = l9p_calloc(1, len + 1);
240		if (*s == NULL)
241			return (-1);
242	}
243
244	if (l9p_iov_io(msg, *s, len) < 0)
245		return (-1);
246
247	if (msg->lm_mode == L9P_UNPACK) {
248		/*
249		 * An embedded NUL byte in a string is illegal.
250		 * We don't necessarily have to check (we'll just
251		 * treat it as a shorter string), but checking
252		 * seems like a good idea.
253		 */
254		if (memchr(*s, '\0', len) != NULL)
255			return (-1);
256	}
257
258	return ((ssize_t)len + 2);
259}
260
261/*
262 * Pack or unpack a number (*num) of strings (but at most max of
263 * them).
264 *
265 * Returns the number of bytes transferred, including the packed
266 * number of strings.  If packing and the packed number of strings
267 * was reduced, the original *num value is unchanged; only the
268 * wire-format number is reduced.  If unpacking and the input
269 * number of strings exceeds the max, the incoming *num is reduced
270 * to lim, if needed.  (NOTE ASYMMETRY HERE!)
271 *
272 * Returns -1 on error.
273 */
274static ssize_t
275l9p_pustrings(struct l9p_message *msg, uint16_t *num, char **strings,
276    size_t max)
277{
278	size_t i, lim;
279	ssize_t r, ret;
280	uint16_t adjusted;
281
282	if (msg->lm_mode == L9P_PACK) {
283		lim = *num;
284		if (lim > max)
285			lim = max;
286		adjusted = (uint16_t)lim;
287		r = l9p_pu16(msg, &adjusted);
288	} else {
289		r = l9p_pu16(msg, num);
290		lim = *num;
291		if (lim > max)
292			*num = (uint16_t)(lim = max);
293	}
294	if (r < 0)
295		return (-1);
296
297	for (i = 0; i < lim; i++) {
298		ret = l9p_pustring(msg, &strings[i]);
299		if (ret < 1)
300			return (-1);
301
302		r += ret;
303	}
304
305	return (r);
306}
307
308/*
309 * Pack or unpack a qid.
310 *
311 * Returns 13 (success) or -1 (error).
312 */
313static ssize_t
314l9p_puqid(struct l9p_message *msg, struct l9p_qid *qid)
315{
316	ssize_t r;
317	uint8_t type;
318
319	if (msg->lm_mode == L9P_PACK) {
320		type = qid->type;
321		r = l9p_pu8(msg, &type);
322	} else {
323		r = l9p_pu8(msg, &type);
324		qid->type = type;
325	}
326	if (r > 0)
327		r = l9p_pu32(msg, &qid->version);
328	if (r > 0)
329		r = l9p_pu64(msg, &qid->path);
330
331	return (r > 0 ? QID_SIZE : r);
332}
333
334/*
335 * Pack or unpack *num qids.
336 *
337 * Returns 2 + 13 * *num (after possibly setting *num), or -1 on error.
338 */
339static ssize_t
340l9p_puqids(struct l9p_message *msg, uint16_t *num, struct l9p_qid *qids)
341{
342	size_t i, lim;
343	ssize_t ret, r;
344
345	r = l9p_pu16(msg, num);
346	if (r <= 0)
347		return (r);
348
349	if (*num > L9P_MAX_WELEM)
350		return (-1);
351
352	for (i = 0, lim = *num; i < lim; i++) {
353		ret = l9p_puqid(msg, &qids[i]);
354		if (ret < 0)
355			return (-1);
356		r += ret;
357	}
358	return (r);
359}
360
361/*
362 * Pack or unpack a l9p_stat.
363 *
364 * These have variable size, and the size further depends on
365 * the protocol version.
366 *
367 * Returns the number of bytes packed/unpacked, or -1 on error.
368 */
369ssize_t
370l9p_pustat(struct l9p_message *msg, struct l9p_stat *stat,
371    enum l9p_version version)
372{
373	ssize_t r = 0;
374	uint16_t size;
375
376	/* The on-wire size field excludes the size of the size field. */
377	if (msg->lm_mode == L9P_PACK)
378		size = l9p_sizeof_stat(stat, version) - 2;
379
380	r += l9p_pu16(msg, &size);
381	r += l9p_pu16(msg, &stat->type);
382	r += l9p_pu32(msg, &stat->dev);
383	r += l9p_puqid(msg, &stat->qid);
384	r += l9p_pu32(msg, &stat->mode);
385	r += l9p_pu32(msg, &stat->atime);
386	r += l9p_pu32(msg, &stat->mtime);
387	r += l9p_pu64(msg, &stat->length);
388	r += l9p_pustring(msg, &stat->name);
389	r += l9p_pustring(msg, &stat->uid);
390	r += l9p_pustring(msg, &stat->gid);
391	r += l9p_pustring(msg, &stat->muid);
392
393	if (version >= L9P_2000U) {
394		r += l9p_pustring(msg, &stat->extension);
395		r += l9p_pu32(msg, &stat->n_uid);
396		r += l9p_pu32(msg, &stat->n_gid);
397		r += l9p_pu32(msg, &stat->n_muid);
398	}
399
400	if (r < size + 2)
401		return (-1);
402
403	return (r);
404}
405
406/*
407 * Pack or unpack a variable-length dirent.
408 *
409 * If unpacking, the name field is malloc()ed and the caller must
410 * free it.
411 *
412 * Returns the wire-format length, or -1 if we ran out of room.
413 */
414ssize_t
415l9p_pudirent(struct l9p_message *msg, struct l9p_dirent *de)
416{
417	ssize_t r, s;
418
419	r = l9p_puqid(msg, &de->qid);
420	r += l9p_pu64(msg, &de->offset);
421	r += l9p_pu8(msg, &de->type);
422	s = l9p_pustring(msg, &de->name);
423	if (r < QID_SIZE + 8 + 1 || s < 0)
424		return (-1);
425	return (r + s);
426}
427
428/*
429 * Pack or unpack a request or response (fcall).
430 *
431 * Returns 0 on success, -1 on error.  (It's up to the caller
432 * to call l9p_freefcall on our failure.)
433 */
434int
435l9p_pufcall(struct l9p_message *msg, union l9p_fcall *fcall,
436    enum l9p_version version)
437{
438	uint32_t length = 0;
439	ssize_t r;
440
441	/*
442	 * Get overall length, type, and tag, which should appear
443	 * in all messages.  If not even that works, abort immediately.
444	 */
445	l9p_pu32(msg, &length);
446	l9p_pu8(msg, &fcall->hdr.type);
447	r = l9p_pu16(msg, &fcall->hdr.tag);
448	if (r < 0)
449		return (-1);
450
451	/*
452	 * Decode remainder of message.	 When unpacking, this may
453	 * allocate memory, even if we fail during the decode.
454	 * Note that the initial fcall is zeroed out, though, so
455	 * we can just freefcall() to release whatever might have
456	 * gotten allocated, if the unpack fails due to a short
457	 * packet.
458	 */
459	switch (fcall->hdr.type) {
460	case L9P_TVERSION:
461	case L9P_RVERSION:
462		l9p_pu32(msg, &fcall->version.msize);
463		r = l9p_pustring(msg, &fcall->version.version);
464		break;
465
466	case L9P_TAUTH:
467		l9p_pu32(msg, &fcall->tauth.afid);
468		r = l9p_pustring(msg, &fcall->tauth.uname);
469		if (r < 0)
470			break;
471		r = l9p_pustring(msg, &fcall->tauth.aname);
472		if (r < 0)
473			break;
474		if (version >= L9P_2000U)
475			r = l9p_pu32(msg, &fcall->tauth.n_uname);
476		break;
477
478	case L9P_RAUTH:
479		r = l9p_puqid(msg, &fcall->rauth.aqid);
480		break;
481
482	case L9P_TATTACH:
483		l9p_pu32(msg, &fcall->hdr.fid);
484		l9p_pu32(msg, &fcall->tattach.afid);
485		r = l9p_pustring(msg, &fcall->tattach.uname);
486		if (r < 0)
487			break;
488		r = l9p_pustring(msg, &fcall->tattach.aname);
489		if (r < 0)
490			break;
491		if (version >= L9P_2000U)
492			r = l9p_pu32(msg, &fcall->tattach.n_uname);
493		break;
494
495	case L9P_RATTACH:
496		r = l9p_puqid(msg, &fcall->rattach.qid);
497		break;
498
499	case L9P_RERROR:
500		r = l9p_pustring(msg, &fcall->error.ename);
501		if (r < 0)
502			break;
503		if (version >= L9P_2000U)
504			r = l9p_pu32(msg, &fcall->error.errnum);
505		break;
506
507	case L9P_RLERROR:
508		r = l9p_pu32(msg, &fcall->error.errnum);
509		break;
510
511	case L9P_TFLUSH:
512		r = l9p_pu16(msg, &fcall->tflush.oldtag);
513		break;
514
515	case L9P_RFLUSH:
516		break;
517
518	case L9P_TWALK:
519		l9p_pu32(msg, &fcall->hdr.fid);
520		l9p_pu32(msg, &fcall->twalk.newfid);
521		r = l9p_pustrings(msg, &fcall->twalk.nwname,
522		    fcall->twalk.wname, N(fcall->twalk.wname));
523		break;
524
525	case L9P_RWALK:
526		r = l9p_puqids(msg, &fcall->rwalk.nwqid, fcall->rwalk.wqid);
527		break;
528
529	case L9P_TOPEN:
530		l9p_pu32(msg, &fcall->hdr.fid);
531		r = l9p_pu8(msg, &fcall->topen.mode);
532		break;
533
534	case L9P_ROPEN:
535		l9p_puqid(msg, &fcall->ropen.qid);
536		r = l9p_pu32(msg, &fcall->ropen.iounit);
537		break;
538
539	case L9P_TCREATE:
540		l9p_pu32(msg, &fcall->hdr.fid);
541		r = l9p_pustring(msg, &fcall->tcreate.name);
542		if (r < 0)
543			break;
544		l9p_pu32(msg, &fcall->tcreate.perm);
545		r = l9p_pu8(msg, &fcall->tcreate.mode);
546		if (version >= L9P_2000U)
547			r = l9p_pustring(msg, &fcall->tcreate.extension);
548		break;
549
550	case L9P_RCREATE:
551		l9p_puqid(msg, &fcall->rcreate.qid);
552		r = l9p_pu32(msg, &fcall->rcreate.iounit);
553		break;
554
555	case L9P_TREAD:
556	case L9P_TREADDIR:
557		l9p_pu32(msg, &fcall->hdr.fid);
558		l9p_pu64(msg, &fcall->io.offset);
559		r = l9p_pu32(msg, &fcall->io.count);
560		break;
561
562	case L9P_RREAD:
563	case L9P_RREADDIR:
564		r = l9p_pu32(msg, &fcall->io.count);
565		break;
566
567	case L9P_TWRITE:
568		l9p_pu32(msg, &fcall->hdr.fid);
569		l9p_pu64(msg, &fcall->io.offset);
570		r = l9p_pu32(msg, &fcall->io.count);
571		break;
572
573	case L9P_RWRITE:
574		r = l9p_pu32(msg, &fcall->io.count);
575		break;
576
577	case L9P_TCLUNK:
578	case L9P_TSTAT:
579	case L9P_TREMOVE:
580	case L9P_TSTATFS:
581		r = l9p_pu32(msg, &fcall->hdr.fid);
582		break;
583
584	case L9P_RCLUNK:
585	case L9P_RREMOVE:
586		break;
587
588	case L9P_RSTAT:
589	{
590		uint16_t size = l9p_sizeof_stat(&fcall->rstat.stat,
591		    version);
592		l9p_pu16(msg, &size);
593		r = l9p_pustat(msg, &fcall->rstat.stat, version);
594	}
595		break;
596
597	case L9P_TWSTAT:
598	{
599		uint16_t size;
600		l9p_pu32(msg, &fcall->hdr.fid);
601		l9p_pu16(msg, &size);
602		r = l9p_pustat(msg, &fcall->twstat.stat, version);
603	}
604		break;
605
606	case L9P_RWSTAT:
607		break;
608
609	case L9P_RSTATFS:
610		l9p_pu32(msg, &fcall->rstatfs.statfs.type);
611		l9p_pu32(msg, &fcall->rstatfs.statfs.bsize);
612		l9p_pu64(msg, &fcall->rstatfs.statfs.blocks);
613		l9p_pu64(msg, &fcall->rstatfs.statfs.bfree);
614		l9p_pu64(msg, &fcall->rstatfs.statfs.bavail);
615		l9p_pu64(msg, &fcall->rstatfs.statfs.files);
616		l9p_pu64(msg, &fcall->rstatfs.statfs.ffree);
617		l9p_pu64(msg, &fcall->rstatfs.statfs.fsid);
618		r = l9p_pu32(msg, &fcall->rstatfs.statfs.namelen);
619		break;
620
621	case L9P_TLOPEN:
622		l9p_pu32(msg, &fcall->hdr.fid);
623		r = l9p_pu32(msg, &fcall->tlopen.flags);
624		break;
625
626	case L9P_RLOPEN:
627		l9p_puqid(msg, &fcall->rlopen.qid);
628		r = l9p_pu32(msg, &fcall->rlopen.iounit);
629		break;
630
631	case L9P_TLCREATE:
632		l9p_pu32(msg, &fcall->hdr.fid);
633		r = l9p_pustring(msg, &fcall->tlcreate.name);
634		if (r < 0)
635			break;
636		l9p_pu32(msg, &fcall->tlcreate.flags);
637		l9p_pu32(msg, &fcall->tlcreate.mode);
638		r = l9p_pu32(msg, &fcall->tlcreate.gid);
639		break;
640
641	case L9P_RLCREATE:
642		l9p_puqid(msg, &fcall->rlcreate.qid);
643		r = l9p_pu32(msg, &fcall->rlcreate.iounit);
644		break;
645
646	case L9P_TSYMLINK:
647		l9p_pu32(msg, &fcall->hdr.fid);
648		r = l9p_pustring(msg, &fcall->tsymlink.name);
649		if (r < 0)
650			break;
651		r = l9p_pustring(msg, &fcall->tsymlink.symtgt);
652		if (r < 0)
653			break;
654		r = l9p_pu32(msg, &fcall->tlcreate.gid);
655		break;
656
657	case L9P_RSYMLINK:
658		r = l9p_puqid(msg, &fcall->rsymlink.qid);
659		break;
660
661	case L9P_TMKNOD:
662		l9p_pu32(msg, &fcall->hdr.fid);
663		r = l9p_pustring(msg, &fcall->tmknod.name);
664		if (r < 0)
665			break;
666		l9p_pu32(msg, &fcall->tmknod.mode);
667		l9p_pu32(msg, &fcall->tmknod.major);
668		l9p_pu32(msg, &fcall->tmknod.minor);
669		r = l9p_pu32(msg, &fcall->tmknod.gid);
670		break;
671
672	case L9P_RMKNOD:
673		r = l9p_puqid(msg, &fcall->rmknod.qid);
674		break;
675
676	case L9P_TRENAME:
677		l9p_pu32(msg, &fcall->hdr.fid);
678		l9p_pu32(msg, &fcall->trename.dfid);
679		r = l9p_pustring(msg, &fcall->trename.name);
680		break;
681
682	case L9P_RRENAME:
683		break;
684
685	case L9P_TREADLINK:
686		r = l9p_pu32(msg, &fcall->hdr.fid);
687		break;
688
689	case L9P_RREADLINK:
690		r = l9p_pustring(msg, &fcall->rreadlink.target);
691		break;
692
693	case L9P_TGETATTR:
694		l9p_pu32(msg, &fcall->hdr.fid);
695		r = l9p_pu64(msg, &fcall->tgetattr.request_mask);
696		break;
697
698	case L9P_RGETATTR:
699		l9p_pu64(msg, &fcall->rgetattr.valid);
700		l9p_puqid(msg, &fcall->rgetattr.qid);
701		l9p_pu32(msg, &fcall->rgetattr.mode);
702		l9p_pu32(msg, &fcall->rgetattr.uid);
703		l9p_pu32(msg, &fcall->rgetattr.gid);
704		l9p_pu64(msg, &fcall->rgetattr.nlink);
705		l9p_pu64(msg, &fcall->rgetattr.rdev);
706		l9p_pu64(msg, &fcall->rgetattr.size);
707		l9p_pu64(msg, &fcall->rgetattr.blksize);
708		l9p_pu64(msg, &fcall->rgetattr.blocks);
709		l9p_pu64(msg, &fcall->rgetattr.atime_sec);
710		l9p_pu64(msg, &fcall->rgetattr.atime_nsec);
711		l9p_pu64(msg, &fcall->rgetattr.mtime_sec);
712		l9p_pu64(msg, &fcall->rgetattr.mtime_nsec);
713		l9p_pu64(msg, &fcall->rgetattr.ctime_sec);
714		l9p_pu64(msg, &fcall->rgetattr.ctime_nsec);
715		l9p_pu64(msg, &fcall->rgetattr.btime_sec);
716		l9p_pu64(msg, &fcall->rgetattr.btime_nsec);
717		l9p_pu64(msg, &fcall->rgetattr.gen);
718		r = l9p_pu64(msg, &fcall->rgetattr.data_version);
719		break;
720
721	case L9P_TSETATTR:
722		l9p_pu32(msg, &fcall->hdr.fid);
723		l9p_pu32(msg, &fcall->tsetattr.valid);
724		l9p_pu32(msg, &fcall->tsetattr.mode);
725		l9p_pu32(msg, &fcall->tsetattr.uid);
726		l9p_pu32(msg, &fcall->tsetattr.gid);
727		l9p_pu64(msg, &fcall->tsetattr.size);
728		l9p_pu64(msg, &fcall->tsetattr.atime_sec);
729		l9p_pu64(msg, &fcall->tsetattr.atime_nsec);
730		l9p_pu64(msg, &fcall->tsetattr.mtime_sec);
731		r = l9p_pu64(msg, &fcall->tsetattr.mtime_nsec);
732		break;
733
734	case L9P_RSETATTR:
735		break;
736
737	case L9P_TXATTRWALK:
738		l9p_pu32(msg, &fcall->hdr.fid);
739		l9p_pu32(msg, &fcall->txattrwalk.newfid);
740		r = l9p_pustring(msg, &fcall->txattrwalk.name);
741		break;
742
743	case L9P_RXATTRWALK:
744		r = l9p_pu64(msg, &fcall->rxattrwalk.size);
745		break;
746
747	case L9P_TXATTRCREATE:
748		l9p_pu32(msg, &fcall->hdr.fid);
749		r = l9p_pustring(msg, &fcall->txattrcreate.name);
750		if (r < 0)
751			break;
752		l9p_pu64(msg, &fcall->txattrcreate.attr_size);
753		r = l9p_pu32(msg, &fcall->txattrcreate.flags);
754		break;
755
756	case L9P_RXATTRCREATE:
757		break;
758
759	case L9P_TFSYNC:
760		r = l9p_pu32(msg, &fcall->hdr.fid);
761		break;
762
763	case L9P_RFSYNC:
764		break;
765
766	case L9P_TLOCK:
767		l9p_pu32(msg, &fcall->hdr.fid);
768		l9p_pu8(msg, &fcall->tlock.type);
769		l9p_pu32(msg, &fcall->tlock.flags);
770		l9p_pu64(msg, &fcall->tlock.start);
771		l9p_pu64(msg, &fcall->tlock.length);
772		l9p_pu32(msg, &fcall->tlock.proc_id);
773		r = l9p_pustring(msg, &fcall->tlock.client_id);
774		break;
775
776	case L9P_RLOCK:
777		r = l9p_pu8(msg, &fcall->rlock.status);
778		break;
779
780	case L9P_TGETLOCK:
781		l9p_pu32(msg, &fcall->hdr.fid);
782		/* FALLTHROUGH */
783
784	case L9P_RGETLOCK:
785		l9p_pu8(msg, &fcall->getlock.type);
786		l9p_pu64(msg, &fcall->getlock.start);
787		l9p_pu64(msg, &fcall->getlock.length);
788		l9p_pu32(msg, &fcall->getlock.proc_id);
789		r = l9p_pustring(msg, &fcall->getlock.client_id);
790		break;
791
792	case L9P_TLINK:
793		l9p_pu32(msg, &fcall->tlink.dfid);
794		l9p_pu32(msg, &fcall->hdr.fid);
795		r = l9p_pustring(msg, &fcall->tlink.name);
796		break;
797
798	case L9P_RLINK:
799		break;
800
801	case L9P_TMKDIR:
802		l9p_pu32(msg, &fcall->hdr.fid);
803		r = l9p_pustring(msg, &fcall->tmkdir.name);
804		if (r < 0)
805			break;
806		l9p_pu32(msg, &fcall->tmkdir.mode);
807		r = l9p_pu32(msg, &fcall->tmkdir.gid);
808		break;
809
810	case L9P_RMKDIR:
811		r = l9p_puqid(msg, &fcall->rmkdir.qid);
812		break;
813
814	case L9P_TRENAMEAT:
815		l9p_pu32(msg, &fcall->hdr.fid);
816		r = l9p_pustring(msg, &fcall->trenameat.oldname);
817		if (r < 0)
818			break;
819		l9p_pu32(msg, &fcall->trenameat.newdirfid);
820		r = l9p_pustring(msg, &fcall->trenameat.newname);
821		break;
822
823	case L9P_RRENAMEAT:
824		break;
825
826	case L9P_TUNLINKAT:
827		l9p_pu32(msg, &fcall->hdr.fid);
828		r = l9p_pustring(msg, &fcall->tunlinkat.name);
829		if (r < 0)
830			break;
831		r = l9p_pu32(msg, &fcall->tunlinkat.flags);
832		break;
833
834	case L9P_RUNLINKAT:
835		break;
836
837	default:
838		L9P_LOG(L9P_ERROR, "%s(): missing case for type %d",
839		    __func__, fcall->hdr.type);
840		break;
841	}
842
843	/* Check for over- or under-run, or pustring error. */
844	if (r < 0)
845		return (-1);
846
847	if (msg->lm_mode == L9P_PACK) {
848		/* Rewind to the beginning and install size at front. */
849		uint32_t len = (uint32_t)msg->lm_size;
850		msg->lm_cursor_offset = 0;
851		msg->lm_cursor_iov = 0;
852
853		/*
854		 * Subtract 4 bytes from current size, becase we're
855		 * overwriting size (rewinding message to the beginning)
856		 * and writing again, which will increase it 4 more.
857		 */
858		msg->lm_size -= sizeof(uint32_t);
859
860		if (fcall->hdr.type == L9P_RREAD ||
861		    fcall->hdr.type == L9P_RREADDIR)
862			len += fcall->io.count;
863
864		l9p_pu32(msg, &len);
865	}
866
867	return (0);
868}
869
870/*
871 * Free any strings or other data malloc'ed in the process of
872 * packing or unpacking an fcall.
873 */
874void
875l9p_freefcall(union l9p_fcall *fcall)
876{
877	uint16_t i;
878
879	switch (fcall->hdr.type) {
880
881	case L9P_TVERSION:
882	case L9P_RVERSION:
883		free(fcall->version.version);
884		return;
885
886	case L9P_TATTACH:
887		free(fcall->tattach.aname);
888		free(fcall->tattach.uname);
889		return;
890
891	case L9P_TWALK:
892		for (i = 0; i < fcall->twalk.nwname; i++)
893			free(fcall->twalk.wname[i]);
894		return;
895
896	case L9P_TCREATE:
897	case L9P_TOPEN:
898		free(fcall->tcreate.name);
899		free(fcall->tcreate.extension);
900		return;
901
902	case L9P_RSTAT:
903		l9p_freestat(&fcall->rstat.stat);
904		return;
905
906	case L9P_TWSTAT:
907		l9p_freestat(&fcall->twstat.stat);
908		return;
909
910	case L9P_TLCREATE:
911		free(fcall->tlcreate.name);
912		return;
913
914	case L9P_TSYMLINK:
915		free(fcall->tsymlink.name);
916		free(fcall->tsymlink.symtgt);
917		return;
918
919	case L9P_TMKNOD:
920		free(fcall->tmknod.name);
921		return;
922
923	case L9P_TRENAME:
924		free(fcall->trename.name);
925		return;
926
927	case L9P_RREADLINK:
928		free(fcall->rreadlink.target);
929		return;
930
931	case L9P_TXATTRWALK:
932		free(fcall->txattrwalk.name);
933		return;
934
935	case L9P_TXATTRCREATE:
936		free(fcall->txattrcreate.name);
937		return;
938
939	case L9P_TLOCK:
940		free(fcall->tlock.client_id);
941		return;
942
943	case L9P_TGETLOCK:
944	case L9P_RGETLOCK:
945		free(fcall->getlock.client_id);
946		return;
947
948	case L9P_TLINK:
949		free(fcall->tlink.name);
950		return;
951
952	case L9P_TMKDIR:
953		free(fcall->tmkdir.name);
954		return;
955
956	case L9P_TRENAMEAT:
957		free(fcall->trenameat.oldname);
958		free(fcall->trenameat.newname);
959		return;
960
961	case L9P_TUNLINKAT:
962		free(fcall->tunlinkat.name);
963		return;
964	}
965}
966
967void
968l9p_freestat(struct l9p_stat *stat)
969{
970	free(stat->name);
971	free(stat->extension);
972	free(stat->uid);
973	free(stat->gid);
974	free(stat->muid);
975}
976
977uint16_t
978l9p_sizeof_stat(struct l9p_stat *stat, enum l9p_version version)
979{
980	uint16_t size = L9P_WORD /* size */
981	    + L9P_WORD /* type */
982	    + L9P_DWORD /* dev */
983	    + QID_SIZE /* qid */
984	    + 3 * L9P_DWORD /* mode, atime, mtime */
985	    + L9P_QWORD /* length */
986	    + STRING_SIZE(stat->name)
987	    + STRING_SIZE(stat->uid)
988	    + STRING_SIZE(stat->gid)
989	    + STRING_SIZE(stat->muid);
990
991	if (version >= L9P_2000U) {
992		size += STRING_SIZE(stat->extension)
993		    + 3 * L9P_DWORD;
994	}
995
996	return (size);
997}
998