1 #include <stdio.h>
2 #include <string.h>
3 #include <arpa/inet.h>
4 #include <netinet/ip6.h>
5
6 static int
do_test(void)7 do_test (void)
8 {
9 int res = 0;
10 char buf[1000];
11 void *p = inet6_rth_init (buf, 24, IPV6_RTHDR_TYPE_0, 0);
12 if (p == NULL)
13 {
14 puts ("first inet6_rth_init failed");
15 res = 1;
16 }
17 else if (inet6_rth_add (p, &in6addr_any) == 0)
18 {
19 puts ("first inet6_rth_add succeeded");
20 res = 1;
21 }
22
23 p = inet6_rth_init (buf, 24, IPV6_RTHDR_TYPE_0, 1);
24 if (p == NULL)
25 {
26 puts ("second inet6_rth_init failed");
27 res = 1;
28 }
29 else if (inet6_rth_add (p, &in6addr_any) != 0)
30 {
31 puts ("second inet6_rth_add failed");
32 res = 1;
33 }
34
35 for (int nseg = 4; nseg < 6; ++nseg)
36 {
37 printf ("nseg = %d\n", nseg);
38
39 p = inet6_rth_init (buf, sizeof (buf), IPV6_RTHDR_TYPE_0, nseg);
40 if (p == NULL)
41 {
42 puts ("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 (p, &tmp) != 0)
54 {
55 printf ("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 (p) != nseg)
62 {
63 puts ("\
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 (p, buf2.buffer) != 0)
75 {
76 puts ("first inet6_rth_reverse call failed");
77 res = 1;
78 goto out;
79 }
80 if (buf2.rthdr0.ip6r0_segleft != nseg)
81 {
82 puts ("segleft after first inet6_rth_reverse wrong");
83 res = 1;
84 }
85
86 if (inet6_rth_segments (p) != inet6_rth_segments (buf2.buffer))
87 {
88 puts ("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 (buf2.buffer, i);
96 if (addr == NULL)
97 {
98 printf ("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 ("\
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 (buf, sizeof (buf), IPV6_RTHDR_TYPE_0, nseg);
120 if (p == NULL)
121 {
122 puts ("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 (p, &tmp) != 0)
134 {
135 printf ("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 (p) != nseg)
142 {
143 puts ("\
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 (p, p) != 0)
150 {
151 puts ("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 ("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 (p, i);
164 if (addr == NULL)
165 {
166 printf ("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 ("\
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