/* Copyright (C) 2008 The Android Open Source Project
**
** This software is licensed under the terms of the GNU General Public
** License version 2, as published by the Free Software Foundation, and
** may be copied, distributed, and modified under those terms.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
*/
#include "android/tcpdump.h"
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>

int  qemu_tcpdump_active;

static FILE*     capture_file;
static uint64_t  capture_count;
static uint64_t  capture_size;
static int       capture_init;

static void
capture_atexit(void)
{
    if (qemu_tcpdump_active) {
        fclose(capture_file);
        qemu_tcpdump_active = 0;
    }
}

/* See http://wiki.wireshark.org/Development/LibpcapFileFormat for
 * the complete description of the packet capture file format
 */

#define  PCAP_MAGIC     0xa1b2c3d4
#define  PCAP_MAJOR     2
#define  PCAP_MINOR     4
#define  PCAP_SNAPLEN   65535
#define  PCAP_ETHERNET  1

static int
pcap_write_header( FILE*  out )
{
    typedef struct {
        uint32_t   magic;
        uint16_t   version_major;
        uint16_t   version_minor;
        int32_t    this_zone;
        uint32_t   sigfigs;
        uint32_t   snaplen;
        uint32_t   network;
    } PcapHeader;

    PcapHeader  h;

    h.magic         = PCAP_MAGIC;
    h.version_major = PCAP_MAJOR;
    h.version_minor = PCAP_MINOR;
    h.this_zone     = 0;
    h.sigfigs       = 0;  /* all tools set it to 0 in practice */
    h.snaplen       = PCAP_SNAPLEN;
    h.network       = PCAP_ETHERNET;

    if (fwrite(&h, sizeof(h), 1, out) != 1) {
        return -1;
    }
    return 0;
}

int
qemu_tcpdump_start( const char*  filepath )
{
    if (!capture_init) {
        capture_init = 1;
        atexit(capture_atexit);
    }

    qemu_tcpdump_stop();

    if (filepath == NULL)
        return -1;

    capture_file = fopen(filepath, "wb");
    if (capture_file == NULL)
        return -1;

    if (pcap_write_header(capture_file) < 0)
        return -1;

    qemu_tcpdump_active = 1;
    return 0;
}

void
qemu_tcpdump_stop( void )
{
    if (!qemu_tcpdump_active)
        return;

    qemu_tcpdump_active = 0;

    capture_count = 0;
    capture_size  = 0;

    fclose(capture_file);
    capture_file = NULL;
}

void
qemu_tcpdump_packet( const void*  base, int  len )
{
    typedef struct {
        uint32_t  ts_sec;
        uint32_t  ts_usec;
        uint32_t  incl_len;
        uint32_t  orig_len;
    } PacketHeader;

    PacketHeader    h;
    struct timeval  now;
    int             len2 = len;

    if (len2 > PCAP_SNAPLEN)
        len2 = PCAP_SNAPLEN;

    gettimeofday(&now, NULL);
    h.ts_sec   = (uint32_t) now.tv_sec;
    h.ts_usec  = (uint32_t) now.tv_usec;
    h.incl_len = (uint32_t) len2;
    h.orig_len = (uint32_t) len;

    fwrite( &h, sizeof(h), 1, capture_file );
    fwrite( base, 1, len2, capture_file );

    capture_count += 1;
    capture_size  += len2;
}

void
qemu_tcpdump_stats( uint64_t  *pcount, uint64_t*  psize )
{
    *pcount = capture_count;
    *psize  = capture_size;
}

