aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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
@@ -27,9 +27,10 @@ varnish_mib_la_SOURCES = \
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" \
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
@@ -11,16 +11,18 @@ VARNISH-MIB DEFINITIONS ::= BEGIN
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 }
@@ -74,8 +76,14 @@ clientCacheMisses OBJECT-TYPE
"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
@@ -527,8 +535,63 @@ bansPersistedFragmentation OBJECT-TYPE
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
--
@@ -585,8 +648,13 @@ varnishGroup OBJECT-GROUP
threadsCreated,
threadsDestroyed,
threadsFailed,
- threadsQueueLength
-
+ threadsQueueLength,
+ banTable,
+ varnishBanEntry,
+ banIndex,
+ banTime,
+ banRefCount,
+ banExpression
}
STATUS current
@@ -602,8 +670,7 @@ varnishStandardComplianceV1 MODULE-COMPLIANCE
"Compliance for an Varnish agent"
MODULE
- MANDATORY-GROUPS {
- varnishGroup}
+ MANDATORY-GROUPS { varnishGroup }
::= { varnishCompl 1 }
diff --git a/src/ban.c b/src/ban.c
index a091e37..a3941ab 100644
--- a/src/ban.c
+++ b/src/ban.c
@@ -16,6 +16,7 @@
*/
#include "varnish_mib.h"
+#include <ctype.h>
static int
send_ban_cmd(vcli_conn_t *conn, const char *expr)
@@ -50,13 +51,199 @@ varnish_ban(netsnmp_agent_request_info *reqinfo,
}
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
@@ -23,28 +23,6 @@
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;
@@ -141,10 +119,83 @@ $vars{'varnish_translate'} = sub {
$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.
@@ -273,6 +324,164 @@ handle_$i(netsnmp_mib_handler *handler,
}
@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)
@@ -295,6 +504,9 @@ init_$modulename(void)
@end@
));
@end@
+ @foreach $i table@
+ initialize_table_$i();
+ @end@
varnish_snmp_init();
}

Return to:

Send suggestions and report system problems to the System administrator.