You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
96 lines
2.7 KiB
96 lines
2.7 KiB
/********************************************************************* |
|
PicoTCP. Copyright (c) 2012-2015 Altran Intelligent Systems. Some rights reserved. |
|
See LICENSE and COPYING for usage. |
|
|
|
Authors: Daniele Lacamera |
|
*********************************************************************/ |
|
|
|
|
|
#include <pcap.h> |
|
#include "pico_device.h" |
|
#include "pico_dev_pcap.h" |
|
#include "pico_stack.h" |
|
|
|
#include <sys/poll.h> |
|
|
|
struct pico_device_pcap { |
|
struct pico_device dev; |
|
pcap_t *conn; |
|
}; |
|
|
|
#define VDE_MTU 2048 |
|
|
|
static int pico_pcap_send(struct pico_device *dev, void *buf, int len) |
|
{ |
|
struct pico_device_pcap *pcap = (struct pico_device_pcap *) dev; |
|
/* dbg("[%s] send %d bytes.\n", dev->name, len); */ |
|
return pcap_inject(pcap->conn, buf, (uint32_t)len); |
|
} |
|
|
|
static void pico_dev_pcap_cb(u_char *u, const struct pcap_pkthdr *h, const u_char *data) |
|
{ |
|
struct pico_device *dev = (struct pico_device *)u; |
|
const uint8_t *buf = (const uint8_t *)data; |
|
pico_stack_recv(dev, buf, (uint32_t)h->len); |
|
} |
|
|
|
|
|
static int pico_pcap_poll(struct pico_device *dev, int loop_score) |
|
{ |
|
struct pico_device_pcap *pcap = (struct pico_device_pcap *) dev; |
|
loop_score -= pcap_dispatch(pcap->conn, loop_score, pico_dev_pcap_cb, (u_char *) pcap); |
|
return loop_score; |
|
} |
|
|
|
/* Public interface: create/destroy. */ |
|
|
|
void pico_pcap_destroy(struct pico_device *dev) |
|
{ |
|
struct pico_device_pcap *pcap = (struct pico_device_pcap *) dev; |
|
pcap_close(pcap->conn); |
|
} |
|
|
|
#define PICO_PCAP_MODE_LIVE 0 |
|
#define PICO_PCAP_MODE_STORED 1 |
|
|
|
static struct pico_device *pico_pcap_create(char *if_file_name, char *name, uint8_t *mac, int mode) |
|
{ |
|
struct pico_device_pcap *pcap = PICO_ZALLOC(sizeof(struct pico_device_pcap)); |
|
char errbuf[2000]; |
|
if (!pcap) |
|
return NULL; |
|
|
|
if( 0 != pico_device_init((struct pico_device *)pcap, name, mac)) { |
|
dbg ("Pcap init failed.\n"); |
|
pico_pcap_destroy((struct pico_device *)pcap); |
|
return NULL; |
|
} |
|
|
|
pcap->dev.overhead = 0; |
|
|
|
if (mode == PICO_PCAP_MODE_LIVE) |
|
pcap->conn = pcap_open_live(if_file_name, 2000, 100, 10, errbuf); |
|
else |
|
pcap->conn = pcap_open_offline(if_file_name, errbuf); |
|
|
|
if (!pcap->conn) { |
|
pico_pcap_destroy((struct pico_device *)pcap); |
|
return NULL; |
|
} |
|
|
|
pcap->dev.send = pico_pcap_send; |
|
pcap->dev.poll = pico_pcap_poll; |
|
pcap->dev.destroy = pico_pcap_destroy; |
|
dbg("Device %s created.\n", pcap->dev.name); |
|
return (struct pico_device *)pcap; |
|
} |
|
|
|
struct pico_device *pico_pcap_create_fromfile(char *filename, char *name, uint8_t *mac) |
|
{ |
|
return pico_pcap_create(filename, name, mac, PICO_PCAP_MODE_STORED); |
|
} |
|
|
|
struct pico_device *pico_pcap_create_live(char *ifname, char *name, uint8_t *mac) |
|
{ |
|
return pico_pcap_create(ifname, name, mac, PICO_PCAP_MODE_LIVE); |
|
}
|
|
|