1 | #include <stdio.h> |
2 | #include <string.h> |
3 | #include <arpa/inet.h> |
4 | #include <netinet/ip6.h> |
5 | |
6 | static int |
7 | do_test (void) |
8 | { |
9 | int res = 0; |
10 | char buf[1000]; |
11 | void *p = inet6_rth_init (bp: buf, bp_len: 24, IPV6_RTHDR_TYPE_0, segments: 0); |
12 | if (p == NULL) |
13 | { |
14 | puts (s: "first inet6_rth_init failed" ); |
15 | res = 1; |
16 | } |
17 | else if (inet6_rth_add (bp: p, addr: &in6addr_any) == 0) |
18 | { |
19 | puts (s: "first inet6_rth_add succeeded" ); |
20 | res = 1; |
21 | } |
22 | |
23 | p = inet6_rth_init (bp: buf, bp_len: 24, IPV6_RTHDR_TYPE_0, segments: 1); |
24 | if (p == NULL) |
25 | { |
26 | puts (s: "second inet6_rth_init failed" ); |
27 | res = 1; |
28 | } |
29 | else if (inet6_rth_add (bp: p, addr: &in6addr_any) != 0) |
30 | { |
31 | puts (s: "second inet6_rth_add failed" ); |
32 | res = 1; |
33 | } |
34 | |
35 | for (int nseg = 4; nseg < 6; ++nseg) |
36 | { |
37 | printf (format: "nseg = %d\n" , nseg); |
38 | |
39 | p = inet6_rth_init (bp: buf, bp_len: sizeof (buf), IPV6_RTHDR_TYPE_0, segments: nseg); |
40 | if (p == NULL) |
41 | { |
42 | puts (s: "third inet6_rth_init failed" ); |
43 | res = 1; |
44 | } |
45 | else |
46 | { |
47 | struct in6_addr tmp; |
48 | memset (&tmp, '\0', sizeof (tmp)); |
49 | |
50 | for (int i = 0; i < nseg; ++i) |
51 | { |
52 | tmp.s6_addr[0] = i; |
53 | if (inet6_rth_add (bp: p, addr: &tmp) != 0) |
54 | { |
55 | printf (format: "call %d of third inet6_rth_add failed\n" , i + 1); |
56 | res = 1; |
57 | goto out; |
58 | } |
59 | } |
60 | ((struct ip6_rthdr0 *) p)->ip6r0_segleft = 0; |
61 | if (inet6_rth_segments (bp: p) != nseg) |
62 | { |
63 | puts (s: "\ |
64 | inet6_rth_segments returned wrong value after loop with third inet6_rth_add" ); |
65 | res = 1; |
66 | goto out; |
67 | } |
68 | |
69 | union |
70 | { |
71 | char buffer[1000]; |
72 | struct ip6_rthdr0 rthdr0; |
73 | } buf2; |
74 | if (inet6_rth_reverse (in: p, out: buf2.buffer) != 0) |
75 | { |
76 | puts (s: "first inet6_rth_reverse call failed" ); |
77 | res = 1; |
78 | goto out; |
79 | } |
80 | if (buf2.rthdr0.ip6r0_segleft != nseg) |
81 | { |
82 | puts (s: "segleft after first inet6_rth_reverse wrong" ); |
83 | res = 1; |
84 | } |
85 | |
86 | if (inet6_rth_segments (bp: p) != inet6_rth_segments (bp: buf2.buffer)) |
87 | { |
88 | puts (s: "number of seconds after first inet6_rth_reverse differs" ); |
89 | res = 1; |
90 | goto out; |
91 | } |
92 | |
93 | for (int i = 0; i < nseg; ++i) |
94 | { |
95 | struct in6_addr *addr = inet6_rth_getaddr (bp: buf2.buffer, index: i); |
96 | if (addr == NULL) |
97 | { |
98 | printf (format: "call %d of first inet6_rth_getaddr failed\n" , |
99 | i + 1); |
100 | res = 1; |
101 | } |
102 | else if (addr->s6_addr[0] != nseg - 1 - i |
103 | || memcmp (&addr->s6_addr[1], &in6addr_any.s6_addr[1], |
104 | sizeof (in6addr_any) |
105 | - sizeof (in6addr_any.s6_addr[0])) != 0) |
106 | { |
107 | char addrbuf[100]; |
108 | inet_ntop (AF_INET6, addr, addrbuf, sizeof (addrbuf)); |
109 | printf (format: "\ |
110 | address %d after first inet6_rth_reverse wrong (%s)\n" , |
111 | i + 1, addrbuf); |
112 | res = 1; |
113 | } |
114 | } |
115 | out: |
116 | ; |
117 | } |
118 | |
119 | p = inet6_rth_init (bp: buf, bp_len: sizeof (buf), IPV6_RTHDR_TYPE_0, segments: nseg); |
120 | if (p == NULL) |
121 | { |
122 | puts (s: "fourth inet6_rth_init failed" ); |
123 | res = 1; |
124 | } |
125 | else |
126 | { |
127 | struct in6_addr tmp; |
128 | memset (&tmp, '\0', sizeof (tmp)); |
129 | |
130 | for (int i = 0; i < nseg; ++i) |
131 | { |
132 | tmp.s6_addr[0] = i; |
133 | if (inet6_rth_add (bp: p, addr: &tmp) != 0) |
134 | { |
135 | printf (format: "call %d of fourth inet6_rth_add failed\n" , i + 1); |
136 | res = 1; |
137 | goto out2; |
138 | } |
139 | } |
140 | ((struct ip6_rthdr0 *) p)->ip6r0_segleft = 0; |
141 | if (inet6_rth_segments (bp: p) != nseg) |
142 | { |
143 | puts (s: "\ |
144 | inet6_rth_segments returned wrong value after loop with fourth inet6_rth_add" ); |
145 | res = 1; |
146 | goto out2; |
147 | } |
148 | |
149 | if (inet6_rth_reverse (in: p, out: p) != 0) |
150 | { |
151 | puts (s: "second inet6_rth_reverse call failed" ); |
152 | res = 1; |
153 | goto out2; |
154 | } |
155 | if (((struct ip6_rthdr0 *) p)->ip6r0_segleft != nseg) |
156 | { |
157 | puts (s: "segleft after second inet6_rth_reverse wrong" ); |
158 | res = 1; |
159 | } |
160 | |
161 | for (int i = 0; i < nseg; ++i) |
162 | { |
163 | struct in6_addr *addr = inet6_rth_getaddr (bp: p, index: i); |
164 | if (addr == NULL) |
165 | { |
166 | printf (format: "call %d of second inet6_rth_getaddr failed\n" , |
167 | i + 1); |
168 | res = 1; |
169 | } |
170 | else if (addr->s6_addr[0] != nseg - 1 - i |
171 | || memcmp (&addr->s6_addr[1], &in6addr_any.s6_addr[1], |
172 | sizeof (in6addr_any) |
173 | - sizeof (in6addr_any.s6_addr[0])) != 0) |
174 | { |
175 | char addrbuf[100]; |
176 | inet_ntop (AF_INET6, addr, addrbuf, sizeof (addrbuf)); |
177 | printf (format: "\ |
178 | address %d after second inet6_rth_reverse wrong (%s)\n" , |
179 | i + 1, addrbuf); |
180 | res = 1; |
181 | } |
182 | } |
183 | out2: |
184 | ; |
185 | } |
186 | } |
187 | |
188 | return res; |
189 | } |
190 | |
191 | #define TEST_FUNCTION do_test () |
192 | #include "../test-skeleton.c" |
193 | |