Merge branch 'master' into bug13658-branch
[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           char buf2[1000];
70           if (inet6_rth_reverse (p, buf2) != 0)
71             {
72               puts ("first inet6_rth_reverse call failed");
73               res = 1;
74               goto out;
75             }
76           if (((struct ip6_rthdr0 *) buf2)->ip6r0_segleft != nseg)
77             {
78               puts ("segleft after first inet6_rth_reverse wrong");
79               res = 1;
80             }
81
82           if (inet6_rth_segments (p) != inet6_rth_segments (buf2))
83             {
84               puts ("number of seconds after first inet6_rth_reverse differs");
85               res = 1;
86               goto out;
87             }
88
89           for (int i = 0; i < nseg; ++i)
90             {
91               struct in6_addr *addr = inet6_rth_getaddr (buf2, i);
92               if (addr == NULL)
93                 {
94                   printf ("call %d of first inet6_rth_getaddr failed\n",
95                           i + 1);
96                   res = 1;
97                 }
98               else if (addr->s6_addr[0] != nseg - 1 - i
99                        || memcmp (&addr->s6_addr[1], &in6addr_any.s6_addr[1],
100                                   sizeof (in6addr_any)
101                                   - sizeof (in6addr_any.s6_addr[0])) != 0)
102                 {
103                   char addrbuf[100];
104                   inet_ntop (AF_INET6, addr, addrbuf, sizeof (addrbuf));
105                   printf ("\
106 address %d after first inet6_rth_reverse wrong (%s)\n",
107                           i + 1, addrbuf);
108                   res = 1;
109                 }
110             }
111         out:
112           ;
113         }
114
115       p = inet6_rth_init (buf, sizeof (buf), IPV6_RTHDR_TYPE_0, nseg);
116       if (p == NULL)
117         {
118           puts ("fourth inet6_rth_init failed");
119           res = 1;
120         }
121       else
122         {
123           struct in6_addr tmp;
124           memset (&tmp, '\0', sizeof (tmp));
125
126           for (int i = 0; i < nseg; ++i)
127             {
128               tmp.s6_addr[0] = i;
129               if (inet6_rth_add (p, &tmp) != 0)
130                 {
131                   printf ("call %d of fourth inet6_rth_add failed\n", i + 1);
132                   res = 1;
133                   goto out2;
134                 }
135             }
136           ((struct ip6_rthdr0 *) p)->ip6r0_segleft = 0;
137           if (inet6_rth_segments (p) != nseg)
138             {
139               puts ("\
140 inet6_rth_segments returned wrong value after loop with fourth inet6_rth_add");
141               res = 1;
142               goto out2;
143             }
144
145           if (inet6_rth_reverse (p, p) != 0)
146             {
147               puts ("second inet6_rth_reverse call failed");
148               res = 1;
149               goto out2;
150             }
151           if (((struct ip6_rthdr0 *) p)->ip6r0_segleft != nseg)
152             {
153               puts ("segleft after second inet6_rth_reverse wrong");
154               res = 1;
155             }
156
157           for (int i = 0; i < nseg; ++i)
158             {
159               struct in6_addr *addr = inet6_rth_getaddr (p, i);
160               if (addr == NULL)
161                 {
162                   printf ("call %d of second inet6_rth_getaddr failed\n",
163                           i + 1);
164                   res = 1;
165                 }
166               else if (addr->s6_addr[0] != nseg - 1 - i
167                        || memcmp (&addr->s6_addr[1], &in6addr_any.s6_addr[1],
168                                   sizeof (in6addr_any)
169                                   - sizeof (in6addr_any.s6_addr[0])) != 0)
170                 {
171                   char addrbuf[100];
172                   inet_ntop (AF_INET6, addr, addrbuf, sizeof (addrbuf));
173                   printf ("\
174 address %d after second inet6_rth_reverse wrong (%s)\n",
175                           i + 1, addrbuf);
176                   res = 1;
177                 }
178             }
179         out2:
180           ;
181         }
182     }
183
184   return res;
185 }
186
187 #define TEST_FUNCTION do_test ()
188 #include "../test-skeleton.c"