]> granicus.if.org Git - strace/blob - ptp.c
net: fix off-by-one error in sorted xlat lookup
[strace] / ptp.c
1 /*
2  * Copyright (c) 2014 Stefan Sørensen <stefan.sorensen@spectralink.com>
3  * Copyright (c) 2014-2015 Dmitry V. Levin <ldv@altlinux.org>
4  * Copyright (c) 2014-2018 The strace developers.
5  * All rights reserved.
6  *
7  * SPDX-License-Identifier: LGPL-2.1-or-later
8  */
9
10 #include "defs.h"
11
12 #ifdef HAVE_STRUCT_PTP_SYS_OFFSET
13
14 # include <linux/ioctl.h>
15 # include <linux/ptp_clock.h>
16
17 # include "print_fields.h"
18 # include "xlat/ptp_flags_options.h"
19
20 int
21 ptp_ioctl(struct tcb *const tcp, const unsigned int code,
22           const kernel_ulong_t arg)
23 {
24         if (!verbose(tcp))
25                 return RVAL_DECODED;
26
27         switch (code) {
28         case PTP_EXTTS_REQUEST: {
29                 struct ptp_extts_request extts;
30
31                 tprints(", ");
32                 if (umove_or_printaddr(tcp, arg, &extts))
33                         break;
34
35                 PRINT_FIELD_D("{", extts, index);
36                 PRINT_FIELD_FLAGS(", ", extts, flags, ptp_flags_options, "PTP_???");
37                 tprints("}");
38                 break;
39         }
40
41         case PTP_PEROUT_REQUEST: {
42                 struct ptp_perout_request perout;
43
44                 tprints(", ");
45                 if (umove_or_printaddr(tcp, arg, &perout))
46                         break;
47
48                 PRINT_FIELD_D("{start={", perout.start, sec);
49                 PRINT_FIELD_U(", ", perout.start, nsec);
50                 PRINT_FIELD_D("}, period={", perout.period, sec);
51                 PRINT_FIELD_U(", ", perout.period, nsec);
52                 PRINT_FIELD_D("}, ", perout, index);
53                 PRINT_FIELD_FLAGS(", ", perout, flags, ptp_flags_options, "PTP_???");
54                 tprints("}");
55                 break;
56         }
57
58         case PTP_ENABLE_PPS:
59                 tprintf(", %" PRI_kld, arg);
60                 break;
61
62         case PTP_SYS_OFFSET: {
63                 struct ptp_sys_offset sysoff;
64
65                 if (entering(tcp)) {
66                         tprints(", ");
67                         if (umove_or_printaddr(tcp, arg, &sysoff))
68                                 break;
69
70                         PRINT_FIELD_U("{", sysoff, n_samples);
71                         return 0;
72                 } else {
73                         unsigned int n_samples, i;
74
75                         if (syserror(tcp)) {
76                                 tprints("}");
77                                 break;
78                         }
79
80                         tprints(", ");
81                         if (umove(tcp, arg, &sysoff) < 0) {
82                                 tprints("???}");
83                                 break;
84                         }
85
86                         tprints("ts=[");
87                         n_samples = sysoff.n_samples > PTP_MAX_SAMPLES ?
88                                 PTP_MAX_SAMPLES : sysoff.n_samples;
89                         for (i = 0; i < 2 * n_samples + 1; ++i) {
90                                 if (i > 0)
91                                         tprints(", ");
92                                 PRINT_FIELD_D("{", sysoff.ts[i], sec);
93                                 PRINT_FIELD_U(", ", sysoff.ts[i], nsec);
94                                 tprints("}");
95                         }
96                         if (sysoff.n_samples > PTP_MAX_SAMPLES)
97                                 tprints(", ...");
98                         tprints("]}");
99                         break;
100                 }
101         }
102         case PTP_CLOCK_GETCAPS: {
103                 struct ptp_clock_caps caps;
104
105                 if (entering(tcp))
106                         return 0;
107
108                 tprints(", ");
109                 if (umove_or_printaddr(tcp, arg, &caps))
110                         break;
111
112                 PRINT_FIELD_D("{", caps, max_adj);
113                 PRINT_FIELD_D(", ", caps, n_alarm);
114                 PRINT_FIELD_D(", ", caps, n_ext_ts);
115                 PRINT_FIELD_D(", ", caps, n_per_out);
116                 PRINT_FIELD_D(", ", caps, pps);
117                 tprints("}");
118                 break;
119         }
120
121         default:
122                 return RVAL_DECODED;
123         }
124
125         return RVAL_IOCTL_DECODED;
126 }
127
128 #endif /* HAVE_STRUCT_PTP_SYS_OFFSET */