diff --git a/.gitignore b/.gitignore index 32a6f77..1792b04 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ -/mib-tc-stats +/csc-snmp-subagent +/mirror-stats *.o diff --git a/Makefile b/Makefile index 450ea3e..ae0ec1d 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,11 @@ -LDFLAGS := -lnl +LDFLAGS := -lnl $(shell net-snmp-config --base-agent-libs) CFLAGS := -g3 -O2 -Wall -all: mib-tc-stats +all: mirror-stats csc-snmp-subagent + +mirror-stats: mirror-stats.o mirror-nl-glue.o + +csc-snmp-subagent: csc-snmp-subagent.o mirror-mib.o mirror-nl-glue.o clean: - rm -f mib-tc-stats + rm -f *.o mirror-stats csc-snmp-subagent diff --git a/csc-snmp-subagent.c b/csc-snmp-subagent.c new file mode 100644 index 0000000..103760b --- /dev/null +++ b/csc-snmp-subagent.c @@ -0,0 +1,221 @@ +/* generated from net-snmp-config */ +#include +#ifdef HAVE_SIGNAL +#include +#endif /* HAVE_SIGNAL */ +#include +#include + #include "mirror-mib.h" +const char *app_name = "cscMIB"; + +extern int netsnmp_running; + +#ifdef __GNUC__ +#define UNUSED __attribute__((unused)) +#else +#define UNUSED +#endif + +RETSIGTYPE +stop_server(UNUSED int a) { + netsnmp_running = 0; +} + +static void +usage(const char *prog) +{ + fprintf(stderr, + "USAGE: %s [OPTIONS]\n" + "\n" + "OPTIONS:\n", prog); + + fprintf(stderr, + " -d\t\t\tdump all traffic\n" + " -D TOKEN[,...]\tturn on debugging output for the specified " + "TOKENs\n" + "\t\t\t (ALL gives extremely verbose debugging output)\n" + " -f\t\t\tDo not fork() from the calling shell.\n" + " -h\t\t\tdisplay this help message\n" + " -H\t\t\tdisplay a list of configuration file directives\n" + " -L LOGOPTS\t\tToggle various defaults controlling logging:\n"); + snmp_log_options_usage("\t\t\t ", stderr); +#ifndef DISABLE_MIB_LOADING + fprintf(stderr, + " -m MIB[:...]\t\tload given list of MIBs (ALL loads " + "everything)\n" + " -M DIR[:...]\t\tlook in given list of directories for MIBs\n"); +#endif /* DISABLE_MIB_LOADING */ +#ifndef DISABLE_MIB_LOADING + fprintf(stderr, + " -P MIBOPTS\t\tToggle various defaults controlling mib " + "parsing:\n"); + snmp_mib_toggle_options_usage("\t\t\t ", stderr); +#endif /* DISABLE_MIB_LOADING */ + fprintf(stderr, + " -v\t\t\tdisplay package version number\n" + " -x TRANSPORT\tconnect to master agent using TRANSPORT\n"); + exit(1); +} + +static void +version(void) +{ + fprintf(stderr, "NET-SNMP version: %s\n", netsnmp_get_version()); + exit(0); +} + +int +main (int argc, char **argv) +{ + int arg; + char* cp = NULL; + int dont_fork = 0, do_help = 0; + + while ((arg = getopt(argc, argv, "dD:fhHL:" +#ifndef DISABLE_MIB_LOADING + "m:M:" +#endif /* DISABLE_MIB_LOADING */ + "n:" +#ifndef DISABLE_MIB_LOADING + "P:" +#endif /* DISABLE_MIB_LOADING */ + "vx:")) != EOF) { + switch (arg) { + case 'd': + netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, + NETSNMP_DS_LIB_DUMP_PACKET, 1); + break; + + case 'D': + debug_register_tokens(optarg); + snmp_set_do_debugging(1); + break; + + case 'f': + dont_fork = 1; + break; + + case 'h': + usage(argv[0]); + break; + + case 'H': + do_help = 1; + break; + + case 'L': + if (snmp_log_options(optarg, argc, argv) < 0) { + exit(1); + } + break; + +#ifndef DISABLE_MIB_LOADING + case 'm': + if (optarg != NULL) { + setenv("MIBS", optarg, 1); + } else { + usage(argv[0]); + } + break; + + case 'M': + if (optarg != NULL) { + setenv("MIBDIRS", optarg, 1); + } else { + usage(argv[0]); + } + break; +#endif /* DISABLE_MIB_LOADING */ + + case 'n': + if (optarg != NULL) { + app_name = optarg; + netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID, + NETSNMP_DS_LIB_APPTYPE, app_name); + } else { + usage(argv[0]); + } + break; + +#ifndef DISABLE_MIB_LOADING + case 'P': + cp = snmp_mib_toggle_options(optarg); + if (cp != NULL) { + fprintf(stderr, "Unknown parser option to -P: %c.\n", *cp); + usage(argv[0]); + } + break; +#endif /* DISABLE_MIB_LOADING */ + + case 'v': + version(); + break; + + case 'x': + if (optarg != NULL) { + netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, + NETSNMP_DS_AGENT_X_SOCKET, optarg); + } else { + usage(argv[0]); + } + break; + + default: + fprintf(stderr, "invalid option: -%c\n", arg); + usage(argv[0]); + break; + } + } + + if (do_help) { + netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, + NETSNMP_DS_AGENT_NO_ROOT_ACCESS, 1); + } else { + /* we are a subagent */ + netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, + NETSNMP_DS_AGENT_ROLE, 1); + + if (!dont_fork) { + if (netsnmp_daemonize(1, snmp_stderrlog_status()) != 0) + exit(1); + } + + /* initialize tcpip, if necessary */ + SOCK_STARTUP; + } + + /* initialize the agent library */ + init_agent(app_name); + + /* initialize your mib code here */ + init_mirror_mib(); + + /* cscMIB will be used to read cscMIB.conf files. */ + init_snmp("cscMIB"); + + if (do_help) { + fprintf(stderr, "Configuration directives understood:\n"); + read_config_print_usage(" "); + exit(0); + } + + /* In case we received a request to stop (kill -TERM or kill -INT) */ + netsnmp_running = 1; +#ifdef SIGTERM + signal(SIGTERM, stop_server); +#endif +#ifdef SIGINT + signal(SIGINT, stop_server); +#endif + + /* main loop here... */ + while(netsnmp_running) { + agent_check_and_process(1); + } + + /* at shutdown time */ + snmp_shutdown(app_name); + SOCK_CLEANUP; + exit(0); +} + diff --git a/cscMIB.h b/cscMIB.h deleted file mode 100644 index 63a036c..0000000 --- a/cscMIB.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Note: this file originally auto-generated by mib2c using - * : mib2c.scalar.conf 11805 2005-01-07 09:37:18Z dts12 $ - */ -#ifndef CSCMIB_H -#define CSCMIB_H - -/* - * function declarations - */ -void init_cscMIB(void); -Netsnmp_Node_Handler handle_cogentBytes; -Netsnmp_Node_Handler handle_orionBytes; -Netsnmp_Node_Handler handle_campusBytes; - -#endif /* CSCMIB_H */ diff --git a/cscMIB.c b/mirror-mib.c similarity index 77% rename from cscMIB.c rename to mirror-mib.c index 663ed84..4cd7e87 100644 --- a/cscMIB.c +++ b/mirror-mib.c @@ -6,12 +6,11 @@ #include #include #include -#include "cscMIB.h" -#include "mib-tc-stats.h" +#include "mirror-mib.h" +#include "mirror-nl-glue.h" -/** Initializes the cscMIB module */ void -init_cscMIB(void) +init_mirror_mib(void) { static oid cogentBytes_oid[] = { 1, 3, 6, 1, 4, 1, 27934, 2, 2, 1 }; @@ -20,7 +19,9 @@ init_cscMIB(void) static oid campusBytes_oid[] = { 1, 3, 6, 1, 4, 1, 27934, 2, 2, 3 }; - DEBUGMSGTL(("cscMIB", "Initializing\n")); + DEBUGMSGTL(("mirror_mib", "Initializing\n")); + + mirror_stats_initialize(); netsnmp_register_scalar(netsnmp_create_handler_registration ("cogentBytes", handle_cogentBytes, @@ -36,20 +37,25 @@ init_cscMIB(void) HANDLER_CAN_RONLY)); } +void explode_counter64(uint64_t num, struct counter64 *counter) { + counter->low = num & 0xFFFFFFFF; + counter->high = (num >> 32) & 0xFFFFFFFF; +} + int handle_cogentBytes(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { - uint64_t bytes; + struct counter64 counter; mirror_stats_refresh(); - bytes = get_class_byte_count(&cogent_class); + explode_counter64(get_class_byte_count(&cogent_class), &counter); switch (reqinfo->mode) { case MODE_GET: snmp_set_var_typed_value(requests->requestvb, ASN_COUNTER64, - (u_char *)&bytes, sizeof(bytes)); + (u_char *)&counter, sizeof(counter)); break; default: die("unknown mode"); @@ -64,14 +70,14 @@ handle_orionBytes(netsnmp_mib_handler *handler, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { - uint64_t bytes; + struct counter64 counter; mirror_stats_refresh(); - bytes = get_class_byte_count(&orion_class); + explode_counter64(get_class_byte_count(&orion_class), &counter); switch (reqinfo->mode) { case MODE_GET: snmp_set_var_typed_value(requests->requestvb, ASN_COUNTER64, - (u_char *)&bytes, sizeof(bytes)); + (u_char *)&counter, sizeof(counter)); break; default: die("unknown mode"); @@ -86,14 +92,14 @@ handle_campusBytes(netsnmp_mib_handler *handler, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { - uint64_t bytes; + struct counter64 counter; mirror_stats_refresh(); - bytes = get_class_byte_count(&campus_class); + explode_counter64(get_class_byte_count(&campus_class), &counter); switch (reqinfo->mode) { case MODE_GET: snmp_set_var_typed_value(requests->requestvb, ASN_COUNTER64, - (u_char *)&bytes, sizeof(bytes)); + (u_char *)&counter, sizeof(counter)); break; default: die("unknown mode"); diff --git a/mirror-mib.h b/mirror-mib.h new file mode 100644 index 0000000..f707f97 --- /dev/null +++ b/mirror-mib.h @@ -0,0 +1,9 @@ +#ifndef MIRRORMIB_H +#define MIRRORMIB_H + +void init_mirror_mib(void); +Netsnmp_Node_Handler handle_cogentBytes; +Netsnmp_Node_Handler handle_orionBytes; +Netsnmp_Node_Handler handle_campusBytes; + +#endif diff --git a/mib-tc-stats.c b/mirror-nl-glue.c similarity index 98% rename from mib-tc-stats.c rename to mirror-nl-glue.c index b01a98e..720ac6a 100644 --- a/mib-tc-stats.c +++ b/mirror-nl-glue.c @@ -8,7 +8,7 @@ #include #include #include -#include "mib-tc-stats.h" +#include "mirror-nl-glue.h" static struct nl_cache *link_cache, *class_cache; static struct rtnl_link *eth; diff --git a/mib-tc-stats.h b/mirror-nl-glue.h similarity index 100% rename from mib-tc-stats.h rename to mirror-nl-glue.h diff --git a/mib-tc-test.c b/mirror-stats.c similarity index 93% rename from mib-tc-test.c rename to mirror-stats.c index aeaa2e8..44bade4 100644 --- a/mib-tc-test.c +++ b/mirror-stats.c @@ -1,4 +1,4 @@ -#include "mib-tc-stats.h" +#include "mirror-nl-glue.h" int main(int argc, char *argv[]) { mirror_stats_initialize();