/*
 * Copyright (c) 2007, Swedish Institute of Computer Science.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * 3. Neither the name of the Institute nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * This file is part of the uIP TCP/IP stack.
 * 
 * Author: Oliver Schmidt <ol.sc@web.de>
 *
 * $Id: wpcap.c,v 1.1 2007/09/05 16:11:08 oliverschmidt Exp $
 */

#define WIN32_LEAN_AND_MEAN
#define _WIN32_WINNT 0x0501
#include <windows.h>
#include <winsock2.h>
#include <iphlpapi.h>

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>

#define htonl contiki_htonl /* htonl is defined in winsock2 */
#define htons contiki_htons /* htons is defined in winsock2 */

#include "uip.h"
#include "uip_arp.h"
#include "ctk.h"
#include "wpcap.h"

struct pcap;

struct pcap_if {
  struct pcap_if *next;
  char *name;
  char *description;
  struct pcap_addr {
    struct pcap_addr *next;
    struct sockaddr *addr;
    struct sockaddr *netmask;
    struct sockaddr *broadaddr;
    struct sockaddr *dstaddr;
  } *addresses;
  DWORD flags;
};

struct pcap_pkthdr {
  struct timeval ts;
  DWORD caplen;
  DWORD len;
};

HMODULE wpcap;

static struct pcap *pcap;

static int (* pcap_findalldevs)(struct pcap_if **, char *);
static struct pcap *(* pcap_open_live)(char *, int, int, int, char *);
static int (* pcap_next_ex)(struct pcap *, struct pcap_pkthdr **, unsigned char **);
static int (* pcap_sendpacket)(struct pcap *, unsigned char *, int);

#define BUF ((struct uip_eth_hdr *)&uip_buf[0])

extern void debug_printf(char *format, ...);

/*---------------------------------------------------------------------------*/
static void
error_exit(char *message)
{
  console_exit();
  cprintf(message);
  exit(EXIT_FAILURE);
}
/*---------------------------------------------------------------------------*/
static void
init_pcap(struct in_addr addr)
{
  struct pcap_if *interfaces;
  char error[256];

  if(pcap_findalldevs(&interfaces, error) == -1) {
    error_exit(error);
  }

  while(interfaces != NULL) {
    debug_printf("init_pcap: found interface: %s\n", interfaces->description);

    if(interfaces->addresses != NULL && 
       interfaces->addresses->addr != NULL &&
       interfaces->addresses->addr->sa_family == AF_INET) {

      struct in_addr interface_addr;
      interface_addr = ((struct sockaddr_in *)interfaces->addresses->addr)->sin_addr;
      debug_printf("init_pcap:    with address: %s\n", inet_ntoa(interface_addr));

      if(interface_addr.s_addr == addr.s_addr) {
        break;
      }     
    }
    interfaces = interfaces->next;
  }

  if(interfaces == NULL) {
    error_exit("no interface found with ip addr specified on cmdline\n");
  }

  pcap = pcap_open_live(interfaces->name, UIP_BUFSIZE, 0, -1, error);
  if(pcap == NULL) {
    error_exit(error);
  }
}
/*---------------------------------------------------------------------------*/
static void
set_ethaddr(struct in_addr addr)
{
  PIP_ADAPTER_ADDRESSES adapters;
  ULONG size = 0;

  if(GetAdaptersAddresses(AF_INET, GAA_FLAG_SKIP_ANYCAST |
				   GAA_FLAG_SKIP_MULTICAST |
				   GAA_FLAG_SKIP_DNS_SERVER,
				   NULL, NULL, &size) != ERROR_BUFFER_OVERFLOW) {
    error_exit("error on access to adapter list size\n");
  }
  adapters = alloca(size);
  if(GetAdaptersAddresses(AF_INET, GAA_FLAG_SKIP_ANYCAST |
				   GAA_FLAG_SKIP_MULTICAST |
				   GAA_FLAG_SKIP_DNS_SERVER,
				   NULL, adapters, &size) != ERROR_SUCCESS) {
    error_exit("error on access to adapter list\n");
  }

  while(adapters != NULL) {

    char buffer[256];
    WideCharToMultiByte(CP_ACP, 0, adapters->Description, -1,
			buffer, sizeof(buffer), NULL, NULL);
    debug_printf("set_ethaddr: found adapter: %s\n", buffer);

    if(adapters->FirstUnicastAddress != NULL &&
       adapters->FirstUnicastAddress->Address.lpSockaddr != NULL &&
       adapters->FirstUnicastAddress->Address.lpSockaddr->sa_family == AF_INET) {

      struct in_addr adapter_addr;
      adapter_addr = ((struct sockaddr_in *)adapters->FirstUnicastAddress->Address.lpSockaddr)->sin_addr;
      debug_printf("set_ethaddr:  with address: %s\n", inet_ntoa(adapter_addr));

      if(adapter_addr.s_addr == addr.s_addr) {
	if(adapters->PhysicalAddressLength != 6) {
	  error_exit("ip addr specified on cmdline does not belong to an ethernet card\n");
	}
	debug_printf("set_ethaddr:  ethernetaddr: %02X-%02X-%02X-%02X-%02X-%02X\n",
		     adapters->PhysicalAddress[0], adapters->PhysicalAddress[1],
		     adapters->PhysicalAddress[2], adapters->PhysicalAddress[3],
		     adapters->PhysicalAddress[4], adapters->PhysicalAddress[5]);

	uip_setethaddr((*(struct uip_eth_addr *)adapters->PhysicalAddress));
	break;
      }
    }
    adapters = adapters->Next;
  }

  if(adapters == NULL) {
    error_exit("no adapter found with ip addr specified on cmdline\n");
  }
}
/*---------------------------------------------------------------------------*/
void
wpcap_init(void)
{
  struct in_addr addr;

  addr.s_addr = inet_addr(__argv[1]);
  if(addr.s_addr == INADDR_NONE) {
    error_exit("usage: <program> <ip addr of ethernet card to share>\n");
  }
  debug_printf("wpcap_init: cmdline address: %s\n", inet_ntoa(addr));

  wpcap = LoadLibrary("wpcap.dll");
  (FARPROC)pcap_findalldevs = GetProcAddress(wpcap, "pcap_findalldevs");
  (FARPROC)pcap_open_live   = GetProcAddress(wpcap, "pcap_open_live");
  (FARPROC)pcap_next_ex     = GetProcAddress(wpcap, "pcap_next_ex");
  (FARPROC)pcap_sendpacket  = GetProcAddress(wpcap, "pcap_sendpacket");

  if(pcap_findalldevs == NULL || pcap_open_live  == NULL ||
     pcap_next_ex     == NULL || pcap_sendpacket == NULL) {
    error_exit("error on access to winpcap library\n");
  }

  init_pcap(addr);
  set_ethaddr(addr);
}
/*---------------------------------------------------------------------------*/
u16_t
wpcap_poll(void)
{
  struct pcap_pkthdr *packet_header;
  unsigned char *packet;

  if(pcap == NULL) {
    return 0;
  }

  switch(pcap_next_ex(pcap, &packet_header, &packet)) {
  case -1: 
    error_exit("error on read\n");
  case 0:
    return 0;
  }

  if(packet_header->caplen > UIP_BUFSIZE) {
    return 0;
  }

  CopyMemory(uip_buf, packet, packet_header->caplen);
  return (u16_t)packet_header->caplen;
}
/*---------------------------------------------------------------------------*/
void
wpcap_send(void)
{
  if(pcap_sendpacket(pcap, uip_buf, uip_len) == -1) {
    error_exit("error on send\n");
  }
}
/*---------------------------------------------------------------------------*/
void
wpcap_exit(void)
{
  FreeLibrary(wpcap);
  pcap = NULL;
}
/*---------------------------------------------------------------------------*/
