/*
 *      idlescan
 *      Copyright (C) 1999 LiquidK <liquidk@superbofh.org>
 */

#include "global.h"

#include <pcap.h>
#include <bpf/net/bpf.h>
#include <netinet/in.h>
#include "capture.h"

static pcap_t *pcapd;
static int link_offset;




void init_capture(char *device)
{
    char pcap_error[PCAP_ERRBUF_SIZE];
    struct in_addr net, mask;
    struct bpf_program pcapfilter;
    char *filter;
    
 
    if ((pcapd = pcap_open_live(device, 200, 0, 10, pcap_error)) == NULL) {
	fprintf(stderr, "pcap_open_live: [fatal] %s\n", pcap_error);
	exit(-1);
    }

    if (pcap_lookupnet(device, &net.s_addr,&mask.s_addr, pcap_error) == -1) {
	fprintf(stderr, "pcap_lookupnet: [fatal] %s\n", pcap_error);
	exit(-1);
    }

    filter = "";

    if (pcap_compile(pcapd, &pcapfilter, filter, 0, mask.s_addr)) {
	pcap_perror(pcapd,"pcap compile");
	exit(-1);
    }

    if (pcap_setfilter(pcapd,&pcapfilter)) {
	pcap_perror(pcapd,"pcap set");
	exit(-1);
    }

    switch(pcap_datalink(pcapd)) {
    case DLT_EN10MB:        link_offset = 14; break;
    case DLT_SLIP:          link_offset = 16; break;
    case DLT_SLIP_BSDOS:    link_offset = 24; break;
    case DLT_NULL:          link_offset =  4; break;
    case DLT_PPP:           link_offset =  4; break;
    case DLT_PPP_BSDOS:     link_offset = 25; break;
    case DLT_IEEE802:       link_offset = 22; break;
    case DLT_ATM_RFC1483:   link_offset =  8; break;
    case DLT_RAW:           link_offset =  0; break;
      
    default:
	fprintf(stderr,"init_capture: [fatal] unsupported interface type\n");
	exit(-1);
    }

}

char *capture()
{
    char *packet;
    struct pcap_pkthdr head;

    packet = (char *)pcap_next(pcapd, &head);

    if(packet)
        debug(6, "capture: received packet\n");

    return packet ? packet + link_offset : NULL;
}
