0857b82dcf725ae8acf959b32dcd077dc636ba4b
[libc-test] / src / functional / inet_pton.c
1 // inet_addr, inet_ntoa, inet_pton and inet_ntop tests with roundtrip check
2 #include <errno.h>
3 #include <string.h>
4 #include <stdio.h>
5 #include <arpa/inet.h>
6 #include "test.h"
7
8 static int digit(int c)
9 {
10         c-='0';
11         if (c>9) c-='a'-'0'-10;
12         return c;
13 }
14
15 static void tobin(void *d, char *s)
16 {
17         int i;
18         unsigned char *p = d;
19         for (i=0; s[2*i]; i++) p[i] = digit(s[2*i])*16+digit(s[2*i+1]);
20 }
21
22 static void tohex(char *d, void *s, int n)
23 {
24         int i;
25         unsigned char *p = s;
26         for (i=0; i<n; i++) sprintf(d+2*i, "%02x", p[i]);
27 }
28
29 #define V6(src,ret,hex) do{\
30         int r; \
31         char binaddr[16]; \
32         char hexaddr[40]; \
33         char txtaddr[60]; \
34         \
35         r=inet_pton(AF_INET6,src,binaddr); \
36         if (r!=ret) \
37                 t_error("inet_pton(AF_INET6, "#src", addr) returned %d, want %d\n", r, ret); \
38         if (ret!=1) break; \
39         tohex(hexaddr,binaddr,16); \
40         if (strcmp(hexaddr,hex)) \
41                 t_error("inet_pton(AF_INET6, "#src", addr) got addr %s, want %s\n", hexaddr, hex); \
42         \
43         tobin(binaddr,hex); \
44         if (inet_ntop(AF_INET6,binaddr,txtaddr,sizeof txtaddr)!=txtaddr) \
45                 t_error("inet_ntop(AF_INET6, <"#hex">, buf, size) did not return buf\n"); \
46         if (inet_pton(AF_INET6,txtaddr,binaddr)!=1) \
47                 t_error("inet_ntop(AF_INET6, <"#hex">, buf, size) got %s, it is rejected by inet_pton\n", txtaddr); \
48         tohex(hexaddr,binaddr,16); \
49         if (strcmp(hexaddr,hex)) \
50                 t_error("inet_ntop(AF_INET6, <"#hex">, buf, size) got %s that is %s, want %s\n", txtaddr, hexaddr, hex); \
51         if (strncmp(hex,"00000000000000000000ffff",24)==0 && !strchr(txtaddr,'.')) \
52                 t_error("inet_ntop(AF_INET6, <"#hex">, buf, size) got %s, should be ipv4 mapped\n", txtaddr); \
53 }while(0);
54
55 // ret and hex are the results of inet_pton and inet_addr respectively
56 #define V4(src,ret,hex) do{\
57         int r; \
58         uint32_t a; \
59         struct in_addr in; \
60         char buf[20]; \
61         char *p; \
62         \
63         a=inet_addr(src); \
64         tohex(buf,&a,4); \
65         if (strcmp(buf,hex)) \
66                 t_error("inet_addr("#src") returned %s, want %s\n", buf, hex); \
67         \
68         r=inet_pton(AF_INET,src,&a); \
69         if (r!=ret) \
70                 t_error("inet_pton(AF_INET, "#src", addr) returned %d, want %d\n", r, ret); \
71         \
72         if (ret!=1) break; \
73         \
74         tohex(buf,&a,4); \
75         if (strcmp(buf,hex)) \
76                 t_error("inet_pton(AF_INET, "#src", addr) got addr %s, want %s\n", buf, hex); \
77         \
78         tobin(&a,hex); \
79         if (inet_ntop(AF_INET,&a,buf,sizeof buf)!=buf) \
80                 t_error("inet_ntop(AF_INET, <"#hex">, buf, size) did not return buf\n"); \
81         if (strcmp(buf,src)) \
82                 t_error("inet_ntop(AF_INET, <"#hex">, buf, size) got %s, want %s\n", buf, src); \
83         \
84         in.s_addr = a; \
85         p=inet_ntoa(in); \
86         if (strcmp(p,src)) \
87                 t_error("inet_ntoa(<"#hex">) returned %s, want %s\n", p, src); \
88 }while(0);
89
90 int main(void)
91 {
92
93 // errors
94 if (inet_pton(12345, "", 0) != -1 || errno != EAFNOSUPPORT)
95         t_error("inet_pton(12345,,) should fail with EAFNOSUPPORT, got %s\n", strerror(errno));
96 errno=0;
97 if (inet_ntop(AF_INET,"xxxx","",0) != 0 || errno != ENOSPC)
98         t_error("inet_ntop(,,0,0) should fail with ENOSPC, got %s\n", strerror(errno));
99 errno=0;
100
101 // dotted-decimal notation
102 V4("0.0.0.0", 1, "00000000")
103 V4("127.0.0.1", 1, "7f000001")
104 V4("10.0.128.31", 1, "0a00801f")
105 V4("255.255.255.255", 1, "ffffffff")
106
107 // numbers-and-dots notation, but not dotted-decimal
108 V4("1.2.03.4", 0, "01020304")
109 V4("1.2.0x33.4", 0, "01023304")
110 V4("1.2.0XAB.4", 0, "0102ab04")
111 V4("1.2.0xabcd", 0, "0102abcd")
112 V4("1.0xabcdef", 0, "01abcdef")
113 V4("00377.0x0ff.65534", 0, "fffffffe")
114
115 // invalid
116 V4(".1.2.3", 0, "ffffffff")
117 V4("1..2.3", 0, "ffffffff")
118 V4("1.2.3.", 0, "ffffffff")
119 V4("1.2.3.4.5", 0, "ffffffff")
120 V4("1.2.3.a", 0, "ffffffff")
121 V4("1.256.2.3", 0, "ffffffff")
122 V4("1.2.4294967296.3", 0, "ffffffff")
123 V4("1.2.-4294967295.3", 0, "ffffffff")
124 V4("1.2. 3.4", 0, "ffffffff")
125
126 // ipv6
127 V6(":", 0, "")
128 V6("::", 1, "00000000000000000000000000000000")
129 V6("::1", 1, "00000000000000000000000000000001")
130 V6(":::", 0, "")
131 V6("192.168.1.1", 0, "")
132 V6(":192.168.1.1", 0, "")
133 V6("::192.168.1.1", 1, "000000000000000000000000c0a80101")
134 V6("0:0:0:0:0:0:192.168.1.1", 1, "000000000000000000000000c0a80101")
135 V6("0:0::0:0:0:192.168.1.1", 1, "000000000000000000000000c0a80101")
136 V6("::012.34.56.78", 0, "")
137 V6(":ffff:192.168.1.1", 0, "")
138 V6("::ffff:192.168.1.1", 1, "00000000000000000000ffffc0a80101")
139 V6(".192.168.1.1", 0, "")
140 V6(":.192.168.1.1", 0, "")
141 V6("a:0b:00c:000d:E:F::", 1, "000a000b000c000d000e000f00000000")
142 V6("a:0b:00c:000d:0000e:f::", 0, "")
143 V6("a:b::c:d:e:f", 1, "000a000b00000000000c000d000e000f")
144 V6("ffff:c0a8:5e4", 0, "")
145 V6(":ffff:c0a8:5e4", 0, "")
146 V6("0:0:0:0:0:ffff:c0a8:5e4", 1, "00000000000000000000ffffc0a805e4")
147 V6("0:0:0:0:ffff:c0a8:5e4", 0, "")
148 V6("0::ffff:c0a8:5e4", 1, "00000000000000000000ffffc0a805e4")
149 V6("::0::ffff:c0a8:5e4", 0, "")
150 V6("c0a8", 0, "")
151
152 return t_status;
153 }