#include <stdio.h>
#include <iostream>
#include "ethernet_header.h"

// Initalize variables.

using namespace std;

pcap_t *handle;                 /* Session handle */
string dev;                     /* Device to sniff on */
char errbuf[PCAP_ERRBUF_SIZE];  /* Error string */
struct bpf_program fp;          /* The compiled filter expression */
char filter_exp[] = "port 443";	/* The filter expression */
bpf_u_int32 mask;               /* The netmask of our sniffing device */
bpf_u_int32 net;                /* The IP of our sniffing device */

void callback(u_char *args, const pcap_pkthdr *header, const u_char *packet) {
    ethernet = (struct sniff_ethernet*)(packet);
    ip = (struct sniff_ip*)(packet + SIZE_ETHERNET);
    size_ip = IP_HL(ip)*4;
    
    if (size_ip < 20) {
        printf("   * Invalid IP header length: %u bytes\n", size_ip);
        return;
    }
    
    tcp = (struct sniff_tcp*)(packet + SIZE_ETHERNET + size_ip);
    size_tcp = TH_OFF(tcp)*4;
    
    if (size_tcp < 20) {
        printf("   * Invalid TCP header length: %u bytes\n", size_tcp);
        return;
    }
    
    payload = (char *)(packet + SIZE_ETHERNET + size_ip + size_tcp);

    cout << (char *) ethernet << endl;
    cout << (char *) ip << endl;
    cout << size_ip << endl;
    cout << tcp << endl;
    cout << size_tcp << endl;
    cout << payload << endl;
}

// Notes on pcap_loop.
// int pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user);

int main()
{
	char *dev, errbuf[PCAP_ERRBUF_SIZE];

    dev = pcap_lookupdev(errbuf);
	
    if (dev == NULL) {
		fprintf(stderr, "Couldn't find default device: %s\n", errbuf);
		return(2);
	}
    
    if(pcap_lookupnet(dev, &net, &mask, errbuf) == -1) {
        fprintf(stderr, "Can't get netmask for device %s\n", dev);
        net = 0;
        mask = 0;
    }
    
    handle = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf);

    if(handle == NULL) {
        fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf);
        return(2);
    }

    if(pcap_compile(handle, &fp, filter_exp, 0, net) == -1) {
        fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(handle));
        return(2);
    }

    if(pcap_setfilter(handle, &fp) == -1) {
        fprintf(stderr, "Couldn't install filter %s: %s\n", filter_exp, pcap_geterr(handle));
        return(2);
    }

    pcap_loop(handle, 10, callback, NULL);
}
