]> granicus.if.org Git - strace/blob - tests/nlattr_fib_rule_hdr.c
strace: terminate itself if interrupted by a signal
[strace] / tests / nlattr_fib_rule_hdr.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 #ifdef HAVE_LINUX_FIB_RULES_H
12
13 # include <stdio.h>
14 # include <inttypes.h>
15 # include "test_nlattr.h"
16 # include <linux/fib_rules.h>
17 # include <linux/in.h>
18 # include <linux/ip.h>
19 # include <linux/rtnetlink.h>
20
21 #define FRA_TUN_ID 12
22 #define FRA_TABLE 15
23 #define FRA_UID_RANGE 20
24 #define FRA_PROTOCOL 21
25 #define FRA_IP_PROTO 22
26 #define FRA_SPORT_RANGE 23
27 #define FRA_DPORT_RANGE 24
28
29 # ifndef HAVE_STRUCT_FIB_RULE_PORT_RANGE
30 struct fib_rule_port_range {
31         uint16_t start;
32         uint16_t end;
33 };
34 # endif /* HAVE_STRUCT_FIB_RULE_PORT_RANGE */
35
36 static void
37 init_rtmsg(struct nlmsghdr *const nlh, const unsigned int msg_len)
38 {
39         SET_STRUCT(struct nlmsghdr, nlh,
40                 .nlmsg_len = msg_len,
41                 .nlmsg_type = RTM_GETRULE,
42                 .nlmsg_flags = NLM_F_DUMP
43         );
44
45         struct rtmsg *const msg = NLMSG_DATA(nlh);
46         SET_STRUCT(struct rtmsg, msg,
47                 .rtm_family = AF_UNIX,
48                 .rtm_tos = IPTOS_LOWDELAY,
49                 .rtm_table = RT_TABLE_UNSPEC,
50                 .rtm_type = FR_ACT_TO_TBL,
51                 .rtm_flags = FIB_RULE_INVERT
52         );
53 }
54
55 static void
56 print_rtmsg(const unsigned int msg_len)
57 {
58         printf("{len=%u, type=RTM_GETRULE, flags=NLM_F_DUMP"
59                ", seq=0, pid=0}, {family=AF_UNIX"
60                ", dst_len=0, src_len=0"
61                ", tos=IPTOS_LOWDELAY"
62                ", table=RT_TABLE_UNSPEC"
63                ", action=FR_ACT_TO_TBL"
64                ", flags=FIB_RULE_INVERT}",
65                msg_len);
66 }
67
68 int
69 main(void)
70 {
71         skip_if_unavailable("/proc/self/fd/");
72
73         const int fd = create_nl_socket(NETLINK_ROUTE);
74         const unsigned int hdrlen = sizeof(struct rtmsg);
75         void *nlh0 = midtail_alloc(NLMSG_SPACE(hdrlen), NLA_HDRLEN + 8);
76
77         static char pattern[4096];
78         fill_memory_ex(pattern, sizeof(pattern), 'a', 'z' - 'a' + 1);
79
80         const unsigned int nla_type = 0xffff & NLA_TYPE_MASK;
81         char nla_type_str[256];
82         sprintf(nla_type_str, "%#x /* FRA_??? */", nla_type);
83         TEST_NLATTR_(fd, nlh0, hdrlen,
84                      init_rtmsg, print_rtmsg,
85                      nla_type, nla_type_str,
86                      4, pattern, 4,
87                      print_quoted_hex(pattern, 4));
88
89         TEST_NLATTR(fd, nlh0, hdrlen,
90                     init_rtmsg, print_rtmsg,
91                     FRA_DST, 4, pattern, 4,
92                     print_quoted_hex(pattern, 4));
93
94         const uint32_t table_id = RT_TABLE_DEFAULT;
95         TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
96                            init_rtmsg, print_rtmsg,
97                            FRA_TABLE, pattern, table_id,
98                            printf("RT_TABLE_DEFAULT"));
99
100 #ifdef HAVE_STRUCT_FIB_RULE_UID_RANGE
101         static const struct fib_rule_uid_range range = {
102                 .start = 0xabcdedad,
103                 .end = 0xbcdeadba
104         };
105         TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
106                            init_rtmsg, print_rtmsg,
107                            FRA_UID_RANGE, pattern, range,
108                            PRINT_FIELD_U("{", range, start);
109                            PRINT_FIELD_U(", ", range, end);
110                            printf("}"));
111 #endif
112 #if defined HAVE_BE64TOH || defined be64toh
113         const uint64_t tun_id = 0xabcdcdbeedabadef;
114         TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
115                            init_rtmsg, print_rtmsg,
116                            FRA_TUN_ID, pattern, tun_id,
117                            printf("htobe64(%" PRIu64 ")", be64toh(tun_id)));
118 #endif
119
120         uint8_t proto;
121
122         static const struct {
123                 uint8_t arg;
124                 const char *str;
125         } proto_args[] = {
126                 { ARG_STR(RTPROT_UNSPEC) },
127                 { 5, "0x5 /* RTPROT_??? */" },
128                 { 17, "RTPROT_MROUTED" },
129                 { 42, "RTPROT_BABEL" },
130                 { 43, "0x2b /* RTPROT_??? */" },
131                 { ARG_STR(0xde) " /* RTPROT_??? */" },
132         };
133
134         for (unsigned i = 0; i < ARRAY_SIZE(proto_args); i++) {
135                 proto = proto_args[i].arg;
136                 TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
137                                    init_rtmsg, print_rtmsg,
138                                    FRA_PROTOCOL, pattern, proto,
139                                    printf("%s", proto_args[i].str));
140         }
141
142         static const struct {
143                 uint8_t arg;
144                 const char *str;
145         } ipproto_args[] = {
146                 { ARG_STR(IPPROTO_TCP) },
147                 { 254, "0xfe /* IPPROTO_??? */" },
148                 { ARG_STR(IPPROTO_RAW) },
149         };
150
151         for (unsigned i = 0; i < ARRAY_SIZE(ipproto_args); i++) {
152                 proto = ipproto_args[i].arg;
153                 TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
154                                    init_rtmsg, print_rtmsg,
155                                    FRA_IP_PROTO, pattern, proto,
156                                    printf("%s", ipproto_args[i].str));
157         }
158
159         static const struct fib_rule_port_range prange = {
160                 .start = 0xabcd,
161                 .end = 0xfeed,
162         };
163         TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
164                            init_rtmsg, print_rtmsg,
165                            FRA_SPORT_RANGE, pattern, prange,
166                            PRINT_FIELD_U("{", prange, start);
167                            PRINT_FIELD_U(", ", prange, end);
168                            printf("}"));
169         TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
170                            init_rtmsg, print_rtmsg,
171                            FRA_DPORT_RANGE, pattern, prange,
172                            PRINT_FIELD_U("{", prange, start);
173                            PRINT_FIELD_U(", ", prange, end);
174                            printf("}"));
175
176         puts("+++ exited with 0 +++");
177         return 0;
178 }
179
180 #else
181
182 SKIP_MAIN_UNDEFINED("HAVE_LINUX_FIB_RULES_H")
183
184 #endif