cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

nf_nat_amanda.c (2518B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/* Amanda extension for TCP NAT alteration.
      3 * (C) 2002 by Brian J. Murrell <netfilter@interlinx.bc.ca>
      4 * based on a copy of HW's ip_nat_irc.c as well as other modules
      5 * (C) 2006-2012 Patrick McHardy <kaber@trash.net>
      6 */
      7
      8#include <linux/kernel.h>
      9#include <linux/module.h>
     10#include <linux/skbuff.h>
     11#include <linux/udp.h>
     12
     13#include <net/netfilter/nf_conntrack_helper.h>
     14#include <net/netfilter/nf_conntrack_expect.h>
     15#include <net/netfilter/nf_nat_helper.h>
     16#include <linux/netfilter/nf_conntrack_amanda.h>
     17
     18#define NAT_HELPER_NAME "amanda"
     19
     20MODULE_AUTHOR("Brian J. Murrell <netfilter@interlinx.bc.ca>");
     21MODULE_DESCRIPTION("Amanda NAT helper");
     22MODULE_LICENSE("GPL");
     23MODULE_ALIAS_NF_NAT_HELPER(NAT_HELPER_NAME);
     24
     25static struct nf_conntrack_nat_helper nat_helper_amanda =
     26	NF_CT_NAT_HELPER_INIT(NAT_HELPER_NAME);
     27
     28static unsigned int help(struct sk_buff *skb,
     29			 enum ip_conntrack_info ctinfo,
     30			 unsigned int protoff,
     31			 unsigned int matchoff,
     32			 unsigned int matchlen,
     33			 struct nf_conntrack_expect *exp)
     34{
     35	char buffer[sizeof("65535")];
     36	u_int16_t port;
     37
     38	/* Connection comes from client. */
     39	exp->saved_proto.tcp.port = exp->tuple.dst.u.tcp.port;
     40	exp->dir = IP_CT_DIR_ORIGINAL;
     41
     42	/* When you see the packet, we need to NAT it the same as the
     43	 * this one (ie. same IP: it will be TCP and master is UDP). */
     44	exp->expectfn = nf_nat_follow_master;
     45
     46	/* Try to get same port: if not, try to change it. */
     47	for (port = ntohs(exp->saved_proto.tcp.port); port != 0; port++) {
     48		int res;
     49
     50		exp->tuple.dst.u.tcp.port = htons(port);
     51		res = nf_ct_expect_related(exp, 0);
     52		if (res == 0)
     53			break;
     54		else if (res != -EBUSY) {
     55			port = 0;
     56			break;
     57		}
     58	}
     59
     60	if (port == 0) {
     61		nf_ct_helper_log(skb, exp->master, "all ports in use");
     62		return NF_DROP;
     63	}
     64
     65	sprintf(buffer, "%u", port);
     66	if (!nf_nat_mangle_udp_packet(skb, exp->master, ctinfo,
     67				      protoff, matchoff, matchlen,
     68				      buffer, strlen(buffer))) {
     69		nf_ct_helper_log(skb, exp->master, "cannot mangle packet");
     70		nf_ct_unexpect_related(exp);
     71		return NF_DROP;
     72	}
     73	return NF_ACCEPT;
     74}
     75
     76static void __exit nf_nat_amanda_fini(void)
     77{
     78	nf_nat_helper_unregister(&nat_helper_amanda);
     79	RCU_INIT_POINTER(nf_nat_amanda_hook, NULL);
     80	synchronize_rcu();
     81}
     82
     83static int __init nf_nat_amanda_init(void)
     84{
     85	BUG_ON(nf_nat_amanda_hook != NULL);
     86	nf_nat_helper_register(&nat_helper_amanda);
     87	RCU_INIT_POINTER(nf_nat_amanda_hook, help);
     88	return 0;
     89}
     90
     91module_init(nf_nat_amanda_init);
     92module_exit(nf_nat_amanda_fini);