#include <iostream>
#include "common.h"
#include "ethernet.h"
#include "ipv6.h"
#include "tcp.h"
#include "pcap.h"

#ifndef DEV
#define DEV "em0"
#endif

int main(int argc, char *argv[])
{
	Ethernet *e = new Ethernet();
	Buffer buf;
	debug = 2;
	bool finish = false;
	string dev(DEV);
	if (argc == 2) {
		dev = argv[1];
	} else
	if (argc > 2) {
		cerr << argv[1] << ": [intf]" << endl;
		return 1;
	}

	Ethernet te;
	te.src("12:23:45:67:89:ab");
	te.dest("12:23:45:67:89:ab");
	IPv6 tip;
	tip.src("2001:67c:1220:809::93e5:090b");
	tip.dest("2001:67c:1220:c001::93e5:be8f");

	TCP tcp(1234, 80);
	TCP_Option_MSS mss(1440);
	TCP_Option_SackPerm sack;
	tcp.add_option(&mss);
	tcp.add_option(&sack);
	tcp.flags(TCP::SYN);
	tcp.window(8192);
	Octet data[1000];
	const char *req = "GET / HTTP/1.0\n\n";
	memcpy(data, req, strlen(req));
	tcp.set_data(data, strlen(req));
	te.attach(&tip);
	tip.attach(&tcp);
	Buffer pkt;
	te.build(pkt); // full packet build
        cout << tcp.to_string(2) << endl;

        cout << pkt << endl;

	PCAP pcap;
	pcap.open(dev);
	pcap.set_filter("ip6 and tcp port 80");
	while (!finish) {
		// get packet
		if (!pcap.read(buf, dev)) continue;
		// full decode
		if (!e->decode(buf)) continue;
		// is any decoded payload?
		if (!e->payload()) continue;
		// is IPv6 packet?
		if (dynamic_cast<IPv6 *>(e->payload()) == NULL) continue;
		IPv6 *ipv6 = dynamic_cast<IPv6 *>(e->payload());
		cout << ipv6 << endl;
		// is any decoded payload?
		if (!ipv6->payload()) continue;
		if (dynamic_cast<TCP *>(ipv6->payload()) == NULL) continue;
		TCP *ptcp = dynamic_cast<TCP *>(ipv6->payload());
		cout << ptcp->to_string(2) << endl;
	}
}
