Couldn't load match `pknock':(null)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi people,

I've just applied some patches to the pknock match module to work with
kernel > 2.6.28 and iptables 1.4.x.

What I get when I try to execute this module is:

# iptables -m pknock --help
iptables v1.4.3: Couldn't load match `pknock':(null)


Does anyone have any clue about this issue?

The updated code is below.

Thanks in advance,


--- /dev/null   2009-04-20 11:00:06.000000000 -0300
+++ libipt_pknock.c     2009-08-18 19:04:20.000000000 -0300
@@ -0,0 +1,351 @@
+/*
+ * Shared library add-on to iptables to add Port Knocking and SPA matching
+ * support.
+ *
+ * (C) 2006-2009 J. Federico Hernandez <fede.hernandez@xxxxxxxxx>
+ * (C) 2006 Luis Floreani <luis.floreani@xxxxxxxxx>
+ *
+ * $Id: libipt_pknock.c 462 2009-07-01 16:17:16Z fender $
+ *
+ * This program is released under the terms of GNU GPL version 2.
+ */
+#include <getopt.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <xtables.h>
+#include <linux/netfilter.h>
+#include <linux/netfilter_ipv4/ip_tables.h>
+//#include <linux/netfilter_ipv4/ipt_pknock.h>
+#include "../kernel/ipt_pknock.h"
+
+static const struct option pknock_opts[] = {
+       /* .name, .has_arg, .flag, .val */
+       { "knockports", 1,      0, 'k' },
+       { "t",                  1,      0, 't' },
+       { "time",               1,      0, 't' },
+       { "name",               1,      0, 'n' },
+       { "opensecret", 1,      0, 'a' },
+       { "closesecret",1,      0, 'z' },
+       { "strict",             0,      0, 'x' },
+       { "checkip",    0,      0, 'c' },
+       { "chkip",              0,      0, 'c' },
+       { .name = NULL }
+};
+
+/* Function which prints out usage message. */
+static void pknock_help(void)
+{
+       printf("pknock match options:\n"
+               " --knockports port[,port,port,...]     "
+                       "Matches destination port(s).\n"
+               " --time seconds\n"
+               " --t ...                               "
+                       "Time between port match.\n"
+               " --secure                              "
+                       "hmac must be in the packets.\n"
+               " --strict                              "
+                       "Knocks sequence must be exact.\n"
+               " --name rule_name                      "
+                       "Rule name.\n"
+               " --checkip                             "
+                       "Matches if the source ip is in the list.\n"
+               " --chkip\n");
+}
+
+static unsigned int
+parse_ports(const char *portstring, u_int16_t *ports, const char *proto)
+{
+       char *buffer, *cp, *next;
+       unsigned int i;
+
+       buffer = strdup(portstring);
+       if (!buffer) xtables_error(OTHER_PROBLEM, "strdup failed");
+
+       for (cp=buffer, i=0; cp && i<IPT_PKNOCK_MAX_PORTS; cp=next, i++)
+       {
+               next=strchr(cp, ',');
+               if (next) *next++='\0';
+               ports[i] = xtables_parse_port(cp, proto);
+       }
+
+       if (cp) xtables_error(PARAMETER_PROBLEM, "too many ports specified");
+
+       free(buffer);
+       return i;
+}
+
+static char *
+proto_to_name(u_int8_t proto)
+{
+       switch (proto) {
+       case IPPROTO_TCP:
+               return "tcp";
+       case IPPROTO_UDP:
+               return "udp";
+       default:
+               return NULL;
+       }
+}
+
+static const char *
+check_proto(u_int16_t pnum, u_int8_t invflags)
+{
+       char *proto;
+
+       if (invflags & XT_INV_PROTO)
+               xtables_error(PARAMETER_PROBLEM, PKNOCK "only works
with TCP and UDP.");
+
+       if ((proto = proto_to_name(pnum)) != NULL)
+               return proto;
+       else if (!pnum)
+               xtables_error(PARAMETER_PROBLEM, PKNOCK "needs `-p
tcp' or `-p udp'");
+       else
+               xtables_error(PARAMETER_PROBLEM, PKNOCK "only works
with TCP and UDP.");
+}
+
+/* Function which parses command options; returns true if it ate an option */
+static int
+__pknock_parse(int c, char **argv, int invert, unsigned int *flags,
+               struct xt_entry_match **match, u_int16_t pnum,
+               u_int16_t invflags)
+{
+       const char *proto;
+       struct ipt_pknock *info = (struct ipt_pknock *) (*match)->data;
+
+       switch (c) {
+       case 'k': /* --knockports */
+               if (*flags & IPT_PKNOCK_KNOCKPORT)
+                       xtables_error(PARAMETER_PROBLEM, PKNOCK
+                               "cannot use --knockports twice.\n");
+
+               xtables_check_inverse(argv[optind-1], &invert, &optind, 0);
+               proto = check_proto(pnum, invflags);
+
+               info->ports_count = parse_ports(optarg, info->port, proto);
+               info->option |= IPT_PKNOCK_KNOCKPORT;
+               *flags |= IPT_PKNOCK_KNOCKPORT;
+#if DEBUG
+               printf("ports_count: %d\n", info->ports_count);
+#endif
+               break;
+
+       case 't': /* --time */
+               if (*flags & IPT_PKNOCK_TIME)
+                       xtables_error(PARAMETER_PROBLEM, PKNOCK
+                               "cannot use --time twice.\n");
+
+               xtables_check_inverse(argv[optind-1], &invert, &optind, 0);
+
+               info->max_time = atoi(optarg);
+               info->option |= IPT_PKNOCK_TIME;
+               *flags |= IPT_PKNOCK_TIME;
+               break;
+
+       case 'n': /* --name */
+               if (*flags & IPT_PKNOCK_NAME)
+                       xtables_error(PARAMETER_PROBLEM, PKNOCK
+                               "cannot use --name twice.\n");
+
+               xtables_check_inverse(argv[optind-1], &invert, &optind, 0);
+
+               memset(info->rule_name, 0, IPT_PKNOCK_MAX_BUF_LEN + 1);
+               strncpy(info->rule_name, optarg, IPT_PKNOCK_MAX_BUF_LEN);
+
+               info->rule_name_len = strlen(info->rule_name);
+               info->option |= IPT_PKNOCK_NAME;
+               *flags |= IPT_PKNOCK_NAME;
+#if DEBUG
+               printf("info->rule_name: %s\n", info->rule_name);
+#endif
+               break;
+
+       case 'a': /* --opensecret */
+               if (*flags & IPT_PKNOCK_OPENSECRET)
+                       xtables_error(PARAMETER_PROBLEM, PKNOCK
+                               "cannot use --opensecret twice.\n");
+
+               xtables_check_inverse(argv[optind-1], &invert, &optind, 0);
+
+               memset(info->open_secret, 0, IPT_PKNOCK_MAX_PASSWD_LEN + 1);
+               strncpy(info->open_secret, optarg, IPT_PKNOCK_MAX_PASSWD_LEN);
+
+               info->open_secret_len = strlen(info->open_secret);
+               info->option |= IPT_PKNOCK_OPENSECRET;
+               *flags |= IPT_PKNOCK_OPENSECRET;
+               break;
+
+       case 'z': /* --closesecret */
+               if (*flags & IPT_PKNOCK_CLOSESECRET)
+                       xtables_error(PARAMETER_PROBLEM, PKNOCK
+                               "cannot use --closesecret twice.\n");
+
+               xtables_check_inverse(argv[optind-1], &invert, &optind, 0);
+
+               memset(info->close_secret, 0, IPT_PKNOCK_MAX_PASSWD_LEN + 1);
+               strncpy(info->close_secret, optarg, IPT_PKNOCK_MAX_PASSWD_LEN);
+
+               info->close_secret_len = strlen(info->close_secret);
+               info->option |= IPT_PKNOCK_CLOSESECRET;
+               *flags |= IPT_PKNOCK_CLOSESECRET;
+               break;
+
+       case 'c': /* --checkip */
+               if (*flags & IPT_PKNOCK_CHECKIP)
+                       xtables_error(PARAMETER_PROBLEM, PKNOCK
+                               "cannot use --checkip twice.\n");
+
+               xtables_check_inverse(argv[optind-1], &invert, &optind, 0);
+
+               info->option |= IPT_PKNOCK_CHECKIP;
+               *flags |= IPT_PKNOCK_CHECKIP;
+               break;
+
+       case 'x': /* --strict */
+               if (*flags & IPT_PKNOCK_STRICT)
+                       xtables_error(PARAMETER_PROBLEM, PKNOCK
+                               "cannot use --strict twice.\n");
+
+               xtables_check_inverse(argv[optind-1], &invert, &optind, 0);
+
+               info->option |= IPT_PKNOCK_STRICT;
+               *flags |= IPT_PKNOCK_STRICT;
+               break;
+
+       default:
+               return 0;
+       }
+
+       if (invert)
+               xtables_error(PARAMETER_PROBLEM, PKNOCK "does not
support invert.");
+
+       return 1;
+}
+
+static int pknock_parse(int c, char **argv, int invert, unsigned int *flags,
+                               const void *e, struct xt_entry_match **match)
+{
+       const struct ipt_entry *entry = e;
+       return __pknock_parse(c, argv, invert, flags, match,
+                       entry->ip.proto, entry->ip.invflags);
+}
+
+/* Final check. */
+static void pknock_check(unsigned int flags)
+{
+       if (!flags)
+               xtables_error(PARAMETER_PROBLEM, PKNOCK "expection an
option.\n");
+
+       if (!(flags & IPT_PKNOCK_NAME))
+               xtables_error(PARAMETER_PROBLEM, PKNOCK
+                       "--name option is required.\n");
+
+       if (flags & IPT_PKNOCK_KNOCKPORT) {
+               if (flags & IPT_PKNOCK_CHECKIP) {
+                       xtables_error(PARAMETER_PROBLEM, PKNOCK
+                               "cannot specify --knockports with
--checkip.\n");
+               }
+               if ((flags & IPT_PKNOCK_OPENSECRET)
+                       && !(flags & IPT_PKNOCK_CLOSESECRET))
+               {
+                       xtables_error(PARAMETER_PROBLEM, PKNOCK
+                               "--opensecret must go with --closesecret.\n");
+               }
+               if ((flags & IPT_PKNOCK_CLOSESECRET)
+                       && !(flags & IPT_PKNOCK_OPENSECRET))
+               {
+                       xtables_error(PARAMETER_PROBLEM, PKNOCK
+                               "--closesecret must go with --opensecret.\n");
+               }
+       }
+
+       if (flags & IPT_PKNOCK_CHECKIP) {
+               if (flags & IPT_PKNOCK_KNOCKPORT) {
+                       xtables_error(PARAMETER_PROBLEM, PKNOCK
+                               "cannot specify --checkip with
--knockports.\n");
+               }
+               if ((flags & IPT_PKNOCK_OPENSECRET)
+                       || (flags & IPT_PKNOCK_CLOSESECRET))
+               {
+                       xtables_error(PARAMETER_PROBLEM, PKNOCK
+                               "cannot specify --opensecret and"
+                               " --closesecret with --checkip.\n");
+               }
+               if (flags & IPT_PKNOCK_TIME) {
+                       xtables_error(PARAMETER_PROBLEM, PKNOCK
+                               "cannot specify --time with --checkip.\n");
+               }
+       }
+}
+
+/* Prints out the matchinfo. */
+static void pknock_print(const void *ip,
+                                               const struct
xt_entry_match *match, int numeric)
+{
+       const struct ipt_pknock *info;
+       int i;
+
+       info = (const struct ipt_pknock *)match->data;
+
+       printf("pknock ");
+       if (info->option & IPT_PKNOCK_KNOCKPORT) {
+               printf("knockports ");
+               for (i=0; i<info->ports_count; i++)
+                       printf("%s%d", i ? "," : "", info->port[i]);
+               printf(" ");
+       }
+       if (info->option & IPT_PKNOCK_TIME)
+               printf("time %ld ", info->max_time);
+       if (info->option & IPT_PKNOCK_NAME)
+               printf("name %s ", info->rule_name);
+       if (info->option & IPT_PKNOCK_OPENSECRET)
+               printf("opensecret ");
+       if (info->option & IPT_PKNOCK_CLOSESECRET)
+               printf("closesecret ");
+}
+
+/* Saves the union ipt_matchinfo in parsable form to stdout. */
+static void pknock_save(const void *ip, const struct xt_entry_match *match)
+{
+       int i;
+       const struct ipt_pknock *info = (const struct ipt_pknock *)match->data;
+
+       if (info->option & IPT_PKNOCK_KNOCKPORT) {
+               printf("--knockports ");
+               for (i=0; i<info->ports_count; i++)
+                       printf("%s%d", i ? "," : "", info->port[i]);
+               printf(" ");
+       }
+       if (info->option & IPT_PKNOCK_TIME)
+               printf("--time %ld ", info->max_time);
+       if (info->option & IPT_PKNOCK_NAME)
+               printf("--name %s ", info->rule_name);
+       if (info->option & IPT_PKNOCK_OPENSECRET)
+               printf("--opensecret ");
+       if (info->option & IPT_PKNOCK_CLOSESECRET)
+               printf("--closesecret ");
+       if (info->option & IPT_PKNOCK_STRICT)
+               printf("--strict ");
+       if (info->option & IPT_PKNOCK_CHECKIP)
+               printf("--checkip ");
+}
+
+static struct xtables_match pknock_match = {
+       .name                   = "pknock",
+       .version                = XTABLES_VERSION,
+       .family                 = NFPROTO_IPV4,
+       .size                   = XT_ALIGN(sizeof (struct ipt_pknock)),
+       .userspacesize  = XT_ALIGN(sizeof (struct ipt_pknock)),
+       .help                   = pknock_help,
+       .parse                  = pknock_parse,
+       .final_check    = pknock_check,
+       .print                  = pknock_print,
+       .save                   = pknock_save,
+       .extra_opts             = pknock_opts
+};
+
+void _init(void)
+{
+       xtables_register_match(&pknock_match);
+}


--- pknock-0.5/kernel/ipt_pknock.c      2008-08-24 22:53:32.000000000 -0300
+++ pknock-0.6/kernel/ipt_pknock.c      2009-08-18 18:33:09.000000000 -0300
@@ -1,10 +1,10 @@
 /*
  * Kernel module to implement Port Knocking and SPA matching support.
  *
- * (C) 2006-2008 J. Federico Hernandez
+ * (C) 2006-2009 J. Federico Hernandez
  * (C) 2006 Luis A. Floreani
  *
- * $Id$
+ * $Id: ipt_pknock.c 461 2009-07-01 14:55:11Z fender $
  *
  * This program is released under the terms of GNU GPL version 2.
  */
@@ -28,16 +28,13 @@
 #include <linux/connector.h>

 #include <linux/netfilter/x_tables.h>
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
-#include <net/net_namespace.h>
-#endif
-
+#include <linux/netfilter_ipv4/ip_tables.h>
+//#include <linux/netfilter_ipv4/ipt_pknock.h>
 #include "ipt_pknock.h"

+MODULE_LICENSE("GPL");
 MODULE_AUTHOR("J. Federico Hernandez Scarso, Luis A. Floreani");
 MODULE_DESCRIPTION("netfilter match for Port Knocking and SPA");
-MODULE_LICENSE("GPL");

 enum {
        GC_EXPIRATION_TIME      = 65000, /* in msecs */
@@ -50,7 +47,7 @@
                list_for_each_safe((pos), (n), (&head[(i)]))

 #if DEBUG
-       #define DEBUGP(msg, peer) printk(KERN_INFO MOD               \
+       #define DEBUGP(msg, peer) printk(KERN_INFO PKNOCK       \
                        "(S) peer: %u.%u.%u.%u - %s.\n",
                      \
                        NIPQUAD((peer)->ip), msg)
        #define duprintf(format, args...) printk(format, ## args);
@@ -120,8 +117,8 @@
        unsigned int i;

        if ((hash = kmalloc(sizeof(*hash) * size, GFP_ATOMIC)) == NULL) {
-               printk(KERN_ERR MOD "kmalloc() error in alloc_hashtable() "
-                        "function.\n");
+               printk(KERN_ERR PKNOCK
+                                               "kmalloc() error in
alloc_hashtable() function.\n");
                return NULL;
        }

@@ -144,8 +141,8 @@
                case ST_INIT:     return "INIT";
                case ST_MATCHING: return "MATCHING";
                case ST_ALLOWED:  return "ALLOWED";
+               default:                        return "UNKNOWN";
        }
-       return "UNKNOWN";
 }

 /**
@@ -274,8 +271,7 @@
        if (timer_pending(&rule->timer))
                del_timer(&rule->timer);

-       rule->timer.expires = jiffies +
-                                msecs_to_jiffies(ipt_pknock_gc_expir_time);
+       rule->timer.expires = jiffies +
msecs_to_jiffies(ipt_pknock_gc_expir_time);
        add_timer(&rule->timer);
 }

@@ -315,8 +311,9 @@

        hashtable_for_each_safe(pos, n, rule->peer_head, peer_hashsize, i) {
                peer = list_entry(pos, struct peer, head);
-               if (!has_logged_during_this_minute(peer)
-                        && is_time_exceeded(peer, rule->max_time))
+
+               if (!has_logged_during_this_minute(peer) &&
+                                               is_time_exceeded(peer,
rule->max_time))
                {
                         DEBUGP("DESTROYED", peer);
                        list_del(pos);
@@ -333,7 +330,7 @@
  * @return: 0 equals, 1 otherwise
  */
 static inline int
-rulecmp(const struct ipt_pknock_info *info, const struct ipt_pknock_rule *rule)
+rulecmp(const struct ipt_pknock *info, const struct ipt_pknock_rule *rule)
 {
        if (info->rule_name_len != rule->rule_name_len)
                return 1;
@@ -349,7 +346,7 @@
  * @return: rule or NULL
  */
 static inline struct ipt_pknock_rule *
-search_rule(const struct ipt_pknock_info *info)
+search_rule(const struct ipt_pknock *info)
 {
        struct ipt_pknock_rule *rule = NULL;
        struct list_head *pos = NULL, *n = NULL;
@@ -371,7 +368,7 @@
  * @return: 1 success, 0 failure
  */
 static bool
-add_rule(struct ipt_pknock_info *info)
+add_rule(struct ipt_pknock *info)
 {
        struct ipt_pknock_rule *rule = NULL;
        struct list_head *pos = NULL, *n = NULL;
@@ -385,7 +382,7 @@
                        rule->ref_count++;
 #if DEBUG
                        if (info->option & IPT_PKNOCK_CHECKIP) {
-                               printk(KERN_DEBUG MOD "add_rule() (AC)"
+                               printk(KERN_DEBUG PKNOCK "add_rule() (AC)"
                                        " rule found: %s - "
                                        "ref_count: %d\n",
                                        rule->rule_name,
@@ -397,7 +394,7 @@
        }

        if ((rule = kmalloc(sizeof (*rule), GFP_ATOMIC)) == NULL) {
-               printk(KERN_ERR MOD "kmalloc() error in add_rule().\n");
+               printk(KERN_ERR PKNOCK "kmalloc() error in add_rule().\n");
                return false;
        }

@@ -411,7 +408,7 @@
        rule->max_time  = info->max_time;

        if (!(rule->peer_head = alloc_hashtable(peer_hashsize))) {
-               printk(KERN_ERR MOD "alloc_hashtable() error in add_rule().\n");
+               printk(KERN_ERR PKNOCK "alloc_hashtable() error in
add_rule().\n");
                return false;
        }

@@ -421,7 +418,7 @@

        rule->status_proc = create_proc_entry(info->rule_name, 0, pde);
        if (!rule->status_proc) {
-               printk(KERN_ERR MOD "create_proc_entry() error in add_rule()"
+               printk(KERN_ERR PKNOCK "create_proc_entry() error in add_rule()"
                         " function.\n");
                 kfree(rule);
                 return false;
@@ -432,7 +429,7 @@

        list_add(&rule->head, &rule_hashtable[hash]);
 #if DEBUG
-       printk(KERN_INFO MOD "(A) rule_name: %s - created.\n", rule->rule_name);
+       printk(KERN_INFO PKNOCK "(A) rule_name: %s - created.\n",
rule->rule_name);
 #endif
        return true;
 }
@@ -443,7 +440,7 @@
  * @info
  */
 static void
-remove_rule(struct ipt_pknock_info *info)
+remove_rule(struct ipt_pknock *info)
 {
        struct ipt_pknock_rule *rule = NULL;
        struct list_head *pos = NULL, *n = NULL;
@@ -470,27 +467,25 @@
        }
 #if DEBUG
        if (!found) {
-               printk(KERN_INFO MOD "(N) rule not found: %s.\n",
-                        info->rule_name);
+               printk(KERN_INFO PKNOCK "(N) rule not found: %s.\n",
info->rule_name);
                return;
        }
 #endif
        if (rule && rule->ref_count == 0) {
-               hashtable_for_each_safe(pos, n, rule->peer_head,
-                        peer_hashsize, i) {
-
+               hashtable_for_each_safe(pos, n, rule->peer_head,
peer_hashsize, i) {
                         peer = list_entry(pos, struct peer, head);
+
                        if (peer != NULL) {
                                DEBUGP("DELETED", peer);
                                list_del(pos);
                                kfree(peer);
                        }
                }
+
                if (rule->status_proc)
                         remove_proc_entry(info->rule_name, pde);
 #if DEBUG
-               printk(KERN_INFO MOD "(D) rule deleted: %s.\n",
-                        rule->rule_name);
+               printk(KERN_INFO PKNOCK "(D) rule deleted: %s.\n",
rule->rule_name);
 #endif
                if (timer_pending(&rule->timer))
                        del_timer(&rule->timer);
@@ -552,7 +547,7 @@
        struct peer *peer = NULL;

        if ((peer = kmalloc(sizeof (*peer), GFP_ATOMIC)) == NULL) {
-               printk(KERN_ERR MOD "kmalloc() error in new_peer().\n");
+               printk(KERN_ERR PKNOCK "kmalloc() error in new_peer().\n");
                return NULL;
        }

@@ -599,7 +594,7 @@
  * @return: 1 success, 0 failure
  */
 static inline bool
-is_first_knock(const struct peer *peer, const struct ipt_pknock_info *info,
+is_first_knock(const struct peer *peer, const struct ipt_pknock *info,
                 u_int16_t port)
 {
        return (peer == NULL && info->port[0] == port) ? 1 : 0;
@@ -612,7 +607,7 @@
  * @return: 1 success, 0 failure
  */
 static inline bool
-is_wrong_knock(const struct peer *peer, const struct ipt_pknock_info *info,
+is_wrong_knock(const struct peer *peer, const struct ipt_pknock *info,
                u_int16_t port)
 {
        return peer && (info->port[peer->id_port_knocked-1] != port);
@@ -624,9 +619,9 @@
  * @return: 1 success, 0 failure
  */
 static inline bool
-is_last_knock(const struct peer *peer, const struct ipt_pknock_info *info)
+is_last_knock(const struct peer *peer, const struct ipt_pknock *info)
 {
-       return peer && (peer->id_port_knocked-1 == info->count_ports);
+       return peer && (peer->id_port_knocked-1 == info->ports_count);
 }

 /**
@@ -647,7 +642,7 @@
  * @return: 1 success, 0 otherwise
  */
 static bool
-msg_to_userspace_nl(const struct ipt_pknock_info *info,
+msg_to_userspace_nl(const struct ipt_pknock *info,
                 const struct peer *peer, int multicast_group)
 {
        struct cn_msg *m;
@@ -655,7 +650,7 @@

        m = kmalloc(sizeof(*m) + sizeof(msg), GFP_ATOMIC);
        if (!m) {
-               printk(KERN_ERR MOD "kmalloc() error in "
+               printk(KERN_ERR PKNOCK "kmalloc() error in "
                         "msg_to_userspace_nl().\n");
                return false;
        }
@@ -672,7 +667,6 @@
        cn_netlink_send(m, multicast_group, GFP_ATOMIC);

        kfree(m);
-
        return true;
 }

@@ -731,7 +725,7 @@

        hexresult = kmalloc(sizeof(char) * hexa_size, GFP_ATOMIC);
        if (hexresult == NULL) {
-               printk(KERN_ERR MOD "kmalloc() error in has_secret().\n");
+               printk(KERN_ERR PKNOCK "kmalloc() error in has_secret().\n");
                return 0;
        }

@@ -764,7 +758,7 @@

        if (memcmp(hexresult, payload, hexa_size) != 0) {
 #if DEBUG
-               printk(KERN_INFO MOD "secret match failed\n");
+               printk(KERN_INFO PKNOCK "secret match failed\n");
 #endif
                goto out;
        }
@@ -777,7 +771,7 @@
 }

 /**
- * If the peer pass the security policy
+ * If the peer pass the security policy.
  *
  * @peer
  * @info
@@ -786,7 +780,7 @@
  * @return: 1 if pass security, 0 otherwise
  */
 static bool
-pass_security(struct peer *peer, const struct ipt_pknock_info *info,
+pass_security(struct peer *peer, const struct ipt_pknock *info,
         unsigned char *payload, int payload_len)
 {
        if (is_allowed(peer))
@@ -817,7 +811,7 @@
  * @return: 1 if allowed, 0 otherwise
  */
 static bool
-update_peer(struct peer *peer, const struct ipt_pknock_info *info,
+update_peer(struct peer *peer, const struct ipt_pknock *info,
                struct ipt_pknock_rule *rule,
                const struct transport_data *hdr)
 {
@@ -837,9 +831,7 @@
                if (hdr->proto != IPPROTO_UDP)
                        return false;

-               if (!pass_security(peer, info, hdr->payload,
-                        hdr->payload_len))
-               {
+               if (!pass_security(peer, info, hdr->payload,
hdr->payload_len)) {
                         return false;
                }
        }
@@ -869,7 +861,7 @@
 #if DEBUG
                        DEBUGP("TIME EXCEEDED", peer);
                        DEBUGP("DESTROYED", peer);
-                       printk(KERN_INFO MOD "max_time: %ld - time: %ld\n",
+                       printk(KERN_INFO PKNOCK "max_time: %ld - time: %ld\n",
                                        peer->timestamp + info->max_time,
                                        time);
 #endif
@@ -894,7 +886,7 @@
  * @return: 1 if close knock, 0 otherwise
  */
 static inline bool
-is_close_knock(const struct peer *peer, const struct ipt_pknock_info *info,
+is_close_knock(const struct peer *peer, const struct ipt_pknock *info,
                unsigned char *payload, int payload_len)
 {
        /* Check for CLOSE secret. */
@@ -914,6 +906,9 @@
 static int
 #endif
 match(const struct sk_buff *skb,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
+       const struct xt_match_param *par
+#else
        const struct net_device *in,
        const struct net_device *out,
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17)
@@ -924,9 +919,15 @@
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
         unsigned int protoff,
 #endif
-       bool *hotdrop)
+       bool *hotdrop
+#endif
+)
 {
-       const struct ipt_pknock_info *info = matchinfo;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
+       const struct ipt_pknock *info = par->matchinfo;
+#else
+       const struct ipt_pknock *info = matchinfo;
+#endif
        struct ipt_pknock_rule *rule = NULL;
        struct peer *peer = NULL;
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
@@ -943,7 +944,11 @@
        int ret = 0;
 #endif

+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
+       pptr = skb_header_pointer(skb, par->thoff, sizeof _ports, &_ports);
+#else
        pptr = skb_header_pointer(skb, protoff, sizeof _ports, &_ports);
+#endif

        if (pptr == NULL) {
                /* We've been asked to examine this packet, and we
@@ -951,7 +956,11 @@
                 */
                duprintf("Dropping evil offset=0 tinygram.\n");
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
+               *par->hotdrop = true;
+#else
                *hotdrop = true;
+#endif
                return false;
 #else
                *hotdrop = 1;
@@ -970,8 +979,8 @@
                        break;

                default:
-                       printk(KERN_INFO MOD "IP payload protocol "
-                                       "is neither tcp nor udp.\n");
+               printk(KERN_INFO PKNOCK
+                                               "IP payload protocol
is neither tcp nor udp.\n");
                        return false;
        }

@@ -979,7 +988,7 @@

        /* Searches a rule from the list depending on info structure options. */
        if ((rule = search_rule(info)) == NULL) {
-               printk(KERN_INFO MOD "The rule %s doesn't exist.\n",
+               printk(KERN_INFO PKNOCK "The rule %s doesn't exist.\n",
                                info->rule_name);
                goto out;
        }
@@ -1000,11 +1009,10 @@
        /* Sets, updates, removes or checks the peer matching status. */
        if (info->option & IPT_PKNOCK_KNOCKPORT) {
                if ((ret = is_allowed(peer))) {
-                       if (info->option & IPT_PKNOCK_CLOSESECRET
-                                && iph->protocol == IPPROTO_UDP)
+                       if (info->option & IPT_PKNOCK_CLOSESECRET &&
+                                                       iph->protocol
== IPPROTO_UDP)
                        {
-                                if (is_close_knock(peer, info, hdr.payload,
-                                        hdr.payload_len))
+                               if (is_close_knock(peer, info,
hdr.payload, hdr.payload_len))
                                {
                                         reset_knock_status(peer);
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
@@ -1036,9 +1044,9 @@
 }

 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
-#define RETURN_ERR(err) do { printk(KERN_ERR MOD err); return false;
} while (0)
+#define RETURN_ERR(err) do { printk(KERN_ERR PKNOCK err); return
false; } while (0)
 #else
-#define RETURN_ERR(err) do { printk(KERN_ERR MOD err); return 0; } while (0)
+#define RETURN_ERR(err) do { printk(KERN_ERR PKNOCK err); return 0; } while (0)
 #endif

 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
@@ -1046,7 +1054,11 @@
 #else
 static int
 #endif
-checkentry(const char *tablename,
+checkentry(
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
+       const struct xt_mtchk_param *par
+#else
+       const char *tablename,
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
        const void *ip,
 #else
@@ -1059,17 +1071,22 @@
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)
        unsigned int matchsize,
 #endif
-       unsigned int hook_mask)
+       unsigned int hook_mask
+#endif
+)
 {
-       struct ipt_pknock_info *info = matchinfo;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
+       struct ipt_pknock *info = par->matchinfo;
+#else
+       struct ipt_pknock *info = matchinfo;
+#endif

        /* Singleton. */
        if (!rule_hashtable) {
                if (!(rule_hashtable = alloc_hashtable(rule_hashsize)))
                        RETURN_ERR("alloc_hashtable() error in checkentry()\n");

-               get_random_bytes(&ipt_pknock_hash_rnd,
-                                sizeof (ipt_pknock_hash_rnd));
+               get_random_bytes(&ipt_pknock_hash_rnd, sizeof
(ipt_pknock_hash_rnd));
        }

        if (!add_rule(info))
@@ -1078,39 +1095,35 @@
        if (!(info->option & IPT_PKNOCK_NAME))
                RETURN_ERR("You must specify --name option.\n");

-       if ((info->option & IPT_PKNOCK_OPENSECRET) && (info->count_ports != 1))
+       if ((info->option & IPT_PKNOCK_OPENSECRET) && (info->ports_count != 1))
                RETURN_ERR("--opensecret must have just one knock port\n");

        if (info->option & IPT_PKNOCK_KNOCKPORT) {
                if (info->option & IPT_PKNOCK_CHECKIP) {
-                       RETURN_ERR("Can't specify --knockports with "
-                                       "--checkip.\n");
+                       RETURN_ERR("Can't specify --knockports with
--checkip.\n");
                }
                if ((info->option & IPT_PKNOCK_OPENSECRET) &&
                                !(info->option & IPT_PKNOCK_CLOSESECRET))
                {
-                       RETURN_ERR("--opensecret must go with "
-                                       "--closesecret.\n");
+                       RETURN_ERR("--opensecret must go with
--closesecret.\n");
                }
                if ((info->option & IPT_PKNOCK_CLOSESECRET) &&
                                !(info->option & IPT_PKNOCK_OPENSECRET))
                {
-                       RETURN_ERR("--closesecret must go with "
-                                       "--opensecret.\n");
+                       RETURN_ERR("--closesecret must go with
--opensecret.\n");
                }
        }

        if (info->option & IPT_PKNOCK_CHECKIP) {
                if (info->option & IPT_PKNOCK_KNOCKPORT)
                {
-                       RETURN_ERR("Can't specify --checkip with "
-                                       "--knockports.\n");
+                       RETURN_ERR("Can't specify --checkip with
--knockports.\n");
                }
                if ((info->option & IPT_PKNOCK_OPENSECRET) ||
                                (info->option & IPT_PKNOCK_CLOSESECRET))
                {
-                       RETURN_ERR("Can't specify --opensecret and "
-                                       "--closesecret with --checkip.\n");
+                       RETURN_ERR("Can't specify --opensecret and
--closesecret"
+                                                       " with --checkip.\n");
                }
                if (info->option & IPT_PKNOCK_TIME)
                        RETURN_ERR("Can't specify --time with --checkip.\n");
@@ -1121,8 +1134,7 @@
                        if (memcmp(info->open_secret, info->close_secret,
                                                info->open_secret_len) == 0)
                        {
-                               RETURN_ERR("opensecret & closesecret cannot "
-                                               "be equal.\n");
+                               RETURN_ERR("opensecret & closesecret
cannot be equal.\n");
                        }
                }
        }
@@ -1136,24 +1148,34 @@

 static void
 destroy(
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
+       const struct xt_mtdtor_param *par
+#else
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17)
-               const struct xt_match *match, void *matchinfo)
+       const struct xt_match *match, void *matchinfo
 #else
-               void *matchinfo, unsigned int matchsize)
+       void *matchinfo, unsigned int matchsize
 #endif
+#endif
+)
 {
-       struct ipt_pknock_info *info = matchinfo;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
+       struct ipt_pknock *info = par->matchinfo;
+#else
+       struct ipt_pknock *info = matchinfo;
+#endif
        /* Removes a rule only if it exits and ref_count is equal to 0. */
        remove_rule(info);
 }

 static struct xt_match ipt_pknock_match __read_mostly = {
        .name           = "pknock",
+       .revision       = 0,
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)
-       .family         = AF_INET,
+       .family         = NFPROTO_IPV4,
 #endif
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17)
-        .matchsize      = sizeof (struct ipt_pknock_info),
+       .matchsize      = sizeof (struct ipt_pknock),
 #endif
        .match          = match,
        .checkentry     = checkentry,
@@ -1163,10 +1185,10 @@

 static int __init ipt_pknock_init(void)
 {
-       printk(KERN_INFO MOD "register.\n");
+       printk(KERN_INFO PKNOCK "register.\n");

        if (request_module(crypto.algo) < 0) {
-               printk(KERN_ERR MOD "request_module('%s') error.\n",
+               printk(KERN_ERR PKNOCK "request_module('%s') error.\n",
                         crypto.algo);
                return -1;
        }
@@ -1174,7 +1196,7 @@
        crypto.tfm = crypto_alloc_hash(crypto.algo, 0, CRYPTO_ALG_ASYNC);

        if (crypto.tfm == NULL) {
-               printk(KERN_ERR MOD "failed to load transform for %s\n",
+               printk(KERN_ERR PKNOCK "failed to load transform for %s\n",
                         crypto.algo);
                return -1;
        }
@@ -1188,7 +1210,7 @@
 #else
        if (!(pde = proc_mkdir("ipt_pknock", proc_net))) {
 #endif
-               printk(KERN_ERR MOD "proc_mkdir() error in _init().\n");
+               printk(KERN_ERR PKNOCK "proc_mkdir() error in _init().\n");
                return -1;
        }
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)
@@ -1200,7 +1222,7 @@

 static void __exit ipt_pknock_fini(void)
 {
-       printk(KERN_INFO MOD "unregister.\n");
+       printk(KERN_INFO PKNOCK "unregister.\n");
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
        remove_proc_entry("ipt_pknock", init_net.proc_net);
 #else


--- pknock-0.5/kernel/ipt_pknock.h      2008-08-15 02:28:25.000000000 -0300
+++ pknock-0.6/kernel/ipt_pknock.h      2009-07-01 11:55:58.000000000 -0300
@@ -4,14 +4,14 @@
  * (C) 2006-2008 J. Federico Hernandez <fede.hernandez@xxxxxxxxx>
  * (C) 2006 Luis Floreani <luis.floreani@xxxxxxxxx>
  *
- * $Id$
+ * $Id: ipt_pknock.h 461 2009-07-01 14:55:11Z fender $
  *
  * This program is released under the terms of GNU GPL version 2.
  */
 #ifndef _IPT_PKNOCK_H
 #define _IPT_PKNOCK_H

-#define MOD "ipt_pknock: "
+#define PKNOCK "ipt_pknock: "

 #define IPT_PKNOCK_KNOCKPORT           0x01
 #define IPT_PKNOCK_TIME                        0x02
@@ -27,14 +27,14 @@

 #define DEBUG 1

-struct ipt_pknock_info {
+struct ipt_pknock {
        char            rule_name[IPT_PKNOCK_MAX_BUF_LEN + 1];
        int             rule_name_len;
        char            open_secret[IPT_PKNOCK_MAX_PASSWD_LEN + 1];
        int             open_secret_len;
        char            close_secret[IPT_PKNOCK_MAX_PASSWD_LEN + 1];
        int             close_secret_len;
-       u_int8_t        count_ports;    /* number of ports */
+       u_int8_t        ports_count;    /* number of ports */
        u_int16_t       port[IPT_PKNOCK_MAX_PORTS]; /* port[,port,port,...] */
        unsigned long   max_time;       /* max matching time between ports */
        u_int8_t        option;         /* --time, --knock-port, ... */




-- 
Federico

/*
 *  J. Federico Hernandez (fender) {frozenspot; at; gmail; dot; com;}
 *  GPG PubKey: wwwkeys.eu.pgp.net key 6AE78BF2
 *  FP: 26AB 7A1B C2C4 70F8 0E7D  C3F4 9736 5CE2 6AE7 8BF2
 */
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Netfitler Users]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux