Re: [PATCH 3/3 nft] src: osf: import nfnl_osf.c to load osf fingerprints

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

 



On Fri, Aug 10, 2018 at 03:02:00PM +0200, Fernando Fernandez Mancera wrote:
> Import iptables/utils/nfnl_osf.c into nftables tree with some changes in order
> to load OS fingerprints automatically from pf.os file.
> 
> Signed-off-by: Fernando Fernandez Mancera <ffmancera@xxxxxxxxxx>
> ---
>  include/linux/netfilter/nfnetlink_osf.h | 119 +++++++
>  include/nfnl_osf.h                      |   6 +
>  include/osf.h                           |   2 +
>  src/Makefile.am                         |   1 +
>  src/nfnl_osf.c                          | 449 ++++++++++++++++++++++++
>  src/osf.c                               |   2 +
>  src/rule.c                              |   5 +
>  7 files changed, 584 insertions(+)
>  create mode 100644 include/linux/netfilter/nfnetlink_osf.h
>  create mode 100644 include/nfnl_osf.h
>  create mode 100644 src/nfnl_osf.c
> 
> diff --git a/include/linux/netfilter/nfnetlink_osf.h b/include/linux/netfilter/nfnetlink_osf.h
> new file mode 100644
> index 0000000..15a39d2
> --- /dev/null
> +++ b/include/linux/netfilter/nfnetlink_osf.h
> @@ -0,0 +1,119 @@
> +#ifndef _NF_OSF_H
> +#define _NF_OSF_H
> +
> +#include <linux/types.h>
> +
> +#define MAXGENRELEN	32
> +
> +#define NF_OSF_GENRE	(1 << 0)
> +#define NF_OSF_TTL	(1 << 1)
> +#define NF_OSF_LOG	(1 << 2)
> +#define NF_OSF_INVERT	(1 << 3)
> +
> +#define NF_OSF_LOGLEVEL_ALL		0	/* log all matched fingerprints */
> +#define NF_OSF_LOGLEVEL_FIRST		1	/* log only the first matced fingerprint */
> +#define NF_OSF_LOGLEVEL_ALL_KNOWN	2	/* do not log unknown packets */
> +
> +#define NF_OSF_TTL_TRUE			0	/* True ip and fingerprint TTL comparison */
> +
> +/* Check if ip TTL is less than fingerprint one */
> +#define NF_OSF_TTL_LESS			1
> +
> +/* Do not compare ip and fingerprint TTL at all */
> +#define NF_OSF_TTL_NOCHECK		2
> +
> +#define NF_OSF_FLAGMASK		(NF_OSF_GENRE | NF_OSF_TTL | \
> +				 NF_OSF_LOG | NF_OSF_INVERT)
> +/* Wildcard MSS (kind of).
> + * It is used to implement a state machine for the different wildcard values
> + * of the MSS and window sizes.
> + */
> +struct nf_osf_wc {
> +	__u32	wc;
> +	__u32	val;
> +};
> +
> +/* This struct represents IANA options
> + * http://www.iana.org/assignments/tcp-parameters
> + */
> +struct nf_osf_opt {
> +	__u16			kind, length;
> +	struct nf_osf_wc	wc;
> +};
> +
> +struct nf_osf_info {
> +	char	genre[MAXGENRELEN];
> +	__u32	len;
> +	__u32	flags;
> +	__u32	loglevel;
> +	__u32	ttl;
> +};
> +
> +struct nf_osf_user_finger {
> +	struct nf_osf_wc	wss;
> +
> +	__u8	ttl, df;
> +	__u16	ss, mss;
> +	__u16	opt_num;
> +
> +	char	genre[MAXGENRELEN];
> +	char	version[MAXGENRELEN];
> +	char	subtype[MAXGENRELEN];
> +
> +	/* MAX_IPOPTLEN is maximum if all options are NOPs or EOLs */
> +	struct nf_osf_opt	opt[MAX_IPOPTLEN];
> +};
> +
> +struct nf_osf_nlmsg {
> +	struct nf_osf_user_finger	f;
> +	struct iphdr			ip;
> +	struct tcphdr			tcp;
> +};
> +
> +/* Defines for IANA option kinds */
> +enum iana_options {
> +	OSFOPT_EOL = 0,		/* End of options */
> +	OSFOPT_NOP,		/* NOP */
> +	OSFOPT_MSS,		/* Maximum segment size */
> +	OSFOPT_WSO,		/* Window scale option */
> +	OSFOPT_SACKP,		/* SACK permitted */
> +	OSFOPT_SACK,		/* SACK */
> +	OSFOPT_ECHO,
> +	OSFOPT_ECHOREPLY,
> +	OSFOPT_TS,		/* Timestamp option */
> +	OSFOPT_POCP,		/* Partial Order Connection Permitted */
> +	OSFOPT_POSP,		/* Partial Order Service Profile */
> +
> +	/* Others are not used in the current OSF */
> +	OSFOPT_EMPTY = 255,
> +};
> +
> +/*
> + * Initial window size option state machine: multiple of mss, mtu or
> + * plain numeric value. Can also be made as plain numeric value which
> + * is not a multiple of specified value.
> + */
> +enum nf_osf_window_size_options {
> +	OSF_WSS_PLAIN	= 0,
> +	OSF_WSS_MSS,
> +	OSF_WSS_MTU,
> +	OSF_WSS_MODULO,
> +	OSF_WSS_MAX,
> +};
> +
> +enum nf_osf_attr_type {
> +	OSF_ATTR_UNSPEC,
> +	OSF_ATTR_FINGER,
> +	OSF_ATTR_MAX,
> +};
> +
> +/*
> + * Add/remove fingerprint from the kernel.
> + */
> +enum nf_osf_msg_types {
> +	OSF_MSG_ADD,
> +	OSF_MSG_REMOVE,
> +	OSF_MSG_MAX,
> +};
> +
> +#endif /* _NF_OSF_H */
> diff --git a/include/nfnl_osf.h b/include/nfnl_osf.h
> new file mode 100644
> index 0000000..d9287e9
> --- /dev/null
> +++ b/include/nfnl_osf.h
> @@ -0,0 +1,6 @@
> +#ifndef _NFNL_OSF_H
> +#define _NFNL_OSF_H
> +
> +int nfnl_osf_load_fingerprints(struct netlink_ctx *ctx, int del);
> +
> +#endif	/* _NFNL_OSF_H */
> diff --git a/include/osf.h b/include/osf.h
> index 715b04e..0a35b07 100644
> --- a/include/osf.h
> +++ b/include/osf.h
> @@ -1,6 +1,8 @@
>  #ifndef NFTABLES_OSF_H
>  #define NFTABLES_OSF_H
>  
> +bool osf_init;

I think you can probably place osf_init in struct netlink_ctx?

>  struct expr *osf_expr_alloc(const struct location *loc);
>  
>  #endif /* NFTABLES_OSF_H */
> diff --git a/src/Makefile.am b/src/Makefile.am
> index ed3640e..e569029 100644
> --- a/src/Makefile.am
> +++ b/src/Makefile.am
> @@ -57,6 +57,7 @@ libnftables_la_SOURCES =			\
>  		services.c			\
>  		mergesort.c			\
>  		osf.c				\
> +		nfnl_osf.c			\
>  		tcpopt.c			\
>  		socket.c			\
>  		libnftables.c
> diff --git a/src/nfnl_osf.c b/src/nfnl_osf.c
> new file mode 100644
> index 0000000..07bf682
> --- /dev/null
> +++ b/src/nfnl_osf.c
> @@ -0,0 +1,449 @@
> +/*
> + * Copyright (c) 2005 Evgeniy Polyakov <johnpol@xxxxxxxxxx>
> + *
> + *
> + * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
> + */
> +
> +#include <sys/time.h>
> +
> +#include <ctype.h>
> +#include <errno.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <time.h>
> +
> +#include <netinet/ip.h>
> +#include <netinet/tcp.h>
> +
> +#include <linux/unistd.h>
> +
> +#include <libmnl/libmnl.h>
> +
> +#include <linux/netfilter/nfnetlink.h>
> +#include <linux/netfilter/nfnetlink_osf.h>
> +#include <mnl.h>
> +#include <nfnl_osf.h>
> +
> +#define OPTDEL			','
> +#define OSFPDEL 		':'
> +#define MAXOPTSTRLEN		128
> +
> +static struct nf_osf_opt IANA_opts[] = {
> +	{ .kind = 0, .length = 1,},
> +	{ .kind=1, .length=1,},
> +	{ .kind=2, .length=4,},
> +	{ .kind=3, .length=3,},
> +	{ .kind=4, .length=2,},
> +	{ .kind=5, .length=1,},		/* SACK length is not defined */
> +	{ .kind=6, .length=6,},
> +	{ .kind=7, .length=6,},
> +	{ .kind=8, .length=10,},
> +	{ .kind=9, .length=2,},
> +	{ .kind=10, .length=3,},
> +	{ .kind=11, .length=1,},		/* CC: Suppose 1 */
> +	{ .kind=12, .length=1,},		/* the same */
> +	{ .kind=13, .length=1,},		/* and here too */
> +	{ .kind=14, .length=3,},
> +	{ .kind=15, .length=1,},		/* TCP Alternate Checksum Data. Length is not defined */
> +	{ .kind=16, .length=1,},
> +	{ .kind=17, .length=1,},
> +	{ .kind=18, .length=3,},
> +	{ .kind=19, .length=18,},
> +	{ .kind=20, .length=1,},
> +	{ .kind=21, .length=1,},
> +	{ .kind=22, .length=1,},
> +	{ .kind=23, .length=1,},
> +	{ .kind=24, .length=1,},
> +	{ .kind=25, .length=1,},
> +	{ .kind=26, .length=1,},
> +};
> +
> +static void uloga(const char *f, struct netlink_ctx *ctx, ...)
> +{
> +	if (!(ctx->debug_mask & NFT_DEBUG_NETLINK))
> +		return;
> +
> +	nft_print(ctx->octx, "%s", f);
> +}

I think you can use uloga() all the time, so you can remove ulog()
function.

> +static void ulog(const char *f, struct netlink_ctx *ctx, ...)
> +{
> +	char str[64];
> +	struct tm tm;
> +	struct timeval tv;
> +
> +	gettimeofday(&tv, NULL);
> +	localtime_r((time_t *)&tv.tv_sec, &tm);
> +	strftime(str, sizeof(str), "%F %R:%S", &tm);
> +
> +	if (!(ctx->debug_mask & NFT_DEBUG_NETLINK))
> +		return;
> +
> +	nft_print(ctx->octx, "%s.%lu %ld %s", str, tv.tv_usec,
> +		  syscall(__NR_gettid), f);
> +}
> +
> +#define ulog_err(f, ctx, a...) uloga(f ": %s [%d].\n", ctx, ##a, strerror(errno), errno)

And this macro too.

Other than that, this looks good to me, thanks.



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

  Powered by Linux