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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 * Copyright 2000 The FreeRADIUS server project
21 * Copyright 2000 Jochen Friedrich <jochen@scram.de>
24 static const char rcsid[] =
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>
40 #include <freeradius-devel/conffile.h>
42 extern int need_reload;
45 * More globals (sigh);
50 #define RADACCOID 1,3,6,1,2,1,67,2,1,1,1
51 #define RADAUTHOID 1,3,6,1,2,1,67,1,1,1,1
52 #define RADIUSOID 1,3,6,1,4,1,3317,1,3,1
54 static const oid radacc_oid [] = { RADACCOID };
55 static const oid radauth_oid [] = { RADAUTHOID };
56 static const oid radius_oid [] = { RADIUSOID };
58 #define COUNTER ASN_COUNTER
59 #define INTEGER ASN_INTEGER
60 #define GAUGE ASN_GAUGE
61 #define TIMETICKS ASN_TIMETICKS
62 #define IPADDRESS ASN_IPADDRESS
63 #define STRING ASN_OCTET_STR
65 #define RADIUSACCSERVIDENT 1
66 #define RADIUSACCSERVUPTIME 2
67 #define RADIUSACCSERVRESETTIME 3
68 #define RADIUSACCSERVCONFIGRESET 4
69 #define RADIUSACCSERVTOTALREQUESTS 5
70 #define RADIUSACCSERVTOTALINVALIDREQUESTS 6
71 #define RADIUSACCSERVTOTALDUPREQUESTS 7
72 #define RADIUSACCSERVTOTALRESPONSES 8
73 #define RADIUSACCSERVTOTALMALFORMEDREQUESTS 9
74 #define RADIUSACCSERVTOTALBADAUTHENTICATORS 10
75 #define RADIUSACCSERVTOTALPACKETSDROPPED 11
76 #define RADIUSACCSERVTOTALNORECORDS 12
77 #define RADIUSACCSERVTOTALUNKNOWNTYPES 13
79 #define RADIUSACCCLIENTADDRESS 2
80 #define RADIUSACCCLIENTID 3
81 #define RADIUSACCSERVPACKETSDROPPED 4
82 #define RADIUSACCSERVREQUESTS 5
83 #define RADIUSACCSERVDUPREQUESTS 6
84 #define RADIUSACCSERVRESPONSES 7
85 #define RADIUSACCSERVBADAUTHENTICATORS 8
86 #define RADIUSACCSERVMALFORMEDREQUESTS 9
87 #define RADIUSACCSERVNORECORDS 10
88 #define RADIUSACCSERVUNKNOWNTYPES 11
90 #define RADIUSAUTHSERVIDENT 1
91 #define RADIUSAUTHSERVUPTIME 2
92 #define RADIUSAUTHSERVRESETTIME 3
93 #define RADIUSAUTHSERVCONFIGRESET 4
94 #define RADIUSAUTHSERVTOTALACCESSREQUESTS 5
95 #define RADIUSAUTHSERVTOTALINVALIDREQUESTS 6
96 #define RADIUSAUTHSERVTOTALDUPACCESSREQUESTS 7
97 #define RADIUSAUTHSERVTOTALACCESSACCEPTS 8
98 #define RADIUSAUTHSERVTOTALACCESSREJECTS 9
99 #define RADIUSAUTHSERVTOTALACCESSCHALLENGES 10
100 #define RADIUSAUTHSERVTOTALMALFORMEDACCESSREQUESTS 11
101 #define RADIUSAUTHSERVTOTALBADAUTHENTICATORS 12
102 #define RADIUSAUTHSERVTOTALPACKETSDROPPED 13
103 #define RADIUSAUTHSERVTOTALUNKNOWNTYPES 14
105 #define RADIUSAUTHCLIENTADDRESS 2
106 #define RADIUSAUTHCLIENTID 3
107 #define RADIUSAUTHSERVACCESSREQUESTS 4
108 #define RADIUSAUTHSERVDUPACCESSREQUESTS 5
109 #define RADIUSAUTHSERVACCESSACCEPTS 6
110 #define RADIUSAUTHSERVACCESSREJECTS 7
111 #define RADIUSAUTHSERVACCESSCHALLENGES 8
112 #define RADIUSAUTHSERVMALFORMEDACCESSREQUESTS 9
113 #define RADIUSAUTHSERVBADAUTHENTICATORS 10
114 #define RADIUSAUTHSERVPACKETSDROPPED 11
115 #define RADIUSAUTHSERVUNKNOWNTYPES 12
117 /* Hook functions. */
118 static const unsigned char *radAccServ(struct variable *vp,
123 WriteMethod **write_method);
124 static const unsigned char *radAccEntry(struct variable *vp,
129 WriteMethod **write_method);
130 static const u_char *radAuthServ(struct variable *vp,
135 WriteMethod **write_method);
136 static const unsigned char *radAuthEntry(struct variable *vp,
141 WriteMethod **write_method);
143 static const struct variable radiusacc_variables[] =
145 {RADIUSACCSERVIDENT, STRING, RONLY, radAccServ, 1, {1}},
146 {RADIUSACCSERVUPTIME, TIMETICKS, RONLY, radAccServ, 1, {2}},
147 {RADIUSACCSERVRESETTIME, TIMETICKS, RONLY, radAccServ, 1, {3}},
148 {RADIUSACCSERVCONFIGRESET, INTEGER, RWRITE, radAccServ, 1, {4}},
149 {RADIUSACCSERVTOTALREQUESTS, COUNTER, RONLY, radAccServ, 1, {5}},
150 {RADIUSACCSERVTOTALINVALIDREQUESTS, COUNTER, RONLY, radAccServ, 1, {6}},
151 {RADIUSACCSERVTOTALDUPREQUESTS, COUNTER, RONLY, radAccServ, 1, {7}},
152 {RADIUSACCSERVTOTALRESPONSES, COUNTER, RONLY, radAccServ, 1, {8}},
153 {RADIUSACCSERVTOTALMALFORMEDREQUESTS, COUNTER, RONLY, radAccServ, 1, {9}},
154 {RADIUSACCSERVTOTALBADAUTHENTICATORS, COUNTER, RONLY, radAccServ, 1, {10}},
155 {RADIUSACCSERVTOTALPACKETSDROPPED, COUNTER, RONLY, radAccServ, 1, {11}},
156 {RADIUSACCSERVTOTALNORECORDS, COUNTER, RONLY, radAccServ, 1, {12}},
157 {RADIUSACCSERVTOTALUNKNOWNTYPES, COUNTER, RONLY, radAccServ, 1, {13}},
158 {RADIUSACCCLIENTADDRESS, IPADDRESS, RONLY, radAccEntry, 3, {14,1,2}},
159 {RADIUSACCCLIENTID, STRING, RONLY, radAccEntry, 3, {14,1,3}},
160 {RADIUSACCSERVPACKETSDROPPED, COUNTER, RONLY, radAccEntry, 3, {14,1,4}},
161 {RADIUSACCSERVREQUESTS, COUNTER, RONLY, radAccEntry, 3, {14,1,5}},
162 {RADIUSACCSERVDUPREQUESTS, COUNTER, RONLY, radAccEntry, 3, {14,1,6}},
163 {RADIUSACCSERVRESPONSES, COUNTER, RONLY, radAccEntry, 3, {14,1,7}},
164 {RADIUSACCSERVBADAUTHENTICATORS, COUNTER, RONLY, radAccEntry, 3, {14,1,8}},
165 {RADIUSACCSERVMALFORMEDREQUESTS, COUNTER, RONLY, radAccEntry, 3, {14,1,9}},
166 {RADIUSACCSERVNORECORDS, COUNTER, RONLY, radAccEntry, 3, {14,1,10}},
167 {RADIUSACCSERVUNKNOWNTYPES, COUNTER, RONLY, radAccEntry, 3, {14,1,11}},
170 static const struct variable radiusauth_variables[] =
172 {RADIUSAUTHSERVIDENT, STRING, RONLY, radAuthServ, 1, {1}},
173 {RADIUSAUTHSERVUPTIME, TIMETICKS, RONLY, radAuthServ, 1, {2}},
174 {RADIUSAUTHSERVRESETTIME, TIMETICKS, RONLY, radAuthServ, 1, {3}},
175 {RADIUSAUTHSERVCONFIGRESET, INTEGER, RWRITE, radAuthServ, 1, {4}},
176 {RADIUSAUTHSERVTOTALACCESSREQUESTS, COUNTER, RONLY, radAuthServ, 1, {5}},
177 {RADIUSAUTHSERVTOTALINVALIDREQUESTS, COUNTER, RONLY, radAuthServ, 1, {6}},
178 {RADIUSAUTHSERVTOTALDUPACCESSREQUESTS, COUNTER, RONLY, radAuthServ, 1, {7}},
179 {RADIUSAUTHSERVTOTALACCESSACCEPTS, COUNTER, RONLY, radAuthServ, 1, {8}},
180 {RADIUSAUTHSERVTOTALACCESSREJECTS, COUNTER, RONLY, radAuthServ, 1, {9}},
181 {RADIUSAUTHSERVTOTALACCESSCHALLENGES, COUNTER, RONLY, radAuthServ, 1, {10}},
182 {RADIUSAUTHSERVTOTALMALFORMEDACCESSREQUESTS, COUNTER, RONLY, radAuthServ, 1, {11}},
183 {RADIUSAUTHSERVTOTALBADAUTHENTICATORS, COUNTER, RONLY, radAuthServ, 1, {12}},
184 {RADIUSAUTHSERVTOTALPACKETSDROPPED, COUNTER, RONLY, radAuthServ, 1, {13}},
185 {RADIUSAUTHSERVTOTALUNKNOWNTYPES, COUNTER, RONLY, radAuthServ, 1, {14}},
186 {RADIUSAUTHCLIENTADDRESS, IPADDRESS, RONLY, radAuthEntry, 3, {15,1,2}},
187 {RADIUSAUTHCLIENTID, STRING, RONLY, radAuthEntry, 3, {15,1,3}},
188 {RADIUSAUTHSERVACCESSREQUESTS, COUNTER, RONLY, radAuthEntry, 3, {15,1,4}},
189 {RADIUSAUTHSERVDUPACCESSREQUESTS, COUNTER, RONLY, radAuthEntry, 3, {15,1,5}},
190 {RADIUSAUTHSERVACCESSACCEPTS, COUNTER, RONLY, radAuthEntry, 3, {15,1,6}},
191 {RADIUSAUTHSERVACCESSREJECTS, COUNTER, RONLY, radAuthEntry, 3, {15,1,7}},
192 {RADIUSAUTHSERVACCESSCHALLENGES, COUNTER, RONLY, radAuthEntry, 3, {15,1,8}},
193 {RADIUSAUTHSERVMALFORMEDACCESSREQUESTS, COUNTER, RONLY, radAuthEntry, 3, {15,1,9}},
194 {RADIUSAUTHSERVBADAUTHENTICATORS, COUNTER, RONLY, radAuthEntry, 3, {15,1,10}},
195 {RADIUSAUTHSERVPACKETSDROPPED, COUNTER, RONLY, radAuthEntry, 3, {15,1,11}},
196 {RADIUSAUTHSERVUNKNOWNTYPES, COUNTER, RONLY, radAuthEntry, 3, {15,1,12}},
200 get_client(struct variable *v, oid objid[], size_t *objid_len, int exact)
205 len = *objid_len - v->namelen;
207 if (!mainconfig.clients)
211 /* Check the length. */
214 if (objid[v->namelen] == 0)
217 i = objid[v->namelen]-1;
219 return client_findbynumber(mainconfig.clients, i);
221 i = objid[v->namelen]-1;
222 *objid_len = v->namelen + 1;
223 if (!len || (objid[v->namelen] == 0)) {
225 return mainconfig.clients;
228 c = client_findbynumber(mainconfig.clients, i);
236 radServReset(int action, u_char *var_val, u_char var_val_type,
237 size_t var_val_len, UNUSED const unsigned char *statP,
238 UNUSED oid *name, UNUSED size_t name_len)
241 int big = SNMP_MAX_LEN;
245 if (var_val_type != INTEGER)
246 return SNMP_ERR_WRONGTYPE;
247 if (var_val_len != sizeof (long))
248 return SNMP_ERR_WRONGLENGTH;
249 if (! asn_parse_int(var_val, &big, &var_val_type, &i, sizeof(long)))
250 return SNMP_ERR_WRONGENCODING;
252 return SNMP_ERR_WRONGVALUE;
260 return SNMP_ERR_GENERR;
262 return SNMP_ERR_NOERROR;
265 static const unsigned char *
266 radAccServ(struct variable *vp, oid *name, size_t *length, int exact,
267 size_t *var_len, WriteMethod **write_method) {
271 /* check whether the instance identifier is valid */
272 if (smux_header_generic(vp, name, length, exact, var_len,
273 write_method) == MATCH_FAILED) {
277 /* return the current value of the variable */
279 case RADIUSACCSERVIDENT:
280 *var_len = strlen(rad_snmp.acct.ident);
281 return (const unsigned char *) rad_snmp.acct.ident;
283 case RADIUSACCSERVUPTIME:
284 rad_snmp.acct.uptime = (time(NULL) - rad_snmp.acct.start_time) * 100;
285 *var_len = sizeof(int32_t);
286 return (unsigned char *) &rad_snmp.acct.uptime;
288 case RADIUSACCSERVRESETTIME:
289 rad_snmp.acct.reset_time = (time(NULL) - rad_snmp.acct.last_reset_time) * 100;
290 *var_len = sizeof(int32_t);
291 return (unsigned char *) &rad_snmp.acct.reset_time;
293 case RADIUSACCSERVCONFIGRESET:
294 *write_method = radServReset;
296 return (unsigned char *) &result;
298 case RADIUSACCSERVTOTALREQUESTS:
299 *var_len = sizeof(int32_t);
300 return (unsigned char *) &rad_snmp.acct.total_requests;
302 case RADIUSACCSERVTOTALINVALIDREQUESTS:
303 *var_len = sizeof(int32_t);
304 return (unsigned char *) &rad_snmp.acct.total_invalid_requests;
306 case RADIUSACCSERVTOTALDUPREQUESTS:
307 *var_len = sizeof(int32_t);
308 return (unsigned char *) &rad_snmp.acct.total_dup_requests;
310 case RADIUSACCSERVTOTALRESPONSES:
311 *var_len = sizeof(int32_t);
312 return (unsigned char *) &rad_snmp.acct.total_responses;
314 case RADIUSACCSERVTOTALMALFORMEDREQUESTS:
315 *var_len = sizeof(int32_t);
316 return (unsigned char *) &rad_snmp.acct.total_malformed_requests;
318 case RADIUSACCSERVTOTALBADAUTHENTICATORS:
319 *var_len = sizeof(int32_t);
320 return (unsigned char *) &rad_snmp.acct.total_bad_authenticators;
322 case RADIUSACCSERVTOTALPACKETSDROPPED:
323 *var_len = sizeof(int32_t);
324 return (unsigned char *) &rad_snmp.acct.total_packets_dropped;
326 case RADIUSACCSERVTOTALNORECORDS:
327 *var_len = sizeof(int32_t);
328 return (unsigned char *) &rad_snmp.acct.total_no_records;
330 case RADIUSACCSERVTOTALUNKNOWNTYPES:
331 *var_len = sizeof(int32_t);
332 return (unsigned char *) &rad_snmp.acct.total_unknown_types;
339 static const unsigned char *
340 radAccEntry(struct variable *vp, oid *name, size_t *length, int exact,
341 size_t *var_len, WriteMethod **write_method) {
345 *write_method = NULL; /* table is read only */
346 c = get_client(vp, name, length, exact);
350 /* return the current value of the variable */
353 case RADIUSACCCLIENTADDRESS:
354 *var_len = sizeof(c->ipaddr);
355 return (unsigned char *)&(c->ipaddr);
357 case RADIUSACCCLIENTID:
358 if (strlen(c->shortname)) {
359 *var_len = strlen(c->shortname);
362 *var_len = strlen(c->longname);
365 case RADIUSACCSERVPACKETSDROPPED:
366 return (unsigned char *) NULL;
368 case RADIUSACCSERVREQUESTS:
369 return (unsigned char *) NULL;
371 case RADIUSACCSERVDUPREQUESTS:
372 return (unsigned char *) NULL;
374 case RADIUSACCSERVRESPONSES:
375 return (unsigned char *) NULL;
377 case RADIUSACCSERVBADAUTHENTICATORS:
378 return (unsigned char *) NULL;
380 case RADIUSACCSERVMALFORMEDREQUESTS:
381 return (unsigned char *) NULL;
383 case RADIUSACCSERVNORECORDS:
384 return (unsigned char *) NULL;
386 case RADIUSACCSERVUNKNOWNTYPES:
387 return (unsigned char *) NULL;
393 static const unsigned char *
394 radAuthServ(struct variable *vp, oid *name, size_t *length, int exact,
395 size_t *var_len, WriteMethod **write_method) {
398 /* check whether the instance identifier is valid */
400 if (smux_header_generic(vp, name, length, exact, var_len,
401 write_method) == MATCH_FAILED) {
405 /* return the current value of the variable */
409 case RADIUSAUTHSERVIDENT:
410 *var_len = strlen(rad_snmp.auth.ident);
411 return (const unsigned char *) rad_snmp.auth.ident;
413 case RADIUSAUTHSERVUPTIME:
414 rad_snmp.auth.uptime = (time(NULL) - rad_snmp.auth.start_time) * 100;
415 *var_len = sizeof(int32_t);
416 return (unsigned char *) &rad_snmp.auth.uptime;
418 case RADIUSAUTHSERVRESETTIME:
419 rad_snmp.auth.reset_time = (time(NULL) - rad_snmp.auth.last_reset_time) * 100;
420 *var_len = sizeof(int32_t);
421 return (unsigned char *) &rad_snmp.auth.reset_time;
423 case RADIUSAUTHSERVCONFIGRESET:
424 *write_method = radServReset;
426 return (unsigned char *) &result;
428 case RADIUSAUTHSERVTOTALACCESSREQUESTS:
429 *var_len = sizeof(int32_t);
430 return (unsigned char *) &rad_snmp.auth.total_requests;
432 case RADIUSAUTHSERVTOTALINVALIDREQUESTS:
433 *var_len = sizeof(int32_t);
434 return (unsigned char *) &rad_snmp.auth.total_invalid_requests;
436 case RADIUSAUTHSERVTOTALDUPACCESSREQUESTS:
437 *var_len = sizeof(int32_t);
438 return (unsigned char *) &rad_snmp.auth.total_dup_requests;
440 case RADIUSAUTHSERVTOTALACCESSACCEPTS:
441 *var_len = sizeof(int32_t);
442 return (unsigned char *) &rad_snmp.auth.total_access_accepts;
444 case RADIUSAUTHSERVTOTALACCESSREJECTS:
445 *var_len = sizeof(int32_t);
446 return (unsigned char *) &rad_snmp.auth.total_access_rejects;
448 case RADIUSAUTHSERVTOTALACCESSCHALLENGES:
449 *var_len = sizeof(int32_t);
450 return (unsigned char *) &rad_snmp.auth.total_access_challenges;
452 case RADIUSAUTHSERVTOTALMALFORMEDACCESSREQUESTS:
453 *var_len = sizeof(int32_t);
454 return (unsigned char *) &rad_snmp.auth.total_malformed_requests;
456 case RADIUSAUTHSERVTOTALBADAUTHENTICATORS:
457 *var_len = sizeof(int32_t);
458 return (unsigned char *) &rad_snmp.auth.total_bad_authenticators;
460 case RADIUSAUTHSERVTOTALPACKETSDROPPED:
461 *var_len = sizeof(int32_t);
462 return (unsigned char *) &rad_snmp.auth.total_packets_dropped;
464 case RADIUSAUTHSERVTOTALUNKNOWNTYPES:
465 *var_len = sizeof(int32_t);
466 return (unsigned char *) &rad_snmp.auth.total_unknown_types;
473 static const unsigned char *
474 radAuthEntry(struct variable *vp, oid *name, size_t *length, int exact,
475 size_t *var_len, WriteMethod **write_method) {
479 *write_method = NULL; /* table is read only */
480 c = get_client(vp, name, length, exact);
484 /* return the current value of the variable */
488 case RADIUSAUTHCLIENTADDRESS:
489 *var_len = sizeof(c->ipaddr);
490 return (unsigned char *)&(c->ipaddr);
492 case RADIUSAUTHCLIENTID:
493 if (strlen(c->shortname)) {
494 *var_len = strlen(c->shortname);
497 *var_len = strlen(c->longname);
500 case RADIUSAUTHSERVACCESSREQUESTS:
501 return (unsigned char *) NULL;
503 case RADIUSAUTHSERVDUPACCESSREQUESTS:
504 return (unsigned char *) NULL;
506 case RADIUSAUTHSERVACCESSACCEPTS:
507 return (unsigned char *) NULL;
509 case RADIUSAUTHSERVACCESSREJECTS:
510 return (unsigned char *) NULL;
512 case RADIUSAUTHSERVACCESSCHALLENGES:
513 return (unsigned char *) NULL;
515 case RADIUSAUTHSERVMALFORMEDACCESSREQUESTS:
516 return (unsigned char *) NULL;
518 case RADIUSAUTHSERVBADAUTHENTICATORS:
519 return (unsigned char *) NULL;
521 case RADIUSAUTHSERVPACKETSDROPPED:
522 return (unsigned char *) NULL;
524 case RADIUSAUTHSERVUNKNOWNTYPES:
525 return (unsigned char *) NULL;
531 static const CONF_PARSER snmp_config[] = {
532 { "smux_password", PW_TYPE_STRING_PTR, 0, &rad_snmp.smux_password, "" },
533 { "snmp_write_access", PW_TYPE_BOOLEAN, 0, &rad_snmp.snmp_write_access, "no" },
534 { NULL, -1, 0, NULL, NULL }
538 /* Register RADIUS MIBs. */
540 radius_snmp_init (void) {
545 * Initialize the RADIUS SNMP data structure.
547 memset(&rad_snmp, 0, sizeof(rad_snmp));
549 rad_snmp.auth.ident = radiusd_version;
550 rad_snmp.acct.ident = radiusd_version;
552 rad_snmp.smux_event = SMUX_NONE;
553 rad_snmp.smux_password = NULL;
554 rad_snmp.snmp_write_access = FALSE;
555 rad_snmp.smux_fd = -1;
556 rad_snmp.smux_max_failures = 3; /* FIXME! get from config */
557 rad_snmp.smux_failures = 0;
560 * We really should get better clock resolution..
562 rad_snmp.auth.start_time = time(NULL);
563 rad_snmp.auth.last_reset_time = rad_snmp.auth.start_time;
565 rad_snmp.acct.start_time = rad_snmp.auth.start_time;
566 rad_snmp.acct.last_reset_time = rad_snmp.auth.start_time;
569 * Parse the SNMP configuration information.
571 cs = cf_section_find(NULL);
573 cf_section_parse(cs, NULL, snmp_config);
576 * Do SMUX initialization.
578 smux_init (radius_oid, sizeof (radius_oid) / sizeof (oid));
579 REGISTER_MIB("mibII/radius-acc-server", radiusacc_variables, variable, radacc_oid);
580 REGISTER_MIB("mibII/radius-auth-server", radiusauth_variables, variable, radauth_oid);
584 #endif /* WITH_SNMP */