aboutsummaryrefslogtreecommitdiff
path: root/src/ban.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ban.c')
-rw-r--r--src/ban.c191
1 files changed, 189 insertions, 2 deletions
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);
+ }
+}

Return to:

Send suggestions and report system problems to the System administrator.