1a9643ea8Slogwang /*
2*2317ada5Sfengbojiang * Copyright (C) 2017-2021 THL A29 Limited, a Tencent company.
3a9643ea8Slogwang * All rights reserved.
4a9643ea8Slogwang *
5a9643ea8Slogwang * Redistribution and use in source and binary forms, with or without
6a9643ea8Slogwang * modification, are permitted provided that the following conditions are met:
7a9643ea8Slogwang *
8a9643ea8Slogwang * 1. Redistributions of source code must retain the above copyright notice, this
9a9643ea8Slogwang * list of conditions and the following disclaimer.
10a9643ea8Slogwang * 2. Redistributions in binary form must reproduce the above copyright notice,
11a9643ea8Slogwang * this list of conditions and the following disclaimer in the documentation
12a9643ea8Slogwang * and/or other materials provided with the distribution.
13a9643ea8Slogwang *
14a9643ea8Slogwang * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15a9643ea8Slogwang * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16a9643ea8Slogwang * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17a9643ea8Slogwang * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
18a9643ea8Slogwang * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19a9643ea8Slogwang * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20a9643ea8Slogwang * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21a9643ea8Slogwang * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22a9643ea8Slogwang * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23a9643ea8Slogwang * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24a9643ea8Slogwang *
25a9643ea8Slogwang */
26a9643ea8Slogwang
27a9643ea8Slogwang #include <sys/time.h>
28a9643ea8Slogwang #include <unistd.h>
29819aafb6Sjinhao2 #include <errno.h>
30a9643ea8Slogwang
31a9643ea8Slogwang #include "ff_dpdk_pcap.h"
32819aafb6Sjinhao2 #define FILE_PATH_LEN 64
33819aafb6Sjinhao2 #define PCAP_FILE_NUM 10
34a9643ea8Slogwang
35a9643ea8Slogwang struct pcap_file_header {
36a9643ea8Slogwang uint32_t magic;
37a9643ea8Slogwang u_short version_major;
38a9643ea8Slogwang u_short version_minor;
39a9643ea8Slogwang int32_t thiszone; /* gmt to local correction */
40a9643ea8Slogwang uint32_t sigfigs; /* accuracy of timestamps */
41a9643ea8Slogwang uint32_t snaplen; /* max length saved portion of each pkt */
42a9643ea8Slogwang uint32_t linktype; /* data link type (LINKTYPE_*) */
43a9643ea8Slogwang };
44a9643ea8Slogwang
45a9643ea8Slogwang struct pcap_pkthdr {
46a9643ea8Slogwang uint32_t sec; /* time stamp */
47a9643ea8Slogwang uint32_t usec; /* struct timeval time_t, in linux64: 8*2=16, in cap: 4 */
48a9643ea8Slogwang uint32_t caplen; /* length of portion present */
49a9643ea8Slogwang uint32_t len; /* length this packet (off wire) */
50a9643ea8Slogwang };
51a9643ea8Slogwang
52819aafb6Sjinhao2 static __thread FILE* g_pcap_fp = NULL;
53819aafb6Sjinhao2 static __thread uint32_t seq = 0;
54819aafb6Sjinhao2 static __thread uint32_t g_flen = 0;
55819aafb6Sjinhao2
ff_enable_pcap(const char * dump_path,uint16_t snap_len)56819aafb6Sjinhao2 int ff_enable_pcap(const char* dump_path, uint16_t snap_len)
57a9643ea8Slogwang {
58819aafb6Sjinhao2 char pcap_f_path[FILE_PATH_LEN] = {0};
59819aafb6Sjinhao2
60819aafb6Sjinhao2 snprintf(pcap_f_path, FILE_PATH_LEN, "%s/cpu%d_%d.pcap", dump_path==NULL?".":dump_path, rte_lcore_id(), seq);
61819aafb6Sjinhao2 g_pcap_fp = fopen(pcap_f_path, "w+");
62819aafb6Sjinhao2 if (g_pcap_fp == NULL) {
63819aafb6Sjinhao2 rte_exit(EXIT_FAILURE, "Cannot open pcap dump path: %s, errno %d.\n", pcap_f_path, errno);
64a9643ea8Slogwang return -1;
65a9643ea8Slogwang }
66819aafb6Sjinhao2 g_flen = 0;
67a9643ea8Slogwang
68a9643ea8Slogwang struct pcap_file_header pcap_file_hdr;
69a9643ea8Slogwang void* file_hdr = &pcap_file_hdr;
70a9643ea8Slogwang
71a9643ea8Slogwang pcap_file_hdr.magic = 0xA1B2C3D4;
72a9643ea8Slogwang pcap_file_hdr.version_major = 0x0002;
73a9643ea8Slogwang pcap_file_hdr.version_minor = 0x0004;
74a9643ea8Slogwang pcap_file_hdr.thiszone = 0x00000000;
75a9643ea8Slogwang pcap_file_hdr.sigfigs = 0x00000000;
76819aafb6Sjinhao2 pcap_file_hdr.snaplen = snap_len; //0x0000FFFF; //65535
77a9643ea8Slogwang pcap_file_hdr.linktype = 0x00000001; //DLT_EN10MB, Ethernet (10Mb)
78a9643ea8Slogwang
79819aafb6Sjinhao2 fwrite(file_hdr, sizeof(struct pcap_file_header), 1, g_pcap_fp);
80819aafb6Sjinhao2 g_flen += sizeof(struct pcap_file_header);
81a9643ea8Slogwang
82a9643ea8Slogwang return 0;
83a9643ea8Slogwang }
84a9643ea8Slogwang
85a9643ea8Slogwang int
ff_dump_packets(const char * dump_path,struct rte_mbuf * pkt,uint16_t snap_len,uint32_t f_maxlen)86819aafb6Sjinhao2 ff_dump_packets(const char* dump_path, struct rte_mbuf* pkt, uint16_t snap_len, uint32_t f_maxlen)
87a9643ea8Slogwang {
88819aafb6Sjinhao2 unsigned int out_len = 0, wr_len = 0;
89a9643ea8Slogwang struct pcap_pkthdr pcap_hdr;
90a9643ea8Slogwang void* hdr = &pcap_hdr;
91a9643ea8Slogwang struct timeval ts;
92819aafb6Sjinhao2 char pcap_f_path[FILE_PATH_LEN] = {0};
93819aafb6Sjinhao2
94819aafb6Sjinhao2 if (g_pcap_fp == NULL) {
95819aafb6Sjinhao2 return -1;
96819aafb6Sjinhao2 }
97819aafb6Sjinhao2 snap_len = pkt->pkt_len < snap_len ? pkt->pkt_len : snap_len;
98a9643ea8Slogwang gettimeofday(&ts, NULL);
99a9643ea8Slogwang pcap_hdr.sec = ts.tv_sec;
100a9643ea8Slogwang pcap_hdr.usec = ts.tv_usec;
101819aafb6Sjinhao2 pcap_hdr.caplen = snap_len;
102a9643ea8Slogwang pcap_hdr.len = pkt->pkt_len;
103819aafb6Sjinhao2 fwrite(hdr, sizeof(struct pcap_pkthdr), 1, g_pcap_fp);
104819aafb6Sjinhao2 g_flen += sizeof(struct pcap_pkthdr);
105a9643ea8Slogwang
106819aafb6Sjinhao2 while(pkt != NULL && out_len <= snap_len) {
107819aafb6Sjinhao2 wr_len = snap_len - out_len;
108819aafb6Sjinhao2 wr_len = wr_len > pkt->data_len ? pkt->data_len : wr_len ;
109e18b415dSjinhao2 fwrite(rte_pktmbuf_mtod(pkt, char*), wr_len, 1, g_pcap_fp);
110e18b415dSjinhao2 out_len += wr_len;
111a9643ea8Slogwang pkt = pkt->next;
112a9643ea8Slogwang }
113819aafb6Sjinhao2 g_flen += out_len;
114a9643ea8Slogwang
115819aafb6Sjinhao2 if ( g_flen >= f_maxlen ){
116819aafb6Sjinhao2 fclose(g_pcap_fp);
117819aafb6Sjinhao2 if ( ++seq >= PCAP_FILE_NUM )
118819aafb6Sjinhao2 seq = 0;
119819aafb6Sjinhao2
120819aafb6Sjinhao2 ff_enable_pcap(dump_path, snap_len);
121819aafb6Sjinhao2 }
122a9643ea8Slogwang
123a9643ea8Slogwang return 0;
124a9643ea8Slogwang }
125a9643ea8Slogwang
126