/*
 * Copyright (c) 2013 Patrick McHardy <kaber@trash.net>
 *
 * 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.
 */

#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <getopt.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pcap/pcap.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>

static const char *iface = "lo";
static uint16_t port;
static const char *chain = "SYNPROXY";

static int parse_packet(const char *host, const uint8_t *data)
{
	const struct iphdr *iph = (void *)data + 14;
	const struct tcphdr *th = (void *)iph + iph->ihl * 4;
	int length;
	uint8_t *ptr;

	if (!th->syn || !th->ack)
		return 0;

	printf("-A %s -d %s -p tcp --dport %u "
	       "-m state --state UNTRACKED,INVALID "
	       "-j SYNPROXY ", chain, host, port);

	/* ECE && !CWR */
	if (th->res2 == 0x1)
		printf("--ecn ");

	length = th->doff * 4 - sizeof(*th);
	ptr = (uint8_t *)(th + 1);
	while (length > 0) {
		int opcode = *ptr++;
		int opsize;

		switch (opcode) {
		case TCPOPT_EOL:
			return 1;
		case TCPOPT_NOP:
			length--;
			continue;
		default:
			opsize = *ptr++;
			if (opsize < 2)
				return 1;
			if (opsize > length)
				return 1;

			switch (opcode) {
			case TCPOPT_MAXSEG:
				if (opsize == TCPOLEN_MAXSEG)
					printf("--mss %u ", ntohs(*(uint16_t *)ptr));
				break;
			case TCPOPT_WINDOW:
				if (opsize == TCPOLEN_WINDOW)
					printf("--wscale %u ", *ptr);
				break;
			case TCPOPT_TIMESTAMP:
				if (opsize == TCPOLEN_TIMESTAMP)
					printf("--timestamp ");
				break;
			case TCPOPT_SACK_PERMITTED:
				if (opsize == TCPOLEN_SACK_PERMITTED)
					printf("--sack-perm ");
				break;
			}

			ptr += opsize - 2;
			length -= opsize;
		}
	}
	printf("\n");
	return 1;
}

static void probe_host(const char *host)
{
	struct sockaddr_in sin;
	char pcap_errbuf[PCAP_ERRBUF_SIZE];
	struct pcap_pkthdr pkthdr;
	const uint8_t *data;
	struct bpf_program fp;
	pcap_t *ph;
	int fd;

	ph = pcap_create(iface, pcap_errbuf);
	if (ph == NULL) {
		perror("pcap_create");
		goto err1;
	}

	if (pcap_setnonblock(ph, 1, pcap_errbuf) == -1) {
		perror("pcap_setnonblock");
		goto err2;
	}

	if (pcap_setfilter(ph, &fp) == -1) {
		pcap_perror(ph, "pcap_setfilter");
		goto err2;
	}

	if (pcap_activate(ph) != 0) {
		pcap_perror(ph, "pcap_activate");
		goto err2;
	}

	if (pcap_compile(ph, &fp, "src host 127.0.0.1 and tcp and src port 80",
			 1, PCAP_NETMASK_UNKNOWN) == -1) {
		pcap_perror(ph, "pcap_compile");
		goto err2;
	}

	fd = socket(AF_INET, SOCK_STREAM, 0);
	if (fd < 0) {
		perror("socket");
		goto err3;
	}

	memset(&sin, 0, sizeof(sin));
	sin.sin_family		= AF_INET;
	sin.sin_port		= htons(port);
	sin.sin_addr.s_addr	= inet_addr(host);

	if (connect(fd, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
		perror("connect");
		goto err4;
	}

	for (;;) {
		data = pcap_next(ph, &pkthdr);
		if (data == NULL)
			break;
		if (parse_packet(host, data))
			break;
	}

	close(fd);

err4:
	close(fd);
err3:
	pcap_freecode(&fp);
err2:
	pcap_close(ph);
err1:
	return;
}

enum {
	OPT_HELP	= 'h',
	OPT_IFACE	= 'i',
	OPT_PORT	= 'p',
	OPT_CHAIN	= 'c',
};

static const struct option options[] = {
	{ .name = "help",  .has_arg = false, .val = OPT_HELP },
	{ .name = "iface", .has_arg = true,  .val = OPT_IFACE },
	{ .name = "port" , .has_arg = true,  .val = OPT_PORT },
	{ .name = "chain", .has_arg = true,  .val = OPT_CHAIN },
	{ }
};

static void print_help(const char *name)
{
	printf("%s [ options ] address...\n"
	       "\n"
	       "Options:\n"
	       " -i/--iface        Outbound interface\n"
	       " -p/--port         Port number to probe\n"
	       " -c/--chain        Chain name to use for rules\n"
	       " -h/--help         Show this help\n",
	       name);
}

int main(int argc, char **argv)
{
	int optidx = 0, c;

	for (;;) {
		c = getopt_long(argc, argv, "hi:p:c:", options, &optidx);
		if (c == -1)
			break;

		switch (c) {
		case OPT_IFACE:
			iface = optarg;
			break;
		case OPT_PORT:
			port = atoi(optarg);
			break;
		case OPT_CHAIN:
			chain = optarg;
			break;
		case OPT_HELP:
			print_help(argv[0]);
			exit(0);
		case '?':
			print_help(argv[0]);
			exit(1);
		}
	}

	argc -= optind;
	argv += optind;

	while (argc > 0) {
		probe_host(*argv);
		argc--;
		argv++;
	}
	return 0;
}
