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