1 | /* Unit tests for GInetAddress |
2 | * Copyright (C) 2012 Red Hat, Inc |
3 | * Author: Matthias Clasen |
4 | * |
5 | * This work is provided "as is"; redistribution and modification |
6 | * in whole or in part, in any medium, physical or electronic is |
7 | * permitted without restriction. |
8 | * |
9 | * This work is distributed in the hope that it will be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
12 | * |
13 | * In no event shall the authors or contributors be liable for any |
14 | * direct, indirect, incidental, special, exemplary, or consequential |
15 | * damages (including, but not limited to, procurement of substitute |
16 | * goods or services; loss of use, data, or profits; or business |
17 | * interruption) however caused and on any theory of liability, whether |
18 | * in contract, strict liability, or tort (including negligence or |
19 | * otherwise) arising in any way out of the use of this software, even |
20 | * if advised of the possibility of such damage. |
21 | */ |
22 | |
23 | #include "config.h" |
24 | |
25 | #include <gio/gio.h> |
26 | #include <gio/gnetworking.h> |
27 | |
28 | static void |
29 | test_parse (void) |
30 | { |
31 | GInetAddress *addr; |
32 | |
33 | addr = g_inet_address_new_from_string (string: "0:0:0:0:0:0:0:0" ); |
34 | g_assert (addr != NULL); |
35 | g_object_unref (object: addr); |
36 | addr = g_inet_address_new_from_string (string: "1:0:0:0:0:0:0:8" ); |
37 | g_assert (addr != NULL); |
38 | g_object_unref (object: addr); |
39 | addr = g_inet_address_new_from_string (string: "0:0:0:0:0:FFFF:204.152.189.116" ); |
40 | g_assert (addr != NULL); |
41 | g_object_unref (object: addr); |
42 | addr = g_inet_address_new_from_string (string: "::1" ); |
43 | g_assert (addr != NULL); |
44 | g_object_unref (object: addr); |
45 | addr = g_inet_address_new_from_string (string: "::" ); |
46 | g_assert (addr != NULL); |
47 | g_object_unref (object: addr); |
48 | addr = g_inet_address_new_from_string (string: "::FFFF:204.152.189.116" ); |
49 | g_assert (addr != NULL); |
50 | g_object_unref (object: addr); |
51 | addr = g_inet_address_new_from_string (string: "204.152.189.116" ); |
52 | g_assert (addr != NULL); |
53 | g_object_unref (object: addr); |
54 | |
55 | addr = g_inet_address_new_from_string (string: "::1::2" ); |
56 | g_assert (addr == NULL); |
57 | addr = g_inet_address_new_from_string (string: "2001:1:2:3:4:5:6:7]" ); |
58 | g_assert (addr == NULL); |
59 | addr = g_inet_address_new_from_string (string: "[2001:1:2:3:4:5:6:7" ); |
60 | g_assert (addr == NULL); |
61 | addr = g_inet_address_new_from_string (string: "[2001:1:2:3:4:5:6:7]" ); |
62 | g_assert (addr == NULL); |
63 | addr = g_inet_address_new_from_string (string: "[2001:1:2:3:4:5:6:7]:80" ); |
64 | g_assert (addr == NULL); |
65 | addr = g_inet_address_new_from_string (string: "0:1:2:3:4:5:6:7:8:9" ); |
66 | g_assert (addr == NULL); |
67 | addr = g_inet_address_new_from_string (string: "::FFFFFFF" ); |
68 | g_assert (addr == NULL); |
69 | addr = g_inet_address_new_from_string (string: "204.152.189.116:80" ); |
70 | g_assert (addr == NULL); |
71 | } |
72 | |
73 | static void |
74 | test_any (void) |
75 | { |
76 | GInetAddress *addr; |
77 | GSocketFamily family[2] = { G_SOCKET_FAMILY_IPV4, G_SOCKET_FAMILY_IPV6 }; |
78 | gsize size[2] = { 4, 16 }; |
79 | gint i; |
80 | |
81 | for (i = 0; i < 2; i++) |
82 | { |
83 | addr = g_inet_address_new_any (family: family[i]); |
84 | |
85 | g_assert (g_inet_address_get_is_any (addr)); |
86 | g_assert (g_inet_address_get_family (addr) == family[i]); |
87 | g_assert (g_inet_address_get_native_size (addr) == size[i]); |
88 | g_assert (!g_inet_address_get_is_loopback (addr)); |
89 | g_assert (!g_inet_address_get_is_link_local (addr)); |
90 | g_assert (!g_inet_address_get_is_site_local (addr)); |
91 | g_assert (!g_inet_address_get_is_multicast (addr)); |
92 | g_assert (!g_inet_address_get_is_mc_global (addr)); |
93 | g_assert (!g_inet_address_get_is_mc_link_local (addr)); |
94 | g_assert (!g_inet_address_get_is_mc_node_local (addr)); |
95 | g_assert (!g_inet_address_get_is_mc_org_local (addr)); |
96 | g_assert (!g_inet_address_get_is_mc_site_local (addr)); |
97 | |
98 | g_object_unref (object: addr); |
99 | } |
100 | } |
101 | |
102 | static void |
103 | test_loopback (void) |
104 | { |
105 | GInetAddress *addr; |
106 | |
107 | addr = g_inet_address_new_from_string (string: "::1" ); |
108 | g_assert (g_inet_address_get_family (addr) == G_SOCKET_FAMILY_IPV6); |
109 | g_assert (g_inet_address_get_is_loopback (addr)); |
110 | g_object_unref (object: addr); |
111 | |
112 | addr = g_inet_address_new_from_string (string: "127.0.0.0" ); |
113 | g_assert (g_inet_address_get_family (addr) == G_SOCKET_FAMILY_IPV4); |
114 | g_assert (g_inet_address_get_is_loopback (addr)); |
115 | g_object_unref (object: addr); |
116 | } |
117 | |
118 | static void |
119 | test_bytes (void) |
120 | { |
121 | GInetAddress *addr1, *addr2, *addr3; |
122 | const guint8 *bytes; |
123 | |
124 | addr1 = g_inet_address_new_from_string (string: "192.168.0.100" ); |
125 | addr2 = g_inet_address_new_from_string (string: "192.168.0.101" ); |
126 | bytes = g_inet_address_to_bytes (address: addr1); |
127 | addr3 = g_inet_address_new_from_bytes (bytes, family: G_SOCKET_FAMILY_IPV4); |
128 | |
129 | g_assert (!g_inet_address_equal (addr1, addr2)); |
130 | g_assert (g_inet_address_equal (addr1, addr3)); |
131 | |
132 | g_object_unref (object: addr1); |
133 | g_object_unref (object: addr2); |
134 | g_object_unref (object: addr3); |
135 | } |
136 | |
137 | static void |
138 | test_property (void) |
139 | { |
140 | GInetAddress *addr; |
141 | GSocketFamily family; |
142 | const guint8 *bytes; |
143 | gboolean any; |
144 | gboolean loopback; |
145 | gboolean link_local; |
146 | gboolean site_local; |
147 | gboolean multicast; |
148 | gboolean mc_global; |
149 | gboolean mc_link_local; |
150 | gboolean mc_node_local; |
151 | gboolean mc_org_local; |
152 | gboolean mc_site_local; |
153 | |
154 | addr = g_inet_address_new_from_string (string: "ff85::" ); |
155 | g_object_get (object: addr, |
156 | first_property_name: "family" , &family, |
157 | "bytes" , &bytes, |
158 | "is-any" , &any, |
159 | "is-loopback" , &loopback, |
160 | "is-link-local" , &link_local, |
161 | "is-site-local" , &site_local, |
162 | "is-multicast" , &multicast, |
163 | "is-mc-global" , &mc_global, |
164 | "is-mc-link-local" , &mc_link_local, |
165 | "is-mc-node-local" , &mc_node_local, |
166 | "is-mc-org-local" , &mc_org_local, |
167 | "is-mc-site-local" , &mc_site_local, |
168 | NULL); |
169 | |
170 | g_assert (family == G_SOCKET_FAMILY_IPV6); |
171 | g_assert (!any); |
172 | g_assert (!loopback); |
173 | g_assert (!link_local); |
174 | g_assert (!site_local); |
175 | g_assert (multicast); |
176 | g_assert (!mc_global); |
177 | g_assert (!mc_link_local); |
178 | g_assert (!mc_node_local); |
179 | g_assert (!mc_org_local); |
180 | g_assert (mc_site_local); |
181 | |
182 | g_object_unref (object: addr); |
183 | } |
184 | |
185 | static void |
186 | test_socket_address (void) |
187 | { |
188 | GInetAddress *addr; |
189 | GInetSocketAddress *saddr; |
190 | guint port; |
191 | guint32 flowinfo; |
192 | guint32 scope_id; |
193 | GSocketFamily family; |
194 | |
195 | addr = g_inet_address_new_from_string (string: "::ffff:125.1.15.5" ); |
196 | saddr = G_INET_SOCKET_ADDRESS (g_inet_socket_address_new (addr, 308)); |
197 | |
198 | g_assert (g_inet_address_equal (addr, g_inet_socket_address_get_address (saddr))); |
199 | g_object_unref (object: addr); |
200 | |
201 | g_assert (g_inet_socket_address_get_port (saddr) == 308); |
202 | g_assert (g_inet_socket_address_get_flowinfo (saddr) == 0); |
203 | g_assert (g_inet_socket_address_get_scope_id (saddr) == 0); |
204 | |
205 | g_object_unref (object: saddr); |
206 | |
207 | addr = g_inet_address_new_from_string (string: "::1" ); |
208 | saddr = G_INET_SOCKET_ADDRESS (g_object_new (G_TYPE_INET_SOCKET_ADDRESS, |
209 | "address" , addr, |
210 | "port" , 308, |
211 | "flowinfo" , 10, |
212 | "scope-id" , 25, |
213 | NULL)); |
214 | g_object_unref (object: addr); |
215 | |
216 | g_assert (g_inet_socket_address_get_port (saddr) == 308); |
217 | g_assert (g_inet_socket_address_get_flowinfo (saddr) == 10); |
218 | g_assert (g_inet_socket_address_get_scope_id (saddr) == 25); |
219 | |
220 | g_object_get (object: saddr, |
221 | first_property_name: "family" , &family, |
222 | "address" , &addr, |
223 | "port" , &port, |
224 | "flowinfo" , &flowinfo, |
225 | "scope-id" , &scope_id, |
226 | NULL); |
227 | |
228 | g_assert (family == G_SOCKET_FAMILY_IPV6); |
229 | g_assert (addr != NULL); |
230 | g_assert (port == 308); |
231 | g_assert (flowinfo == 10); |
232 | g_assert (scope_id == 25); |
233 | |
234 | g_object_unref (object: addr); |
235 | g_object_unref (object: saddr); |
236 | } |
237 | |
238 | static void |
239 | test_socket_address_to_string (void) |
240 | { |
241 | GSocketAddress *sa = NULL; |
242 | GInetAddress *ia = NULL; |
243 | gchar *str = NULL; |
244 | |
245 | /* IPv4. */ |
246 | ia = g_inet_address_new_from_string (string: "123.1.123.1" ); |
247 | sa = g_inet_socket_address_new (address: ia, port: 80); |
248 | str = g_socket_connectable_to_string (G_SOCKET_CONNECTABLE (sa)); |
249 | g_assert_cmpstr (str, ==, "123.1.123.1:80" ); |
250 | g_free (mem: str); |
251 | g_object_unref (object: sa); |
252 | g_object_unref (object: ia); |
253 | |
254 | /* IPv6. */ |
255 | ia = g_inet_address_new_from_string (string: "fe80::80" ); |
256 | sa = g_inet_socket_address_new (address: ia, port: 80); |
257 | str = g_socket_connectable_to_string (G_SOCKET_CONNECTABLE (sa)); |
258 | g_assert_cmpstr (str, ==, "[fe80::80]:80" ); |
259 | g_free (mem: str); |
260 | g_object_unref (object: sa); |
261 | g_object_unref (object: ia); |
262 | |
263 | /* IPv6 without port. */ |
264 | ia = g_inet_address_new_from_string (string: "fe80::80" ); |
265 | sa = g_inet_socket_address_new (address: ia, port: 0); |
266 | str = g_socket_connectable_to_string (G_SOCKET_CONNECTABLE (sa)); |
267 | g_assert_cmpstr (str, ==, "fe80::80" ); |
268 | g_free (mem: str); |
269 | g_object_unref (object: sa); |
270 | g_object_unref (object: ia); |
271 | |
272 | /* IPv6 with scope. */ |
273 | ia = g_inet_address_new_from_string (string: "::1" ); |
274 | sa = G_SOCKET_ADDRESS (g_object_new (G_TYPE_INET_SOCKET_ADDRESS, |
275 | "address" , ia, |
276 | "port" , 123, |
277 | "flowinfo" , 10, |
278 | "scope-id" , 25, |
279 | NULL)); |
280 | str = g_socket_connectable_to_string (G_SOCKET_CONNECTABLE (sa)); |
281 | g_assert_cmpstr (str, ==, "[::1%25]:123" ); |
282 | g_free (mem: str); |
283 | g_object_unref (object: sa); |
284 | g_object_unref (object: ia); |
285 | } |
286 | |
287 | static void |
288 | test_mask_parse (void) |
289 | { |
290 | GInetAddressMask *mask; |
291 | GError *error = NULL; |
292 | |
293 | mask = g_inet_address_mask_new_from_string (mask_string: "10.0.0.0/8" , error: &error); |
294 | g_assert_no_error (error); |
295 | g_assert (mask != NULL); |
296 | g_object_unref (object: mask); |
297 | |
298 | mask = g_inet_address_mask_new_from_string (mask_string: "fe80::/10" , error: &error); |
299 | g_assert_no_error (error); |
300 | g_assert (mask != NULL); |
301 | g_object_unref (object: mask); |
302 | |
303 | mask = g_inet_address_mask_new_from_string (mask_string: "::" , error: &error); |
304 | g_assert_no_error (error); |
305 | g_assert (mask != NULL); |
306 | g_object_unref (object: mask); |
307 | |
308 | mask = g_inet_address_mask_new_from_string (mask_string: "::/abc" , error: &error); |
309 | g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); |
310 | g_assert (mask == NULL); |
311 | g_clear_error (err: &error); |
312 | |
313 | mask = g_inet_address_mask_new_from_string (mask_string: "127.0.0.1/128" , error: &error); |
314 | g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); |
315 | g_assert (mask == NULL); |
316 | g_clear_error (err: &error); |
317 | } |
318 | |
319 | static void |
320 | test_mask_property (void) |
321 | { |
322 | GInetAddressMask *mask; |
323 | GInetAddress *addr; |
324 | GSocketFamily family; |
325 | guint len; |
326 | |
327 | addr = g_inet_address_new_from_string (string: "fe80::" ); |
328 | mask = g_inet_address_mask_new_from_string (mask_string: "fe80::/10" , NULL); |
329 | g_assert (g_inet_address_mask_get_family (mask) == G_SOCKET_FAMILY_IPV6); |
330 | g_assert (g_inet_address_equal (addr, g_inet_address_mask_get_address (mask))); |
331 | g_assert (g_inet_address_mask_get_length (mask) == 10); |
332 | g_object_unref (object: addr); |
333 | |
334 | g_object_get (object: mask, |
335 | first_property_name: "family" , &family, |
336 | "address" , &addr, |
337 | "length" , &len, |
338 | NULL); |
339 | g_assert (family == G_SOCKET_FAMILY_IPV6); |
340 | g_assert (addr != NULL); |
341 | g_assert (len == 10); |
342 | g_object_unref (object: addr); |
343 | |
344 | g_object_unref (object: mask); |
345 | } |
346 | |
347 | static void |
348 | test_mask_equal (void) |
349 | { |
350 | GInetAddressMask *mask; |
351 | GInetAddressMask *mask2; |
352 | gchar *str; |
353 | |
354 | mask = g_inet_address_mask_new_from_string (mask_string: "fe80:0:0::/10" , NULL); |
355 | str = g_inet_address_mask_to_string (mask); |
356 | g_assert_cmpstr (str, ==, "fe80::/10" ); |
357 | mask2 = g_inet_address_mask_new_from_string (mask_string: str, NULL); |
358 | g_assert (g_inet_address_mask_equal (mask, mask2)); |
359 | g_object_unref (object: mask2); |
360 | g_free (mem: str); |
361 | |
362 | mask2 = g_inet_address_mask_new_from_string (mask_string: "fe80::/12" , NULL); |
363 | g_assert (!g_inet_address_mask_equal (mask, mask2)); |
364 | g_object_unref (object: mask2); |
365 | |
366 | mask2 = g_inet_address_mask_new_from_string (mask_string: "ff80::/10" , NULL); |
367 | g_assert (!g_inet_address_mask_equal (mask, mask2)); |
368 | g_object_unref (object: mask2); |
369 | |
370 | g_object_unref (object: mask); |
371 | } |
372 | |
373 | static void |
374 | test_mask_match (void) |
375 | { |
376 | GInetAddressMask *mask; |
377 | GInetAddress *addr; |
378 | |
379 | mask = g_inet_address_mask_new_from_string (mask_string: "1.2.0.0/16" , NULL); |
380 | |
381 | addr = g_inet_address_new_from_string (string: "1.2.0.0" ); |
382 | g_assert (g_inet_address_mask_matches (mask, addr)); |
383 | g_object_unref (object: addr); |
384 | addr = g_inet_address_new_from_string (string: "1.2.3.4" ); |
385 | g_assert (g_inet_address_mask_matches (mask, addr)); |
386 | g_object_unref (object: addr); |
387 | addr = g_inet_address_new_from_string (string: "1.3.1.1" ); |
388 | g_assert (!g_inet_address_mask_matches (mask, addr)); |
389 | g_object_unref (object: addr); |
390 | |
391 | g_object_unref (object: mask); |
392 | |
393 | mask = g_inet_address_mask_new_from_string (mask_string: "1.2.0.0/24" , NULL); |
394 | |
395 | addr = g_inet_address_new_from_string (string: "1.2.0.0" ); |
396 | g_assert (g_inet_address_mask_matches (mask, addr)); |
397 | g_object_unref (object: addr); |
398 | addr = g_inet_address_new_from_string (string: "1.2.3.4" ); |
399 | g_assert (!g_inet_address_mask_matches (mask, addr)); |
400 | g_object_unref (object: addr); |
401 | addr = g_inet_address_new_from_string (string: "1.2.0.24" ); |
402 | g_assert (g_inet_address_mask_matches (mask, addr)); |
403 | g_object_unref (object: addr); |
404 | |
405 | g_object_unref (object: mask); |
406 | |
407 | } |
408 | |
409 | int |
410 | main (int argc, char *argv[]) |
411 | { |
412 | g_test_init (argc: &argc, argv: &argv, NULL); |
413 | |
414 | g_test_add_func (testpath: "/inet-address/parse" , test_func: test_parse); |
415 | g_test_add_func (testpath: "/inet-address/any" , test_func: test_any); |
416 | g_test_add_func (testpath: "/inet-address/loopback" , test_func: test_loopback); |
417 | g_test_add_func (testpath: "/inet-address/bytes" , test_func: test_bytes); |
418 | g_test_add_func (testpath: "/inet-address/property" , test_func: test_property); |
419 | g_test_add_func (testpath: "/socket-address/basic" , test_func: test_socket_address); |
420 | g_test_add_func (testpath: "/socket-address/to-string" , test_func: test_socket_address_to_string); |
421 | g_test_add_func (testpath: "/address-mask/parse" , test_func: test_mask_parse); |
422 | g_test_add_func (testpath: "/address-mask/property" , test_func: test_mask_property); |
423 | g_test_add_func (testpath: "/address-mask/equal" , test_func: test_mask_equal); |
424 | g_test_add_func (testpath: "/address-mask/match" , test_func: test_mask_match); |
425 | |
426 | return g_test_run (); |
427 | } |
428 | |