1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21/*
22 * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23 * Use is subject to license terms.
24 */
25
26#include <sys/fm/protocol.h>
27
28#include <strings.h>
29#include <libgen.h>
30#include <regex.h>
31#include <libnvpair.h>
32
33#include <fmd_log_impl.h>
34#include <fmd_log.h>
35
36/*ARGSUSED*/
37int
38fmd_log_filter_class(fmd_log_t *lp, const fmd_log_record_t *rp, void *arg)
39{
40	nvlist_t **nva;
41	uint32_t i, size;
42	char *class;
43
44	if (gmatch(rp->rec_class, arg))
45		return (1);
46
47	/* return false if the record doesn't contain valid fault list */
48	if (! gmatch(rp->rec_class, FM_LIST_EVENT ".*") ||
49	    nvlist_lookup_uint32(rp->rec_nvl, FM_SUSPECT_FAULT_SZ,
50	    &size) != 0 || size == 0 ||
51	    nvlist_lookup_nvlist_array(rp->rec_nvl, FM_SUSPECT_FAULT_LIST,
52	    &nva, &size) != 0)
53		return (0);
54
55	/* return true if any fault in the list matches */
56	for (i = 0; i < size; i++) {
57		if (nvlist_lookup_string(nva[i], FM_CLASS, &class) == 0 &&
58		    gmatch(class, arg))
59			return (1);
60	}
61
62	return (0);
63}
64
65/*ARGSUSED*/
66int
67fmd_log_filter_uuid(fmd_log_t *lp, const fmd_log_record_t *rp, void *arg)
68{
69	char *uuid;
70
71	/*
72	 * Note: the uuid filter matches *any* member whose name is 'uuid'.
73	 * This permits us to match not only a list.suspect uuid but any
74	 * other event that decides to embed uuids, too, using the same name.
75	 */
76	return (nvlist_lookup_string(rp->rec_nvl,
77	    "uuid", &uuid) == 0 && strcmp(uuid, arg) == 0);
78}
79
80/*ARGSUSED*/
81int
82fmd_log_filter_before(fmd_log_t *lp, const fmd_log_record_t *rp, void *arg)
83{
84	uint64_t sec = ((struct timeval *)arg)->tv_sec;
85	uint64_t nsec = ((struct timeval *)arg)->tv_usec * (NANOSEC / MICROSEC);
86	return (rp->rec_sec == sec ? rp->rec_nsec <= nsec : rp->rec_sec <= sec);
87}
88
89/*ARGSUSED*/
90int
91fmd_log_filter_after(fmd_log_t *lp, const fmd_log_record_t *rp, void *arg)
92{
93	uint64_t sec = ((struct timeval *)arg)->tv_sec;
94	uint64_t nsec = ((struct timeval *)arg)->tv_usec * (NANOSEC / MICROSEC);
95	return (rp->rec_sec == sec ? rp->rec_nsec >= nsec : rp->rec_sec >= sec);
96}
97
98/*ARGSUSED*/
99int
100fmd_log_filter_nv(fmd_log_t *lp, const fmd_log_record_t *rp, void *arg)
101{
102	fmd_log_filter_nvarg_t *argt = (fmd_log_filter_nvarg_t *)arg;
103	char		*name = argt->nvarg_name;
104	char		*value = argt->nvarg_value;
105	regex_t		*value_regex = argt->nvarg_value_regex;
106	nvpair_t	*nvp;
107	int		ai;
108
109	/* see if nvlist has named member */
110	if (nvlist_lookup_nvpair_embedded_index(rp->rec_nvl, name,
111	    &nvp, &ai, NULL) != 0)
112		return (0);		/* name filter failure */
113
114	/* check value match for matching nvpair */
115	if ((value == NULL) ||
116	    (nvpair_value_match_regex(nvp, ai, value, value_regex, NULL) == 1))
117		return (1);		/* name/value filter pass */
118
119	return (0);			/* value filter failure */
120}
121