1 /*
2  * Copyright (c) 2005-2006 The FreeBSD Project
3  * All rights reserved.
4  *
5  * Author: Victor Cruceru <soc-victor@freebsd.org>
6  *
7  * Redistribution of this software and documentation and use in source and
8  * binary forms, with or without modification, are permitted provided that
9  * the following conditions are met:
10  *
11  * 1. Redistributions of source code or documentation must retain the above
12  *    copyright notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * Host Resources MIB for SNMPd.
30  */
31 
32 #ifndef HOSTRES_SNMP_H_1132245017
33 #define	HOSTRES_SNMP_H_1132245017
34 
35 #include <sys/types.h>
36 #include <sys/queue.h>
37 
38 #include <stdio.h>
39 #include <fcntl.h>
40 #include <kvm.h>
41 #include <devinfo.h>
42 
43 #include <bsnmp/asn1.h>
44 #include <bsnmp/snmp.h>
45 
46 #include <bsnmp/snmpmod.h>
47 
48 /*
49  * Default package directory for hrSWInstalledTable. Can be overridden
50  * via SNMP or configuration file.
51  */
52 #define	PATH_PKGDIR     "/var/db/pkg"
53 
54 /*
55  * These are the default maximum caching intervals for the various tables
56  * in seconds. They can be overridden from the configuration file.
57  */
58 #define	HR_STORAGE_TBL_REFRESH	7
59 #define	HR_FS_TBL_REFRESH	7
60 #define	HR_DISK_TBL_REFRESH	7
61 #define	HR_NETWORK_TBL_REFRESH	7
62 #define	HR_SWINS_TBL_REFRESH	120
63 #define	HR_SWRUN_TBL_REFRESH	3
64 
65 struct tm;
66 struct statfs;
67 
68 /* a debug macro */
69 #ifndef NDEBUG
70 
71 #define	HRDBG(...) do {							\
72 	fprintf(stderr, "HRDEBUG: %s: ", __func__);			\
73 	fprintf(stderr, __VA_ARGS__);					\
74 	fprintf(stderr, "\n");						\
75    } while (0)
76 
77 #else
78 
79 #define	HRDBG(...) do { } while (0)
80 
81 #endif /*NDEBUG*/
82 
83 /* path to devd(8) output pipe */
84 #define	PATH_DEVD_PIPE	"/var/run/devd.pipe"
85 
86 #define	IS_KERNPROC(kp)	(((kp)->ki_flag & P_KPROC) == P_KPROC)
87 
88 enum snmpTCTruthValue {
89 	SNMP_TRUE = 1,
90 	SNMP_FALSE= 2
91 };
92 
93 /* The number of CPU load samples per one minute, per each CPU */
94 #define	MAX_CPU_SAMPLES 4
95 
96 
97 /*
98  * max len (including '\0'), for device_entry::descr field below,
99  * according to MIB
100  */
101 #define	DEV_DESCR_MLEN	(64 + 1)
102 
103 /*
104  * max len (including '\0'), for device_entry::name and
105  * device_map_entry::name_key fields below, according to MIB
106  */
107 #define	DEV_NAME_MLEN	(32 + 1)
108 
109 /*
110  * max len (including '\0'), for device_entry::location and
111  * device_map_entry::location_key fields below, according to MIB
112  */
113 #define	DEV_LOC_MLEN	(128 + 1)
114 
115 /*
116  * This structure is used to hold a SNMP table entry
117  * for HOST-RESOURCES-MIB's hrDeviceTable
118  */
119 struct device_entry {
120 	int32_t		index;
121 	const struct asn_oid *type;
122 	u_char		*descr;
123 	const struct asn_oid *id;	/* only oid_zeroDotZero as (*id) value*/
124 	int32_t		status;		/* enum DeviceStatus */
125 	uint32_t	errors;
126 
127 #define	HR_DEVICE_FOUND		0x001
128 	/* not detected by libdevice, so don't try to refresh it*/
129 #define	HR_DEVICE_IMMUTABLE	0x002
130 
131 	/* next 3 are not from the SNMP mib table, only to be used internally */
132 	uint32_t	flags;
133 
134 	u_char		*name;
135 	u_char		*location;
136 	TAILQ_ENTRY(device_entry) link;
137 };
138 
139 /*
140  * Next structure is used to keep o list of mappings from a specific
141  * name (a_name) to an entry in the hrFSTblEntry;
142  * We are trying to keep the same index for a specific name at least
143  * for the duration of one SNMP agent run.
144  */
145 struct device_map_entry {
146 	int32_t		hrIndex;	/* used for hrDeviceTblEntry::index */
147 
148 	/* map key is the pair (name_key, location_key) */
149 	u_char		*name_key;	/* copy of device name */
150 	u_char		*location_key;
151 
152 	/*
153 	 * Next may be NULL if the respective hrDeviceTblEntry
154 	 * is (temporally) gone.
155 	 */
156 	struct device_entry *entry_p;
157 	STAILQ_ENTRY(device_map_entry) link;
158 };
159 STAILQ_HEAD(device_map, device_map_entry);
160 
161 /* descriptor to access kernel memory */
162 extern kvm_t *hr_kd;
163 
164 /* Table used for consistent device table indexing. */
165 extern struct device_map device_map;
166 
167 /* Maximum number of ticks between two updates for hrStorageTable */
168 extern uint32_t storage_tbl_refresh;
169 
170 /* Maximum number of ticks between updated of FS table */
171 extern uint32_t fs_tbl_refresh;
172 
173 /* maximum number of ticks between updates of SWRun and SWRunPerf table */
174 extern uint32_t swrun_tbl_refresh;
175 
176 /* Maximum number of ticks between device table refreshs. */
177 extern uint32_t device_tbl_refresh;
178 
179 /* maximum number of ticks between refreshs */
180 extern uint32_t disk_storage_tbl_refresh;
181 
182 /* maximum number of ticks between updates of network table */
183 extern uint32_t swins_tbl_refresh;
184 
185 /* maximum number of ticks between updates of network table */
186 extern uint32_t network_tbl_refresh;
187 
188 /* package directory */
189 extern u_char *pkg_dir;
190 
191 /* Initialize and populate storage table */
192 void init_storage_tbl(void);
193 
194 /* Finalization routine for hrStorageTable. */
195 void fini_storage_tbl(void);
196 
197 /* Refresh routine for hrStorageTable. */
198 void refresh_storage_tbl(int);
199 
200 /*
201  * Get the type of filesystem referenced in a struct statfs * -
202  * used by FSTbl and StorageTbl functions.
203  */
204 const struct asn_oid *fs_get_type(const struct statfs *);
205 
206 /*
207  * Because hrFSTable depends to hrStorageTable we are
208  * refreshing hrFSTable by refreshing hrStorageTable.
209  * When one entry "of type" fs from hrStorageTable is refreshed
210  * then the corresponding entry from hrFSTable is refreshed
211  * FS_tbl_pre_refresh_v() is called  before refreshing fs part of hrStorageTable
212  */
213 void fs_tbl_pre_refresh(void);
214 void fs_tbl_process_statfs_entry(const struct statfs *, int32_t);
215 
216 /* Called after refreshing fs part of hrStorageTable */
217 void fs_tbl_post_refresh(void);
218 
219 /* Refresh the FS table if necessary. */
220 void refresh_fs_tbl(void);
221 
222 /* Finalization routine for hrFSTable. */
223 void fini_fs_tbl(void);
224 
225 /* Init the things for both of hrSWRunTable and hrSWRunPerfTable */
226 void init_swrun_tbl(void);
227 
228 /* Finalization routine for both of hrSWRunTable and hrSWRunPerfTable */
229 void fini_swrun_tbl(void);
230 
231 /* Init and populate hrDeviceTable */
232 void init_device_tbl(void);
233 
234 /* start devd monitoring */
235 void start_device_tbl(struct lmodule *);
236 
237 /* Finalization routine for hrDeviceTable */
238 void fini_device_tbl(void);
239 
240 /* Refresh routine for hrDeviceTable. */
241 void refresh_device_tbl(int);
242 
243 /* Find an item in hrDeviceTbl by its entry->index. */
244 struct device_entry *device_find_by_index(int32_t);
245 
246 /* Find an item in hrDeviceTbl by name. */
247 struct device_entry *device_find_by_name(const char *);
248 
249 /* Create a new entry out of thin air. */
250 struct device_entry *device_entry_create(const char *, const char *,
251     const char *);
252 
253 /* Delete an entry from hrDeviceTbl */
254 void device_entry_delete(struct device_entry *entry);
255 
256 /* Init the things for hrProcessorTable. */
257 void init_processor_tbl(void);
258 
259 /* Finalization routine for hrProcessorTable. */
260 void fini_processor_tbl(void);
261 
262 /* Start the processor table CPU load collector. */
263 void start_processor_tbl(struct lmodule *);
264 
265 /* Init the things for hrDiskStorageTable */
266 int init_disk_storage_tbl(void);
267 
268 /* Finalization routine for hrDiskStorageTable. */
269 void fini_disk_storage_tbl(void);
270 
271 /* Refresh routine for hrDiskStorageTable. */
272 void refresh_disk_storage_tbl(int);
273 
274 /* Finalization routine for hrPartitionTable. */
275 void fini_partition_tbl(void);
276 
277 /* Finalization routine for hrNetworkTable. */
278 void fini_network_tbl(void);
279 
280 /* populate network table */
281 void start_network_tbl(void);
282 
283 /* initialize installed software table */
284 void init_swins_tbl(void);
285 
286 /* finalize installed software table */
287 void fini_swins_tbl(void);
288 
289 /* refresh the hrSWInstalledTable if necessary */
290 void refresh_swins_tbl(void);
291 
292 /* Init the things for hrPrinterTable */
293 void init_printer_tbl(void);
294 
295 /* Finalization routine for hrPrinterTable. */
296 void fini_printer_tbl(void);
297 
298 /* Refresh printer table */
299 void refresh_printer_tbl(void);
300 
301 /* get boot command line */
302 int OS_getSystemInitialLoadParameters(u_char **);
303 
304 /* Start refreshing the partition table */
305 void partition_tbl_post_refresh(void);
306 
307 /* Handle refresh for the given disk */
308 void partition_tbl_handle_disk(int32_t, const char *);
309 
310 /* Finish refreshing the partition table. */
311 void partition_tbl_pre_refresh(void);
312 
313 /* Set the FS index in a partition table entry */
314 void handle_partition_fs_index(const char *, int32_t);
315 
316 /* Make an SNMP DateAndTime from a struct tm. */
317 int make_date_time(u_char *, const struct tm *, u_int);
318 
319 /* Free all static data */
320 void fini_scalars(void);
321 
322 #endif /* HOSTRES_SNMP_H_1132245017 */
323