/*
 *
 *			   IPSEC for Linux
 *		         Preliminary Release
 * 
 *	 Copyright (C) 1996, 1997, John Ioannidis <ji@hol.gr>
 *
 * Changes by Angelos D. Keromytis and Niels Provos
 * ported from OpenBSD 2.2 by Petr Novak, <pn@i.cz>
 * 
 * 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
 *
 */

#include <linux/config.h>
#include <asm/segment.h>
#include <asm/system.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/config.h>

#include <linux/socket.h>
#include <linux/sockios.h>
#include <linux/in.h>
#include <linux/inet.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/icmp.h>
#include <linux/udp.h>
#include <net/ip.h>
#include <net/protocol.h>
#include <net/route.h>
#include <net/tcp.h>
#include <net/udp.h>
#include <net/sock.h>
#include <net/icmp.h>

#include <net/checksum.h>

#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/miscdevice.h>

#include <linux/skbuff.h>
#include <linux/proc_fs.h>
#include <linux/stat.h>

#include <net/netlink.h>
#include <unistd.h>
#include <linux/random.h>
#include "radij.h"
#include "ipsec_encap.h"
#include "ipsec_radij.h"
#include "ipsec_netlink.h"
#include "ipsec_xform.h"
#include "ipsec_ipe4.h"

struct sk_buff *
ipe4_input(struct sk_buff *skb, struct tdb *tdbp)
{
	printk("ipe4_input: why was I called?\n");
	
	return skb;
}

int
ipe4_attach(void)
{
	printk("ipe4_attach: called.\n");
	return 0;
}

/*
 * ipe4_init() is called when an SPI is being set up. It interprets the
 * encap_msghdr present in m, and sets up the transformation data.
 * In our case, all the setup has already been done in SETSPI processing.
 */

int
ipe4_init(struct tdb *tdbp, struct xformsw *xsp, struct encap_msghdr *em)
{
	tdbp->tdb_xform = xsp;

	return 0;
}

int ipe4_zeroize(struct tdb *tdpb)
{
	return 0;
}

int ipe4_print(void *xdat, char *buf)
{
	int size;
	
	size = sprintf(buf, "[nothing]");
	return size;
}

int
ipe4_room(struct tdb *tp, int iphlen, int tlen, int *hr, int *tr)
{
	*hr += sizeof(struct iphdr);
	*tr += 0;
	return 0;
}

int ipe4_output(struct sk_buff *skb, struct tdb *tdbp)
{

	struct iphdr *iph;

	skb->h.iph = (struct iphdr *) skb_push(skb, sizeof (struct iphdr));

	/*
	 *	Push down and install the IPIP header (from new_tunnel.c)
	 */
	 
	iph 			=	skb->h.iph;
	iph->version		= 	4;
	iph->tos		=	skb->ip_hdr->tos;
	if (tdbp->tdb_flags & TDBF_SAME_TTL)
		iph->ttl	=	skb->ip_hdr->ttl;
	else if (tdbp->tdb_ttl == 0)
		iph->ttl	=	64; /* XXX should be from ie. ip_statistics.IpDefaultTTL */
	else
		iph->ttl	=	tdbp->tdb_ttl;
	iph->frag_off		=	skb->ip_hdr->frag_off & ~(IP_MF|IP_OFFSET);	/* keep C and DF as in OpenBSD */
	iph->daddr		=	tdbp->tdb_odst.s_addr;
	iph->saddr		=	tdbp->tdb_osrc.s_addr;
	iph->protocol		=	IPPROTO_IPIP;
	iph->ihl		=	5;
	iph->tot_len		=	htons(skb->len);
	get_random_bytes((caddr_t *)&(iph->id), sizeof(iph->id));
	skb->ip_hdr 		=	skb->h.iph;

	iph->check = 0;
	iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);

	return 0;
}
