aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/.gitignore1
-rw-r--r--src/Makefile.am5
-rw-r--r--src/VARNISH-MIB.txt83
-rw-r--r--src/ban.c191
-rw-r--r--src/varnish_mib.h52
-rw-r--r--src/varnish_mib.mib2c258
6 files changed, 503 insertions, 87 deletions
diff --git a/src/.gitignore b/src/.gitignore
index 49f397c..61958b7 100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -1 +1,2 @@
varnish_mib.c
+varnish_mib.h
diff --git a/src/Makefile.am b/src/Makefile.am
index a0e7e72..4643fde 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -18,27 +18,28 @@ dlmoddir=@DLMODDIR@
dlmod_LTLIBRARIES = varnish-mib.la
varnish_mib_la_SOURCES = \
auth.c\
ban.c\
sha256.c\
sha256.h\
varnish_mib.c\
varnish_mib.h\
vcli.c
BUILT_SOURCES = \
- varnish_mib.c
+ varnish_mib.c\
+ varnish_mib.h
-varnish_mib.c: varnish_mib.mib2c VARNISH-MIB.txt
+varnish_mib.c varnish_mib.h: varnish_mib.mib2c VARNISH-MIB.txt
.mib2c.c:
MIBDIRS=${top_srcdir}/src:${NET_SNMP_MIBDIRS} MIBS="+VARNISH-MIB" \
mib2c -c $< -f $@ varnish
#NET_SNMP_INCLUDES = `$(NET_SNMP_CONFIG) --cflags`
NET_SNMP_INCLUDES =
NET_SNMP_LIBS = `$(NET_SNMP_CONFIG) --libs`
NET_SNMP_EXLIBS = `$(NET_SNMP_CONFIG) --external-libs`
NET_SNMP_MIBDIRS = `net-snmp-config --mibdirs`
AM_LDFLAGS = \
diff --git a/src/VARNISH-MIB.txt b/src/VARNISH-MIB.txt
index cde935a..47e39c8 100644
--- a/src/VARNISH-MIB.txt
+++ b/src/VARNISH-MIB.txt
@@ -2,34 +2,36 @@ VARNISH-MIB DEFINITIONS ::= BEGIN
-- *************************************************************
-- $Id: VARNISH-MIB.txt 8 2014-11-24 14:38:24Z graygnuorg $
--
-- Varnish reverse proxy MIB
-- by Shared Autonomous sYstems
--
-- *************************************************************
IMPORTS
MODULE-IDENTITY, OBJECT-TYPE, enterprises, Counter64, TimeTicks
FROM SNMPv2-SMI
+ DateAndTime
+ FROM SNMPv2-TC
OBJECT-GROUP, MODULE-COMPLIANCE
FROM SNMPv2-CONF;
varnishMIB MODULE-IDENTITY
- LAST-UPDATED "201411241848Z"
+ LAST-UPDATED "201411260759Z"
ORGANIZATION "Shared Autonomous sYstems"
CONTACT-INFO "mhe@say.no"
DESCRIPTION
"This MIB module defines objects for Varnish reverse web proxy."
- REVISION "201411241848Z"
+ REVISION "201411260759Z"
DESCRIPTION
"Initial version."
::= { varnish 0 }
varnish OBJECT IDENTIFIER ::= { enterprises 33043 6 1 }
client OBJECT IDENTIFIER ::= { varnish 1 }
backend OBJECT IDENTIFIER ::= { varnish 2 }
total OBJECT IDENTIFIER ::= { varnish 3 }
master OBJECT IDENTIFIER ::= { varnish 4 }
session OBJECT IDENTIFIER ::= { varnish 5 }
threads OBJECT IDENTIFIER ::= { varnish 6 }
bans OBJECT IDENTIFIER ::= { varnish 7 }
@@ -65,26 +67,32 @@ clientCacheHitsPass OBJECT-TYPE
DESCRIPTION
"Cache hits for pass"
::= { client 4 }
clientCacheMisses OBJECT-TYPE
SYNTAX Counter64
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Cache misses"
::= { client 5 }
+VarnishBanString ::= TEXTUAL-CONVENTION
+ DISPLAY-HINT "1024t"
+ STATUS current
+ DESCRIPTION ""
+ SYNTAX OCTET STRING (SIZE (0..1024))
+
clientBan OBJECT-TYPE
- SYNTAX OCTET STRING (SIZE(0..1024))
+ SYNTAX VarnishBanString
MAX-ACCESS read-write
STATUS current
DESCRIPTION
"When set, invalidates the cache using the supplied value as
argument to ban. When read, returns an empty string."
::= { client 6 }
clientRequests400 OBJECT-TYPE
SYNTAX Counter64
MAX-ACCESS read-only
STATUS current
DESCRIPTION
@@ -518,26 +526,81 @@ bansPersistedBytes OBJECT-TYPE
STATUS current
DESCRIPTION
"Number of bytes used by the persisted ban lists"
::= { bans 15 }
bansPersistedFragmentation OBJECT-TYPE
SYNTAX Counter64
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Extra bytes in persisted ban lists due to fragmentation"
::= { bans 17 }
-
+banTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF VarnishBanEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "The (conceptual) table listing available bans"
+ ::= { bans 18 }
+
+varnishBanEntry OBJECT-TYPE
+ SYNTAX VarnishBanEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "An entry (conceptual row) representing a ban"
+ INDEX { banIndex }
+ ::= { banTable 1 }
+
+VarnishBanEntry ::= SEQUENCE {
+ banIndex Integer32,
+ banTime DateAndTime,
+ banRefCount Counter64,
+ banExpression VarnishBanString
+}
+
+banIndex OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "A number uniquely identifying each ban"
+ ::= { varnishBanEntry 1 }
+
+banTime OBJECT-TYPE
+ SYNTAX DateAndTime
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Time when the ban was created"
+ ::= { varnishBanEntry 2 }
+
+banRefCount OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Number of references to this ban"
+ ::= { varnishBanEntry 3 }
+
+banExpression OBJECT-TYPE
+ SYNTAX VarnishBanString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "VCL expression of the ban"
+ ::= { varnishBanEntry 4 }
+
--
-- Groups and Compliance
--
varnishConfs OBJECT IDENTIFIER ::= { varnish 100 }
varnishGroups OBJECT IDENTIFIER ::= { varnishConfs 1 }
varnishCompl OBJECT IDENTIFIER ::= { varnishConfs 2 }
--
-- Groups
--
varnishGroup OBJECT-GROUP
OBJECTS {
@@ -576,43 +639,47 @@ varnishGroup OBJECT-GROUP
sessPipeline,
sessReadAhead,
sessHerd,
sessDrop,
sessFail,
sessPipeOverflow,
threadsPools,
threadsTotal,
threadsLimitHits,
threadsCreated,
threadsDestroyed,
threadsFailed,
- threadsQueueLength
-
+ threadsQueueLength,
+ banTable,
+ varnishBanEntry,
+ banIndex,
+ banTime,
+ banRefCount,
+ banExpression
}
STATUS current
DESCRIPTION "Group of Varnish objects"
::= { varnishGroups 1 }
--
-- Compliance
--
varnishStandardComplianceV1 MODULE-COMPLIANCE
STATUS current
DESCRIPTION
"Compliance for an Varnish agent"
MODULE
- MANDATORY-GROUPS {
- varnishGroup}
+ MANDATORY-GROUPS { varnishGroup }
::= { varnishCompl 1 }
END
-- Local variables:
-- eval: (add-hook 'write-file-hooks 'time-stamp)
-- time-stamp-start: "\\(LAST-UPDATED\\|REVISION\\) *\""
-- time-stamp-end: "\""
-- time-stamp-format: "%:y%02m%02d%02H%02MZ"
-- time-stamp-line-limit: 25
-- time-stamp-count: 2
diff --git a/src/ban.c b/src/ban.c
index a091e37..a3941ab 100644
--- a/src/ban.c
+++ b/src/ban.c
@@ -7,24 +7,25 @@
any later version.
Varnish-mib is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with varnish-mib. If not, see <http://www.gnu.org/licenses/>.
*/
#include "varnish_mib.h"
+#include <ctype.h>
static int
send_ban_cmd(vcli_conn_t *conn, const char *expr)
{
if (vcli_asprintf(conn, "ban %s\n", expr) || vcli_write(conn))
return 1;
if (vcli_read_response(conn))
return 1;
if (conn->resp != CLIS_OK) {
snmp_log(LOG_ERR, "command rejected: %u %s\n",
@@ -41,22 +42,208 @@ varnish_ban(netsnmp_agent_request_info *reqinfo,
{
int rc;
struct vcli_conn conn;
size_t len = requests->requestvb->val_len;
char *expr = malloc(len + 1);
if (!expr) {
snmp_log(LOG_ERR, "out of memory\n");
return SNMP_ERR_GENERR;
}
memcpy(expr, requests->requestvb->val.string, len);
expr[len] = 0;
- DEBUGMSGTL(("vcli_mib", "ban %s\n", expr));
+ DEBUGMSGTL(("varnish_ban", "setting ban %s\n", expr));
rc = vcli_connect(vd, &conn);
if (rc == SNMP_ERR_NOERROR) {
rc = send_ban_cmd(&conn, expr);
- vcli_disconnect(&conn);
+ vcli_disconnect(&conn);
}
free(expr);
return rc ? SNMP_ERR_GENERR : SNMP_ERR_NOERROR;
}
+
+unsigned banTable_timeout = 60;
+/*
+ * create a new row in the table
+ */
+static struct banTable_entry *
+create_entry(netsnmp_tdata *table_data, long idx, struct banTable_entry *ent)
+{
+ struct banTable_entry *entry;
+ netsnmp_tdata_row *row;
+
+ entry = SNMP_MALLOC_TYPEDEF(struct banTable_entry);
+ if (!entry)
+ return NULL;
+
+ row = netsnmp_tdata_create_row();
+ if (!row) {
+ SNMP_FREE(entry);
+ return NULL;
+ }
+ row->data = entry;
+ *entry = *ent;
+
+ entry->banIndex = idx;
+ netsnmp_tdata_row_add_index(row, ASN_INTEGER,
+ &entry->banIndex,
+ sizeof(entry->banIndex));
+ if (table_data)
+ netsnmp_tdata_add_row(table_data, row);
+ return entry;
+}
+
+#define TMSEC(t) (((t)->tm_hour * 60 + (t)->tm_min) * 60 + (t)->tm_sec)
+
+static int
+utc_offset (void)
+{
+ time_t t = time (NULL);
+ struct tm ltm = *localtime (&t);
+ struct tm gtm = *gmtime (&t);
+ int d = TMSEC (&ltm) - TMSEC (&gtm);
+ if (!(ltm.tm_year = gtm.tm_year && ltm.tm_mon == gtm.tm_mon))
+ d += 86400;
+ return d / 60;
+}
+
+/* Refill the ban table */
+int
+banTable_load(netsnmp_cache *cache, void *vmagic)
+{
+ netsnmp_tdata *table = (netsnmp_tdata *) vmagic;
+ long idx = 0;
+ int rc;
+ struct vcli_conn conn;
+ char *p;
+ struct VSM_data *vd;
+
+ DEBUGMSGTL(("varnish_ban", "reloading ban table"));
+ vd = varnish_get_vsm_data();
+ rc = vcli_connect(vd, &conn);
+ if (rc != SNMP_ERR_NOERROR)
+ return rc;
+
+ if (vcli_asprintf(&conn, "ban.list\n") || vcli_write(&conn))
+ return SNMP_ERR_GENERR;
+
+ if (vcli_read_response(&conn))
+ return SNMP_ERR_GENERR;
+
+ if (conn.resp != CLIS_OK) {
+ snmp_log(LOG_ERR, "ban.list command rejected: %u %s\n",
+ conn.resp, conn.base);
+ return SNMP_ERR_GENERR;
+ }
+
+ p = conn.base;
+ while (p < conn.base + conn.bufsize) {
+ char *q;
+ struct banTable_entry e;
+ struct tm *tm;
+ time_t t;
+ int n;
+
+ if (*p == '\n') {
+ ++p;
+ continue;
+ }
+ e.banIndex = idx;
+ t = strtoul(p, &q, 10);
+ if (*q != '.') {
+ p = strchr(p, '\n');
+ if (!p)
+ break;
+ continue;
+ }
+ ++q;
+
+ e.banTime_len = 11;
+ e.banTime = malloc(e.banTime_len + 1);
+ if (!e.banTime) {
+ vcli_disconnect(&conn);
+ snmp_log(LOG_ERR, "out of memory\n");
+ return SNMP_ERR_GENERR;
+ }
+ tm = localtime(&t);
+ /* A date-time specification.
+
+ field octets contents range
+ ----- ------ -------- -----
+ 1 1-2 year* 0..65536
+ 2 3 month 1..12
+ 3 4 day 1..31
+ 4 5 hour 0..23
+ 5 6 minutes 0..59
+ 6 7 seconds 0..60
+ (use 60 for leap-second)
+ 7 8 deci-seconds 0..9
+ 8 9 direction from UTC '+' / '-'
+ 9 10 hours from UTC* 0..13
+ 10 11 minutes from UTC 0..59
+
+ * Notes:
+ - the value of year is in network-byte order
+ */
+ n = tm->tm_year % 100;
+ e.banTime[0] = n >> 8;
+ e.banTime[1] = n & 0xff;
+ e.banTime[2] = tm->tm_mon + 1;
+ e.banTime[3] = tm->tm_mday;
+ e.banTime[4] = tm->tm_hour;
+ e.banTime[5] = tm->tm_min;
+ e.banTime[6] = tm->tm_sec;
+ e.banTime[7] = *q - '0';
+ n = utc_offset();
+ if (n < 0) {
+ e.banTime[8] = '-';
+ n = - n;
+ } else
+ e.banTime[8] = '+';
+ e.banTime[9] = n / 60;
+ e.banTime[10] = n % 60;
+
+ while (*q && isdigit(*q))
+ ++q;
+ while (*q && isspace(*q))
+ ++q;
+ e.banRefCount = strtoul(q, &q, 10);
+
+ while (*q && isspace(*q))
+ ++q;
+
+ e.banExpression_len = strcspn(q, "\n");
+ e.banExpression = malloc(e.banExpression_len);
+ if (!e.banExpression) {
+ vcli_disconnect(&conn);
+ free(e.banTime);
+ snmp_log(LOG_ERR, "out of memory\n");
+ return SNMP_ERR_GENERR;
+ }
+ memcpy(e.banExpression, q, e.banExpression_len);
+
+ create_entry(table, idx, &e);
+ ++idx;
+ q += e.banExpression_len;
+ p = q;
+ }
+ vcli_disconnect(&conn);
+ DEBUGMSGTL(("varnish_ban", "loaded %ld ban entries", idx));
+ return 0;
+}
+
+void
+banTable_free(netsnmp_cache *cache, void *vmagic)
+{
+ netsnmp_tdata *table = (netsnmp_tdata *) vmagic;
+ netsnmp_tdata_row *row;
+
+ DEBUGMSGTL(("varnish_ban", "freeing ban table"));
+ while ((row = netsnmp_tdata_row_first(table))) {
+ struct banTable_entry *entry = row->data;
+ free(entry->banExpression);
+ free(entry->banTime);
+ SNMP_FREE(entry);
+ netsnmp_tdata_remove_and_delete_row(table, row);
+ }
+}
diff --git a/src/varnish_mib.h b/src/varnish_mib.h
deleted file mode 100644
index 31e3de1..0000000
--- a/src/varnish_mib.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* This file is part of varnish-mib -*- c -*-
- Copyright (C) 2014 Sergey Poznyakoff
-
- Varnish-mib is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3, or (at your option)
- any later version.
-
- Varnish-mib is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with varnish-mib. If not, see <http://www.gnu.org/licenses/>.
-*/
-#include <config.h>
-#include <stdlib.h>
-#include <stdint.h>
-
-#include <vapi/vsc.h>
-#include <vapi/vsm.h>
-#include <vcli.h>
-
-#include <net-snmp/net-snmp-config.h>
-#include <net-snmp/net-snmp-includes.h>
-#include <net-snmp/agent/net-snmp-agent-includes.h>
-
-typedef struct vcli_conn {
- int fd;
- char *secret;
- int resp;
- char *base;
- size_t bufmax;
- size_t bufsize;
-} vcli_conn_t;
-
-int vcli_write(vcli_conn_t *conn);
-int vcli_read_response(vcli_conn_t *conn);
-int vcli_vasprintf(vcli_conn_t *conn, const char *fmt, va_list ap);
-int vcli_asprintf(vcli_conn_t *conn, const char *fmt, ...);
-void vcli_disconnect(vcli_conn_t *conn);
-int vcli_connect(struct VSM_data *vd, vcli_conn_t *conn);
-
-
-int varnish_auth_response(const char *file, const char *challenge,
- char response[CLI_AUTH_RESPONSE_LEN + 1]);
-
-int varnish_ban(netsnmp_agent_request_info *reqinfo,
- netsnmp_request_info *requests,
- struct VSM_data *vd);
-
diff --git a/src/varnish_mib.mib2c b/src/varnish_mib.mib2c
index 9825728..34f0f16 100644
--- a/src/varnish_mib.mib2c
+++ b/src/varnish_mib.mib2c
@@ -14,46 +14,24 @@
# You should have received a copy of the GNU General Public License
# along with varnish-mib. If not, see <http://www.gnu.org/licenses/>.
# This macro inserts a comment instructing Emacs and vi that
# this file is read-only. It must be called at the end of the file.
@define ROCOM@
/* Local variables:
buffer-read-only: t
End:
vi: set ro:
*/
@enddefine@
-@open ${name}@
-/* THIS FILE IS GENERATED AUTOMATICALLY. PLEASE DO NOT EDIT. */
-
-#include "varnish_mib.h"
-
-static struct VSM_data *vd;
-
-void
-varnish_snmp_init(void)
-{
- vd = VSM_New();
-
- if (VSM_Open(vd))
- exit(1);
-}
-
-void
-varnish_snmp_deinit(void)
-{
- VSM_Close(vd);
-}
-
@startperl@
$vars{'varnish_translate'} = sub {
my $name = shift;
my %trans = (
uptime => [ 'MAIN', 'uptime' ],
clientAcceptedConnections => [ 'MAIN', 'sess_conn' ],
clientRequestsReceived => [ 'MAIN', 'client_req' ],
clientCacheHits => [ 'MAIN', 'cache_hit' ],
clientCacheHitsPass => [ 'MAIN', 'cache_hitpass' ],
clientCacheMisses => [ 'MAIN', 'cache_miss' ],
clientBan => [ 'STRING', '',
{ varnish_set_action => 'varnish_ban' } ],
@@ -132,28 +110,101 @@ $vars{'varnish_translate'} = sub {
$vars{'varnish_member'} = $r->[1];
if ($#{$r} == 2) {
@vars{keys %{$r->[2]}} = values %{$r->[2]};
} else {
delete $vars{$setkw};
}
return 0;
};
$vars{'modulename'} = $vars{'name'};
$vars{'modulename'} =~ s#.*/##;
$vars{'modulename'} =~ s/\.c$//;
-print "$vars{'modulename'}\n";
+#print "$vars{'modulename'}\n";
0;
@endperl@
+@open ${modulename}.h@
+/* THIS FILE IS GENERATED AUTOMATICALLY. PLEASE DO NOT EDIT. */
+#include <config.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+#include <vapi/vsc.h>
+#include <vapi/vsm.h>
+#include <vcli.h>
+
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/agent/net-snmp-agent-includes.h>
+
+typedef struct vcli_conn {
+ int fd;
+ char *secret;
+ int resp;
+ char *base;
+ size_t bufmax;
+ size_t bufsize;
+} vcli_conn_t;
+
+int vcli_write(vcli_conn_t *conn);
+int vcli_read_response(vcli_conn_t *conn);
+int vcli_vasprintf(vcli_conn_t *conn, const char *fmt, va_list ap);
+int vcli_asprintf(vcli_conn_t *conn, const char *fmt, ...);
+void vcli_disconnect(vcli_conn_t *conn);
+int vcli_connect(struct VSM_data *vd, vcli_conn_t *conn);
+
+struct VSM_data *varnish_get_vsm_data(void);
+
+int varnish_auth_response(const char *file, const char *challenge,
+ char response[CLI_AUTH_RESPONSE_LEN + 1]);
+
+int varnish_ban(netsnmp_agent_request_info *reqinfo,
+ netsnmp_request_info *requests,
+ struct VSM_data *vd);
+
+extern unsigned banTable_timeout;
+
+@open ${name}@
+/* THIS FILE IS GENERATED AUTOMATICALLY. PLEASE DO NOT EDIT. */
+
+#include "varnish_mib.h"
+
+static struct VSM_data *vd;
+
+void
+varnish_snmp_init(void)
+{
+ vd = VSM_New();
+
+ if (VSM_Open(vd))
+ exit(1);
+}
+
+void
+varnish_snmp_deinit(void)
+{
+ VSM_Close(vd);
+}
+
+struct VSM_data *
+varnish_get_vsm_data()
+{
+ if (VSM_Abandoned(vd)) {
+ DEBUGMSGTL(("$modulename", "reopening vd\n"));
+ VSM_Close(vd);
+ VSM_Open(vd);
+ }
+ return vd;
+}
/* Variable handlers.
An instance handler only hands us one request at a time, unwrapping
any eventual GETNEXT requests.
*/
@foreach $i scalar@
static int
handle_$i(netsnmp_mib_handler *handler,
netsnmp_handler_registration *reginfo,
netsnmp_agent_request_info *reqinfo,
@@ -264,43 +315,204 @@ handle_$i(netsnmp_mib_handler *handler,
@end@
default:
/* we should never get here, so this is a really bad error */
snmp_log(LOG_ERR, "unknown mode (%d) in handle_${i}\n", reqinfo->mode );
return SNMP_ERR_GENERR;
}
return SNMP_ERR_NOERROR;
}
@end@
+@foreach $i table@
+ ## Determine the first/last column names
+ @eval $first_column = "-"@
+ @eval $last_column = "-"@
+ @foreach $c column@
+ @if $c.readable@
+ @if "$first_column" eq "-"@
+ @eval $first_column = $c@
+ @end@
+ @eval $last_column = $c@
+ @end@
+ @end@
+
+@push@
+@append ${modulename}.h@
+/* column number definitions for table $i */
+ @foreach $c column@
+#define COLUMN_$c.uc $c.subid
+ @end@
+
+struct ${i}_entry {
+ /* Index values */
+ @foreach $idx index@
+ @if $idx.needlength@
+ $idx.decl *$idx;
+ size_t ${idx}_len;
+ @else@
+ $idx.decl $idx;
+ @end@
+ @end@
+
+ /* Column values */
+ @foreach $c nonindex@
+ @if $c.readable@
+ @if $c.needlength@
+ $c.decl *$c;
+ size_t ${c}_len;
+ @else@
+ $c.decl $c;
+ @end@
+ @end@
+ @end@
+};
+
+int ${i}_load(netsnmp_cache *cache, void *vmagic);
+void ${i}_free(netsnmp_cache *cache, void *vmagic);
+@pop@
+
+/** handles requests for the $i table */
+static int
+handle_table_${i}(
+ netsnmp_mib_handler *handler,
+ netsnmp_handler_registration *reginfo,
+ netsnmp_agent_request_info *reqinfo,
+ netsnmp_request_info *requests)
+{
+ netsnmp_request_info *request;
+ netsnmp_table_request_info *table_info;
+ struct ${i}_entry *table_entry;
+
+ switch (reqinfo->mode) {
+ case MODE_GET:
+ for (request = requests; request; request = request->next) {
+ table_entry = (struct ${i}_entry *)
+ netsnmp_tdata_extract_entry(request);
+ table_info = netsnmp_extract_table_info(request);
+
+ switch (table_info->colnum) {
+ @foreach $c column@
+ @if $c.readable@
+ case COLUMN_$c.uc:
+ if (!table_entry) {
+ netsnmp_set_request_error(reqinfo, request,
+ SNMP_NOSUCHINSTANCE);
+ continue;
+ }
+ @if $c.needlength@
+ snmp_set_var_typed_value(request->requestvb, $c.type,
+ table_entry->$c,
+ table_entry->${c}_len);
+ @else@
+ snmp_set_var_typed_integer(request->requestvb, $c.type,
+ table_entry->$c);
+ @end@
+ break;
+ @end@
+ @end@
+ default:
+ netsnmp_set_request_error(reqinfo, request,
+ SNMP_NOSUCHOBJECT);
+ break;
+ }
+ }
+ break;
+ default:
+ /* we should never get here, so this is a really bad error */
+ snmp_log(LOG_ERR, "unknown mode (%d) in handle_table_${i}\n",
+ reqinfo->mode);
+ return SNMP_ERR_GENERR;
+
+ }
+ return SNMP_ERR_NOERROR;
+}
+
+/** Initialize the $i table by defining its contents and how it's structured */
+static void
+initialize_table_$i(void)
+{
+ const oid ${i}_oid[] = {$i.commaoid};
+ const size_t ${i}_oid_len = OID_LENGTH(${i}_oid);
+ netsnmp_handler_registration *reg;
+ netsnmp_tdata *table_data;
+ netsnmp_table_registration_info *table_info;
+ netsnmp_cache *cache;
+
+ DEBUGMSGTL(("${name}:init", "initializing table $i\n"));
+
+ reg = netsnmp_create_handler_registration("$i", handle_table_${i},
+ ${i}_oid, ${i}_oid_len,
+ HANDLER_CAN_RONLY);
+
+ table_data = netsnmp_tdata_create_table("$i", 0);
+ if (!table_data) {
+ snmp_log(LOG_ERR,"error creating tdata table for $i\n");
+ return;
+ }
+ cache = netsnmp_cache_create(${i}_timeout,
+ ${i}_load, ${i}_free,
+ ${i}_oid, ${i}_oid_len);
+ if (!cache) {
+ snmp_log(LOG_ERR,"error creating cache for $i\n");
+ } else
+ cache->magic = (void *)table_data;
+ table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
+ if (!table_info) {
+ snmp_log(LOG_ERR,"error creating table info for $i\n");
+ return;
+ }
+ netsnmp_table_helper_add_indexes(table_info,
+ @foreach $idx index@
+ $idx.type, /* index: $idx */
+ @end@
+ 0);
+
+ table_info->min_column = COLUMN_$first_column.uc;
+ table_info->max_column = COLUMN_$last_column.uc;
+
+ netsnmp_tdata_register(reg, table_data, table_info);
+ if (cache)
+ netsnmp_inject_handler(reg, netsnmp_cache_handler_get(cache));
+/*
+ netsnmp_inject_handler_before(reg, netsnmp_cache_handler_get(cache),
+ TABLE_TDATA_NAME);
+*/
+}
+
+@end@
+
/** Initializes the $name module */
void
init_$modulename(void)
{
@foreach $i scalar@
const oid ${i}_oid[] = { $i.commaoid };
@end@
DEBUGMSGTL(("$modulename", "Initializing\n"));
@foreach $i scalar@
netsnmp_register_scalar(
netsnmp_create_handler_registration("$i", handle_$i,
${i}_oid, OID_LENGTH(${i}_oid),
@if !$i.settable@
HANDLER_CAN_RONLY
@end@
@if $i.settable@
HANDLER_CAN_RWRITE
@end@
));
@end@
+ @foreach $i table@
+ initialize_table_$i();
+ @end@
varnish_snmp_init();
}
void
deinit_$modulename(void)
{
varnish_snmp_deinit();
}
@calldefine ROCOM@

Return to:

Send suggestions and report system problems to the System administrator.