From 1f1c42b58223ada541adf4f523d1b6ca5e05483a Mon Sep 17 00:00:00 2001 From: kaber Date: Sun, 18 Apr 2004 17:33:26 +0000 Subject: Add connrate match userspace part (Nuuti Kotivuori) --- extensions/.connrate-test | 2 + extensions/libipt_connrate.c | 189 +++++++++++++++++++++++++++++++++++++++++ extensions/libipt_connrate.man | 6 ++ 3 files changed, 197 insertions(+) create mode 100755 extensions/.connrate-test create mode 100644 extensions/libipt_connrate.c create mode 100644 extensions/libipt_connrate.man (limited to 'extensions') diff --git a/extensions/.connrate-test b/extensions/.connrate-test new file mode 100755 index 0000000..d110c15 --- /dev/null +++ b/extensions/.connrate-test @@ -0,0 +1,2 @@ +#! /bin/sh +[ -f $KERNEL_DIR/include/linux/netfilter_ipv4/ipt_connrate.h ] && echo connrate diff --git a/extensions/libipt_connrate.c b/extensions/libipt_connrate.c new file mode 100644 index 0000000..a952cb7 --- /dev/null +++ b/extensions/libipt_connrate.c @@ -0,0 +1,189 @@ +/* Shared library add-on to iptables to add connection rate tracking + * support. + * + * Copyright (c) 2004 Nuutti Kotivuori + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + **/ +#include +#include +#include +#include +#include +#include +#include +#include + +/* Function which prints out usage message. */ +static void +help(void) +{ + printf( +"connrate v%s options:\n" +" --connrate [!] [from]:[to]\n" +" Match connection transfer rate in bytes\n" +" per second. `inf' can be used for maximum\n" +" expressible value.\n" +"\n", IPTABLES_VERSION); +} + +static struct option opts[] = { + { "connrate", 1, 0, '1' }, + {0} +}; + +/* Initialize the match. */ +static void +init(struct ipt_entry_match *m, unsigned int *nfcache) +{ + /* caching not yet implemented */ + *nfcache |= NFC_UNKNOWN; +} + +static u_int32_t +parse_value(const char *arg, u_int32_t def) +{ + char *end; + size_t len; + u_int32_t value; + + len = strlen(arg); + if(len == 0) + return def; + if(strcmp(arg, "inf") == 0) + return 0xFFFFFFFF; + value = strtoul(arg, &end, 0); + if(*end != '\0') + exit_error(PARAMETER_PROBLEM, + "Bad value in range `%s'", arg); + return value; +} + +static void +parse_range(const char *arg, struct ipt_connrate_info *si) +{ + char *buffer; + char *colon; + + buffer = strdup(arg); + if ((colon = strchr(buffer, ':')) == NULL) + exit_error(PARAMETER_PROBLEM, "Bad range `%s'", arg); + *colon = '\0'; + si->from = parse_value(buffer, 0); + si->to = parse_value(colon+1, 0xFFFFFFFF); + if (si->from > si->to) + exit_error(PARAMETER_PROBLEM, "%u should be less than %u", si->from,si->to); + free(buffer); +} + +#define CONNRATE_OPT 0x01 + +/* Function which parses command options; returns true if it + ate an option */ +static int +parse(int c, char **argv, int invert, unsigned int *flags, + const struct ipt_entry *entry, + unsigned int *nfcache, + struct ipt_entry_match **match) +{ + struct ipt_connrate_info *sinfo = (struct ipt_connrate_info *)(*match)->data; + u_int32_t tmp; + + switch (c) { + case '1': + if (*flags & CONNRATE_OPT) + exit_error(PARAMETER_PROBLEM, + "Only one `--connrate' allowed"); + check_inverse(optarg, &invert, &optind, 0); + parse_range(argv[optind-1], sinfo); + if (invert) { + tmp = sinfo->from; + sinfo->from = sinfo->to; + sinfo->to = tmp; + } + *flags |= CONNRATE_OPT; + break; + + default: + return 0; + } + + return 1; +} + +static void final_check(unsigned int flags) +{ + if (!(flags & CONNRATE_OPT)) + exit_error(PARAMETER_PROBLEM, + "connrate match: You must specify `--connrate'"); +} + +static void +print_value(u_int32_t value) +{ + if(value == 0xFFFFFFFF) + printf("inf"); + else + printf("%u", value); +} + +static void +print_range(struct ipt_connrate_info *sinfo) +{ + if (sinfo->from > sinfo->to) { + printf("! "); + print_value(sinfo->to); + printf(":"); + print_value(sinfo->from); + } else { + print_value(sinfo->from); + printf(":"); + print_value(sinfo->to); + } +} + +/* Prints out the matchinfo. */ +static void +print(const struct ipt_ip *ip, + const struct ipt_entry_match *match, + int numeric) +{ + struct ipt_connrate_info *sinfo = (struct ipt_connrate_info *)match->data; + + printf("connrate "); + print_range(sinfo); + printf(" "); +} + +/* Saves the matchinfo in parsable form to stdout. */ +static void save(const struct ipt_ip *ip, const struct ipt_entry_match *match) +{ + struct ipt_connrate_info *sinfo = (struct ipt_connrate_info *)match->data; + + printf("--connrate "); + print_range(sinfo); + printf(" "); +} + +static +struct iptables_match state += { NULL, + "connrate", + IPTABLES_VERSION, + IPT_ALIGN(sizeof(struct ipt_connrate_info)), + IPT_ALIGN(sizeof(struct ipt_connrate_info)), + &help, + &init, + &parse, + &final_check, + &print, + &save, + opts +}; + +void _init(void) +{ + register_match(&state); +} diff --git a/extensions/libipt_connrate.man b/extensions/libipt_connrate.man new file mode 100644 index 0000000..45cba9d --- /dev/null +++ b/extensions/libipt_connrate.man @@ -0,0 +1,6 @@ +This module matches the current transfer rate in a connection. +.TP +.BI "--connrate " "[!] [\fIfrom\fP]:[\fIto\fP]" +Match against the current connection transfer rate being within 'from' +and 'to' bytes per second. When the "!" argument is used before the +range, the sense of the match is inverted. -- cgit v1.2.3