1/********************************************************************* 2 PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved. 3 See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 5 Authors: Daniele Lacamera 6 *********************************************************************/ 7 8 9#include <pcap.h> 10#include "pico_device.h" 11#include "pico_dev_pcap.h" 12#include "pico_stack.h" 13 14#include <sys/poll.h> 15 16struct pico_device_pcap { 17 struct pico_device dev; 18 pcap_t *conn; 19}; 20 21#define VDE_MTU 2048 22 23static int pico_pcap_send(struct pico_device *dev, void *buf, int len) 24{ 25 struct pico_device_pcap *pcap = (struct pico_device_pcap *) dev; 26 /* dbg("[%s] send %d bytes.\n", dev->name, len); */ 27 return pcap_inject(pcap->conn, buf, (uint32_t)len); 28} 29 30static void pico_dev_pcap_cb(u_char *u, const struct pcap_pkthdr *h, const u_char *data) 31{ 32 struct pico_device *dev = (struct pico_device *)u; 33 const uint8_t *buf = (const uint8_t *)data; 34 pico_stack_recv(dev, buf, (uint32_t)h->len); 35} 36 37 38static int pico_pcap_poll(struct pico_device *dev, int loop_score) 39{ 40 struct pico_device_pcap *pcap = (struct pico_device_pcap *) dev; 41 loop_score -= pcap_dispatch(pcap->conn, loop_score, pico_dev_pcap_cb, (u_char *) pcap); 42 return loop_score; 43} 44 45/* Public interface: create/destroy. */ 46 47void pico_pcap_destroy(struct pico_device *dev) 48{ 49 struct pico_device_pcap *pcap = (struct pico_device_pcap *) dev; 50 pcap_close(pcap->conn); 51} 52 53#define PICO_PCAP_MODE_LIVE 0 54#define PICO_PCAP_MODE_STORED 1 55 56static struct pico_device *pico_pcap_create(char *if_file_name, char *name, uint8_t *mac, int mode) 57{ 58 struct pico_device_pcap *pcap = PICO_ZALLOC(sizeof(struct pico_device_pcap)); 59 char errbuf[2000]; 60 if (!pcap) 61 return NULL; 62 63 if( 0 != pico_device_init((struct pico_device *)pcap, name, mac)) { 64 dbg ("Pcap init failed.\n"); 65 pico_pcap_destroy((struct pico_device *)pcap); 66 return NULL; 67 } 68 69 pcap->dev.overhead = 0; 70 71 if (mode == PICO_PCAP_MODE_LIVE) 72 pcap->conn = pcap_open_live(if_file_name, 2000, 100, 10, errbuf); 73 else 74 pcap->conn = pcap_open_offline(if_file_name, errbuf); 75 76 if (!pcap->conn) { 77 pico_pcap_destroy((struct pico_device *)pcap); 78 return NULL; 79 } 80 81 pcap->dev.send = pico_pcap_send; 82 pcap->dev.poll = pico_pcap_poll; 83 pcap->dev.destroy = pico_pcap_destroy; 84 dbg("Device %s created.\n", pcap->dev.name); 85 return (struct pico_device *)pcap; 86} 87 88struct pico_device *pico_pcap_create_fromfile(char *filename, char *name, uint8_t *mac) 89{ 90 return pico_pcap_create(filename, name, mac, PICO_PCAP_MODE_STORED); 91} 92 93struct pico_device *pico_pcap_create_live(char *ifname, char *name, uint8_t *mac) 94{ 95 return pico_pcap_create(ifname, name, mac, PICO_PCAP_MODE_LIVE); 96} 97