Skip to content

Commit 45a51bf

Browse files
committed
support nanosecond timestamp precision in pcap dump
1 parent 22608e4 commit 45a51bf

6 files changed

Lines changed: 35 additions & 15 deletions

File tree

config.ini

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,11 +98,16 @@ nb_bond=0
9898
# Each core write into own pcap file, which is open one time, close one time if enough.
9999
# Support dump the first snaplen bytes of each packet.
100100
# if pcap file is lager than savelen bytes, it will be closed and next file was dumped into.
101+
# timestamp_precision: 0 = microseconds (default, standard pcap magic 0xA1B2C3D4),
102+
# 1 = nanoseconds (nanosecond pcap magic 0xA1B23C4D).
103+
# Nanosecond mode uses clock_gettime(CLOCK_REALTIME) for ns-level timestamps.
104+
# Wireshark and tcpdump >= 4.0 can parse nanosecond pcap files automatically.
101105
[pcap]
102106
enable=0
103107
snaplen=96
104108
savelen=16777216
105109
savepath=.
110+
timestamp_precision=0
106111

107112
# Port config section
108113
# Correspond to dpdk.port_list's index: port0, port1...

lib/ff_config.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1033,6 +1033,8 @@ ini_parse_handler(void* user, const char* section, const char* name,
10331033
pconfig->pcap.enable = (uint16_t)atoi(value);
10341034
} else if (strcmp(name, "savepath") == 0) {
10351035
pconfig->pcap.save_path = strdup(value);
1036+
} else if (strcmp(name, "timestamp_precision") == 0) {
1037+
pconfig->pcap.timestamp_precision = (uint8_t)atoi(value);
10361038
}
10371039
} else if (strcmp(section, "rss_check") == 0) {
10381040
return rss_check_cfg_handler(pconfig, section, name, value);

lib/ff_config.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,7 @@ struct ff_config {
338338
uint16_t snap_len;
339339
uint32_t save_len;
340340
char* save_path;
341+
uint8_t timestamp_precision; /* 0=usec (default), 1=nsec */
341342
} pcap;
342343
};
343344

lib/ff_dpdk_if.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ init_lcore_conf(void)
317317

318318
/* Enable pcap dump */
319319
if (ff_global_cfg.pcap.enable) {
320-
ff_enable_pcap(ff_global_cfg.pcap.save_path, ff_global_cfg.pcap.snap_len);
320+
ff_enable_pcap(ff_global_cfg.pcap.save_path, ff_global_cfg.pcap.snap_len, ff_global_cfg.pcap.timestamp_precision);
321321
}
322322

323323
lcore_conf.nb_queue_list[port_id] = pconf->nb_lcores;
@@ -1651,7 +1651,7 @@ process_packets(uint16_t port_id, uint16_t queue_id, struct rte_mbuf **bufs,
16511651

16521652
if (unlikely( ff_global_cfg.pcap.enable)) {
16531653
if (!pkts_from_ring) {
1654-
ff_dump_packets( ff_global_cfg.pcap.save_path, rtem, ff_global_cfg.pcap.snap_len, ff_global_cfg.pcap.save_len);
1654+
ff_dump_packets(ff_global_cfg.pcap.save_path, rtem, ff_global_cfg.pcap.snap_len, ff_global_cfg.pcap.save_len, ff_global_cfg.pcap.timestamp_precision);
16551655
}
16561656
}
16571657

@@ -2048,8 +2048,8 @@ send_burst(struct lcore_conf *qconf, uint16_t n, uint8_t port)
20482048
if (unlikely(ff_global_cfg.pcap.enable)) {
20492049
uint16_t i;
20502050
for (i = 0; i < n; i++) {
2051-
ff_dump_packets( ff_global_cfg.pcap.save_path, m_table[i],
2052-
ff_global_cfg.pcap.snap_len, ff_global_cfg.pcap.save_len);
2051+
ff_dump_packets(ff_global_cfg.pcap.save_path, m_table[i],
2052+
ff_global_cfg.pcap.snap_len, ff_global_cfg.pcap.save_len, ff_global_cfg.pcap.timestamp_precision);
20532053
}
20542054
}
20552055

lib/ff_dpdk_pcap.c

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,15 @@
2525
*/
2626

2727
#include <sys/time.h>
28+
#include <time.h>
2829
#include <unistd.h>
2930
#include <errno.h>
3031

3132
#include "ff_dpdk_pcap.h"
3233
#define FILE_PATH_LEN 64
3334
#define PCAP_FILE_NUM 10
35+
#define PCAP_MAGIC_USEC 0xA1B2C3D4
36+
#define PCAP_MAGIC_NSEC 0xA1B23C4D
3437

3538
struct pcap_file_header {
3639
uint32_t magic;
@@ -44,7 +47,7 @@ struct pcap_file_header {
4447

4548
struct pcap_pkthdr {
4649
uint32_t sec; /* time stamp */
47-
uint32_t usec; /* struct timeval time_t, in linux64: 8*2=16, in cap: 4 */
50+
uint32_t usec_or_nsec; /* usec when magic=0xA1B2C3D4, nsec when magic=0xA1B23C4D */
4851
uint32_t caplen; /* length of portion present */
4952
uint32_t len; /* length this packet (off wire) */
5053
};
@@ -53,7 +56,7 @@ static __thread FILE* g_pcap_fp = NULL;
5356
static __thread uint32_t seq = 0;
5457
static __thread uint32_t g_flen = 0;
5558

56-
int ff_enable_pcap(const char* dump_path, uint16_t snap_len)
59+
int ff_enable_pcap(const char* dump_path, uint16_t snap_len, uint8_t timestamp_precision)
5760
{
5861
char pcap_f_path[FILE_PATH_LEN] = {0};
5962

@@ -68,7 +71,7 @@ int ff_enable_pcap(const char* dump_path, uint16_t snap_len)
6871
struct pcap_file_header pcap_file_hdr;
6972
void* file_hdr = &pcap_file_hdr;
7073

71-
pcap_file_hdr.magic = 0xA1B2C3D4;
74+
pcap_file_hdr.magic = timestamp_precision ? PCAP_MAGIC_NSEC : PCAP_MAGIC_USEC;
7275
pcap_file_hdr.version_major = 0x0002;
7376
pcap_file_hdr.version_minor = 0x0004;
7477
pcap_file_hdr.thiszone = 0x00000000;
@@ -83,21 +86,30 @@ int ff_enable_pcap(const char* dump_path, uint16_t snap_len)
8386
}
8487

8588
int
86-
ff_dump_packets(const char* dump_path, struct rte_mbuf* pkt, uint16_t snap_len, uint32_t f_maxlen)
89+
ff_dump_packets(const char* dump_path, struct rte_mbuf* pkt, uint16_t snap_len, uint32_t f_maxlen, uint8_t timestamp_precision)
8790
{
8891
unsigned int out_len = 0, wr_len = 0;
8992
struct pcap_pkthdr pcap_hdr;
9093
void* hdr = &pcap_hdr;
91-
struct timeval ts;
9294
char pcap_f_path[FILE_PATH_LEN] = {0};
9395

9496
if (g_pcap_fp == NULL) {
9597
return -1;
9698
}
9799
snap_len = pkt->pkt_len < snap_len ? pkt->pkt_len : snap_len;
98-
gettimeofday(&ts, NULL);
99-
pcap_hdr.sec = ts.tv_sec;
100-
pcap_hdr.usec = ts.tv_usec;
100+
101+
if (timestamp_precision) {
102+
struct timespec ts;
103+
clock_gettime(CLOCK_REALTIME, &ts);
104+
pcap_hdr.sec = ts.tv_sec;
105+
pcap_hdr.usec_or_nsec = ts.tv_nsec;
106+
} else {
107+
struct timeval ts;
108+
gettimeofday(&ts, NULL);
109+
pcap_hdr.sec = ts.tv_sec;
110+
pcap_hdr.usec_or_nsec = ts.tv_usec;
111+
}
112+
101113
pcap_hdr.caplen = snap_len;
102114
pcap_hdr.len = pkt->pkt_len;
103115
fwrite(hdr, sizeof(struct pcap_pkthdr), 1, g_pcap_fp);
@@ -117,7 +129,7 @@ ff_dump_packets(const char* dump_path, struct rte_mbuf* pkt, uint16_t snap_len,
117129
if ( ++seq >= PCAP_FILE_NUM )
118130
seq = 0;
119131

120-
ff_enable_pcap(dump_path, snap_len);
132+
ff_enable_pcap(dump_path, snap_len, timestamp_precision);
121133
}
122134

123135
return 0;

lib/ff_dpdk_pcap.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@
3030
#include <rte_config.h>
3131
#include <rte_mbuf.h>
3232

33-
int ff_enable_pcap(const char* dump_path, uint16_t snap_len);
34-
int ff_dump_packets(const char* dump_path, struct rte_mbuf *pkt, uint16_t snap_len, uint32_t f_maxlen);
33+
int ff_enable_pcap(const char* dump_path, uint16_t snap_len, uint8_t timestamp_precision);
34+
int ff_dump_packets(const char* dump_path, struct rte_mbuf *pkt, uint16_t snap_len, uint32_t f_maxlen, uint8_t timestamp_precision);
3535

3636

3737
#endif /* ifndef _FSTACK_DPDK_PCAP_H */

0 commit comments

Comments
 (0)