Line data Source code
1 : /*
2 : * Unix SMB/CIFS implementation.
3 : *
4 : * Copyright (C) 2021 Uri Simchoni <uri@samba.org>
5 : *
6 : * This program is free software; you can redistribute it and/or modify
7 : * it under the terms of the GNU General Public License as published by
8 : * the Free Software Foundation; either version 3 of the License, or
9 : * (at your option) any later version.
10 : *
11 : * This program is distributed in the hope that it will be useful,
12 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : * GNU General Public License for more details.
15 : *
16 : * You should have received a copy of the GNU General Public License
17 : * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 : */
19 :
20 : #include <errno.h>
21 : #include <setjmp.h>
22 : #include <stdarg.h>
23 : #include <stddef.h>
24 : #include <stdint.h>
25 :
26 : #include <cmocka.h>
27 : #include <tsocket.h>
28 :
29 1 : static int setup(void **state)
30 : {
31 1 : TALLOC_CTX *mem_ctx = talloc_new(NULL);
32 :
33 1 : assert_non_null(mem_ctx);
34 1 : *state = mem_ctx;
35 :
36 1 : return 0;
37 : }
38 :
39 1 : static int teardown(void **state)
40 : {
41 1 : TALLOC_CTX *mem_ctx = *state;
42 1 : TALLOC_FREE(mem_ctx);
43 :
44 1 : return 0;
45 : }
46 :
47 1 : static void test_address_inet_from_strings(void **state)
48 : {
49 1 : int rc = 0;
50 1 : int save_errno;
51 1 : TALLOC_CTX *mem_ctx = *state;
52 1 : struct tsocket_address *addr = NULL;
53 1 : char *addr_s = NULL;
54 :
55 : /*
56 : * Unspecified IP family, given an IPv4 address
57 : */
58 1 : rc = tsocket_address_inet_from_strings(mem_ctx, "ip", "1.2.3.4", 1234,
59 : &addr);
60 1 : assert_return_code(rc, errno);
61 1 : assert_non_null(addr);
62 1 : addr_s = tsocket_address_string(addr, mem_ctx);
63 1 : assert_non_null(addr_s);
64 1 : assert_string_equal(addr_s, "ipv4:1.2.3.4:1234");
65 1 : assert_true(tsocket_address_is_inet(addr, "ip"));
66 1 : assert_true(tsocket_address_is_inet(addr, "ipv4"));
67 1 : assert_false(tsocket_address_is_inet(addr, "ipv6"));
68 1 : assert_int_equal(tsocket_address_inet_port(addr), 1234);
69 1 : TALLOC_FREE(addr);
70 1 : TALLOC_FREE(addr_s);
71 :
72 : /*
73 : * Expecting IPv4, given an IPv4 address
74 : */
75 1 : rc = tsocket_address_inet_from_strings(mem_ctx, "ipv4", "1.2.3.4", 1234,
76 : &addr);
77 1 : assert_return_code(rc, errno);
78 1 : assert_non_null(addr);
79 1 : addr_s = tsocket_address_string(addr, mem_ctx);
80 1 : assert_non_null(addr_s);
81 1 : assert_string_equal(addr_s, "ipv4:1.2.3.4:1234");
82 1 : assert_true(tsocket_address_is_inet(addr, "ip"));
83 1 : assert_true(tsocket_address_is_inet(addr, "ipv4"));
84 1 : assert_false(tsocket_address_is_inet(addr, "ipv6"));
85 1 : assert_int_equal(tsocket_address_inet_port(addr), 1234);
86 1 : TALLOC_FREE(addr);
87 1 : TALLOC_FREE(addr_s);
88 :
89 : /*
90 : * Expecting IPv6, given an IPv4 address
91 : */
92 1 : errno = 0;
93 1 : rc = tsocket_address_inet_from_strings(mem_ctx, "ipv6", "1.2.3.4", 1234,
94 : &addr);
95 1 : save_errno = errno;
96 1 : assert_int_equal(rc, -1);
97 1 : assert_int_not_equal(save_errno, 0);
98 1 : assert_null(addr);
99 :
100 : /*
101 : * Unspecified IP family, given an IPv6 address
102 : */
103 1 : rc = tsocket_address_inet_from_strings(mem_ctx, "ip", "2001::1", 1234,
104 : &addr);
105 1 : assert_return_code(rc, errno);
106 1 : assert_non_null(addr);
107 1 : addr_s = tsocket_address_string(addr, mem_ctx);
108 1 : assert_non_null(addr_s);
109 1 : assert_string_equal(addr_s, "ipv6:2001::1:1234");
110 1 : assert_true(tsocket_address_is_inet(addr, "ip"));
111 1 : assert_false(tsocket_address_is_inet(addr, "ipv4"));
112 1 : assert_true(tsocket_address_is_inet(addr, "ipv6"));
113 1 : assert_int_equal(tsocket_address_inet_port(addr), 1234);
114 1 : TALLOC_FREE(addr);
115 1 : TALLOC_FREE(addr_s);
116 :
117 : /*
118 : * Expecting IPv4, given an IPv6 address
119 : */
120 1 : errno = 0;
121 1 : rc = tsocket_address_inet_from_strings(mem_ctx, "ipv4", "2001::1", 1234,
122 : &addr);
123 1 : save_errno = errno;
124 1 : assert_int_equal(rc, -1);
125 1 : assert_int_not_equal(save_errno, 0);
126 1 : assert_null(addr);
127 :
128 : /*
129 : * expecting IPv6, given an IPv6 address
130 : */
131 1 : rc = tsocket_address_inet_from_strings(mem_ctx, "ipv6", "2001::1", 1234,
132 : &addr);
133 1 : assert_return_code(rc, errno);
134 1 : assert_non_null(addr);
135 1 : addr_s = tsocket_address_string(addr, mem_ctx);
136 1 : assert_non_null(addr_s);
137 1 : assert_string_equal(addr_s, "ipv6:2001::1:1234");
138 1 : assert_true(tsocket_address_is_inet(addr, "ip"));
139 1 : assert_false(tsocket_address_is_inet(addr, "ipv4"));
140 1 : assert_true(tsocket_address_is_inet(addr, "ipv6"));
141 1 : assert_int_equal(tsocket_address_inet_port(addr), 1234);
142 1 : TALLOC_FREE(addr);
143 1 : TALLOC_FREE(addr_s);
144 :
145 : /*
146 : * Unspecified IP family, given an illegal address
147 : */
148 1 : errno = 0;
149 1 : rc = tsocket_address_inet_from_strings(mem_ctx, "ip", "localhost", 1234,
150 : &addr);
151 1 : save_errno = errno;
152 1 : assert_int_equal(rc, -1);
153 1 : assert_int_not_equal(save_errno, 0);
154 1 : assert_null(addr);
155 :
156 : /*
157 : * Illegal IP family
158 : */
159 1 : errno = 0;
160 1 : rc = tsocket_address_inet_from_strings(mem_ctx, "ipx", "1.2.3.4", 1234,
161 : &addr);
162 1 : save_errno = errno;
163 1 : assert_int_equal(rc, -1);
164 1 : assert_int_not_equal(save_errno, 0);
165 1 : assert_null(addr);
166 :
167 : /*
168 : * Unspecified IP family, given NULL, verify it returns something
169 : */
170 1 : rc = tsocket_address_inet_from_strings(mem_ctx, "ip", NULL, 1234,
171 : &addr);
172 1 : assert_return_code(rc, errno);
173 1 : assert_non_null(addr);
174 1 : TALLOC_FREE(addr);
175 :
176 : /*
177 : * IPv4, given NULL, verify it returns 0.0.0.0
178 : */
179 1 : rc = tsocket_address_inet_from_strings(mem_ctx, "ipv4", NULL, 1234,
180 : &addr);
181 1 : assert_return_code(rc, errno);
182 1 : assert_non_null(addr);
183 1 : addr_s = tsocket_address_string(addr, mem_ctx);
184 1 : assert_non_null(addr_s);
185 1 : assert_string_equal(addr_s, "ipv4:0.0.0.0:1234");
186 1 : assert_true(tsocket_address_is_inet(addr, "ip"));
187 1 : assert_true(tsocket_address_is_inet(addr, "ipv4"));
188 1 : assert_false(tsocket_address_is_inet(addr, "ipv6"));
189 1 : assert_int_equal(tsocket_address_inet_port(addr), 1234);
190 1 : TALLOC_FREE(addr);
191 1 : TALLOC_FREE(addr_s);
192 :
193 : /*
194 : * IPv6, given NULL, verify it returns ::
195 : */
196 1 : rc = tsocket_address_inet_from_strings(mem_ctx, "ipv6", NULL, 1234,
197 : &addr);
198 1 : assert_return_code(rc, errno);
199 1 : assert_non_null(addr);
200 1 : addr_s = tsocket_address_string(addr, mem_ctx);
201 1 : assert_non_null(addr_s);
202 1 : assert_string_equal(addr_s, "ipv6::::1234");
203 1 : assert_true(tsocket_address_is_inet(addr, "ip"));
204 1 : assert_false(tsocket_address_is_inet(addr, "ipv4"));
205 1 : assert_true(tsocket_address_is_inet(addr, "ipv6"));
206 1 : assert_int_equal(tsocket_address_inet_port(addr), 1234);
207 1 : TALLOC_FREE(addr);
208 1 : TALLOC_FREE(addr_s);
209 1 : }
210 :
211 1 : static void test_address_inet_from_hostport_strings(void **state)
212 : {
213 1 : int rc = 0;
214 1 : int save_errno;
215 1 : TALLOC_CTX *mem_ctx = *state;
216 1 : struct tsocket_address *addr = NULL;
217 1 : char *addr_s = NULL;
218 :
219 : /*
220 : * IPv4 host:port
221 : */
222 1 : rc = tsocket_address_inet_from_hostport_strings(
223 : mem_ctx, "ip", "1.2.3.4:5678", 1234, &addr);
224 1 : assert_return_code(rc, errno);
225 1 : assert_non_null(addr);
226 1 : addr_s = tsocket_address_string(addr, mem_ctx);
227 1 : assert_non_null(addr_s);
228 1 : assert_string_equal(addr_s, "ipv4:1.2.3.4:5678");
229 1 : TALLOC_FREE(addr);
230 1 : TALLOC_FREE(addr_s);
231 :
232 : /*
233 : * IPv4 host
234 : */
235 1 : rc = tsocket_address_inet_from_hostport_strings(
236 : mem_ctx, "ip", "1.2.3.4", 1234, &addr);
237 1 : assert_return_code(rc, errno);
238 1 : assert_non_null(addr);
239 1 : addr_s = tsocket_address_string(addr, mem_ctx);
240 1 : assert_non_null(addr_s);
241 1 : assert_string_equal(addr_s, "ipv4:1.2.3.4:1234");
242 1 : TALLOC_FREE(addr);
243 1 : TALLOC_FREE(addr_s);
244 :
245 : /*
246 : * IPv6 [host]:port
247 : */
248 1 : rc = tsocket_address_inet_from_hostport_strings(
249 : mem_ctx, "ip", "[2001::1]:5678", 1234, &addr);
250 1 : assert_return_code(rc, errno);
251 1 : assert_non_null(addr);
252 1 : addr_s = tsocket_address_string(addr, mem_ctx);
253 1 : assert_non_null(addr_s);
254 1 : assert_string_equal(addr_s, "ipv6:2001::1:5678");
255 1 : TALLOC_FREE(addr);
256 1 : TALLOC_FREE(addr_s);
257 :
258 : /*
259 : * IPv6 [host]
260 : */
261 1 : rc = tsocket_address_inet_from_hostport_strings(
262 : mem_ctx, "ip", "[2001::1]", 1234, &addr);
263 1 : assert_return_code(rc, errno);
264 1 : assert_non_null(addr);
265 1 : addr_s = tsocket_address_string(addr, mem_ctx);
266 1 : assert_non_null(addr_s);
267 1 : assert_string_equal(addr_s, "ipv6:2001::1:1234");
268 1 : TALLOC_FREE(addr);
269 1 : TALLOC_FREE(addr_s);
270 :
271 : /*
272 : * IPv6 host
273 : */
274 1 : rc = tsocket_address_inet_from_hostport_strings(
275 : mem_ctx, "ip", "2001::1", 1234, &addr);
276 1 : assert_return_code(rc, errno);
277 1 : assert_non_null(addr);
278 1 : addr_s = tsocket_address_string(addr, mem_ctx);
279 1 : assert_non_null(addr_s);
280 1 : assert_string_equal(addr_s, "ipv6:2001::1:1234");
281 1 : TALLOC_FREE(addr);
282 1 : TALLOC_FREE(addr_s);
283 :
284 : /*
285 : * Given NULL, verify it returns something
286 : */
287 1 : rc = tsocket_address_inet_from_hostport_strings(
288 : mem_ctx, "ipv6", NULL, 1234, &addr);
289 1 : assert_return_code(rc, errno);
290 1 : assert_non_null(addr);
291 1 : addr_s = tsocket_address_string(addr, mem_ctx);
292 1 : assert_non_null(addr_s);
293 1 : assert_string_equal(addr_s, "ipv6::::1234");
294 1 : TALLOC_FREE(addr);
295 1 : TALLOC_FREE(addr_s);
296 :
297 : /*
298 : * [host]grarbage
299 : */
300 1 : errno = 0;
301 1 : rc = tsocket_address_inet_from_hostport_strings(
302 : mem_ctx, "ip", "[2001::1]garbage", 1234, &addr);
303 1 : save_errno = errno;
304 1 : assert_int_equal(rc, -1);
305 1 : assert_int_not_equal(save_errno, 0);
306 1 : assert_null(addr);
307 :
308 : /*
309 : * [host]:grarbage
310 : */
311 1 : errno = 0;
312 1 : rc = tsocket_address_inet_from_hostport_strings(
313 : mem_ctx, "ip", "[2001::1]:garbage", 1234, &addr);
314 1 : save_errno = errno;
315 1 : assert_int_equal(rc, -1);
316 1 : assert_int_not_equal(save_errno, 0);
317 1 : assert_null(addr);
318 :
319 : /*
320 : * host:grarbage
321 : */
322 1 : errno = 0;
323 1 : rc = tsocket_address_inet_from_hostport_strings(
324 : mem_ctx, "ip", "1.2.3.4:garbage", 1234, &addr);
325 1 : save_errno = errno;
326 1 : assert_int_equal(rc, -1);
327 1 : assert_int_not_equal(save_errno, 0);
328 1 : assert_null(addr);
329 :
330 : /*
331 : * [host]:<port-too-large>
332 : */
333 1 : errno = 0;
334 1 : rc = tsocket_address_inet_from_hostport_strings(
335 : mem_ctx, "ip", "[2001::1]:100000", 1234, &addr);
336 1 : save_errno = errno;
337 1 : assert_int_equal(rc, -1);
338 1 : assert_int_not_equal(save_errno, 0);
339 1 : assert_null(addr);
340 :
341 : /*
342 : * host:<port-too-large>
343 : */
344 1 : errno = 0;
345 1 : rc = tsocket_address_inet_from_hostport_strings(
346 : mem_ctx, "ip", "1.2.3.4:100000", 1234, &addr);
347 1 : save_errno = errno;
348 1 : assert_int_equal(rc, -1);
349 1 : assert_int_not_equal(save_errno, 0);
350 1 : assert_null(addr);
351 1 : }
352 :
353 1 : int main(int argc, char *argv[])
354 : {
355 1 : int rc;
356 1 : const struct CMUnitTest tests[] = {
357 : cmocka_unit_test(test_address_inet_from_strings),
358 : cmocka_unit_test(test_address_inet_from_hostport_strings),
359 : };
360 :
361 1 : if (argc == 2) {
362 0 : cmocka_set_test_filter(argv[1]);
363 : }
364 1 : cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
365 :
366 1 : rc = cmocka_run_group_tests(tests, setup, teardown);
367 :
368 1 : return rc;
369 : }
|