Replace fr_client_stats_t with fr_stats_t. They have the
[freeradius.git] / src / main / radius_snmp.c
1 /*
2  * radius_snmp.c        Radius SNMP support
3  *
4  * Version:     $Id$
5  *
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.
10  *
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.
15  *
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
19  *
20  * Copyright 2000,2006  The FreeRADIUS server project
21  * Copyright 2000  Jochen Friedrich <jochen@scram.de>
22  */
23
24 #include <freeradius-devel/ident.h>
25 RCSID("$Id$")
26
27 #include <freeradius-devel/radiusd.h>
28
29 #ifdef WITH_SNMP
30
31 #include <freeradius-devel/smux.h>
32 #include <freeradius-devel/radius_snmp.h>
33
34 /*
35  *      More globals (sigh);
36  */
37 rad_snmp_t              rad_snmp;
38
39
40 #define RADACCOID  1,3,6,1,2,1,67,2,1,1,1
41 #define RADAUTHOID 1,3,6,1,2,1,67,1,1,1,1
42 #define RADIUSOID  1,3,6,1,4,1,11344,1,1,1
43
44 static const oid radacc_oid [] = { RADACCOID };
45 static const oid radauth_oid [] = { RADAUTHOID };
46 static const oid radius_oid [] = { RADIUSOID };
47
48 #define COUNTER ASN_COUNTER
49 #define INTEGER ASN_INTEGER
50 #define GAUGE ASN_GAUGE
51 #define TIMETICKS ASN_TIMETICKS
52 #define IPADDRESS ASN_IPADDRESS
53 #define STRING ASN_OCTET_STR
54
55 #define RADIUSACCSERVIDENT               1
56 #define RADIUSACCSERVUPTIME              2
57 #define RADIUSACCSERVRESETTIME           3
58 #define RADIUSACCSERVCONFIGRESET         4
59 #define RADIUSACCSERVTOTALREQUESTS       5
60 #define RADIUSACCSERVTOTALINVALIDREQUESTS 6
61 #define RADIUSACCSERVTOTALDUPREQUESTS    7
62 #define RADIUSACCSERVTOTALRESPONSES      8
63 #define RADIUSACCSERVTOTALMALFORMEDREQUESTS 9
64 #define RADIUSACCSERVTOTALBADAUTHENTICATORS 10
65 #define RADIUSACCSERVTOTALPACKETSDROPPED 11
66 #define RADIUSACCSERVTOTALNORECORDS      12
67 #define RADIUSACCSERVTOTALUNKNOWNTYPES   13
68 /* */
69 #define RADIUSACCCLIENTADDRESS           2
70 #define RADIUSACCCLIENTID                3
71 #define RADIUSACCSERVPACKETSDROPPED      4
72 #define RADIUSACCSERVREQUESTS            5
73 #define RADIUSACCSERVDUPREQUESTS         6
74 #define RADIUSACCSERVRESPONSES           7
75 #define RADIUSACCSERVBADAUTHENTICATORS   8
76 #define RADIUSACCSERVMALFORMEDREQUESTS   9
77 #define RADIUSACCSERVNORECORDS           10
78 #define RADIUSACCSERVUNKNOWNTYPES        11
79 /* */
80 #define RADIUSAUTHSERVIDENT              1
81 #define RADIUSAUTHSERVUPTIME             2
82 #define RADIUSAUTHSERVRESETTIME          3
83 #define RADIUSAUTHSERVCONFIGRESET        4
84 #define RADIUSAUTHSERVTOTALACCESSREQUESTS 5
85 #define RADIUSAUTHSERVTOTALINVALIDREQUESTS 6
86 #define RADIUSAUTHSERVTOTALDUPACCESSREQUESTS 7
87 #define RADIUSAUTHSERVTOTALACCESSACCEPTS 8
88 #define RADIUSAUTHSERVTOTALACCESSREJECTS 9
89 #define RADIUSAUTHSERVTOTALACCESSCHALLENGES 10
90 #define RADIUSAUTHSERVTOTALMALFORMEDACCESSREQUESTS 11
91 #define RADIUSAUTHSERVTOTALBADAUTHENTICATORS 12
92 #define RADIUSAUTHSERVTOTALPACKETSDROPPED 13
93 #define RADIUSAUTHSERVTOTALUNKNOWNTYPES  14
94 /* */
95 #define RADIUSAUTHCLIENTADDRESS          2
96 #define RADIUSAUTHCLIENTID               3
97 #define RADIUSAUTHSERVACCESSREQUESTS     4
98 #define RADIUSAUTHSERVDUPACCESSREQUESTS  5
99 #define RADIUSAUTHSERVACCESSACCEPTS      6
100 #define RADIUSAUTHSERVACCESSREJECTS      7
101 #define RADIUSAUTHSERVACCESSCHALLENGES   8
102 #define RADIUSAUTHSERVMALFORMEDACCESSREQUESTS 9
103 #define RADIUSAUTHSERVBADAUTHENTICATORS  10
104 #define RADIUSAUTHSERVPACKETSDROPPED     11
105 #define RADIUSAUTHSERVUNKNOWNTYPES       12
106
107 /* Hook functions. */
108 #ifdef WITH_ACCOUNTING
109 static const u_char *radAccServ(struct variable *vp,
110         oid     *name,
111         size_t  *length,
112         int     exact,
113         size_t  *var_len,
114         WriteMethod **write_method);
115 static const u_char *radAccEntry(struct variable *vp,
116         oid     *name,
117         size_t  *length,
118         int     exact,
119         size_t  *var_len,
120         WriteMethod **write_method);
121 #endif
122 static const u_char *radAuthServ(struct variable *vp,
123         oid     *name,
124         size_t  *length,
125         int     exact,
126         size_t  *var_len,
127         WriteMethod **write_method);
128 static const u_char *radAuthEntry(struct variable *vp,
129         oid     *name,
130         size_t  *length,
131         int     exact,
132         size_t  *var_len,
133         WriteMethod **write_method);
134
135 #ifdef WITH_ACCOUNTING
136 static const struct variable radiusacc_variables[] =
137 {
138         {RADIUSACCSERVIDENT, STRING, RONLY, radAccServ, 1, {1}},
139         {RADIUSACCSERVUPTIME, TIMETICKS, RONLY, radAccServ, 1, {2}},
140         {RADIUSACCSERVRESETTIME, TIMETICKS, RONLY, radAccServ, 1, {3}},
141         {RADIUSACCSERVCONFIGRESET, INTEGER, RWRITE, radAccServ, 1, {4}},
142         {RADIUSACCSERVTOTALREQUESTS, COUNTER, RONLY, radAccServ, 1, {5}},
143         {RADIUSACCSERVTOTALINVALIDREQUESTS, COUNTER, RONLY, radAccServ, 1, {6}},
144         {RADIUSACCSERVTOTALDUPREQUESTS, COUNTER, RONLY, radAccServ, 1, {7}},
145         {RADIUSACCSERVTOTALRESPONSES, COUNTER, RONLY, radAccServ, 1, {8}},
146         {RADIUSACCSERVTOTALMALFORMEDREQUESTS, COUNTER, RONLY, radAccServ, 1, {9}},
147         {RADIUSACCSERVTOTALBADAUTHENTICATORS, COUNTER, RONLY, radAccServ, 1, {10}},
148         {RADIUSACCSERVTOTALPACKETSDROPPED, COUNTER, RONLY, radAccServ, 1, {11}},
149         {RADIUSACCSERVTOTALNORECORDS, COUNTER, RONLY, radAccServ, 1, {12}},
150         {RADIUSACCSERVTOTALUNKNOWNTYPES, COUNTER, RONLY, radAccServ, 1, {13}},
151         {RADIUSACCCLIENTADDRESS, IPADDRESS, RONLY, radAccEntry, 3, {14,1,2}},
152         {RADIUSACCCLIENTID, STRING, RONLY, radAccEntry, 3, {14,1,3}},
153         {RADIUSACCSERVPACKETSDROPPED, COUNTER, RONLY, radAccEntry, 3, {14,1,4}},
154         {RADIUSACCSERVREQUESTS, COUNTER, RONLY, radAccEntry, 3, {14,1,5}},
155         {RADIUSACCSERVDUPREQUESTS, COUNTER, RONLY, radAccEntry, 3, {14,1,6}},
156         {RADIUSACCSERVRESPONSES, COUNTER, RONLY, radAccEntry, 3, {14,1,7}},
157         {RADIUSACCSERVBADAUTHENTICATORS, COUNTER, RONLY, radAccEntry, 3, {14,1,8}},
158         {RADIUSACCSERVMALFORMEDREQUESTS, COUNTER, RONLY, radAccEntry, 3, {14,1,9}},
159         {RADIUSACCSERVNORECORDS, COUNTER, RONLY, radAccEntry, 3, {14,1,10}},
160         {RADIUSACCSERVUNKNOWNTYPES, COUNTER, RONLY, radAccEntry, 3, {14,1,11}},
161 };
162 #endif
163
164 static const struct variable radiusauth_variables[] =
165 {
166         {RADIUSAUTHSERVIDENT, STRING, RONLY, radAuthServ, 1, {1}},
167         {RADIUSAUTHSERVUPTIME, TIMETICKS, RONLY, radAuthServ, 1, {2}},
168         {RADIUSAUTHSERVRESETTIME, TIMETICKS, RONLY, radAuthServ, 1, {3}},
169         {RADIUSAUTHSERVCONFIGRESET, INTEGER, RWRITE, radAuthServ, 1, {4}},
170         {RADIUSAUTHSERVTOTALACCESSREQUESTS, COUNTER, RONLY, radAuthServ, 1, {5}},
171         {RADIUSAUTHSERVTOTALINVALIDREQUESTS, COUNTER, RONLY, radAuthServ, 1, {6}},
172         {RADIUSAUTHSERVTOTALDUPACCESSREQUESTS, COUNTER, RONLY, radAuthServ, 1, {7}},
173         {RADIUSAUTHSERVTOTALACCESSACCEPTS, COUNTER, RONLY, radAuthServ, 1, {8}},
174         {RADIUSAUTHSERVTOTALACCESSREJECTS, COUNTER, RONLY, radAuthServ, 1, {9}},
175         {RADIUSAUTHSERVTOTALACCESSCHALLENGES, COUNTER, RONLY, radAuthServ, 1, {10}},
176         {RADIUSAUTHSERVTOTALMALFORMEDACCESSREQUESTS, COUNTER, RONLY, radAuthServ, 1, {11}},
177         {RADIUSAUTHSERVTOTALBADAUTHENTICATORS, COUNTER, RONLY, radAuthServ, 1, {12}},
178         {RADIUSAUTHSERVTOTALPACKETSDROPPED, COUNTER, RONLY, radAuthServ, 1, {13}},
179         {RADIUSAUTHSERVTOTALUNKNOWNTYPES, COUNTER, RONLY, radAuthServ, 1, {14}},
180         {RADIUSAUTHCLIENTADDRESS, IPADDRESS, RONLY, radAuthEntry, 3, {15,1,2}},
181         {RADIUSAUTHCLIENTID, STRING, RONLY, radAuthEntry, 3, {15,1,3}},
182         {RADIUSAUTHSERVACCESSREQUESTS, COUNTER, RONLY, radAuthEntry, 3, {15,1,4}},
183         {RADIUSAUTHSERVDUPACCESSREQUESTS, COUNTER, RONLY, radAuthEntry, 3, {15,1,5}},
184         {RADIUSAUTHSERVACCESSACCEPTS, COUNTER, RONLY, radAuthEntry, 3, {15,1,6}},
185         {RADIUSAUTHSERVACCESSREJECTS, COUNTER, RONLY, radAuthEntry, 3, {15,1,7}},
186         {RADIUSAUTHSERVACCESSCHALLENGES, COUNTER, RONLY, radAuthEntry, 3, {15,1,8}},
187         {RADIUSAUTHSERVMALFORMEDACCESSREQUESTS, COUNTER, RONLY, radAuthEntry, 3, {15,1,9}},
188         {RADIUSAUTHSERVBADAUTHENTICATORS, COUNTER, RONLY, radAuthEntry, 3, {15,1,10}},
189         {RADIUSAUTHSERVPACKETSDROPPED, COUNTER, RONLY, radAuthEntry, 3, {15,1,11}},
190         {RADIUSAUTHSERVUNKNOWNTYPES, COUNTER, RONLY, radAuthEntry, 3, {15,1,12}},
191 };
192
193 static RADCLIENT *
194 get_client(struct variable *v, oid objid[], size_t *objid_len, int exact)
195 {
196         RADCLIENT *c;
197         int i, len;
198
199         len = *objid_len - v->namelen;
200
201         if (exact) {
202                 /* Check the length. */
203                 if (len != 1)
204                         return NULL;
205                 if (objid[v->namelen] == 0)
206                         return NULL;
207
208                 i = objid[v->namelen]-1;
209
210                 return client_findbynumber(NULL, i);
211         }
212         *objid_len = v->namelen + 1;
213         if (!len || (objid[v->namelen] == 0)) {
214                 objid[v->namelen]=1;
215                 return client_findbynumber(NULL, 0);
216         }
217
218         i = objid[v->namelen]-1;
219         c = client_findbynumber(NULL, i);
220         if (c) {
221                 objid[v->namelen]++;
222         }
223         return c;
224 }
225
226 static int
227 radServReset(int action, u_char *var_val, u_char var_val_type,
228              size_t var_val_len, UNUSED const u_char *statP,
229              UNUSED oid *name, UNUSED size_t name_len)
230 {
231         long i;
232         size_t big = SNMP_MAX_LEN;
233
234         switch (action) {
235                 case RESERVE1:
236                         if (var_val_type != INTEGER)
237                                 return SNMP_ERR_WRONGTYPE;
238                         if (var_val_len != sizeof (long))
239                                 return SNMP_ERR_WRONGLENGTH;
240                         if (! asn_parse_int(var_val, &big, &var_val_type, &i, sizeof(long)))
241                                 return SNMP_ERR_WRONGENCODING;
242                         if (i != 2)
243                                 return SNMP_ERR_WRONGVALUE;
244                         break;
245                 case COMMIT:
246                         radius_signal_self(RADIUS_SIGNAL_SELF_HUP);
247                         break;
248                 case FREE:
249                         break;
250                 default:
251                         return SNMP_ERR_GENERR;
252         }
253         return SNMP_ERR_NOERROR;
254 }
255
256 #ifdef WITH_ACCOUNTING
257 static const u_char *
258 radAccServ(struct variable *vp, oid *name, size_t *length, int exact,
259                 size_t *var_len, WriteMethod **write_method) {
260
261         static int result;
262
263         /* check whether the instance identifier is valid */
264         if (smux_header_generic(vp, name, length, exact, var_len,
265                 write_method) == MATCH_FAILED) {
266                 return NULL;
267         }
268
269         /* return the current value of the variable */
270         switch (vp->magic) {
271                 case RADIUSACCSERVIDENT:
272                         *var_len = strlen(rad_snmp.acct.ident);
273                         return (const u_char *) rad_snmp.acct.ident;
274
275                 case RADIUSACCSERVUPTIME:
276                         rad_snmp.acct.uptime = (time(NULL) - rad_snmp.acct.start_time) * 100;
277                         *var_len = sizeof(int32_t);
278                         return (u_char *) &rad_snmp.acct.uptime;
279
280                 case RADIUSACCSERVRESETTIME:
281                         rad_snmp.acct.reset_time = (time(NULL) - rad_snmp.acct.last_reset_time) * 100;
282                         *var_len = sizeof(int32_t);
283                         return (u_char *) &rad_snmp.acct.reset_time;
284
285                 case RADIUSACCSERVCONFIGRESET:
286                         *write_method = radServReset;
287                         result = 4;
288                         return (u_char *) &result;
289
290                 case RADIUSACCSERVTOTALREQUESTS:
291                         *var_len = sizeof(int32_t);
292                         return (u_char *) &radius_acct_stats.total_requests;
293
294                 case RADIUSACCSERVTOTALINVALIDREQUESTS:
295                         *var_len = sizeof(int32_t);
296                         return (u_char *) &radius_acct_stats.total_invalid_requests;
297
298                 case RADIUSACCSERVTOTALDUPREQUESTS:
299                         *var_len = sizeof(int32_t);
300                         return (u_char *) &radius_acct_stats.total_dup_requests;
301
302                 case RADIUSACCSERVTOTALRESPONSES:
303                         *var_len = sizeof(int32_t);
304                         return (u_char *) &radius_acct_stats.total_responses;
305
306                 case RADIUSACCSERVTOTALMALFORMEDREQUESTS:
307                         *var_len = sizeof(int32_t);
308                         return (u_char *) &radius_acct_stats.total_malformed_requests;
309
310                 case RADIUSACCSERVTOTALBADAUTHENTICATORS:
311                         *var_len = sizeof(int32_t);
312                         return (u_char *) &radius_acct_stats.total_bad_authenticators;
313
314                 case RADIUSACCSERVTOTALPACKETSDROPPED:
315                         *var_len = sizeof(int32_t);
316                         return (u_char *) &radius_acct_stats.total_packets_dropped;
317
318                 case RADIUSACCSERVTOTALNORECORDS:
319                         *var_len = sizeof(int32_t);
320                         return (u_char *) &radius_acct_stats.total_no_records;
321
322                 case RADIUSACCSERVTOTALUNKNOWNTYPES:
323                         *var_len = sizeof(int32_t);
324                         return (u_char *) &radius_acct_stats.total_unknown_types;
325
326         }
327
328         return NULL;
329 }
330
331 static const u_char *
332 radAccEntry(struct variable *vp, oid *name, size_t *length, int exact,
333                 size_t *var_len, WriteMethod **write_method) {
334
335         RADCLIENT *c;
336         static uint32_t zero = 0;
337
338         *write_method = NULL; /* table is read only */
339         c = get_client(vp, name, length, exact);
340         if (!c)
341                 return NULL;
342
343         /* return the current value of the variable */
344
345         switch (vp->magic) {
346                 case RADIUSACCCLIENTADDRESS:
347                         if (c->ipaddr.af != AF_INET) return NULL;
348
349                         *var_len = sizeof(c->ipaddr.ipaddr.ip4addr);
350                         return (u_char *)&(c->ipaddr.ipaddr.ip4addr);
351
352                 case RADIUSACCCLIENTID:
353                         if (c->shortname && c->shortname[0]) {
354                                 *var_len = strlen(c->shortname);
355                                 return (u_char *) c->shortname;
356                         }
357                         *var_len = strlen(c->longname);
358                         return (u_char *) c->longname;
359
360                 case RADIUSACCSERVPACKETSDROPPED:
361                         *var_len = sizeof(int32_t);
362                         return (u_char *) &c->acct->total_packets_dropped;
363
364                 case RADIUSACCSERVREQUESTS:
365                         *var_len = sizeof(int32_t);
366                         return (u_char *) &c->acct->total_requests;
367
368                 case RADIUSACCSERVDUPREQUESTS:
369                         *var_len = sizeof(int32_t);
370                         return (u_char *) &c->acct->total_dup_requests;
371
372                 case RADIUSACCSERVRESPONSES:
373                         *var_len = sizeof(int32_t);
374                         return (u_char *) &c->acct->total_responses;
375
376                 case RADIUSACCSERVBADAUTHENTICATORS:
377                         *var_len = sizeof(int32_t);
378                         return (u_char *) &c->acct->total_bad_authenticators;
379
380                 case RADIUSACCSERVMALFORMEDREQUESTS:
381                         *var_len = sizeof(int32_t);
382                         return (u_char *) &c->acct->total_malformed_requests;
383
384                         /*
385                          *      Received && responded to, but not
386                          *      recorded anywhere.  This is always
387                          *      zero.
388                          */
389                 case RADIUSACCSERVNORECORDS:
390                         *var_len = sizeof(int32_t);
391                         return (u_char *) &zero;
392
393                 case RADIUSACCSERVUNKNOWNTYPES:
394                         *var_len = sizeof(int32_t);
395                         return (u_char *) &c->acct->total_unknown_types;
396         }
397         return NULL;
398 }
399 #endif
400
401 static const u_char *
402 radAuthServ(struct variable *vp, oid *name, size_t *length, int exact,
403                 size_t *var_len, WriteMethod **write_method) {
404
405         static int result;
406         /* check whether the instance identifier is valid */
407
408         if (smux_header_generic(vp, name, length, exact, var_len,
409                         write_method) == MATCH_FAILED) {
410                 return NULL;
411         }
412
413         /* return the current value of the variable */
414
415         switch (vp->magic) {
416                 case RADIUSAUTHSERVIDENT:
417                         *var_len = strlen(rad_snmp.auth.ident);
418                         return (const u_char *) rad_snmp.auth.ident;
419
420                 case RADIUSAUTHSERVUPTIME:
421                         rad_snmp.auth.uptime = (time(NULL) - rad_snmp.auth.start_time) * 100;
422                         *var_len = sizeof(int32_t);
423                         return (u_char *) &rad_snmp.auth.uptime;
424
425                 case RADIUSAUTHSERVRESETTIME:
426                         rad_snmp.auth.reset_time = (time(NULL) - rad_snmp.auth.last_reset_time) * 100;
427                         *var_len = sizeof(int32_t);
428                         return (u_char *) &rad_snmp.auth.reset_time;
429
430                 case RADIUSAUTHSERVCONFIGRESET:
431                         *write_method = radServReset;
432                         result = 4;
433                         return (u_char *) &result;
434
435                 case RADIUSAUTHSERVTOTALACCESSREQUESTS:
436                         *var_len = sizeof(int32_t);
437                         return (u_char *) &radius_auth_stats.total_requests;
438
439                 case RADIUSAUTHSERVTOTALINVALIDREQUESTS:
440                         *var_len = sizeof(int32_t);
441                         return (u_char *) &radius_auth_stats.total_invalid_requests;
442
443                 case RADIUSAUTHSERVTOTALDUPACCESSREQUESTS:
444                         *var_len = sizeof(int32_t);
445                         return (u_char *) &radius_auth_stats.total_dup_requests;
446
447                 case RADIUSAUTHSERVTOTALACCESSACCEPTS:
448                         *var_len = sizeof(int32_t);
449                         return (u_char *) &radius_auth_stats.total_access_accepts;
450
451                 case RADIUSAUTHSERVTOTALACCESSREJECTS:
452                         *var_len = sizeof(int32_t);
453                         return (u_char *) &radius_auth_stats.total_access_rejects;
454
455                 case RADIUSAUTHSERVTOTALACCESSCHALLENGES:
456                         *var_len = sizeof(int32_t);
457                         return (u_char *) &radius_auth_stats.total_access_challenges;
458
459                 case RADIUSAUTHSERVTOTALMALFORMEDACCESSREQUESTS:
460                         *var_len = sizeof(int32_t);
461                         return (u_char *) &radius_auth_stats.total_malformed_requests;
462
463                 case RADIUSAUTHSERVTOTALBADAUTHENTICATORS:
464                         *var_len = sizeof(int32_t);
465                         return (u_char *) &radius_auth_stats.total_bad_authenticators;
466
467                 case RADIUSAUTHSERVTOTALPACKETSDROPPED:
468                         *var_len = sizeof(int32_t);
469                         return (u_char *) &radius_auth_stats.total_packets_dropped;
470
471                 case RADIUSAUTHSERVTOTALUNKNOWNTYPES:
472                         *var_len = sizeof(int32_t);
473                         return (u_char *) &radius_auth_stats.total_unknown_types;
474
475         }
476
477     return NULL;
478 }
479
480 static const u_char *
481 radAuthEntry(struct variable *vp, oid    *name, size_t *length, int exact,
482                 size_t *var_len, WriteMethod **write_method) {
483
484         RADCLIENT *c;
485
486         *write_method = NULL; /* table is read only */
487         c = get_client(vp, name, length, exact);
488         if (!c)
489                 return NULL;
490
491         /* return the current value of the variable */
492
493         switch (vp->magic) {
494
495                 case RADIUSAUTHCLIENTADDRESS:
496                         if (c->ipaddr.af != AF_INET) return NULL;
497
498                         *var_len = sizeof(c->ipaddr.ipaddr.ip4addr);
499                         return (u_char *)&(c->ipaddr.ipaddr.ip4addr);
500
501                 case RADIUSAUTHCLIENTID:
502                         if (c->shortname && c->shortname[0]) {
503                                 *var_len = strlen(c->shortname);
504                                 return (u_char *) c->shortname;
505                         }
506                         *var_len = strlen(c->longname);
507                         return (u_char *) c->longname;
508
509                 case RADIUSAUTHSERVACCESSREQUESTS:
510                         *var_len = sizeof(int32_t);
511                         return (u_char *) &c->auth->total_requests;
512
513                 case RADIUSAUTHSERVDUPACCESSREQUESTS:
514                         *var_len = sizeof(int32_t);
515                         return (u_char *) &c->auth->total_dup_requests;
516
517                 case RADIUSAUTHSERVACCESSACCEPTS:
518                         *var_len = sizeof(int32_t);
519                         return (u_char *) &c->auth->total_access_accepts;
520
521                 case RADIUSAUTHSERVACCESSREJECTS:
522                         *var_len = sizeof(int32_t);
523                         return (u_char *) &c->auth->total_access_rejects;
524
525                 case RADIUSAUTHSERVACCESSCHALLENGES:
526                         *var_len = sizeof(int32_t);
527                         return (u_char *) &c->auth->total_access_challenges;
528
529                 case RADIUSAUTHSERVMALFORMEDACCESSREQUESTS:
530                         *var_len = sizeof(int32_t);
531                         return (u_char *) &c->auth->total_malformed_requests;
532
533                 case RADIUSAUTHSERVBADAUTHENTICATORS:
534                         *var_len = sizeof(int32_t);
535                         return (u_char *) &c->auth->total_bad_authenticators;
536
537                 case RADIUSAUTHSERVPACKETSDROPPED:
538                         *var_len = sizeof(int32_t);
539                         return (u_char *) &c->auth->total_packets_dropped;
540
541                 case RADIUSAUTHSERVUNKNOWNTYPES:
542                         *var_len = sizeof(int32_t);
543                         return (u_char *) &c->auth->total_unknown_types;
544
545         }
546         return NULL;
547 }
548
549 static const CONF_PARSER snmp_config[] = {
550         { "snmp",              PW_TYPE_BOOLEAN,
551           0, &mainconfig.do_snmp,      "no" },
552         { "smux_password",     PW_TYPE_STRING_PTR,
553           0, &rad_snmp.smux_password, "" },
554         { "snmp_write_access", PW_TYPE_BOOLEAN,
555           0, &rad_snmp.snmp_write_access, "no" },
556         { NULL, -1, 0, NULL, NULL }
557 };
558
559
560 /* Register RADIUS MIBs. */
561 int
562 radius_snmp_init (CONF_SECTION *cs)
563 {
564         static int initialized = FALSE;
565
566         if (!initialized) {
567                 /*
568                  *  Initialize the RADIUS SNMP data structure.
569                  */
570                 memset(&rad_snmp, 0, sizeof(rad_snmp));
571
572                 rad_snmp.auth.ident = radiusd_version;
573 #ifdef WITH_ACCOUNTING
574                 rad_snmp.acct.ident = radiusd_version;
575
576
577 #endif
578                 rad_snmp.smux_event = SMUX_NONE;
579                 rad_snmp.smux_password = NULL;
580                 rad_snmp.snmp_write_access = FALSE;
581                 rad_snmp.smux_fd = -1;
582                 rad_snmp.smux_max_failures = 3; /* FIXME! get from config */
583                 rad_snmp.smux_failures = 0;
584
585                 rad_snmp.auth.start_time = time(NULL);
586                 rad_snmp.auth.last_reset_time = rad_snmp.auth.start_time;
587
588 #ifdef WITH_ACCOUNTING
589                 rad_snmp.acct.start_time = rad_snmp.auth.start_time;
590                 rad_snmp.acct.last_reset_time = rad_snmp.auth.start_time;
591 #endif
592         } else {
593                 rad_snmp.auth.last_reset_time = time(NULL);
594 #ifdef WITH_ACCOUNTING
595                 rad_snmp.acct.last_reset_time = rad_snmp.auth.last_reset_time;
596 #endif
597                 rad_snmp.smux_failures = 0;
598         }
599
600         /*
601          *  Parse the SNMP configuration information.
602          */
603         cf_section_parse(cs, NULL, snmp_config);
604
605         smux_stop();
606
607         if (!mainconfig.do_snmp) return 0;
608
609         /*
610          *  Do SMUX initialization.
611          */
612         smux_init (radius_oid, sizeof (radius_oid) / sizeof (oid));
613
614         if (!initialized) {
615 #ifdef WITH_ACCOUNTING
616                 SMUX_REGISTER_MIB("mibII/radius-acc-server", radiusacc_variables, variable, radacc_oid);
617 #endif
618                 SMUX_REGISTER_MIB("mibII/radius-auth-server", radiusauth_variables, variable, radauth_oid);
619         }
620
621         smux_start ();
622
623         initialized = TRUE;
624
625         return 1;
626 }
627
628 #endif /* WITH_SNMP */