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[] =
31 #include "libradius.h"
33 #ifdef HAVE_NETINET_IN_H
34 # include <netinet/in.h>
40 #include "radius_snmp.h"
44 extern int need_reload;
47 * More globals (sigh);
52 #define RADACCOID 1,3,6,1,2,1,67,2,1,1,1
53 #define RADAUTHOID 1,3,6,1,2,1,67,1,1,1,1
54 #define RADIUSOID 1,3,6,1,4,1,3317,1,3,1
56 static oid radacc_oid [] = { RADACCOID };
57 static oid radauth_oid [] = { RADAUTHOID };
58 static oid radius_oid [] = { RADIUSOID };
60 #define COUNTER ASN_COUNTER
61 #define INTEGER ASN_INTEGER
62 #define GAUGE ASN_GAUGE
63 #define TIMETICKS ASN_TIMETICKS
64 #define IPADDRESS ASN_IPADDRESS
65 #define STRING ASN_OCTET_STR
67 #define RADIUSACCSERVIDENT 1
68 #define RADIUSACCSERVUPTIME 2
69 #define RADIUSACCSERVRESETTIME 3
70 #define RADIUSACCSERVCONFIGRESET 4
71 #define RADIUSACCSERVTOTALREQUESTS 5
72 #define RADIUSACCSERVTOTALINVALIDREQUESTS 6
73 #define RADIUSACCSERVTOTALDUPREQUESTS 7
74 #define RADIUSACCSERVTOTALRESPONSES 8
75 #define RADIUSACCSERVTOTALMALFORMEDREQUESTS 9
76 #define RADIUSACCSERVTOTALBADAUTHENTICATORS 10
77 #define RADIUSACCSERVTOTALPACKETSDROPPED 11
78 #define RADIUSACCSERVTOTALNORECORDS 12
79 #define RADIUSACCSERVTOTALUNKNOWNTYPES 13
81 #define RADIUSACCCLIENTADDRESS 2
82 #define RADIUSACCCLIENTID 3
83 #define RADIUSACCSERVPACKETSDROPPED 4
84 #define RADIUSACCSERVREQUESTS 5
85 #define RADIUSACCSERVDUPREQUESTS 6
86 #define RADIUSACCSERVRESPONSES 7
87 #define RADIUSACCSERVBADAUTHENTICATORS 8
88 #define RADIUSACCSERVMALFORMEDREQUESTS 9
89 #define RADIUSACCSERVNORECORDS 10
90 #define RADIUSACCSERVUNKNOWNTYPES 11
92 #define RADIUSAUTHSERVIDENT 1
93 #define RADIUSAUTHSERVUPTIME 2
94 #define RADIUSAUTHSERVRESETTIME 3
95 #define RADIUSAUTHSERVCONFIGRESET 4
96 #define RADIUSAUTHSERVTOTALACCESSREQUESTS 5
97 #define RADIUSAUTHSERVTOTALINVALIDREQUESTS 6
98 #define RADIUSAUTHSERVTOTALDUPACCESSREQUESTS 7
99 #define RADIUSAUTHSERVTOTALACCESSACCEPTS 8
100 #define RADIUSAUTHSERVTOTALACCESSREJECTS 9
101 #define RADIUSAUTHSERVTOTALACCESSCHALLENGES 10
102 #define RADIUSAUTHSERVTOTALMALFORMEDACCESSREQUESTS 11
103 #define RADIUSAUTHSERVTOTALBADAUTHENTICATORS 12
104 #define RADIUSAUTHSERVTOTALPACKETSDROPPED 13
105 #define RADIUSAUTHSERVTOTALUNKNOWNTYPES 14
107 #define RADIUSAUTHCLIENTADDRESS 2
108 #define RADIUSAUTHCLIENTID 3
109 #define RADIUSAUTHSERVACCESSREQUESTS 4
110 #define RADIUSAUTHSERVDUPACCESSREQUESTS 5
111 #define RADIUSAUTHSERVACCESSACCEPTS 6
112 #define RADIUSAUTHSERVACCESSREJECTS 7
113 #define RADIUSAUTHSERVACCESSCHALLENGES 8
114 #define RADIUSAUTHSERVMALFORMEDACCESSREQUESTS 9
115 #define RADIUSAUTHSERVBADAUTHENTICATORS 10
116 #define RADIUSAUTHSERVPACKETSDROPPED 11
117 #define RADIUSAUTHSERVUNKNOWNTYPES 12
119 /* Hook functions. */
120 static const unsigned char *radAccServ(struct variable *vp,
125 WriteMethod **write_method);
126 static const unsigned char *radAccEntry(struct variable *vp,
131 WriteMethod **write_method);
132 static const u_char *radAuthServ(struct variable *vp,
137 WriteMethod **write_method);
138 static const unsigned char *radAuthEntry(struct variable *vp,
143 WriteMethod **write_method);
145 static struct variable radiusacc_variables[] =
147 {RADIUSACCSERVIDENT, STRING, RONLY, radAccServ, 1, {1}},
148 {RADIUSACCSERVUPTIME, TIMETICKS, RONLY, radAccServ, 1, {2}},
149 {RADIUSACCSERVRESETTIME, TIMETICKS, RONLY, radAccServ, 1, {3}},
150 {RADIUSACCSERVCONFIGRESET, INTEGER, RWRITE, radAccServ, 1, {4}},
151 {RADIUSACCSERVTOTALREQUESTS, COUNTER, RONLY, radAccServ, 1, {5}},
152 {RADIUSACCSERVTOTALINVALIDREQUESTS, COUNTER, RONLY, radAccServ, 1, {6}},
153 {RADIUSACCSERVTOTALDUPREQUESTS, COUNTER, RONLY, radAccServ, 1, {7}},
154 {RADIUSACCSERVTOTALRESPONSES, COUNTER, RONLY, radAccServ, 1, {8}},
155 {RADIUSACCSERVTOTALMALFORMEDREQUESTS, COUNTER, RONLY, radAccServ, 1, {9}},
156 {RADIUSACCSERVTOTALBADAUTHENTICATORS, COUNTER, RONLY, radAccServ, 1, {10}},
157 {RADIUSACCSERVTOTALPACKETSDROPPED, COUNTER, RONLY, radAccServ, 1, {11}},
158 {RADIUSACCSERVTOTALNORECORDS, COUNTER, RONLY, radAccServ, 1, {12}},
159 {RADIUSACCSERVTOTALUNKNOWNTYPES, COUNTER, RONLY, radAccServ, 1, {13}},
160 {RADIUSACCCLIENTADDRESS, IPADDRESS, RONLY, radAccEntry, 3, {14,1,2}},
161 {RADIUSACCCLIENTID, STRING, RONLY, radAccEntry, 3, {14,1,3}},
162 {RADIUSACCSERVPACKETSDROPPED, COUNTER, RONLY, radAccEntry, 3, {14,1,4}},
163 {RADIUSACCSERVREQUESTS, COUNTER, RONLY, radAccEntry, 3, {14,1,5}},
164 {RADIUSACCSERVDUPREQUESTS, COUNTER, RONLY, radAccEntry, 3, {14,1,6}},
165 {RADIUSACCSERVRESPONSES, COUNTER, RONLY, radAccEntry, 3, {14,1,7}},
166 {RADIUSACCSERVBADAUTHENTICATORS, COUNTER, RONLY, radAccEntry, 3, {14,1,8}},
167 {RADIUSACCSERVMALFORMEDREQUESTS, COUNTER, RONLY, radAccEntry, 3, {14,1,9}},
168 {RADIUSACCSERVNORECORDS, COUNTER, RONLY, radAccEntry, 3, {14,1,10}},
169 {RADIUSACCSERVUNKNOWNTYPES, COUNTER, RONLY, radAccEntry, 3, {14,1,11}},
172 static struct variable radiusauth_variables[] =
174 {RADIUSAUTHSERVIDENT, STRING, RONLY, radAuthServ, 1, {1}},
175 {RADIUSAUTHSERVUPTIME, TIMETICKS, RONLY, radAuthServ, 1, {2}},
176 {RADIUSAUTHSERVRESETTIME, TIMETICKS, RONLY, radAuthServ, 1, {3}},
177 {RADIUSAUTHSERVCONFIGRESET, INTEGER, RWRITE, radAuthServ, 1, {4}},
178 {RADIUSAUTHSERVTOTALACCESSREQUESTS, COUNTER, RONLY, radAuthServ, 1, {5}},
179 {RADIUSAUTHSERVTOTALINVALIDREQUESTS, COUNTER, RONLY, radAuthServ, 1, {6}},
180 {RADIUSAUTHSERVTOTALDUPACCESSREQUESTS, COUNTER, RONLY, radAuthServ, 1, {7}},
181 {RADIUSAUTHSERVTOTALACCESSACCEPTS, COUNTER, RONLY, radAuthServ, 1, {8}},
182 {RADIUSAUTHSERVTOTALACCESSREJECTS, COUNTER, RONLY, radAuthServ, 1, {9}},
183 {RADIUSAUTHSERVTOTALACCESSCHALLENGES, COUNTER, RONLY, radAuthServ, 1, {10}},
184 {RADIUSAUTHSERVTOTALMALFORMEDACCESSREQUESTS, COUNTER, RONLY, radAuthServ, 1, {11}},
185 {RADIUSAUTHSERVTOTALBADAUTHENTICATORS, COUNTER, RONLY, radAuthServ, 1, {12}},
186 {RADIUSAUTHSERVTOTALPACKETSDROPPED, COUNTER, RONLY, radAuthServ, 1, {13}},
187 {RADIUSAUTHSERVTOTALUNKNOWNTYPES, COUNTER, RONLY, radAuthServ, 1, {14}},
188 {RADIUSAUTHCLIENTADDRESS, IPADDRESS, RONLY, radAuthEntry, 3, {15,1,2}},
189 {RADIUSAUTHCLIENTID, STRING, RONLY, radAuthEntry, 3, {15,1,3}},
190 {RADIUSAUTHSERVACCESSREQUESTS, COUNTER, RONLY, radAuthEntry, 3, {15,1,4}},
191 {RADIUSAUTHSERVDUPACCESSREQUESTS, COUNTER, RONLY, radAuthEntry, 3, {15,1,5}},
192 {RADIUSAUTHSERVACCESSACCEPTS, COUNTER, RONLY, radAuthEntry, 3, {15,1,6}},
193 {RADIUSAUTHSERVACCESSREJECTS, COUNTER, RONLY, radAuthEntry, 3, {15,1,7}},
194 {RADIUSAUTHSERVACCESSCHALLENGES, COUNTER, RONLY, radAuthEntry, 3, {15,1,8}},
195 {RADIUSAUTHSERVMALFORMEDACCESSREQUESTS, COUNTER, RONLY, radAuthEntry, 3, {15,1,9}},
196 {RADIUSAUTHSERVBADAUTHENTICATORS, COUNTER, RONLY, radAuthEntry, 3, {15,1,10}},
197 {RADIUSAUTHSERVPACKETSDROPPED, COUNTER, RONLY, radAuthEntry, 3, {15,1,11}},
198 {RADIUSAUTHSERVUNKNOWNTYPES, COUNTER, RONLY, radAuthEntry, 3, {15,1,12}},
203 get_client(struct variable *v, oid objid[], size_t *objid_len, int exact) {
208 len = *objid_len - v->namelen;
210 if (!mainconfig.clients)
214 /* Check the length. */
217 if (objid[v->namelen] == 0)
220 i = objid[v->namelen]-1;
221 c = mainconfig.clients;
231 i = objid[v->namelen]-1;
232 *objid_len = v->namelen + 1;
233 if (!len || (objid[v->namelen] == 0)) {
235 return mainconfig.clients;
237 c = mainconfig.clients->next;
250 radServReset (int action, u_char *var_val, u_char var_val_type,
251 size_t var_val_len, const unsigned char *statP, oid *name,
255 int big = SNMP_MAX_LEN;
259 if (var_val_type != INTEGER)
260 return SNMP_ERR_WRONGTYPE;
261 if (var_val_len != sizeof (long))
262 return SNMP_ERR_WRONGLENGTH;
263 if (! asn_parse_int(var_val, &big, &var_val_type, &i, sizeof(long)))
264 return SNMP_ERR_WRONGENCODING;
266 return SNMP_ERR_WRONGVALUE;
274 return SNMP_ERR_GENERR;
276 return SNMP_ERR_NOERROR;
279 static const unsigned char *
280 radAccServ(struct variable *vp, oid *name, size_t *length, int exact,
281 size_t *var_len, WriteMethod **write_method) {
285 /* check whether the instance identifier is valid */
286 if (smux_header_generic(vp, name, length, exact, var_len,
287 write_method) == MATCH_FAILED) {
291 /* return the current value of the variable */
293 case RADIUSACCSERVIDENT:
294 *var_len = strlen(rad_snmp.acct.ident);
295 return (const unsigned char *) rad_snmp.acct.ident;
297 case RADIUSACCSERVUPTIME:
298 rad_snmp.acct.uptime = (time(NULL) - rad_snmp.acct.start_time) * 100;
299 *var_len = sizeof(int32_t);
300 return (unsigned char *) &rad_snmp.acct.uptime;
302 case RADIUSACCSERVRESETTIME:
303 rad_snmp.acct.reset_time = (time(NULL) - rad_snmp.acct.last_reset_time) * 100;
304 *var_len = sizeof(int32_t);
305 return (unsigned char *) &rad_snmp.acct.reset_time;
307 case RADIUSACCSERVCONFIGRESET:
308 *write_method = radServReset;
310 return (unsigned char *) &result;
312 case RADIUSACCSERVTOTALREQUESTS:
313 *var_len = sizeof(int32_t);
314 return (unsigned char *) &rad_snmp.acct.total_requests;
316 case RADIUSACCSERVTOTALINVALIDREQUESTS:
317 *var_len = sizeof(int32_t);
318 return (unsigned char *) &rad_snmp.acct.total_invalid_requests;
320 case RADIUSACCSERVTOTALDUPREQUESTS:
321 *var_len = sizeof(int32_t);
322 return (unsigned char *) &rad_snmp.acct.total_dup_requests;
324 case RADIUSACCSERVTOTALRESPONSES:
325 *var_len = sizeof(int32_t);
326 return (unsigned char *) &rad_snmp.acct.total_responses;
328 case RADIUSACCSERVTOTALMALFORMEDREQUESTS:
329 *var_len = sizeof(int32_t);
330 return (unsigned char *) &rad_snmp.acct.total_malformed_requests;
332 case RADIUSACCSERVTOTALBADAUTHENTICATORS:
333 *var_len = sizeof(int32_t);
334 return (unsigned char *) &rad_snmp.acct.total_bad_authenticators;
336 case RADIUSACCSERVTOTALPACKETSDROPPED:
337 *var_len = sizeof(int32_t);
338 return (unsigned char *) &rad_snmp.acct.total_packets_dropped;
340 case RADIUSACCSERVTOTALNORECORDS:
341 *var_len = sizeof(int32_t);
342 return (unsigned char *) &rad_snmp.acct.total_no_records;
344 case RADIUSACCSERVTOTALUNKNOWNTYPES:
345 *var_len = sizeof(int32_t);
346 return (unsigned char *) &rad_snmp.acct.total_unknown_types;
353 static const unsigned char *
354 radAccEntry(struct variable *vp, oid *name, size_t *length, int exact,
355 size_t *var_len, WriteMethod **write_method) {
359 *write_method = NULL; /* table is read only */
360 c = get_client(vp, name, length, exact);
364 /* return the current value of the variable */
367 case RADIUSACCCLIENTADDRESS:
368 *var_len = sizeof(c->ipaddr);
369 return (unsigned char *)&(c->ipaddr);
371 case RADIUSACCCLIENTID:
372 if (strlen(c->shortname)) {
373 *var_len = strlen(c->shortname);
376 *var_len = strlen(c->longname);
379 case RADIUSACCSERVPACKETSDROPPED:
380 return (unsigned char *) NULL;
382 case RADIUSACCSERVREQUESTS:
383 return (unsigned char *) NULL;
385 case RADIUSACCSERVDUPREQUESTS:
386 return (unsigned char *) NULL;
388 case RADIUSACCSERVRESPONSES:
389 return (unsigned char *) NULL;
391 case RADIUSACCSERVBADAUTHENTICATORS:
392 return (unsigned char *) NULL;
394 case RADIUSACCSERVMALFORMEDREQUESTS:
395 return (unsigned char *) NULL;
397 case RADIUSACCSERVNORECORDS:
398 return (unsigned char *) NULL;
400 case RADIUSACCSERVUNKNOWNTYPES:
401 return (unsigned char *) NULL;
407 static const unsigned char *
408 radAuthServ(struct variable *vp, oid *name, size_t *length, int exact,
409 size_t *var_len, WriteMethod **write_method) {
412 /* check whether the instance identifier is valid */
414 if (smux_header_generic(vp, name, length, exact, var_len,
415 write_method) == MATCH_FAILED) {
419 /* return the current value of the variable */
423 case RADIUSAUTHSERVIDENT:
424 *var_len = strlen(rad_snmp.auth.ident);
425 return (const unsigned char *) rad_snmp.auth.ident;
427 case RADIUSAUTHSERVUPTIME:
428 rad_snmp.auth.uptime = (time(NULL) - rad_snmp.auth.start_time) * 100;
429 *var_len = sizeof(int32_t);
430 return (unsigned char *) &rad_snmp.auth.uptime;
432 case RADIUSAUTHSERVRESETTIME:
433 rad_snmp.auth.reset_time = (time(NULL) - rad_snmp.auth.last_reset_time) * 100;
434 *var_len = sizeof(int32_t);
435 return (unsigned char *) &rad_snmp.auth.reset_time;
437 case RADIUSAUTHSERVCONFIGRESET:
438 *write_method = radServReset;
440 return (unsigned char *) &result;
442 case RADIUSAUTHSERVTOTALACCESSREQUESTS:
443 *var_len = sizeof(int32_t);
444 return (unsigned char *) &rad_snmp.auth.total_requests;
446 case RADIUSAUTHSERVTOTALINVALIDREQUESTS:
447 *var_len = sizeof(int32_t);
448 return (unsigned char *) &rad_snmp.auth.total_invalid_requests;
450 case RADIUSAUTHSERVTOTALDUPACCESSREQUESTS:
451 *var_len = sizeof(int32_t);
452 return (unsigned char *) &rad_snmp.auth.total_dup_requests;
454 case RADIUSAUTHSERVTOTALACCESSACCEPTS:
455 *var_len = sizeof(int32_t);
456 return (unsigned char *) &rad_snmp.auth.total_access_accepts;
458 case RADIUSAUTHSERVTOTALACCESSREJECTS:
459 *var_len = sizeof(int32_t);
460 return (unsigned char *) &rad_snmp.auth.total_access_rejects;
462 case RADIUSAUTHSERVTOTALACCESSCHALLENGES:
463 *var_len = sizeof(int32_t);
464 return (unsigned char *) &rad_snmp.auth.total_access_challenges;
466 case RADIUSAUTHSERVTOTALMALFORMEDACCESSREQUESTS:
467 *var_len = sizeof(int32_t);
468 return (unsigned char *) &rad_snmp.auth.total_malformed_requests;
470 case RADIUSAUTHSERVTOTALBADAUTHENTICATORS:
471 *var_len = sizeof(int32_t);
472 return (unsigned char *) &rad_snmp.auth.total_bad_authenticators;
474 case RADIUSAUTHSERVTOTALPACKETSDROPPED:
475 *var_len = sizeof(int32_t);
476 return (unsigned char *) &rad_snmp.auth.total_packets_dropped;
478 case RADIUSAUTHSERVTOTALUNKNOWNTYPES:
479 *var_len = sizeof(int32_t);
480 return (unsigned char *) &rad_snmp.auth.total_unknown_types;
487 static const unsigned char *
488 radAuthEntry(struct variable *vp, oid *name, size_t *length, int exact,
489 size_t *var_len, WriteMethod **write_method) {
493 *write_method = NULL; /* table is read only */
494 c = get_client(vp, name, length, exact);
498 /* return the current value of the variable */
502 case RADIUSAUTHCLIENTADDRESS:
503 *var_len = sizeof(c->ipaddr);
504 return (unsigned char *)&(c->ipaddr);
506 case RADIUSAUTHCLIENTID:
507 if (strlen(c->shortname)) {
508 *var_len = strlen(c->shortname);
511 *var_len = strlen(c->longname);
514 case RADIUSAUTHSERVACCESSREQUESTS:
515 return (unsigned char *) NULL;
517 case RADIUSAUTHSERVDUPACCESSREQUESTS:
518 return (unsigned char *) NULL;
520 case RADIUSAUTHSERVACCESSACCEPTS:
521 return (unsigned char *) NULL;
523 case RADIUSAUTHSERVACCESSREJECTS:
524 return (unsigned char *) NULL;
526 case RADIUSAUTHSERVACCESSCHALLENGES:
527 return (unsigned char *) NULL;
529 case RADIUSAUTHSERVMALFORMEDACCESSREQUESTS:
530 return (unsigned char *) NULL;
532 case RADIUSAUTHSERVBADAUTHENTICATORS:
533 return (unsigned char *) NULL;
535 case RADIUSAUTHSERVPACKETSDROPPED:
536 return (unsigned char *) NULL;
538 case RADIUSAUTHSERVUNKNOWNTYPES:
539 return (unsigned char *) NULL;
545 static CONF_PARSER snmp_config[] = {
546 { "smux_password", PW_TYPE_STRING_PTR, 0, &rad_snmp.smux_password, "" },
547 { "snmp_write_access", PW_TYPE_BOOLEAN, 0, &rad_snmp.snmp_write_access, "no" },
548 { NULL, -1, 0, NULL, NULL }
552 /* Register RADIUS MIBs. */
554 radius_snmp_init (void) {
559 * Initialize the RADIUS SNMP data structure.
561 memset(&rad_snmp, 0, sizeof(rad_snmp));
563 rad_snmp.auth.ident = radiusd_version;
564 rad_snmp.acct.ident = radiusd_version;
566 rad_snmp.smux_event = SMUX_NONE;
567 rad_snmp.smux_password = NULL;
568 rad_snmp.snmp_write_access = FALSE;
569 rad_snmp.smux_fd = -1;
570 rad_snmp.smux_max_failures = 3; /* FIXME! get from config */
571 rad_snmp.smux_failures = 0;
574 * We really should get better clock resolution..
576 rad_snmp.auth.start_time = time(NULL);
577 rad_snmp.auth.last_reset_time = rad_snmp.auth.start_time;
579 rad_snmp.acct.start_time = rad_snmp.auth.start_time;
580 rad_snmp.acct.last_reset_time = rad_snmp.auth.start_time;
583 * Parse the SNMP configuration information.
585 cs = cf_section_find(NULL);
587 cf_section_parse(cs, NULL, snmp_config);
590 * Do SMUX initialization.
592 smux_init (radius_oid, sizeof (radius_oid) / sizeof (oid));
593 REGISTER_MIB("mibII/radius-acc-server", radiusacc_variables, variable, radacc_oid);
594 REGISTER_MIB("mibII/radius-auth-server", radiusauth_variables, variable, radauth_oid);
598 #endif /* WITH_SNMP */