Hi, On k, jan 22, 2008 at 12:22:56 +0100, Jan Engelhardt wrote: > This is how it would look then: > commit 807482809f619a167d3dd349553d621ee4cd3b48 > Author: Jan Engelhardt <jengelh@xxxxxxxxxxxxxxx> > Date: Mon Jan 21 14:08:27 2008 +0100 > > [NETFILTER]: xt_socket: input path processing > > tproxy adds a function for socket lookup; xt_socket can use this to > be usable in the PREROUTING and INPUT chains. > (This code has not been compile tested, but serves as an example.) > > Signed-off-by: Jan Engelhardt <jengelh@xxxxxxxxxxxxxxx> > > diff --git a/net/netfilter/xt_socket.c b/net/netfilter/xt_socket.c > index 07d681c..1deacb2 100644 > --- a/net/netfilter/xt_socket.c > +++ b/net/netfilter/xt_socket.c #ifdef CONFIG_NETFILTER_TPROXY #include <net/netfilter/nf_tproxy_core.h> #include <net/netfilter/ipv4/nf_defrag_ipv4.h> #endif > @@ -76,17 +76,46 @@ owner_mt6_v0(const struct sk_buff *skb, const struct net_device *in, > return true; > } > > +static struct sock * > +socket_mt_getsock(const struct sk_buff *skb, const struct net_device *in) > +{ > +#ifdef CONFIG_NETFILTER_TPROXY > + const struct iphdr *iph = ip_hdr(skb); > + const struct udphdr *udph; > + struct udphdr udphdr; > + > + if (iph->protocol != IPPROTO_TCP && iph->protocol != IPPROTO_UDP && > + iph->protocol != IPPROTO_UDPLITE) > + return false; Should return NULL here. > + > + /* > + * All the protocols that are currently supported (see above if > + * statement) have source and destination port at the same position, > + * so we can use this udph shortcut. Why UDP? The struct is the > + * smallest. > + */ > + udph = skb_header_pointer(skb, ip_hdrlen(skb), udphdr, sizeof(udphdr)); > + if (udph == NULL) > + return NULL; > + > + return nf_tproxy_get_v4(iph->protocol, iph->saddr, iph->daddr, > + hp->source, hp->dest, in, false); > +#endif > + return NULL; > +} > + > +static void socket_mt_putsock(struct sock *sk) Inline? > +{ > +#ifdef CONFIG_NETFILTER_TPROXY > + nf_tproxy_put_sock(sk); > +#endif > +} > + > static bool > -socket_mt(const struct sk_buff *skb, const struct net_device *in, > - const struct net_device *out, const struct xt_match *match, > - const void *matchinfo, int offset, unsigned int protoff, > - bool *hotdrop) > +socket_mt_match(const struct sock *sk, const struct xt_socket_mtinfo *info) > { > - const struct xt_socket_mtinfo *info = matchinfo; > const struct file *filp; > - const struct sock *sk; > > - sk = skb->sk; > if (sk == NULL || sk->sk_socket == NULL) > return (info->match ^ info->invert) == 0; > else if (info->match & info->invert & XT_SOCKET_EXISTS) > @@ -117,6 +146,25 @@ socket_mt(const struct sk_buff *skb, const struct net_device *in, > } > > static bool > +socket_mt(const struct sk_buff *skb, const struct net_device *in, > + const struct net_device *out, const struct xt_match *match, > + const void *matchinfo, int offset, unsigned int protoff, > + bool *hotdrop) > +{ > + struct sock *tpsk = NULL; > + const struct sock *sk; > + bool ret; > + > + sk = skb->sk; > + if (sk == NULL && in != NULL && match->family == AF_INET) > + sk = tpsk = socket_mt_getsock(skb, in); > + ret = socket_mt_match(sk, matchinfo); > + if (tpsk != NULL) > + socket_mt_putsock(tpsk); > + return ret; > +} > + > +static bool > owner_mt_check_v0(const char *tablename, const void *ip, > const struct xt_match *match, void *matchinfo, > unsigned int hook_mask) > @@ -149,6 +197,22 @@ owner_mt6_check_v0(const char *tablename, const void *ip, > return true; > } > > +static bool > +socket_mt4_check(const char *tablename, const void *ip, > + const struct xt_match *match, void *matchinfo, > + unsigned int hook_mask) > +{ > +#ifndef CONFIG_NETFILTER_TPROXY > + if (hook_mask & (NF_INET_PRE_ROUTING | NF_INET_LOCAL_IN)) { > + printk(KERN_WARNING KBUILD_MODNAME > + ": Use in PREROUTING and INPUT chains only " > + "possible with tproxy\n"); > + return false; > + } > +#endif > + return true; > +} > + > static struct xt_match socket_mt_reg[] __read_mostly = { > { > .name = "owner", > @@ -178,7 +242,10 @@ static struct xt_match socket_mt_reg[] __read_mostly = { > .family = AF_INET, > .match = socket_mt, > .matchsize = sizeof(struct xt_socket_mtinfo), > - .hooks = (1 << NF_INET_LOCAL_OUT) | > + .checkentry = socket_mt4_check, > + .hooks = (1 << NF_INET_PRE_ROUTING) | > + (1 << NF_INET_LOCAL_IN) | > + (1 << NF_INET_LOCAL_OUT) | > (1 << NF_INET_POST_ROUTING), > .me = THIS_MODULE, > }, > @@ -196,6 +263,13 @@ static struct xt_match socket_mt_reg[] __read_mostly = { > > static int __init socket_mt_init(void) > { > +#ifdef CONFIG_NETFILTER_TPROXY nf_defrag_ipv4_enable(); As socket can be used without conntrack but you _need_ the first few bytes of the IP datagram to be able to do the socket lookup you have to defrag. This is just another ugly kludge... > + printk(KERN_INFO KBUILD_MODNAME > + ": Input path socket lookup for IPv4 via tproxy.\n"); > +#else > + printk(KERN_INFO KBUILD_MODNAME > + ": No socket lookup for PREROUTING/INPUT available.\n"); > +#endif > return xt_register_matches(socket_mt_reg, ARRAY_SIZE(socket_mt_reg)); > } > > -- KOVACS Krisztian - To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html