/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2012  Intel Corporation. All rights reserved.
 *
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>

#include "pcap.h"

#define le16_to_cpu(val) (val)
#define le32_to_cpu(val) (val)
#define cpu_to_le16(val) (val)
#define cpu_to_le32(val) (val)

struct pcap_hdr {
	uint32_t magic_number;	/* magic number */
	uint16_t version_major;	/* major version number */
	uint16_t version_minor;	/* minor version number */
	int32_t  thiszone;	/* GMT to local correction */
	uint32_t sigfigs;	/* accuracy of timestamps */
	uint32_t snaplen;	/* max length of captured packets, in octets */
	uint32_t network;	/* data link type */
} __attribute__ ((packed));
#define PCAP_HDR_SIZE (sizeof(struct pcap_hdr))

struct pcap_pkt {
	uint32_t ts_sec;	/* timestamp seconds */
	uint32_t ts_usec;	/* timestamp microseconds */
	uint32_t incl_len;	/* number of octets of packet saved in file */
	uint32_t orig_len;	/* actual length of packet */
} __attribute__ ((packed));
#define PCAP_PKT_SIZE (sizeof(struct pcap_pkt))

struct pcap_ppi {
	uint8_t  version;	/* version, currently 0 */
	uint8_t  flags;		/* flags */
	uint16_t len;		/* length of entire message */
	uint32_t dlt;		/* data link type */
} __attribute__ ((packed));
#define PCAP_PPI_SIZE (sizeof(struct pcap_ppi))

struct pcap {
	int ref_count;
	int fd;
	uint32_t type;
	uint32_t snaplen;
};

struct pcap *pcap_open(const char *path)
{
	struct pcap *pcap;
	struct pcap_hdr hdr;
	ssize_t len;

	pcap = calloc(1, sizeof(*pcap));
	if (!pcap)
		return NULL;

	pcap->fd = open(path, O_RDONLY | O_CLOEXEC);
	if (pcap->fd < 0) {
		free(pcap);
		return NULL;
	}

	len = read(pcap->fd, &hdr, PCAP_HDR_SIZE);
	if (len < 0 || len != PCAP_HDR_SIZE)
		goto failed;

	if (hdr.magic_number != 0xa1b2c3d4)
		goto failed;

	if (hdr.version_major != 2 || hdr.version_minor != 4)
		goto failed;

	pcap->snaplen = hdr.snaplen;
	pcap->type = hdr.network;

	return pcap_ref(pcap);

failed:
	close(pcap->fd);
	free(pcap);

	return NULL;
}

struct pcap *pcap_ref(struct pcap *pcap)
{
	if (!pcap)
		return NULL;

	__sync_fetch_and_add(&pcap->ref_count, 1);

	return pcap;
}

void pcap_unref(struct pcap *pcap)
{
	if (!pcap)
		return;

	if (__sync_sub_and_fetch(&pcap->ref_count, 1))
		return;

	if (pcap->fd >= 0)
		close(pcap->fd);

	free(pcap);
}

uint32_t pcap_get_type(struct pcap *pcap)
{
	if (!pcap)
		return PCAP_TYPE_INVALID;

	return pcap->type;
}

uint32_t pcap_get_snaplen(struct pcap *pcap)
{
	if (!pcap)
		return 0;

	return pcap->snaplen;
}

bool pcap_read(struct pcap *pcap, struct timeval *tv,
				void *data, uint32_t size, uint32_t *len)
{
	struct pcap_pkt pkt;
	uint32_t toread;
	ssize_t bytes_read;

	if (!pcap)
		return false;

	bytes_read = read(pcap->fd, &pkt, PCAP_PKT_SIZE);
	if (bytes_read != PCAP_PKT_SIZE)
		return false;

	if (pkt.incl_len > size)
		toread = size;
	else
		toread = pkt.incl_len;

	bytes_read = read(pcap->fd, data, toread);
	if (bytes_read < 0)
		return false;

	if (tv) {
		tv->tv_sec = pkt.ts_sec;
		tv->tv_usec = pkt.ts_usec;
	}

	if (len)
		*len = toread;

	return true;
}

bool pcap_read_ppi(struct pcap *pcap, struct timeval *tv, uint32_t *type,
					void *data, uint32_t size,
					uint32_t *offset, uint32_t *len)
{
	struct pcap_pkt pkt;
	struct pcap_ppi ppi;
	uint16_t pph_len;
	uint32_t toread;
	ssize_t bytes_read;

	if (!pcap)
		return false;

	bytes_read = read(pcap->fd, &pkt, PCAP_PKT_SIZE);
	if (bytes_read != PCAP_PKT_SIZE)
		return false;

	if (pkt.incl_len > size)
		toread = size;
	else
		toread = pkt.incl_len;

	bytes_read = read(pcap->fd, &ppi, PCAP_PPI_SIZE);
	if (bytes_read != PCAP_PPI_SIZE)
		return false;

	if (ppi.flags)
		return false;

	pph_len = le16_to_cpu(ppi.len);
	if (pph_len < PCAP_PPI_SIZE)
		return false;

	bytes_read = read(pcap->fd, data, toread - PCAP_PPI_SIZE);
	if (bytes_read < 0)
		return false;

	if (tv) {
		tv->tv_sec = pkt.ts_sec;
		tv->tv_usec = pkt.ts_usec;
	}

	if (type)
		*type = le32_to_cpu(ppi.dlt);

	if (offset)
		*offset = pph_len - PCAP_PPI_SIZE;

	if (len)
		*len = toread - pph_len;

	return true;
}
