bsm_io.c revision 159248
1/*
2 * Copyright (c) 2004 Apple Computer, Inc.
3 * Copyright (c) 2005 SPARTA, Inc.
4 * Copyright (c) 2006 Robert N. M. Watson
5 * All rights reserved.
6 *
7 * This code was developed in part by Robert N. M. Watson, Senior Principal
8 * Scientist, SPARTA, Inc.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1.  Redistributions of source code must retain the above copyright
14 *     notice, this list of conditions and the following disclaimer.
15 * 2.  Redistributions in binary form must reproduce the above copyright
16 *     notice, this list of conditions and the following disclaimer in the
17 *     documentation and/or other materials provided with the distribution.
18 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
19 *     its contributors may be used to endorse or promote products derived
20 *     from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR
26 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
30 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
31 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 *
34 * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_io.c#37 $
35 */
36
37#include <sys/types.h>
38
39#include <config/config.h>
40#ifdef HAVE_SYS_ENDIAN_H
41#include <sys/endian.h>
42#else /* !HAVE_SYS_ENDIAN_H */
43#ifdef HAVE_MACHINE_ENDIAN_H
44#include <machine/endian.h>
45#else /* !HAVE_MACHINE_ENDIAN_H */
46#ifdef HAVE_ENDIAN_H
47#include <endian.h>
48#else /* !HAVE_ENDIAN_H */
49#error "No supported endian.h"
50#endif /* !HAVE_ENDIAN_H */
51#endif /* !HAVE_MACHINE_ENDIAN_H */
52#include <compat/endian.h>
53#endif /* !HAVE_SYS_ENDIAN_H */
54#ifdef HAVE_FULL_QUEUE_H
55#include <sys/queue.h>
56#else /* !HAVE_FULL_QUEUE_H */
57#include <compat/queue.h>
58#endif /* !HAVE_FULL_QUEUE_H */
59
60#include <sys/stat.h>
61#include <sys/socket.h>
62
63#include <bsm/libbsm.h>
64
65#include <unistd.h>
66#include <netinet/in.h>
67#include <arpa/inet.h>
68#include <errno.h>
69#include <time.h>
70#include <stdlib.h>
71#include <stdio.h>
72#include <string.h>
73#include <pwd.h>
74#include <grp.h>
75
76#include <bsm/audit_internal.h>
77
78#define	READ_TOKEN_BYTES(buf, len, dest, size, bytesread, err) do {	\
79	if (bytesread + size > len) {					\
80		err = 1;						\
81	} else {							\
82		memcpy(dest, buf + bytesread, size);			\
83		bytesread += size;					\
84	}								\
85} while (0)
86
87#define	READ_TOKEN_U_CHAR(buf, len, dest, bytesread, err) do {		\
88	if (bytesread + sizeof(u_char) <= len) {			\
89		dest = buf[bytesread];					\
90		bytesread += sizeof(u_char);				\
91	} else								\
92		err = 1;						\
93} while (0)
94
95#define	READ_TOKEN_U_INT16(buf, len, dest, bytesread, err) do {		\
96	if (bytesread + sizeof(u_int16_t) <= len) {			\
97		dest = be16dec(buf + bytesread);			\
98		bytesread += sizeof(u_int16_t);				\
99	} else								\
100		err = 1;						\
101} while (0)
102
103#define	READ_TOKEN_U_INT32(buf, len, dest, bytesread, err) do {		\
104	if (bytesread + sizeof(u_int32_t) <= len) {			\
105		dest = be32dec(buf + bytesread);			\
106		bytesread += sizeof(u_int32_t);				\
107	} else								\
108		err = 1; 						\
109} while (0)
110
111#define	READ_TOKEN_U_INT64(buf, len, dest, bytesread, err) do {		\
112	if (bytesread + sizeof(u_int64_t) <= len) {			\
113		dest = be64dec(buf + bytesread);			\
114		bytesread += sizeof(u_int64_t);				\
115	} else								\
116		err = 1; 						\
117} while (0)
118
119#define	SET_PTR(buf, len, ptr, size, bytesread, err) do {		\
120	if ((bytesread) + (size) > (len))				\
121		(err) = 1;						\
122	else {								\
123		(ptr) = (buf) + (bytesread);				\
124		(bytesread) += (size);					\
125	}								\
126} while (0)
127
128/*
129 * Prints the delimiter string.
130 */
131static void
132print_delim(FILE *fp, const char *del)
133{
134
135	fprintf(fp, "%s", del);
136}
137
138/*
139 * Prints a single byte in the given format.
140 */
141static void
142print_1_byte(FILE *fp, u_char val, const char *format)
143{
144
145	fprintf(fp, format, val);
146}
147
148/*
149 * Print 2 bytes in the given format.
150 */
151static void
152print_2_bytes(FILE *fp, u_int16_t val, const char *format)
153{
154
155	fprintf(fp, format, val);
156}
157
158/*
159 * Prints 4 bytes in the given format.
160 */
161static void
162print_4_bytes(FILE *fp, u_int32_t val, const char *format)
163{
164
165	fprintf(fp, format, val);
166}
167
168/*
169 * Prints 8 bytes in the given format.
170 */
171static void
172print_8_bytes(FILE *fp, u_int64_t val, const char *format)
173{
174
175	fprintf(fp, format, val);
176}
177
178/*
179 * Prints the given size of data bytes in hex.
180 */
181static void
182print_mem(FILE *fp, u_char *data, size_t len)
183{
184	int i;
185
186	if (len > 0) {
187		fprintf(fp, "0x");
188		for (i = 0; i < len; i++)
189			fprintf(fp, "%x", data[i]);
190	}
191}
192
193/*
194 * Prints the given data bytes as a string.
195 */
196static void
197print_string(FILE *fp, u_char *str, size_t len)
198{
199	int i;
200
201	if (len > 0) {
202		for (i = 0; i < len; i++) {
203			if (str[i] != '\0')
204				fprintf(fp, "%c", str[i]);
205		}
206	}
207}
208
209/*
210 * Prints the token type in either the raw or the default form.
211 */
212static void
213print_tok_type(FILE *fp, u_char type, const char *tokname, char raw)
214{
215
216	if (raw)
217		fprintf(fp, "%u", type);
218	else
219		fprintf(fp, "%s", tokname);
220}
221
222/*
223 * Prints a user value.
224 */
225static void
226print_user(FILE *fp, u_int32_t usr, char raw)
227{
228	struct passwd *pwent;
229
230	if (raw)
231		fprintf(fp, "%d", usr);
232	else {
233		pwent = getpwuid(usr);
234		if (pwent != NULL)
235			fprintf(fp, "%s", pwent->pw_name);
236		else
237			fprintf(fp, "%d", usr);
238	}
239}
240
241/*
242 * Prints a group value.
243 */
244static void
245print_group(FILE *fp, u_int32_t grp, char raw)
246{
247	struct group *grpent;
248
249	if (raw)
250		fprintf(fp, "%d", grp);
251	else {
252		grpent = getgrgid(grp);
253		if (grpent != NULL)
254			fprintf(fp, "%s", grpent->gr_name);
255		else
256			fprintf(fp, "%d", grp);
257	}
258}
259
260/*
261 * Prints the event from the header token in either the short, default or raw
262 * form.
263 */
264static void
265print_event(FILE *fp, u_int16_t ev, char raw, char sfrm)
266{
267	char event_ent_name[AU_EVENT_NAME_MAX];
268	char event_ent_desc[AU_EVENT_DESC_MAX];
269	struct au_event_ent e, *ep;
270
271	bzero(&e, sizeof(e));
272	bzero(event_ent_name, sizeof(event_ent_name));
273	bzero(event_ent_desc, sizeof(event_ent_desc));
274	e.ae_name = event_ent_name;
275	e.ae_desc = event_ent_desc;
276
277	ep = getauevnum_r(&e, ev);
278	if (ep == NULL) {
279		fprintf(fp, "%u", ev);
280		return;
281	}
282
283	if (raw)
284		fprintf(fp, "%u", ev);
285	else if (sfrm)
286		fprintf(fp, "%s", e.ae_name);
287	else
288		fprintf(fp, "%s", e.ae_desc);
289}
290
291
292/*
293 * Prints the event modifier from the header token in either the default or
294 * raw form.
295 */
296static void
297print_evmod(FILE *fp, u_int16_t evmod, char raw)
298{
299	if (raw)
300		fprintf(fp, "%u", evmod);
301	else
302		fprintf(fp, "%u", evmod);
303}
304
305/*
306 * Prints seconds in the ctime format.
307 */
308static void
309print_sec32(FILE *fp, u_int32_t sec, char raw)
310{
311	time_t timestamp;
312	char timestr[26];
313
314	if (raw)
315		fprintf(fp, "%u", sec);
316	else {
317		timestamp = (time_t)sec;
318		ctime_r(&timestamp, timestr);
319		timestr[24] = '\0'; /* No new line */
320		fprintf(fp, "%s", timestr);
321	}
322}
323
324/*
325 * XXXRW: 64-bit token streams make use of 64-bit time stamps; since we
326 * assume a 32-bit time_t, we simply truncate for now.
327 */
328static void
329print_sec64(FILE *fp, u_int64_t sec, char raw)
330{
331	time_t timestamp;
332	char timestr[26];
333
334	if (raw)
335		fprintf(fp, "%u", (u_int32_t)sec);
336	else {
337		timestamp = (time_t)sec;
338		ctime_r(&timestamp, timestr);
339		timestr[24] = '\0'; /* No new line */
340		fprintf(fp, "%s", timestr);
341	}
342}
343
344/*
345 * Prints the excess milliseconds.
346 */
347static void
348print_msec32(FILE *fp, u_int32_t msec, char raw)
349{
350	if (raw)
351		fprintf(fp, "%u", msec);
352	else
353		fprintf(fp, " + %u msec", msec);
354}
355
356/*
357 * XXXRW: 64-bit token streams make use of 64-bit time stamps; since we assume
358 * a 32-bit msec, we simply truncate for now.
359 */
360static void
361print_msec64(FILE *fp, u_int64_t msec, char raw)
362{
363
364	msec &= 0xffffffff;
365	if (raw)
366		fprintf(fp, "%u", (u_int32_t)msec);
367	else
368		fprintf(fp, " + %u msec", (u_int32_t)msec);
369}
370
371/*
372 * Prints a dotted form for the IP address.
373 */
374static void
375print_ip_address(FILE *fp, u_int32_t ip)
376{
377	struct in_addr ipaddr;
378
379	ipaddr.s_addr = ip;
380	fprintf(fp, "%s", inet_ntoa(ipaddr));
381}
382
383/*
384 * Prints a string value for the given ip address.
385 */
386static void
387print_ip_ex_address(FILE *fp, u_int32_t type, u_int32_t *ipaddr)
388{
389	struct in_addr ipv4;
390	struct in6_addr ipv6;
391	char dst[INET6_ADDRSTRLEN];
392
393	switch (type) {
394	case AU_IPv4:
395		ipv4.s_addr = (in_addr_t)(ipaddr[0]);
396		fprintf(fp, "%s", inet_ntop(AF_INET, &ipv4, dst,
397		    INET6_ADDRSTRLEN));
398		break;
399
400	case AU_IPv6:
401		bcopy(ipaddr, &ipv6, sizeof(ipv6));
402		fprintf(fp, "%s", inet_ntop(AF_INET6, &ipv6, dst,
403		    INET6_ADDRSTRLEN));
404		break;
405
406	default:
407		fprintf(fp, "invalid");
408	}
409}
410
411/*
412 * Prints return value as success or failure.
413 */
414static void
415print_retval(FILE *fp, u_char status, char raw)
416{
417	if (raw)
418		fprintf(fp, "%u", status);
419	else {
420		if (status == 0)
421			fprintf(fp, "success");
422		else
423			fprintf(fp, "failure : %s", strerror(status));
424	}
425}
426
427/*
428 * Prints the exit value.
429 */
430static void
431print_errval(FILE *fp, u_int32_t val)
432{
433
434	fprintf(fp, "Error %u", val);
435}
436
437/*
438 * Prints IPC type.
439 */
440static void
441print_ipctype(FILE *fp, u_char type, char raw)
442{
443	if (raw)
444		fprintf(fp, "%u", type);
445	else {
446		if (type == AT_IPC_MSG)
447			fprintf(fp, "Message IPC");
448		else if (type == AT_IPC_SEM)
449			fprintf(fp, "Semaphore IPC");
450		else if (type == AT_IPC_SHM)
451			fprintf(fp, "Shared Memory IPC");
452		else
453			fprintf(fp, "%u", type);
454	}
455}
456
457/*
458 * record byte count       4 bytes
459 * version #               1 byte    [2]
460 * event type              2 bytes
461 * event modifier          2 bytes
462 * seconds of time         4 bytes/8 bytes (32-bit/64-bit value)
463 * milliseconds of time    4 bytes/8 bytes (32-bit/64-bit value)
464 */
465static int
466fetch_header32_tok(tokenstr_t *tok, char *buf, int len)
467{
468	int err = 0;
469
470	READ_TOKEN_U_INT32(buf, len, tok->tt.hdr32.size, tok->len, err);
471	if (err)
472		return (-1);
473
474	READ_TOKEN_U_CHAR(buf, len, tok->tt.hdr32.version, tok->len, err);
475	if (err)
476		return (-1);
477
478	READ_TOKEN_U_INT16(buf, len, tok->tt.hdr32.e_type, tok->len, err);
479	if (err)
480		return (-1);
481
482	READ_TOKEN_U_INT16(buf, len, tok->tt.hdr32.e_mod, tok->len, err);
483	if (err)
484		return (-1);
485
486	READ_TOKEN_U_INT32(buf, len, tok->tt.hdr32.s, tok->len, err);
487	if (err)
488		return (-1);
489
490	READ_TOKEN_U_INT32(buf, len, tok->tt.hdr32.ms, tok->len, err);
491	if (err)
492		return (-1);
493
494	return (0);
495}
496
497static void
498print_header32_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, char sfrm)
499{
500
501	print_tok_type(fp, tok->id, "header", raw);
502	print_delim(fp, del);
503	print_4_bytes(fp, tok->tt.hdr32.size, "%u");
504	print_delim(fp, del);
505	print_1_byte(fp, tok->tt.hdr32.version, "%u");
506	print_delim(fp, del);
507	print_event(fp, tok->tt.hdr32.e_type, raw, sfrm);
508	print_delim(fp, del);
509	print_evmod(fp, tok->tt.hdr32.e_mod, raw);
510	print_delim(fp, del);
511	print_sec32(fp, tok->tt.hdr32.s, raw);
512	print_delim(fp, del);
513	print_msec32(fp, tok->tt.hdr32.ms, raw);
514}
515
516/*
517 * The Solaris specifications for AUE_HEADER32_EX seem to differ a bit
518 * depending on the bit of the specifications found.  The OpenSolaris source
519 * code uses a 4-byte address length, followed by some number of bytes of
520 * address data.  This contrasts with the Solaris audit.log.5 man page, which
521 * specifies a 1-byte length field.  We use the Solaris 10 definition so that
522 * we can parse audit trails from that system.
523 *
524 * record byte count       4 bytes
525 * version #               1 byte     [2]
526 * event type              2 bytes
527 * event modifier          2 bytes
528 * address type/length     4 bytes
529 *   [ Solaris man page: address type/length     1 byte]
530 * machine address         4 bytes/16 bytes (IPv4/IPv6 address)
531 * seconds of time         4 bytes/8 bytes  (32/64-bits)
532 * nanoseconds of time     4 bytes/8 bytes  (32/64-bits)
533 */
534static int
535fetch_header32_ex_tok(tokenstr_t *tok, char *buf, int len)
536{
537	int err = 0;
538
539	READ_TOKEN_U_INT32(buf, len, tok->tt.hdr32_ex.size, tok->len, err);
540	if (err)
541		return (-1);
542
543	READ_TOKEN_U_CHAR(buf, len, tok->tt.hdr32_ex.version, tok->len, err);
544	if (err)
545		return (-1);
546
547	READ_TOKEN_U_INT16(buf, len, tok->tt.hdr32_ex.e_type, tok->len, err);
548	if (err)
549		return (-1);
550
551	READ_TOKEN_U_INT16(buf, len, tok->tt.hdr32_ex.e_mod, tok->len, err);
552	if (err)
553		return (-1);
554
555	READ_TOKEN_U_INT32(buf, len, tok->tt.hdr32_ex.ad_type, tok->len, err);
556	if (err)
557		return (-1);
558
559	bzero(tok->tt.hdr32_ex.addr, sizeof(tok->tt.hdr32_ex.addr));
560	switch (tok->tt.hdr32_ex.ad_type) {
561	case AU_IPv4:
562		READ_TOKEN_BYTES(buf, len, &tok->tt.hdr32_ex.addr[0],
563		    sizeof(tok->tt.hdr32_ex.addr[0]), tok->len, err);
564		if (err)
565			return (-1);
566		break;
567
568	case AU_IPv6:
569		READ_TOKEN_BYTES(buf, len, tok->tt.hdr32_ex.addr,
570		    sizeof(tok->tt.hdr32_ex.addr), tok->len, err);
571		break;
572	}
573
574	READ_TOKEN_U_INT32(buf, len, tok->tt.hdr32_ex.s, tok->len, err);
575	if (err)
576		return (-1);
577
578	READ_TOKEN_U_INT32(buf, len, tok->tt.hdr32_ex.ms, tok->len, err);
579	if (err)
580		return (-1);
581
582	return (0);
583}
584
585static void
586print_header32_ex_tok(FILE *fp, tokenstr_t *tok, char *del, char raw,
587    char sfrm)
588{
589
590	print_tok_type(fp, tok->id, "header_ex", raw);
591	print_delim(fp, del);
592	print_4_bytes(fp, tok->tt.hdr32_ex.size, "%u");
593	print_delim(fp, del);
594	print_1_byte(fp, tok->tt.hdr32_ex.version, "%u");
595	print_delim(fp, del);
596	print_event(fp, tok->tt.hdr32_ex.e_type, raw, sfrm);
597	print_delim(fp, del);
598	print_evmod(fp, tok->tt.hdr32_ex.e_mod, raw);
599	print_delim(fp, del);
600	print_ip_ex_address(fp, tok->tt.hdr32_ex.ad_type,
601	    tok->tt.hdr32_ex.addr);
602	print_delim(fp, del);
603	print_sec32(fp, tok->tt.hdr32_ex.s, raw);
604	print_delim(fp, del);
605	print_msec32(fp, tok->tt.hdr32_ex.ms, raw);
606}
607
608/*
609 * record byte count       4 bytes
610 * event type              2 bytes
611 * event modifier          2 bytes
612 * seconds of time         4 bytes/8 bytes (32-bit/64-bit value)
613 * milliseconds of time    4 bytes/8 bytes (32-bit/64-bit value)
614 * version #
615 */
616static int
617fetch_header64_tok(tokenstr_t *tok, char *buf, int len)
618{
619	int err = 0;
620
621	READ_TOKEN_U_INT32(buf, len, tok->tt.hdr64.size, tok->len, err);
622	if (err)
623		return (-1);
624
625	READ_TOKEN_U_CHAR(buf, len, tok->tt.hdr64.version, tok->len, err);
626	if (err)
627		return (-1);
628
629	READ_TOKEN_U_INT16(buf, len, tok->tt.hdr64.e_type, tok->len, err);
630	if (err)
631		return (-1);
632
633	READ_TOKEN_U_INT16(buf, len, tok->tt.hdr64.e_mod, tok->len, err);
634	if (err)
635		return (-1);
636
637	READ_TOKEN_U_INT64(buf, len, tok->tt.hdr64.s, tok->len, err);
638	if (err)
639		return (-1);
640
641	READ_TOKEN_U_INT64(buf, len, tok->tt.hdr64.ms, tok->len, err);
642	if (err)
643		return (-1);
644
645	return (0);
646}
647
648static void
649print_header64_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, char sfrm)
650{
651
652	print_tok_type(fp, tok->id, "header", raw);
653	print_delim(fp, del);
654	print_4_bytes(fp, tok->tt.hdr64.size, "%u");
655	print_delim(fp, del);
656	print_1_byte(fp, tok->tt.hdr64.version, "%u");
657	print_delim(fp, del);
658	print_event(fp, tok->tt.hdr64.e_type, raw, sfrm);
659	print_delim(fp, del);
660	print_evmod(fp, tok->tt.hdr64.e_mod, raw);
661	print_delim(fp, del);
662	print_sec64(fp, tok->tt.hdr64.s, raw);
663	print_delim(fp, del);
664	print_msec64(fp, tok->tt.hdr64.ms, raw);
665}
666/*
667 * record byte count       4 bytes
668 * version #               1 byte     [2]
669 * event type              2 bytes
670 * event modifier          2 bytes
671 * address type/length     4 bytes
672 *   [ Solaris man page: address type/length     1 byte]
673 * machine address         4 bytes/16 bytes (IPv4/IPv6 address)
674 * seconds of time         4 bytes/8 bytes  (32/64-bits)
675 * nanoseconds of time     4 bytes/8 bytes  (32/64-bits)
676 *
677 * XXXAUDIT: See comment by fetch_header32_ex_tok() for details on the
678 * accuracy of the BSM spec.
679 */
680static int
681fetch_header64_ex_tok(tokenstr_t *tok, char *buf, int len)
682{
683	int err = 0;
684
685	READ_TOKEN_U_INT32(buf, len, tok->tt.hdr64_ex.size, tok->len, err);
686	if (err)
687		return (-1);
688
689	READ_TOKEN_U_CHAR(buf, len, tok->tt.hdr64_ex.version, tok->len, err);
690	if (err)
691		return (-1);
692
693	READ_TOKEN_U_INT16(buf, len, tok->tt.hdr64_ex.e_type, tok->len, err);
694	if (err)
695		return (-1);
696
697	READ_TOKEN_U_INT16(buf, len, tok->tt.hdr64_ex.e_mod, tok->len, err);
698	if (err)
699		return (-1);
700
701	READ_TOKEN_U_INT32(buf, len, tok->tt.hdr64_ex.ad_type, tok->len, err);
702	if (err)
703		return (-1);
704
705	bzero(tok->tt.hdr64_ex.addr, sizeof(tok->tt.hdr64_ex.addr));
706	switch (tok->tt.hdr64_ex.ad_type) {
707	case AU_IPv4:
708		READ_TOKEN_BYTES(buf, len, &tok->tt.hdr64_ex.addr[0],
709		    sizeof(tok->tt.hdr64_ex.addr[0]), tok->len, err);
710		if (err)
711			return (-1);
712		break;
713
714	case AU_IPv6:
715		READ_TOKEN_BYTES(buf, len, tok->tt.hdr64_ex.addr,
716		    sizeof(tok->tt.hdr64_ex.addr), tok->len, err);
717		break;
718	}
719
720	READ_TOKEN_U_INT64(buf, len, tok->tt.hdr64_ex.s, tok->len, err);
721	if (err)
722		return (-1);
723
724	READ_TOKEN_U_INT64(buf, len, tok->tt.hdr64_ex.ms, tok->len, err);
725	if (err)
726		return (-1);
727
728	return (0);
729}
730
731static void
732print_header64_ex_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, char sfrm)
733{
734
735	print_tok_type(fp, tok->id, "header_ex", raw);
736	print_delim(fp, del);
737	print_4_bytes(fp, tok->tt.hdr64_ex.size, "%u");
738	print_delim(fp, del);
739	print_1_byte(fp, tok->tt.hdr64_ex.version, "%u");
740	print_delim(fp, del);
741	print_event(fp, tok->tt.hdr64_ex.e_type, raw, sfrm);
742	print_delim(fp, del);
743	print_evmod(fp, tok->tt.hdr64_ex.e_mod, raw);
744	print_delim(fp, del);
745	print_ip_ex_address(fp, tok->tt.hdr64_ex.ad_type,
746	    tok->tt.hdr64_ex.addr);
747	print_delim(fp, del);
748	print_sec64(fp, tok->tt.hdr64_ex.s, raw);
749	print_delim(fp, del);
750	print_msec64(fp, tok->tt.hdr64_ex.ms, raw);
751}
752
753/*
754 * trailer magic                        2 bytes
755 * record size                          4 bytes
756 */
757static int
758fetch_trailer_tok(tokenstr_t *tok, char *buf, int len)
759{
760	int err = 0;
761
762	READ_TOKEN_U_INT16(buf, len, tok->tt.trail.magic, tok->len, err);
763	if (err)
764		return (-1);
765
766	READ_TOKEN_U_INT32(buf, len, tok->tt.trail.count, tok->len, err);
767	if (err)
768		return (-1);
769
770	return (0);
771}
772
773static void
774print_trailer_tok(FILE *fp, tokenstr_t *tok, char *del, char raw,
775    __unused char sfrm)
776{
777
778	print_tok_type(fp, tok->id, "trailer", raw);
779	print_delim(fp, del);
780	print_4_bytes(fp, tok->tt.trail.count, "%u");
781}
782
783/*
784 * argument #              1 byte
785 * argument value          4 bytes/8 bytes (32-bit/64-bit value)
786 * text length             2 bytes
787 * text                    N bytes + 1 terminating NULL byte
788 */
789static int
790fetch_arg32_tok(tokenstr_t *tok, char *buf, int len)
791{
792	int err = 0;
793
794	READ_TOKEN_U_CHAR(buf, len, tok->tt.arg32.no, tok->len, err);
795	if (err)
796		return (-1);
797
798	READ_TOKEN_U_INT32(buf, len, tok->tt.arg32.val, tok->len, err);
799	if (err)
800		return (-1);
801
802	READ_TOKEN_U_INT16(buf, len, tok->tt.arg32.len, tok->len, err);
803	if (err)
804		return (-1);
805
806	SET_PTR(buf, len, tok->tt.arg32.text, tok->tt.arg32.len, tok->len,
807	    err);
808	if (err)
809		return (-1);
810
811	return (0);
812}
813
814static void
815print_arg32_tok(FILE *fp, tokenstr_t *tok, char *del, char raw,
816    __unused char sfrm)
817{
818
819	print_tok_type(fp, tok->id, "argument", raw);
820	print_delim(fp, del);
821	print_1_byte(fp, tok->tt.arg32.no, "%u");
822	print_delim(fp, del);
823	print_4_bytes(fp, tok->tt.arg32.val, "%#x");
824	print_delim(fp, del);
825	print_string(fp, tok->tt.arg32.text, tok->tt.arg32.len);
826}
827
828static int
829fetch_arg64_tok(tokenstr_t *tok, char *buf, int len)
830{
831	int err = 0;
832
833	READ_TOKEN_U_CHAR(buf, len, tok->tt.arg64.no, tok->len, err);
834	if (err)
835		return (-1);
836
837	READ_TOKEN_U_INT64(buf, len, tok->tt.arg64.val, tok->len, err);
838	if (err)
839		return (-1);
840
841	READ_TOKEN_U_INT16(buf, len, tok->tt.arg64.len, tok->len, err);
842	if (err)
843		return (-1);
844
845	SET_PTR(buf, len, tok->tt.arg64.text, tok->tt.arg64.len, tok->len,
846	    err);
847	if (err)
848		return (-1);
849
850	return (0);
851}
852
853static void
854print_arg64_tok(FILE *fp, tokenstr_t *tok, char *del, char raw,
855    __unused char sfrm)
856{
857
858	print_tok_type(fp, tok->id, "argument", raw);
859	print_delim(fp, del);
860	print_1_byte(fp, tok->tt.arg64.no, "%u");
861	print_delim(fp, del);
862	print_8_bytes(fp, tok->tt.arg64.val, "%#llx");
863	print_delim(fp, del);
864	print_string(fp, tok->tt.arg64.text, tok->tt.arg64.len);
865}
866
867/*
868 * how to print            1 byte
869 * basic unit              1 byte
870 * unit count              1 byte
871 * data items              (depends on basic unit)
872 */
873static int
874fetch_arb_tok(tokenstr_t *tok, char *buf, int len)
875{
876	int err = 0;
877	int datasize;
878
879	READ_TOKEN_U_CHAR(buf, len, tok->tt.arb.howtopr, tok->len, err);
880	if (err)
881		return (-1);
882
883	READ_TOKEN_U_CHAR(buf, len, tok->tt.arb.bu, tok->len, err);
884	if (err)
885		return (-1);
886
887	READ_TOKEN_U_CHAR(buf, len, tok->tt.arb.uc, tok->len, err);
888	if (err)
889		return (-1);
890
891	/*
892	 * Determine the size of the basic unit.
893	 */
894	switch(tok->tt.arb.bu) {
895	case AUR_BYTE:
896	/* case AUR_CHAR: */
897		datasize = AUR_BYTE_SIZE;
898		break;
899
900	case AUR_SHORT:
901		datasize = AUR_SHORT_SIZE;
902		break;
903
904	case AUR_INT32:
905	/* case AUR_INT: */
906		datasize = AUR_INT32_SIZE;
907		break;
908
909	case AUR_INT64:
910		datasize = AUR_INT64_SIZE;
911		break;
912
913	default:
914		return (-1);
915	}
916
917	SET_PTR(buf, len, tok->tt.arb.data, datasize * tok->tt.arb.uc,
918	    tok->len, err);
919	if (err)
920		return (-1);
921
922	return (0);
923}
924
925static void
926print_arb_tok(FILE *fp, tokenstr_t *tok, char *del, char raw,
927    __unused char sfrm)
928{
929	char *str;
930	char *format;
931	size_t size;
932	int i;
933
934	print_tok_type(fp, tok->id, "arbitrary", raw);
935	print_delim(fp, del);
936
937	switch(tok->tt.arb.howtopr) {
938	case AUP_BINARY:
939		str = "binary";
940		format = " %c";
941		break;
942
943	case AUP_OCTAL:
944		str = "octal";
945		format = " %o";
946		break;
947
948	case AUP_DECIMAL:
949		str = "decimal";
950		format = " %d";
951		break;
952
953	case AUP_HEX:
954		str = "hex";
955		format = " %x";
956		break;
957
958	case AUP_STRING:
959		str = "string";
960		format = "%c";
961		break;
962
963	default:
964		return;
965	}
966
967	print_string(fp, str, strlen(str));
968	print_delim(fp, del);
969	switch(tok->tt.arb.bu) {
970	case AUR_BYTE:
971	/* case AUR_CHAR: */
972		str = "byte";
973		size = AUR_BYTE_SIZE;
974		print_string(fp, str, strlen(str));
975		print_delim(fp, del);
976		print_1_byte(fp, tok->tt.arb.uc, "%u");
977		print_delim(fp, del);
978		for (i = 0; i<tok->tt.arb.uc; i++)
979			fprintf(fp, format, *(tok->tt.arb.data + (size * i)));
980		break;
981
982	case AUR_SHORT:
983		str = "short";
984		size = AUR_SHORT_SIZE;
985		print_string(fp, str, strlen(str));
986		print_delim(fp, del);
987		print_1_byte(fp, tok->tt.arb.uc, "%u");
988		print_delim(fp, del);
989		for (i = 0; i < tok->tt.arb.uc; i++)
990			fprintf(fp, format, *((u_int16_t *)(tok->tt.arb.data +
991			    (size * i))));
992		break;
993
994	case AUR_INT32:
995	/* case AUR_INT: */
996		str = "int";
997		size = AUR_INT32_SIZE;
998		print_string(fp, str, strlen(str));
999		print_delim(fp, del);
1000		print_1_byte(fp, tok->tt.arb.uc, "%u");
1001		print_delim(fp, del);
1002		for (i = 0; i < tok->tt.arb.uc; i++)
1003			fprintf(fp, format, *((u_int32_t *)(tok->tt.arb.data +
1004			    (size * i))));
1005		break;
1006
1007	case AUR_INT64:
1008		str = "int64";
1009		size = AUR_INT64_SIZE;
1010		print_string(fp, str, strlen(str));
1011		print_delim(fp, del);
1012		print_1_byte(fp, tok->tt.arb.uc, "%u");
1013		print_delim(fp, del);
1014		for (i = 0; i < tok->tt.arb.uc; i++)
1015			fprintf(fp, format, *((u_int64_t *)(tok->tt.arb.data +
1016			    (size * i))));
1017		break;
1018
1019	default:
1020		return;
1021	}
1022}
1023
1024/*
1025 * file access mode        4 bytes
1026 * owner user ID           4 bytes
1027 * owner group ID          4 bytes
1028 * file system ID          4 bytes
1029 * node ID                 8 bytes
1030 * device                  4 bytes/8 bytes (32-bit/64-bit)
1031 */
1032static int
1033fetch_attr32_tok(tokenstr_t *tok, char *buf, int len)
1034{
1035	int err = 0;
1036
1037	READ_TOKEN_U_INT32(buf, len, tok->tt.attr32.mode, tok->len, err);
1038	if (err)
1039		return (-1);
1040
1041	READ_TOKEN_U_INT32(buf, len, tok->tt.attr32.uid, tok->len, err);
1042	if (err)
1043		return (-1);
1044
1045	READ_TOKEN_U_INT32(buf, len, tok->tt.attr32.gid, tok->len, err);
1046	if (err)
1047		return (-1);
1048
1049	READ_TOKEN_U_INT32(buf, len, tok->tt.attr32.fsid, tok->len, err);
1050	if (err)
1051		return (-1);
1052
1053	READ_TOKEN_U_INT64(buf, len, tok->tt.attr32.nid, tok->len, err);
1054	if (err)
1055		return (-1);
1056
1057	READ_TOKEN_U_INT32(buf, len, tok->tt.attr32.dev, tok->len, err);
1058	if (err)
1059		return (-1);
1060
1061	return (0);
1062}
1063
1064static void
1065print_attr32_tok(FILE *fp, tokenstr_t *tok, char *del, char raw,
1066    __unused char sfrm)
1067{
1068
1069	print_tok_type(fp, tok->id, "attribute", raw);
1070	print_delim(fp, del);
1071	print_4_bytes(fp, tok->tt.attr32.mode, "%o");
1072	print_delim(fp, del);
1073	print_user(fp, tok->tt.attr32.uid, raw);
1074	print_delim(fp, del);
1075	print_group(fp, tok->tt.attr32.gid, raw);
1076	print_delim(fp, del);
1077	print_4_bytes(fp, tok->tt.attr32.fsid, "%u");
1078	print_delim(fp, del);
1079	print_8_bytes(fp, tok->tt.attr32.nid, "%lld");
1080	print_delim(fp, del);
1081	print_4_bytes(fp, tok->tt.attr32.dev, "%u");
1082}
1083
1084/*
1085 * file access mode        4 bytes
1086 * owner user ID           4 bytes
1087 * owner group ID          4 bytes
1088 * file system ID          4 bytes
1089 * node ID                 8 bytes
1090 * device                  4 bytes/8 bytes (32-bit/64-bit)
1091 */
1092static int
1093fetch_attr64_tok(tokenstr_t *tok, char *buf, int len)
1094{
1095	int err = 0;
1096
1097	READ_TOKEN_U_INT32(buf, len, tok->tt.attr64.mode, tok->len, err);
1098	if (err)
1099		return (-1);
1100
1101	READ_TOKEN_U_INT32(buf, len, tok->tt.attr64.uid, tok->len, err);
1102	if (err)
1103		return (-1);
1104
1105	READ_TOKEN_U_INT32(buf, len, tok->tt.attr64.gid, tok->len, err);
1106	if (err)
1107		return (-1);
1108
1109	READ_TOKEN_U_INT32(buf, len, tok->tt.attr64.fsid, tok->len, err);
1110	if (err)
1111		return (-1);
1112
1113	READ_TOKEN_U_INT64(buf, len, tok->tt.attr64.nid, tok->len, err);
1114	if (err)
1115		return (-1);
1116
1117	READ_TOKEN_U_INT64(buf, len, tok->tt.attr64.dev, tok->len, err);
1118	if (err)
1119		return (-1);
1120
1121	return (0);
1122}
1123
1124static void
1125print_attr64_tok(FILE *fp, tokenstr_t *tok, char *del, char raw,
1126    __unused char sfrm)
1127{
1128
1129	print_tok_type(fp, tok->id, "attribute", raw);
1130	print_delim(fp, del);
1131	print_4_bytes(fp, tok->tt.attr64.mode, "%o");
1132	print_delim(fp, del);
1133	print_user(fp, tok->tt.attr64.uid, raw);
1134	print_delim(fp, del);
1135	print_group(fp, tok->tt.attr64.gid, raw);
1136	print_delim(fp, del);
1137	print_4_bytes(fp, tok->tt.attr64.fsid, "%u");
1138	print_delim(fp, del);
1139	print_8_bytes(fp, tok->tt.attr64.nid, "%lld");
1140	print_delim(fp, del);
1141	print_8_bytes(fp, tok->tt.attr64.dev, "%llu");
1142}
1143
1144/*
1145 * status                  4 bytes
1146 * return value            4 bytes
1147 */
1148static int
1149fetch_exit_tok(tokenstr_t *tok, char *buf, int len)
1150{
1151	int err = 0;
1152
1153	READ_TOKEN_U_INT32(buf, len, tok->tt.exit.status, tok->len, err);
1154	if (err)
1155		return (-1);
1156
1157	READ_TOKEN_U_INT32(buf, len, tok->tt.exit.ret, tok->len, err);
1158	if (err)
1159		return (-1);
1160
1161	return (0);
1162}
1163
1164static void
1165print_exit_tok(FILE *fp, tokenstr_t *tok, char *del, char raw,
1166    __unused char sfrm)
1167{
1168
1169	print_tok_type(fp, tok->id, "exit", raw);
1170	print_delim(fp, del);
1171	print_errval(fp, tok->tt.exit.status);
1172	print_delim(fp, del);
1173	print_4_bytes(fp, tok->tt.exit.ret, "%u");
1174}
1175
1176/*
1177 * count                   4 bytes
1178 * text                    count null-terminated string(s)
1179 */
1180static int
1181fetch_execarg_tok(tokenstr_t *tok, char *buf, int len)
1182{
1183	int err = 0;
1184	int i;
1185	char *bptr;
1186
1187	READ_TOKEN_U_INT32(buf, len, tok->tt.execarg.count, tok->len, err);
1188	if (err)
1189		return (-1);
1190
1191	for (i = 0; i < tok->tt.execarg.count; i++) {
1192		bptr = buf + tok->len;
1193		tok->tt.execarg.text[i] = bptr;
1194
1195		/* Look for a null terminated string. */
1196		while (bptr && (*bptr != '\0')) {
1197			if (++tok->len >=len)
1198				return (-1);
1199			bptr = buf + tok->len;
1200		}
1201		if (!bptr)
1202			return (-1);
1203		tok->len++; /* \0 character */
1204	}
1205
1206	return (0);
1207}
1208
1209static void
1210print_execarg_tok(FILE *fp, tokenstr_t *tok, char *del, char raw,
1211    __unused char sfrm)
1212{
1213	int i;
1214
1215	print_tok_type(fp, tok->id, "exec arg", raw);
1216	for (i = 0; i < tok->tt.execarg.count; i++) {
1217		print_delim(fp, del);
1218		print_string(fp, tok->tt.execarg.text[i],
1219		    strlen(tok->tt.execarg.text[i]));
1220	}
1221}
1222
1223/*
1224 * count                   4 bytes
1225 * text                    count null-terminated string(s)
1226 */
1227static int
1228fetch_execenv_tok(tokenstr_t *tok, char *buf, int len)
1229{
1230	int err = 0;
1231	int i;
1232	char *bptr;
1233
1234	READ_TOKEN_U_INT32(buf, len, tok->tt.execenv.count, tok->len, err);
1235	if (err)
1236		return (-1);
1237
1238	for (i = 0; i< tok->tt.execenv.count; i++) {
1239		bptr = buf + tok->len;
1240		tok->tt.execenv.text[i] = bptr;
1241
1242		/* Look for a null terminated string. */
1243		while (bptr && (*bptr != '\0')) {
1244			if (++tok->len >=len)
1245				return (-1);
1246			bptr = buf + tok->len;
1247		}
1248		if (!bptr)
1249			return (-1);
1250		tok->len++; /* \0 character */
1251	}
1252
1253	return (0);
1254}
1255
1256static void
1257print_execenv_tok(FILE *fp, tokenstr_t *tok, char *del, char raw,
1258    __unused char sfrm)
1259{
1260	int i;
1261
1262	print_tok_type(fp, tok->id, "exec arg", raw);
1263	for (i = 0; i< tok->tt.execenv.count; i++) {
1264		print_delim(fp, del);
1265		print_string(fp, tok->tt.execenv.text[i],
1266		    strlen(tok->tt.execenv.text[i]));
1267	}
1268}
1269
1270/*
1271 * seconds of time          4 bytes
1272 * milliseconds of time     4 bytes
1273 * file name len            2 bytes
1274 * file pathname            N bytes + 1 terminating NULL byte
1275 */
1276static int
1277fetch_file_tok(tokenstr_t *tok, char *buf, int len)
1278{
1279	int err = 0;
1280
1281	READ_TOKEN_U_INT32(buf, len, tok->tt.file.s, tok->len, err);
1282	if (err)
1283		return (-1);
1284
1285	READ_TOKEN_U_INT32(buf, len, tok->tt.file.ms, tok->len, err);
1286	if (err)
1287		return (-1);
1288
1289	READ_TOKEN_U_INT16(buf, len, tok->tt.file.len, tok->len, err);
1290	if (err)
1291		return (-1);
1292
1293	SET_PTR(buf, len, tok->tt.file.name, tok->tt.file.len, tok->len, err);
1294	if (err)
1295		return (-1);
1296
1297	return (0);
1298}
1299
1300static void
1301print_file_tok(FILE *fp, tokenstr_t *tok, char *del, char raw,
1302    __unused char sfrm)
1303{
1304
1305	print_tok_type(fp, tok->id, "file", raw);
1306	print_delim(fp, del);
1307	print_sec32(fp, tok->tt.file.s, raw);
1308	print_delim(fp, del);
1309	print_msec32(fp, tok->tt.file.ms, raw);
1310	print_delim(fp, del);
1311	print_string(fp, tok->tt.file.name, tok->tt.file.len);
1312}
1313
1314/*
1315 * number groups           2 bytes
1316 * group list              count * 4 bytes
1317 */
1318static int
1319fetch_newgroups_tok(tokenstr_t *tok, char *buf, int len)
1320{
1321	int i;
1322	int err = 0;
1323
1324	READ_TOKEN_U_INT16(buf, len, tok->tt.grps.no, tok->len, err);
1325	if (err)
1326		return (-1);
1327
1328	for (i = 0; i<tok->tt.grps.no; i++) {
1329		READ_TOKEN_U_INT32(buf, len, tok->tt.grps.list[i], tok->len,
1330		    err);
1331    		if (err)
1332    			return (-1);
1333	}
1334
1335	return (0);
1336}
1337
1338static void
1339print_newgroups_tok(FILE *fp, tokenstr_t *tok, char *del, char raw,
1340    __unused char sfrm)
1341{
1342	int i;
1343
1344	print_tok_type(fp, tok->id, "group", raw);
1345	for (i = 0; i < tok->tt.grps.no; i++) {
1346		print_delim(fp, del);
1347		print_group(fp, tok->tt.grps.list[i], raw);
1348	}
1349}
1350
1351/*
1352 * Internet addr 4 bytes
1353 */
1354static int
1355fetch_inaddr_tok(tokenstr_t *tok, char *buf, int len)
1356{
1357	int err = 0;
1358
1359	READ_TOKEN_BYTES(buf, len, &tok->tt.inaddr.addr, sizeof(uint32_t),
1360	    tok->len, err);
1361	if (err)
1362		return (-1);
1363
1364	return (0);
1365
1366}
1367
1368static void
1369print_inaddr_tok(FILE *fp, tokenstr_t *tok, char *del, char raw,
1370    __unused char sfrm)
1371{
1372
1373	print_tok_type(fp, tok->id, "ip addr", raw);
1374	print_delim(fp, del);
1375	print_ip_address(fp, tok->tt.inaddr.addr);
1376}
1377
1378/*
1379 * type 	4 bytes
1380 * address 16 bytes
1381 */
1382static int
1383fetch_inaddr_ex_tok(tokenstr_t *tok, char *buf, int len)
1384{
1385	int err = 0;
1386
1387	READ_TOKEN_U_INT32(buf, len, tok->tt.inaddr_ex.type, tok->len, err);
1388	if (err)
1389		return (-1);
1390
1391	if (tok->tt.inaddr_ex.type == AU_IPv4) {
1392		READ_TOKEN_BYTES(buf, len, &tok->tt.inaddr_ex.addr[0],
1393		    sizeof(tok->tt.inaddr_ex.addr[0]), tok->len, err);
1394		if (err)
1395			return (-1);
1396	} else if (tok->tt.inaddr_ex.type == AU_IPv6) {
1397		READ_TOKEN_BYTES(buf, len, tok->tt.inaddr_ex.addr,
1398		    sizeof(tok->tt.inaddr_ex.addr), tok->len, err);
1399		if (err)
1400			return (-1);
1401	} else
1402		return (-1);
1403
1404	return (0);
1405}
1406
1407static void
1408print_inaddr_ex_tok(FILE *fp, tokenstr_t *tok, char *del, char raw,
1409    __unused char sfrm)
1410{
1411
1412	print_tok_type(fp, tok->id, "ip addr ex", raw);
1413	print_delim(fp, del);
1414	print_ip_ex_address(fp, tok->tt.inaddr_ex.type,
1415	    tok->tt.inaddr_ex.addr);
1416}
1417
1418/*
1419 * ip header     20 bytes
1420 */
1421static int
1422fetch_ip_tok(tokenstr_t *tok, char *buf, int len)
1423{
1424	int err = 0;
1425
1426	READ_TOKEN_U_CHAR(buf, len, tok->tt.ip.version, tok->len, err);
1427	if (err)
1428		return (-1);
1429
1430	READ_TOKEN_U_CHAR(buf, len, tok->tt.ip.tos, tok->len, err);
1431	if (err)
1432		return (-1);
1433
1434	READ_TOKEN_BYTES(buf, len, &tok->tt.ip.len, sizeof(uint16_t),
1435	    tok->len, err);
1436	if (err)
1437		return (-1);
1438
1439	READ_TOKEN_BYTES(buf, len, &tok->tt.ip.id, sizeof(uint16_t),
1440	    tok->len, err);
1441	if (err)
1442		return (-1);
1443
1444	READ_TOKEN_BYTES(buf, len, &tok->tt.ip.offset, sizeof(uint16_t),
1445	    tok->len, err);
1446	if (err)
1447		return (-1);
1448
1449	READ_TOKEN_U_CHAR(buf, len, tok->tt.ip.ttl, tok->len, err);
1450	if (err)
1451		return (-1);
1452
1453	READ_TOKEN_U_CHAR(buf, len, tok->tt.ip.prot, tok->len, err);
1454	if (err)
1455		return (-1);
1456
1457	READ_TOKEN_BYTES(buf, len, &tok->tt.ip.chksm, sizeof(uint16_t),
1458	    tok->len, err);
1459	if (err)
1460		return (-1);
1461
1462	READ_TOKEN_BYTES(buf, len, &tok->tt.ip.src, sizeof(tok->tt.ip.src),
1463	    tok->len, err);
1464	if (err)
1465		return (-1);
1466
1467	READ_TOKEN_BYTES(buf, len, &tok->tt.ip.dest, sizeof(tok->tt.ip.dest),
1468	    tok->len, err);
1469	if (err)
1470		return (-1);
1471
1472	return (0);
1473}
1474
1475static void
1476print_ip_tok(FILE *fp, tokenstr_t *tok, char *del, char raw,
1477    __unused char sfrm)
1478{
1479
1480	print_tok_type(fp, tok->id, "ip", raw);
1481	print_delim(fp, del);
1482	print_mem(fp, (u_char *)(&tok->tt.ip.version), sizeof(u_char));
1483	print_delim(fp, del);
1484	print_mem(fp, (u_char *)(&tok->tt.ip.tos), sizeof(u_char));
1485	print_delim(fp, del);
1486	print_2_bytes(fp, ntohs(tok->tt.ip.len), "%u");
1487	print_delim(fp, del);
1488	print_2_bytes(fp, ntohs(tok->tt.ip.id), "%u");
1489	print_delim(fp, del);
1490	print_2_bytes(fp, ntohs(tok->tt.ip.offset), "%u");
1491	print_delim(fp, del);
1492	print_mem(fp, (u_char *)(&tok->tt.ip.ttl), sizeof(u_char));
1493	print_delim(fp, del);
1494	print_mem(fp, (u_char *)(&tok->tt.ip.prot), sizeof(u_char));
1495	print_delim(fp, del);
1496	print_2_bytes(fp, ntohs(tok->tt.ip.chksm), "%u");
1497	print_delim(fp, del);
1498	print_ip_address(fp, tok->tt.ip.src);
1499	print_delim(fp, del);
1500	print_ip_address(fp, tok->tt.ip.dest);
1501}
1502
1503/*
1504 * object ID type       1 byte
1505 * Object ID            4 bytes
1506 */
1507static int
1508fetch_ipc_tok(tokenstr_t *tok, char *buf, int len)
1509{
1510	int err = 0;
1511
1512	READ_TOKEN_U_CHAR(buf, len, tok->tt.ipc.type, tok->len, err);
1513	if (err)
1514		return (-1);
1515
1516	READ_TOKEN_U_INT32(buf, len, tok->tt.ipc.id, tok->len, err);
1517	if (err)
1518		return (-1);
1519
1520	return (0);
1521}
1522
1523static void
1524print_ipc_tok(FILE *fp, tokenstr_t *tok, char *del, char raw,
1525    __unused char sfrm)
1526{
1527
1528	print_tok_type(fp, tok->id, "IPC", raw);
1529	print_delim(fp, del);
1530	print_ipctype(fp, tok->tt.ipc.type, raw);
1531	print_delim(fp, del);
1532	print_4_bytes(fp, tok->tt.ipc.id, "%u");
1533}
1534
1535/*
1536 * owner user id        4 bytes
1537 * owner group id       4 bytes
1538 * creator user id      4 bytes
1539 * creator group id     4 bytes
1540 * access mode          4 bytes
1541 * slot seq                     4 bytes
1542 * key                          4 bytes
1543 */
1544static int
1545fetch_ipcperm_tok(tokenstr_t *tok, char *buf, int len)
1546{
1547	int err = 0;
1548
1549	READ_TOKEN_U_INT32(buf, len, tok->tt.ipcperm.uid, tok->len, err);
1550	if (err)
1551		return (-1);
1552
1553	READ_TOKEN_U_INT32(buf, len, tok->tt.ipcperm.gid, tok->len, err);
1554	if (err)
1555		return (-1);
1556
1557	READ_TOKEN_U_INT32(buf, len, tok->tt.ipcperm.puid, tok->len, err);
1558	if (err)
1559		return (-1);
1560
1561	READ_TOKEN_U_INT32(buf, len, tok->tt.ipcperm.pgid, tok->len, err);
1562	if (err)
1563		return (-1);
1564
1565	READ_TOKEN_U_INT32(buf, len, tok->tt.ipcperm.mode, tok->len, err);
1566	if (err)
1567		return (-1);
1568
1569	READ_TOKEN_U_INT32(buf, len, tok->tt.ipcperm.seq, tok->len, err);
1570	if (err)
1571		return (-1);
1572
1573	READ_TOKEN_U_INT32(buf, len, tok->tt.ipcperm.key, tok->len, err);
1574	if (err)
1575		return (-1);
1576
1577	return (0);
1578}
1579
1580static void
1581print_ipcperm_tok(FILE *fp, tokenstr_t *tok, char *del, char raw,
1582    __unused char sfrm)
1583{
1584
1585	print_tok_type(fp, tok->id, "IPC perm", raw);
1586	print_delim(fp, del);
1587	print_user(fp, tok->tt.ipcperm.uid, raw);
1588	print_delim(fp, del);
1589	print_group(fp, tok->tt.ipcperm.gid, raw);
1590	print_delim(fp, del);
1591	print_user(fp, tok->tt.ipcperm.puid, raw);
1592	print_delim(fp, del);
1593	print_group(fp, tok->tt.ipcperm.pgid, raw);
1594	print_delim(fp, del);
1595	print_4_bytes(fp, tok->tt.ipcperm.mode, "%o");
1596	print_delim(fp, del);
1597	print_4_bytes(fp, tok->tt.ipcperm.seq, "%u");
1598	print_delim(fp, del);
1599	print_4_bytes(fp, tok->tt.ipcperm.key, "%u");
1600}
1601
1602/*
1603 * port Ip address  2 bytes
1604 */
1605static int
1606fetch_iport_tok(tokenstr_t *tok, char *buf, int len)
1607{
1608	int err = 0;
1609
1610	READ_TOKEN_BYTES(buf, len, &tok->tt.iport.port, sizeof(uint16_t),
1611	    tok->len, err);
1612	if (err)
1613		return (-1);
1614
1615	return (0);
1616}
1617
1618static void
1619print_iport_tok(FILE *fp, tokenstr_t *tok, char *del, char raw,
1620    __unused char sfrm)
1621{
1622
1623	print_tok_type(fp, tok->id, "ip port", raw);
1624	print_delim(fp, del);
1625	print_2_bytes(fp, ntohs(tok->tt.iport.port), "%#x");
1626}
1627
1628/*
1629 * size                         2 bytes
1630 * data                         size bytes
1631 */
1632static int
1633fetch_opaque_tok(tokenstr_t *tok, char *buf, int len)
1634{
1635	int err = 0;
1636
1637	READ_TOKEN_U_INT16(buf, len, tok->tt.opaque.size, tok->len, err);
1638	if (err)
1639		return (-1);
1640
1641	SET_PTR(buf, len, tok->tt.opaque.data, tok->tt.opaque.size, tok->len,
1642	    err);
1643	if (err)
1644		return (-1);
1645
1646	return (0);
1647}
1648
1649static void
1650print_opaque_tok(FILE *fp, tokenstr_t *tok, char *del, char raw,
1651    __unused char sfrm)
1652{
1653
1654	print_tok_type(fp, tok->id, "opaque", raw);
1655	print_delim(fp, del);
1656	print_2_bytes(fp, tok->tt.opaque.size, "%u");
1657	print_delim(fp, del);
1658	print_mem(fp, tok->tt.opaque.data, tok->tt.opaque.size);
1659}
1660
1661/*
1662 * size                         2 bytes
1663 * data                         size bytes
1664 */
1665static int
1666fetch_path_tok(tokenstr_t *tok, char *buf, int len)
1667{
1668	int err = 0;
1669
1670	READ_TOKEN_U_INT16(buf, len, tok->tt.path.len, tok->len, err);
1671	if (err)
1672		return (-1);
1673
1674	SET_PTR(buf, len, tok->tt.path.path, tok->tt.path.len, tok->len, err);
1675	if (err)
1676		return (-1);
1677
1678	return (0);
1679}
1680
1681static void
1682print_path_tok(FILE *fp, tokenstr_t *tok, char *del, char raw,
1683    __unused char sfrm)
1684{
1685
1686	print_tok_type(fp, tok->id, "path", raw);
1687	print_delim(fp, del);
1688	print_string(fp, tok->tt.path.path, tok->tt.path.len);
1689}
1690
1691/*
1692 * token ID                     1 byte
1693 * audit ID                     4 bytes
1694 * euid                         4 bytes
1695 * egid                         4 bytes
1696 * ruid                         4 bytes
1697 * rgid                         4 bytes
1698 * pid                          4 bytes
1699 * sessid                       4 bytes
1700 * terminal ID
1701 *   portid             4 bytes
1702 *   machine id         4 bytes
1703 */
1704static int
1705fetch_process32_tok(tokenstr_t *tok, char *buf, int len)
1706{
1707	int err = 0;
1708
1709	READ_TOKEN_U_INT32(buf, len, tok->tt.proc32.auid, tok->len, err);
1710	if (err)
1711		return (-1);
1712
1713	READ_TOKEN_U_INT32(buf, len, tok->tt.proc32.euid, tok->len, err);
1714	if (err)
1715		return (-1);
1716
1717	READ_TOKEN_U_INT32(buf, len, tok->tt.proc32.egid, tok->len, err);
1718	if (err)
1719		return (-1);
1720
1721	READ_TOKEN_U_INT32(buf, len, tok->tt.proc32.ruid, tok->len, err);
1722	if (err)
1723		return (-1);
1724
1725	READ_TOKEN_U_INT32(buf, len, tok->tt.proc32.rgid, tok->len, err);
1726	if (err)
1727		return (-1);
1728
1729	READ_TOKEN_U_INT32(buf, len, tok->tt.proc32.pid, tok->len, err);
1730	if (err)
1731		return (-1);
1732
1733	READ_TOKEN_U_INT32(buf, len, tok->tt.proc32.sid, tok->len, err);
1734	if (err)
1735		return (-1);
1736
1737	READ_TOKEN_U_INT32(buf, len, tok->tt.proc32.tid.port, tok->len, err);
1738	if (err)
1739		return (-1);
1740
1741	READ_TOKEN_BYTES(buf, len, &tok->tt.proc32.tid.addr,
1742	    sizeof(tok->tt.proc32.tid.addr), tok->len, err);
1743	if (err)
1744		return (-1);
1745
1746	return (0);
1747}
1748
1749static void
1750print_process32_tok(FILE *fp, tokenstr_t *tok, char *del, char raw,
1751    __unused char sfrm)
1752{
1753
1754	print_tok_type(fp, tok->id, "process", raw);
1755	print_delim(fp, del);
1756	print_user(fp, tok->tt.proc32.auid, raw);
1757	print_delim(fp, del);
1758	print_user(fp, tok->tt.proc32.euid, raw);
1759	print_delim(fp, del);
1760	print_group(fp, tok->tt.proc32.egid, raw);
1761	print_delim(fp, del);
1762	print_user(fp, tok->tt.proc32.ruid, raw);
1763	print_delim(fp, del);
1764	print_group(fp, tok->tt.proc32.rgid, raw);
1765	print_delim(fp, del);
1766	print_4_bytes(fp, tok->tt.proc32.pid, "%u");
1767	print_delim(fp, del);
1768	print_4_bytes(fp, tok->tt.proc32.sid, "%u");
1769	print_delim(fp, del);
1770	print_4_bytes(fp, tok->tt.proc32.tid.port, "%u");
1771	print_delim(fp, del);
1772	print_ip_address(fp, tok->tt.proc32.tid.addr);
1773}
1774
1775static int
1776fetch_process32ex_tok(tokenstr_t *tok, char *buf, int len)
1777{
1778	int err = 0;
1779
1780	READ_TOKEN_U_INT32(buf, len, tok->tt.proc32_ex.auid, tok->len, err);
1781	if (err)
1782		return (-1);
1783
1784	READ_TOKEN_U_INT32(buf, len, tok->tt.proc32_ex.euid, tok->len, err);
1785	if (err)
1786		return (-1);
1787
1788	READ_TOKEN_U_INT32(buf, len, tok->tt.proc32_ex.egid, tok->len, err);
1789	if (err)
1790		return (-1);
1791
1792	READ_TOKEN_U_INT32(buf, len, tok->tt.proc32_ex.ruid, tok->len, err);
1793	if (err)
1794		return (-1);
1795
1796	READ_TOKEN_U_INT32(buf, len, tok->tt.proc32_ex.rgid, tok->len, err);
1797	if (err)
1798		return (-1);
1799
1800	READ_TOKEN_U_INT32(buf, len, tok->tt.proc32_ex.pid, tok->len, err);
1801	if (err)
1802		return (-1);
1803
1804	READ_TOKEN_U_INT32(buf, len, tok->tt.proc32_ex.sid, tok->len, err);
1805	if (err)
1806		return (-1);
1807
1808	READ_TOKEN_U_INT32(buf, len, tok->tt.proc32_ex.tid.port, tok->len,
1809	    err);
1810	if (err)
1811		return (-1);
1812
1813	READ_TOKEN_U_INT32(buf, len, tok->tt.proc32_ex.tid.type, tok->len,
1814	    err);
1815	if (err)
1816		return (-1);
1817
1818	if (tok->tt.proc32_ex.tid.type == AU_IPv4) {
1819		READ_TOKEN_BYTES(buf, len, &tok->tt.proc32_ex.tid.addr[0],
1820		    sizeof(tok->tt.proc32_ex.tid.addr[0]), tok->len, err);
1821		if (err)
1822			return (-1);
1823	} else if (tok->tt.proc32_ex.tid.type == AU_IPv6) {
1824		READ_TOKEN_BYTES(buf, len, tok->tt.proc32_ex.tid.addr,
1825		    sizeof(tok->tt.proc32_ex.tid.addr), tok->len, err);
1826		if (err)
1827			return (-1);
1828	} else
1829		return (-1);
1830
1831	return (0);
1832}
1833
1834static void
1835print_process32ex_tok(FILE *fp, tokenstr_t *tok, char *del, char raw,
1836    __unused char sfrm)
1837{
1838
1839	print_tok_type(fp, tok->id, "process_ex", raw);
1840	print_delim(fp, del);
1841	print_user(fp, tok->tt.proc32_ex.auid, raw);
1842	print_delim(fp, del);
1843	print_user(fp, tok->tt.proc32_ex.euid, raw);
1844	print_delim(fp, del);
1845	print_group(fp, tok->tt.proc32_ex.egid, raw);
1846	print_delim(fp, del);
1847	print_user(fp, tok->tt.proc32_ex.ruid, raw);
1848	print_delim(fp, del);
1849	print_group(fp, tok->tt.proc32_ex.rgid, raw);
1850	print_delim(fp, del);
1851	print_4_bytes(fp, tok->tt.proc32_ex.pid, "%u");
1852	print_delim(fp, del);
1853	print_4_bytes(fp, tok->tt.proc32_ex.sid, "%u");
1854	print_delim(fp, del);
1855	print_4_bytes(fp, tok->tt.proc32_ex.tid.port, "%u");
1856	print_delim(fp, del);
1857	print_ip_ex_address(fp, tok->tt.proc32_ex.tid.type,
1858	    tok->tt.proc32_ex.tid.addr);
1859}
1860
1861/*
1862 * errno                        1 byte
1863 * return value         4 bytes
1864 */
1865static int
1866fetch_return32_tok(tokenstr_t *tok, char *buf, int len)
1867{
1868	int err = 0;
1869
1870	READ_TOKEN_U_CHAR(buf, len, tok->tt.ret32.status, tok->len, err);
1871	if (err)
1872		return (-1);
1873
1874	READ_TOKEN_U_INT32(buf, len, tok->tt.ret32.ret, tok->len, err);
1875	if (err)
1876		return (-1);
1877
1878	return (0);
1879}
1880
1881static void
1882print_return32_tok(FILE *fp, tokenstr_t *tok, char *del, char raw,
1883    __unused char sfrm)
1884{
1885
1886	print_tok_type(fp, tok->id, "return", raw);
1887	print_delim(fp, del);
1888	print_retval(fp, tok->tt.ret32.status, raw);
1889	print_delim(fp, del);
1890	print_4_bytes(fp, tok->tt.ret32.ret, "%u");
1891}
1892
1893static int
1894fetch_return64_tok(tokenstr_t *tok, char *buf, int len)
1895{
1896	int err = 0;
1897
1898	READ_TOKEN_U_CHAR(buf, len, tok->tt.ret64.err, tok->len, err);
1899	if (err)
1900		return (-1);
1901
1902	READ_TOKEN_U_INT64(buf, len, tok->tt.ret64.val, tok->len, err);
1903	if (err)
1904		return (-1);
1905
1906	return (0);
1907}
1908
1909static void
1910print_return64_tok(FILE *fp, tokenstr_t *tok, char *del, char raw,
1911    __unused char sfrm)
1912{
1913
1914	print_tok_type(fp, tok->id, "return", raw);
1915	print_delim(fp, del);
1916	print_retval(fp, tok->tt.ret64.err, raw);
1917	print_delim(fp, del);
1918	print_8_bytes(fp, tok->tt.ret64.val, "%lld");
1919}
1920
1921/*
1922 * seq                          4 bytes
1923 */
1924static int
1925fetch_seq_tok(tokenstr_t *tok, char *buf, int len)
1926{
1927	int err = 0;
1928
1929	READ_TOKEN_U_INT32(buf, len, tok->tt.seq.seqno, tok->len, err);
1930	if (err)
1931		return (-1);
1932
1933	return (0);
1934}
1935
1936static void
1937print_seq_tok(FILE *fp, tokenstr_t *tok, char *del, char raw,
1938    __unused char sfrm)
1939{
1940
1941	print_tok_type(fp, tok->id, "sequence", raw);
1942	print_delim(fp, del);
1943	print_4_bytes(fp, tok->tt.seq.seqno, "%u");
1944}
1945
1946/*
1947 * socket family           2 bytes
1948 * local port              2 bytes
1949 * socket address          4 bytes
1950 */
1951static int
1952fetch_sock_inet32_tok(tokenstr_t *tok, char *buf, int len)
1953{
1954	int err = 0;
1955
1956	READ_TOKEN_U_INT16(buf, len, tok->tt.sockinet32.family, tok->len,
1957	    err);
1958	if (err)
1959		return (-1);
1960
1961	READ_TOKEN_BYTES(buf, len, &tok->tt.sockinet32.port,
1962	    sizeof(uint16_t), tok->len, err);
1963	if (err)
1964		return (-1);
1965
1966	READ_TOKEN_BYTES(buf, len, &tok->tt.sockinet32.addr,
1967	    sizeof(tok->tt.sockinet32.addr), tok->len, err);
1968	if (err)
1969		return (-1);
1970
1971	return (0);
1972}
1973
1974static void
1975print_sock_inet32_tok(FILE *fp, tokenstr_t *tok, char *del, char raw,
1976    __unused char sfrm)
1977{
1978
1979	print_tok_type(fp, tok->id, "socket-inet", raw);
1980	print_delim(fp, del);
1981	print_2_bytes(fp, tok->tt.sockinet32.family, "%u");
1982	print_delim(fp, del);
1983	print_2_bytes(fp, ntohs(tok->tt.sockinet32.port), "%u");
1984	print_delim(fp, del);
1985	print_ip_address(fp, tok->tt.sockinet32.addr);
1986}
1987
1988/*
1989 * socket family           2 bytes
1990 * path                    104 bytes
1991 */
1992static int
1993fetch_sock_unix_tok(tokenstr_t *tok, char *buf, int len)
1994{
1995	int err = 0;
1996
1997	READ_TOKEN_U_INT16(buf, len, tok->tt.sockunix.family, tok->len, err);
1998	if (err)
1999		return (-1);
2000
2001	READ_TOKEN_BYTES(buf, len, tok->tt.sockunix.path, 104, tok->len,
2002	    err);
2003	if (err)
2004		return (-1);
2005
2006	return (0);
2007}
2008
2009static void
2010print_sock_unix_tok(FILE *fp, tokenstr_t *tok, char *del, char raw,
2011    __unused char sfrm)
2012{
2013
2014	print_tok_type(fp, tok->id, "socket-unix", raw);
2015	print_delim(fp, del);
2016	print_2_bytes(fp, tok->tt.sockunix.family, "%u");
2017	print_delim(fp, del);
2018	print_string(fp, tok->tt.sockunix.path,
2019	    strlen(tok->tt.sockunix.path));
2020}
2021
2022/*
2023 * socket type             2 bytes
2024 * local port              2 bytes
2025 * local address           4 bytes
2026 * remote port             2 bytes
2027 * remote address          4 bytes
2028 */
2029static int
2030fetch_socket_tok(tokenstr_t *tok, char *buf, int len)
2031{
2032	int err = 0;
2033
2034	READ_TOKEN_U_INT16(buf, len, tok->tt.socket.type, tok->len, err);
2035	if (err)
2036		return (-1);
2037
2038	READ_TOKEN_BYTES(buf, len, &tok->tt.socket.l_port, sizeof(uint16_t),
2039	    tok->len, err);
2040	if (err)
2041		return (-1);
2042
2043	READ_TOKEN_BYTES(buf, len, &tok->tt.socket.l_addr,
2044	    sizeof(tok->tt.socket.l_addr), tok->len, err);
2045	if (err)
2046		return (-1);
2047
2048	READ_TOKEN_BYTES(buf, len, &tok->tt.socket.r_port, sizeof(uint16_t),
2049	    tok->len, err);
2050	if (err)
2051		return (-1);
2052
2053	READ_TOKEN_BYTES(buf, len, &tok->tt.socket.l_addr,
2054	    sizeof(tok->tt.socket.r_addr), tok->len, err);
2055	if (err)
2056		return (-1);
2057
2058	return (0);
2059}
2060
2061static void
2062print_socket_tok(FILE *fp, tokenstr_t *tok, char *del, char raw,
2063    __unused char sfrm)
2064{
2065
2066	print_tok_type(fp, tok->id, "socket", raw);
2067	print_delim(fp, del);
2068	print_2_bytes(fp, tok->tt.socket.type, "%u");
2069	print_delim(fp, del);
2070	print_2_bytes(fp, ntohs(tok->tt.socket.l_port), "%u");
2071	print_delim(fp, del);
2072	print_ip_address(fp, tok->tt.socket.l_addr);
2073	print_delim(fp, del);
2074	print_2_bytes(fp, ntohs(tok->tt.socket.r_port), "%u");
2075	print_delim(fp, del);
2076	print_ip_address(fp, tok->tt.socket.r_addr);
2077}
2078
2079/*
2080 * audit ID                     4 bytes
2081 * euid                         4 bytes
2082 * egid                         4 bytes
2083 * ruid                         4 bytes
2084 * rgid                         4 bytes
2085 * pid                          4 bytes
2086 * sessid                       4 bytes
2087 * terminal ID
2088 *   portid             4 bytes/8 bytes (32-bit/64-bit value)
2089 *   machine id         4 bytes
2090 */
2091static int
2092fetch_subject32_tok(tokenstr_t *tok, char *buf, int len)
2093{
2094	int err = 0;
2095
2096	READ_TOKEN_U_INT32(buf, len, tok->tt.subj32.auid, tok->len, err);
2097	if (err)
2098		return (-1);
2099
2100	READ_TOKEN_U_INT32(buf, len, tok->tt.subj32.euid, tok->len, err);
2101	if (err)
2102		return (-1);
2103
2104	READ_TOKEN_U_INT32(buf, len, tok->tt.subj32.egid, tok->len, err);
2105	if (err)
2106		return (-1);
2107
2108	READ_TOKEN_U_INT32(buf, len, tok->tt.subj32.ruid, tok->len, err);
2109	if (err)
2110		return (-1);
2111
2112	READ_TOKEN_U_INT32(buf, len, tok->tt.subj32.rgid, tok->len, err);
2113	if (err)
2114		return (-1);
2115
2116	READ_TOKEN_U_INT32(buf, len, tok->tt.subj32.pid, tok->len, err);
2117	if (err)
2118		return (-1);
2119
2120	READ_TOKEN_U_INT32(buf, len, tok->tt.subj32.sid, tok->len, err);
2121	if (err)
2122		return (-1);
2123
2124	READ_TOKEN_U_INT32(buf, len, tok->tt.subj32.tid.port, tok->len, err);
2125	if (err)
2126		return (-1);
2127
2128	READ_TOKEN_BYTES(buf, len, &tok->tt.subj32.tid.addr,
2129	    sizeof(tok->tt.subj32.tid.addr), tok->len, err);
2130	if (err)
2131		return (-1);
2132
2133	return (0);
2134}
2135
2136static void
2137print_subject32_tok(FILE *fp, tokenstr_t *tok, char *del, char raw,
2138    __unused char sfrm)
2139{
2140
2141	print_tok_type(fp, tok->id, "subject", raw);
2142	print_delim(fp, del);
2143	print_user(fp, tok->tt.subj32.auid, raw);
2144	print_delim(fp, del);
2145	print_user(fp, tok->tt.subj32.euid, raw);
2146	print_delim(fp, del);
2147	print_group(fp, tok->tt.subj32.egid, raw);
2148	print_delim(fp, del);
2149	print_user(fp, tok->tt.subj32.ruid, raw);
2150	print_delim(fp, del);
2151	print_group(fp, tok->tt.subj32.rgid, raw);
2152	print_delim(fp, del);
2153	print_4_bytes(fp, tok->tt.subj32.pid, "%u");
2154	print_delim(fp, del);
2155	print_4_bytes(fp, tok->tt.subj32.sid, "%u");
2156	print_delim(fp, del);
2157	print_4_bytes(fp, tok->tt.subj32.tid.port, "%u");
2158	print_delim(fp, del);
2159	print_ip_address(fp, tok->tt.subj32.tid.addr);
2160}
2161
2162/*
2163 * audit ID                     4 bytes
2164 * euid                         4 bytes
2165 * egid                         4 bytes
2166 * ruid                         4 bytes
2167 * rgid                         4 bytes
2168 * pid                          4 bytes
2169 * sessid                       4 bytes
2170 * terminal ID
2171 *   portid             4 bytes/8 bytes (32-bit/64-bit value)
2172 *   machine id         4 bytes
2173 */
2174static int
2175fetch_subject64_tok(tokenstr_t *tok, char *buf, int len)
2176{
2177	int err = 0;
2178
2179	READ_TOKEN_U_INT32(buf, len, tok->tt.subj64.auid, tok->len, err);
2180	if (err)
2181		return (-1);
2182
2183	READ_TOKEN_U_INT32(buf, len, tok->tt.subj64.euid, tok->len, err);
2184	if (err)
2185		return (-1);
2186
2187	READ_TOKEN_U_INT32(buf, len, tok->tt.subj64.egid, tok->len, err);
2188	if (err)
2189		return (-1);
2190
2191	READ_TOKEN_U_INT32(buf, len, tok->tt.subj64.ruid, tok->len, err);
2192	if (err)
2193		return (-1);
2194
2195	READ_TOKEN_U_INT32(buf, len, tok->tt.subj64.rgid, tok->len, err);
2196	if (err)
2197		return (-1);
2198
2199	READ_TOKEN_U_INT32(buf, len, tok->tt.subj64.pid, tok->len, err);
2200	if (err)
2201		return (-1);
2202
2203	READ_TOKEN_U_INT32(buf, len, tok->tt.subj64.sid, tok->len, err);
2204	if (err)
2205		return (-1);
2206
2207	READ_TOKEN_U_INT64(buf, len, tok->tt.subj64.tid.port, tok->len, err);
2208	if (err)
2209		return (-1);
2210
2211	READ_TOKEN_BYTES(buf, len, &tok->tt.subj64.tid.addr,
2212	    sizeof(tok->tt.subj64.tid.addr), tok->len, err);
2213	if (err)
2214		return (-1);
2215
2216	return (0);
2217}
2218
2219static void
2220print_subject64_tok(FILE *fp, tokenstr_t *tok, char *del, char raw,
2221    __unused char sfrm)
2222{
2223
2224	print_tok_type(fp, tok->id, "subject", raw);
2225	print_delim(fp, del);
2226	print_user(fp, tok->tt.subj64.auid, raw);
2227	print_delim(fp, del);
2228	print_user(fp, tok->tt.subj64.euid, raw);
2229	print_delim(fp, del);
2230	print_group(fp, tok->tt.subj64.egid, raw);
2231	print_delim(fp, del);
2232	print_user(fp, tok->tt.subj64.ruid, raw);
2233	print_delim(fp, del);
2234	print_group(fp, tok->tt.subj64.rgid, raw);
2235	print_delim(fp, del);
2236	print_4_bytes(fp, tok->tt.subj64.pid, "%u");
2237	print_delim(fp, del);
2238	print_4_bytes(fp, tok->tt.subj64.sid, "%u");
2239	print_delim(fp, del);
2240	print_8_bytes(fp, tok->tt.subj64.tid.port, "%llu");
2241	print_delim(fp, del);
2242	print_ip_address(fp, tok->tt.subj64.tid.addr);
2243}
2244
2245/*
2246 * audit ID                     4 bytes
2247 * euid                         4 bytes
2248 * egid                         4 bytes
2249 * ruid                         4 bytes
2250 * rgid                         4 bytes
2251 * pid                          4 bytes
2252 * sessid                       4 bytes
2253 * terminal ID
2254 *   portid             4 bytes
2255 *	 type				4 bytes
2256 *   machine id         16 bytes
2257 */
2258static int
2259fetch_subject32ex_tok(tokenstr_t *tok, char *buf, int len)
2260{
2261	int err = 0;
2262
2263	READ_TOKEN_U_INT32(buf, len, tok->tt.subj32_ex.auid, tok->len, err);
2264	if (err)
2265		return (-1);
2266
2267	READ_TOKEN_U_INT32(buf, len, tok->tt.subj32_ex.euid, tok->len, err);
2268	if (err)
2269		return (-1);
2270
2271	READ_TOKEN_U_INT32(buf, len, tok->tt.subj32_ex.egid, tok->len, err);
2272	if (err)
2273		return (-1);
2274
2275	READ_TOKEN_U_INT32(buf, len, tok->tt.subj32_ex.ruid, tok->len, err);
2276	if (err)
2277		return (-1);
2278
2279	READ_TOKEN_U_INT32(buf, len, tok->tt.subj32_ex.rgid, tok->len, err);
2280	if (err)
2281		return (-1);
2282
2283	READ_TOKEN_U_INT32(buf, len, tok->tt.subj32_ex.pid, tok->len, err);
2284	if (err)
2285		return (-1);
2286
2287	READ_TOKEN_U_INT32(buf, len, tok->tt.subj32_ex.sid, tok->len, err);
2288	if (err)
2289		return (-1);
2290
2291	READ_TOKEN_U_INT32(buf, len, tok->tt.subj32_ex.tid.port, tok->len,
2292	    err);
2293	if (err)
2294		return (-1);
2295
2296	READ_TOKEN_U_INT32(buf, len, tok->tt.subj32_ex.tid.type, tok->len,
2297	    err);
2298	if (err)
2299		return (-1);
2300
2301	if (tok->tt.subj32_ex.tid.type == AU_IPv4) {
2302		READ_TOKEN_BYTES(buf, len, &tok->tt.subj32_ex.tid.addr[0],
2303		    sizeof(tok->tt.subj32_ex.tid.addr[0]), tok->len, err);
2304		if (err)
2305			return (-1);
2306	} else if (tok->tt.subj32_ex.tid.type == AU_IPv6) {
2307		READ_TOKEN_BYTES(buf, len, tok->tt.subj32_ex.tid.addr,
2308		    sizeof(tok->tt.subj32_ex.tid.addr), tok->len, err);
2309		if (err)
2310			return (-1);
2311	} else
2312		return (-1);
2313
2314	return (0);
2315}
2316
2317static void
2318print_subject32ex_tok(FILE *fp, tokenstr_t *tok, char *del, char raw,
2319    __unused char sfrm)
2320{
2321
2322	print_tok_type(fp, tok->id, "subject_ex", raw);
2323	print_delim(fp, del);
2324	print_user(fp, tok->tt.subj32_ex.auid, raw);
2325	print_delim(fp, del);
2326	print_user(fp, tok->tt.subj32_ex.euid, raw);
2327	print_delim(fp, del);
2328	print_group(fp, tok->tt.subj32_ex.egid, raw);
2329	print_delim(fp, del);
2330	print_user(fp, tok->tt.subj32_ex.ruid, raw);
2331	print_delim(fp, del);
2332	print_group(fp, tok->tt.subj32_ex.rgid, raw);
2333	print_delim(fp, del);
2334	print_4_bytes(fp, tok->tt.subj32_ex.pid, "%u");
2335	print_delim(fp, del);
2336	print_4_bytes(fp, tok->tt.subj32_ex.sid, "%u");
2337	print_delim(fp, del);
2338	print_4_bytes(fp, tok->tt.subj32_ex.tid.port, "%u");
2339	print_delim(fp, del);
2340	print_ip_ex_address(fp, tok->tt.subj32_ex.tid.type,
2341	    tok->tt.subj32_ex.tid.addr);
2342}
2343
2344/*
2345 * size                         2 bytes
2346 * data                         size bytes
2347 */
2348static int
2349fetch_text_tok(tokenstr_t *tok, char *buf, int len)
2350{
2351	int err = 0;
2352
2353	READ_TOKEN_U_INT16(buf, len, tok->tt.text.len, tok->len, err);
2354	if (err)
2355		return (-1);
2356
2357	SET_PTR(buf, len, tok->tt.text.text, tok->tt.text.len, tok->len,
2358	    err);
2359	if (err)
2360		return (-1);
2361
2362	return (0);
2363}
2364
2365static void
2366print_text_tok(FILE *fp, tokenstr_t *tok, char *del, char raw,
2367    __unused char sfrm)
2368{
2369
2370	print_tok_type(fp, tok->id, "text", raw);
2371	print_delim(fp, del);
2372	print_string(fp, tok->tt.text.text, tok->tt.text.len);
2373}
2374
2375/*
2376 * socket type             2 bytes
2377 * local port              2 bytes
2378 * address type/length     4 bytes
2379 * local Internet address  4 bytes
2380 * remote port             4 bytes
2381 * address type/length     4 bytes
2382 * remote Internet address 4 bytes
2383 */
2384static int
2385fetch_socketex32_tok(tokenstr_t *tok, char *buf, int len)
2386{
2387	int err = 0;
2388
2389	READ_TOKEN_U_INT16(buf, len, tok->tt.socket_ex32.type, tok->len,
2390	    err);
2391	if (err)
2392		return (-1);
2393
2394	READ_TOKEN_BYTES(buf, len, &tok->tt.socket_ex32.l_port,
2395	    sizeof(uint16_t), tok->len, err);
2396	if (err)
2397		return (-1);
2398
2399	READ_TOKEN_U_INT32(buf, len, tok->tt.socket_ex32.l_ad_type, tok->len,
2400	    err);
2401	if (err)
2402		return (-1);
2403
2404	READ_TOKEN_BYTES(buf, len, &tok->tt.socket_ex32.l_addr,
2405	    sizeof(tok->tt.socket_ex32.l_addr), tok->len, err);
2406	if (err)
2407		return (-1);
2408
2409	READ_TOKEN_BYTES(buf, len, &tok->tt.socket_ex32.r_port,
2410	    sizeof(uint16_t), tok->len, err);
2411	if (err)
2412		return (-1);
2413
2414	READ_TOKEN_U_INT32(buf, len, tok->tt.socket_ex32.r_ad_type, tok->len,
2415	    err);
2416	if (err)
2417		return (-1);
2418
2419	READ_TOKEN_BYTES(buf, len, &tok->tt.socket_ex32.r_addr,
2420	    sizeof(tok->tt.socket_ex32.r_addr), tok->len, err);
2421	if (err)
2422		return (-1);
2423
2424	return (0);
2425}
2426
2427static void
2428print_socketex32_tok(FILE *fp, tokenstr_t *tok, char *del, char raw,
2429    __unused char sfrm)
2430{
2431
2432	print_tok_type(fp, tok->id, "socket", raw);
2433	print_delim(fp, del);
2434	print_2_bytes(fp, tok->tt.socket_ex32.type, "%#x");
2435	print_delim(fp, del);
2436	print_2_bytes(fp, ntohs(tok->tt.socket_ex32.l_port), "%#x");
2437	print_delim(fp, del);
2438	print_ip_address(fp, tok->tt.socket_ex32.l_addr);
2439	print_delim(fp, del);
2440	print_4_bytes(fp, ntohs(tok->tt.socket_ex32.r_port), "%#x");
2441	print_delim(fp, del);
2442	print_ip_address(fp, tok->tt.socket_ex32.r_addr);
2443}
2444
2445static int
2446fetch_invalid_tok(tokenstr_t *tok, char *buf, int len)
2447{
2448	int err = 0;
2449	int recoversize;
2450
2451	recoversize = len - (tok->len + BSM_TRAILER_SIZE);
2452	if (recoversize <= 0)
2453		return (-1);
2454
2455	tok->tt.invalid.length = recoversize;
2456
2457	SET_PTR(buf, len, tok->tt.invalid.data, recoversize, tok->len, err);
2458	if (err)
2459		return (-1);
2460
2461	return (0);
2462}
2463
2464static void
2465print_invalid_tok(FILE *fp, tokenstr_t *tok, char *del, char raw,
2466    __unused char sfrm)
2467{
2468
2469	print_tok_type(fp, tok->id, "unknown", raw);
2470	print_delim(fp, del);
2471	print_mem(fp, tok->tt.invalid.data, tok->tt.invalid.length);
2472}
2473
2474
2475/*
2476 * Reads the token beginning at buf into tok.
2477 */
2478int
2479au_fetch_tok(tokenstr_t *tok, u_char *buf, int len)
2480{
2481
2482	if (len <= 0)
2483		return (-1);
2484
2485	tok->len = 1;
2486	tok->data = buf;
2487	tok->id = *buf;
2488
2489	switch(tok->id) {
2490	case AUT_HEADER32:
2491		return (fetch_header32_tok(tok, buf, len));
2492
2493	case AUT_HEADER32_EX:
2494		return (fetch_header32_ex_tok(tok, buf, len));
2495
2496	case AUT_HEADER64:
2497		return (fetch_header64_tok(tok, buf, len));
2498
2499	case AUT_HEADER64_EX:
2500		return (fetch_header64_ex_tok(tok, buf, len));
2501
2502	case AUT_TRAILER:
2503		return (fetch_trailer_tok(tok, buf, len));
2504
2505	case AUT_ARG32:
2506		return (fetch_arg32_tok(tok, buf, len));
2507
2508	case AUT_ARG64:
2509		return (fetch_arg64_tok(tok, buf, len));
2510
2511	case AUT_ATTR32:
2512		return (fetch_attr32_tok(tok, buf, len));
2513
2514	case AUT_ATTR64:
2515		return (fetch_attr64_tok(tok, buf, len));
2516
2517	case AUT_EXIT:
2518		return (fetch_exit_tok(tok, buf, len));
2519
2520	case AUT_EXEC_ARGS:
2521		return (fetch_execarg_tok(tok, buf, len));
2522
2523	case AUT_EXEC_ENV:
2524		return (fetch_execenv_tok(tok, buf, len));
2525
2526	case AUT_OTHER_FILE32:
2527		return (fetch_file_tok(tok, buf, len));
2528
2529	case AUT_NEWGROUPS:
2530		return (fetch_newgroups_tok(tok, buf, len));
2531
2532	case AUT_IN_ADDR:
2533		return (fetch_inaddr_tok(tok, buf, len));
2534
2535	case AUT_IN_ADDR_EX:
2536		return (fetch_inaddr_ex_tok(tok, buf, len));
2537
2538	case AUT_IP:
2539		return (fetch_ip_tok(tok, buf, len));
2540
2541	case AUT_IPC:
2542		return (fetch_ipc_tok(tok, buf, len));
2543
2544	case AUT_IPC_PERM:
2545		return (fetch_ipcperm_tok(tok, buf, len));
2546
2547	case AUT_IPORT:
2548		return (fetch_iport_tok(tok, buf, len));
2549
2550	case AUT_OPAQUE:
2551		return (fetch_opaque_tok(tok, buf, len));
2552
2553	case AUT_PATH:
2554		return (fetch_path_tok(tok, buf, len));
2555
2556	case AUT_PROCESS32:
2557		return (fetch_process32_tok(tok, buf, len));
2558
2559	case AUT_PROCESS32_EX:
2560		return (fetch_process32ex_tok(tok, buf, len));
2561
2562	case AUT_RETURN32:
2563		return (fetch_return32_tok(tok, buf, len));
2564
2565	case AUT_RETURN64:
2566		return (fetch_return64_tok(tok, buf, len));
2567
2568	case AUT_SEQ:
2569		return (fetch_seq_tok(tok, buf, len));
2570
2571	case AUT_SOCKET:
2572		return (fetch_socket_tok(tok, buf, len));
2573
2574	case AUT_SOCKINET32:
2575		return (fetch_sock_inet32_tok(tok, buf, len));
2576
2577	case AUT_SOCKUNIX:
2578		return (fetch_sock_unix_tok(tok, buf, len));
2579
2580	case AUT_SUBJECT32:
2581		return (fetch_subject32_tok(tok, buf, len));
2582
2583	case AUT_SUBJECT64:
2584		return (fetch_subject64_tok(tok, buf, len));
2585
2586	case AUT_SUBJECT32_EX:
2587		return (fetch_subject32ex_tok(tok, buf, len));
2588
2589	case AUT_TEXT:
2590		return (fetch_text_tok(tok, buf, len));
2591
2592	case AUT_SOCKET_EX:
2593		return (fetch_socketex32_tok(tok, buf, len));
2594
2595	case AUT_DATA:
2596		return (fetch_arb_tok(tok, buf, len));
2597
2598	default:
2599		return (fetch_invalid_tok(tok, buf, len));
2600	}
2601}
2602
2603/*
2604 * 'prints' the token out to outfp
2605 */
2606void
2607au_print_tok(FILE *outfp, tokenstr_t *tok, char *del, char raw, char sfrm)
2608{
2609
2610	switch(tok->id) {
2611	case AUT_HEADER32:
2612		print_header32_tok(outfp, tok, del, raw, sfrm);
2613		return;
2614
2615	case AUT_HEADER32_EX:
2616		print_header32_ex_tok(outfp, tok, del, raw, sfrm);
2617		return;
2618
2619	case AUT_HEADER64:
2620		print_header64_tok(outfp, tok, del, raw, sfrm);
2621		return;
2622
2623	case AUT_HEADER64_EX:
2624		print_header64_ex_tok(outfp, tok, del, raw, sfrm);
2625		return;
2626
2627	case AUT_TRAILER:
2628		print_trailer_tok(outfp, tok, del, raw, sfrm);
2629		return;
2630
2631	case AUT_ARG32:
2632		print_arg32_tok(outfp, tok, del, raw, sfrm);
2633		return;
2634
2635	case AUT_ARG64:
2636		print_arg64_tok(outfp, tok, del, raw, sfrm);
2637		return;
2638
2639	case AUT_DATA:
2640		print_arb_tok(outfp, tok, del, raw, sfrm);
2641		return;
2642
2643	case AUT_ATTR32:
2644		print_attr32_tok(outfp, tok, del, raw, sfrm);
2645		return;
2646
2647	case AUT_ATTR64:
2648		print_attr64_tok(outfp, tok, del, raw, sfrm);
2649		return;
2650
2651	case AUT_EXIT:
2652		print_exit_tok(outfp, tok, del, raw, sfrm);
2653		return;
2654
2655	case AUT_EXEC_ARGS:
2656		print_execarg_tok(outfp, tok, del, raw, sfrm);
2657		return;
2658
2659	case AUT_EXEC_ENV:
2660		print_execenv_tok(outfp, tok, del, raw, sfrm);
2661		return;
2662
2663	case AUT_OTHER_FILE32:
2664		print_file_tok(outfp, tok, del, raw, sfrm);
2665		return;
2666
2667	case AUT_NEWGROUPS:
2668		print_newgroups_tok(outfp, tok, del, raw, sfrm);
2669		return;
2670
2671	case AUT_IN_ADDR:
2672		print_inaddr_tok(outfp, tok, del, raw, sfrm);
2673		return;
2674
2675	case AUT_IN_ADDR_EX:
2676		print_inaddr_ex_tok(outfp, tok, del, raw, sfrm);
2677		return;
2678
2679	case AUT_IP:
2680		print_ip_tok(outfp, tok, del, raw, sfrm);
2681		return;
2682
2683	case AUT_IPC:
2684		print_ipc_tok(outfp, tok, del, raw, sfrm);
2685		return;
2686
2687	case AUT_IPC_PERM:
2688		print_ipcperm_tok(outfp, tok, del, raw, sfrm);
2689		return;
2690
2691	case AUT_IPORT:
2692		print_iport_tok(outfp, tok, del, raw, sfrm);
2693		return;
2694
2695	case AUT_OPAQUE:
2696		print_opaque_tok(outfp, tok, del, raw, sfrm);
2697		return;
2698
2699	case AUT_PATH:
2700		print_path_tok(outfp, tok, del, raw, sfrm);
2701		return;
2702
2703	case AUT_PROCESS32:
2704		print_process32_tok(outfp, tok, del, raw, sfrm);
2705		return;
2706
2707	case AUT_PROCESS32_EX:
2708		print_process32ex_tok(outfp, tok, del, raw, sfrm);
2709		return;
2710
2711	case AUT_RETURN32:
2712		print_return32_tok(outfp, tok, del, raw, sfrm);
2713		return;
2714
2715	case AUT_RETURN64:
2716		print_return64_tok(outfp, tok, del, raw, sfrm);
2717		return;
2718
2719	case AUT_SEQ:
2720		print_seq_tok(outfp, tok, del, raw, sfrm);
2721		return;
2722
2723	case AUT_SOCKET:
2724		print_socket_tok(outfp, tok, del, raw, sfrm);
2725		return;
2726
2727	case AUT_SOCKINET32:
2728		print_sock_inet32_tok(outfp, tok, del, raw, sfrm);
2729		return;
2730
2731	case AUT_SOCKUNIX:
2732		print_sock_unix_tok(outfp, tok, del, raw, sfrm);
2733		return;
2734
2735	case AUT_SUBJECT32:
2736		print_subject32_tok(outfp, tok, del, raw, sfrm);
2737		return;
2738
2739	case AUT_SUBJECT64:
2740		print_subject64_tok(outfp, tok, del, raw, sfrm);
2741		return;
2742
2743	case AUT_SUBJECT32_EX:
2744		print_subject32ex_tok(outfp, tok, del, raw, sfrm);
2745		return;
2746
2747	case AUT_TEXT:
2748		print_text_tok(outfp, tok, del, raw, sfrm);
2749		return;
2750
2751	case AUT_SOCKET_EX:
2752		print_socketex32_tok(outfp, tok, del, raw, sfrm);
2753		return;
2754
2755	default:
2756		print_invalid_tok(outfp, tok, del, raw, sfrm);
2757	}
2758}
2759
2760/*
2761 * Read a record from the file pointer, store data in buf memory for buf is
2762 * also allocated in this function and has to be free'd outside this call.
2763 *
2764 * au_read_rec() handles two possibilities: a stand-alone file token, or a
2765 * complete audit record.
2766 *
2767 * XXXRW: Note that if we hit an error, we leave the stream in an unusable
2768 * state, because it will be partly offset into a record.  We should rewind
2769 * or do something more intelligent.  Particularly interesting is the case
2770 * where we perform a partial read of a record from a non-blockable file
2771 * descriptor.  We should return the partial read and continue...?
2772 */
2773int
2774au_read_rec(FILE *fp, u_char **buf)
2775{
2776	u_char *bptr;
2777	u_int32_t recsize;
2778	u_int32_t bytestoread;
2779	u_char type;
2780
2781	u_int32_t sec, msec;
2782	u_int16_t filenamelen;
2783
2784	type = fgetc(fp);
2785
2786	switch (type) {
2787	case AUT_HEADER32:
2788	case AUT_HEADER32_EX:
2789	case AUT_HEADER64:
2790	case AUT_HEADER64_EX:
2791		/* read the record size from the token */
2792		if (fread(&recsize, 1, sizeof(u_int32_t), fp) <
2793		    sizeof(u_int32_t)) {
2794			errno = EINVAL;
2795			return (-1);
2796		}
2797		recsize = be32toh(recsize);
2798
2799		/* Check for recsize sanity */
2800		if (recsize < (sizeof(u_int32_t) + sizeof(u_char))) {
2801			errno = EINVAL;
2802			return (-1);
2803		}
2804
2805		*buf = malloc(recsize * sizeof(u_char));
2806		if (*buf == NULL)
2807			return (-1);
2808		bptr = *buf;
2809		memset(bptr, 0, recsize);
2810
2811		/* store the token contents already read, back to the buffer*/
2812		*bptr = type;
2813		bptr++;
2814		be32enc(bptr, recsize);
2815		bptr += sizeof(u_int32_t);
2816
2817		/* now read remaining record bytes */
2818		bytestoread = recsize - (sizeof(u_int32_t) + sizeof(u_char));
2819
2820		if (fread(bptr, 1, bytestoread, fp) < bytestoread) {
2821			free(*buf);
2822			errno = EINVAL;
2823			return (-1);
2824		}
2825		break;
2826
2827	case AUT_OTHER_FILE32:
2828		/*
2829		 * The file token is variable-length, as it includes a
2830		 * pathname.  As a result, we have to read incrementally
2831		 * until we know the total length, then allocate space and
2832		 * read the rest.
2833		 */
2834		if (fread(&sec, 1, sizeof(sec), fp) < sizeof(sec)) {
2835			errno = EINVAL;
2836			return (-1);
2837		}
2838		if (fread(&msec, 1, sizeof(msec), fp) < sizeof(msec)) {
2839			errno = EINVAL;
2840			return (-1);
2841		}
2842		if (fread(&filenamelen, 1, sizeof(filenamelen), fp) <
2843		    sizeof(filenamelen)) {
2844			errno = EINVAL;
2845			return (-1);
2846		}
2847		recsize = sizeof(type) + sizeof(sec) + sizeof(msec) +
2848		    sizeof(filenamelen) + ntohs(filenamelen);
2849		*buf = malloc(recsize);
2850		if (*buf == NULL)
2851			return (-1);
2852		bptr = *buf;
2853
2854		bcopy(&type, bptr, sizeof(type));
2855		bptr += sizeof(type);
2856		bcopy(&sec, bptr, sizeof(sec));
2857		bptr += sizeof(sec);
2858		bcopy(&msec, bptr, sizeof(msec));
2859		bptr += sizeof(msec);
2860		bcopy(&filenamelen, bptr, sizeof(filenamelen));
2861		bptr += sizeof(filenamelen);
2862
2863		if (fread(bptr, 1, ntohs(filenamelen), fp) <
2864		    ntohs(filenamelen)) {
2865			free(buf);
2866			errno = EINVAL;
2867			return (-1);
2868		}
2869		break;
2870
2871	default:
2872		errno = EINVAL;
2873		return (-1);
2874	}
2875
2876	return (recsize);
2877}
2878