summaryrefslogtreecommitdiffstats
path: root/Documentation/networking/timestamping/txtimestamp.c
diff options
context:
space:
mode:
Diffstat (limited to 'Documentation/networking/timestamping/txtimestamp.c')
-rw-r--r--Documentation/networking/timestamping/txtimestamp.c38
1 files changed, 26 insertions, 12 deletions
diff --git a/Documentation/networking/timestamping/txtimestamp.c b/Documentation/networking/timestamping/txtimestamp.c
index 876f71c5625a..8217510d3842 100644
--- a/Documentation/networking/timestamping/txtimestamp.c
+++ b/Documentation/networking/timestamping/txtimestamp.c
@@ -30,6 +30,8 @@
* 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
*/
+#define _GNU_SOURCE
+
#include <arpa/inet.h>
#include <asm/types.h>
#include <error.h>
@@ -59,14 +61,6 @@
#include <time.h>
#include <unistd.h>
-/* ugly hack to work around netinet/in.h and linux/ipv6.h conflicts */
-#ifndef in6_pktinfo
-struct in6_pktinfo {
- struct in6_addr ipi6_addr;
- int ipi6_ifindex;
-};
-#endif
-
/* command line parameters */
static int cfg_proto = SOCK_STREAM;
static int cfg_ipproto = IPPROTO_TCP;
@@ -76,6 +70,7 @@ static int do_ipv6 = 1;
static int cfg_payload_len = 10;
static bool cfg_show_payload;
static bool cfg_do_pktinfo;
+static bool cfg_loop_nodata;
static uint16_t dest_port = 9000;
static struct sockaddr_in daddr;
@@ -147,6 +142,9 @@ static void print_payload(char *data, int len)
{
int i;
+ if (!len)
+ return;
+
if (len > 70)
len = 70;
@@ -183,6 +181,7 @@ static void __recv_errmsg_cmsg(struct msghdr *msg, int payload_len)
struct sock_extended_err *serr = NULL;
struct scm_timestamping *tss = NULL;
struct cmsghdr *cm;
+ int batch = 0;
for (cm = CMSG_FIRSTHDR(msg);
cm && cm->cmsg_len;
@@ -215,10 +214,18 @@ static void __recv_errmsg_cmsg(struct msghdr *msg, int payload_len)
} else
fprintf(stderr, "unknown cmsg %d,%d\n",
cm->cmsg_level, cm->cmsg_type);
+
+ if (serr && tss) {
+ print_timestamp(tss, serr->ee_info, serr->ee_data,
+ payload_len);
+ serr = NULL;
+ tss = NULL;
+ batch++;
+ }
}
- if (serr && tss)
- print_timestamp(tss, serr->ee_info, serr->ee_data, payload_len);
+ if (batch > 1)
+ fprintf(stderr, "batched %d timestamps\n", batch);
}
static int recv_errmsg(int fd)
@@ -250,7 +257,7 @@ static int recv_errmsg(int fd)
if (ret == -1 && errno != EAGAIN)
error(1, errno, "recvmsg");
- if (ret > 0) {
+ if (ret >= 0) {
__recv_errmsg_cmsg(&msg, ret);
if (cfg_show_payload)
print_payload(data, cfg_payload_len);
@@ -315,6 +322,9 @@ static void do_test(int family, unsigned int opt)
opt |= SOF_TIMESTAMPING_SOFTWARE |
SOF_TIMESTAMPING_OPT_CMSG |
SOF_TIMESTAMPING_OPT_ID;
+ if (cfg_loop_nodata)
+ opt |= SOF_TIMESTAMPING_OPT_TSONLY;
+
if (setsockopt(fd, SOL_SOCKET, SO_TIMESTAMPING,
(char *) &opt, sizeof(opt)))
error(1, 0, "setsockopt timestamping");
@@ -384,6 +394,7 @@ static void __attribute__((noreturn)) usage(const char *filepath)
" -h: show this message\n"
" -I: request PKTINFO\n"
" -l N: send N bytes at a time\n"
+ " -n: set no-payload option\n"
" -r: use raw\n"
" -R: use raw (IP_HDRINCL)\n"
" -p N: connect to port N\n"
@@ -398,7 +409,7 @@ static void parse_opt(int argc, char **argv)
int proto_count = 0;
char c;
- while ((c = getopt(argc, argv, "46hIl:p:rRux")) != -1) {
+ while ((c = getopt(argc, argv, "46hIl:np:rRux")) != -1) {
switch (c) {
case '4':
do_ipv6 = 0;
@@ -409,6 +420,9 @@ static void parse_opt(int argc, char **argv)
case 'I':
cfg_do_pktinfo = true;
break;
+ case 'n':
+ cfg_loop_nodata = true;
+ break;
case 'r':
proto_count++;
cfg_proto = SOCK_RAW;