From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 3B4B1A0546; Sun, 14 Feb 2021 02:20:56 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id F1A0F1CC565; Sun, 14 Feb 2021 02:20:31 +0100 (CET) Received: from mail-lj1-f177.google.com (mail-lj1-f177.google.com [209.85.208.177]) by mails.dpdk.org (Postfix) with ESMTP id 658A01CC4FA for ; Sun, 14 Feb 2021 02:20:28 +0100 (CET) Received: by mail-lj1-f177.google.com with SMTP id v6so3624399ljh.9 for ; Sat, 13 Feb 2021 17:20:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=yomGuCJWW0fAlEWEyNq4xm4hvoYWH7DBpIyrckA/Xdc=; b=id+j4zSgCZ2qn9TVyNBT3tiShyPNYQK48iVKO0OY1OWtZ8xuRzlS3v+aMl3jh0AsHI Mjo0xjsfP3+sj2hKze3GQkV6doyD9AoQWfmRm73sW+DhEas/y24XKr3jGP6J783zuV71 4t04HlQ2txkrX5qsRYAerXNB/DlYTcTsZc2mszYaMpf9brTFuZHU38YamrVc7hs/38Lg PIRhjMmW7OoZI1f1p1ClRkYCe5k17XDqq3wtE4KI3fURL6jviUsQc1fGUKCwxS0dh5XB ER/i1xo3tqGojNeHyvpTAiIE0CB4srXqECln8n566EdxDDz4EQc09QaH5slrmtntY6SJ rIxQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=yomGuCJWW0fAlEWEyNq4xm4hvoYWH7DBpIyrckA/Xdc=; b=RjdTOr66twle5Evod8uHTaK5aaRHVTrmbcCfR4wuTjUEkO8DuXCvAPHnoIjT93en/Z UXsXydBpe8FSor/J94ubckKzb3fMB/XqkUESjuBQuouV93y+e5+scdBwOCh5ESiZk+Fg 2MOOFt6h/bWmuggHSFKU5TYAJ1I4c3z+Dts8sCPdDKVMEFxR1LVIOGiBE5RC/NsYGgVQ wJ+NriG8Co3NLqW2OGugh1MdKQbAgvs7FrNI2JoDpgiMcIEFe4TxdJeu9fUf2puXlJCF ht6X2mCZLu6ePg2IMAF913NqEIrCZQ5LI3B2PNtH9kdTvUmjGuKRDLnXr+iXKS+vR9LK 1mtQ== X-Gm-Message-State: AOAM533m+jBYAi5986OPP36azHn1y71m9Y3o7NOqS52R+c4ROn+cVq8U woY55BhzR8cGkNP3Ymg3HsVCqLfq8dGqow== X-Google-Smtp-Source: ABdhPJz7yLzfb1iiPXC34Ljt8f+Og+AQ5ORW5vlulWmWGInuwaLOFUWpvFS5esyGiTd5bTXZTntLHg== X-Received: by 2002:a2e:9613:: with SMTP id v19mr5648957ljh.127.1613265627440; Sat, 13 Feb 2021 17:20:27 -0800 (PST) Received: from localhost.localdomain (broadband-37-110-65-23.ip.moscow.rt.ru. [37.110.65.23]) by smtp.gmail.com with ESMTPSA id h11sm2237648lfd.243.2021.02.13.17.20.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 13 Feb 2021 17:20:27 -0800 (PST) From: Dmitry Kozlyuk To: dev@dpdk.org Cc: Tyler Retzlaff , Mike Wells , Dmitry Kozlyuk , Ferruh Yigit Date: Sun, 14 Feb 2021 04:20:11 +0300 Message-Id: <20210214012013.23165-5-dmitry.kozliuk@gmail.com> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210214012013.23165-1-dmitry.kozliuk@gmail.com> References: <20210214012013.23165-1-dmitry.kozliuk@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: [dpdk-dev] [PATCH 4/6] net/pcap: add libpcap wrappers X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" libpcap headers can expose OS headers. On Windows, system networking headers are incompatible with DPDK ones, causing multiple name clashes. API of libpcap itself involves a non-standard u_char type. Add a limited set of trivial libpcap wrappers, so that libpcap headers are not included directly by OS-independent PMD code. Use EAL types and functions for time instead of POSIX ones. Signed-off-by: Dmitry Kozlyuk --- drivers/net/pcap/meson.build | 1 + drivers/net/pcap/pcap_ethdev.c | 157 +++++++++++++++++---------------- drivers/net/pcap/pcap_osdep.c | 122 +++++++++++++++++++++++++ drivers/net/pcap/pcap_osdep.h | 50 +++++++++++ 4 files changed, 252 insertions(+), 78 deletions(-) create mode 100644 drivers/net/pcap/pcap_osdep.c diff --git a/drivers/net/pcap/meson.build b/drivers/net/pcap/meson.build index 26b606699..9ab95ec3e 100644 --- a/drivers/net/pcap/meson.build +++ b/drivers/net/pcap/meson.build @@ -13,6 +13,7 @@ if not dpdk_conf.has('RTE_PORT_PCAP') endif sources = files( 'pcap_ethdev.c', + 'pcap_osdep.c', 'pcap_osdep_@0@.c'.format(exec_env), ) ext_deps += pcap_dep diff --git a/drivers/net/pcap/pcap_ethdev.c b/drivers/net/pcap/pcap_ethdev.c index a102897e9..6461213e0 100644 --- a/drivers/net/pcap/pcap_ethdev.c +++ b/drivers/net/pcap/pcap_ethdev.c @@ -4,17 +4,13 @@ * All rights reserved. */ -#include - -#include - -#include #include #include +#include +#include #include #include #include -#include #include "pcap_osdep.h" @@ -36,8 +32,8 @@ #define RTE_PMD_PCAP_MAX_QUEUES 16 -static char errbuf[PCAP_ERRBUF_SIZE]; -static struct timeval start_time; +static char errbuf[OSDEP_PCAP_ERRBUF_SIZE]; +static struct rte_time_us start_time; static uint64_t start_cycles; static uint64_t hz; static uint8_t iface_idx; @@ -83,16 +79,16 @@ struct pmd_internals { }; struct pmd_process_private { - pcap_t *rx_pcap[RTE_PMD_PCAP_MAX_QUEUES]; - pcap_t *tx_pcap[RTE_PMD_PCAP_MAX_QUEUES]; - pcap_dumper_t *tx_dumper[RTE_PMD_PCAP_MAX_QUEUES]; + osdep_pcap * rx_pcap[RTE_PMD_PCAP_MAX_QUEUES]; + osdep_pcap * tx_pcap[RTE_PMD_PCAP_MAX_QUEUES]; + osdep_pcap_dumper * tx_dumper[RTE_PMD_PCAP_MAX_QUEUES]; }; struct pmd_devargs { unsigned int num_of_queue; struct devargs_queue { - pcap_dumper_t *dumper; - pcap_t *pcap; + osdep_pcap_dumper *dumper; + osdep_pcap *pcap; const char *name; const char *type; } queue[RTE_PMD_PCAP_MAX_QUEUES]; @@ -137,7 +133,7 @@ RTE_LOG_REGISTER(eth_pcap_logtype, pmd.net.pcap, NOTICE); static int eth_pcap_rx_jumbo(struct rte_mempool *mb_pool, struct rte_mbuf *mbuf, - const u_char *data, uint16_t data_len) + const uint8_t *data, uint16_t data_len) { /* Copy the first segment. */ uint16_t len = rte_pktmbuf_tailroom(mbuf); @@ -214,14 +210,14 @@ static uint16_t eth_pcap_rx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) { unsigned int i; - struct pcap_pkthdr header; + struct osdep_pcap_pkthdr header; struct pmd_process_private *pp; - const u_char *packet; + const uint8_t *packet; struct rte_mbuf *mbuf; struct pcap_rx_queue *pcap_q = queue; uint16_t num_rx = 0; uint32_t rx_bytes = 0; - pcap_t *pcap; + osdep_pcap *pcap; pp = rte_eth_devices[pcap_q->port_id].process_private; pcap = pp->rx_pcap[pcap_q->queue_id]; @@ -234,7 +230,7 @@ eth_pcap_rx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) */ for (i = 0; i < nb_pkts; i++) { /* Get the next PCAP packet */ - packet = pcap_next(pcap, &header); + packet = osdep_pcap_next(pcap, &header); if (unlikely(packet == NULL)) break; @@ -261,8 +257,8 @@ eth_pcap_rx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) mbuf->pkt_len = (uint16_t)header.caplen; *RTE_MBUF_DYNFIELD(mbuf, timestamp_dynfield_offset, rte_mbuf_timestamp_t *) = - (uint64_t)header.ts.tv_sec * 1000000 + - header.ts.tv_usec; + (uint64_t)header.ts.sec * 1000000 + + header.ts.usec; mbuf->ol_flags |= timestamp_rx_dynflag; mbuf->port = pcap_q->port_id; bufs[num_rx] = mbuf; @@ -285,20 +281,24 @@ eth_null_rx(void *queue __rte_unused, #define NSEC_PER_SEC 1000000000L +/* + * This function stores nanoseconds in "usec" field of struct rte_time_us, + * because "ts" goes directly to nanosecond-precision dump. + */ static inline void -calculate_timestamp(struct timeval *ts) { +calculate_timestamp(struct rte_time_us *ts) { uint64_t cycles; - struct timeval cur_time; + struct rte_time_us cur_time; cycles = rte_get_timer_cycles() - start_cycles; - cur_time.tv_sec = cycles / hz; - cur_time.tv_usec = (cycles % hz) * NSEC_PER_SEC / hz; - - ts->tv_sec = start_time.tv_sec + cur_time.tv_sec; - ts->tv_usec = start_time.tv_usec + cur_time.tv_usec; - if (ts->tv_usec >= NSEC_PER_SEC) { - ts->tv_usec -= NSEC_PER_SEC; - ts->tv_sec += 1; + cur_time.sec = cycles / hz; + cur_time.usec = (cycles % hz) * NSEC_PER_SEC / hz; + + ts->sec = start_time.sec + cur_time.sec; + ts->usec = start_time.usec + cur_time.usec; + if (ts->usec >= NSEC_PER_SEC) { + ts->usec -= NSEC_PER_SEC; + ts->sec += 1; } } @@ -314,8 +314,8 @@ eth_pcap_tx_dumper(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) struct pcap_tx_queue *dumper_q = queue; uint16_t num_tx = 0; uint32_t tx_bytes = 0; - struct pcap_pkthdr header; - pcap_dumper_t *dumper; + struct osdep_pcap_pkthdr header; + osdep_pcap_dumper *dumper; unsigned char temp_data[RTE_ETH_PCAP_SNAPLEN]; size_t len, caplen; @@ -342,7 +342,7 @@ eth_pcap_tx_dumper(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) * in the mbuf (when the mbuf is contiguous) or, otherwise, * a pointer to temp_data after copying into it. */ - pcap_dump((u_char *)dumper, &header, + osdep_pcap_dump((uint8_t *)dumper, &header, rte_pktmbuf_read(mbuf, 0, caplen, temp_data)); num_tx++; @@ -355,7 +355,7 @@ eth_pcap_tx_dumper(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) * process stops and to make sure the pcap file is actually written, * we flush the pcap dumper within each burst. */ - pcap_dump_flush(dumper); + osdep_pcap_dump_flush(dumper); dumper_q->tx_stat.pkts += num_tx; dumper_q->tx_stat.bytes += tx_bytes; dumper_q->tx_stat.err_pkts += nb_pkts - num_tx; @@ -400,7 +400,7 @@ eth_pcap_tx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) struct pcap_tx_queue *tx_queue = queue; uint16_t num_tx = 0; uint32_t tx_bytes = 0; - pcap_t *pcap; + osdep_pcap *pcap; unsigned char temp_data[RTE_ETH_PCAP_SNAPLEN]; size_t len; @@ -426,7 +426,7 @@ eth_pcap_tx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) * in the mbuf (when the mbuf is contiguous) or, otherwise, * a pointer to temp_data after copying into it. */ - ret = pcap_sendpacket(pcap, + ret = osdep_pcap_sendpacket(pcap, rte_pktmbuf_read(mbuf, 0, len, temp_data), len); if (unlikely(ret != 0)) break; @@ -443,11 +443,11 @@ eth_pcap_tx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) } /* - * pcap_open_live wrapper function + * osdep_pcap_open_live wrapper function */ static inline int -open_iface_live(const char *iface, pcap_t **pcap) { - *pcap = pcap_open_live(iface, RTE_ETH_PCAP_SNAPLEN, +open_iface_live(const char *iface, osdep_pcap **pcap) { + *pcap = osdep_pcap_open_live(iface, RTE_ETH_PCAP_SNAPLEN, RTE_ETH_PCAP_PROMISC, RTE_ETH_PCAP_TIMEOUT, errbuf); if (*pcap == NULL) { @@ -459,7 +459,7 @@ open_iface_live(const char *iface, pcap_t **pcap) { } static int -open_single_iface(const char *iface, pcap_t **pcap) +open_single_iface(const char *iface, osdep_pcap **pcap) { if (open_iface_live(iface, pcap) < 0) { PMD_LOG(ERR, "Couldn't open interface %s", iface); @@ -470,39 +470,39 @@ open_single_iface(const char *iface, pcap_t **pcap) } static int -open_single_tx_pcap(const char *pcap_filename, pcap_dumper_t **dumper) +open_single_tx_pcap(const char *pcap_filename, osdep_pcap_dumper **dumper) { - pcap_t *tx_pcap; + osdep_pcap *tx_pcap; /* - * We need to create a dummy empty pcap_t to use it - * with pcap_dump_open(). We create big enough an Ethernet + * We need to create a dummy empty osdep_pcap to use it + * with osdep_pcap_dump_open(). We create big enough an Ethernet * pcap holder. */ - tx_pcap = pcap_open_dead_with_tstamp_precision(DLT_EN10MB, - RTE_ETH_PCAP_SNAPSHOT_LEN, PCAP_TSTAMP_PRECISION_NANO); + tx_pcap = osdep_pcap_open_dead_with_tstamp_precision(OSDEP_DLT_EN10MB, + RTE_ETH_PCAP_SNAPSHOT_LEN, OSDEP_PCAP_TSTAMP_PRECISION_NANO); if (tx_pcap == NULL) { PMD_LOG(ERR, "Couldn't create dead pcap"); return -1; } - /* The dumper is created using the previous pcap_t reference */ - *dumper = pcap_dump_open(tx_pcap, pcap_filename); + /* The dumper is created using the previous osdep_pcap reference */ + *dumper = osdep_pcap_dump_open(tx_pcap, pcap_filename); if (*dumper == NULL) { - pcap_close(tx_pcap); + osdep_pcap_close(tx_pcap); PMD_LOG(ERR, "Couldn't open %s for writing.", pcap_filename); return -1; } - pcap_close(tx_pcap); + osdep_pcap_close(tx_pcap); return 0; } static int -open_single_rx_pcap(const char *pcap_filename, pcap_t **pcap) +open_single_rx_pcap(const char *pcap_filename, osdep_pcap **pcap) { - *pcap = pcap_open_offline(pcap_filename, errbuf); + *pcap = osdep_pcap_open_offline(pcap_filename, errbuf); if (*pcap == NULL) { PMD_LOG(ERR, "Couldn't open %s: %s", pcap_filename, errbuf); @@ -513,17 +513,17 @@ open_single_rx_pcap(const char *pcap_filename, pcap_t **pcap) } static uint64_t -count_packets_in_pcap(pcap_t **pcap, struct pcap_rx_queue *pcap_q) +count_packets_in_pcap(osdep_pcap **pcap, struct pcap_rx_queue *pcap_q) { - const u_char *packet; - struct pcap_pkthdr header; + const uint8_t *packet; + struct osdep_pcap_pkthdr header; uint64_t pcap_pkt_count = 0; - while ((packet = pcap_next(*pcap, &header))) + while ((packet = osdep_pcap_next(*pcap, &header))) pcap_pkt_count++; /* The pcap is reopened so it can be used as normal later. */ - pcap_close(*pcap); + osdep_pcap_close(*pcap); *pcap = NULL; open_single_rx_pcap(pcap_q->name, pcap); @@ -612,7 +612,7 @@ eth_dev_stop(struct rte_eth_dev *dev) /* Special iface case. Single pcap is open and shared between tx/rx. */ if (internals->single_iface) { - pcap_close(pp->tx_pcap[0]); + osdep_pcap_close(pp->tx_pcap[0]); pp->tx_pcap[0] = NULL; pp->rx_pcap[0] = NULL; goto status_down; @@ -620,19 +620,19 @@ eth_dev_stop(struct rte_eth_dev *dev) for (i = 0; i < dev->data->nb_tx_queues; i++) { if (pp->tx_dumper[i] != NULL) { - pcap_dump_close(pp->tx_dumper[i]); + osdep_pcap_dump_close(pp->tx_dumper[i]); pp->tx_dumper[i] = NULL; } if (pp->tx_pcap[i] != NULL) { - pcap_close(pp->tx_pcap[i]); + osdep_pcap_close(pp->tx_pcap[i]); pp->tx_pcap[i] = NULL; } } for (i = 0; i < dev->data->nb_rx_queues; i++) { if (pp->rx_pcap[i] != NULL) { - pcap_close(pp->rx_pcap[i]); + osdep_pcap_close(pp->rx_pcap[i]); pp->rx_pcap[i] = NULL; } } @@ -804,11 +804,11 @@ eth_rx_queue_setup(struct rte_eth_dev *dev, if (internals->infinite_rx) { struct pmd_process_private *pp; - char ring_name[NAME_MAX]; + char ring_name[RTE_RING_NAMESIZE]; static uint32_t ring_number; uint64_t pcap_pkt_count = 0; struct rte_mbuf *bufs[1]; - pcap_t **pcap; + osdep_pcap **pcap; pp = rte_eth_devices[pcap_q->port_id].process_private; pcap = &pp->rx_pcap[pcap_q->queue_id]; @@ -932,7 +932,7 @@ static const struct eth_dev_ops ops = { static int add_queue(struct pmd_devargs *pmd, const char *name, const char *type, - pcap_t *pcap, pcap_dumper_t *dumper) + osdep_pcap *pcap, osdep_pcap_dumper *dumper) { if (pmd->num_of_queue >= RTE_PMD_PCAP_MAX_QUEUES) return -1; @@ -955,13 +955,13 @@ open_rx_pcap(const char *key, const char *value, void *extra_args) { const char *pcap_filename = value; struct pmd_devargs *rx = extra_args; - pcap_t *pcap = NULL; + osdep_pcap *pcap = NULL; if (open_single_rx_pcap(pcap_filename, &pcap) < 0) return -1; if (add_queue(rx, pcap_filename, key, pcap, NULL) < 0) { - pcap_close(pcap); + osdep_pcap_close(pcap); return -1; } @@ -977,13 +977,13 @@ open_tx_pcap(const char *key, const char *value, void *extra_args) { const char *pcap_filename = value; struct pmd_devargs *dumpers = extra_args; - pcap_dumper_t *dumper; + osdep_pcap_dumper *dumper; if (open_single_tx_pcap(pcap_filename, &dumper) < 0) return -1; if (add_queue(dumpers, pcap_filename, key, NULL, dumper) < 0) { - pcap_dump_close(dumper); + osdep_pcap_dump_close(dumper); return -1; } @@ -998,7 +998,7 @@ open_rx_tx_iface(const char *key, const char *value, void *extra_args) { const char *iface = value; struct pmd_devargs *tx = extra_args; - pcap_t *pcap = NULL; + osdep_pcap *pcap = NULL; if (open_single_iface(iface, &pcap) < 0) return -1; @@ -1011,13 +1011,14 @@ open_rx_tx_iface(const char *key, const char *value, void *extra_args) } static inline int -set_iface_direction(const char *iface, pcap_t *pcap, - pcap_direction_t direction) +set_iface_direction(const char *iface, osdep_pcap *pcap, + enum osdep_pcap_direction direction) { - const char *direction_str = (direction == PCAP_D_IN) ? "IN" : "OUT"; - if (pcap_setdirection(pcap, direction) < 0) { + const char *direction_str = + (direction == OSDEP_PCAP_D_IN) ? "IN" : "OUT"; + if (osdep_pcap_setdirection(pcap, direction) < 0) { PMD_LOG(ERR, "Setting %s pcap direction %s failed - %s\n", - iface, direction_str, pcap_geterr(pcap)); + iface, direction_str, osdep_pcap_geterr(pcap)); return -1; } PMD_LOG(INFO, "Setting %s pcap direction %s\n", @@ -1030,12 +1031,12 @@ open_iface(const char *key, const char *value, void *extra_args) { const char *iface = value; struct pmd_devargs *pmd = extra_args; - pcap_t *pcap = NULL; + osdep_pcap *pcap = NULL; if (open_single_iface(iface, &pcap) < 0) return -1; if (add_queue(pmd, iface, key, pcap, NULL) < 0) { - pcap_close(pcap); + osdep_pcap_close(pcap); return -1; } @@ -1057,7 +1058,7 @@ open_rx_iface(const char *key, const char *value, void *extra_args) set_iface_direction(pmd->queue[qid].name, pmd->queue[qid].pcap, - PCAP_D_IN); + OSDEP_PCAP_D_IN); } return 0; @@ -1311,7 +1312,7 @@ pmd_pcap_probe(struct rte_vdev_device *dev) name = rte_vdev_device_name(dev); PMD_LOG(INFO, "Initializing pmd_pcap for %s", name); - gettimeofday(&start_time, NULL); + rte_time_get_us(&start_time); start_cycles = rte_get_timer_cycles(); hz = rte_get_timer_hz(); diff --git a/drivers/net/pcap/pcap_osdep.c b/drivers/net/pcap/pcap_osdep.c new file mode 100644 index 000000000..5cac9bb89 --- /dev/null +++ b/drivers/net/pcap/pcap_osdep.c @@ -0,0 +1,122 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2021 Dmitry Kozlyuk + */ + +#include + +#include + +#include "pcap_osdep.h" + +static inline void +to_osdep_header(const struct pcap_pkthdr *in, struct osdep_pcap_pkthdr *out) +{ + out->ts.sec = in->ts.tv_sec; + out->ts.usec = in->ts.tv_usec; + out->caplen = in->caplen; + out->len = in->len; +} + +static inline void +to_pcap_header(const struct osdep_pcap_pkthdr *in, struct pcap_pkthdr *out) +{ + out->ts.tv_sec = in->ts.sec; + out->ts.tv_usec = in->ts.usec; + out->caplen = in->caplen; + out->len = in->len; +} + +osdep_pcap * +osdep_pcap_open_live(const char *device, int snaplen, + int promisc, int to_ms, char *errbuf) +{ + RTE_BUILD_BUG_ON(OSDEP_PCAP_ERRBUF_SIZE != PCAP_ERRBUF_SIZE); + + return (osdep_pcap *)pcap_open_live(device, snaplen, promisc, to_ms, + errbuf); +} + +osdep_pcap * +osdep_pcap_open_offline(const char *fname, char *errbuf) +{ + return (osdep_pcap *)pcap_open_offline(fname, errbuf); +} + +osdep_pcap * +osdep_pcap_open_dead_with_tstamp_precision(int linktype, int snaplen, + unsigned int precision) +{ + RTE_BUILD_BUG_ON(OSDEP_DLT_EN10MB != DLT_EN10MB); + RTE_BUILD_BUG_ON(OSDEP_PCAP_TSTAMP_PRECISION_NANO != + PCAP_TSTAMP_PRECISION_NANO); + + return (osdep_pcap *)pcap_open_dead_with_tstamp_precision(linktype, + snaplen, precision); +} + +const uint8_t * +osdep_pcap_next(osdep_pcap *pcap, struct osdep_pcap_pkthdr *header) +{ + const uint8_t *data; + struct pcap_pkthdr pkthdr; + + data = pcap_next((pcap_t *)pcap, &pkthdr); + to_osdep_header(&pkthdr, header); + return data; +} + +int +osdep_pcap_sendpacket(osdep_pcap *pcap, const uint8_t *buf, int size) +{ + return pcap_sendpacket((pcap_t *)pcap, buf, size); +} + +void +osdep_pcap_close(osdep_pcap *pcap) +{ + pcap_close((pcap_t *)pcap); +} + +osdep_pcap_dumper * +osdep_pcap_dump_open(osdep_pcap *pcap, const char *fname) +{ + return (osdep_pcap_dumper *)pcap_dump_open((pcap_t *)pcap, fname); +} + +void +osdep_pcap_dump(uint8_t *user, const struct osdep_pcap_pkthdr *header, + const uint8_t *sp) +{ + struct pcap_pkthdr pkthdr; + + to_pcap_header(header, &pkthdr); + pcap_dump(user, &pkthdr, sp); +} + +int +osdep_pcap_dump_flush(osdep_pcap_dumper *p) +{ + return pcap_dump_flush((pcap_dumper_t *)p); +} + +void +osdep_pcap_dump_close(osdep_pcap_dumper *p) +{ + pcap_dump_close((pcap_dumper_t *)p); +} + +int +osdep_pcap_setdirection(osdep_pcap *pcap, enum osdep_pcap_direction dir) +{ + RTE_BUILD_BUG_ON((int)OSDEP_PCAP_D_INOUT != (int)PCAP_D_INOUT); + RTE_BUILD_BUG_ON((int)OSDEP_PCAP_D_IN != (int)PCAP_D_IN); + RTE_BUILD_BUG_ON((int)OSDEP_PCAP_D_OUT != (int)PCAP_D_OUT); + + return pcap_setdirection((pcap_t *)pcap, (pcap_direction_t)dir); +} + +const char * +osdep_pcap_geterr(osdep_pcap *pcap) +{ + return pcap_geterr((pcap_t *)pcap); +} diff --git a/drivers/net/pcap/pcap_osdep.h b/drivers/net/pcap/pcap_osdep.h index 46810d86f..bd00b728a 100644 --- a/drivers/net/pcap/pcap_osdep.h +++ b/drivers/net/pcap/pcap_osdep.h @@ -6,6 +6,7 @@ #define _RTE_PCAP_OSDEP_ #include +#include /* * Interface manipulation is always OS-specific. @@ -14,4 +15,53 @@ int osdep_iface_index_get(const char *name); int osdep_iface_mac_get(const char *name, struct rte_ether_addr *mac); +/* + * On Windows, libpcap (npcap or WinPcap) exposes Win32 API which clashes + * with some DPDK constructs. Trivial libpcap wrappers with "osdep_" prefix + * are provided to isolate PMD code from Win32 API. + */ + +#define OSDEP_DLT_EN10MB 1 + +#define OSDEP_PCAP_ERRBUF_SIZE 256 + +#define OSDEP_PCAP_TSTAMP_PRECISION_NANO 1 + +/** Handle for an open packet capture. */ +typedef struct osdep_pcap_type osdep_pcap; + +/** Handle for an open packet dump. */ +typedef struct osdep_pcap_dumper_type osdep_pcap_dumper; + +struct osdep_pcap_pkthdr { + struct rte_time_us ts; + uint32_t caplen; + uint32_t len; +}; + +enum osdep_pcap_direction { + OSDEP_PCAP_D_INOUT = 0, + OSDEP_PCAP_D_IN, + OSDEP_PCAP_D_OUT +}; + +osdep_pcap *osdep_pcap_open_live(const char *device, int snaplen, + int promisc, int to_ms, char *errbuf); +osdep_pcap *osdep_pcap_open_offline(const char *fname, char *errbuf); +osdep_pcap *osdep_pcap_open_dead_with_tstamp_precision(int linktype, + int snaplen, unsigned int precision); +const uint8_t *osdep_pcap_next(osdep_pcap *pcap, + struct osdep_pcap_pkthdr *header); +int osdep_pcap_sendpacket(osdep_pcap *pcap, const uint8_t *buf, int size); +void osdep_pcap_close(osdep_pcap *pcap); + +osdep_pcap_dumper *osdep_pcap_dump_open(osdep_pcap *pcap, const char *fname); +void osdep_pcap_dump(uint8_t *user, const struct osdep_pcap_pkthdr *header, + const uint8_t *sp); +int osdep_pcap_dump_flush(osdep_pcap_dumper *p); +void osdep_pcap_dump_close(osdep_pcap_dumper *p); + +int osdep_pcap_setdirection(osdep_pcap *pcap, enum osdep_pcap_direction dir); +const char *osdep_pcap_geterr(osdep_pcap *pcap); + #endif -- 2.29.2