@@ -0,0 +1,401 @@
+
+/*
+ * Copyright (c) 2008 Peter Poeml <poeml@suse.de> / Novell Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *
+ *
+ * mod_asn
+ *
+ * look up the autonomous system, and network prefix, that a client's IP
+ * address is belonging to
+ *
+ */
+
+#include "ap_config.h"
+#include "httpd.h"
+#include "http_request.h"
+#include "http_config.h"
+#include "http_core.h"
+#include "http_log.h"
+#include "http_main.h"
+#include "http_protocol.h"
+
+#include "apr_strings.h"
+#include "apr_lib.h"
+#include "apr_dbd.h"
+#include "mod_dbd.h"
+
+
+#ifndef UNSET
+#define UNSET (-1)
+#endif
+
+#define MOD_ASN_VER "1.0"
+#define VERSION_COMPONENT "mod_asn/"MOD_ASN_VER
+
+/* from ssl/ssl_engine_config.c */
+#define cfgMerge(el,unset) mrg->el = (add->el == (unset)) ? base->el : add->el
+#define cfgMergeArray(el) mrg->el = apr_array_append(p, add->el, base->el)
+#define cfgMergeString(el) cfgMerge(el, NULL)
+#define cfgMergeBool(el) cfgMerge(el, UNSET)
+#define cfgMergeInt(el) cfgMerge(el, UNSET)
+
+#define DEFAULT_QUERY "SELECT pfx, asn FROM pfx2asn WHERE pfx >>= ip4r(%s) ORDER BY ip4r_size(pfx) LIMIT 1"
+
+module AP_MODULE_DECLARE_DATA asn_module;
+
+
+/* per-dir configuration */
+typedef struct
+{
+ int asn_enabled;
+ int set_headers;
+ int debug;
+} asn_dir_conf;
+
+/* per-server configuration */
+typedef struct
+{
+ const char *query;
+ const char *query_prep;
+ const char *ip_header;
+ const char *ip_envvar;
+} asn_server_conf;
+
+
+
+/* optional function - look it up once in post_config */
+static ap_dbd_t *(*asn_dbd_acquire_fn)(request_rec*) = NULL;
+static void (*asn_dbd_prepare_fn)(server_rec*, const char*, const char*) = NULL;
+
+
+static void debugLog(const request_rec *r, const asn_dir_conf *cfg,
+ const char *fmt, ...)
+{
+ if (cfg->debug == 1) {
+ char buf[512];
+ va_list ap;
+ va_start(ap, fmt);
+ apr_vsnprintf(buf, sizeof (buf), fmt, ap);
+ va_end(ap);
+ /* we use warn loglevel to be able to debug without
+ * setting the entire server into debug logging mode */
+ ap_log_rerror(APLOG_MARK,
+ APLOG_WARNING,
+ APR_SUCCESS,
+ r, "[mod_asn] %s", buf);
+ }
+}
+
+
+static int asn_post_config(apr_pool_t *pconf, apr_pool_t *plog,
+ apr_pool_t *ptemp, server_rec *s)
+{
+ ap_add_version_component(pconf, VERSION_COMPONENT);
+
+ /* make sure that mod_dbd is loaded */
+ if (asn_dbd_prepare_fn == NULL) {
+ asn_dbd_prepare_fn = APR_RETRIEVE_OPTIONAL_FN(ap_dbd_prepare);
+ if (asn_dbd_prepare_fn == NULL) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ "[mod_asn] You must load mod_dbd to enable mod_asn functions");
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+ asn_dbd_acquire_fn = APR_RETRIEVE_OPTIONAL_FN(ap_dbd_acquire);
+ }
+
+ /* prepare DBD SQL statements */
+ static unsigned int label_num = 0;
+ server_rec *sp;
+ for (sp = s; sp; sp = sp->next) {
+ asn_server_conf *cfg = ap_get_module_config(sp->module_config,
+ &asn_module);
+ /* make a label */
+ cfg->query_prep = apr_psprintf(pconf, "asn_dbd_%d", ++label_num);
+ asn_dbd_prepare_fn(sp, cfg->query, cfg->query_prep);
+ }
+
+ return OK;
+}
+
+static void *create_asn_dir_config(apr_pool_t *p, char *dirspec)
+{
+ asn_dir_conf *new =
+ (asn_dir_conf *) apr_pcalloc(p, sizeof(asn_dir_conf));
+
+ new->asn_enabled = UNSET;
+ new->set_headers = UNSET;
+ new->debug = UNSET;
+ return (void *) new;
+}
+
+static void *merge_asn_dir_config(apr_pool_t *p, void *basev, void *addv)
+{
+ asn_dir_conf *mrg = (asn_dir_conf *) apr_pcalloc(p, sizeof(asn_dir_conf));
+ asn_dir_conf *base = (asn_dir_conf *) basev;
+ asn_dir_conf *add = (asn_dir_conf *) addv;
+
+ cfgMergeInt(asn_enabled);
+ cfgMergeInt(set_headers);
+ cfgMergeInt(debug);
+ return (void *) mrg;
+}
+
+static void *create_asn_server_config(apr_pool_t *p, server_rec *s)
+{
+ asn_server_conf *new =
+ (asn_server_conf *) apr_pcalloc(p, sizeof(asn_server_conf));
+
+ new->query = DEFAULT_QUERY;
+ new->query_prep = NULL;
+ new->ip_header = NULL;
+ new->ip_envvar = NULL;
+ return (void *) new;
+}
+
+static void *merge_asn_server_config(apr_pool_t *p, void *basev, void *addv)
+{
+ asn_server_conf *base = (asn_server_conf *) basev;
+ asn_server_conf *add = (asn_server_conf *) addv;
+ asn_server_conf *mrg = apr_pcalloc(p, sizeof(asn_server_conf));
+
+ mrg->query = (add->query != (char *) DEFAULT_QUERY) ? add->query : base->query;
+ cfgMergeString(query_prep);
+ cfgMergeString(ip_header);
+ cfgMergeString(ip_envvar);
+ return (void *) mrg;
+}
+
+static const char *asn_cmd_asn(cmd_parms *cmd, void *config, int flag)
+{
+ asn_dir_conf *cfg = (asn_dir_conf *) config;
+ cfg->asn_enabled = flag;
+ return NULL;
+}
+
+static const char *asn_cmd_debug(cmd_parms *cmd, void *config, int flag)
+{
+ asn_dir_conf *cfg = (asn_dir_conf *) config;
+ cfg->debug = flag;
+ return NULL;
+}
+
+static const char *asn_cmd_setheaders(cmd_parms *cmd, void *config, int flag)
+{
+ asn_dir_conf *cfg = (asn_dir_conf *) config;
+ cfg->set_headers = flag;
|