NPTL: Remove gratuitous Linuxisms from gai_misc.h.
[platform/upstream/glibc.git] / inet / tst-inet6_rth.c
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 (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"