diff options
| author | Qiuwen Lu <[email protected]> | 2020-09-25 10:32:21 +0800 |
|---|---|---|
| committer | Qiuwen Lu <[email protected]> | 2020-09-25 10:32:21 +0800 |
| commit | db786dde8c5c06974de6a270b07c095fc458bc54 (patch) | |
| tree | 1726a4428e5bf800d65d7331242979bfb3f90324 | |
| parent | 22287cc07341fb17f36bd88e553eba09dac660c4 (diff) | |
为pdump工具增加写入PPI头部的功能,将VLAN标志写入保留字段。
| -rw-r--r-- | tools/tcpdump/pdump.c | 129 |
1 files changed, 123 insertions, 6 deletions
diff --git a/tools/tcpdump/pdump.c b/tools/tcpdump/pdump.c index 9e114de..c968115 100644 --- a/tools/tcpdump/pdump.c +++ b/tools/tcpdump/pdump.c @@ -72,6 +72,7 @@ #define CMD_LINE_OPT_DUMPFILE_PATH "dumpfile-path" #define CMD_LINE_OPT_DUMPFILE_COUNT "dumpfile-count" #define CMD_LINE_OPT_BPF_RULE "bpf-rule" +#define CMD_LINE_OPT_USE_PPI_HEADER "use-ppi-header" #define VDEV_PCAP "net_pcap_%s_%d,tx_pcap=%s" #define VDEV_IFACE "net_pcap_%s_%d,tx_iface=%s" @@ -175,6 +176,20 @@ struct parse_val uint64_t val; }; +struct ppi_packetheader +{ + uint8_t pph_version; // Version. Currently 0 + uint8_t pph_flags; // Flags. + uint16_t pph_len; // Length of entire message, including this header and TLV payload. + uint32_t pph_dlt; // libpcap Data Link Type of the captured packet data. +}; + +struct ppi_fieldheader +{ + uint16_t pfh_type; // Type + uint16_t pfh_datalen; // Length of data +}; + int num_tuples; volatile uint8_t quit_signal; static char server_socket_path[PATH_MAX]; @@ -187,6 +202,7 @@ static struct bpf_program bpf_prog; static pcap_dumper_t *pcap_dumper = NULL; static char str_bpf_expr[4096] = {}; static bool is_str_bpf_expr_set = false; +static bool is_use_ppi_header = false; /**< display usage */ static void @@ -207,7 +223,8 @@ pdump_usage(const char *prgname) "[--dumpfile-path=<dumpfile>]" "default:dumpfile.pcap\n" "[--bpf-rule=<bpf-rule>]" - "default:<None>\n", + "default:<None>\n" + "[--use-ppi-header]", prgname); } @@ -401,6 +418,7 @@ launch_args_parse(int argc, char **argv, char *prgname) {"dumpfile-path", 1, 0, 0}, {"dumpfile-count", 1, 0, 0}, {"bpf-rule", 1, 0, 0}, + {"use-ppi-header", 0, 0, 0}, {NULL, 0, 0, 0}}; if (argc == 1) @@ -468,6 +486,13 @@ launch_args_parse(int argc, char **argv, char *prgname) snprintf(str_bpf_expr, sizeof(str_bpf_expr), "%s", optarg); } + if (!strncmp(long_option[option_index].name, + CMD_LINE_OPT_USE_PPI_HEADER, + sizeof(CMD_LINE_OPT_USE_PPI_HEADER))) + { + is_use_ppi_header = true; + } + break; default: @@ -508,6 +533,75 @@ disable_pdump(struct pdump_tuples *pt) rte_pdump_disable(pt->port, pt->queue, pt->dir); } +static char ppi_packet_buffer[128 * 1024 * 1024]; + +struct pfh_data +{ + uint16_t vlan_tci; + uint16_t vlan_tci_outer; +}; + +static int ppi_packet_encap(char *buf, unsigned buflen, struct rte_mbuf *mbuf, const char *pkt, unsigned int pktlen) +{ + char *buf_to_write = buf; + unsigned int write_len = 0; + + /* SECTION A */ + struct ppi_packetheader *ppi_hdr = (struct ppi_packetheader *)buf_to_write; + /* PPI version must be zero */ + ppi_hdr->pph_version = 0; + /* Flags is zero, non-aligned */ + ppi_hdr->pph_flags = 0; + /* Length of entire message, including this header and TLV payload */ + ppi_hdr->pph_len = sizeof(struct ppi_packetheader) + sizeof(struct ppi_fieldheader) + sizeof(struct pfh_data); + /* DLT */ + ppi_hdr->pph_dlt = DLT_EN10MB; + + buf_to_write += sizeof(struct ppi_packetheader); + write_len += sizeof(struct ppi_packetheader); + + /* SECTION B */ + struct ppi_fieldheader *field_hdr = (struct ppi_fieldheader *)buf_to_write; + field_hdr->pfh_type = 30000; + field_hdr->pfh_datalen = sizeof(struct pfh_data); + + buf_to_write += sizeof(struct ppi_fieldheader); + write_len += sizeof(struct ppi_fieldheader); + + /* SECTION C */ + struct pfh_data *phf_data = (struct pfh_data *)buf_to_write; + + if (mbuf->ol_flags & PKT_RX_VLAN || + mbuf->tx_offload & PKT_TX_VLAN_PKT) + { + phf_data->vlan_tci = mbuf->vlan_tci; + } + else + { + phf_data->vlan_tci = 0; + } + + if (mbuf->ol_flags & PKT_RX_QINQ || + mbuf->tx_offload & PKT_TX_QINQ_PKT) + { + phf_data->vlan_tci_outer = mbuf->vlan_tci_outer; + } + else + { + phf_data->vlan_tci_outer = 0; + } + + buf_to_write += sizeof(struct pfh_data); + write_len += sizeof(struct pfh_data); + + /* SECTION D */ + rte_memcpy(buf_to_write, pkt, pktlen); + buf_to_write += pktlen; + write_len += pktlen; + + return write_len; +} + static inline void pdump_rxtx(struct rte_ring *ring, uint16_t vdev_id, struct pdump_stats *stats) { @@ -531,11 +625,26 @@ pdump_rxtx(struct rte_ring *ring, uint16_t vdev_id, struct pdump_stats *stats) struct pcap_pkthdr pcap_pkthdr; gettimeofday(&pcap_pkthdr.ts, NULL); - pcap_pkthdr.caplen = pkt_len; - pcap_pkthdr.len = pkt_len; + const char *to_write_ptr = NULL; + + if (is_use_ppi_header) + { + int ppi_pktlen = ppi_packet_encap(ppi_packet_buffer, sizeof(ppi_packet_buffer), + rxtx_bufs[i], pkt_ptr, pkt_len); + + pcap_pkthdr.caplen = ppi_pktlen; + pcap_pkthdr.len = ppi_pktlen; + to_write_ptr = ppi_packet_buffer; + } + else + { + pcap_pkthdr.caplen = pkt_len; + pcap_pkthdr.len = pkt_len; + to_write_ptr = pkt_ptr; + } /* 写DUMPFILE */ - pcap_dump((u_char *)pcap_dumper, &pcap_pkthdr, (const u_char *)pkt_ptr); + pcap_dump((u_char *)pcap_dumper, &pcap_pkthdr, (const u_char *)to_write_ptr); stats->tx_pkts += 1; } @@ -836,7 +945,15 @@ dump_packets(void) static inline void create_pcap_dumper() { - pcap_handle_dead = pcap_open_dead(DLT_EN10MB, 65535); + if (is_use_ppi_header) + { + pcap_handle_dead = pcap_open_dead(DLT_PPI, 65535); + } + else + { + pcap_handle_dead = pcap_open_dead(DLT_EN10MB, 65535); + } + if (pcap_handle_dead == NULL) { cleanup_pdump_resources(); @@ -852,7 +969,7 @@ static inline void create_pcap_dumper() if (is_str_bpf_expr_set) { - int ret = pcap_compile(pcap_handle_dead, &bpf_prog, str_bpf_expr, 1, PCAP_NETMASK_UNKNOWN); + int ret = pcap_compile_nopcap(65535, DLT_EN10MB, &bpf_prog, str_bpf_expr, 1, PCAP_NETMASK_UNKNOWN); if (ret < 0) { cleanup_pdump_resources(); |
