1 /*
2 * Copyright (c) 2023 Eugene Syromyatnikov <evgsyr@gmail.com>
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 */
7
8 #include "tests.h"
9
10 #include <limits.h>
11 #include <stdio.h>
12 #include <unistd.h>
13 #include <arpa/inet.h>
14 #include <netinet/in.h>
15 #include <sys/socket.h>
16
17 #ifndef IP_LOCAL_PORT_RANGE
18 # define IP_LOCAL_PORT_RANGE 51
19 #endif
20
21 #ifndef INJSTR
22 # define INJSTR ""
23 #endif
24
25 int
26 main(void)
27 {
28 static const struct strval32 opts[] = {
29 { 0, NULL },
30 { 1, "1.." },
31 { 12345, "12345.." },
32 { 0xbeef, "48879.." },
33 { 0x10000, "..1" },
34 { 12345 << 16, "..12345" },
35 { 0x12341234U, "4660..4660" },
36 { 0x87654321U, "17185..34661" },
37 { 0xbadc0dedU, "3565..47836" },
38 { 0xbeef0000U, "..48879" },
39 { 0xbeef0001U, "1..48879" },
40 { 0xbeefbeefU, "48879..48879" },
41 { 0xbeeffaceU, NULL },
42 };
43
44 TAIL_ALLOC_OBJECT_CONST_PTR(unsigned int, ports);
45 TAIL_ALLOC_OBJECT_CONST_ARR(unsigned int, big_ports, 2);
46 const char *errstr;
47 socklen_t len;
48 int rc;
49
50 for (unsigned int i = 0; i < ARRAY_SIZE(opts); ++i) {
51 *ports = opts[i].val;
52
53 /* optlen < 0, EINVAL */
54 len = -1;
55 rc = setsockopt(0, SOL_IP, IP_LOCAL_PORT_RANGE, ports, len);
56 printf("setsockopt(0, " XLAT_FMT ", " XLAT_FMT ", %p, -1) = %s"
57 INJSTR "\n",
58 XLAT_ARGS(SOL_IP), XLAT_ARGS(IP_LOCAL_PORT_RANGE),
59 ports, sprintrc(rc));
60
61 rc = getsockopt(0, SOL_IP, IP_LOCAL_PORT_RANGE, ports, &len);
62 printf("getsockopt(0, " XLAT_FMT ", " XLAT_FMT ", %p, [-1]) = %s"
63 INJSTR "\n",
64 XLAT_ARGS(SOL_IP), XLAT_ARGS(IP_LOCAL_PORT_RANGE),
65 ports, sprintrc(rc));
66
67
68 /* optlen = 0, EINVAL */
69 len = 0;
70 rc = setsockopt(0, SOL_IP, IP_LOCAL_PORT_RANGE, ports, len);
71 printf("setsockopt(0, " XLAT_FMT ", " XLAT_FMT ", \"\", 0) = %s"
72 INJSTR "\n",
73 XLAT_ARGS(SOL_IP), XLAT_ARGS(IP_LOCAL_PORT_RANGE),
74 sprintrc(rc));
75
76 rc = getsockopt(0, SOL_IP, IP_LOCAL_PORT_RANGE, ports, &len);
77 printf("getsockopt(0, " XLAT_FMT ", " XLAT_FMT ", %p, [0]) = %s"
78 INJSTR "\n",
79 XLAT_ARGS(SOL_IP), XLAT_ARGS(IP_LOCAL_PORT_RANGE),
80 ports, sprintrc(rc));
81
82
83 /* optlen < sizeof(int), EINVAL */
84 len = sizeof(*ports) - 1;
85 rc = setsockopt(0, SOL_IP, IP_LOCAL_PORT_RANGE, ports, len);
86 errstr = sprintrc(rc);
87 printf("setsockopt(0, " XLAT_FMT ", " XLAT_FMT ", ",
88 XLAT_ARGS(SOL_IP), XLAT_ARGS(IP_LOCAL_PORT_RANGE));
89 print_quoted_hex(ports, len);
90 printf(", 3) = %s" INJSTR "\n", errstr);
91
92 rc = getsockopt(0, SOL_IP, IP_LOCAL_PORT_RANGE, ports, &len);
93 errstr = sprintrc(rc);
94 printf("getsockopt(0, " XLAT_FMT ", " XLAT_FMT ", ",
95 XLAT_ARGS(SOL_IP), XLAT_ARGS(IP_LOCAL_PORT_RANGE));
96 if (INJSTR[0])
97 print_quoted_hex(ports, len);
98 else
99 printf("%p", ports);
100 printf(", [3]) = %s" INJSTR "\n", errstr);
101
102
103 /* optval EFAULT */
104 len = sizeof(*ports);
105 rc = setsockopt(0, SOL_IP, IP_LOCAL_PORT_RANGE, ports + 1, len);
106 printf("setsockopt(0, " XLAT_FMT ", " XLAT_FMT ", %p, 4) = %s"
107 INJSTR "\n",
108 XLAT_ARGS(SOL_IP), XLAT_ARGS(IP_LOCAL_PORT_RANGE),
109 ports + 1, sprintrc(rc));
110
111 rc = getsockopt(0, SOL_IP, IP_LOCAL_PORT_RANGE, ports + 1, &len);
112 printf("getsockopt(0, " XLAT_FMT ", " XLAT_FMT ", %p, [4]) = %s"
113 INJSTR "\n",
114 XLAT_ARGS(SOL_IP), XLAT_ARGS(IP_LOCAL_PORT_RANGE),
115 ports + 1, sprintrc(rc));
116
117
118 /* classic */
119 len = sizeof(*ports);
120 rc = setsockopt(0, SOL_IP, IP_LOCAL_PORT_RANGE, ports, len);
121 printf("setsockopt(0, " XLAT_FMT ", " XLAT_FMT ", [%#x%s%s%s]"
122 ", 4) = %s" INJSTR "\n",
123 XLAT_ARGS(SOL_IP), XLAT_ARGS(IP_LOCAL_PORT_RANGE),
124 *ports,
125 !XLAT_RAW && opts[i].str ? " /* " : "",
126 !XLAT_RAW && opts[i].str ? opts[i].str : "",
127 !XLAT_RAW && opts[i].str ? " */" : "",
128 sprintrc(rc));
129
130 rc = getsockopt(0, SOL_IP, IP_LOCAL_PORT_RANGE, ports, &len);
131 errstr = sprintrc(rc);
132 printf("getsockopt(0, " XLAT_FMT ", " XLAT_FMT ", ",
133 XLAT_ARGS(SOL_IP), XLAT_ARGS(IP_LOCAL_PORT_RANGE));
134 if (INJSTR[0]) {
135 printf("[%#x%s%s%s]",
136 *ports,
137 !XLAT_RAW && opts[i].str ? " /* " : "",
138 !XLAT_RAW && opts[i].str ? opts[i].str : "",
139 !XLAT_RAW && opts[i].str ? " */" : "");
140 } else {
141 printf("%p", ports);
142 }
143 printf(", [4]) = %s" INJSTR "\n", errstr);
144
145
146 /* optval > sizeof(int), EFAULT */
147 len = sizeof(*ports) + 1;
148 rc = setsockopt(0, SOL_IP, IP_LOCAL_PORT_RANGE, ports, len);
149 printf("setsockopt(0, " XLAT_FMT ", " XLAT_FMT ", %p, 5) = %s"
150 INJSTR "\n",
151 XLAT_ARGS(SOL_IP), XLAT_ARGS(IP_LOCAL_PORT_RANGE),
152 ports, sprintrc(rc));
153
154 rc = getsockopt(0, SOL_IP, IP_LOCAL_PORT_RANGE, ports, &len);
155 printf("getsockopt(0, " XLAT_FMT ", " XLAT_FMT ", %p, [5]) = %s"
156 INJSTR "\n",
157 XLAT_ARGS(SOL_IP), XLAT_ARGS(IP_LOCAL_PORT_RANGE),
158 ports, sprintrc(rc));
159
160
161 /* optlen > sizeof(int), EINVAL */
162 len = sizeof(*ports) * 2;
163 big_ports[0] = opts[i].val;
164 big_ports[1] = opts[i].val;
165 rc = setsockopt(0, SOL_IP, IP_LOCAL_PORT_RANGE, big_ports, len);
166 errstr = sprintrc(rc);
167 printf("setsockopt(0, " XLAT_FMT ", " XLAT_FMT ", ",
168 XLAT_ARGS(SOL_IP), XLAT_ARGS(IP_LOCAL_PORT_RANGE));
169 print_quoted_hex(big_ports, len);
170 printf(", 8) = %s" INJSTR "\n", errstr);
171
172 rc = getsockopt(0, SOL_IP, IP_LOCAL_PORT_RANGE, big_ports, &len);
173 errstr = sprintrc(rc);
174 printf("getsockopt(0, " XLAT_FMT ", " XLAT_FMT ", ",
175 XLAT_ARGS(SOL_IP), XLAT_ARGS(IP_LOCAL_PORT_RANGE));
176 if (INJSTR[0])
177 print_quoted_hex(big_ports, len);
178 else
179 printf("%p", big_ports);
180 printf(", [8]) = %s" INJSTR "\n", errstr);
181 }
182
183 puts("+++ exited with 0 +++");
184 return 0;
185 }