1 /* This file is part of GNU Radius.
2 Copyright (C) 2000,2001,2002,2003,2004,2006,
3 2007,2008 Free Software Foundation, Inc.
4
5 Written by Sergey Poznyakoff
6
7 GNU Radius is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 GNU Radius is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU Radius; if not, write to the Free Software Foundation,
19 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20
21 #if defined(HAVE_CONFIG_H)
22 # include <config.h>
23 #endif
24
25 #ifdef USE_SNMP
26
27 #include <sys/types.h>
28 #include <sys/socket.h>
29
30 #include <snmp/asn1.h>
31 #include <snmp/snmp.h>
32 #include <snmp/mib.h>
33
34 #include <sysdep.h>
35 #include <radiusd.h>
36 #include <radius/radutmp.h>
37 #include <radsnmp.h>
38 #define SERVER
39 #include <radmibs.h>
40
41 #define MAXOIDLEN 512
42
43 struct snmp_pdu * snmp_agent_response(struct snmp_pdu *pdu, int access);
44 int variable_cmp(struct snmp_var *v1, struct snmp_var *v2);
45 static grad_nas_t *nas_lookup_index(int ind);
46 static void snmpserv_before_config_hook(void *unused1, void *unused2);
47 static void snmpserv_after_config_hook(void *arg, void *unused);
48 static void snmp_tree_init();
49
50 static grad_list_t /* of ACL */ *snmp_acl;
51 static grad_list_t /* of Community */ *commlist;
52 Server_stat *server_stat;
53 struct radstat radstat;
54
55 /* ************************************************************************ */
56 /* Configuration file */
57
58 static grad_list_t /* of NETNAME */ *netlist;
59
60 static int
_netname_cmp(const void * item,const void * data)61 _netname_cmp(const void *item, const void *data)
62 {
63 const NETNAME *p = item;
64 const char *name = data;
65 return strcmp(p->name, name);
66 }
67
68 static NETNAME *
netname_find(char * name)69 netname_find(char *name)
70 {
71 return grad_list_locate(netlist, name, _netname_cmp);
72 }
73
74 static int
_netdef_destroy(void * item,void * data ARG_UNUSED)75 _netdef_destroy(void *item, void *data ARG_UNUSED)
76 {
77 grad_free(item);
78 return 0;
79 }
80
81 static int
_netname_destroy(void * item,void * data ARG_UNUSED)82 _netname_destroy(void *item, void *data ARG_UNUSED)
83 {
84 NETNAME *p = item;
85 grad_free(p->name);
86 grad_list_destroy(&p->netlist, _netdef_destroy, NULL);
87 grad_free(p);
88 return 0;
89 }
90
91 static void
netgrad_list_destroy()92 netgrad_list_destroy()
93 {
94 grad_list_destroy(&netlist, _netname_destroy, NULL);
95 }
96
97 /* ************************************************************************ */
98 /* ACL fiddling */
99
100 void
snmp_add_community(char * str,int access)101 snmp_add_community(char *str, int access)
102 {
103 Community *p = grad_emalloc(sizeof(*p));
104 p->name = grad_estrdup(str);
105 p->access = access;
106 if (!commlist)
107 commlist = grad_list_create();
108 grad_list_append(commlist, p);
109 }
110
111
112 static int
_community_cmp(const void * item,const void * data)113 _community_cmp(const void *item, const void *data)
114 {
115 const Community *p = item;
116 return strcmp(p->name, (const char*) data);
117 }
118
119
120 Community *
snmp_find_community(char * str)121 snmp_find_community(char *str)
122 {
123 return grad_list_locate(commlist, str, _community_cmp);
124 }
125
126 static int
_community_destroy(void * item,void * data)127 _community_destroy(void *item, void *data)
128 {
129 Community *p = item;
130 grad_free(p->name);
131 grad_free(p);
132 return 0;
133 }
134
135 void
snmp_free_communities()136 snmp_free_communities()
137 {
138 grad_list_destroy(&commlist, _community_destroy, NULL);
139 }
140
141 struct acl_closure {
142 grad_uint32_t ip;
143 char *community;
144 int access;
145 };
146
147 int
_netdef_cmp(const void * item,const void * data)148 _netdef_cmp(const void *item, const void *data)
149 {
150 const grad_netdef_t *nd = item;
151 const struct acl_closure *clos = data;
152
153 if (grad_ip_in_net_p(nd, clos->ip))
154 return 0;
155 return 1;
156 }
157
158 int
_acl_iterator(void * item,void * data)159 _acl_iterator(void *item, void *data)
160 {
161 ACL *acl = item;
162 struct acl_closure *clos = data;
163
164 if (acl->community
165 && strcmp(acl->community->name, clos->community))
166 return 0;
167 if (grad_list_locate(acl->netlist, data, _netdef_cmp)) {
168 clos->access = acl->community ? acl->community->access : 0;
169 return 1;
170 }
171 return 0;
172 }
173
174 int
check_acl(grad_uint32_t ip,char * community)175 check_acl(grad_uint32_t ip, char *community)
176 {
177 struct acl_closure clos;
178
179 clos.ip = ntohl(ip);
180 clos.community = community;
181 clos.access = 0;
182 grad_list_iterate(snmp_acl, _acl_iterator, &clos);
183 return clos.access;
184 }
185
186 void
snmp_add_acl(Community * community,grad_list_t * netlist)187 snmp_add_acl(Community *community, grad_list_t /* of grad_netdef_t */ *netlist)
188 {
189 ACL *acl;
190
191 acl = grad_emalloc(sizeof(*acl));
192 acl->community = community;
193 acl->netlist = netlist;
194 if (!snmp_acl)
195 snmp_acl = grad_list_create();
196 grad_list_append(snmp_acl, acl);
197 }
198
199 static int
_acl_destroy(void * item,void * data)200 _acl_destroy(void *item, void *data)
201 {
202 grad_free(item);
203 return 0;
204 }
205
206 void
snmp_free_acl()207 snmp_free_acl()
208 {
209 grad_list_destroy(&snmp_acl, _acl_destroy, NULL);
210 }
211
212
213 /* ************************************************************************* */
214 static int _opened_snmp_sockets;
215
216 int
snmp_stmt_begin(int finish,void * data,void * up_data)217 snmp_stmt_begin(int finish, void *data, void *up_data)
218 {
219 if (!finish) {
220 netgrad_list_destroy();
221 snmp_free_communities();
222 snmp_free_acl();
223 _opened_snmp_sockets = 0;
224 } else if (radius_mode == MODE_DAEMON
225 && !_opened_snmp_sockets
226 && snmp_port)
227 udp_open(R_SNMP, INADDR_ANY, snmp_port, 1);
228 return 0;
229 }
230
231 static int
snmp_cfg_ident(int argc,cfg_value_t * argv,void * block_data,void * handler_data)232 snmp_cfg_ident(int argc, cfg_value_t *argv, void *block_data,
233 void *handler_data)
234 {
235 if (argc > 2) {
236 cfg_argc_error(0);
237 return 0;
238 }
239
240 if (argv[1].type != CFG_STRING) {
241 cfg_type_error(CFG_STRING);
242 return 0;
243 }
244 if (server_id)
245 grad_free(server_id);
246 server_id = grad_estrdup(argv[1].v.string);
247 return 0;
248 }
249
250 static grad_keyword_t snmp_access[] = {
251 { "read-only", SNMP_RO },
252 { "read-write", SNMP_RW },
253 { "ro", SNMP_RO },
254 { "rw", SNMP_RW },
255 { 0 }
256 };
257
258 static int
snmp_cfg_community(int argc,cfg_value_t * argv,void * block_data,void * handler_data)259 snmp_cfg_community(int argc, cfg_value_t *argv,
260 void *block_data, void *handler_data)
261 {
262 int access;
263
264 if (argc != 3) {
265 cfg_argc_error(argc < 3);
266 return 0;
267 }
268
269 if (argv[1].type != CFG_STRING
270 || argv[2].type != CFG_STRING) {
271 cfg_type_error(CFG_STRING);
272 return 0;
273 }
274
275 access = grad_xlat_keyword(snmp_access, argv[2].v.string, -1);
276 if (access == -1)
277 return 1;
278
279 if (snmp_find_community(argv[1].v.string)) {
280 grad_log(GRAD_LOG_ERR,
281 _("%s:%d: community %s already declared"),
282 cfg_filename, cfg_line_num, argv[1].v.string);
283 return 0;
284 }
285
286 snmp_add_community(argv[1].v.string, access);
287 return 0;
288 }
289
290 int
snmp_cfg_listen(int argc,cfg_value_t * argv,void * block_data,void * handler_data)291 snmp_cfg_listen(int argc, cfg_value_t *argv,
292 void *block_data, void *handler_data)
293 {
294 int i, errcnt = 0;
295
296 if (argc == 2 && argv[1].type == CFG_BOOLEAN) {
297 if (argv[1].v.bool == 0)
298 snmp_port = 0;
299 return 0;
300 }
301
302 for (i = 1; i < argc; i++)
303 if (argv[i].type != CFG_HOST) {
304 cfg_type_error(CFG_HOST);
305 errcnt++;
306 }
307
308 if (errcnt == 0 && radius_mode == MODE_DAEMON)
309 for (i = 1; i < argc; i++)
310 udp_open(R_SNMP,
311 argv[i].v.host.ipaddr,
312 argv[i].v.host.port > 0 ?
313 argv[i].v.host.port : snmp_port,
314 1);
315 _opened_snmp_sockets++;
316 return 0;
317 }
318
319 static int
snmp_cfg_network(int argc,cfg_value_t * argv,void * block_data,void * handler_data)320 snmp_cfg_network(int argc, cfg_value_t *argv,
321 void *block_data, void *handler_data)
322 {
323 int i;
324 NETNAME *np;
325
326 if (argc < 3) {
327 cfg_argc_error(1);
328 return 0;
329 }
330
331 if (argv[1].type != CFG_STRING) {
332 cfg_type_error(CFG_STRING);
333 return 0;
334 }
335
336 np = grad_emalloc(sizeof(*np));
337 if (!netlist)
338 netlist = grad_list_create(netlist);
339
340 grad_list_append(netlist, np);
341 np->name = grad_estrdup(argv[1].v.string);
342 np->netlist = grad_list_create();
343 for (i = 2; i < argc; i++) {
344 if (argv[i].type != CFG_NETWORK) {
345 grad_log(GRAD_LOG_ERR,
346 _("%s:%d: list item %d has wrong datatype"),
347 cfg_filename, cfg_line_num,
348 i);
349 } else {
350 grad_netdef_t *net = grad_emalloc(sizeof(*net));
351 net->ipaddr = argv[i].v.network.ipaddr;
352 net->netmask = argv[i].v.network.netmask;
353 grad_list_append(np->netlist, net);
354 }
355 }
356 return 0;
357 }
358
359 static int
snmp_cfg_allow(int argc,cfg_value_t * argv,void * block_data,void * handler_data)360 snmp_cfg_allow(int argc, cfg_value_t *argv,
361 void *block_data, void *handler_data)
362 {
363 Community *comm;
364 NETNAME *nn;
365
366 if (argc != 3) {
367 cfg_argc_error(argc < 3);
368 return 0;
369 }
370
371 if (argv[1].type != CFG_STRING || argv[2].type != CFG_STRING) {
372 cfg_type_error(CFG_STRING);
373 return 0;
374 }
375
376 if ((nn = netname_find(argv[1].v.string)) == NULL) {
377 grad_log(GRAD_LOG_ERR, _("%s:%d: no such network: %s"),
378 cfg_filename, cfg_line_num, argv[1].v.string);
379 return 0;
380 }
381
382 comm = snmp_find_community(argv[2].v.string);
383 if (!comm) {
384 grad_log(GRAD_LOG_ERR,
385 _("%s:%d: undefined community %s"),
386 cfg_filename, cfg_line_num, argv[2].v.string);
387 return 0;
388 }
389
390 snmp_add_acl(comm, nn->netlist);
391 return 0;
392 }
393
394 static int
snmp_cfg_deny(int argc,cfg_value_t * argv,void * block_data,void * handler_data)395 snmp_cfg_deny(int argc, cfg_value_t *argv,
396 void *block_data, void *handler_data)
397 {
398 NETNAME *nn;
399
400 if (argc != 2) {
401 cfg_argc_error(argc < 2);
402 return 0;
403 }
404
405 if (argv[1].type != CFG_STRING) {
406 cfg_type_error(CFG_STRING);
407 return 0;
408 }
409
410 if ((nn = netname_find(argv[1].v.string)) == NULL) {
411 grad_log(GRAD_LOG_ERR, _("%s:%d: no such network: %s"),
412 cfg_filename, cfg_line_num, argv[1].v.string);
413 return 0;
414 }
415
416 snmp_add_acl(NULL, nn->netlist);
417 return 0;
418 }
419
420 static struct cfg_stmt acl_stmt[] = {
421 { "allow", CS_STMT, NULL, snmp_cfg_allow, NULL, NULL, NULL },
422 { "deny", CS_STMT, NULL, snmp_cfg_deny, NULL, NULL, NULL },
423 { NULL },
424 };
425
426 struct cfg_stmt snmp_stmt[] = {
427 { "port", CS_STMT, NULL, cfg_get_port, &snmp_port, NULL, NULL },
428 { "listen", CS_STMT, NULL, snmp_cfg_listen, NULL, NULL, NULL },
429 { "max-requests", CS_STMT, NULL,
430 cfg_get_integer, &request_class[R_SNMP].max_requests,
431 NULL, NULL },
432 { "time-to-live", CS_STMT, NULL,
433 cfg_get_integer, &request_class[R_SNMP].ttl,
434 NULL, NULL },
435 { "request-cleanup-delay", CS_STMT, NULL,
436 cfg_get_integer, &request_class[R_SNMP].cleanup_delay,
437 NULL, NULL },
438 { "ident", CS_STMT, NULL, snmp_cfg_ident, NULL,
439 NULL, NULL },
440 { "community", CS_STMT, NULL, snmp_cfg_community, NULL,
441 NULL, NULL },
442 { "storage", CS_BLOCK, NULL, NULL, NULL,
443 storage_stmt, NULL },
444 { "network", CS_STMT, NULL, snmp_cfg_network, NULL,
445 NULL, NULL },
446 { "acl", CS_BLOCK, NULL, NULL, NULL, acl_stmt, NULL },
447 /* Obsolete statements */
448 { "spawn", CS_STMT, NULL, cfg_obsolete, NULL, NULL, NULL },
449 { NULL, }
450 };
451
452 static void
snmpserv_before_config_hook(void * a ARG_UNUSED,void * b ARG_UNUSED)453 snmpserv_before_config_hook(void *a ARG_UNUSED, void *b ARG_UNUSED)
454 {
455 if (server_stat) {
456 server_stat->auth.status = serv_init;
457 server_stat->acct.status = serv_init;
458 }
459 }
460
461 static void
snmpserv_after_config_hook(void * arg,void * data ARG_UNUSED)462 snmpserv_after_config_hook(void *arg, void *data ARG_UNUSED)
463 {
464 stat_done();
465 stat_init();
466 if (server_stat) {
467 grad_nas_t *nas;
468 grad_iterator_t *itr;
469
470 server_stat->auth.status =
471 suspend_flag ? serv_suspended : serv_running;
472 snmp_auth_server_reset();
473
474 server_stat->acct.status = server_stat->auth.status;
475 snmp_acct_server_reset();
476
477 *(serv_stat*)arg = server_stat->auth.status;
478 snmp_init_nas_stat();
479 itr = grad_nas_iterator();
480 for (nas = grad_iterator_first(itr); nas; nas = grad_iterator_next(itr))
481 snmp_attach_nas_stat(nas);
482 grad_iterator_destroy(&itr);
483 snmp_sort_nas_stat();
484 }
485 }
486
487 void
snmpserv_init(void * arg)488 snmpserv_init(void *arg)
489 {
490 stat_init();
491 radiusd_set_preconfig_hook(snmpserv_before_config_hook, NULL, 0);
492 radiusd_set_postconfig_hook(snmpserv_after_config_hook, arg, 0);
493 snmp_tree_init();
494 snmpserv_after_config_hook(arg, NULL);
495 }
496
497 /* ************************************************************************ */
498 /* Application-specific */
499
500 struct mib_node_t *mib_tree;
501 int snmp_auth_handler(enum mib_node_cmd cmd, void *closure, subid_t subid,
502 struct snmp_var **varp, int *errp);
503 int snmp_auth_v_handler(enum mib_node_cmd cmd, void *closure, subid_t subid,
504 struct snmp_var **varp, int *errp);
505 int snmp_acct_handler(enum mib_node_cmd cmd, void *closure, subid_t subid,
506 struct snmp_var **varp, int *errp);
507 int snmp_acct_v_handler(enum mib_node_cmd cmd, void *closure, subid_t subid,
508 struct snmp_var **varp, int *errp);
509 int snmp_serv_handler(enum mib_node_cmd cmd, void *closure, subid_t subid,
510 struct snmp_var **varp, int *errp);
511 int snmp_stat_handler(enum mib_node_cmd cmd, void *closure, subid_t subid,
512 struct snmp_var **varp, int *errp);
513
514 int snmp_stat_nas1(enum mib_node_cmd cmd, void *closure, subid_t subid,
515 struct snmp_var **varp, int *errp);
516 int snmp_stat_nas2(enum mib_node_cmd cmd, void *closure, subid_t subid,
517 struct snmp_var **varp, int *errp);
518 int snmp_stat_nas3(enum mib_node_cmd cmd, void *closure, subid_t subid,
519 struct snmp_var **varp, int *errp);
520 int snmp_stat_nas4(enum mib_node_cmd cmd, void *closure, subid_t subid,
521 struct snmp_var **varp, int *errp);
522 int snmp_nas_table(enum mib_node_cmd cmd, void *closure, subid_t subid,
523 struct snmp_var **varp, int *errp);
524 int snmp_port_index1(enum mib_node_cmd cmd, void *closure, subid_t subid,
525 struct snmp_var **varp, int *errp);
526 int snmp_port_index2(enum mib_node_cmd cmd, void *closure, subid_t subid,
527 struct snmp_var **varp, int *errp);
528 int snmp_port_table(enum mib_node_cmd cmd, void *closure, subid_t subid,
529 struct snmp_var **varp, int *errp);
530
531 struct auth_mib_data {
532 int nas_index;
533 };
534
535 struct nas_data {
536 subid_t quad[4];
537 };
538
539 struct nas_table_data {
540 int row;
541 };
542
543 struct port_data {
544 int nas_index;
545 int port_no;
546 };
547
548 struct port_table_data {
549 int port_index;
550 };
551
552 union snmpserv_data {
553 struct auth_mib_data auth_mib;
554 struct nas_data nas;
555 struct nas_table_data nas_data;
556 struct port_data port;
557 struct port_table_data port_table;
558 };
559
560 static union snmpserv_data *__snmpserv_data;
561
562 static void *
snmpserv_get_data()563 snmpserv_get_data()
564 {
565 if (!__snmpserv_data) {
566 __snmpserv_data = grad_emalloc(sizeof(*__snmpserv_data));
567 __snmpserv_data->auth_mib.nas_index = 1;
568 }
569 return __snmpserv_data;
570 }
571
572 static struct mib_data {
573 oid_t oid;
574 mib_fp handler;
575 void *closure;
576 } mib_data[] = {
577 /* Authentication */
578 /* Fixed oids */
579 { oid_AuthServIdent, snmp_auth_handler, NULL },
580 { oid_AuthServUpTime, snmp_auth_handler, NULL },
581 { oid_AuthServResetTime, snmp_auth_handler, NULL },
582 { oid_AuthServConfigReset, snmp_auth_handler, NULL },
583 { oid_AuthServTotalAccessRequests, snmp_auth_handler, NULL },
584 { oid_AuthServTotalInvalidRequests, snmp_auth_handler, NULL },
585 { oid_AuthServTotalDupAccessRequests, snmp_auth_handler, NULL },
586 { oid_AuthServTotalAccessAccepts, snmp_auth_handler, NULL },
587 { oid_AuthServTotalAccessRejects, snmp_auth_handler, NULL },
588 { oid_AuthServTotalAccessChallenges, snmp_auth_handler, NULL },
589 { oid_AuthServTotalMalformedAccessRequests,
590 snmp_auth_handler, NULL },
591 { oid_AuthServTotalBadAuthenticators, snmp_auth_handler, NULL },
592 { oid_AuthServTotalPacketsDropped, snmp_auth_handler, NULL },
593 { oid_AuthServTotalUnknownTypes, snmp_auth_handler, NULL },
594
595 /* Variable oids */
596 { oid_AuthClientIndex, snmp_auth_v_handler,NULL },
597 { oid_AuthClientAddress, snmp_auth_v_handler,NULL },
598 { oid_AuthClientID, snmp_auth_v_handler,NULL },
599 { oid_AuthServAccessRequests, snmp_auth_v_handler,NULL },
600 { oid_AuthServDupAccessRequests, snmp_auth_v_handler,NULL },
601 { oid_AuthServAccessAccepts, snmp_auth_v_handler,NULL },
602 { oid_AuthServAccessRejects, snmp_auth_v_handler,NULL },
603 { oid_AuthServAccessChallenges, snmp_auth_v_handler,NULL },
604 { oid_AuthServMalformedAccessRequests, snmp_auth_v_handler,NULL },
605 { oid_AuthServBadAuthenticators, snmp_auth_v_handler,NULL },
606 { oid_AuthServPacketsDropped, snmp_auth_v_handler,NULL },
607 { oid_AuthServUnknownTypes, snmp_auth_v_handler,NULL },
608
609 /* Accounting */
610 /* Fixed oids */
611 { oid_AccServIdent, snmp_acct_handler, NULL },
612 { oid_AccServUpTime, snmp_acct_handler, NULL },
613 { oid_AccServResetTime, snmp_acct_handler, NULL },
614 { oid_AccServConfigReset, snmp_acct_handler, NULL },
615 { oid_AccServTotalRequests, snmp_acct_handler, NULL },
616 { oid_AccServTotalInvalidRequests, snmp_acct_handler, NULL },
617 { oid_AccServTotalDupRequests, snmp_acct_handler, NULL },
618 { oid_AccServTotalResponses, snmp_acct_handler, NULL },
619 { oid_AccServTotalMalformedRequests, snmp_acct_handler, NULL },
620 { oid_AccServTotalBadAuthenticators, snmp_acct_handler, NULL },
621 { oid_AccServTotalPacketsDropped, snmp_acct_handler, NULL },
622 { oid_AccServTotalNoRecords, snmp_acct_handler, NULL },
623 { oid_AccServTotalUnknownTypes, snmp_acct_handler, NULL },
624
625 /* Variable oids */
626 { oid_AccClientIndex, snmp_acct_v_handler,NULL },
627 { oid_AccClientAddress, snmp_acct_v_handler,NULL },
628 { oid_AccClientID, snmp_acct_v_handler,NULL },
629 { oid_AccServPacketsDropped, snmp_acct_v_handler,NULL },
630 { oid_AccServRequests, snmp_acct_v_handler,NULL },
631 { oid_AccServDupRequests, snmp_acct_v_handler,NULL },
632 { oid_AccServResponses, snmp_acct_v_handler,NULL },
633 { oid_AccServBadAuthenticators, snmp_acct_v_handler,NULL },
634 { oid_AccServMalformedRequests, snmp_acct_v_handler,NULL },
635 { oid_AccServNoRecords, snmp_acct_v_handler,NULL },
636 { oid_AccServUnknownTypes, snmp_acct_v_handler,NULL },
637
638 #ifdef SNMP_COMPAT_0_96
639
640 /* Server */
641 { oid_grad_radiusServerUpTime, snmp_serv_handler, NULL },
642 { oid_grad_radiusServerResetTime, snmp_serv_handler, NULL },
643 { oid_grad_radiusServerState, snmp_serv_handler, NULL },
644
645
646 /* Statistics */
647 { oid_grad_StatIdent, snmp_stat_handler, NULL },
648 { oid_grad_StatUpTime, snmp_stat_handler, NULL },
649 { oid_grad_StatConfigReset, snmp_stat_handler, NULL },
650 { oid_grad_StatTotalLines, snmp_stat_handler, NULL },
651 { oid_grad_StatTotalLinesInUse, snmp_stat_handler, NULL },
652 { oid_grad_StatTotalLinesIdle, snmp_stat_handler, NULL },
653
654 /* Variable oids */
655 { oid_grad_NASIndex1, snmp_stat_nas1, NULL },
656 { oid_grad_NASIndex2, snmp_stat_nas2, NULL },
657 { oid_grad_NASIndex3, snmp_stat_nas3, NULL },
658 { oid_grad_NASIndex4, snmp_stat_nas4, NULL },
659
660 { oid_grad_NASAddress, snmp_nas_table, NULL },
661 { oid_grad_NASID, snmp_nas_table, NULL },
662 { oid_grad_NASLines, snmp_nas_table, NULL },
663 { oid_grad_NASLinesInUse, snmp_nas_table, NULL },
664 { oid_grad_NASLinesIdle, snmp_nas_table, NULL },
665
666 { oid_grad_StatPortIndex1, snmp_port_index1, NULL },
667 { oid_grad_StatPortIndex2, snmp_port_index2, NULL },
668
669 /* port table */
670 { oid_grad_StatPortNASIndex, snmp_port_table, NULL },
671 { oid_grad_StatPortID, snmp_port_table, NULL },
672 { oid_grad_StatPortFramedAddress, snmp_port_table, NULL },
673 { oid_grad_StatPortTotalLogins, snmp_port_table, NULL },
674 { oid_grad_StatPortStatus, snmp_port_table, NULL },
675 { oid_grad_StatPortStatusChangeTimestamp, snmp_port_table, NULL },
676 { oid_grad_StatPortUpTime, snmp_port_table, NULL },
677 { oid_grad_StatPortLastLoginName, snmp_port_table, NULL },
678 { oid_grad_StatPortLastLoginTimestamp, snmp_port_table, NULL },
679 { oid_grad_StatPortLastLogoutTimestamp, snmp_port_table, NULL },
680 { oid_grad_StatPortIdleTotalTime, snmp_port_table, NULL },
681 { oid_grad_StatPortIdleMaxTime, snmp_port_table, NULL },
682 { oid_grad_StatPortIdleMaxTimestamp, snmp_port_table, NULL },
683 { oid_grad_StatPortInUseTotalTime, snmp_port_table, NULL },
684 { oid_grad_StatPortInUseMaxTime, snmp_port_table, NULL },
685 { oid_grad_StatPortInUseMaxTimestamp, snmp_port_table, NULL },
686 #endif
687 /* enterprise.gnu.radius subtree */
688 /* Server */
689 { oid_radiusServerUpTime, snmp_serv_handler, NULL },
690 { oid_radiusServerResetTime, snmp_serv_handler, NULL },
691 { oid_radiusServerState, snmp_serv_handler, NULL },
692
693
694 /* Statistics */
695 { oid_StatIdent, snmp_stat_handler, NULL },
696 { oid_StatUpTime, snmp_stat_handler, NULL },
697 { oid_StatConfigReset, snmp_stat_handler, NULL },
698 { oid_StatTotalLines, snmp_stat_handler, NULL },
699 { oid_StatTotalLinesInUse, snmp_stat_handler, NULL },
700 { oid_StatTotalLinesIdle, snmp_stat_handler, NULL },
701
702 /* Variable oids */
703 { oid_NASIndex1, snmp_stat_nas1, NULL },
704 { oid_NASIndex2, snmp_stat_nas2, NULL },
705 { oid_NASIndex3, snmp_stat_nas3, NULL },
706 { oid_NASIndex4, snmp_stat_nas4, NULL },
707
708 { oid_NASAddress, snmp_nas_table, NULL },
709 { oid_NASID, snmp_nas_table, NULL },
710 { oid_NASLines, snmp_nas_table, NULL },
711 { oid_NASLinesInUse, snmp_nas_table, NULL },
712 { oid_NASLinesIdle, snmp_nas_table, NULL },
713
714 { oid_StatPortIndex1, snmp_port_index1, NULL },
715 { oid_StatPortIndex2, snmp_port_index2, NULL },
716
717 /* port table */
718 { oid_StatPortNASIndex, snmp_port_table, NULL },
719 { oid_StatPortID, snmp_port_table, NULL },
720 { oid_StatPortFramedAddress, snmp_port_table, NULL },
721 { oid_StatPortTotalLogins, snmp_port_table, NULL },
722 { oid_StatPortStatus, snmp_port_table, NULL },
723 { oid_StatPortStatusChangeTimestamp, snmp_port_table, NULL },
724 { oid_StatPortUpTime, snmp_port_table, NULL },
725 { oid_StatPortLastLoginName, snmp_port_table, NULL },
726 { oid_StatPortLastLoginTimestamp, snmp_port_table, NULL },
727 { oid_StatPortLastLogoutTimestamp, snmp_port_table, NULL },
728 { oid_StatPortIdleTotalTime, snmp_port_table, NULL },
729 { oid_StatPortIdleMaxTime, snmp_port_table, NULL },
730 { oid_StatPortIdleMaxTimestamp, snmp_port_table, NULL },
731 { oid_StatPortInUseTotalTime, snmp_port_table, NULL },
732 { oid_StatPortInUseMaxTime, snmp_port_table, NULL },
733 { oid_StatPortInUseMaxTimestamp, snmp_port_table, NULL },
734
735 };
736
737 void
snmp_tree_init()738 snmp_tree_init()
739 {
740 struct mib_data *p;
741 struct mib_node_t *node;
742
743 snmp_init(0, 0, (snmp_alloc_t)grad_emalloc, (snmp_free_t)grad_free);
744
745 for (p = mib_data; p < mib_data + GRAD_NITEMS(mib_data); p++) {
746 mib_insert(&mib_tree, p->oid, &node);
747 if (p->handler) {
748 node->handler = p->handler;
749 node->closure = p->closure;
750 }
751 }
752 }
753
754 /* Mark reset of the auth server. Do not do any real work, though.
755 */
756 void
snmp_auth_server_reset()757 snmp_auth_server_reset()
758 {
759 struct timeval tv;
760 struct timezone tz;
761
762 gettimeofday(&tv, &tz);
763 server_stat->auth.reset_time = tv;
764 }
765
766 /* Mark reset of the acct server. Again, no real work, please.
767 */
768 void
snmp_acct_server_reset()769 snmp_acct_server_reset()
770 {
771 struct timeval tv;
772 struct timezone tz;
773
774 gettimeofday(&tv, &tz);
775 server_stat->acct.reset_time = tv;
776 }
777
778
779 /* ************************************************************************* */
780 /* FIXME: these belong to snmp_mib.c */
781
782 int mib_get(struct mib_node_t *node, struct snmp_var **varp,
783 int *errp);
784 int mib_get_next(struct mib_node_t *node, struct snmp_var **varp,
785 int *errp);
786 int mib_set_try(struct mib_node_t *node, struct snmp_var **varp,
787 int *errp);
788 int mib_set(struct mib_node_t *node, struct snmp_var **varp);
789 oid_t mib_node_oid(struct mib_node_t *node);
790
791 int mib_down(struct mib_node_t *node, oid_t oid);
792 void mib_reset(struct mib_node_t *node);
793
794 /* For a given node generate its oid. Note: When not needed anymore, the
795 oid should be freed by snmp_free */
796 oid_t
mib_node_oid(struct mib_node_t * node)797 mib_node_oid(struct mib_node_t *node)
798 {
799 oid_t oid;
800 int i;
801
802 oid = oid_create(node->index+1);
803 if (!oid)
804 return oid;
805 for (i = node->index; node && i >= 0; i--, node = node->up) {
806 SUBID(oid,i) = (node->subid != SUBID_X) ?
807 node->subid :
808 (subid_t)(*node->handler)(MIB_NODE_GET_SUBID,
809 node->closure,
810 0,
811 NULL, NULL);
812 }
813 return oid;
814 }
815
816 void
mib_reset(struct mib_node_t * node)817 mib_reset(struct mib_node_t *node)
818 {
819 if (node->subid == SUBID_X) {
820 (*node->handler)(MIB_NODE_RESET, node->closure,
821 0,
822 NULL, NULL);
823 }
824 }
825
826 int
mib_down(struct mib_node_t * node,oid_t oid)827 mib_down(struct mib_node_t *node, oid_t oid)
828 {
829 if (node->subid == SUBID_X) {
830 if (OIDLEN(oid) <= node->index) {
831 (*node->handler)(MIB_NODE_RESET, node->closure,
832 0,
833 NULL, NULL);
834 return 0;
835 } else if ((*node->handler)(MIB_NODE_NEXT, node->closure,
836 SUBID(oid,node->index),
837 NULL, NULL) == 0)
838 return 0;
839 }
840 return 1;
841 }
842
843 /* Get next node.
844 Input: node -- root node to start search from
845 varp[0][0] -- Variable to start from
846 Output: varp[0][0] -- Next variable (with its value)
847 errp[0] -- Error status
848 Return: 0 -- OK */
849 int
mib_get_next(struct mib_node_t * node,struct snmp_var ** varp,int * errp)850 mib_get_next(struct mib_node_t *node, struct snmp_var **varp, int *errp)
851 {
852 int rc;
853 oid_t oid = (*varp)->name;
854 char buf[MAXOIDLEN];
855 struct snmp_var *temp_var;
856 struct mib_node_t *found_node;
857
858 GRAD_DEBUG1(2, "OID %s",
859 sprint_oid(buf, sizeof(buf), (*varp)->name));
860
861 /* first, find the node itself */
862 rc = mib_lookup(node, oid, OIDLEN(oid), &found_node);
863
864 *errp = SNMP_ERR_NOERROR;
865
866 do {
867 int depth = 0;
868 node = found_node;
869 mib_reset(node);
870
871 while (node) {
872 if (depth++ && node->next == NULL)
873 break;
874
875 if (node->next) {
876 node = node->next;
877 mib_reset(node);
878 } else if (node->subid == SUBID_X) {
879 if (mib_down(node, oid))
880 node = NULL;
881 } else
882 node = node->down;
883 }
884
885 if (!node) {
886 /* The subtree is exhausted. Roll back until we find
887 first non-traversed down link */
888 GRAD_DEBUG2(2, "rolling back from %d:%d",
889 found_node->index,
890 found_node->subid);
891 while (node = found_node->up) {
892 mib_reset(node);
893 if (node->down && node->down != found_node)
894 break;
895 if (node->subid == SUBID_X &&
896 mib_down(node, oid) == 0)
897 break;
898 found_node = node;
899 }
900
901 if (node)
902 GRAD_DEBUG2(2, "rollback stopped at %d:%d",
903 node->index,
904 node->subid);
905
906 if (node && node->subid != SUBID_X)
907 node = node->down;
908
909 }
910
911 found_node = node;
912
913 } while (found_node && found_node->handler == NULL);
914
915 if (!found_node || !found_node->handler) {
916 *errp = SNMP_ERR_NOSUCHNAME;
917 return -1;
918 }
919
920 oid = mib_node_oid(found_node);
921 temp_var = snmp_var_create(oid);
922 snmp_free(oid);
923
924 GRAD_DEBUG1(2, "NXT %s", sprint_oid(buf, sizeof(buf), temp_var->name));
925
926 *varp = temp_var;
927 (*found_node->handler)(MIB_NODE_GET,
928 found_node->closure,
929 SUBID(temp_var->name,OIDLEN(temp_var->name)-1),
930 varp, errp);
931 snmp_var_free(temp_var);
932 return 0;
933 }
934
935 /* Get the value of a given variable
936 Input: node -- root node to start search from
937 varp[0][0] -- Variable to look for
938 Output: varp[0][0] -- Variable with value (not the same as on input!)
939 errp[0] -- Error status
940 Return: 0 -- OK */
941 int
mib_get(struct mib_node_t * node,struct snmp_var ** varp,int * errp)942 mib_get(struct mib_node_t *node, struct snmp_var **varp, int *errp)
943 {
944 oid_t oid = (*varp)->name;
945
946 if (mib_lookup(node, oid, OIDLEN(oid), &node) != MIB_MATCH_EXACT ||
947 !node->handler) {
948 *errp = SNMP_ERR_NOSUCHNAME;
949 return -1;
950 }
951
952 return (*node->handler)(MIB_NODE_GET, node->closure,
953 SUBID(oid,OIDLEN(oid)-1),
954 varp, errp);
955 }
956
957 /* Check if a variable can be set
958 Input: node -- tree node to start from
959 varp[0][0] -- variable to look for
960 Output:errp -- error status
961 Return: 0 -- OK */
962 int
mib_set_try(struct mib_node_t * node,struct snmp_var ** varp,int * errp)963 mib_set_try(struct mib_node_t *node, struct snmp_var **varp, int *errp)
964 {
965 oid_t oid = (*varp)->name;
966
967 if (mib_lookup(node, oid, OIDLEN(oid), &node) != MIB_MATCH_EXACT ||
968 !node->handler) {
969 *errp = SNMP_ERR_NOSUCHNAME;
970 return -1;
971 }
972
973 if ((*node->handler)(MIB_NODE_SET_TRY, node->closure,
974 SUBID(oid,OIDLEN(oid)-1),
975 varp, errp) != 0)
976 return -1;
977 return 0;
978 }
979
980 /* Set a variable to the new value. The fuction must be called only
981 when previous call to mib_set_try returned OK, so only rudimentary
982 error checking is done.
983 Input: node -- tree node to start from
984 varp[0][0] -- variable to be set
985 Return: 0 -- OK */
986 int
mib_set(struct mib_node_t * node,struct snmp_var ** varp)987 mib_set(struct mib_node_t *node, struct snmp_var **varp)
988 {
989 oid_t oid = (*varp)->name;
990
991 if (mib_lookup(node, oid, OIDLEN(oid), &node) != MIB_MATCH_EXACT ||
992 !node->handler) {
993 return -1;
994 }
995
996 return (*node->handler)(MIB_NODE_SET, node->closure,
997 SUBID(oid,OIDLEN(oid)-1),
998 varp, NULL);
999 }
1000
1001 /* ************************************************************************* */
1002
1003 /* Generate response PDU for a given request.
1004 Input: pdu -- Request pdu
1005 access -- Access rights
1006 Return:Response PDU, NULL on error */
1007 struct snmp_pdu *
snmp_agent_response(struct snmp_pdu * pdu,int access)1008 snmp_agent_response(struct snmp_pdu *pdu, int access)
1009 {
1010 struct snmp_pdu *answer = NULL;
1011 struct snmp_var *vp, *vnew = NULL, **vpp;
1012 struct snmp_var **vresp;
1013 int index = 0;
1014
1015 if ((answer = snmp_pdu_create(SNMP_PDU_RESPONSE))) {
1016 answer->req_id = pdu->req_id;
1017 answer->err_ind = 0;
1018 switch (pdu->type) {
1019
1020 case SNMP_PDU_SET:
1021 /* First, check for the consistency of
1022 * the request (rfc1157, 4.1.5):
1023 */
1024 GRAD_DEBUG(1, "SetRequest-PDU");
1025 if (access == SNMP_RO) {
1026 answer->err_stat = SNMP_ERR_GENERR;
1027 answer->err_ind = 1;
1028 GRAD_DEBUG(1,"bad access mode");
1029 return answer;
1030 }
1031 for (vp = pdu->var; vp; vp = vp->next) {
1032 index++;
1033
1034 if (mib_set_try(mib_tree, &vp,
1035 &answer->err_stat))
1036 break;
1037 }
1038
1039 if (answer->err_stat != SNMP_ERR_NOERROR) {
1040 answer->var = snmp_var_dup_list(pdu->var);
1041 answer->err_ind = index;
1042 GRAD_DEBUG(1, "returning error");
1043 return answer;
1044 }
1045
1046 /* Do real work */
1047 vresp = &answer->var;
1048 /* Loop through all variables */
1049 for (vpp = &pdu->var;
1050 *vpp;
1051 vpp = &(*vpp)->next) {
1052 vp = *vpp;
1053
1054 vnew = vp;
1055 mib_set(mib_tree, &vnew);
1056
1057 *vresp = vnew;
1058 vresp = &vnew->next;
1059 }
1060
1061 GRAD_DEBUG(1, "success");
1062 return answer;
1063
1064 case SNMP_PDU_GET:
1065 GRAD_DEBUG(1, "GetRequest-PDU");
1066
1067 vresp = &answer->var;
1068 /* Loop through all variables */
1069 for (vpp = &pdu->var; *vpp; vpp = &(*vpp)->next) {
1070 vp = *vpp;
1071
1072 index++;
1073
1074 vnew = vp;
1075 mib_get(mib_tree, &vnew,
1076 &answer->err_stat);
1077
1078 /* Was there an error? */
1079 if (answer->err_stat != SNMP_ERR_NOERROR
1080 || vnew == NULL) {
1081 answer->err_ind = index;
1082 GRAD_DEBUG(1,"returning");
1083 /* preserve the rest of vars */
1084 *vresp = snmp_var_dup_list(vp);
1085 return answer;
1086 }
1087 /* No error.
1088 * Insert this var at the end, and move on
1089 * to the next.
1090 */
1091 *vresp = vnew;
1092 vresp = &vnew->next;
1093 }
1094 return answer;
1095
1096 case SNMP_PDU_GETNEXT:
1097 GRAD_DEBUG(1, "GetNextRequest-PDU");
1098
1099 vresp = &answer->var;
1100 /* Loop through all variables */
1101 for (vpp = &pdu->var; *vpp; vpp = &(*vpp)->next) {
1102 vp = *vpp;
1103
1104 index++;
1105 vnew = vp;
1106 mib_get_next(mib_tree, &vnew,
1107 &answer->err_stat);
1108 /* Was there an error? */
1109 if (answer->err_stat != SNMP_ERR_NOERROR
1110 || vnew == NULL) {
1111 answer->err_ind = index;
1112 GRAD_DEBUG1(1,
1113 "returning: err_stat=%d",
1114 answer->err_stat);
1115 /* preserve the rest of vars */
1116 *vresp = snmp_var_dup_list(vp);
1117 return answer;
1118 }
1119 /* No error.
1120 * Insert this var at the end, and move on
1121 * to the next.
1122 */
1123 *vresp = vnew;
1124 vresp = &vnew->next;
1125 }
1126 break;
1127
1128 default:
1129 snmp_pdu_free(answer);
1130 answer = NULL;
1131 }
1132 }
1133 return answer;
1134 }
1135
1136 /* ************************************************************************* */
1137
1138 grad_counter_t
timeval_diff(struct timeval * tva,struct timeval * tvb)1139 timeval_diff(struct timeval *tva, struct timeval *tvb)
1140 {
1141 return (tva->tv_sec - tvb->tv_sec)*100 +
1142 (tva->tv_usec - tvb->tv_usec)/10000;
1143 }
1144
1145 serv_stat
abridge_server_state()1146 abridge_server_state()
1147 {
1148 switch (server_stat->auth.status) {
1149 case serv_init:
1150 case serv_running:
1151 return server_stat->auth.status;
1152 case serv_other:
1153 default:
1154 return serv_other;
1155 }
1156 }
1157
1158 /* ************************************************************************* */
1159 /* Auth sub-tree */
1160
1161 struct snmp_var *snmp_auth_var_get(subid_t subid, oid_t oid, int *errp);
1162 int snmp_auth_var_set(subid_t subid, struct snmp_var **vp, int *errp);
1163
1164 /* Handler function for fixed oids from the authentication subtree */
1165 int
snmp_auth_handler(enum mib_node_cmd cmd,void * closure,subid_t subid,struct snmp_var ** varp,int * errp)1166 snmp_auth_handler(enum mib_node_cmd cmd, void *closure,
1167 subid_t subid, struct snmp_var **varp, int *errp)
1168 {
1169 oid_t oid = (*varp)->name;
1170
1171 switch (cmd) {
1172 case MIB_NODE_GET:
1173 if ((*varp = snmp_auth_var_get(subid, oid, errp)) == NULL)
1174 return -1;
1175 break;
1176
1177 case MIB_NODE_SET:
1178 return snmp_auth_var_set(subid, varp, errp);
1179
1180 case MIB_NODE_SET_TRY:
1181 return snmp_auth_var_set(subid, varp, errp);
1182
1183 case MIB_NODE_RESET:
1184 break;
1185
1186 default: /* unused: should never get there */
1187 abort();
1188
1189 }
1190
1191 return 0;
1192 }
1193
1194 struct snmp_var *
snmp_auth_var_get(subid_t subid,oid_t oid,int * errp)1195 snmp_auth_var_get(subid_t subid, oid_t oid, int *errp)
1196 {
1197 struct snmp_var *ret;
1198 struct timeval tv;
1199 struct timezone tz;
1200 char *p;
1201
1202 ret = snmp_var_create(oid);
1203 *errp = SNMP_ERR_NOERROR;
1204
1205 switch (subid) {
1206
1207 case MIB_KEY_AuthServIdent:
1208 p = make_server_ident();
1209 ret->type = ASN_OCTET_STR;
1210 ret->val_length = strlen(p);
1211 ret->var_str = snmp_strdup(p);
1212 grad_free(p);
1213 break;
1214
1215 case MIB_KEY_AuthServUpTime:
1216 gettimeofday(&tv, &tz);
1217 ret->type = SMI_TIMETICKS;
1218 ret->val_length = sizeof(grad_counter_t);
1219 ret->var_int = timeval_diff(&tv, &server_stat->start_time);
1220 break;
1221
1222 case MIB_KEY_AuthServResetTime:
1223 gettimeofday(&tv, &tz);
1224 ret->type = SMI_TIMETICKS;
1225 ret->val_length = sizeof(grad_counter_t);
1226 ret->var_int = timeval_diff(&tv,
1227 &server_stat->auth.reset_time);
1228 break;
1229
1230 case MIB_KEY_AuthServConfigReset:
1231 ret->type = ASN_INTEGER;
1232 ret->val_length = sizeof(grad_counter_t);
1233 ret->var_int = abridge_server_state();
1234 break;
1235
1236 case MIB_KEY_AuthServTotalAccessRequests:
1237 ret->type = SMI_COUNTER32;
1238 ret->val_length = sizeof(grad_counter_t);
1239 ret->var_int = server_stat->auth.num_access_req;
1240 break;
1241
1242 case MIB_KEY_AuthServTotalInvalidRequests:
1243 ret->type = SMI_COUNTER32;
1244 ret->val_length = sizeof(grad_counter_t);
1245 ret->var_int = server_stat->auth.num_invalid_req;
1246 break;
1247
1248 case MIB_KEY_AuthServTotalDupAccessRequests:
1249 ret->type = SMI_COUNTER32;
1250 ret->val_length = sizeof(grad_counter_t);
1251 ret->var_int = server_stat->auth.num_dup_req;
1252 break;
1253
1254 case MIB_KEY_AuthServTotalAccessAccepts:
1255 ret->type = SMI_COUNTER32;
1256 ret->val_length = sizeof(grad_counter_t);
1257 ret->var_int = server_stat->auth.num_accepts;
1258 break;
1259
1260 case MIB_KEY_AuthServTotalAccessRejects:
1261 ret->type = SMI_COUNTER32;
1262 ret->val_length = sizeof(grad_counter_t);
1263 ret->var_int = server_stat->auth.num_rejects;
1264 break;
1265
1266 case MIB_KEY_AuthServTotalAccessChallenges:
1267 ret->type = SMI_COUNTER32;
1268 ret->val_length = sizeof(grad_counter_t);
1269 ret->var_int = server_stat->auth.num_challenges;
1270 break;
1271
1272 case MIB_KEY_AuthServTotalMalformedAccessRequests:
1273 ret->type = SMI_COUNTER32;
1274 ret->val_length = sizeof(grad_counter_t);
1275 ret->var_int = server_stat->auth.num_bad_req;
1276 break;
1277
1278 case MIB_KEY_AuthServTotalBadAuthenticators:
1279 ret->type = SMI_COUNTER32;
1280 ret->val_length = sizeof(grad_counter_t);
1281 ret->var_int = server_stat->auth.num_bad_auth;
1282 break;
1283
1284 case MIB_KEY_AuthServTotalPacketsDropped:
1285 ret->type = SMI_COUNTER32;
1286 ret->val_length = sizeof(grad_counter_t);
1287 ret->var_int = server_stat->auth.num_dropped;
1288 break;
1289
1290 case MIB_KEY_AuthServTotalUnknownTypes:
1291 ret->type = SMI_COUNTER32;
1292 ret->val_length = sizeof(grad_counter_t);
1293 ret->var_int = server_stat->auth.num_unknowntypes;
1294 break;
1295
1296 default:
1297 *errp = SNMP_ERR_NOSUCHNAME;
1298 snmp_var_free(ret);
1299 return NULL;
1300 }
1301 return ret;
1302 }
1303
1304 int
snmp_auth_var_set(subid_t subid,struct snmp_var ** vp,int * errp)1305 snmp_auth_var_set(subid_t subid, struct snmp_var **vp, int *errp)
1306 {
1307 if (errp) { /* just test */
1308 *errp = SNMP_ERR_NOERROR;
1309 switch (subid) {
1310
1311 case MIB_KEY_AccServConfigReset:
1312 if ((*vp)->type != ASN_INTEGER ||
1313 (*vp)->var_int != serv_reset) {
1314 *errp = SNMP_ERR_BADVALUE;
1315 *vp = NULL;
1316 }
1317 break;
1318 default:
1319 *errp = SNMP_ERR_BADVALUE;
1320 (*vp) = NULL;
1321 }
1322 } else {
1323 /* do set it */
1324 *vp = snmp_var_dup(*vp);
1325
1326 switch (subid) {
1327
1328 case MIB_KEY_AccServConfigReset:
1329 server_stat->auth.status = serv_init;
1330 grad_log(GRAD_LOG_INFO,
1331 _("acct server re-initializing on SNMP request"));
1332 break;
1333
1334 }
1335 }
1336 return (*vp == NULL);
1337 }
1338
1339 /* Variable oids */
1340
1341 void get_auth_nasstat(grad_nas_t *nas, struct snmp_var *var, int ind);
1342 int snmp_auth_v_handler(enum mib_node_cmd cmd, void *closure,
1343 subid_t subid, struct snmp_var **varp,
1344 int *errp);
1345 struct snmp_var *snmp_auth_var_v_get(subid_t subid, struct snmp_var *var,
1346 int *errp);
1347 int snmp_auth_var_next(subid_t subid, struct auth_mib_data *closure);
1348
1349 /* Handler function for variable oid of the authentication subtree */
1350 int
snmp_auth_v_handler(enum mib_node_cmd cmd,void * unused,subid_t subid,struct snmp_var ** varp,int * errp)1351 snmp_auth_v_handler(enum mib_node_cmd cmd, void *unused, subid_t subid,
1352 struct snmp_var **varp, int *errp)
1353 {
1354 struct auth_mib_data *data = (struct auth_mib_data *)
1355 snmpserv_get_data();
1356 switch (cmd) {
1357 case MIB_NODE_GET:
1358 if ((*varp = snmp_auth_var_v_get(subid, *varp, errp)) == NULL)
1359 return -1;
1360 break;
1361
1362 case MIB_NODE_SET:
1363 case MIB_NODE_SET_TRY:
1364 /* None of these can be set */
1365 if (errp)
1366 *errp = SNMP_ERR_NOSUCHNAME;
1367 return -1;
1368
1369 case MIB_NODE_COMPARE:
1370 return 0;
1371
1372 case MIB_NODE_NEXT:
1373 return snmp_auth_var_next(subid+1, data);
1374
1375 case MIB_NODE_GET_SUBID:
1376 return data->nas_index;
1377
1378 case MIB_NODE_RESET:
1379 data->nas_index = 1;
1380 break;
1381
1382 }
1383
1384 return 0;
1385 }
1386
1387 int
snmp_auth_var_next(subid_t subid,struct auth_mib_data * closure)1388 snmp_auth_var_next(subid_t subid, struct auth_mib_data *closure)
1389 {
1390 if (!nas_lookup_index(subid))
1391 return -1;
1392
1393 closure->nas_index = subid;
1394 return 0;
1395 }
1396
1397 struct snmp_var *
snmp_auth_var_v_get(subid_t subid,struct snmp_var * var,int * errp)1398 snmp_auth_var_v_get(subid_t subid, struct snmp_var *var, int *errp)
1399 {
1400 struct snmp_var *ret;
1401 subid_t key;
1402 grad_nas_t *nas;
1403
1404 ret = snmp_var_create(var->name);
1405 *errp = SNMP_ERR_NOERROR;
1406
1407 switch (key = SUBID(var->name, OIDLEN(var->name)-2)) {
1408 case MIB_KEY_AuthClientIndex:
1409 case MIB_KEY_AuthClientAddress:
1410 case MIB_KEY_AuthClientID:
1411 case MIB_KEY_AuthServAccessRequests:
1412 case MIB_KEY_AuthServDupAccessRequests:
1413 case MIB_KEY_AuthServAccessAccepts:
1414 case MIB_KEY_AuthServAccessRejects:
1415 case MIB_KEY_AuthServAccessChallenges:
1416 case MIB_KEY_AuthServMalformedAccessRequests:
1417 case MIB_KEY_AuthServBadAuthenticators:
1418 case MIB_KEY_AuthServPacketsDropped:
1419 case MIB_KEY_AuthServUnknownTypes:
1420 if ((nas = nas_lookup_index(subid)) != NULL &&
1421 nas->app_data) {
1422 get_auth_nasstat(nas, ret, key);
1423 break;
1424 }
1425 /*FALLTHRU*/
1426 default:
1427 *errp = SNMP_ERR_NOSUCHNAME;
1428 snmp_var_free(ret);
1429 return NULL;
1430 }
1431 return ret;
1432 }
1433
1434 void
get_auth_nasstat(grad_nas_t * nas,struct snmp_var * var,int key)1435 get_auth_nasstat(grad_nas_t *nas, struct snmp_var *var, int key)
1436 {
1437 struct nas_stat *statp = nas->app_data;
1438
1439 switch (key) {
1440 case MIB_KEY_AuthClientIndex:
1441 var->type = ASN_INTEGER;
1442 var->val_length = sizeof(int);
1443 var->var_int = statp->index;
1444 break;
1445
1446 case MIB_KEY_AuthClientAddress:
1447 var->type = SMI_IPADDRESS;
1448 var->val_length = sizeof(grad_uint32_t);
1449 var->var_str = snmp_alloc(sizeof(grad_uint32_t));
1450 *(grad_uint32_t*)var->var_str = ntohl(statp->ipaddr);
1451 break;
1452
1453 case MIB_KEY_AuthClientID:
1454 var->type = ASN_OCTET_STR;
1455 var->val_length = strlen(nas->longname);
1456 var->var_str = snmp_strdup(nas->longname);
1457 break;
1458
1459 case MIB_KEY_AuthServAccessRequests:
1460 var->type = SMI_COUNTER32;
1461 var->val_length = sizeof(grad_counter_t);
1462 var->var_int = statp->auth.num_access_req;
1463 break;
1464
1465 case MIB_KEY_AuthServDupAccessRequests:
1466 var->type = SMI_COUNTER32;
1467 var->val_length = sizeof(grad_counter_t);
1468 var->var_int = statp->auth.num_dup_req;
1469 break;
1470
1471 case MIB_KEY_AuthServAccessAccepts:
1472 var->type = SMI_COUNTER32;
1473 var->val_length = sizeof(grad_counter_t);
1474 var->var_int = statp->auth.num_accepts;
1475 break;
1476
1477 case MIB_KEY_AuthServAccessRejects:
1478 var->type = SMI_COUNTER32;
1479 var->val_length = sizeof(grad_counter_t);
1480 var->var_int = statp->auth.num_rejects;
1481 break;
1482
1483 case MIB_KEY_AuthServAccessChallenges:
1484 var->type = SMI_COUNTER32;
1485 var->val_length = sizeof(grad_counter_t);
1486 var->var_int = statp->auth.num_challenges;
1487 break;
1488
1489 case MIB_KEY_AuthServMalformedAccessRequests:
1490 var->type = SMI_COUNTER32;
1491 var->val_length = sizeof(grad_counter_t);
1492 var->var_int = statp->auth.num_bad_req;
1493 break;
1494
1495 case MIB_KEY_AuthServBadAuthenticators:
1496 var->type = SMI_COUNTER32;
1497 var->val_length = sizeof(grad_counter_t);
1498 var->var_int = statp->auth.num_bad_auth;
1499 break;
1500
1501 case MIB_KEY_AuthServPacketsDropped:
1502 var->type = SMI_COUNTER32;
1503 var->val_length = sizeof(grad_counter_t);
1504 var->var_int = statp->auth.num_dropped;
1505 break;
1506
1507 case MIB_KEY_AuthServUnknownTypes:
1508 var->type = SMI_COUNTER32;
1509 var->val_length = sizeof(grad_counter_t);
1510 var->var_int = statp->auth.num_unknowntypes;
1511 break;
1512
1513 }
1514 }
1515
1516
1517 /* ************************************************************************* */
1518 /* Accounting sub-tree */
1519 struct snmp_var *snmp_acct_var_get(subid_t subid, oid_t oid, int *errp);
1520 int snmp_acct_var_set(subid_t subid, struct snmp_var **vp, int *errp);
1521
1522 /* Handler function for fixed oids from the authentication subtree */
1523
1524 int
snmp_acct_handler(enum mib_node_cmd cmd,void * closure,subid_t subid,struct snmp_var ** varp,int * errp)1525 snmp_acct_handler(enum mib_node_cmd cmd, void *closure, subid_t subid,
1526 struct snmp_var **varp, int *errp)
1527 {
1528 oid_t oid = (*varp)->name;
1529
1530 switch (cmd) {
1531 case MIB_NODE_GET:
1532 if ((*varp = snmp_acct_var_get(subid, oid, errp)) == NULL)
1533 return -1;
1534 break;
1535
1536 case MIB_NODE_SET:
1537 return snmp_acct_var_set(subid, varp, errp);
1538
1539 case MIB_NODE_SET_TRY:
1540 return snmp_acct_var_set(subid, varp, errp);
1541
1542 case MIB_NODE_RESET:
1543 break;
1544
1545 default: /* unused: should never get there */
1546 abort();
1547
1548 }
1549
1550 return 0;
1551 }
1552
1553 struct snmp_var *
snmp_acct_var_get(subid_t subid,oid_t oid,int * errp)1554 snmp_acct_var_get(subid_t subid, oid_t oid, int *errp)
1555 {
1556 struct snmp_var *ret;
1557 struct timeval tv;
1558 struct timezone tz;
1559 char *p;
1560
1561 ret = snmp_var_create(oid);
1562 *errp = SNMP_ERR_NOERROR;
1563
1564 switch (subid) {
1565
1566 case MIB_KEY_AccServIdent:
1567 p = make_server_ident();
1568 ret->type = ASN_OCTET_STR;
1569 ret->val_length = strlen(p);
1570 ret->var_str = snmp_strdup(p);
1571 grad_free(p);
1572 break;
1573
1574 case MIB_KEY_AccServUpTime:
1575 gettimeofday(&tv, &tz);
1576 ret->type = SMI_TIMETICKS;
1577 ret->val_length = sizeof(grad_counter_t);
1578 ret->var_int = timeval_diff(&tv, &server_stat->start_time);
1579 break;
1580
1581 case MIB_KEY_AccServResetTime:
1582 gettimeofday(&tv, &tz);
1583 ret->type = SMI_TIMETICKS;
1584 ret->val_length = sizeof(grad_counter_t);
1585 ret->var_int = timeval_diff(&tv, &server_stat->acct.reset_time);
1586 break;
1587
1588 case MIB_KEY_AccServConfigReset:
1589 ret->type = ASN_INTEGER;
1590 ret->val_length = sizeof(grad_counter_t);
1591 ret->var_int = abridge_server_state();
1592 break;
1593
1594 case MIB_KEY_AccServTotalRequests:
1595 ret->type = SMI_COUNTER32;
1596 ret->val_length = sizeof(grad_counter_t);
1597 ret->var_int = server_stat->acct.num_req;
1598 break;
1599
1600 case MIB_KEY_AccServTotalInvalidRequests:
1601 ret->type = SMI_COUNTER32;
1602 ret->val_length = sizeof(grad_counter_t);
1603 ret->var_int = server_stat->acct.num_invalid_req;
1604 break;
1605
1606 case MIB_KEY_AccServTotalDupRequests:
1607 ret->type = SMI_COUNTER32;
1608 ret->val_length = sizeof(grad_counter_t);
1609 ret->var_int = server_stat->acct.num_dup_req;
1610 break;
1611
1612 case MIB_KEY_AccServTotalResponses:
1613 ret->type = SMI_COUNTER32;
1614 ret->val_length = sizeof(grad_counter_t);
1615 ret->var_int = server_stat->acct.num_resp;
1616 break;
1617
1618 case MIB_KEY_AccServTotalMalformedRequests:
1619 ret->type = SMI_COUNTER32;
1620 ret->val_length = sizeof(grad_counter_t);
1621 ret->var_int = server_stat->acct.num_bad_req;
1622 break;
1623
1624 case MIB_KEY_AccServTotalBadAuthenticators:
1625 ret->type = SMI_COUNTER32;
1626 ret->val_length = sizeof(grad_counter_t);
1627 ret->var_int = server_stat->acct.num_bad_sign;
1628 break;
1629
1630 case MIB_KEY_AccServTotalPacketsDropped:
1631 ret->type = SMI_COUNTER32;
1632 ret->val_length = sizeof(grad_counter_t);
1633 ret->var_int = server_stat->acct.num_dropped;
1634 break;
1635
1636 case MIB_KEY_AccServTotalNoRecords:
1637 ret->type = SMI_COUNTER32;
1638 ret->val_length = sizeof(grad_counter_t);
1639 ret->var_int = server_stat->acct.num_norecords;
1640 break;
1641
1642 case MIB_KEY_AccServTotalUnknownTypes:
1643 ret->type = SMI_COUNTER32;
1644 ret->val_length = sizeof(grad_counter_t);
1645 ret->var_int = server_stat->acct.num_unknowntypes;
1646 break;
1647
1648 default:
1649 *errp = SNMP_ERR_NOSUCHNAME;
1650 snmp_var_free(ret);
1651 return NULL;
1652 }
1653 return ret;
1654 }
1655
1656 int
snmp_acct_var_set(subid_t subid,struct snmp_var ** vp,int * errp)1657 snmp_acct_var_set(subid_t subid, struct snmp_var **vp, int *errp)
1658 {
1659 if (errp) { /* just test */
1660 *errp = SNMP_ERR_NOERROR;
1661 switch (subid) {
1662
1663 case MIB_KEY_AuthServConfigReset:
1664 if ((*vp)->type != ASN_INTEGER ||
1665 (*vp)->var_int != serv_reset) {
1666 *errp = SNMP_ERR_BADVALUE;
1667 *vp = NULL;
1668 }
1669 break;
1670 default:
1671 *errp = SNMP_ERR_BADVALUE;
1672 (*vp) = NULL;
1673 }
1674 } else {
1675 /* do set it */
1676 *vp = snmp_var_dup(*vp);
1677
1678 switch (subid) {
1679
1680 case MIB_KEY_AuthServConfigReset:
1681 server_stat->auth.status = serv_init;
1682 grad_log(GRAD_LOG_INFO,
1683 _("auth server re-initializing on SNMP request"));
1684 break;
1685
1686 }
1687 }
1688 return (*vp == NULL);
1689 }
1690
1691 void get_acct_nasstat(grad_nas_t *nas, struct snmp_var *var, int key);
1692 int snmp_acct_v_handler(enum mib_node_cmd cmd, void *closure,
1693 subid_t subid, struct snmp_var **varp,
1694 int *errp);
1695 struct snmp_var *snmp_acct_var_v_get(subid_t subid, struct snmp_var *var,
1696 int *errp);
1697
1698 /* Handler function for variable oid of the authentication subtree */
1699 int
snmp_acct_v_handler(enum mib_node_cmd cmd,void * unused,subid_t subid,struct snmp_var ** varp,int * errp)1700 snmp_acct_v_handler(enum mib_node_cmd cmd, void *unused, subid_t subid,
1701 struct snmp_var **varp, int *errp)
1702 {
1703 struct auth_mib_data *data = (struct auth_mib_data *)
1704 snmpserv_get_data();
1705 switch (cmd) {
1706 case MIB_NODE_GET:
1707 if ((*varp = snmp_acct_var_v_get(subid, *varp, errp)) == NULL)
1708 return -1;
1709 break;
1710
1711 case MIB_NODE_SET:
1712 case MIB_NODE_SET_TRY:
1713 /* None of these can be set */
1714 if (errp)
1715 *errp = SNMP_ERR_NOSUCHNAME;
1716 return -1;
1717
1718 case MIB_NODE_COMPARE:
1719 return 0;
1720
1721 case MIB_NODE_NEXT:
1722 return snmp_auth_var_next(subid+1, data);
1723
1724 case MIB_NODE_GET_SUBID:
1725 return data->nas_index;
1726
1727 case MIB_NODE_RESET:
1728 data->nas_index = 1;
1729 break;
1730
1731 }
1732
1733 return 0;
1734 }
1735
1736 struct snmp_var *
snmp_acct_var_v_get(subid_t subid,struct snmp_var * var,int * errp)1737 snmp_acct_var_v_get(subid_t subid, struct snmp_var *var, int *errp)
1738 {
1739 struct snmp_var *ret;
1740 subid_t key;
1741 grad_nas_t *nas;
1742
1743 ret = snmp_var_create(var->name);
1744 *errp = SNMP_ERR_NOERROR;
1745
1746 switch (key = SUBID(var->name, OIDLEN(var->name)-2)) {
1747 case MIB_KEY_AccClientIndex:
1748 case MIB_KEY_AccClientAddress:
1749 case MIB_KEY_AccClientID:
1750 case MIB_KEY_AccServPacketsDropped:
1751 case MIB_KEY_AccServRequests:
1752 case MIB_KEY_AccServDupRequests:
1753 case MIB_KEY_AccServResponses:
1754 case MIB_KEY_AccServBadAuthenticators:
1755 case MIB_KEY_AccServMalformedRequests:
1756 case MIB_KEY_AccServNoRecords:
1757 case MIB_KEY_AccServUnknownTypes:
1758 if ((nas = nas_lookup_index(subid)) != NULL &&
1759 nas->app_data) {
1760 get_acct_nasstat(nas, ret, key);
1761 break;
1762 }
1763 /*FALLTHRU*/
1764 default:
1765 *errp = SNMP_ERR_NOSUCHNAME;
1766 snmp_var_free(ret);
1767 return NULL;
1768 }
1769 return ret;
1770 }
1771
1772 void
get_acct_nasstat(grad_nas_t * nas,struct snmp_var * var,int key)1773 get_acct_nasstat(grad_nas_t *nas, struct snmp_var *var, int key)
1774 {
1775 struct nas_stat *statp = nas->app_data;
1776
1777 switch (key) {
1778 case MIB_KEY_AccClientIndex:
1779 var->type = ASN_INTEGER;
1780 var->val_length = sizeof(int);
1781 var->var_int = statp->index;
1782 break;
1783
1784 case MIB_KEY_AccClientAddress:
1785 var->type = SMI_IPADDRESS;
1786 var->val_length = sizeof(grad_uint32_t);
1787 var->var_str = snmp_alloc(sizeof(grad_uint32_t));
1788 *(grad_uint32_t*)var->var_str = ntohl(statp->ipaddr);
1789 break;
1790
1791 case MIB_KEY_AccClientID:
1792 var->type = ASN_OCTET_STR;
1793 var->val_length = strlen(nas->longname);
1794 var->var_str = snmp_strdup(nas->longname);
1795 break;
1796
1797 case MIB_KEY_AccServPacketsDropped:
1798 var->type = SMI_COUNTER32;
1799 var->val_length = sizeof(grad_counter_t);
1800 var->var_int = statp->acct.num_dropped;
1801 break;
1802
1803 case MIB_KEY_AccServRequests:
1804 var->type = SMI_COUNTER32;
1805 var->val_length = sizeof(grad_counter_t);
1806 var->var_int = statp->acct.num_req;
1807 break;
1808
1809 case MIB_KEY_AccServDupRequests:
1810 var->type = SMI_COUNTER32;
1811 var->val_length = sizeof(grad_counter_t);
1812 var->var_int = statp->acct.num_dup_req;
1813 break;
1814
1815 case MIB_KEY_AccServResponses:
1816 var->type = SMI_COUNTER32;
1817 var->val_length = sizeof(grad_counter_t);
1818 var->var_int = statp->acct.num_resp;
1819 break;
1820
1821 case MIB_KEY_AccServBadAuthenticators:
1822 var->type = SMI_COUNTER32;
1823 var->val_length = sizeof(grad_counter_t);
1824 var->var_int = statp->acct.num_bad_sign;
1825 break;
1826
1827 case MIB_KEY_AccServMalformedRequests:
1828 var->type = SMI_COUNTER32;
1829 var->val_length = sizeof(grad_counter_t);
1830 var->var_int = statp->acct.num_bad_req;
1831 break;
1832
1833 case MIB_KEY_AccServNoRecords:
1834 var->type = SMI_COUNTER32;
1835 var->val_length = sizeof(grad_counter_t);
1836 var->var_int = statp->acct.num_norecords;
1837 break;
1838
1839 case MIB_KEY_AccServUnknownTypes:
1840 var->type = SMI_COUNTER32;
1841 var->val_length = sizeof(grad_counter_t);
1842 var->var_int = statp->acct.num_unknowntypes;
1843 break;
1844 }
1845 }
1846
1847 /* ************************************************************************* */
1848 /* Server */
1849 struct snmp_var *snmp_serv_var_get(subid_t subid, oid_t oid, int *errp);
1850 int snmp_serv_var_set(subid_t subid, struct snmp_var **vp, int *errp);
1851
1852 /* Handler function for fixed oids from the server subtree */
1853
1854 int
snmp_serv_handler(enum mib_node_cmd cmd,void * closure,subid_t subid,struct snmp_var ** varp,int * errp)1855 snmp_serv_handler(enum mib_node_cmd cmd, void *closure,
1856 subid_t subid, struct snmp_var **varp, int *errp)
1857 {
1858 oid_t oid = (*varp)->name;
1859
1860 switch (cmd) {
1861 case MIB_NODE_GET:
1862 if ((*varp = snmp_serv_var_get(subid, oid, errp)) == NULL)
1863 return -1;
1864 break;
1865
1866 case MIB_NODE_SET:
1867 return snmp_serv_var_set(subid, varp, errp);
1868
1869 case MIB_NODE_SET_TRY:
1870 return snmp_serv_var_set(subid, varp, errp);
1871
1872 case MIB_NODE_RESET:
1873 break;
1874
1875 default: /* unused: should never get there */
1876 abort();
1877
1878 }
1879
1880 return 0;
1881 }
1882
1883 struct snmp_var *
snmp_serv_var_get(subid_t subid,oid_t oid,int * errp)1884 snmp_serv_var_get(subid_t subid, oid_t oid, int *errp)
1885 {
1886 struct snmp_var *ret;
1887 struct timeval tv;
1888 struct timezone tz;
1889
1890 ret = snmp_var_create(oid);
1891 *errp = SNMP_ERR_NOERROR;
1892
1893 switch (subid) {
1894
1895 case MIB_KEY_radiusServerUpTime:
1896 gettimeofday(&tv, &tz);
1897 ret->type = SMI_TIMETICKS;
1898 ret->val_length = sizeof(grad_counter_t);
1899 ret->var_int = timeval_diff(&tv, &server_stat->start_time);
1900 break;
1901
1902 case MIB_KEY_radiusServerResetTime:
1903 gettimeofday(&tv, &tz);
1904 ret->type = SMI_TIMETICKS;
1905 ret->val_length = sizeof(grad_counter_t);
1906 ret->var_int = timeval_diff(&tv,
1907 &server_stat->auth.reset_time);
1908 break;
1909
1910 case MIB_KEY_radiusServerState:
1911 ret->type = ASN_INTEGER;
1912 ret->val_length = sizeof(grad_counter_t);
1913 ret->var_int = server_stat->auth.status;/*FIXME*/
1914 break;
1915 default:
1916 *errp = SNMP_ERR_NOSUCHNAME;
1917 snmp_var_free(ret);
1918 return NULL;
1919 }
1920 return ret;
1921 }
1922
1923 int
snmp_serv_var_set(subid_t subid,struct snmp_var ** vp,int * errp)1924 snmp_serv_var_set(subid_t subid, struct snmp_var **vp, int *errp)
1925 {
1926 if (errp) { /* just test */
1927 *errp = SNMP_ERR_NOERROR;
1928 switch (subid) {
1929
1930 case MIB_KEY_radiusServerState:
1931 if ((*vp)->type != ASN_INTEGER) {
1932 *errp = SNMP_ERR_BADVALUE;
1933 *vp = NULL;
1934 } else {
1935 switch ((*vp)->var_int) {
1936 case serv_reset:
1937 case serv_init:
1938 case serv_running:
1939 case serv_suspended:
1940 case serv_shutdown:
1941 break;
1942 default:
1943 *errp = SNMP_ERR_BADVALUE;
1944 *vp = NULL;
1945 }
1946 }
1947 break;
1948 default:
1949 *errp = SNMP_ERR_BADVALUE;
1950 (*vp) = NULL;
1951 }
1952 } else {
1953 /* do set it */
1954 *vp = snmp_var_dup(*vp);
1955
1956 switch (subid) {
1957
1958 case MIB_KEY_radiusServerState:
1959 server_stat->auth.status = (*vp)->var_int;
1960 switch ((*vp)->var_int) {
1961 case serv_reset:
1962 grad_log(GRAD_LOG_NOTICE,
1963 _("server re-initializing on SNMP request"));
1964 break;
1965 case serv_init:
1966 grad_log(GRAD_LOG_NOTICE,
1967 _("server restart on SNMP request"));
1968 break;
1969 case serv_running:
1970 grad_log(GRAD_LOG_NOTICE,
1971 _("server continuing on SNMP request"));
1972 break;
1973 case serv_suspended:
1974 grad_log(GRAD_LOG_NOTICE,
1975 _("server suspending on SNMP request"));
1976 break;
1977 case serv_shutdown:
1978 grad_log(GRAD_LOG_NOTICE,
1979 _("server shutting down on SNMP request"));
1980 break;
1981 }
1982 break;
1983
1984 }
1985 }
1986 return (*vp == NULL);
1987 }
1988
1989
1990 /* ************************************************************************* */
1991 /* Statistics */
1992 struct snmp_var *snmp_stat_var_get(subid_t subid, oid_t oid, int *errp);
1993 int snmp_stat_var_set(subid_t subid, struct snmp_var **vp, int *errp);
1994
1995 /* Handler function for fixed oids from the authentication subtree */
1996
1997 int
snmp_stat_handler(enum mib_node_cmd cmd,void * closure,subid_t subid,struct snmp_var ** varp,int * errp)1998 snmp_stat_handler(enum mib_node_cmd cmd, void *closure, subid_t subid,
1999 struct snmp_var **varp, int *errp)
2000 {
2001 oid_t oid = (*varp)->name;
2002
2003 switch (cmd) {
2004 case MIB_NODE_GET:
2005 if ((*varp = snmp_stat_var_get(subid, oid, errp)) == NULL)
2006 return -1;
2007 break;
2008
2009 case MIB_NODE_SET:
2010 case MIB_NODE_SET_TRY:
2011 /*FIXME: return snmp_stat_var_set(subid, varp, errp); */
2012 *errp = SNMP_ERR_BADVALUE;
2013 return -1;
2014
2015 case MIB_NODE_RESET:
2016 break;
2017
2018 default: /* unused: should never get there */
2019 abort();
2020
2021 }
2022
2023 return 0;
2024 }
2025
2026 struct snmp_var *
snmp_stat_var_get(subid_t subid,oid_t oid,int * errp)2027 snmp_stat_var_get(subid_t subid, oid_t oid, int *errp)
2028 {
2029 struct snmp_var *ret;
2030 struct timeval tv;
2031 struct timezone tz;
2032 char *p;
2033
2034 ret = snmp_var_create(oid);
2035 *errp = SNMP_ERR_NOERROR;
2036
2037 switch (subid) {
2038
2039 case MIB_KEY_StatIdent:
2040 p = make_server_ident();
2041 ret->type = ASN_OCTET_STR;
2042 ret->val_length = strlen(p);
2043 ret->var_str = snmp_strdup(p);
2044 grad_free(p);
2045 break;
2046
2047 case MIB_KEY_StatUpTime:
2048 gettimeofday(&tv, &tz);
2049 ret->type = SMI_TIMETICKS;
2050 ret->val_length = sizeof(grad_counter_t);
2051 ret->var_int = timeval_diff(&tv, &radstat.start_time);
2052 break;
2053
2054 case MIB_KEY_StatConfigReset:
2055 ret->type = ASN_INTEGER;
2056 ret->val_length = sizeof(grad_counter_t);
2057 ret->var_int = serv_running;;
2058 break;
2059
2060 case MIB_KEY_StatTotalLines:
2061 ret->type = SMI_COUNTER32;
2062 ret->val_length = sizeof(grad_counter_t);
2063 stat_count_ports();
2064 ret->var_int = radstat.port_active_count
2065 + radstat.port_idle_count;
2066 break;
2067
2068 case MIB_KEY_StatTotalLinesInUse:
2069 ret->type = SMI_COUNTER32;
2070 ret->val_length = sizeof(grad_counter_t);
2071 stat_count_ports();
2072 ret->var_int = radstat.port_active_count;
2073 break;
2074
2075 case MIB_KEY_StatTotalLinesIdle:
2076 ret->type = SMI_COUNTER32;
2077 ret->val_length = sizeof(grad_counter_t);
2078 stat_count_ports();
2079 ret->var_int = radstat.port_idle_count;
2080 break;
2081
2082 default:
2083 *errp = SNMP_ERR_NOSUCHNAME;
2084 snmp_var_free(ret);
2085 return NULL;
2086 }
2087 return ret;
2088 }
2089
2090 int
snmp_stat_nas(int num,enum mib_node_cmd cmd,struct nas_data * closure,subid_t subid,struct snmp_var ** varp,int * errp)2091 snmp_stat_nas(int num, enum mib_node_cmd cmd, struct nas_data *closure,
2092 subid_t subid, struct snmp_var **varp, int *errp)
2093 {
2094 grad_nas_t *nas;
2095 struct nas_stat *nsp;
2096 grad_uint32_t ip;
2097 struct snmp_var *var;
2098 int len;
2099
2100 switch (cmd) {
2101 case MIB_NODE_GET:
2102 if (SUBID((*varp)->name, 6) == 9163)
2103 len = LEN_grad_NASIndex4;
2104 else
2105 len = LEN_NASIndex4;
2106
2107 if (num != 3 || OIDLEN((*varp)->name) != len) {
2108 *errp = SNMP_ERR_NOSUCHNAME;
2109 return -1;
2110 }
2111 ip = (closure->quad[0]<<24)+
2112 (closure->quad[1]<<16)+
2113 (closure->quad[2]<<8) +
2114 closure->quad[3];
2115
2116 if ((nsp = find_nas_stat(ip)) == NULL) {
2117 *errp = SNMP_ERR_NOSUCHNAME;
2118 return -1;
2119 }
2120
2121 *errp = SNMP_ERR_NOERROR;
2122 var = snmp_var_create((*varp)->name);
2123 var->type = ASN_INTEGER;
2124 var->val_length = sizeof(int);
2125 var->var_int = nsp->index;
2126
2127 *varp = var;
2128 break;
2129
2130 case MIB_NODE_SET:
2131 case MIB_NODE_SET_TRY:
2132 /* None of these can be set */
2133 if (errp)
2134 *errp = SNMP_ERR_NOSUCHNAME;
2135 return -1;
2136
2137 case MIB_NODE_COMPARE:
2138 closure->quad[num] = subid;
2139 return 0;
2140
2141 case MIB_NODE_NEXT:
2142 if (num != 3)
2143 return -1;
2144
2145 ip = (closure->quad[0]<<24)+
2146 (closure->quad[1]<<16)+
2147 (closure->quad[2]<<8) +
2148 closure->quad[3];
2149
2150 if ((nas = grad_nas_lookup_ip(ip)) == NULL) {
2151 return -1;
2152 }
2153
2154 nsp = nas->app_data;
2155 if ((nas = nas_lookup_index(nsp->index+1)) == NULL) {
2156 return -1;
2157 }
2158
2159 /* FIXME: MIBS do not reflect netmask */
2160 for (num = 0; num < 4; num++)
2161 closure->quad[num] = (nas->netdef.ipaddr >>
2162 (8*(3-num))) & 0xff;
2163
2164 break;
2165
2166 case MIB_NODE_GET_SUBID:
2167 return closure->quad[num];
2168
2169 case MIB_NODE_RESET:
2170 if (num == 0) {
2171 if (nas = nas_lookup_index(1))
2172 for (num = 0; num < 4; num++)
2173 closure->quad[num] =
2174 (nas->netdef.ipaddr >>
2175 (8*(3-num))) & 0xff;
2176 }
2177 break;
2178
2179 }
2180
2181 return 0;
2182 }
2183
2184 int
snmp_stat_nas1(enum mib_node_cmd cmd,void * unused,subid_t subid,struct snmp_var ** varp,int * errp)2185 snmp_stat_nas1(enum mib_node_cmd cmd, void *unused,
2186 subid_t subid, struct snmp_var **varp, int *errp)
2187 {
2188 return snmp_stat_nas(0, cmd,
2189 (struct nas_data*)snmpserv_get_data(), subid,
2190 varp, errp);
2191 }
2192
2193 int
snmp_stat_nas2(enum mib_node_cmd cmd,void * unused,subid_t subid,struct snmp_var ** varp,int * errp)2194 snmp_stat_nas2(enum mib_node_cmd cmd, void *unused,
2195 subid_t subid, struct snmp_var **varp, int *errp)
2196 {
2197 return snmp_stat_nas(1, cmd,
2198 (struct nas_data*)snmpserv_get_data(), subid,
2199 varp, errp);
2200 }
2201
2202 int
snmp_stat_nas3(enum mib_node_cmd cmd,void * unused,subid_t subid,struct snmp_var ** varp,int * errp)2203 snmp_stat_nas3(enum mib_node_cmd cmd, void *unused,
2204 subid_t subid, struct snmp_var **varp, int *errp)
2205 {
2206 return snmp_stat_nas(2, cmd,
2207 (struct nas_data*)snmpserv_get_data(), subid,
2208 varp, errp);
2209 }
2210
2211 int
snmp_stat_nas4(enum mib_node_cmd cmd,void * unused,subid_t subid,struct snmp_var ** varp,int * errp)2212 snmp_stat_nas4(enum mib_node_cmd cmd, void *unused,
2213 subid_t subid, struct snmp_var **varp, int *errp)
2214 {
2215 return snmp_stat_nas(3, cmd,
2216 (struct nas_data*)snmpserv_get_data(), subid,
2217 varp, errp);
2218 }
2219
2220
2221 void get_stat_nasstat(grad_nas_t *nas, struct snmp_var *var, int ind);
2222 struct snmp_var *snmp_nas_table_get(subid_t subid, oid_t oid, int *errp);
2223
2224 int
snmp_nas_table(enum mib_node_cmd cmd,void * unused,subid_t subid,struct snmp_var ** varp,int * errp)2225 snmp_nas_table(enum mib_node_cmd cmd, void *unused,
2226 subid_t subid, struct snmp_var **varp, int *errp)
2227 {
2228 struct nas_table_data *data = (struct nas_table_data*)
2229 snmpserv_get_data();
2230 switch (cmd) {
2231 case MIB_NODE_GET:
2232 if ((*varp = snmp_nas_table_get(subid, (*varp)->name, errp))
2233 == NULL)
2234 return -1;
2235 break;
2236
2237 case MIB_NODE_SET:
2238 case MIB_NODE_SET_TRY:
2239 /* None of these can be set */
2240 if (errp)
2241 *errp = SNMP_ERR_NOSUCHNAME;
2242 return -1;
2243
2244 case MIB_NODE_NEXT:
2245 if (!nas_lookup_index(subid+1))
2246 return -1;
2247 data->row = subid+1;
2248 break;
2249
2250 case MIB_NODE_RESET:
2251 data->row = 1;
2252 break;
2253
2254 case MIB_NODE_GET_SUBID:
2255 return data->row;
2256
2257 case MIB_NODE_COMPARE:
2258 return 0;
2259
2260 default: /* unused: should never get there */
2261 abort();
2262
2263 }
2264
2265 return 0;
2266
2267 }
2268
2269 struct snmp_var *
snmp_nas_table_get(subid_t subid,oid_t oid,int * errp)2270 snmp_nas_table_get(subid_t subid, oid_t oid, int *errp)
2271 {
2272 struct snmp_var *ret;
2273 subid_t key;
2274 grad_nas_t *nas;
2275
2276 ret = snmp_var_create(oid);
2277 *errp = SNMP_ERR_NOERROR;
2278
2279 switch (key = SUBID(oid, OIDLEN(oid)-2)) {
2280 case MIB_KEY_NASAddress:
2281 case MIB_KEY_NASID:
2282 case MIB_KEY_NASLines:
2283 case MIB_KEY_NASLinesInUse:
2284 case MIB_KEY_NASLinesIdle:
2285 if ((nas = nas_lookup_index(subid)) != NULL && nas->app_data) {
2286 get_stat_nasstat(nas, ret, key);
2287 break;
2288 }
2289 /*FALLTHRU*/
2290 default:
2291 *errp = SNMP_ERR_NOSUCHNAME;
2292 snmp_var_free(ret);
2293 return NULL;
2294 }
2295 return ret;
2296 }
2297
2298 void
get_stat_nasstat(grad_nas_t * nas,struct snmp_var * var,int ind)2299 get_stat_nasstat(grad_nas_t *nas, struct snmp_var *var, int ind)
2300 {
2301 struct nas_stat *statp = nas->app_data;
2302
2303 switch (ind) {
2304 case MIB_KEY_NASAddress:
2305 var->type = SMI_IPADDRESS;
2306 var->val_length = sizeof(grad_uint32_t);
2307 var->var_str = snmp_alloc(sizeof(grad_uint32_t));
2308 *(grad_uint32_t*)var->var_str = ntohl(statp->ipaddr);
2309 break;
2310
2311 case MIB_KEY_NASID:
2312 var->type = ASN_OCTET_STR;
2313 var->val_length = strlen(nas->longname);
2314 var->var_str = snmp_strdup(nas->longname);
2315 break;
2316
2317 case MIB_KEY_NASLines:
2318 stat_count_ports();
2319 var->type = SMI_COUNTER32;
2320 var->val_length = sizeof(grad_counter_t);
2321 var->var_int = statp->ports_active +
2322 statp->ports_idle;
2323 break;
2324
2325 case MIB_KEY_NASLinesInUse:
2326 stat_count_ports();
2327 var->type = SMI_COUNTER32;
2328 var->val_length = sizeof(grad_counter_t);
2329 var->var_int = statp->ports_active;
2330 break;
2331
2332 case MIB_KEY_NASLinesIdle:
2333 stat_count_ports();
2334 var->type = SMI_COUNTER32;
2335 var->val_length = sizeof(grad_counter_t);
2336 var->var_int = statp->ports_idle;
2337 break;
2338
2339 }
2340 }
2341
2342 /*ARGSUSED*/
2343 int
snmp_port_index1(enum mib_node_cmd cmd,void * unused,subid_t subid,struct snmp_var ** varp,int * errp)2344 snmp_port_index1(enum mib_node_cmd cmd, void *unused,
2345 subid_t subid, struct snmp_var **varp, int *errp)
2346 {
2347 grad_nas_t *nas;
2348 struct port_data *pind = (struct port_data*)snmpserv_get_data();
2349
2350 switch (cmd) {
2351 case MIB_NODE_GET:
2352 *errp = SNMP_ERR_NOSUCHNAME;
2353 return -1;
2354
2355 case MIB_NODE_SET:
2356 case MIB_NODE_SET_TRY:
2357 /* None of these can be set */
2358 if (errp)
2359 *errp = SNMP_ERR_NOSUCHNAME;
2360 return -1;
2361
2362 case MIB_NODE_COMPARE:
2363 pind->nas_index = subid;
2364 return 0;
2365
2366 case MIB_NODE_NEXT:
2367 return -1;
2368
2369 case MIB_NODE_GET_SUBID:
2370 return pind->nas_index;
2371
2372 case MIB_NODE_RESET:
2373 pind->nas_index = 1;
2374 while ((nas = nas_lookup_index(pind->nas_index)) &&
2375 (pind->port_no = stat_get_next_port_no(nas, 0)) == 0)
2376 pind->nas_index++;
2377 break;
2378 }
2379
2380 return 0;
2381 }
2382
2383 int
snmp_port_index2(enum mib_node_cmd cmd,void * unused,subid_t subid,struct snmp_var ** varp,int * errp)2384 snmp_port_index2(enum mib_node_cmd cmd, void *unused,
2385 subid_t subid, struct snmp_var **varp, int *errp)
2386 {
2387 grad_nas_t *nas;
2388 int index;
2389 struct snmp_var *var;
2390 struct port_data *pind = (struct port_data*)snmpserv_get_data();
2391
2392 switch (cmd) {
2393 case MIB_NODE_GET:
2394 if ((nas = nas_lookup_index(pind->nas_index)) == NULL ||
2395 (index = stat_get_port_index(nas, pind->port_no)) == 0) {
2396 *errp = SNMP_ERR_NOSUCHNAME;
2397 return -1;
2398 }
2399 *errp = SNMP_ERR_NOERROR;
2400 var = snmp_var_create((*varp)->name);
2401 var->type = ASN_INTEGER;
2402 var->val_length = sizeof(int);
2403 var->var_int = index;
2404 *varp = var;
2405 break;
2406
2407 case MIB_NODE_SET:
2408 case MIB_NODE_SET_TRY:
2409 /* None of these can be set */
2410 if (errp)
2411 *errp = SNMP_ERR_NOSUCHNAME;
2412 return -1;
2413
2414 case MIB_NODE_COMPARE:
2415 pind->port_no = subid;
2416 return 0;
2417
2418 case MIB_NODE_NEXT:
2419 if ((nas = nas_lookup_index(pind->nas_index)) == NULL)
2420 return -1;
2421 index = stat_get_next_port_no(nas, pind->port_no);
2422 if (index > 0) {
2423 pind->port_no = index;
2424 break;
2425 }
2426 /* move to next nas */
2427 while ((nas = nas_lookup_index(++pind->nas_index)) &&
2428 (pind->port_no = stat_get_next_port_no(nas, 0)) == 0)
2429 ;
2430
2431 if (nas && pind->port_no > 0)
2432 break;
2433
2434 return -1;
2435
2436 case MIB_NODE_GET_SUBID:
2437 return pind->port_no;
2438
2439 case MIB_NODE_RESET:
2440 break;
2441 }
2442
2443 return 0;
2444 }
2445
2446 struct snmp_var *snmp_port_get(subid_t subid, struct snmp_var *var, int *errp);
2447 void get_port_stat(PORT_STAT *port, struct snmp_var *var, subid_t key);
2448
2449 int
snmp_port_table(enum mib_node_cmd cmd,void * unused,subid_t subid,struct snmp_var ** varp,int * errp)2450 snmp_port_table(enum mib_node_cmd cmd, void *unused,
2451 subid_t subid, struct snmp_var **varp, int *errp)
2452 {
2453 struct port_table_data *p = (struct port_table_data*)
2454 snmpserv_get_data();
2455
2456 switch (cmd) {
2457 case MIB_NODE_GET:
2458 if ((*varp = snmp_port_get(subid, *varp, errp)) == NULL)
2459 return -1;
2460 break;
2461
2462 case MIB_NODE_SET:
2463 case MIB_NODE_SET_TRY:
2464 /* None of these can be set */
2465 if (errp)
2466 *errp = SNMP_ERR_NOSUCHNAME;
2467 return -1;
2468
2469 case MIB_NODE_COMPARE:
2470 return 0;
2471
2472 case MIB_NODE_NEXT:
2473 if (findportbyindex(subid+1)) {
2474 p->port_index = subid+1;
2475 return 0;
2476 }
2477 return -1;
2478
2479 case MIB_NODE_GET_SUBID:
2480 return p->port_index;
2481
2482 case MIB_NODE_RESET:
2483 p->port_index = 1;
2484 break;
2485
2486 }
2487
2488 return 0;
2489 }
2490
2491 struct snmp_var *
snmp_port_get(subid_t subid,struct snmp_var * var,int * errp)2492 snmp_port_get(subid_t subid, struct snmp_var *var, int *errp)
2493 {
2494 struct snmp_var *ret;
2495 subid_t key;
2496 oid_t oid = var->name;
2497 PORT_STAT *port;
2498
2499 ret = snmp_var_create(oid);
2500 *errp = SNMP_ERR_NOERROR;
2501
2502 switch (key = SUBID(oid, OIDLEN(oid)-2)) {
2503
2504 case MIB_KEY_StatPortNASIndex:
2505 case MIB_KEY_StatPortID:
2506 case MIB_KEY_StatPortFramedAddress:
2507 case MIB_KEY_StatPortTotalLogins:
2508 case MIB_KEY_StatPortStatus:
2509 case MIB_KEY_StatPortStatusChangeTimestamp:
2510 case MIB_KEY_StatPortUpTime:
2511 case MIB_KEY_StatPortLastLoginName:
2512 case MIB_KEY_StatPortLastLoginTimestamp:
2513 case MIB_KEY_StatPortLastLogoutTimestamp:
2514 case MIB_KEY_StatPortIdleTotalTime:
2515 case MIB_KEY_StatPortIdleMaxTime:
2516 case MIB_KEY_StatPortIdleMaxTimestamp:
2517 case MIB_KEY_StatPortInUseTotalTime:
2518 case MIB_KEY_StatPortInUseMaxTime:
2519 case MIB_KEY_StatPortInUseMaxTimestamp:
2520 if (port = findportbyindex(subid)) {
2521 get_port_stat(port, ret, key);
2522 break;
2523 }
2524 /*FALLTHRU*/
2525
2526 default:
2527 *errp = SNMP_ERR_NOSUCHNAME;
2528 snmp_var_free(ret);
2529 return NULL;
2530 }
2531 return ret;
2532 }
2533
2534 #define TDIFF(tv, time) (tv.tv_sec - time)*100 + tv.tv_usec/10000;
2535
2536 void
get_port_stat(PORT_STAT * port,struct snmp_var * var,subid_t key)2537 get_port_stat(PORT_STAT *port, struct snmp_var *var, subid_t key)
2538 {
2539 struct timeval tv;
2540 struct timezone tz;
2541 grad_nas_t *nas;
2542
2543 switch (key) {
2544
2545 case MIB_KEY_StatPortNASIndex:
2546 nas = grad_nas_lookup_ip(port->ip);
2547 var->type = ASN_INTEGER;
2548 var->val_length = sizeof(grad_counter_t);
2549 if (nas && nas->app_data) {
2550 struct nas_stat *nsp = nas->app_data;
2551 var->var_int = nsp->index;
2552 } else
2553 var->var_int = 0;
2554 break;
2555
2556 case MIB_KEY_StatPortID:
2557 var->type = ASN_INTEGER;
2558 var->val_length = sizeof(grad_counter_t);
2559 var->var_int = port->port_no;
2560 break;
2561
2562 case MIB_KEY_StatPortFramedAddress:
2563 var->type = SMI_IPADDRESS;
2564 var->val_length = sizeof(grad_uint32_t);
2565 var->var_str = snmp_alloc(sizeof(grad_uint32_t));
2566 *(grad_uint32_t*)var->var_str = port->framed_address;
2567 break;
2568
2569 case MIB_KEY_StatPortTotalLogins:
2570 var->type = SMI_COUNTER32;
2571 var->val_length = sizeof(grad_counter_t);
2572 var->var_int = port->count;
2573 break;
2574
2575 case MIB_KEY_StatPortStatus:
2576 var->type = ASN_INTEGER;
2577 var->val_length = sizeof(grad_counter_t);
2578 var->var_int = port->active ? port_active : port_idle;
2579 break;
2580
2581 case MIB_KEY_StatPortStatusChangeTimestamp:
2582 var->type = ASN_INTEGER;
2583 var->val_length = sizeof(int);
2584 var->var_int = port->start;
2585 break;
2586
2587 case MIB_KEY_StatPortUpTime:
2588 gettimeofday(&tv, &tz);
2589 var->type = SMI_TIMETICKS;
2590 var->val_length = sizeof(grad_counter_t);
2591 var->var_int = TDIFF(tv, port->start);
2592 break;
2593
2594 case MIB_KEY_StatPortLastLoginName:
2595 var->type = ASN_OCTET_STR;
2596 var->val_length = strlen(port->login);
2597 var->var_str = snmp_strdup(port->login);
2598 break;
2599
2600 case MIB_KEY_StatPortLastLoginTimestamp:
2601 var->type = ASN_INTEGER;
2602 var->val_length = sizeof(int);
2603 var->var_int = port->lastin;
2604 break;
2605
2606 case MIB_KEY_StatPortLastLogoutTimestamp:
2607 var->type = ASN_INTEGER;
2608 var->val_length = sizeof(int);
2609 var->var_int = port->lastout;
2610 break;
2611
2612 case MIB_KEY_StatPortIdleTotalTime:
2613 var->type = SMI_TIMETICKS;
2614 var->val_length = sizeof(grad_counter_t);
2615 var->var_int = port->idle * 100;
2616 break;
2617
2618 case MIB_KEY_StatPortIdleMaxTime:
2619 var->type = SMI_TIMETICKS;
2620 var->val_length = sizeof(grad_counter_t);
2621 var->var_int = port->maxidle.time * 100;
2622 break;
2623
2624 case MIB_KEY_StatPortIdleMaxTimestamp:
2625 var->type = ASN_INTEGER;
2626 var->val_length = sizeof(int);
2627 var->var_int = port->maxidle.start;
2628 break;
2629
2630 case MIB_KEY_StatPortInUseTotalTime:
2631 var->type = SMI_TIMETICKS;
2632 var->val_length = sizeof(grad_counter_t);
2633 var->var_int = port->inuse * 100;
2634 break;
2635
2636 case MIB_KEY_StatPortInUseMaxTime:
2637 var->type = SMI_TIMETICKS;
2638 var->val_length = sizeof(grad_counter_t);
2639 var->var_int = port->maxinuse.time * 100;
2640 break;
2641
2642 case MIB_KEY_StatPortInUseMaxTimestamp:
2643 var->type = ASN_INTEGER;
2644 var->val_length = sizeof(int);
2645 var->var_int = port->maxinuse.start;
2646 break;
2647 }
2648 }
2649
2650 grad_nas_t *
nas_lookup_index(int ind)2651 nas_lookup_index(int ind)
2652 {
2653 grad_nas_t *nas;
2654 grad_iterator_t *itr = grad_nas_iterator();
2655 struct nas_stat *ns;
2656
2657 for (nas = grad_iterator_first(itr); nas; nas = grad_iterator_next(itr)) {
2658 ns = nas->app_data;
2659 if (ns && ns->index == ind)
2660 break;
2661 }
2662 grad_iterator_destroy(&itr);
2663 return nas;
2664 }
2665
2666
2667 /* *********************** SNMP Protocol Interface ************************* */
2668
2669 /* Decode the SNMP request */
2670 static int
snmp_decode(SNMP_REQ * req,u_char * buf,size_t len)2671 snmp_decode(SNMP_REQ *req, u_char *buf, size_t len)
2672 {
2673 struct snmp_pdu *pdu;
2674 struct snmp_session sess;
2675 int access;
2676 char comm[128];
2677 int comm_len;
2678 char ipbuf[GRAD_IPV4_STRING_LENGTH];
2679
2680 log_open(GRAD_LOG_SNMP);
2681
2682 if ((pdu = snmp_pdu_create(0)) == NULL) {
2683 grad_log(GRAD_LOG_ERR,
2684 _("can't create SNMP PDU: %s"),
2685 snmp_strerror(snmp_errno));
2686 return -1;
2687 }
2688 comm_len = sizeof(comm);
2689 if (snmp_decode_request(&sess, pdu, buf, len, comm, &comm_len)) {
2690 grad_log(GRAD_LOG_ERR,
2691 _("can't decode SNMP packet from %s: %s"),
2692 grad_ip_iptostr(ntohl(req->addr.sin_addr.s_addr),
2693 ipbuf),
2694 snmp_strerror(snmp_errno));
2695 return -1;
2696 }
2697
2698 access = check_acl(req->addr.sin_addr.s_addr, comm);
2699 if (!access) {
2700 grad_log(GRAD_LOG_NOTICE,
2701 _("DENIED attempt to access community %s from %s"),
2702 comm,
2703 grad_ip_iptostr(ntohl(req->addr.sin_addr.s_addr),
2704 ipbuf));
2705 return 1;
2706 }
2707 req->pdu = pdu;
2708 req->community = grad_estrdup(comm);
2709 req->access = access;
2710 return 0;
2711 }
2712
2713 int
snmp_req_decode(const struct sockaddr_in * srv_sa,const struct sockaddr_in * clt_sa,void * input,size_t inputsize,void ** output)2714 snmp_req_decode(const struct sockaddr_in *srv_sa,
2715 const struct sockaddr_in *clt_sa,
2716 void *input, size_t inputsize, void **output)
2717 {
2718 SNMP_REQ *req;
2719
2720 req = grad_emalloc(sizeof *req);
2721 req->addr = *clt_sa;
2722 if (snmp_decode(req, input, inputsize)) {
2723 grad_free(req);
2724 return 1;
2725 }
2726 *output = req;
2727 return 0;
2728 }
2729
2730 int
snmp_req_cmp(void * ap,void * bp)2731 snmp_req_cmp(void *ap, void *bp)
2732 {
2733 SNMP_REQ *a = ap, *b = bp;
2734 return (a->addr.sin_addr.s_addr == b->addr.sin_addr.s_addr &&
2735 a->pdu->req_id == b->pdu->req_id) ? RCMP_EQ : RCMP_NE;
2736 }
2737
2738 /* Free the SNMP request */
2739 void
snmp_req_free(void * ptr)2740 snmp_req_free(void *ptr)
2741 {
2742 SNMP_REQ *req = ptr;
2743 snmp_pdu_free(req->pdu);
2744 grad_free(req->community);
2745 grad_free(req);
2746 }
2747
2748 void
snmp_req_drop(int type,void * data,void * orig_data,int fd,const char * status_str)2749 snmp_req_drop(int type, void *data, void *orig_data,
2750 int fd, const char *status_str)
2751 {
2752 SNMP_REQ *req = data ? data : orig_data;
2753 char ipbuf[GRAD_IPV4_STRING_LENGTH];
2754
2755 grad_log(GRAD_LOG_NOTICE,
2756 _("Dropping SNMP request from client %s: %s"),
2757 grad_ip_iptostr(ntohl(req->addr.sin_addr.s_addr), ipbuf),
2758 status_str);
2759 }
2760
2761 static u_char send_buffer[RAD_BUFFER_SIZE];
2762
2763 int
snmp_req_respond(REQUEST * request)2764 snmp_req_respond(REQUEST *request)
2765 {
2766 SNMP_REQ *req = request->data;
2767 struct snmp_session session;
2768 struct snmp_pdu *pdu;
2769 int len;
2770
2771 pdu = snmp_agent_response(req->pdu, req->access);
2772 if (pdu) {
2773 session.version = SNMP_VERSION_1;
2774 session.community.str = req->community;
2775 session.community.len = strlen(req->community);
2776 len = sizeof(send_buffer);
2777 if (snmp_encode_request(&session, pdu, send_buffer, &len)==0) {
2778 sendto(request->fd,
2779 send_buffer, len,
2780 0, (struct sockaddr *) &request->addr,
2781 sizeof(request->addr));
2782 }
2783 snmp_pdu_free(pdu);
2784 }
2785 return 0;
2786 }
2787
2788 #endif
2789
2790
2791
2792
2793
2794