nfslog_elf.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* nfs log - read buffer file and print structs in user-readable form
*/
#define _REENTRANT
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <strings.h>
#include <time.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <time.h>
#include <limits.h>
#include <libintl.h>
#include <pwd.h>
#include <netdb.h>
#include <syslog.h>
#include <netconfig.h>
#include <netdir.h>
#include "fhtab.h"
#include "nfslogd.h"
"\"none\"", "\"file\"", "\"dir\"", "\"blk device\"",
"\"chr device\"", "\"link\"", "\"socket\"", "\"fifo\""
};
#define NFSL_FTYPE3(ftype) \
"\"unchecked", "\"guarded\"", "\"exclusive\""
};
#define NFSL_CREATEMODE3(createmode) \
"\"auth_null\"", "\"auth_unix\"", "\"auth_short\"", "\"auth_des\"",
"\"auth_kerb\"", "\"none\"", "\"rpcsec_gss\""
};
#define NFSL_AUTH_FLAVOR_PRINT(auth_flavor) \
(((auth_flavor) <= RPCSEC_GSS) ? \
/*
* Two arrays - one short ints containing err codes, the other the strings
* (merged codes for both v2 and v3
*/
"\"ok\"", "\"perm\"", "\"noent\"", "\"io\"",
"\"nxio\"", "\"access\"", "\"exist\"", "\"xdev\"",
"\"nodev\"", "\"notdir\"", "\"isdir\"", "\"inval\"",
"\"fbig\"", "\"nospc\"", "\"rofs\"", "\"mlink\"",
"\"notsupp\"", "\"nametoolong\"", "\"notempty\"", "\"dquot\"",
"\"stale\"", "\"remote\"", "\"wflush\"", "\"badhandle\"",
"\"not_sync\"", "\"bad_cookie\"", "\"notsupp\"", "\"toosmall\"",
"\"serverfault\"", "\"badtype\"", "\"jukebox\"",
};
static short nfsl_status[NFSL_ERR_CNT] = {
0, 1, 2, 5, 6, 13, 17, 18,
19, 20, 21, 22, 27, 28, 30, 31,
45, 63, 66, 69, 70, 71, 99, 10001,
10002, 10003, 10004, 10005, 10006, 10007, 10008
};
/* list of open elf files */
/* Imported functions */
/* Static functions */
struct nfsl_log_file **elf_listp);
struct nfsl_log_file *elf_list);
struct nfsl_log_file **elf_listp);
static void nfsl_elf_record_header_print(struct nfsl_log_file *,
nfslog_record_header *, char *, char *,
struct nfsl_proc_disp *, char *);
static void nfsl_elf_buffer_header_print(struct nfsl_log_file *,
static struct nfsl_proc_disp *nfsl_find_elf_dispatch(
nfslog_request_record *, char **);
static void nfsl_elf_rpc_print(struct nfsl_log_file *,
nfslog_request_record *, struct nfsl_proc_disp *,
char *, char *, char *);
/*
* NFS VERSION 2
*/
/* Functions for elf print of the arguments */
static void nfslog_setattrargs_print(struct nfsl_log_file *,
static void nfslog_sattr_print(struct nfsl_log_file *,
nfslog_sattr *);
static void nfslog_nfsreadargs_print(struct nfsl_log_file *,
static void nfslog_writeargs_print(struct nfsl_log_file *,
nfslog_writeargs *);
static void nfslog_writeresult_print(struct nfsl_log_file *,
nfslog_writeresult *, bool_t);
static void nfslog_creatargs_print(struct nfsl_log_file *,
static void nfslog_symlinkargs_print(struct nfsl_log_file *,
static void nfslog_sharefsargs_print(struct nfsl_log_file *,
static void nfslog_getfhargs_print(struct nfsl_log_file *,
nfslog_getfhargs *);
/* Functions for elf print of the response */
bool_t);
bool_t);
bool_t);
static void nfslog_rdresult_print(struct nfsl_log_file *,
nfslog_rdresult *, bool_t);
bool_t);
/*
* NFS VERSION 3
*/
/* Functions for elf print of the arguments */
static void nfslog_diropargs3_print(struct nfsl_log_file *,
static void nfslog_SETATTR3args_print(struct nfsl_log_file *,
static void nfslog_WRITE3args_print(struct nfsl_log_file *,
static void nfslog_CREATE3args_print(struct nfsl_log_file *,
static void nfslog_MKDIR3args_print(struct nfsl_log_file *,
static void nfslog_SYMLINK3args_print(struct nfsl_log_file *,
static void nfslog_MKNOD3args_print(struct nfsl_log_file *,
static void nfslog_REMOVE3args_print(struct nfsl_log_file *,
static void nfslog_RMDIR3args_print(struct nfsl_log_file *,
static void nfslog_RENAME3args_print(struct nfsl_log_file *,
static void nfslog_LINK3args_print(struct nfsl_log_file *,
nfslog_LINK3args *);
static void nfslog_COMMIT3args_print(struct nfsl_log_file *,
static void nfslog_READDIRPLUS3args_print(struct nfsl_log_file *,
/* Functions for elf print of the response */
static void nfslog_nfsstat3_print(struct nfsl_log_file *,
static void nfslog_LOOKUP3res_print(struct nfsl_log_file *,
nfslog_LOOKUP3res *, bool_t);
static void nfslog_READLINK3res_print(struct nfsl_log_file *,
static void nfslog_READ3res_print(struct nfsl_log_file *,
nfslog_READ3res *, bool_t);
static void nfslog_WRITE3res_print(struct nfsl_log_file *,
nfslog_WRITE3res *, bool_t);
static void nfslog_CREATE3res_print(struct nfsl_log_file *,
nfslog_CREATE3res *, bool_t);
static void nfslog_MKDIR3res_print(struct nfsl_log_file *,
nfslog_MKDIR3res *, bool_t);
static void nfslog_SYMLINK3res_print(struct nfsl_log_file *,
nfslog_SYMLINK3res *, bool_t);
static void nfslog_MKNOD3res_print(struct nfsl_log_file *,
nfslog_MKNOD3res *, bool_t);
static void nfslog_READDIRPLUS3res_print(struct nfsl_log_file *,
extern int debug;
#define DFLT_BUFFERSIZE 8192
/*
*
* In some cases, the nl types are the same as the nfs types and a simple
* bcopy should suffice. Rather that define tens of identical procedures,
* simply define these to bcopy. Similarly this takes care of different
* procs that use same parameter struct.
*/
static struct nfsl_proc_disp nfsl_elf_proc_v2[] = {
/*
* NFS VERSION 2
*/
/* RFS_NULL = 0 */
/* RFS_GETATTR = 1 */
/* RFS_SETATTR = 2 */
/* RFS_ROOT = 3 *** NO LONGER SUPPORTED *** */
/* RFS_LOOKUP = 4 */
/* RFS_READLINK = 5 */
/* RFS_READ = 6 */
/* RFS_WRITECACHE = 7 *** NO LONGER SUPPORTED *** */
/* RFS_WRITE = 8 */
/* RFS_CREATE = 9 */
/* RFS_REMOVE = 10 */
/* RFS_RENAME = 11 */
/* RFS_LINK = 12 */
/* RFS_SYMLINK = 13 */
/* RFS_MKDIR = 14 */
/* RFS_RMDIR = 15 */
/* RFS_READDIR = 16 */
/* RFS_STATFS = 17 */
};
/*
* NFS VERSION 3
*/
static struct nfsl_proc_disp nfsl_elf_proc_v3[] = {
/* NFSPROC3_NULL = 0 */
/* NFSPROC3_GETATTR = 1 */
/* NFSPROC3_SETATTR = 2 */
/* NFSPROC3_LOOKUP = 3 */
/* NFSPROC3_ACCESS = 4 */
/* NFSPROC3_READLINK = 5 */
/* NFSPROC3_READ = 6 */
/* NFSPROC3_WRITE = 7 */
/* NFSPROC3_CREATE = 8 */
/* NFSPROC3_MKDIR = 9 */
/* NFSPROC3_SYMLINK = 10 */
/* NFSPROC3_MKNOD = 11 */
/* NFSPROC3_REMOVE = 12 */
/* NFSPROC3_RMDIR = 13 */
/* NFSPROC3_RENAME = 14 */
/* NFSPROC3_LINK = 15 */
/* NFSPROC3_READDIR = 16 */
/* NFSPROC3_READDIRPLUS = 17 */
"\"readdirplus\""},
/* NFSPROC3_FSSTAT = 18 */
/* NFSPROC3_FSINFO = 19 */
/* NFSPROC3_PATHCONF = 20 */
/* NFSPROC3_COMMIT = 21 */
};
/*
* NFSLOG VERSION 1
*/
static struct nfsl_proc_disp nfsl_log_elf_proc_v1[] = {
/* NFSLOG_NULL = 0 */
/* NFSLOG_SHARE = 1 */
/* NFSLOG_UNSHARE = 2 */
/* NFSLOG_LOOKUP = 3 */
/* NFSLOG_GETFH = 4 */
};
static struct nfsl_vers_disp nfsl_elf_vers_disptable[] = {
{sizeof (nfsl_elf_proc_v2) / sizeof (nfsl_elf_proc_v2[0]),
{sizeof (nfsl_elf_proc_v3) / sizeof (nfsl_elf_proc_v3[0]),
};
static struct nfsl_vers_disp nfsl_log_elf_vers_disptable[] = {
{sizeof (nfsl_log_elf_proc_v1) / sizeof (nfsl_log_elf_proc_v1[0]),
};
static struct nfsl_prog_disp nfsl_elf_dispatch_table[] = {
sizeof (nfsl_elf_vers_disptable) /
sizeof (nfsl_elf_vers_disptable[0]),
nfsl_elf_vers_disptable, "nfs"},
sizeof (nfsl_log_elf_vers_disptable) /
sizeof (nfsl_log_elf_vers_disptable[0]),
nfsl_log_elf_vers_disptable, "nfslog"},
};
static int nfsl_elf_dispatch_table_arglen =
sizeof (nfsl_elf_dispatch_table) /
sizeof (nfsl_elf_dispatch_table[0]);
static char *
nfslog_get_status(short status)
{
short errstat;
/* Usually status is 0... */
if (status == 0)
return (nfsl_status_name[0]);
low = 0;
high = NFSL_ERR_CNT;
/* binary search for status string */
} else { /* search upper half */
}
}
return (nfsl_status_name[mid]);
}
return (NULL);
}
/* nfsl_get_time - return string with time formatted as hh:mm:ss */
static char *
{
static char timestr[20];
return (timestr);
return (empty_name);
}
return (timestr);
}
/* nfsl_get_date - return date string formatted as "yyyy-mm-dd hh:mm:ss" */
static char *
{
static char timestr[30];
return (timestr);
return (empty_name);
}
return (timestr);
}
/*
* nfsl_get_date_nq - return date string formatted as yyyy-mm-dd hh:mm:ss
* (no quotes)
*/
static char *
{
static char timestr[30];
return (timestr);
return (empty_name);
}
return (timestr);
}
/* write log buffer out to file */
static int
{
int rc;
if (debug > 1)
(void) printf("nfsl_write_elfbuf: bufoffset %d\n",
if (elfbufoffset <= 0)
return (0);
return (-1);
}
if (rc != elfbufoffset) {
return (-1);
}
return (0);
}
/*ARGSUSED*/
static void
{
}
/*ARGSUSED*/
static void
{
}
static void
{
if (!nfsl_print_fh)
return;
} else {
}
}
/*
* NFS VERSION 2
*/
/* Functions that elf print the arguments */
static void
{
if (!nfsl_print_fh)
return;
}
static void
{
if (nfsl_print_fh) {
} else {
}
}
}
static void
{
/* BEGIN CSTYLED */
}
}
}
}
" \"atime=%s\"",
}
" \"mtime=%s\"",
}
/* END CSTYLED */
}
static void
{
}
static void
{
int elfbufoffset;
args->ra_totcount);
}
static void
{
args->waargs_count);
}
static void
{
if (print_status) {
}
}
static void
{
}
static void
{
int elfbufoffset;
args->rda_offset);
}
static void
{
}
static void
{
}
static void
{
int elfbufoffset;
}
/*
*/
static void
{
unsigned int elfbufoffset;
if (nfsl_print_fh) {
} else {
}
}
}
static void
{
unsigned int elfbufoffset;
if (nfsl_print_fh) {
} else {
}
}
}
static void
{
if (print_status) {
statp);
else
*res);
}
}
static void
{
if (print_status) {
}
}
static void
{
if (print_status) {
}
}
static void
{
if (print_status) {
}
}
static void
{
if (print_status) {
}
}
/*
* NFS VERSION 3
*/
static void
{
if (nfsl_print_fh) {
}
}
static void
{
/* CSTYLED */
}
}
static void
{
}
static void
{
}
static void
{
int elfbufoffset;
}
static void
{
}
}
static void
{
}
static void
{
}
static void
{
}
static void
{
}
static void
{
}
static void
{
}
static void
{
}
static void
{
}
static void
{
}
static void
{
if (print_status) {
statp);
else
*res);
}
}
static void
{
if (print_status) {
}
}
static void
{
if (print_status) {
}
}
static void
{
if (print_status) {
}
}
static void
{
if (print_status) {
}
}
static void
{
if (print_status) {
}
}
}
static void
{
if (print_status) {
}
}
}
static void
{
if (print_status) {
}
}
}
static void
{
if (print_status) {
}
}
}
static void
{
if (print_status) {
}
}
/*
* **** End of table functions for logging specific procs ****
*
* Hereafter are the general logging management and dispatcher.
*/
/*
* nfsl_ipaddr_print - extracts sender ip address from transport struct
* and prints it in legible form.
*/
static void
{
extern char *inet_ntop();
char *addrp;
return;
}
/* LINTED */
switch (sin_family) {
case (AF_INET):
/* LINTED */
break;
case (AF_INET6):
/* LINTED */
break;
default:
/* unknown protocol: print address in hex form */
*addrp);
}
return;
}
== NULL) {
/* Not enough space to print - should never happen */
return;
}
/* inet_ntop copied address into elfbuf, so update offset */
/* get host name and log it as well */
} else {
}
}
static void
{
/*
* Fields: time bytes tag rpc-program rpc-version rpc-procedure
* auth-flavor s-user-name s-uid uid u-name gid net-id
* c-ip c-dns s-dns status rpcarg-path <arguments> <response>
*/
} else {
}
} else {
" %s", empty_name);
}
} else {
}
} else {
}
}
static void
{
int rc;
"#Version %d.0\n#Software \"%s\"\n",
"#Fields: time bytes tag");
" rpc-program rpc-version rpc-procedure");
" auth-flavor s-user-name s-uid uid u-name gid net-id c-ip");
" c-dns s-dns status rpcarg-path");
" rpc-arguments... rpc-response...\n");
}
/*
* nfsl_find_elf_dispatch - get the dispatch struct for this request
*/
static struct nfsl_proc_disp *
{
int i, vers;
/* Find prog element - search because can't use prog as array index */
for (i = 0; (i < nfsl_elf_dispatch_table_arglen) &&
i++);
if (i >= nfsl_elf_dispatch_table_arglen) { /* program not logged */
/* not an error */
return (NULL);
}
progtable = &nfsl_elf_dispatch_table[i];
/* Find vers element - no validity check - if here it's valid vers */
/* Find proc element - no validity check - if here it's valid proc */
}
/*
* nfsl_elf_rpc_print - Print the record buffer.
*/
static void
{
if (debug > 1) {
(void) printf(": '%s', '%s'\n",
}
/*
* XXXX programs using this file to get a usable record should
* take "record" struct.
*/
/*
* Print the variable fields:
* principal name
* netid
* ip address
* rpc args
* rpc res
* Use the displacements calculated earlier...
*/
/*
* Fields: time bytes tag rpc-program rpc-version rpc-procedure
* auth-flavor s-user-name s-uid uid u-name gid net-id c-ip
* c-dns s-dns status rpcarg-path <arguments> <response>
*/
} else {
" %s", empty_name);
}
" \"%s\"", hostname);
/* Next is return status */
/* Next is argpath */
" \"%s\"", path1);
} else {
" %s", empty_name);
}
/*
* empty print it here as it's a part of the args
*/
" \"%s\"", path2);
}
/* Next print formatted rpc args */
/* Next print formatted rpc res (minus status) */
}
/*
* nfsl_log_file_add - add a new record to the list
*/
static void
struct nfsl_log_file **elf_listp)
{
}
}
/*
* nfsl_log_file_find - finds a record in the list, given a cookie (== elfrec)
* Returns the record.
*/
static struct nfsl_log_file *
struct nfsl_log_file *elf_list)
{
struct nfsl_log_file *rec;
return (rec);
}
/*
* nfsl_log_file_del - delete a record from the list, does not free rec.
* Returns the deleted record.
*/
static struct nfsl_log_file *
struct nfsl_log_file **elf_listp)
{
struct nfsl_log_file *rec;
return (NULL);
}
} else {
}
}
return (rec);
}
/*
* nfsl_log_file_free - frees a record
*/
static void
{
return;
}
/*
* Exported Functions
*/
/*
* nfslog_open_elf_file - open the output elf file and mallocs needed buffers
* Returns a pointer to the nfsl_log_file on success, NULL on error.
*
* *error contains the last error encountered on this object, It can
* be used to avoid reporting the same error endlessly, by comparing
* the current error to the last error. It is reset to the current error
* code on return.
*/
void *
{
struct nfsl_log_file *elfrec;
}
return (NULL);
}
}
return (NULL);
}
}
return (NULL);
}
}
return (NULL);
}
}
return (NULL);
}
/*
* Print header unto logfile
*/
}
if (hostname[0] == '\0') {
}
return (elfrec);
}
/*
* nfslog_close_elf_file - close elffile and write out last buffer
*/
void
nfslog_close_elf_file(void **elfcookie)
{
struct nfsl_log_file *elfrec;
return;
}
/* Write the last output buffer to disk */
(void) nfsl_write_elfbuf(elfrec);
}
}
/*
* nfslog_process_elf_rec - processes the record in the buffer and outputs
* to the elf log.
* Return 0 for success, errno else.
*/
int
{
struct nfsl_log_file *elfrec;
struct nfsl_proc_disp *disp;
char *progname;
return (EINVAL);
}
/* Make sure there is room */
if (nfsl_write_elfbuf(elfrec) < 0) {
return (errno);
}
}
}
return (0);
}