]> granicus.if.org Git - strace/blob - tests/nlattr_ifinfomsg.c
strace: terminate itself if interrupted by a signal
[strace] / tests / nlattr_ifinfomsg.c
1 /*
2  * Copyright (c) 2017 JingPiao Chen <chenjingpiao@gmail.com>
3  * Copyright (c) 2017-2018 The strace developers.
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: GPL-2.0-or-later
7  */
8
9 #include "tests.h"
10
11 #include <stdio.h>
12 #include <stddef.h>
13 #include "test_nlattr.h"
14
15 #include <linux/if.h>
16 #include <linux/if_arp.h>
17 #ifdef HAVE_LINUX_IF_LINK_H
18 # include <linux/if_link.h>
19 #endif
20 #include <linux/rtnetlink.h>
21
22 #ifndef IFLA_LINKINFO
23 # define IFLA_LINKINFO 18
24 #endif
25 #ifndef IFLA_VF_PORTS
26 # define IFLA_VF_PORTS 24
27 #endif
28 #define IFLA_LINK_NETNSID 37
29 #define IFLA_EVENT 44
30
31 #ifndef IFLA_INFO_KIND
32 # define IFLA_INFO_KIND 1
33 #endif
34
35 #ifndef IFLA_VF_PORT
36 # define IFLA_VF_PORT 1
37 #endif
38
39 static void
40 init_ifinfomsg(struct nlmsghdr *const nlh, const unsigned int msg_len)
41 {
42         SET_STRUCT(struct nlmsghdr, nlh,
43                 .nlmsg_len = msg_len,
44                 .nlmsg_type = RTM_GETLINK,
45                 .nlmsg_flags = NLM_F_DUMP
46         );
47
48         struct ifinfomsg *const msg = NLMSG_DATA(nlh);
49         SET_STRUCT(struct ifinfomsg, msg,
50                 .ifi_family = AF_UNIX,
51                 .ifi_type = ARPHRD_LOOPBACK,
52                 .ifi_index = ifindex_lo(),
53                 .ifi_flags = IFF_UP,
54         );
55 }
56
57 static void
58 print_ifinfomsg(const unsigned int msg_len)
59 {
60         printf("{len=%u, type=RTM_GETLINK, flags=NLM_F_DUMP"
61                ", seq=0, pid=0}, {ifi_family=AF_UNIX"
62                ", ifi_type=ARPHRD_LOOPBACK"
63                ", ifi_index=" IFINDEX_LO_STR
64                ", ifi_flags=IFF_UP, ifi_change=0}",
65                msg_len);
66 }
67
68 int
69 main(void)
70 {
71         skip_if_unavailable("/proc/self/fd/");
72
73         static const struct rtnl_link_stats st = {
74                 .rx_packets = 0xabcdefac,
75                 .tx_packets = 0xbcdacdab,
76                 .rx_bytes = 0xcdbafaab,
77                 .tx_bytes = 0xdafabadb,
78                 .rx_errors = 0xeabcdaeb,
79                 .tx_errors = 0xfefabeab,
80                 .rx_dropped = 0xadbafafb,
81                 .tx_dropped = 0xbdffabda,
82                 .multicast = 0xcdabdfea,
83                 .collisions = 0xefadbaeb,
84                 .rx_length_errors = 0xfabffabd,
85                 .rx_over_errors = 0xafbafabc,
86                 .rx_crc_errors = 0xbfdabdad,
87                 .rx_frame_errors = 0xcfdabfad,
88                 .rx_fifo_errors = 0xddfdebad,
89                 .rx_missed_errors = 0xefabdcba,
90                 .tx_aborted_errors = 0xefdadbfa,
91                 .tx_carrier_errors = 0xfaefbada,
92                 .tx_fifo_errors = 0xaebdffab,
93                 .tx_heartbeat_errors = 0xbadebaaf,
94                 .tx_window_errors = 0xcdafbada,
95                 .rx_compressed = 0xdeffadbd,
96                 .tx_compressed = 0xefdadfab
97         };
98         const int fd = create_nl_socket(NETLINK_ROUTE);
99         const unsigned int hdrlen = sizeof(struct ifinfomsg);
100         void *nlh0 = midtail_alloc(NLMSG_SPACE(hdrlen),
101                                    NLA_HDRLEN + sizeof(st));
102
103         static char pattern[4096];
104         fill_memory_ex(pattern, sizeof(pattern), 'a', 'z' - 'a' + 1);
105
106         const unsigned int nla_type = 0xffff & NLA_TYPE_MASK;
107         char nla_type_str[256];
108         sprintf(nla_type_str, "%#x /* IFLA_??? */", nla_type);
109         TEST_NLATTR_(fd, nlh0, hdrlen,
110                      init_ifinfomsg, print_ifinfomsg,
111                      nla_type, nla_type_str,
112                      4, pattern, 4,
113                      print_quoted_hex(pattern, 4));
114
115         const int32_t netnsid = 0xacbdabda;
116         TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
117                            init_ifinfomsg, print_ifinfomsg,
118                            IFLA_LINK_NETNSID, pattern, netnsid,
119                            printf("%d", netnsid));
120
121         TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
122                            init_ifinfomsg, print_ifinfomsg,
123                            IFLA_STATS, pattern, st,
124                            PRINT_FIELD_U("{", st, rx_packets);
125                            PRINT_FIELD_U(", ", st, tx_packets);
126                            PRINT_FIELD_U(", ", st, rx_bytes);
127                            PRINT_FIELD_U(", ", st, tx_bytes);
128                            PRINT_FIELD_U(", ", st, rx_errors);
129                            PRINT_FIELD_U(", ", st, tx_errors);
130                            PRINT_FIELD_U(", ", st, rx_dropped);
131                            PRINT_FIELD_U(", ", st, tx_dropped);
132                            PRINT_FIELD_U(", ", st, multicast);
133                            PRINT_FIELD_U(", ", st, collisions);
134                            PRINT_FIELD_U(", ", st, rx_length_errors);
135                            PRINT_FIELD_U(", ", st, rx_over_errors);
136                            PRINT_FIELD_U(", ", st, rx_crc_errors);
137                            PRINT_FIELD_U(", ", st, rx_frame_errors);
138                            PRINT_FIELD_U(", ", st, rx_fifo_errors);
139                            PRINT_FIELD_U(", ", st, rx_missed_errors);
140                            PRINT_FIELD_U(", ", st, tx_aborted_errors);
141                            PRINT_FIELD_U(", ", st, tx_carrier_errors);
142                            PRINT_FIELD_U(", ", st, tx_fifo_errors);
143                            PRINT_FIELD_U(", ", st, tx_heartbeat_errors);
144                            PRINT_FIELD_U(", ", st, tx_window_errors);
145                            PRINT_FIELD_U(", ", st, rx_compressed);
146                            PRINT_FIELD_U(", ", st, tx_compressed);
147 #ifdef HAVE_STRUCT_RTNL_LINK_STATS_RX_NOHANDLER
148                            PRINT_FIELD_U(", ", st, rx_nohandler);
149 #endif
150                            printf("}"));
151
152 #ifdef HAVE_STRUCT_RTNL_LINK_STATS_RX_NOHANDLER
153         const unsigned int sizeof_stats =
154                 offsetofend(struct rtnl_link_stats, tx_compressed);
155         TEST_NLATTR(fd, nlh0, hdrlen,
156                     init_ifinfomsg, print_ifinfomsg,
157                     IFLA_STATS, sizeof_stats, &st, sizeof_stats,
158                     PRINT_FIELD_U("{", st, rx_packets);
159                     PRINT_FIELD_U(", ", st, tx_packets);
160                     PRINT_FIELD_U(", ", st, rx_bytes);
161                     PRINT_FIELD_U(", ", st, tx_bytes);
162                     PRINT_FIELD_U(", ", st, rx_errors);
163                     PRINT_FIELD_U(", ", st, tx_errors);
164                     PRINT_FIELD_U(", ", st, rx_dropped);
165                     PRINT_FIELD_U(", ", st, tx_dropped);
166                     PRINT_FIELD_U(", ", st, multicast);
167                     PRINT_FIELD_U(", ", st, collisions);
168                     PRINT_FIELD_U(", ", st, rx_length_errors);
169                     PRINT_FIELD_U(", ", st, rx_over_errors);
170                     PRINT_FIELD_U(", ", st, rx_crc_errors);
171                     PRINT_FIELD_U(", ", st, rx_frame_errors);
172                     PRINT_FIELD_U(", ", st, rx_fifo_errors);
173                     PRINT_FIELD_U(", ", st, rx_missed_errors);
174                     PRINT_FIELD_U(", ", st, tx_aborted_errors);
175                     PRINT_FIELD_U(", ", st, tx_carrier_errors);
176                     PRINT_FIELD_U(", ", st, tx_fifo_errors);
177                     PRINT_FIELD_U(", ", st, tx_heartbeat_errors);
178                     PRINT_FIELD_U(", ", st, tx_window_errors);
179                     PRINT_FIELD_U(", ", st, rx_compressed);
180                     PRINT_FIELD_U(", ", st, tx_compressed);
181                     printf("}"));
182 #endif /* HAVE_STRUCT_RTNL_LINK_STATS_RX_NOHANDLER */
183
184         static const struct rtnl_link_ifmap map = {
185                 .mem_start = 0xadcbefedefbcdedb,
186                 .mem_end = 0xefcbeabdecdcdefa,
187                 .base_addr = 0xaddbeabdfaacdbae,
188                 .irq = 0xefaf,
189                 .dma = 0xab,
190                 .port = 0xcd
191         };
192         const unsigned int sizeof_ifmap =
193                 offsetofend(struct rtnl_link_ifmap, port);
194         const unsigned int plen = sizeof_ifmap - 1 > DEFAULT_STRLEN
195                                   ? DEFAULT_STRLEN
196                                   : (int) sizeof_ifmap - 1;
197         /* len < sizeof_ifmap */
198         TEST_NLATTR(fd, nlh0, hdrlen,
199                     init_ifinfomsg, print_ifinfomsg,
200                     IFLA_MAP, plen, pattern, plen,
201                     print_quoted_hex(pattern, plen));
202
203         /* short read of sizeof_ifmap */
204         TEST_NLATTR(fd, nlh0, hdrlen,
205                     init_ifinfomsg, print_ifinfomsg,
206                     IFLA_MAP, sizeof_ifmap, &map, sizeof_ifmap - 1,
207                     printf("%p", RTA_DATA(TEST_NLATTR_nla)));
208
209         /* sizeof_ifmap */
210         TEST_NLATTR(fd, nlh0, hdrlen,
211                     init_ifinfomsg, print_ifinfomsg,
212                     IFLA_MAP, sizeof_ifmap, &map, sizeof_ifmap,
213                     PRINT_FIELD_X("{", map, mem_start);
214                     PRINT_FIELD_X(", ", map, mem_end);
215                     PRINT_FIELD_X(", ", map, base_addr);
216                     PRINT_FIELD_U(", ", map, irq);
217                     PRINT_FIELD_U(", ", map, dma);
218                     PRINT_FIELD_U(", ", map, port);
219                     printf("}"));
220
221 #ifdef HAVE_STRUCT_RTNL_LINK_STATS64
222         static const struct rtnl_link_stats64 st64 = {
223                 .rx_packets = 0xadcbefedefbcdedb,
224                 .tx_packets = 0xbdabdedabdcdeabd,
225                 .rx_bytes = 0xcdbaefbaeadfabec,
226                 .tx_bytes = 0xdbaedbafabbeacdb,
227                 .rx_errors = 0xefabfdaefabaefab,
228                 .tx_errors = 0xfaebfabfabbaeabf,
229                 .rx_dropped = 0xacdbaedbadbabeba,
230                 .tx_dropped = 0xbcdeffebdabeadbe,
231                 .multicast = 0xeeffbaeabaeffabe,
232                 .collisions = 0xffbaefcefbafacef,
233                 .rx_length_errors = 0xaabbdeabceffdecb,
234                 .rx_over_errors = 0xbbdcdadebadeaeed,
235                 .rx_crc_errors= 0xccdeabecefaedbef,
236                 .rx_frame_errors = 0xddbedaedebcedaef,
237                 .rx_fifo_errors = 0xeffbadefafdaeaab,
238                 .rx_missed_errors = 0xfefaebccceadeecd,
239                 .tx_aborted_errors = 0xabcdadefcdadef,
240                 .tx_carrier_errors = 0xbccdafaeeaaefe,
241                 .tx_fifo_errors = 0xcddefdbedeadce,
242                 .tx_heartbeat_errors = 0xedaededdadcdea,
243                 .tx_window_errors = 0xfdacdeaccedcda,
244                 .rx_compressed = 0xacdbbcacdbccef,
245                 .tx_compressed = 0xbcdadefcdedfea
246         };
247         TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
248                            init_ifinfomsg, print_ifinfomsg,
249                            IFLA_STATS64, pattern, st64,
250                            PRINT_FIELD_U("{", st64, rx_packets);
251                            PRINT_FIELD_U(", ", st64, tx_packets);
252                            PRINT_FIELD_U(", ", st64, rx_bytes);
253                            PRINT_FIELD_U(", ", st64, tx_bytes);
254                            PRINT_FIELD_U(", ", st64, rx_errors);
255                            PRINT_FIELD_U(", ", st64, tx_errors);
256                            PRINT_FIELD_U(", ", st64, rx_dropped);
257                            PRINT_FIELD_U(", ", st64, tx_dropped);
258                            PRINT_FIELD_U(", ", st64, multicast);
259                            PRINT_FIELD_U(", ", st64, collisions);
260                            PRINT_FIELD_U(", ", st64, rx_length_errors);
261                            PRINT_FIELD_U(", ", st64, rx_over_errors);
262                            PRINT_FIELD_U(", ", st64, rx_crc_errors);
263                            PRINT_FIELD_U(", ", st64, rx_frame_errors);
264                            PRINT_FIELD_U(", ", st64, rx_fifo_errors);
265                            PRINT_FIELD_U(", ", st64, rx_missed_errors);
266                            PRINT_FIELD_U(", ", st64, tx_aborted_errors);
267                            PRINT_FIELD_U(", ", st64, tx_carrier_errors);
268                            PRINT_FIELD_U(", ", st64, tx_fifo_errors);
269                            PRINT_FIELD_U(", ", st64, tx_heartbeat_errors);
270                            PRINT_FIELD_U(", ", st64, tx_window_errors);
271                            PRINT_FIELD_U(", ", st64, rx_compressed);
272                            PRINT_FIELD_U(", ", st64, tx_compressed);
273 #ifdef HAVE_STRUCT_RTNL_LINK_STATS64_RX_NOHANDLER
274                            PRINT_FIELD_U(", ", st64, rx_nohandler);
275 #endif
276                            printf("}"));
277
278 #ifdef HAVE_STRUCT_RTNL_LINK_STATS64_RX_NOHANDLER
279         const unsigned int sizeof_stats64 =
280                 offsetofend(struct rtnl_link_stats64, tx_compressed);
281         TEST_NLATTR(fd, nlh0, hdrlen,
282                     init_ifinfomsg, print_ifinfomsg,
283                     IFLA_STATS64, sizeof_stats64, &st64, sizeof_stats64,
284                     PRINT_FIELD_U("{", st64, rx_packets);
285                     PRINT_FIELD_U(", ", st64, tx_packets);
286                     PRINT_FIELD_U(", ", st64, rx_bytes);
287                     PRINT_FIELD_U(", ", st64, tx_bytes);
288                     PRINT_FIELD_U(", ", st64, rx_errors);
289                     PRINT_FIELD_U(", ", st64, tx_errors);
290                     PRINT_FIELD_U(", ", st64, rx_dropped);
291                     PRINT_FIELD_U(", ", st64, tx_dropped);
292                     PRINT_FIELD_U(", ", st64, multicast);
293                     PRINT_FIELD_U(", ", st64, collisions);
294                     PRINT_FIELD_U(", ", st64, rx_length_errors);
295                     PRINT_FIELD_U(", ", st64, rx_over_errors);
296                     PRINT_FIELD_U(", ", st64, rx_crc_errors);
297                     PRINT_FIELD_U(", ", st64, rx_frame_errors);
298                     PRINT_FIELD_U(", ", st64, rx_fifo_errors);
299                     PRINT_FIELD_U(", ", st64, rx_missed_errors);
300                     PRINT_FIELD_U(", ", st64, tx_aborted_errors);
301                     PRINT_FIELD_U(", ", st64, tx_carrier_errors);
302                     PRINT_FIELD_U(", ", st64, tx_fifo_errors);
303                     PRINT_FIELD_U(", ", st64, tx_heartbeat_errors);
304                     PRINT_FIELD_U(", ", st64, tx_window_errors);
305                     PRINT_FIELD_U(", ", st64, rx_compressed);
306                     PRINT_FIELD_U(", ", st64, tx_compressed);
307                     printf("}"));
308 #endif /* HAVE_STRUCT_RTNL_LINK_STATS64_RX_NOHANDLER */
309 #endif /* HAVE_STRUCT_RTNL_LINK_STATS64 */
310
311         struct nlattr nla = {
312                 .nla_len = sizeof(nla),
313                 .nla_type = IFLA_INFO_KIND,
314         };
315         TEST_NLATTR(fd, nlh0, hdrlen,
316                     init_ifinfomsg, print_ifinfomsg,
317                     IFLA_LINKINFO, sizeof(nla), &nla, sizeof(nla),
318                     printf("{nla_len=%u, nla_type=IFLA_INFO_KIND}",
319                            nla.nla_len));
320
321         nla.nla_type = IFLA_VF_PORT;
322         TEST_NLATTR(fd, nlh0, hdrlen,
323                     init_ifinfomsg, print_ifinfomsg,
324                     IFLA_VF_PORTS, sizeof(nla), &nla, sizeof(nla),
325                     printf("{nla_len=%u, nla_type=IFLA_VF_PORT}",
326                            nla.nla_len));
327
328         static const struct {
329                 uint32_t val;
330                 const char *str;
331         } ifla_events[] = {
332                 { 0, "IFLA_EVENT_NONE" },
333                 { 6, "IFLA_EVENT_BONDING_OPTIONS" },
334                 { ARG_STR(0x7) " /* IFLA_EVENT_??? */" },
335                 { ARG_STR(0xdeadfeed) " /* IFLA_EVENT_??? */" },
336         };
337         for (size_t i = 0; i < ARRAY_SIZE(ifla_events); i++) {
338                 TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
339                                    init_ifinfomsg, print_ifinfomsg,
340                                    IFLA_EVENT, pattern, ifla_events[i].val,
341                                    printf("%s", ifla_events[i].str));
342         }
343
344         puts("+++ exited with 0 +++");
345         return 0;
346 }