1#include <stdio.h>
2#include <string.h>
3#include <arpa/inet.h>
4#include <netinet/ip6.h>
5
6static int
7do_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: "\
64inet6_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: "\
110address %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: "\
144inet6_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: "\
178address %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

source code of glibc/inet/tst-inet6_rth.c