#include <iostream>
#include "common.h"
#include "ethernet.h"
#include "ipv6.h"
#include "udp.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");

	UDP tudp(123, 123);
	Octet data[] = { 0x24, 0x02, 0x0a, 0xed, 0x00, 0x00, 0x00, 0x3c,0x00, 0x00, 0x05, 0x1a, 0x93, 0xe5, 0x09, 0x0a,
0xd1, 0x47, 0x27, 0x86 , 0xdd, 0x5e , 0xfd, 0x4a , 0xd1, 0x47 , 0x27, 0xfb , 0xe9, 0x77 , 0x34, 0x0f,
0xd1, 0x47, 0x27, 0xfb , 0xe9, 0x27 , 0x0c, 0xbf , 0xd1, 0x47 , 0x27, 0xfb , 0xe9, 0x34 , 0x07, 0xc7};
	tudp.set_data(data, 48);
	te.attach(&tip);
	tip.attach(&tudp);
	Buffer pkt;
	te.build(pkt); // full packet build
        cout << tudp.to_string(2) << endl;

        cout << pkt << endl;

	PCAP pcap;
	pcap.open(dev);
	pcap.set_filter("ip6 and udp");
	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<UDP *>(ipv6->payload()) == NULL) continue;
		UDP *udp = dynamic_cast<UDP *>(ipv6->payload());
		cout << udp->to_string(2) << endl;
	}
}
