* [1/1] OSF: pom-ng - linux-2.6.
@ 2004-12-08 10:58 Evgeniy Polyakov
2004-12-08 11:02 ` Evgeniy Polyakov
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Evgeniy Polyakov @ 2004-12-08 10:58 UTC (permalink / raw)
To: netfilter-devel; +Cc: Harald Welte, Patrick McHardy
[-- Attachment #1.1: Type: text/plain, Size: 323 bytes --]
Since OSF originally was created in 2.5 environment
it is strange not to have 2.6 support for OSF.
This(similar) patch was sent some time ago but was lost.
Please apply.
Signed-off-by: Evgeniy Polyakov <johnpol@2ka.mipt.ru>
--
Evgeniy Polyakov
Crash is better than data corruption -- Arthur Grabowski
[-- Attachment #1.2: ipt_osf --]
[-- Type: text/plain, Size: 2790 bytes --]
--- /tmp/osf/ipt_osf.c 2004-12-08 13:39:02.621927128 +0300
+++ /home/s0mbre/aWork/tmp/osf/ipt_osf.c 2004-08-25 09:02:25.000000000 +0400
@@ -52,14 +52,15 @@
#include "ipt_osf.h"
-#define OSF_DEBUG
+//#define OSF_DEBUG
+#undef OSF_DEBUG
#ifdef OSF_DEBUG
#define log(x...) printk(KERN_INFO "ipt_osf: " x)
#define loga(x...) printk(x)
#else
-#define log(x...) do {} while(0)
-#define loga(x...) do {} while(0)
+#define log(x...)
+#define loga(x...)
#endif
#define FMATCH_WRONG 0
@@ -76,7 +77,7 @@
static struct list_head finger_list;
static int match(const struct sk_buff *, const struct net_device *, const struct net_device *,
const void *, int,
- const void *, u_int16_t,
+ //const void *, u_int16_t,
int *);
static int checkentry(const char *, const struct ipt_ip *, void *,
unsigned int, unsigned int);
@@ -153,7 +154,7 @@
static int
match(const struct sk_buff *skb, const struct net_device *in, const struct net_device *out,
const void *matchinfo, int offset,
- const void *hdr, u_int16_t datalen,
+ //const void *hdr, u_int16_t datalen,
int *hotdrop)
{
struct ipt_osf_info *info = (struct ipt_osf_info *)matchinfo;
@@ -184,7 +185,6 @@
optsize = tcp->doff*4 - sizeof(struct tcphdr);
}
-
/* Actually we can create hash/table of all genres and search
* only in appropriate part, but here is initial variant,
* so will use slow path.
@@ -414,7 +414,10 @@
}
read_unlock(&osf_lock);
-
+
+ if (fcount)
+ fmatch = FMATCH_OK;
+
return (fmatch == FMATCH_OK)?1:0;
}
@@ -600,9 +603,10 @@
{
struct list_head *ent;
struct osf_finger *f = NULL;
- int i;
+ int i, __count, err;
*eof = 1;
+ __count = count;
count = 0;
read_lock_bh(&osf_lock);
@@ -612,10 +616,13 @@
log("%s [%s]", f->genre, f->details);
- count += sprintf(buf+count, "%s - %s[%s] : %s",
+ err = snprintf(buf+count, __count-count, "%s - %s[%s] : %s",
f->genre, f->version,
f->subtype, f->details);
-
+ if (err == 0 || __count <= count + err)
+ break;
+ else
+ count += err;
if (f->opt_num)
{
loga(" OPT: ");
@@ -629,7 +636,11 @@
}
}
loga("\n");
- count += sprintf(buf+count, "\n");
+ err = snprintf(buf+count, __count-count, "\n");
+ if (err == 0 || __count <= count + err)
+ break;
+ else
+ count += err;
}
read_unlock_bh(&osf_lock);
@@ -844,8 +855,8 @@
remove_proc_entry("sys/net/ipv4/osf", NULL);
ipt_unregister_match(&osf_match);
- if (nts && nts->socket)
- sock_release(nts->socket);
+ if (nts && nts->sk_socket)
+ sock_release(nts->sk_socket);
list_for_each_safe(ent, n, &finger_list)
{
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [1/1] OSF: pom-ng - linux-2.6.
2004-12-08 10:58 [1/1] OSF: pom-ng - linux-2.6 Evgeniy Polyakov
@ 2004-12-08 11:02 ` Evgeniy Polyakov
2004-12-08 18:48 ` Patrick McHardy
2004-12-08 13:32 ` Pavel A. Nekrasov
2004-12-08 18:44 ` Patrick McHardy
2 siblings, 1 reply; 8+ messages in thread
From: Evgeniy Polyakov @ 2004-12-08 11:02 UTC (permalink / raw)
To: netfilter-devel; +Cc: Harald Welte, Patrick McHardy
[-- Attachment #1.1: Type: text/plain, Size: 495 bytes --]
On Wed, 2004-12-08 at 13:58 +0300, Evgeniy Polyakov wrote:
> Since OSF originally was created in 2.5 environment
> it is strange not to have 2.6 support for OSF.
> This(similar) patch was sent some time ago but was lost.
> Please apply.
>
> Signed-off-by: Evgeniy Polyakov <johnpol@2ka.mipt.ru>
My dear hands, please contact my brain before doing anything.
Thanks.
Proper patch attached.
--
Evgeniy Polyakov
Crash is better than data corruption -- Arthur Grabowski
[-- Attachment #1.2: pom.diff --]
[-- Type: text/x-patch, Size: 26763 bytes --]
diff -Nru patch-o-matic-ng-20040621-orig/osf/info patch-o-matic-ng-20040621/osf/info
--- patch-o-matic-ng-20040621-orig/osf/info 2004-12-08 13:43:48.828417128 +0300
+++ patch-o-matic-ng-20040621/osf/info 2004-12-08 13:49:41.040872696 +0300
@@ -1,3 +1,2 @@
Author: Evgeniy Polyakov <johnpol@2ka.mipt.ru>
Repository: base
-Requires: linux < 2.6.0
diff -Nru patch-o-matic-ng-20040621-orig/osf/linux-2.6/include/linux/netfilter_ipv4/ipt_osf.h patch-o-matic-ng-20040621/osf/linux-2.6/include/linux/netfilter_ipv4/ipt_osf.h
--- patch-o-matic-ng-20040621-orig/osf/linux-2.6/include/linux/netfilter_ipv4/ipt_osf.h 1970-01-01 03:00:00.000000000 +0300
+++ patch-o-matic-ng-20040621/osf/linux-2.6/include/linux/netfilter_ipv4/ipt_osf.h 2004-03-01 00:19:47.000000000 +0300
@@ -0,0 +1,148 @@
+/*
+ * ipt_osf.h
+ *
+ * Copyright (c) 2003 Evgeniy Polyakov <johnpol@2ka.mipt.ru>
+ *
+ *
+ * This program 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _IPT_OSF_H
+#define _IPT_OSF_H
+
+#define MAXGENRELEN 32
+#define MAXDETLEN 64
+
+#define IPT_OSF_GENRE 1
+#define IPT_OSF_SMART 2
+#define IPT_OSF_LOG 4
+#define IPT_OSF_NETLINK 8
+
+#define IPT_OSF_LOGLEVEL_ALL 0
+#define IPT_OSF_LOGLEVEL_FIRST 1
+
+#include <linux/list.h>
+
+#ifndef __KERNEL__
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
+
+struct list_head
+{
+ struct list_head *prev, *next;
+};
+#endif
+
+struct ipt_osf_info
+{
+ char genre[MAXGENRELEN];
+ int len;
+ unsigned long flags;
+ int loglevel;
+ int invert; /* UNSUPPORTED */
+};
+
+struct osf_wc
+{
+ char wc;
+ unsigned long val;
+};
+
+/* This struct represents IANA options
+ * http://www.iana.org/assignments/tcp-parameters
+ */
+struct osf_opt
+{
+ unsigned char kind;
+ unsigned char length;
+ struct osf_wc wc;
+};
+
+struct osf_finger
+{
+ struct list_head flist;
+ struct osf_wc wss;
+ unsigned char ttl;
+ unsigned char df;
+ unsigned long ss;
+ unsigned char genre[MAXGENRELEN];
+ unsigned char version[MAXGENRELEN], subtype[MAXGENRELEN];
+
+ /* Not needed, but for consistency with original table from Michal Zalewski */
+ unsigned char details[MAXDETLEN];
+
+ int opt_num;
+ struct osf_opt opt[MAX_IPOPTLEN]; /* In case it is all NOP or EOL */
+
+};
+
+struct ipt_osf_nlmsg
+{
+ struct osf_finger f;
+ struct iphdr ip;
+ struct tcphdr tcp;
+};
+
+#ifdef __KERNEL__
+
+/* Defines for IANA option kinds */
+
+#define OSFOPT_EOL 0 /* End of options */
+#define OSFOPT_NOP 1 /* NOP */
+#define OSFOPT_MSS 2 /* Maximum segment size */
+#define OSFOPT_WSO 3 /* Window scale option */
+#define OSFOPT_SACKP 4 /* SACK permitted */
+#define OSFOPT_SACK 5 /* SACK */
+#define OSFOPT_ECHO 6
+#define OSFOPT_ECHOREPLY 7
+#define OSFOPT_TS 8 /* Timestamp option */
+#define OSFOPT_POCP 9 /* Partial Order Connection Permitted */
+#define OSFOPT_POSP 10 /* Partial Order Service Profile */
+/* Others are not used in current OSF */
+
+static struct osf_opt IANA_opts[] =
+{
+ {0, 1,},
+ {1, 1,},
+ {2, 4,},
+ {3, 3,},
+ {4, 2,},
+ {5, 1 ,}, /* SACK length is not defined */
+ {6, 6,},
+ {7, 6,},
+ {8, 10,},
+ {9, 2,},
+ {10, 3,},
+ {11, 1,}, /* CC: Suppose 1 */
+ {12, 1,}, /* the same */
+ {13, 1,}, /* and here too */
+ {14, 3,},
+ {15, 1,}, /* TCP Alternate Checksum Data. Length is not defined */
+ {16, 1,},
+ {17, 1,},
+ {18, 3,},
+ {19, 18,},
+ {20, 1,},
+ {21, 1,},
+ {22, 1,},
+ {23, 1,},
+ {24, 1,},
+ {25, 1,},
+ {26, 1,},
+};
+
+#endif /* __KERNEL__ */
+
+#endif /* _IPT_OSF_H */
diff -Nru patch-o-matic-ng-20040621-orig/osf/linux-2.6/net/ipv4/netfilter/ipt_osf.c patch-o-matic-ng-20040621/osf/linux-2.6/net/ipv4/netfilter/ipt_osf.c
--- patch-o-matic-ng-20040621-orig/osf/linux-2.6/net/ipv4/netfilter/ipt_osf.c 1970-01-01 03:00:00.000000000 +0300
+++ patch-o-matic-ng-20040621/osf/linux-2.6/net/ipv4/netfilter/ipt_osf.c 2004-12-08 13:47:59.130365448 +0300
@@ -0,0 +1,863 @@
+/*
+ * ipt_osf.c
+ *
+ * Copyright (c) 2003 Evgeniy Polyakov <johnpol@2ka.mipt.ru>
+ *
+ *
+ * This program 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * OS fingerprint matching module.
+ * It simply compares various parameters from SYN packet with
+ * some hardcoded ones.
+ *
+ * Original table was created by Michal Zalewski <lcamtuf@coredump.cx>
+ * for his p0f.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/smp.h>
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/file.h>
+#include <linux/ip.h>
+#include <linux/proc_fs.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/ctype.h>
+#include <linux/list.h>
+#include <linux/if.h>
+
+#include <net/sock.h>
+#include <net/ip.h>
+
+#include <linux/netfilter_ipv4/ip_tables.h>
+
+#include <linux/netfilter_ipv4/ipt_osf.h>
+
+#define OSF_DEBUG
+
+#ifdef OSF_DEBUG
+#define log(x...) printk(KERN_INFO "ipt_osf: " x)
+#define loga(x...) printk(x)
+#else
+#define log(x...) do {} while(0)
+#define loga(x...) do {} while(0)
+#endif
+
+#define FMATCH_WRONG 0
+#define FMATCH_OK 1
+#define FMATCH_OPT_WRONG 2
+
+#define OPTDEL ','
+#define OSFPDEL ':'
+#define MAXOPTSTRLEN 128
+#define OSFFLUSH "FLUSH"
+
+static rwlock_t osf_lock = RW_LOCK_UNLOCKED;
+static spinlock_t ipt_osf_netlink_lock = SPIN_LOCK_UNLOCKED;
+static struct list_head finger_list;
+static int match(const struct sk_buff *, const struct net_device *, const struct net_device *,
+ const void *, int,
+ int *);
+static int checkentry(const char *, const struct ipt_ip *, void *,
+ unsigned int, unsigned int);
+
+static unsigned long seq, ipt_osf_groups = 1;
+static struct sock *nts;
+
+static struct ipt_match osf_match =
+{
+ { NULL, NULL },
+ "osf",
+ &match,
+ &checkentry,
+ NULL,
+ THIS_MODULE
+};
+
+static void ipt_osf_nlsend(struct osf_finger *f, const struct sk_buff *sk)
+{
+ unsigned int size;
+ struct sk_buff *skb;
+ struct ipt_osf_nlmsg *data;
+ struct nlmsghdr *nlh;
+
+ size = NLMSG_SPACE(sizeof(struct ipt_osf_nlmsg));
+
+ skb = alloc_skb(size, GFP_ATOMIC);
+ if (!skb)
+ {
+ log("skb_alloc() failed.\n");
+ return;
+ }
+
+ nlh = NLMSG_PUT(skb, 0, seq++, NLMSG_DONE, size - sizeof(*nlh));
+
+ data = (struct ipt_osf_nlmsg *)NLMSG_DATA(nlh);
+
+ memcpy(&data->f, f, sizeof(struct osf_finger));
+ memcpy(&data->ip, sk->nh.iph, sizeof(struct iphdr));
+ memcpy(&data->tcp, (struct tcphdr *)((u_int32_t *)sk->nh.iph + sk->nh.iph->ihl), sizeof(struct tcphdr));
+
+ NETLINK_CB(skb).dst_groups = ipt_osf_groups;
+ netlink_broadcast(nts, skb, 0, ipt_osf_groups, GFP_ATOMIC);
+
+nlmsg_failure:
+ return;
+}
+
+static inline int smart_dec(const struct sk_buff *skb, unsigned long flags, unsigned char f_ttl)
+{
+ struct iphdr *ip = skb->nh.iph;
+
+ if (flags & IPT_OSF_SMART)
+ {
+ struct in_device *in_dev = in_dev_get(skb->dev);
+
+ for_ifa(in_dev)
+ {
+ if (inet_ifa_match(ip->saddr, ifa))
+ {
+ in_dev_put(in_dev);
+ return (ip->ttl == f_ttl);
+ }
+ }
+ endfor_ifa(in_dev);
+
+ in_dev_put(in_dev);
+ return (ip->ttl <= f_ttl);
+ }
+ else
+ return (ip->ttl == f_ttl);
+}
+
+static int
+match(const struct sk_buff *skb, const struct net_device *in, const struct net_device *out,
+ const void *matchinfo, int offset,
+ int *hotdrop)
+{
+ struct ipt_osf_info *info = (struct ipt_osf_info *)matchinfo;
+ struct iphdr *ip = skb->nh.iph;
+ struct tcphdr *tcp;
+ int fmatch = FMATCH_WRONG, fcount = 0;
+ unsigned long totlen, optsize = 0, window;
+ unsigned char df, *optp = NULL, *_optp = NULL;
+ char check_WSS = 0;
+ struct list_head *ent;
+ struct osf_finger *f;
+
+ if (!ip || !info)
+ return 0;
+
+ tcp = (struct tcphdr *)((u_int32_t *)ip + ip->ihl);
+
+ if (!tcp->syn)
+ return 0;
+
+ totlen = ntohs(ip->tot_len);
+ df = ((ntohs(ip->frag_off) & IP_DF)?1:0);
+ window = ntohs(tcp->window);
+
+ if (tcp->doff*4 > sizeof(struct tcphdr))
+ {
+ _optp = optp = (char *)(tcp+1);
+ optsize = tcp->doff*4 - sizeof(struct tcphdr);
+ }
+
+
+ /* Actually we can create hash/table of all genres and search
+ * only in appropriate part, but here is initial variant,
+ * so will use slow path.
+ */
+ read_lock(&osf_lock);
+ list_for_each(ent, &finger_list)
+ {
+ f = list_entry(ent, struct osf_finger, flist);
+
+ if (!(info->flags & IPT_OSF_LOG) && strcmp(info->genre, f->genre))
+ continue;
+
+ optp = _optp;
+ fmatch = FMATCH_WRONG;
+
+ if (totlen == f->ss && df == f->df &&
+ smart_dec(skb, info->flags, f->ttl))
+ {
+ unsigned long foptsize;
+ int optnum;
+ unsigned short mss = 0;
+
+ check_WSS = 0;
+
+ switch (f->wss.wc)
+ {
+ case 0: check_WSS = 0; break;
+ case 'S': check_WSS = 1; break;
+ case 'T': check_WSS = 2; break;
+ case '%': check_WSS = 3; break;
+ default: log("Wrong fingerprint wss.wc=%d, %s - %s\n",
+ f->wss.wc, f->genre, f->details);
+ check_WSS = 4;
+ break;
+ }
+ if (check_WSS == 4)
+ continue;
+
+ /* Check options */
+
+ foptsize = 0;
+ for (optnum=0; optnum<f->opt_num; ++optnum)
+ foptsize += f->opt[optnum].length;
+
+
+ if (foptsize > MAX_IPOPTLEN || optsize > MAX_IPOPTLEN || optsize != foptsize)
+ continue;
+
+ if (!optp)
+ {
+ fmatch = FMATCH_OK;
+ loga("\tYEP : matching without options.\n");
+ if ((info->flags & IPT_OSF_LOG) &&
+ info->loglevel == IPT_OSF_LOGLEVEL_FIRST)
+ break;
+ else
+ continue;
+ }
+
+
+ for (optnum=0; optnum<f->opt_num; ++optnum)
+ {
+ if (f->opt[optnum].kind == (*optp))
+ {
+ unsigned char len = f->opt[optnum].length;
+ unsigned char *optend = optp + len;
+ int loop_cont = 0;
+
+ fmatch = FMATCH_OK;
+
+
+ switch (*optp)
+ {
+ case OSFOPT_MSS:
+ mss = ntohs(*(unsigned short *)(optp+2));
+ break;
+ case OSFOPT_TS:
+ loop_cont = 1;
+ break;
+ }
+
+ if (loop_cont)
+ {
+ optp = optend;
+ continue;
+ }
+
+ if (len != 1)
+ {
+ /* Skip kind and length fields*/
+ optp += 2;
+
+ if (f->opt[optnum].wc.val != 0)
+ {
+ unsigned long tmp = 0;
+
+ /* Hmmm... It looks a bit ugly. :) */
+ memcpy(&tmp, optp,
+ (len > sizeof(unsigned long)?
+ sizeof(unsigned long):len));
+ /* 2 + 2: optlen(2 bytes) +
+ * kind(1 byte) + length(1 byte) */
+ if (len == 4)
+ tmp = ntohs(tmp);
+ else
+ tmp = ntohl(tmp);
+
+ if (f->opt[optnum].wc.wc == '%')
+ {
+ if ((tmp % f->opt[optnum].wc.val) != 0)
+ fmatch = FMATCH_OPT_WRONG;
+ }
+ else if (tmp != f->opt[optnum].wc.val)
+ fmatch = FMATCH_OPT_WRONG;
+ }
+ }
+
+ optp = optend;
+ }
+ else
+ fmatch = FMATCH_OPT_WRONG;
+
+ if (fmatch != FMATCH_OK)
+ break;
+ }
+
+ if (fmatch != FMATCH_OPT_WRONG)
+ {
+ fmatch = FMATCH_WRONG;
+
+ switch (check_WSS)
+ {
+ case 0:
+ if (f->wss.val == 0 || window == f->wss.val)
+ fmatch = FMATCH_OK;
+ break;
+ case 1: /* MSS */
+/* Lurked in OpenBSD */
+#define SMART_MSS 1460
+ if (window == f->wss.val*mss ||
+ window == f->wss.val*SMART_MSS)
+ fmatch = FMATCH_OK;
+ break;
+ case 2: /* MTU */
+ if (window == f->wss.val*(mss+40) ||
+ window == f->wss.val*(SMART_MSS+40))
+ fmatch = FMATCH_OK;
+ break;
+ case 3: /* MOD */
+ if ((window % f->wss.val) == 0)
+ fmatch = FMATCH_OK;
+ break;
+ }
+ }
+
+
+ if (fmatch == FMATCH_OK)
+ {
+ fcount++;
+ log("%s [%s:%s:%s] : %u.%u.%u.%u:%u -> %u.%u.%u.%u:%u hops=%d\n",
+ f->genre, f->version,
+ f->subtype, f->details,
+ NIPQUAD(ip->saddr), ntohs(tcp->source),
+ NIPQUAD(ip->daddr), ntohs(tcp->dest),
+ f->ttl - ip->ttl);
+ if (info->flags & IPT_OSF_NETLINK)
+ {
+ spin_lock_bh(&ipt_osf_netlink_lock);
+ ipt_osf_nlsend(f, skb);
+ spin_unlock_bh(&ipt_osf_netlink_lock);
+ }
+ if ((info->flags & IPT_OSF_LOG) &&
+ info->loglevel == IPT_OSF_LOGLEVEL_FIRST)
+ break;
+ }
+ }
+ }
+ if (!fcount && (info->flags & (IPT_OSF_LOG | IPT_OSF_NETLINK)))
+ {
+ unsigned char opt[4 * 15 - sizeof(struct tcphdr)];
+ unsigned int i, optsize;
+ struct osf_finger fg;
+
+ memset(&fg, 0, sizeof(fg));
+
+ if ((info->flags & IPT_OSF_LOG))
+ log("Unknown: %lu:%d:%d:%lu:", window, ip->ttl, df, totlen);
+ if (optp)
+ {
+ optsize = tcp->doff * 4 - sizeof(struct tcphdr);
+ if (skb_copy_bits(skb, ip->ihl*4 + sizeof(struct tcphdr),
+ opt, optsize) < 0)
+ {
+ if (info->flags & IPT_OSF_LOG)
+ loga("TRUNCATED");
+ if (info->flags & IPT_OSF_NETLINK)
+ strcpy(fg.details, "TRUNCATED");
+ }
+ else
+ {
+ for (i = 0; i < optsize; i++)
+ {
+ if (info->flags & IPT_OSF_LOG)
+ loga("%02X", opt[i]);
+ }
+ if (info->flags & IPT_OSF_NETLINK)
+ memcpy(fg.details, opt, MAXDETLEN);
+ }
+ }
+ if ((info->flags & IPT_OSF_LOG))
+ loga(" %u.%u.%u.%u:%u -> %u.%u.%u.%u:%u\n",
+ NIPQUAD(ip->saddr), ntohs(tcp->source),
+ NIPQUAD(ip->daddr), ntohs(tcp->dest));
+
+ if (info->flags & IPT_OSF_NETLINK)
+ {
+ fg.wss.val = window;
+ fg.ttl = ip->ttl;
+ fg.df = df;
+ fg.ss = totlen;
+ strncpy(fg.genre, "Unknown", MAXGENRELEN);
+
+ spin_lock_bh(&ipt_osf_netlink_lock);
+ ipt_osf_nlsend(&fg, skb);
+ spin_unlock_bh(&ipt_osf_netlink_lock);
+ }
+ }
+
+ read_unlock(&osf_lock);
+
+ return (fmatch == FMATCH_OK)?1:0;
+}
+
+static int
+checkentry(const char *tablename,
+ const struct ipt_ip *ip,
+ void *matchinfo,
+ unsigned int matchsize,
+ unsigned int hook_mask)
+{
+ if (matchsize != IPT_ALIGN(sizeof(struct ipt_osf_info)))
+ return 0;
+ if (ip->proto != IPPROTO_TCP)
+ return 0;
+
+ return 1;
+}
+
+static char * osf_strchr(char *ptr, char c)
+{
+ char *tmp;
+
+ tmp = strchr(ptr, c);
+
+ while (tmp && tmp+1 && isspace(*(tmp+1)))
+ tmp++;
+
+ return tmp;
+}
+
+static struct osf_finger * finger_alloc(void)
+{
+ struct osf_finger *f;
+
+ f = kmalloc(sizeof(struct osf_finger), GFP_KERNEL);
+ if (f)
+ memset(f, 0, sizeof(struct osf_finger));
+
+ return f;
+}
+
+static void finger_free(struct osf_finger *f)
+{
+ memset(f, 0, sizeof(struct osf_finger));
+ kfree(f);
+}
+
+
+static void osf_parse_opt(struct osf_opt *opt, int *optnum, char *obuf, int olen)
+{
+ int i, op;
+ char *ptr, wc;
+ unsigned long val;
+
+ ptr = &obuf[0];
+ i = 0;
+ while (ptr != NULL && i < olen)
+ {
+ val = 0;
+ op = 0;
+ wc = 0;
+ switch (obuf[i])
+ {
+ case 'N':
+ op = OSFOPT_NOP;
+ ptr = osf_strchr(&obuf[i], OPTDEL);
+ if (ptr)
+ {
+ *ptr = '\0';
+ ptr++;
+ i += (int)(ptr-&obuf[i]);
+
+ }
+ else
+ i++;
+ break;
+ case 'S':
+ op = OSFOPT_SACKP;
+ ptr = osf_strchr(&obuf[i], OPTDEL);
+ if (ptr)
+ {
+ *ptr = '\0';
+ ptr++;
+ i += (int)(ptr-&obuf[i]);
+
+ }
+ else
+ i++;
+ break;
+ case 'T':
+ op = OSFOPT_TS;
+ ptr = osf_strchr(&obuf[i], OPTDEL);
+ if (ptr)
+ {
+ *ptr = '\0';
+ ptr++;
+ i += (int)(ptr-&obuf[i]);
+
+ }
+ else
+ i++;
+ break;
+ case 'W':
+ op = OSFOPT_WSO;
+ ptr = osf_strchr(&obuf[i], OPTDEL);
+ if (ptr)
+ {
+ switch (obuf[i+1])
+ {
+ case '%': wc = '%'; break;
+ case 'S': wc = 'S'; break;
+ case 'T': wc = 'T'; break;
+ default: wc = 0; break;
+ }
+
+ *ptr = '\0';
+ ptr++;
+ if (wc)
+ val = simple_strtoul(&obuf[i+2], NULL, 10);
+ else
+ val = simple_strtoul(&obuf[i+1], NULL, 10);
+ i += (int)(ptr-&obuf[i]);
+
+ }
+ else
+ i++;
+ break;
+ case 'M':
+ op = OSFOPT_MSS;
+ ptr = osf_strchr(&obuf[i], OPTDEL);
+ if (ptr)
+ {
+ if (obuf[i+1] == '%')
+ wc = '%';
+ *ptr = '\0';
+ ptr++;
+ if (wc)
+ val = simple_strtoul(&obuf[i+2], NULL, 10);
+ else
+ val = simple_strtoul(&obuf[i+1], NULL, 10);
+ i += (int)(ptr-&obuf[i]);
+
+ }
+ else
+ i++;
+ break;
+ case 'E':
+ op = OSFOPT_EOL;
+ ptr = osf_strchr(&obuf[i], OPTDEL);
+ if (ptr)
+ {
+ *ptr = '\0';
+ ptr++;
+ i += (int)(ptr-&obuf[i]);
+
+ }
+ else
+ i++;
+ break;
+ default:
+ ptr = osf_strchr(&obuf[i], OPTDEL);
+ if (ptr)
+ {
+ ptr++;
+ i += (int)(ptr-&obuf[i]);
+
+ }
+ else
+ i++;
+ break;
+ }
+
+ opt[*optnum].kind = IANA_opts[op].kind;
+ opt[*optnum].length = IANA_opts[op].length;
+ opt[*optnum].wc.wc = wc;
+ opt[*optnum].wc.val = val;
+
+ (*optnum)++;
+ }
+}
+
+static int osf_proc_read(char *buf, char **start, off_t off, int count, int *eof, void *data)
+{
+ struct list_head *ent;
+ struct osf_finger *f = NULL;
+ int i;
+
+ *eof = 1;
+ count = 0;
+
+ read_lock_bh(&osf_lock);
+ list_for_each(ent, &finger_list)
+ {
+ f = list_entry(ent, struct osf_finger, flist);
+
+ log("%s [%s]", f->genre, f->details);
+
+ count += sprintf(buf+count, "%s - %s[%s] : %s",
+ f->genre, f->version,
+ f->subtype, f->details);
+
+ if (f->opt_num)
+ {
+ loga(" OPT: ");
+ //count += sprintf(buf+count, " OPT: ");
+ for (i=0; i<f->opt_num; ++i)
+ {
+ //count += sprintf(buf+count, "%d.%c%lu; ",
+ // f->opt[i].kind, (f->opt[i].wc.wc)?f->opt[i].wc.wc:' ', f->opt[i].wc.val);
+ loga("%d.%c%lu; ",
+ f->opt[i].kind, (f->opt[i].wc.wc)?f->opt[i].wc.wc:' ', f->opt[i].wc.val);
+ }
+ }
+ loga("\n");
+ count += sprintf(buf+count, "\n");
+ }
+ read_unlock_bh(&osf_lock);
+
+ return count;
+}
+
+static int osf_proc_write(struct file *file, const char *buffer, unsigned long count, void *data)
+{
+ int cnt;
+ unsigned long i;
+ char obuf[MAXOPTSTRLEN];
+ struct osf_finger *finger;
+ struct list_head *ent, *n;
+
+ char *pbeg, *pend;
+
+ if (count == strlen(OSFFLUSH) && !strncmp(buffer, OSFFLUSH, strlen(OSFFLUSH)))
+ {
+ int i = 0;
+ write_lock_bh(&osf_lock);
+ list_for_each_safe(ent, n, &finger_list)
+ {
+ i++;
+ finger = list_entry(ent, struct osf_finger, flist);
+ list_del(&finger->flist);
+ finger_free(finger);
+ }
+ write_unlock_bh(&osf_lock);
+
+ log("Flushed %d entries.\n", i);
+
+ return count;
+ }
+
+
+ cnt = 0;
+ for (i=0; i<count && buffer[i] != '\0'; ++i)
+ if (buffer[i] == ':')
+ cnt++;
+
+ if (cnt != 8 || i != count)
+ {
+ log("Wrong input line cnt=%d[8], len=%lu[%lu]\n",
+ cnt, i, count);
+ return count;
+ }
+
+ memset(obuf, 0, sizeof(obuf));
+
+ finger = finger_alloc();
+ if (!finger)
+ {
+ log("Failed to allocate new fingerprint entry.\n");
+ return -ENOMEM;
+ }
+
+ pbeg = (char *)buffer;
+ pend = osf_strchr(pbeg, OSFPDEL);
+ if (pend)
+ {
+ *pend = '\0';
+ if (pbeg[0] == 'S')
+ {
+ finger->wss.wc = 'S';
+ if (pbeg[1] == '%')
+ finger->wss.val = simple_strtoul(pbeg+2, NULL, 10);
+ else if (pbeg[1] == '*')
+ finger->wss.val = 0;
+ else
+ finger->wss.val = simple_strtoul(pbeg+1, NULL, 10);
+ }
+ else if (pbeg[0] == 'T')
+ {
+ finger->wss.wc = 'T';
+ if (pbeg[1] == '%')
+ finger->wss.val = simple_strtoul(pbeg+2, NULL, 10);
+ else if (pbeg[1] == '*')
+ finger->wss.val = 0;
+ else
+ finger->wss.val = simple_strtoul(pbeg+1, NULL, 10);
+ }
+ else if (pbeg[0] == '%')
+ {
+ finger->wss.wc = '%';
+ finger->wss.val = simple_strtoul(pbeg+1, NULL, 10);
+ }
+ else if (isdigit(pbeg[0]))
+ {
+ finger->wss.wc = 0;
+ finger->wss.val = simple_strtoul(pbeg, NULL, 10);
+ }
+
+ pbeg = pend+1;
+ }
+ pend = osf_strchr(pbeg, OSFPDEL);
+ if (pend)
+ {
+ *pend = '\0';
+ finger->ttl = simple_strtoul(pbeg, NULL, 10);
+ pbeg = pend+1;
+ }
+ pend = osf_strchr(pbeg, OSFPDEL);
+ if (pend)
+ {
+ *pend = '\0';
+ finger->df = simple_strtoul(pbeg, NULL, 10);
+ pbeg = pend+1;
+ }
+ pend = osf_strchr(pbeg, OSFPDEL);
+ if (pend)
+ {
+ *pend = '\0';
+ finger->ss = simple_strtoul(pbeg, NULL, 10);
+ pbeg = pend+1;
+ }
+
+ pend = osf_strchr(pbeg, OSFPDEL);
+ if (pend)
+ {
+ *pend = '\0';
+ cnt = snprintf(obuf, sizeof(obuf), "%s", pbeg);
+ pbeg = pend+1;
+ }
+
+ pend = osf_strchr(pbeg, OSFPDEL);
+ if (pend)
+ {
+ *pend = '\0';
+ if (pbeg[0] == '@' || pbeg[0] == '*')
+ cnt = snprintf(finger->genre, sizeof(finger->genre), "%s", pbeg+1);
+ else
+ cnt = snprintf(finger->genre, sizeof(finger->genre), "%s", pbeg);
+ pbeg = pend+1;
+ }
+
+ pend = osf_strchr(pbeg, OSFPDEL);
+ if (pend)
+ {
+ *pend = '\0';
+ cnt = snprintf(finger->version, sizeof(finger->version), "%s", pbeg);
+ pbeg = pend+1;
+ }
+
+ pend = osf_strchr(pbeg, OSFPDEL);
+ if (pend)
+ {
+ *pend = '\0';
+ cnt = snprintf(finger->subtype, sizeof(finger->subtype), "%s", pbeg);
+ pbeg = pend+1;
+ }
+
+ cnt = snprintf(finger->details,
+ ((count - (pbeg - buffer)+1) > MAXDETLEN)?MAXDETLEN:(count - (pbeg - buffer)+1),
+ "%s", pbeg);
+
+ log("%s - %s[%s] : %s\n",
+ finger->genre, finger->version,
+ finger->subtype, finger->details);
+
+ osf_parse_opt(finger->opt, &finger->opt_num, obuf, sizeof(obuf));
+
+
+ write_lock_bh(&osf_lock);
+ list_add_tail(&finger->flist, &finger_list);
+ write_unlock_bh(&osf_lock);
+
+ return count;
+}
+
+static int __init osf_init(void)
+{
+ int err;
+ struct proc_dir_entry *p;
+
+ log("Startng OS fingerprint matching module.\n");
+
+ INIT_LIST_HEAD(&finger_list);
+
+ err = ipt_register_match(&osf_match);
+ if (err)
+ {
+ log("Failed to register OS fingerprint matching module.\n");
+ return -ENXIO;
+ }
+
+ p = create_proc_entry("sys/net/ipv4/osf", S_IFREG | 0644, NULL);
+ if (!p)
+ {
+ ipt_unregister_match(&osf_match);
+ return -ENXIO;
+ }
+
+ p->write_proc = osf_proc_write;
+ p->read_proc = osf_proc_read;
+
+ nts = netlink_kernel_create(NETLINK_NFLOG, NULL);
+ if (!nts)
+ {
+ log("netlink_kernel_create() failed\n");
+ remove_proc_entry("sys/net/ipv4/osf", NULL);
+ ipt_unregister_match(&osf_match);
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+static void __exit osf_fini(void)
+{
+ struct list_head *ent, *n;
+ struct osf_finger *f;
+
+ remove_proc_entry("sys/net/ipv4/osf", NULL);
+ ipt_unregister_match(&osf_match);
+ if (nts && nts->sk_socket)
+ sock_release(nts->sk_socket);
+
+ list_for_each_safe(ent, n, &finger_list)
+ {
+ f = list_entry(ent, struct osf_finger, flist);
+ list_del(&f->flist);
+ finger_free(f);
+ }
+
+ log("OS fingerprint matching module finished.\n");
+}
+
+module_init(osf_init);
+module_exit(osf_fini);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>");
+MODULE_DESCRIPTION("Passive OS fingerprint matching.");
diff -Nru patch-o-matic-ng-20040621-orig/osf/linux-2.6/net/ipv4/netfilter/Kconfig.ladd patch-o-matic-ng-20040621/osf/linux-2.6/net/ipv4/netfilter/Kconfig.ladd
--- patch-o-matic-ng-20040621-orig/osf/linux-2.6/net/ipv4/netfilter/Kconfig.ladd 1970-01-01 03:00:00.000000000 +0300
+++ patch-o-matic-ng-20040621/osf/linux-2.6/net/ipv4/netfilter/Kconfig.ladd 2004-05-06 17:27:49.000000000 +0400
@@ -0,0 +1,21 @@
+config IP_NF_MATCH_OSF
+ tristate 'OSF match support'
+ depends on IP_NF_IPTABLES
+ help
+
+ The idea of passive OS fingerprint matching exists for quite a long time,
+ but was created as extension fo OpenBSD pf only some weeks ago.
+ Original idea was lurked in some OpenBSD mailing list (thanks
+ grange@open...) and than adopted for Linux netfilter in form of this code.
+
+ Original table was created by Michal Zalewski <lcamtuf@coredump.cx> for
+ his excellent p0f and than changed a bit for more convenience.
+
+ This module compares some data(WS, MSS, options and it's order, ttl,
+ df and others) from first SYN packet (actually from packets with SYN
+ bit set) with hardcoded in fingers[] table ones.
+
+ If you say Y here, try iptables -m osf --help for more information.
+
+ If you want to compile it as a module, say M here and read
+ Documentation/modules.txt. If unsure, say `N'.
diff -Nru patch-o-matic-ng-20040621-orig/osf/linux-2.6/net/ipv4/netfilter/Makefile.ladd patch-o-matic-ng-20040621/osf/linux-2.6/net/ipv4/netfilter/Makefile.ladd
--- patch-o-matic-ng-20040621-orig/osf/linux-2.6/net/ipv4/netfilter/Makefile.ladd 1970-01-01 03:00:00.000000000 +0300
+++ patch-o-matic-ng-20040621/osf/linux-2.6/net/ipv4/netfilter/Makefile.ladd 2003-12-18 21:28:43.000000000 +0300
@@ -0,0 +1,4 @@
+obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o
+
+obj-$(CONFIG_IP_NF_MATCH_OSF) += ipt_osf.o
+
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [1/1] OSF: pom-ng - linux-2.6.
2004-12-08 10:58 [1/1] OSF: pom-ng - linux-2.6 Evgeniy Polyakov
2004-12-08 11:02 ` Evgeniy Polyakov
@ 2004-12-08 13:32 ` Pavel A. Nekrasov
2004-12-08 13:43 ` Evgeniy Polyakov
2004-12-08 18:44 ` Patrick McHardy
2 siblings, 1 reply; 8+ messages in thread
From: Pavel A. Nekrasov @ 2004-12-08 13:32 UTC (permalink / raw)
To: johnpol; +Cc: Harald Welte, netfilter-devel, Patrick McHardy
i got you doing the same.
Evgeniy Polyakov wrote:
>+ nts = netlink_kernel_create(NETLINK_NFLOG, NULL);
drivers/w1/w1_int.c: dev->nls = netlink_kernel_create(NETLINK_NFLOG, NULL);
NETLINK_NFLOG is used by ipt_ULOG, you can't use that socket because
you are breaking compatibility. You have to use different sockets,
call davem and request new ones.
kind regards,
Pavel
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [1/1] OSF: pom-ng - linux-2.6.
2004-12-08 13:32 ` Pavel A. Nekrasov
@ 2004-12-08 13:43 ` Evgeniy Polyakov
0 siblings, 0 replies; 8+ messages in thread
From: Evgeniy Polyakov @ 2004-12-08 13:43 UTC (permalink / raw)
To: Pavel A. Nekrasov; +Cc: Harald Welte, netfilter-devel, Patrick McHardy
[-- Attachment #1: Type: text/plain, Size: 978 bytes --]
On Wed, 2004-12-08 at 14:32 +0100, Pavel A. Nekrasov wrote:
> i got you doing the same.
>
> Evgeniy Polyakov wrote:
>
> >+ nts = netlink_kernel_create(NETLINK_NFLOG, NULL);
>
> drivers/w1/w1_int.c: dev->nls = netlink_kernel_create(NETLINK_NFLOG, NULL);
>
> NETLINK_NFLOG is used by ipt_ULOG, you can't use that socket because
> you are breaking compatibility. You have to use different sockets,
> call davem and request new ones.
No, ipt_osf used this number forever.
And it was discussed with Harald some time ago.
Allocating new socket number for any new driver that want to communicate
over netlink is badly broken idea.
I've created so called "kernel connector" aka ioctl-ng to solve this
problem, and this patch is flying around for some time, but until it
is
committed we should not break old compatibility issues.
> kind regards,
> Pavel
--
Evgeniy Polyakov
Crash is better than data corruption -- Arthur Grabowski
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [1/1] OSF: pom-ng - linux-2.6.
2004-12-08 10:58 [1/1] OSF: pom-ng - linux-2.6 Evgeniy Polyakov
2004-12-08 11:02 ` Evgeniy Polyakov
2004-12-08 13:32 ` Pavel A. Nekrasov
@ 2004-12-08 18:44 ` Patrick McHardy
2 siblings, 0 replies; 8+ messages in thread
From: Patrick McHardy @ 2004-12-08 18:44 UTC (permalink / raw)
To: johnpol; +Cc: Harald Welte, netfilter-devel
Evgeniy Polyakov wrote:
>Since OSF originally was created in 2.5 environment
>it is strange not to have 2.6 support for OSF.
>This(similar) patch was sent some time ago but was lost.
>Please apply.
>
>
Please send patches that apply -p1 in the patch-o-matic-ng directory
in the future. Your patch doesn't apply at all:
~/src/nf/svn/netfilter/trunk/patch-o-matic-ng/osf/linux-2.6/net/ipv4/netfilter$
patch -p6 </tmp/ipt_osf --dry-run
missing header for unified diff at line 3 of patch
(Stripping trailing CRs from patch.)
patching file ipt_osf.c
Hunk #1 succeeded at 52 with fuzz 2.
Hunk #2 FAILED at 77.
Hunk #3 FAILED at 154.
Hunk #4 FAILED at 185.
Hunk #5 FAILED at 414.
Hunk #6 FAILED at 603.
Hunk #7 FAILED at 616.
Hunk #8 FAILED at 636.
Hunk #9 FAILED at 855.
8 out of 9 hunks FAILED -- saving rejects to file ipt_osf.c.rej
To make osf fit for 2.6, you also need to handle non-linear skbs.
Regards
Patrick
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [1/1] OSF: pom-ng - linux-2.6.
2004-12-08 11:02 ` Evgeniy Polyakov
@ 2004-12-08 18:48 ` Patrick McHardy
2004-12-12 15:13 ` Evgeniy Polyakov
0 siblings, 1 reply; 8+ messages in thread
From: Patrick McHardy @ 2004-12-08 18:48 UTC (permalink / raw)
To: johnpol; +Cc: Harald Welte, netfilter-devel
Evgeniy Polyakov wrote:
>On Wed, 2004-12-08 at 13:58 +0300, Evgeniy Polyakov wrote:
>
>
>>Since OSF originally was created in 2.5 environment
>>it is strange not to have 2.6 support for OSF.
>>This(similar) patch was sent some time ago but was lost.
>>Please apply.
>>
>>Signed-off-by: Evgeniy Polyakov <johnpol@2ka.mipt.ru>
>>
>>
>
>My dear hands, please contact my brain before doing anything.
>Thanks.
>
>
And I need to read first before complaining :)
>Proper patch attached.
>
>
Still doesn't apply, it seems to be present already. The latest
change was two month ago.
~/src/nf/svn/netfilter/trunk/patch-o-matic-ng$ patch -p1 </tmp/pom.diff
--dry-run
(Stripping trailing CRs from patch.)
patching file osf/info
Reversed (or previously applied) patch detected! Assume -R? [n]
Apply anyway? [n]
Skipping patch.
1 out of 1 hunk ignored -- saving rejects to file osf/info.rej
The next patch would create the file
osf/linux-2.6/include/linux/netfilter_ipv4/ipt_osf.h,
which already exists! Assume -R? [n]
Apply anyway? [n]
Skipping patch.
1 out of 1 hunk ignored -- saving rejects to file
osf/linux-2.6/include/linux/netfilter_ipv4/ipt_osf.h.rej
The next patch would create the file
osf/linux-2.6/net/ipv4/netfilter/ipt_osf.c,
which already exists! Assume -R? [n]
Apply anyway? [n]
Skipping patch.
1 out of 1 hunk ignored -- saving rejects to file
osf/linux-2.6/net/ipv4/netfilter/ipt_osf.c.rej
The next patch would create the file
osf/linux-2.6/net/ipv4/netfilter/Kconfig.ladd,
which already exists! Assume -R? [n]
Apply anyway? [n]
Skipping patch.
1 out of 1 hunk ignored -- saving rejects to file
osf/linux-2.6/net/ipv4/netfilter/Kconfig.ladd.rej
The next patch would create the file
osf/linux-2.6/net/ipv4/netfilter/Makefile.ladd,
which already exists! Assume -R? [n]
Apply anyway? [n]
Skipping patch.
1 out of 1 hunk ignored -- saving rejects to file
osf/linux-2.6/net/ipv4/netfilter/Makefile.ladd.rej
Anyhow, it still needs to handle non-linear skbs. Have a look
at the other matches and their use of skb_header_pointer.
Regards
Patrick
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [1/1] OSF: pom-ng - linux-2.6.
2004-12-08 18:48 ` Patrick McHardy
@ 2004-12-12 15:13 ` Evgeniy Polyakov
2005-01-02 23:31 ` Patrick McHardy
0 siblings, 1 reply; 8+ messages in thread
From: Evgeniy Polyakov @ 2004-12-12 15:13 UTC (permalink / raw)
To: Patrick McHardy; +Cc: Harald Welte, netfilter-devel
[-- Attachment #1: Type: text/plain, Size: 1534 bytes --]
On Wed, 08 Dec 2004 19:48:44 +0100
Patrick McHardy <kaber@trash.net> wrote:
> Evgeniy Polyakov wrote:
>
> >On Wed, 2004-12-08 at 13:58 +0300, Evgeniy Polyakov wrote:
> >
> >
> >>Since OSF originally was created in 2.5 environment
> >>it is strange not to have 2.6 support for OSF.
> >>This(similar) patch was sent some time ago but was lost.
> >>Please apply.
> >>
> >>Signed-off-by: Evgeniy Polyakov <johnpol@2ka.mipt.ru>
> >>
> >>
> >
> >My dear hands, please contact my brain before doing anything.
> >Thanks.
> >
> >
> And I need to read first before complaining :)
>
> >Proper patch attached.
> >
> >
> Still doesn't apply, it seems to be present already. The latest
> change was two month ago.
Yep, my fault, I saw into the latest pom-ng.
...
> Anyhow, it still needs to handle non-linear skbs. Have a look
> at the other matches and their use of skb_header_pointer.
Sure.
Patch attached, although I do not quite understand what should be
done with a poor skb to move IP and TCP headers into the fragments...
P.S. patch was done against my own tree, but should be applied
against CVS, probably with some fuzz. I can not test it with the
latest CVS since pserver.netfilter.org:2401 is not accessible.
P.P.S. I do not have 2.4 sources but if 2.4 has skb_header_pointer
(as long as it has skb_copy_bits()) patch can be applied against it
as well, but path in diff should be changed. If needed it is attached
as well.
> Regards
> Patrick
Evgeniy Polyakov
Only failure makes us experts. -- Theo de Raadt
[-- Attachment #2: ipt_osf.patch --]
[-- Type: application/octet-stream, Size: 1704 bytes --]
--- orig/osf/linux/net/ipv4/netfilter/ipt_osf.c
+++ mod/osf/linux/net/ipv4/netfilter/ipt_osf.c
@@ -158,20 +158,30 @@
int *hotdrop)
{
struct ipt_osf_info *info = (struct ipt_osf_info *)matchinfo;
- struct iphdr *ip = skb->nh.iph;
- struct tcphdr *tcp;
+ struct iphdr _iph, *ip;
+ struct tcphdr _tcph, *tcp;
int fmatch = FMATCH_WRONG, fcount = 0;
unsigned long totlen, optsize = 0, window;
unsigned char df, *optp = NULL, *_optp = NULL;
+ unsigned char opts[MAX_IPOPTLEN];
char check_WSS = 0;
struct list_head *ent;
struct osf_finger *f;
+ int off;
- if (!ip || !info)
+ if (!info)
+ return 0;
+
+ off = 0;
+
+ ip = skb_header_pointer(skb, off, sizeof(_iph), &_iph);
+ if (!ip)
return 0;
- tcp = (struct tcphdr *)((u_int32_t *)ip + ip->ihl);
-
+ tcp = skb_header_pointer(skb, off + ip->ihl * 4, sizeof(_tcph), &_tcph);
+ if (!tcp)
+ return 0;
+
if (!tcp->syn)
return 0;
@@ -181,8 +191,16 @@
if (tcp->doff*4 > sizeof(struct tcphdr))
{
- _optp = optp = (char *)(tcp+1);
optsize = tcp->doff*4 - sizeof(struct tcphdr);
+
+ if (optsize > sizeof(opts))
+ {
+ log("%s: BUG: too big options size: optsize=%lu, max=%d.\n",
+ __func__, optsize, sizeof(opts));
+ optsize = sizeof(opts);
+ }
+
+ _optp = optp = skb_header_pointer(skb, off + ip->ihl*4 + sizeof(_tcph), optsize, opts);
}
/* Actually we can create hash/table of all genres and search
@@ -375,7 +393,7 @@
if (optp)
{
optsize = tcp->doff * 4 - sizeof(struct tcphdr);
- if (skb_copy_bits(skb, ip->ihl*4 + sizeof(struct tcphdr),
+ if (skb_copy_bits(skb, off + ip->ihl*4 + sizeof(struct tcphdr),
opt, optsize) < 0)
{
if (info->flags & IPT_OSF_LOG)
[-- Attachment #3: ipt_osf.patch-2.4 --]
[-- Type: application/octet-stream, Size: 1704 bytes --]
--- orig/osf/linux/net/ipv4/netfilter/ipt_osf.c
+++ mod/osf/linux/net/ipv4/netfilter/ipt_osf.c
@@ -158,20 +158,30 @@
int *hotdrop)
{
struct ipt_osf_info *info = (struct ipt_osf_info *)matchinfo;
- struct iphdr *ip = skb->nh.iph;
- struct tcphdr *tcp;
+ struct iphdr _iph, *ip;
+ struct tcphdr _tcph, *tcp;
int fmatch = FMATCH_WRONG, fcount = 0;
unsigned long totlen, optsize = 0, window;
unsigned char df, *optp = NULL, *_optp = NULL;
+ unsigned char opts[MAX_IPOPTLEN];
char check_WSS = 0;
struct list_head *ent;
struct osf_finger *f;
+ int off;
- if (!ip || !info)
+ if (!info)
+ return 0;
+
+ off = 0;
+
+ ip = skb_header_pointer(skb, off, sizeof(_iph), &_iph);
+ if (!ip)
return 0;
- tcp = (struct tcphdr *)((u_int32_t *)ip + ip->ihl);
-
+ tcp = skb_header_pointer(skb, off + ip->ihl * 4, sizeof(_tcph), &_tcph);
+ if (!tcp)
+ return 0;
+
if (!tcp->syn)
return 0;
@@ -181,8 +191,16 @@
if (tcp->doff*4 > sizeof(struct tcphdr))
{
- _optp = optp = (char *)(tcp+1);
optsize = tcp->doff*4 - sizeof(struct tcphdr);
+
+ if (optsize > sizeof(opts))
+ {
+ log("%s: BUG: too big options size: optsize=%lu, max=%d.\n",
+ __func__, optsize, sizeof(opts));
+ optsize = sizeof(opts);
+ }
+
+ _optp = optp = skb_header_pointer(skb, off + ip->ihl*4 + sizeof(_tcph), optsize, opts);
}
/* Actually we can create hash/table of all genres and search
@@ -375,7 +393,7 @@
if (optp)
{
optsize = tcp->doff * 4 - sizeof(struct tcphdr);
- if (skb_copy_bits(skb, ip->ihl*4 + sizeof(struct tcphdr),
+ if (skb_copy_bits(skb, off + ip->ihl*4 + sizeof(struct tcphdr),
opt, optsize) < 0)
{
if (info->flags & IPT_OSF_LOG)
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [1/1] OSF: pom-ng - linux-2.6.
2004-12-12 15:13 ` Evgeniy Polyakov
@ 2005-01-02 23:31 ` Patrick McHardy
0 siblings, 0 replies; 8+ messages in thread
From: Patrick McHardy @ 2005-01-02 23:31 UTC (permalink / raw)
To: johnpol; +Cc: Harald Welte, netfilter-devel
Evgeniy Polyakov wrote:
>On Wed, 08 Dec 2004 19:48:44 +0100
>Patrick McHardy <kaber@trash.net> wrote:
>
>>Anyhow, it still needs to handle non-linear skbs. Have a look
>>at the other matches and their use of skb_header_pointer.
>>
>
>Sure.
>Patch attached, although I do not quite understand what should be
>done with a poor skb to move IP and TCP headers into the fragments...
>
Applied, sorry for the delay. Copying the ip-header is not necessary,
but the TCP header may be nonlinear because of defragmentation.
>P.P.S. I do not have 2.4 sources but if 2.4 has skb_header_pointer
>(as long as it has skb_copy_bits()) patch can be applied against it
>as well, but path in diff should be changed. If needed it is attached
>as well.
>
2.4 doesn't need this change, netfilter always gets linearized skbs.
Regards
Patrick
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2005-01-02 23:31 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-12-08 10:58 [1/1] OSF: pom-ng - linux-2.6 Evgeniy Polyakov
2004-12-08 11:02 ` Evgeniy Polyakov
2004-12-08 18:48 ` Patrick McHardy
2004-12-12 15:13 ` Evgeniy Polyakov
2005-01-02 23:31 ` Patrick McHardy
2004-12-08 13:32 ` Pavel A. Nekrasov
2004-12-08 13:43 ` Evgeniy Polyakov
2004-12-08 18:44 ` Patrick McHardy
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.