2 * Host Resources MIB - Device group implementation - hr_device.c
6 #include <net-snmp/net-snmp-config.h>
14 #include "hr_device.h"
16 /*********************
18 * Kernel & interface information,
19 * and internal forward declarations
21 *********************/
23 int Get_Next_Device(void);
25 PFV init_device[HRDEV_TYPE_MAX];
26 PFIV next_device[HRDEV_TYPE_MAX];
27 PFV save_device[HRDEV_TYPE_MAX];
28 int dev_idx_inc[HRDEV_TYPE_MAX];
30 PFS device_descr[HRDEV_TYPE_MAX];
31 PFO device_prodid[HRDEV_TYPE_MAX];
32 PFI device_status[HRDEV_TYPE_MAX];
33 PFI device_errors[HRDEV_TYPE_MAX];
37 void Init_Device(void);
38 int header_hrdevice(struct variable *, oid *, size_t *, int,
39 size_t *, WriteMethod **);
42 /*********************
44 * Initialisation & common implementation functions
46 *********************/
52 #define HRDEV_STATUS 5
53 #define HRDEV_ERRORS 6
55 struct variable4 hrdevice_variables[] = {
56 {HRDEV_INDEX, ASN_INTEGER, RONLY, var_hrdevice, 2, {1, 1}},
57 {HRDEV_TYPE, ASN_OBJECT_ID, RONLY, var_hrdevice, 2, {1, 2}},
58 {HRDEV_DESCR, ASN_OCTET_STR, RONLY, var_hrdevice, 2, {1, 3}},
59 {HRDEV_ID, ASN_OBJECT_ID, RONLY, var_hrdevice, 2, {1, 4}},
60 {HRDEV_STATUS, ASN_INTEGER, RONLY, var_hrdevice, 2, {1, 5}},
61 {HRDEV_ERRORS, ASN_COUNTER, RONLY, var_hrdevice, 2, {1, 6}}
63 oid hrdevice_variables_oid[] = { 1, 3, 6, 1, 2, 1, 25, 3, 2 };
72 * Initially assume no devices
73 * Insert pointers to initialisation/get_next routines
74 * for particular device types as they are implemented
75 * (set up in the appropriate 'init_*()' routine )
78 for (i = 0; i < HRDEV_TYPE_MAX; ++i) {
79 init_device[i] = NULL;
80 next_device[i] = NULL;
81 save_device[i] = NULL;
82 dev_idx_inc[i] = 0; /* Assume random indices */
84 device_descr[i] = NULL;
85 device_prodid[i] = NULL;
86 device_status[i] = NULL;
87 device_errors[i] = NULL;
90 REGISTER_MIB("host/hr_device", hrdevice_variables, variable4,
91 hrdevice_variables_oid);
98 * vp IN - pointer to variable entry that points here
99 * name IN/OUT - IN/name requested, OUT/name found
100 * length IN/OUT - length of IN/OUT oid's
101 * exact IN - TRUE if an exact match was requested
102 * var_len OUT - length of variable or 0 if function returned
108 header_hrdevice(struct variable *vp,
111 int exact, size_t * var_len, WriteMethod ** write_method)
113 #define HRDEV_ENTRY_NAME_LENGTH 11
114 oid newname[MAX_OID_LEN];
115 int dev_idx, LowIndex = -1, LowType = -1;
118 DEBUGMSGTL(("host/hr_device", "var_hrdevice: "));
119 DEBUGMSGOID(("host/hr_device", name, *length));
120 DEBUGMSG(("host/hr_device", " %d\n", exact));
122 memcpy((char *) newname, (char *) vp->name,
123 (int) vp->namelen * sizeof(oid));
127 * Find the "next" device entry.
128 * If we're in the middle of the table, then there's
129 * no point in examining earlier types of devices,
130 * so set the starting type to that of the variable
132 * If we've moved from one column of the table to another,
133 * then we need to start at the beginning again.
134 * (i.e. the 'compare' fails to match)
135 * Similarly if we're at the start of the table
136 * (i.e. *length is too short to be a full instance)
139 if ((snmp_oid_compare(vp->name, vp->namelen, name, vp->namelen) == 0)
140 && (*length > HRDEV_ENTRY_NAME_LENGTH))
141 current_type = (name[HRDEV_ENTRY_NAME_LENGTH] >> HRDEV_TYPE_SHIFT);
147 dev_idx = Get_Next_Device();
148 DEBUGMSG(("host/hr_device", "(index %d ....", dev_idx));
151 if (LowType != -1 && LowType < (dev_idx >> HRDEV_TYPE_SHIFT))
153 newname[HRDEV_ENTRY_NAME_LENGTH] = dev_idx;
154 DEBUGMSGOID(("host/hr_device", newname, *length));
155 DEBUGMSG(("host/hr_device", "\n"));
156 result = snmp_oid_compare(name, *length, newname, vp->namelen + 1);
157 if (exact && (result == 0)) {
158 if (save_device[current_type] != NULL)
159 (*save_device[current_type]) ();
163 if ((!exact && (result < 0)) &&
164 (LowIndex == -1 || dev_idx < LowIndex)) {
165 if (save_device[current_type] != NULL)
166 (*save_device[current_type]) ();
168 LowType = (dev_idx >> HRDEV_TYPE_SHIFT);
169 if (dev_idx_inc[LowType]) /* Increasing indices => now done */
175 if (LowIndex == -1) {
176 DEBUGMSGTL(("host/hr_device", "... index out of range\n"));
177 return (MATCH_FAILED);
180 newname[HRDEV_ENTRY_NAME_LENGTH] = LowIndex;
181 memcpy((char *) name, (char *) newname,
182 ((int) vp->namelen + 1) * sizeof(oid));
183 *length = vp->namelen + 1;
185 *var_len = sizeof(long); /* default to 'long' results */
187 DEBUGMSGTL(("host/hr_device", "... get device stats "));
188 DEBUGMSGOID(("host/hr_device", name, *length));
189 DEBUGMSG(("host/hr_device", "\n"));
195 oid device_type_id[] = { 1, 3, 6, 1, 2, 1, 25, 3, 1, 99 }; /* hrDeviceType99 */
196 int device_type_len =
197 sizeof(device_type_id) / sizeof(device_type_id[0]);
200 /*********************
202 * System specific implementation functions
204 *********************/
208 var_hrdevice(struct variable *vp,
211 int exact, size_t * var_len, WriteMethod ** write_method)
215 static char string[100];
218 header_hrdevice(vp, name, length, exact, var_len, write_method);
219 if (dev_idx == MATCH_FAILED)
222 type = (dev_idx >> HRDEV_TYPE_SHIFT);
226 long_return = dev_idx;
227 return (u_char *) & long_return;
229 device_type_id[device_type_len - 1] = type;
230 *var_len = sizeof(device_type_id);
231 return (u_char *) device_type_id;
233 if (device_descr[type] != NULL) {
234 strncpy(string, ((*device_descr[type]) (dev_idx)),
236 string[ sizeof(string)-1] = 0;
241 sprintf(string, "a black box of some sort");
243 *var_len = strlen(string);
244 return (u_char *) string;
246 if (device_prodid[type] != NULL)
247 oid_p = ((*device_prodid[type]) (dev_idx, var_len));
250 *var_len = nullOidLen;
252 return (u_char *) oid_p;
254 if (device_status[type] != NULL)
255 long_return = ((*device_status[type]) (dev_idx));
260 long_return = 2; /* Assume running */
262 return (u_char *) & long_return;
264 if (device_errors[type] != NULL)
265 long_return = (*device_errors[type]) (dev_idx);
270 long_return = 0; /* Assume OK */
272 return (u_char *) & long_return;
274 DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_hrdevice\n",
281 /*********************
283 * Internal implementation functions
285 *********************/
292 * Find the first non-NULL initialisation function
295 while (current_type < HRDEV_TYPE_MAX &&
296 init_device[current_type] == NULL)
297 if (++current_type >= HRDEV_TYPE_MAX)
299 (*init_device[current_type]) ();
303 Get_Next_Device(void)
308 * Call the 'next device' function for the current
311 * TODO: save the necessary information about that device
313 if (current_type < HRDEV_TYPE_MAX && next_device[current_type] != NULL)
314 result = (*next_device[current_type]) ();
317 * No more devices of the current type.
318 * Try the next type (if any)
321 if (++current_type >= HRDEV_TYPE_MAX) {
326 return Get_Next_Device();