All of lore.kernel.org
 help / color / mirror / Atom feed
* [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.