/*
 *
 * module-wide functions, mostly boilerplate
 *
 * Copyright (c) 2013-2014 Andrew Yourtchenko <ayourtch@gmail.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2
 * as published by the Free Software Foundation
 *
 * 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.
 *
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/ip.h>
#include <linux/icmp.h>
#include <linux/inet.h>
#include <linux/icmpv6.h>
#include <linux/inetdevice.h>
#include <linux/types.h>
#include <linux/netfilter_ipv4.h>


#include <linux/fs.h>           // for basic filesystem
#include <linux/proc_fs.h>      // for the proc filesystem
#include <linux/seq_file.h>     // for sequence files

#include <net/ip.h>
#include <net/tcp.h>
#include <net/udp.h>
#include <net/icmp.h>
#include <net/route.h>
#include <net/ip6_route.h>

#include <net/ipv6.h>

#include "nat46-core.h"
#include "nat46-netdev.h"

#define NAT46_PROC_NAME	"nat46"
#define NAT46_CONTROL_PROC_NAME "control"

#ifndef NAT46_VERSION
#define NAT46_VERSION __DATE__ " " __TIME__
#endif

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Andrew Yourtchenko <ayourtch@gmail.com>");
MODULE_DESCRIPTION("NAT46 stateless translation");

int debug = 0;
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "debugging messages level (default=1)");
bool add_dummy_header = 0;
module_param(add_dummy_header, bool, 0);
MODULE_PARM_DESC(add_dummy_header, "Add dummy fragment header");

static DEFINE_MUTEX(add_del_lock);
static struct proc_dir_entry *nat46_proc_entry;
static struct proc_dir_entry *nat46_proc_parent;


static int nat46_proc_show(struct seq_file *m, void *v)
{
	nat64_show_all_configs(m);
	return 0;
}


static int nat46_proc_open(struct inode *inode, struct file *file)
{
	return single_open(file, nat46_proc_show, NULL);
}

static char *get_devname(char **ptail)
{
	const int maxlen = IFNAMSIZ-1;
	char *devname = get_next_arg(ptail);
	if(strlen(devname) > maxlen) {
		printk(KERN_INFO "nat46: '%s' is "
			"longer than %d chars, truncating\n", devname, maxlen);
		devname[maxlen] = 0;
	}
	return devname;
}

static ssize_t nat46_proc_write(struct file *file, const char __user *buffer,
                              size_t count, loff_t *ppos)
{
	char *buf = NULL;
	char *tail = NULL;
	char *devname = NULL;
	char *arg_name = NULL;

	buf = kmalloc(sizeof(char) * (count + 1), GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

	if (copy_from_user(buf, buffer, count)) {
		kfree(buf);
		return -EFAULT;
	}
	tail = buf;
	buf[count] = '\0';
	if( (count > 0) && (buf[count-1] == '\n') ) {
		buf[count-1] = '\0';
	}

	while (NULL != (arg_name = get_next_arg(&tail))) {
		if (0 == strcmp(arg_name, "add")) {
			devname = get_devname(&tail);
			printk(KERN_INFO "nat46: adding device (%s)\n", devname);
			mutex_lock(&add_del_lock);
			nat46_create(devname);
			mutex_unlock(&add_del_lock);
		} else if (0 == strcmp(arg_name, "del")) {
			devname = get_devname(&tail);
			printk(KERN_INFO "nat46: deleting device (%s)\n", devname);
			mutex_lock(&add_del_lock);
			nat46_destroy(devname);
			mutex_unlock(&add_del_lock);
		} else if (0 == strcmp(arg_name, "config")) {
			devname = get_devname(&tail);
			printk(KERN_INFO "nat46: configure device (%s) with '%s'\n", devname, tail);
			mutex_lock(&add_del_lock);
			nat46_configure(devname, tail);
			mutex_unlock(&add_del_lock);
		} else if (0 == strcmp(arg_name, "insert")) {
			devname = get_devname(&tail);
			printk(KERN_INFO "nat46: insert new rule into device (%s) with '%s'\n", devname, tail);
			mutex_lock(&add_del_lock);
			nat46_insert(devname, tail);
			mutex_unlock(&add_del_lock);
		}
	}

	kfree(buf);
	return count;
}

static const struct file_operations nat46_proc_fops = {
	.owner		= THIS_MODULE,
	.open		= nat46_proc_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
	.write		= nat46_proc_write,
};


int create_nat46_proc_entry(void) {
	nat46_proc_parent = proc_mkdir(NAT46_PROC_NAME, init_net.proc_net);
	if (nat46_proc_parent) {
		nat46_proc_entry = proc_create(NAT46_CONTROL_PROC_NAME, 0644, nat46_proc_parent, &nat46_proc_fops );
		if(!nat46_proc_entry) {
			printk(KERN_INFO "Error creating proc entry");
			return -ENOMEM;
		}
	}
	return 0;
}


static int __init nat46_init(void)
{
	int ret = 0;

	printk("nat46: module (version %s) loaded.\n", NAT46_VERSION);
	ret = create_nat46_proc_entry();
	if(ret) {
		goto error;
	}
	return 0;

error:
	return ret;
}

static void __exit nat46_exit(void)
{
	nat46_destroy_all();
	if (nat46_proc_parent) {
		if (nat46_proc_entry) {
			remove_proc_entry(NAT46_CONTROL_PROC_NAME, nat46_proc_parent);
		}
		remove_proc_entry(NAT46_PROC_NAME, init_net.proc_net);
	}
	printk("nat46: module unloaded.\n");
}

module_init(nat46_init);
module_exit(nat46_exit);


