]> git.ipfire.org Git - thirdparty/glibc.git/blame - inet/test-inet6_opt.c
.
[thirdparty/glibc.git] / inet / test-inet6_opt.c
CommitLineData
32c075e1
JJ
1#include <netinet/in.h>
2#include <stdio.h>
3#include <stdlib.h>
4#include <string.h>
5
6#define OPT_X 42
7#define OPT_Y 43
8#define OPT_Z 44
9
10static void *
11encode_inet6_opt (socklen_t *elp)
12{
13 void *eb = NULL;
14 socklen_t el;
15 int cl;
16 void *db;
17 int offset;
18 uint8_t val1;
19 uint16_t val2;
20 uint32_t val4;
21 uint64_t val8;
22
23 *elp = 0;
24#define CHECK() \
25 if (cl == -1) \
26 { \
27 printf ("cl == -1 on line %d\n", __LINE__); \
28 free (eb); \
29 return NULL; \
30 }
31
32 /* Estimate the length */
33 cl = inet6_opt_init (NULL, 0);
34 CHECK ();
35 cl = inet6_opt_append (NULL, 0, cl, OPT_X, 12, 8, NULL);
36 CHECK ();
37 cl = inet6_opt_append (NULL, 0, cl, OPT_Y, 7, 4, NULL);
38 CHECK ();
39 cl = inet6_opt_append (NULL, 0, cl, OPT_Z, 7, 1, NULL);
40 CHECK ();
41 cl = inet6_opt_finish (NULL, 0, cl);
42 CHECK ();
43 el = cl;
44
45 eb = malloc (el + 8);
46 if (eb == NULL)
47 {
48 puts ("malloc failed");
49 return NULL;
50 }
51 /* Canary. */
52 memcpy (eb + el, "deadbeef", 8);
53
54 cl = inet6_opt_init (eb, el);
55 CHECK ();
56
57 cl = inet6_opt_append (eb, el, cl, OPT_X, 12, 8, &db);
58 CHECK ();
59 val4 = 0x12345678;
60 offset = inet6_opt_set_val (db, 0, &val4, sizeof (val4));
61 val8 = 0x0102030405060708LL;
62 inet6_opt_set_val (db, offset, &val8, sizeof (val8));
63
64 cl = inet6_opt_append (eb, el, cl, OPT_Y, 7, 4, &db);
65 CHECK ();
66 val1 = 0x01;
67 offset = inet6_opt_set_val (db, 0, &val1, sizeof (val1));
68 val2 = 0x1331;
69 offset = inet6_opt_set_val (db, offset, &val2, sizeof (val2));
70 val4 = 0x01020304;
71 inet6_opt_set_val (db, offset, &val4, sizeof (val4));
72
73 cl = inet6_opt_append (eb, el, cl, OPT_Z, 7, 1, &db);
74 CHECK ();
75 inet6_opt_set_val (db, 0, (void *) "abcdefg", 7);
76
77 cl = inet6_opt_finish (eb, el, cl);
78 CHECK ();
79
80 if (memcmp (eb + el, "deadbeef", 8) != 0)
81 {
82 puts ("Canary corrupted");
83 free (eb);
84 return NULL;
85 }
86 *elp = el;
87 return eb;
88}
89
90int
91decode_inet6_opt (void *eb, socklen_t el)
92{
93 int ret = 0;
94 int seq = 0;
95 int cl = 0;
96 int offset;
97 uint8_t type;
98 socklen_t len;
99 uint8_t val1;
100 uint16_t val2;
101 uint32_t val4;
102 uint64_t val8;
103 void *db;
104 char buf[8];
105
106 while ((cl = inet6_opt_next (eb, el, cl, &type, &len, &db)) != -1)
107 switch (type)
108 {
109 case OPT_X:
110 if (seq++ != 0)
111 {
112 puts ("OPT_X is not first");
113 ret = 1;
114 }
115 if (len != 12)
116 {
117 printf ("OPT_X's length %d != 12\n", len);
118 ret = 1;
119 }
120 offset = inet6_opt_get_val (db, 0, &val4, sizeof (val4));
121 if (val4 != 0x12345678)
122 {
123 printf ("OPT_X's val4 %x != 0x12345678\n", val4);
124 ret = 1;
125 }
126 offset = inet6_opt_get_val (db, offset, &val8, sizeof (val8));
127 if (offset != len || val8 != 0x0102030405060708LL)
128 {
129 printf ("OPT_X's val8 %llx != 0x0102030405060708\n",
130 (long long) val8);
131 ret = 1;
132 }
133 break;
134 case OPT_Y:
135 if (seq++ != 1)
136 {
137 puts ("OPT_Y is not second");
138 ret = 1;
139 }
140 if (len != 7)
141 {
142 printf ("OPT_Y's length %d != 7\n", len);
143 ret = 1;
144 }
145 offset = inet6_opt_get_val (db, 0, &val1, sizeof (val1));
146 if (val1 != 0x01)
147 {
148 printf ("OPT_Y's val1 %x != 0x01\n", val1);
149 ret = 1;
150 }
151 offset = inet6_opt_get_val (db, offset, &val2, sizeof (val2));
152 if (val2 != 0x1331)
153 {
154 printf ("OPT_Y's val2 %x != 0x1331\n", val2);
155 ret = 1;
156 }
157 offset = inet6_opt_get_val (db, offset, &val4, sizeof (val4));
158 if (offset != len || val4 != 0x01020304)
159 {
160 printf ("OPT_Y's val4 %x != 0x01020304\n", val4);
161 ret = 1;
162 }
163 break;
164 case OPT_Z:
165 if (seq++ != 2)
166 {
167 puts ("OPT_Z is not third");
168 ret = 1;
169 }
170 if (len != 7)
171 {
172 printf ("OPT_Z's length %d != 7\n", len);
173 ret = 1;
174 }
175 offset = inet6_opt_get_val (db, 0, buf, 7);
176 if (offset != len || memcmp (buf, "abcdefg", 7) != 0)
177 {
178 buf[7] = '\0';
179 printf ("OPT_Z's buf \"%s\" != \"abcdefg\"\n", buf);
180 ret = 1;
181 }
182 break;
183 default:
184 printf ("Unknown option %d\n", type);
185 ret = 1;
186 break;
187 }
188 if (seq != 3)
189 {
190 puts ("Didn't see all of OPT_X, OPT_Y and OPT_Z");
191 ret = 1;
192 }
193 return ret;
194}
195
196int
197main (void)
198{
199 void *eb;
200 socklen_t el;
201 eb = encode_inet6_opt (&el);
202 if (eb == NULL)
203 return 1;
204 if (decode_inet6_opt (eb, el))
205 return 1;
206 return 0;
207}