2 * radius_snmp.c Radius SNMP support
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 * Copyright 2000,2006 The FreeRADIUS server project
21 * Copyright 2000 Jochen Friedrich <jochen@scram.de>
24 #include <freeradius-devel/ident.h>
27 #include <freeradius-devel/autoconf.h>
31 #ifdef HAVE_NETINET_IN_H
32 # include <netinet/in.h>
37 #include <freeradius-devel/smux.h>
38 #include <freeradius-devel/radius_snmp.h>
39 #include <freeradius-devel/radiusd.h>
41 extern int need_reload;
44 * More globals (sigh);
49 #define RADACCOID 1,3,6,1,2,1,67,2,1,1,1
50 #define RADAUTHOID 1,3,6,1,2,1,67,1,1,1,1
51 #define RADIUSOID 1,3,6,1,4,1,3317,1,3,1
53 static const oid radacc_oid [] = { RADACCOID };
54 static const oid radauth_oid [] = { RADAUTHOID };
55 static const oid radius_oid [] = { RADIUSOID };
57 #define COUNTER ASN_COUNTER
58 #define INTEGER ASN_INTEGER
59 #define GAUGE ASN_GAUGE
60 #define TIMETICKS ASN_TIMETICKS
61 #define IPADDRESS ASN_IPADDRESS
62 #define STRING ASN_OCTET_STR
64 #define RADIUSACCSERVIDENT 1
65 #define RADIUSACCSERVUPTIME 2
66 #define RADIUSACCSERVRESETTIME 3
67 #define RADIUSACCSERVCONFIGRESET 4
68 #define RADIUSACCSERVTOTALREQUESTS 5
69 #define RADIUSACCSERVTOTALINVALIDREQUESTS 6
70 #define RADIUSACCSERVTOTALDUPREQUESTS 7
71 #define RADIUSACCSERVTOTALRESPONSES 8
72 #define RADIUSACCSERVTOTALMALFORMEDREQUESTS 9
73 #define RADIUSACCSERVTOTALBADAUTHENTICATORS 10
74 #define RADIUSACCSERVTOTALPACKETSDROPPED 11
75 #define RADIUSACCSERVTOTALNORECORDS 12
76 #define RADIUSACCSERVTOTALUNKNOWNTYPES 13
78 #define RADIUSACCCLIENTADDRESS 2
79 #define RADIUSACCCLIENTID 3
80 #define RADIUSACCSERVPACKETSDROPPED 4
81 #define RADIUSACCSERVREQUESTS 5
82 #define RADIUSACCSERVDUPREQUESTS 6
83 #define RADIUSACCSERVRESPONSES 7
84 #define RADIUSACCSERVBADAUTHENTICATORS 8
85 #define RADIUSACCSERVMALFORMEDREQUESTS 9
86 #define RADIUSACCSERVNORECORDS 10
87 #define RADIUSACCSERVUNKNOWNTYPES 11
89 #define RADIUSAUTHSERVIDENT 1
90 #define RADIUSAUTHSERVUPTIME 2
91 #define RADIUSAUTHSERVRESETTIME 3
92 #define RADIUSAUTHSERVCONFIGRESET 4
93 #define RADIUSAUTHSERVTOTALACCESSREQUESTS 5
94 #define RADIUSAUTHSERVTOTALINVALIDREQUESTS 6
95 #define RADIUSAUTHSERVTOTALDUPACCESSREQUESTS 7
96 #define RADIUSAUTHSERVTOTALACCESSACCEPTS 8
97 #define RADIUSAUTHSERVTOTALACCESSREJECTS 9
98 #define RADIUSAUTHSERVTOTALACCESSCHALLENGES 10
99 #define RADIUSAUTHSERVTOTALMALFORMEDACCESSREQUESTS 11
100 #define RADIUSAUTHSERVTOTALBADAUTHENTICATORS 12
101 #define RADIUSAUTHSERVTOTALPACKETSDROPPED 13
102 #define RADIUSAUTHSERVTOTALUNKNOWNTYPES 14
104 #define RADIUSAUTHCLIENTADDRESS 2
105 #define RADIUSAUTHCLIENTID 3
106 #define RADIUSAUTHSERVACCESSREQUESTS 4
107 #define RADIUSAUTHSERVDUPACCESSREQUESTS 5
108 #define RADIUSAUTHSERVACCESSACCEPTS 6
109 #define RADIUSAUTHSERVACCESSREJECTS 7
110 #define RADIUSAUTHSERVACCESSCHALLENGES 8
111 #define RADIUSAUTHSERVMALFORMEDACCESSREQUESTS 9
112 #define RADIUSAUTHSERVBADAUTHENTICATORS 10
113 #define RADIUSAUTHSERVPACKETSDROPPED 11
114 #define RADIUSAUTHSERVUNKNOWNTYPES 12
116 /* Hook functions. */
117 static const unsigned char *radAccServ(struct variable *vp,
122 WriteMethod **write_method);
123 static const unsigned char *radAccEntry(struct variable *vp,
128 WriteMethod **write_method);
129 static const u_char *radAuthServ(struct variable *vp,
134 WriteMethod **write_method);
135 static const unsigned char *radAuthEntry(struct variable *vp,
140 WriteMethod **write_method);
142 static const struct variable radiusacc_variables[] =
144 {RADIUSACCSERVIDENT, STRING, RONLY, radAccServ, 1, {1}},
145 {RADIUSACCSERVUPTIME, TIMETICKS, RONLY, radAccServ, 1, {2}},
146 {RADIUSACCSERVRESETTIME, TIMETICKS, RONLY, radAccServ, 1, {3}},
147 {RADIUSACCSERVCONFIGRESET, INTEGER, RWRITE, radAccServ, 1, {4}},
148 {RADIUSACCSERVTOTALREQUESTS, COUNTER, RONLY, radAccServ, 1, {5}},
149 {RADIUSACCSERVTOTALINVALIDREQUESTS, COUNTER, RONLY, radAccServ, 1, {6}},
150 {RADIUSACCSERVTOTALDUPREQUESTS, COUNTER, RONLY, radAccServ, 1, {7}},
151 {RADIUSACCSERVTOTALRESPONSES, COUNTER, RONLY, radAccServ, 1, {8}},
152 {RADIUSACCSERVTOTALMALFORMEDREQUESTS, COUNTER, RONLY, radAccServ, 1, {9}},
153 {RADIUSACCSERVTOTALBADAUTHENTICATORS, COUNTER, RONLY, radAccServ, 1, {10}},
154 {RADIUSACCSERVTOTALPACKETSDROPPED, COUNTER, RONLY, radAccServ, 1, {11}},
155 {RADIUSACCSERVTOTALNORECORDS, COUNTER, RONLY, radAccServ, 1, {12}},
156 {RADIUSACCSERVTOTALUNKNOWNTYPES, COUNTER, RONLY, radAccServ, 1, {13}},
157 {RADIUSACCCLIENTADDRESS, IPADDRESS, RONLY, radAccEntry, 3, {14,1,2}},
158 {RADIUSACCCLIENTID, STRING, RONLY, radAccEntry, 3, {14,1,3}},
159 {RADIUSACCSERVPACKETSDROPPED, COUNTER, RONLY, radAccEntry, 3, {14,1,4}},
160 {RADIUSACCSERVREQUESTS, COUNTER, RONLY, radAccEntry, 3, {14,1,5}},
161 {RADIUSACCSERVDUPREQUESTS, COUNTER, RONLY, radAccEntry, 3, {14,1,6}},
162 {RADIUSACCSERVRESPONSES, COUNTER, RONLY, radAccEntry, 3, {14,1,7}},
163 {RADIUSACCSERVBADAUTHENTICATORS, COUNTER, RONLY, radAccEntry, 3, {14,1,8}},
164 {RADIUSACCSERVMALFORMEDREQUESTS, COUNTER, RONLY, radAccEntry, 3, {14,1,9}},
165 {RADIUSACCSERVNORECORDS, COUNTER, RONLY, radAccEntry, 3, {14,1,10}},
166 {RADIUSACCSERVUNKNOWNTYPES, COUNTER, RONLY, radAccEntry, 3, {14,1,11}},
169 static const struct variable radiusauth_variables[] =
171 {RADIUSAUTHSERVIDENT, STRING, RONLY, radAuthServ, 1, {1}},
172 {RADIUSAUTHSERVUPTIME, TIMETICKS, RONLY, radAuthServ, 1, {2}},
173 {RADIUSAUTHSERVRESETTIME, TIMETICKS, RONLY, radAuthServ, 1, {3}},
174 {RADIUSAUTHSERVCONFIGRESET, INTEGER, RWRITE, radAuthServ, 1, {4}},
175 {RADIUSAUTHSERVTOTALACCESSREQUESTS, COUNTER, RONLY, radAuthServ, 1, {5}},
176 {RADIUSAUTHSERVTOTALINVALIDREQUESTS, COUNTER, RONLY, radAuthServ, 1, {6}},
177 {RADIUSAUTHSERVTOTALDUPACCESSREQUESTS, COUNTER, RONLY, radAuthServ, 1, {7}},
178 {RADIUSAUTHSERVTOTALACCESSACCEPTS, COUNTER, RONLY, radAuthServ, 1, {8}},
179 {RADIUSAUTHSERVTOTALACCESSREJECTS, COUNTER, RONLY, radAuthServ, 1, {9}},
180 {RADIUSAUTHSERVTOTALACCESSCHALLENGES, COUNTER, RONLY, radAuthServ, 1, {10}},
181 {RADIUSAUTHSERVTOTALMALFORMEDACCESSREQUESTS, COUNTER, RONLY, radAuthServ, 1, {11}},
182 {RADIUSAUTHSERVTOTALBADAUTHENTICATORS, COUNTER, RONLY, radAuthServ, 1, {12}},
183 {RADIUSAUTHSERVTOTALPACKETSDROPPED, COUNTER, RONLY, radAuthServ, 1, {13}},
184 {RADIUSAUTHSERVTOTALUNKNOWNTYPES, COUNTER, RONLY, radAuthServ, 1, {14}},
185 {RADIUSAUTHCLIENTADDRESS, IPADDRESS, RONLY, radAuthEntry, 3, {15,1,2}},
186 {RADIUSAUTHCLIENTID, STRING, RONLY, radAuthEntry, 3, {15,1,3}},
187 {RADIUSAUTHSERVACCESSREQUESTS, COUNTER, RONLY, radAuthEntry, 3, {15,1,4}},
188 {RADIUSAUTHSERVDUPACCESSREQUESTS, COUNTER, RONLY, radAuthEntry, 3, {15,1,5}},
189 {RADIUSAUTHSERVACCESSACCEPTS, COUNTER, RONLY, radAuthEntry, 3, {15,1,6}},
190 {RADIUSAUTHSERVACCESSREJECTS, COUNTER, RONLY, radAuthEntry, 3, {15,1,7}},
191 {RADIUSAUTHSERVACCESSCHALLENGES, COUNTER, RONLY, radAuthEntry, 3, {15,1,8}},
192 {RADIUSAUTHSERVMALFORMEDACCESSREQUESTS, COUNTER, RONLY, radAuthEntry, 3, {15,1,9}},
193 {RADIUSAUTHSERVBADAUTHENTICATORS, COUNTER, RONLY, radAuthEntry, 3, {15,1,10}},
194 {RADIUSAUTHSERVPACKETSDROPPED, COUNTER, RONLY, radAuthEntry, 3, {15,1,11}},
195 {RADIUSAUTHSERVUNKNOWNTYPES, COUNTER, RONLY, radAuthEntry, 3, {15,1,12}},
199 get_client(struct variable *v, oid objid[], size_t *objid_len, int exact)
204 len = *objid_len - v->namelen;
206 if (!mainconfig.clients)
210 /* Check the length. */
213 if (objid[v->namelen] == 0)
216 i = objid[v->namelen]-1;
218 return client_findbynumber(mainconfig.clients, i);
220 i = objid[v->namelen]-1;
221 *objid_len = v->namelen + 1;
222 if (!len || (objid[v->namelen] == 0)) {
224 return mainconfig.clients;
227 c = client_findbynumber(mainconfig.clients, i);
235 radServReset(int action, u_char *var_val, u_char var_val_type,
236 size_t var_val_len, UNUSED const unsigned char *statP,
237 UNUSED oid *name, UNUSED size_t name_len)
240 int big = SNMP_MAX_LEN;
244 if (var_val_type != INTEGER)
245 return SNMP_ERR_WRONGTYPE;
246 if (var_val_len != sizeof (long))
247 return SNMP_ERR_WRONGLENGTH;
248 if (! asn_parse_int(var_val, &big, &var_val_type, &i, sizeof(long)))
249 return SNMP_ERR_WRONGENCODING;
251 return SNMP_ERR_WRONGVALUE;
259 return SNMP_ERR_GENERR;
261 return SNMP_ERR_NOERROR;
264 static const unsigned char *
265 radAccServ(struct variable *vp, oid *name, size_t *length, int exact,
266 size_t *var_len, WriteMethod **write_method) {
270 /* check whether the instance identifier is valid */
271 if (smux_header_generic(vp, name, length, exact, var_len,
272 write_method) == MATCH_FAILED) {
276 /* return the current value of the variable */
278 case RADIUSACCSERVIDENT:
279 *var_len = strlen(rad_snmp.acct.ident);
280 return (const unsigned char *) rad_snmp.acct.ident;
282 case RADIUSACCSERVUPTIME:
283 rad_snmp.acct.uptime = (time(NULL) - rad_snmp.acct.start_time) * 100;
284 *var_len = sizeof(int32_t);
285 return (unsigned char *) &rad_snmp.acct.uptime;
287 case RADIUSACCSERVRESETTIME:
288 rad_snmp.acct.reset_time = (time(NULL) - rad_snmp.acct.last_reset_time) * 100;
289 *var_len = sizeof(int32_t);
290 return (unsigned char *) &rad_snmp.acct.reset_time;
292 case RADIUSACCSERVCONFIGRESET:
293 *write_method = radServReset;
295 return (unsigned char *) &result;
297 case RADIUSACCSERVTOTALREQUESTS:
298 *var_len = sizeof(int32_t);
299 return (unsigned char *) &rad_snmp.acct.total_requests;
301 case RADIUSACCSERVTOTALINVALIDREQUESTS:
302 *var_len = sizeof(int32_t);
303 return (unsigned char *) &rad_snmp.acct.total_invalid_requests;
305 case RADIUSACCSERVTOTALDUPREQUESTS:
306 *var_len = sizeof(int32_t);
307 return (unsigned char *) &rad_snmp.acct.total_dup_requests;
309 case RADIUSACCSERVTOTALRESPONSES:
310 *var_len = sizeof(int32_t);
311 return (unsigned char *) &rad_snmp.acct.total_responses;
313 case RADIUSACCSERVTOTALMALFORMEDREQUESTS:
314 *var_len = sizeof(int32_t);
315 return (unsigned char *) &rad_snmp.acct.total_malformed_requests;
317 case RADIUSACCSERVTOTALBADAUTHENTICATORS:
318 *var_len = sizeof(int32_t);
319 return (unsigned char *) &rad_snmp.acct.total_bad_authenticators;
321 case RADIUSACCSERVTOTALPACKETSDROPPED:
322 *var_len = sizeof(int32_t);
323 return (unsigned char *) &rad_snmp.acct.total_packets_dropped;
325 case RADIUSACCSERVTOTALNORECORDS:
326 *var_len = sizeof(int32_t);
327 return (unsigned char *) &rad_snmp.acct.total_no_records;
329 case RADIUSACCSERVTOTALUNKNOWNTYPES:
330 *var_len = sizeof(int32_t);
331 return (unsigned char *) &rad_snmp.acct.total_unknown_types;
338 static const unsigned char *
339 radAccEntry(struct variable *vp, oid *name, size_t *length, int exact,
340 size_t *var_len, WriteMethod **write_method) {
344 *write_method = NULL; /* table is read only */
345 c = get_client(vp, name, length, exact);
349 /* return the current value of the variable */
352 case RADIUSACCCLIENTADDRESS:
353 *var_len = sizeof(c->ipaddr);
354 return (unsigned char *)&(c->ipaddr);
356 case RADIUSACCCLIENTID:
357 if (c->shortname && c->shortname[0]) {
358 *var_len = strlen(c->shortname);
361 *var_len = strlen(c->longname);
364 case RADIUSACCSERVPACKETSDROPPED:
365 return (unsigned char *) NULL;
367 case RADIUSACCSERVREQUESTS:
368 return (unsigned char *) NULL;
370 case RADIUSACCSERVDUPREQUESTS:
371 return (unsigned char *) NULL;
373 case RADIUSACCSERVRESPONSES:
374 return (unsigned char *) NULL;
376 case RADIUSACCSERVBADAUTHENTICATORS:
377 return (unsigned char *) NULL;
379 case RADIUSACCSERVMALFORMEDREQUESTS:
380 return (unsigned char *) NULL;
382 case RADIUSACCSERVNORECORDS:
383 return (unsigned char *) NULL;
385 case RADIUSACCSERVUNKNOWNTYPES:
386 return (unsigned char *) NULL;
392 static const unsigned char *
393 radAuthServ(struct variable *vp, oid *name, size_t *length, int exact,
394 size_t *var_len, WriteMethod **write_method) {
397 /* check whether the instance identifier is valid */
399 if (smux_header_generic(vp, name, length, exact, var_len,
400 write_method) == MATCH_FAILED) {
404 /* return the current value of the variable */
408 case RADIUSAUTHSERVIDENT:
409 *var_len = strlen(rad_snmp.auth.ident);
410 return (const unsigned char *) rad_snmp.auth.ident;
412 case RADIUSAUTHSERVUPTIME:
413 rad_snmp.auth.uptime = (time(NULL) - rad_snmp.auth.start_time) * 100;
414 *var_len = sizeof(int32_t);
415 return (unsigned char *) &rad_snmp.auth.uptime;
417 case RADIUSAUTHSERVRESETTIME:
418 rad_snmp.auth.reset_time = (time(NULL) - rad_snmp.auth.last_reset_time) * 100;
419 *var_len = sizeof(int32_t);
420 return (unsigned char *) &rad_snmp.auth.reset_time;
422 case RADIUSAUTHSERVCONFIGRESET:
423 *write_method = radServReset;
425 return (unsigned char *) &result;
427 case RADIUSAUTHSERVTOTALACCESSREQUESTS:
428 *var_len = sizeof(int32_t);
429 return (unsigned char *) &rad_snmp.auth.total_requests;
431 case RADIUSAUTHSERVTOTALINVALIDREQUESTS:
432 *var_len = sizeof(int32_t);
433 return (unsigned char *) &rad_snmp.auth.total_invalid_requests;
435 case RADIUSAUTHSERVTOTALDUPACCESSREQUESTS:
436 *var_len = sizeof(int32_t);
437 return (unsigned char *) &rad_snmp.auth.total_dup_requests;
439 case RADIUSAUTHSERVTOTALACCESSACCEPTS:
440 *var_len = sizeof(int32_t);
441 return (unsigned char *) &rad_snmp.auth.total_access_accepts;
443 case RADIUSAUTHSERVTOTALACCESSREJECTS:
444 *var_len = sizeof(int32_t);
445 return (unsigned char *) &rad_snmp.auth.total_access_rejects;
447 case RADIUSAUTHSERVTOTALACCESSCHALLENGES:
448 *var_len = sizeof(int32_t);
449 return (unsigned char *) &rad_snmp.auth.total_access_challenges;
451 case RADIUSAUTHSERVTOTALMALFORMEDACCESSREQUESTS:
452 *var_len = sizeof(int32_t);
453 return (unsigned char *) &rad_snmp.auth.total_malformed_requests;
455 case RADIUSAUTHSERVTOTALBADAUTHENTICATORS:
456 *var_len = sizeof(int32_t);
457 return (unsigned char *) &rad_snmp.auth.total_bad_authenticators;
459 case RADIUSAUTHSERVTOTALPACKETSDROPPED:
460 *var_len = sizeof(int32_t);
461 return (unsigned char *) &rad_snmp.auth.total_packets_dropped;
463 case RADIUSAUTHSERVTOTALUNKNOWNTYPES:
464 *var_len = sizeof(int32_t);
465 return (unsigned char *) &rad_snmp.auth.total_unknown_types;
472 static const unsigned char *
473 radAuthEntry(struct variable *vp, oid *name, size_t *length, int exact,
474 size_t *var_len, WriteMethod **write_method) {
478 *write_method = NULL; /* table is read only */
479 c = get_client(vp, name, length, exact);
483 /* return the current value of the variable */
487 case RADIUSAUTHCLIENTADDRESS:
488 *var_len = sizeof(c->ipaddr);
489 return (unsigned char *)&(c->ipaddr);
491 case RADIUSAUTHCLIENTID:
492 if (c->shortname && c->shortname[0]) {
493 *var_len = strlen(c->shortname);
496 *var_len = strlen(c->longname);
499 case RADIUSAUTHSERVACCESSREQUESTS:
500 return (unsigned char *) NULL;
502 case RADIUSAUTHSERVDUPACCESSREQUESTS:
503 return (unsigned char *) NULL;
505 case RADIUSAUTHSERVACCESSACCEPTS:
506 return (unsigned char *) NULL;
508 case RADIUSAUTHSERVACCESSREJECTS:
509 return (unsigned char *) NULL;
511 case RADIUSAUTHSERVACCESSCHALLENGES:
512 return (unsigned char *) NULL;
514 case RADIUSAUTHSERVMALFORMEDACCESSREQUESTS:
515 return (unsigned char *) NULL;
517 case RADIUSAUTHSERVBADAUTHENTICATORS:
518 return (unsigned char *) NULL;
520 case RADIUSAUTHSERVPACKETSDROPPED:
521 return (unsigned char *) NULL;
523 case RADIUSAUTHSERVUNKNOWNTYPES:
524 return (unsigned char *) NULL;
530 static const CONF_PARSER snmp_config[] = {
531 { "smux_password", PW_TYPE_STRING_PTR, 0, &rad_snmp.smux_password, "" },
532 { "snmp_write_access", PW_TYPE_BOOLEAN, 0, &rad_snmp.snmp_write_access, "no" },
533 { NULL, -1, 0, NULL, NULL }
537 /* Register RADIUS MIBs. */
539 radius_snmp_init (void) {
544 * Initialize the RADIUS SNMP data structure.
546 memset(&rad_snmp, 0, sizeof(rad_snmp));
548 rad_snmp.auth.ident = radiusd_version;
549 rad_snmp.acct.ident = radiusd_version;
551 rad_snmp.smux_event = SMUX_NONE;
552 rad_snmp.smux_password = NULL;
553 rad_snmp.snmp_write_access = FALSE;
554 rad_snmp.smux_fd = -1;
555 rad_snmp.smux_max_failures = 3; /* FIXME! get from config */
556 rad_snmp.smux_failures = 0;
559 * We really should get better clock resolution..
561 rad_snmp.auth.start_time = time(NULL);
562 rad_snmp.auth.last_reset_time = rad_snmp.auth.start_time;
564 rad_snmp.acct.start_time = rad_snmp.auth.start_time;
565 rad_snmp.acct.last_reset_time = rad_snmp.auth.start_time;
568 * Parse the SNMP configuration information.
570 cs = cf_section_find(NULL);
572 cf_section_parse(cs, NULL, snmp_config);
575 * Do SMUX initialization.
577 smux_init (radius_oid, sizeof (radius_oid) / sizeof (oid));
578 REGISTER_MIB("mibII/radius-acc-server", radiusacc_variables, variable, radacc_oid);
579 REGISTER_MIB("mibII/radius-auth-server", radiusauth_variables, variable, radauth_oid);
583 #endif /* WITH_SNMP */