/* 
 * OpenGGSN - Gateway GPRS Support Node
 * Copyright (C) 2002, 2003, 2004 Mondru AB.
 * 
 * The contents of this file may be used under the terms of the GNU
 * General Public License Version 2, provided that the above copyright
 * notice and this permission notice is included in all copies or
 * substantial portions of the software.
 * 
 */

/* ggsn.c
 *
 */

#ifdef __linux__
#define _GNU_SOURCE 1		/* strdup() prototype, broken arpa/inet.h */
#endif

#include "../config.h"

#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif

#include <syslog.h>
#include <ctype.h>
#include <netdb.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>

#include <errno.h>

#include <time.h>

#include "../lib/tun.h"
#include "../lib/ippool.h"
#include "../lib/syserr.h"
#include "../gtp/pdp.h"
#include "../gtp/gtp.h"
#include "cmdline.h"

int end = 0;
int maxfd = 0;			/* For select()            */

struct in_addr listen_;
struct in_addr netaddr, destaddr, net, mask;	/* Network interface       */
struct in_addr dns1, dns2;	/* PCO DNS address         */
char *ipup, *ipdown;		/* Filename of scripts     */
int debug;			/* Print debug output      */
struct ul255_t pco;
struct ul255_t qos;
struct ul255_t apn;

struct gsn_t *gsn;		/* GSN instance            */
struct tun_t *tun;		/* TUN instance            */
struct ippool_t *ippool;	/* Pool of IP addresses    */

/* To exit gracefully. Used with GCC compilation flag -pg and gprof */
void signal_handler(int s)
{
	if (debug)
		printf("Received signal %d, exiting.\n", s);
	end = 1;
}

/* Used to write process ID to file. Assume someone else will delete */
void log_pid(char *pidfile)
{
	FILE *file;
	mode_t oldmask;

	oldmask = umask(022);
	file = fopen(pidfile, "w");
	umask(oldmask);
	if (!file) {
		sys_err(LOG_ERR, __FILE__, __LINE__, 0,
			"Failed to create process ID file: %s!", pidfile);
		return;
	}
	fprintf(file, "%d\n", (int)getpid());
	fclose(file);
}

#if defined(__sun__)
int daemon(int nochdir, int noclose)
{
	int fd;

	switch (fork()) {
	case -1:
		return (-1);
	case 0:
		break;
	default:
		_exit(0);
	}

	if (setsid() == -1)
		return (-1);

	if (!nochdir)
		chdir("/");

	if (!noclose && (fd = open("/dev/null", O_RDWR, 0)) != -1) {
		dup2(fd, STDIN_FILENO);
		dup2(fd, STDOUT_FILENO);
		dup2(fd, STDERR_FILENO);
		if (fd > 2)
			close(fd);
	}
	return (0);
}
#endif

int encaps_printf(void *p, void *packet, unsigned len)
{
	unsigned int i;
	if (debug) {
		printf("The packet looks like this:\n");
		for (i = 0; i < len; i++) {
			printf("%02x ", (unsigned char)*(char *)(packet + i));
			if (!((i + 1) % 16))
				printf("\n");
		};
		printf("\n");
	}
	return 0;
}

int delete_context(struct pdp_t *pdp)
{
	if (debug)
		printf("Deleting PDP context\n");
	if (pdp->peer)
		ippool_freeip(ippool, (struct ippoolm_t *)pdp->peer);
	else
		sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Peer not defined!");
	return 0;
}

int create_context_ind(struct pdp_t *pdp)
{
	struct in_addr addr;
	struct ippoolm_t *member;

	if (debug)
		printf("Received create PDP context request\n");

	pdp->eua.l = 0;		/* TODO: Indicates dynamic IP */

	/* ulcpy(&pdp->qos_neg, &pdp->qos_req, sizeof(pdp->qos_req.v)); */
	memcpy(pdp->qos_neg0, pdp->qos_req0, sizeof(pdp->qos_req0));
	memcpy(&pdp->pco_neg, &pco, sizeof(pdp->pco_neg));

	memcpy(pdp->qos_neg.v, pdp->qos_req.v, pdp->qos_req.l);	/* TODO */
	pdp->qos_neg.l = pdp->qos_req.l;

	if (pdp_euaton(&pdp->eua, &addr)) {
		addr.s_addr = 0;	/* Request dynamic */
	}

	if (ippool_newip(ippool, &member, &addr, 0)) {
		gtp_create_context_resp(gsn, pdp, GTPCAUSE_NO_RESOURCES);
		return 0;	/* Allready in use, or no more available */
	}

	pdp_ntoeua(&member->addr, &pdp->eua);
	pdp->peer = member;
	pdp->ipif = tun;	/* TODO */
	member->peer = pdp;

	gtp_create_context_resp(gsn, pdp, GTPCAUSE_ACC_REQ);
	return 0;		/* Success */
}

/* Callback for receiving messages from tun */
int cb_tun_ind(struct tun_t *tun, void *pack, unsigned len)
{
	struct ippoolm_t *ipm;
	struct in_addr dst;
	struct tun_packet_t *iph = (struct tun_packet_t *)pack;

	dst.s_addr = iph->dst;

	if (debug)
		printf("Received packet from tun!\n");

	if (ippool_getip(ippool, &ipm, &dst)) {
		if (debug)
			printf("Received packet with no destination!!!\n");
		return 0;
	}

	if (ipm->peer)		/* Check if a peer protocol is defined */
		gtp_data_req(gsn, (struct pdp_t *)ipm->peer, pack, len);
	return 0;
}

int encaps_tun(struct pdp_t *pdp, void *pack, unsigned len)
{
	if (debug)
		printf("encaps_tun. Packet received: forwarding to tun\n");
	return tun_encaps((struct tun_t *)pdp->ipif, pack, len);
}

int main(int argc, char **argv)
{
	/* gengeopt declarations */
	struct gengetopt_args_info args_info;

	struct hostent *host;

	/* Handle keyboard interrupt SIGINT */
	struct sigaction s;
	s.sa_handler = (void *)signal_handler;
	if ((0 != sigemptyset(&s.sa_mask)) && debug)
		printf("sigemptyset failed.\n");
	s.sa_flags = SA_RESETHAND;
	if ((sigaction(SIGINT, &s, NULL) != 0) && debug)
		printf("Could not register SIGINT signal handler.\n");

	fd_set fds;		/* For select() */
	struct timeval idleTime;	/* How long to select() */

	int timelimit;		/* Number of seconds to be connected */
	int starttime;		/* Time program was started */

	/* open a connection to the syslog daemon */
	/*openlog(PACKAGE, LOG_PID, LOG_DAEMON); */

	/* TODO: Only use LOG__PERROR for linux */
#ifdef __linux__
	openlog(PACKAGE, (LOG_PID | LOG_PERROR), LOG_DAEMON);
#else
	openlog(PACKAGE, (LOG_PID), LOG_DAEMON);
#endif

	if (cmdline_parser(argc, argv, &args_info) != 0)
		exit(1);
	if (args_info.debug_flag) {
		printf("listen: %s\n", args_info.listen_arg);
		if (args_info.conf_arg)
			printf("conf: %s\n", args_info.conf_arg);
		printf("fg: %d\n", args_info.fg_flag);
		printf("debug: %d\n", args_info.debug_flag);
		printf("qos: %#08x\n", args_info.qos_arg);
		if (args_info.apn_arg)
			printf("apn: %s\n", args_info.apn_arg);
		if (args_info.net_arg)
			printf("net: %s\n", args_info.net_arg);
		if (args_info.dynip_arg)
			printf("dynip: %s\n", args_info.dynip_arg);
		if (args_info.statip_arg)
			printf("statip: %s\n", args_info.statip_arg);
		if (args_info.ipup_arg)
			printf("ipup: %s\n", args_info.ipup_arg);
		if (args_info.ipdown_arg)
			printf("ipdown: %s\n", args_info.ipdown_arg);
		if (args_info.pidfile_arg)
			printf("pidfile: %s\n", args_info.pidfile_arg);
		if (args_info.statedir_arg)
			printf("statedir: %s\n", args_info.statedir_arg);
		printf("timelimit: %d\n", args_info.timelimit_arg);
	}

	/* Try out our new parser */

	if (cmdline_parser_configfile(args_info.conf_arg, &args_info, 0, 0, 0)
	    != 0)
		exit(1);

	/* Open a log file */
	if (args_info.logfile_arg) {
		FILE* log_file = fopen(args_info.logfile_arg, "a");
		if (!log_file) {
			printf("Failed to open logfile: '%s'\n",
				args_info.logfile_arg);
			exit(1);
		}
		sys_err_setlogfile(log_file);
	}

	if (args_info.debug_flag) {
		printf("cmdline_parser_configfile\n");
		printf("listen: %s\n", args_info.listen_arg);
		printf("conf: %s\n", args_info.conf_arg);
		printf("fg: %d\n", args_info.fg_flag);
		printf("debug: %d\n", args_info.debug_flag);
		printf("qos: %#08x\n", args_info.qos_arg);
		if (args_info.apn_arg)
			printf("apn: %s\n", args_info.apn_arg);
		if (args_info.net_arg)
			printf("net: %s\n", args_info.net_arg);
		if (args_info.dynip_arg)
			printf("dynip: %s\n", args_info.dynip_arg);
		if (args_info.statip_arg)
			printf("statip: %s\n", args_info.statip_arg);
		if (args_info.ipup_arg)
			printf("ipup: %s\n", args_info.ipup_arg);
		if (args_info.ipdown_arg)
			printf("ipdown: %s\n", args_info.ipdown_arg);
		if (args_info.pidfile_arg)
			printf("pidfile: %s\n", args_info.pidfile_arg);
		if (args_info.statedir_arg)
			printf("statedir: %s\n", args_info.statedir_arg);
		printf("timelimit: %d\n", args_info.timelimit_arg);
	}

	/* Handle each option */

	/* debug                                                        */
	debug = args_info.debug_flag;

	/* listen                                                       */
	/* Do hostname lookup to translate hostname to IP address       */
	/* Any port listening is not possible as a valid address is     */
	/* required for create_pdp_context_response messages            */
	if (args_info.listen_arg) {
		if (!(host = gethostbyname(args_info.listen_arg))) {
			sys_err(LOG_ERR, __FILE__, __LINE__, 0,
				"Invalid listening address: %s!",
				args_info.listen_arg);
			exit(1);
		} else {
			memcpy(&listen_.s_addr, host->h_addr, host->h_length);
		}
	} else {
		sys_err(LOG_ERR, __FILE__, __LINE__, 0,
			"Listening address must be specified! "
			"Please use command line option --listen or "
			"edit %s configuration file\n", args_info.conf_arg);
		exit(1);
	}

	/* net                                                          */
	/* Store net as in_addr net and mask                            */
	if (args_info.net_arg) {
		if (ippool_aton(&net, &mask, args_info.net_arg, 0)) {
			sys_err(LOG_ERR, __FILE__, __LINE__, 0,
				"Invalid network address: %s!",
				args_info.net_arg);
			exit(1);
		}
		netaddr.s_addr = htonl(ntohl(net.s_addr) + 1);
		destaddr.s_addr = htonl(ntohl(net.s_addr) + 1);
	} else {
		sys_err(LOG_ERR, __FILE__, __LINE__, 0,
			"Network address must be specified: %s!",
			args_info.net_arg);
		exit(1);
	}

	/* dynip                                                        */
	if (!args_info.dynip_arg) {
		if (ippool_new(&ippool, args_info.net_arg, NULL, 1, 0,
			       IPPOOL_NONETWORK | IPPOOL_NOGATEWAY |
			       IPPOOL_NOBROADCAST)) {
			sys_err(LOG_ERR, __FILE__, __LINE__, 0,
				"Failed to allocate IP pool!");
			exit(1);
		}
	} else {
		if (ippool_new(&ippool, args_info.dynip_arg, NULL, 1, 0,
			       IPPOOL_NONETWORK | IPPOOL_NOGATEWAY |
			       IPPOOL_NOBROADCAST)) {
			sys_err(LOG_ERR, __FILE__, __LINE__, 0,
				"Failed to allocate IP pool!");
			exit(1);
		}
	}

	/* DNS1 and DNS2 */
#ifdef HAVE_INET_ATON
	dns1.s_addr = 0;
	if (args_info.pcodns1_arg) {
		if (0 == inet_aton(args_info.pcodns1_arg, &dns1)) {
			sys_err(LOG_ERR, __FILE__, __LINE__, 0,
				"Failed to convert pcodns1!");
			exit(1);
		}
	}
	dns2.s_addr = 0;
	if (args_info.pcodns2_arg) {
		if (0 == inet_aton(args_info.pcodns2_arg, &dns2)) {
			sys_err(LOG_ERR, __FILE__, __LINE__, 0,
				"Failed to convert pcodns2!");
			exit(1);
		}
	}
#else
	dns1.s_addr = 0;
	if (args_info.pcodns1_arg) {
		dns1.s_addr = inet_addr(args_info.pcodns1_arg);
		if (dns1.s_addr == -1) {
			sys_err(LOG_ERR, __FILE__, __LINE__, 0,
				"Failed to convert pcodns1!");
			exit(1);
		}
	}
	dns2.s_addr = 0;
	if (args_info.pcodns2_arg) {
		dns2.s_addr = inet_addr(args_info.pcodns2_arg);
		if (dns2.s_addr == -1) {
			sys_err(LOG_ERR, __FILE__, __LINE__, 0,
				"Failed to convert pcodns2!");
			exit(1);
		}
	}
#endif

	pco.l = 20;
	pco.v[0] = 0x80;	/* x0000yyy x=1, yyy=000: PPP */
	pco.v[1] = 0x80;	/* IPCP */
	pco.v[2] = 0x21;
	pco.v[3] = 0x10;	/* Length of contents */
	pco.v[4] = 0x02;	/* ACK */
	pco.v[5] = 0x00;	/* ID: Need to match request */
	pco.v[6] = 0x00;	/* Length */
	pco.v[7] = 0x10;
	pco.v[8] = 0x81;	/* DNS 1 */
	pco.v[9] = 0x06;
	memcpy(&pco.v[10], &dns1, sizeof(dns1));
	pco.v[14] = 0x83;
	pco.v[15] = 0x06;	/* DNS 2 */
	memcpy(&pco.v[16], &dns2, sizeof(dns2));

	/* ipup */
	ipup = args_info.ipup_arg;

	/* ipdown */
	ipdown = args_info.ipdown_arg;

	/* Timelimit                                                       */
	timelimit = args_info.timelimit_arg;
	starttime = time(NULL);

	/* qos                                                             */
	qos.l = 3;
	qos.v[2] = (args_info.qos_arg) & 0xff;
	qos.v[1] = ((args_info.qos_arg) >> 8) & 0xff;
	qos.v[0] = ((args_info.qos_arg) >> 16) & 0xff;

	/* apn                                                             */
	if (strlen(args_info.apn_arg) > (sizeof(apn.v) - 1)) {
		printf("Invalid APN\n");
		return -1;
	}
	apn.l = strlen(args_info.apn_arg) + 1;
	apn.v[0] = (char)strlen(args_info.apn_arg);
	strncpy((char *)&apn.v[1], args_info.apn_arg, sizeof(apn.v) - 1);

	/* foreground                                                   */
	/* If flag not given run as a daemon                            */
	if (!args_info.fg_flag) {
		FILE *f;
		int rc;
		closelog();
		/* Close the standard file descriptors. */
		/* Is this really needed ? */
		f = freopen("/dev/null", "w", stdout);
		if (f == NULL) {
			sys_err(LOG_WARNING, __FILE__, __LINE__, 0,
				"Could not redirect stdout to /dev/null");
		}
		f = freopen("/dev/null", "w", stderr);
		if (f == NULL) {
			sys_err(LOG_WARNING, __FILE__, __LINE__, 0,
				"Could not redirect stderr to /dev/null");
		}
		f = freopen("/dev/null", "r", stdin);
		if (f == NULL) {
			sys_err(LOG_WARNING, __FILE__, __LINE__, 0,
				"Could not redirect stdin to /dev/null");
		}
		rc = daemon(0, 0);
		if (rc != 0) {
			sys_err(LOG_ERR, __FILE__, __LINE__, rc,
				"Could not daemonize");
			exit(1);
		}
		/* Open log again. This time with new pid */
		openlog(PACKAGE, LOG_PID, LOG_DAEMON);
	}

	/* pidfile */
	/* This has to be done after we have our final pid */
	if (args_info.pidfile_arg) {
		log_pid(args_info.pidfile_arg);
	}

	if (debug)
		printf("gtpclient: Initialising GTP tunnel\n");

	if (gtp_new(&gsn, args_info.statedir_arg, &listen_, GTP_MODE_GGSN)) {
		sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Failed to create gtp");
		exit(1);
	}
	if (gsn->fd0 > maxfd)
		maxfd = gsn->fd0;
	if (gsn->fd1c > maxfd)
		maxfd = gsn->fd1c;
	if (gsn->fd1u > maxfd)
		maxfd = gsn->fd1u;

	gtp_set_cb_data_ind(gsn, encaps_tun);
	gtp_set_cb_delete_context(gsn, delete_context);
	gtp_set_cb_create_context_ind(gsn, create_context_ind);

	/* Create a tunnel interface */
	if (debug)
		printf("Creating tun interface\n");
	if (tun_new((struct tun_t **)&tun)) {
		sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Failed to create tun");
		if (debug)
			printf("Failed to create tun\n");
		exit(1);
	}

	if (debug)
		printf("Setting tun IP address\n");
	if (tun_setaddr(tun, &netaddr, &destaddr, &mask)) {
		sys_err(LOG_ERR, __FILE__, __LINE__, 0,
			"Failed to set tun IP address");
		if (debug)
			printf("Failed to set tun IP address\n");
		exit(1);
	}

	tun_set_cb_ind(tun, cb_tun_ind);
	if (tun->fd > maxfd)
		maxfd = tun->fd;

	if (ipup)
		tun_runscript(tun, ipup);

  /******************************************************************/
	/* Main select loop                                               */
  /******************************************************************/

	while ((((starttime + timelimit) > time(NULL)) || (0 == timelimit))
	       && (!end)) {

		FD_ZERO(&fds);
		if (tun)
			FD_SET(tun->fd, &fds);
		FD_SET(gsn->fd0, &fds);
		FD_SET(gsn->fd1c, &fds);
		FD_SET(gsn->fd1u, &fds);

		gtp_retranstimeout(gsn, &idleTime);
		switch (select(maxfd + 1, &fds, NULL, NULL, &idleTime)) {
		case -1:	/* errno == EINTR : unblocked signal */
			sys_err(LOG_ERR, __FILE__, __LINE__, 0,
				"select() returned -1");
			/* On error, select returns without modifying fds */
			FD_ZERO(&fds);
			break;
		case 0:
			/* printf("Select returned 0\n"); */
			gtp_retrans(gsn);	/* Only retransmit if nothing else */
			break;
		default:
			break;
		}

		if (tun->fd != -1 && FD_ISSET(tun->fd, &fds) &&
		    tun_decaps(tun) < 0) {
			sys_err(LOG_ERR, __FILE__, __LINE__, 0,
				"TUN read failed (fd)=(%d)", tun->fd);
		}

		if (FD_ISSET(gsn->fd0, &fds))
			gtp_decaps0(gsn);

		if (FD_ISSET(gsn->fd1c, &fds))
			gtp_decaps1c(gsn);

		if (FD_ISSET(gsn->fd1u, &fds))
			gtp_decaps1u(gsn);

	}

	cmdline_parser_free(&args_info);
	ippool_free(ippool);
	gtp_free(gsn);
	tun_free(tun);

	return 1;

}
