diff options
author | cvs2svn <admin@example.com> | 2025-04-14 17:32:06 +0000 |
---|---|---|
committer | cvs2svn <admin@example.com> | 2025-04-14 17:32:06 +0000 |
commit | eb8dd9dca1228af0cd132f515509051ecfabf6f6 (patch) | |
tree | edb6da6af7e865d488dc1a29309f1e1ec226e603 /src/lib/libc/net/ip6opt.c | |
parent | 247f0352e0ed72a4f476db9dc91f4d982bc83eb2 (diff) | |
download | openbsd-tb_20250414.tar.gz openbsd-tb_20250414.tar.bz2 openbsd-tb_20250414.zip |
This commit was manufactured by cvs2git to create tag 'tb_20250414'.tb_20250414
Diffstat (limited to 'src/lib/libc/net/ip6opt.c')
-rw-r--r-- | src/lib/libc/net/ip6opt.c | 285 |
1 files changed, 0 insertions, 285 deletions
diff --git a/src/lib/libc/net/ip6opt.c b/src/lib/libc/net/ip6opt.c deleted file mode 100644 index 3837489448..0000000000 --- a/src/lib/libc/net/ip6opt.c +++ /dev/null | |||
@@ -1,285 +0,0 @@ | |||
1 | /* $OpenBSD: ip6opt.c,v 1.10 2020/01/22 07:52:37 deraadt Exp $ */ | ||
2 | /* $KAME: ip6opt.c,v 1.18 2005/06/15 07:11:35 keiichi Exp $ */ | ||
3 | |||
4 | /* | ||
5 | * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. | ||
6 | * All rights reserved. | ||
7 | * | ||
8 | * Redistribution and use in source and binary forms, with or without | ||
9 | * modification, are permitted provided that the following conditions | ||
10 | * are met: | ||
11 | * 1. Redistributions of source code must retain the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer. | ||
13 | * 2. Redistributions in binary form must reproduce the above copyright | ||
14 | * notice, this list of conditions and the following disclaimer in the | ||
15 | * documentation and/or other materials provided with the distribution. | ||
16 | * 3. Neither the name of the project nor the names of its contributors | ||
17 | * may be used to endorse or promote products derived from this software | ||
18 | * without specific prior written permission. | ||
19 | * | ||
20 | * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND | ||
21 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
22 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
23 | * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE | ||
24 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
25 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
26 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
27 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
28 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
29 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
30 | * SUCH DAMAGE. | ||
31 | */ | ||
32 | |||
33 | #include <sys/types.h> | ||
34 | #include <sys/socket.h> | ||
35 | |||
36 | #include <netinet/in.h> | ||
37 | #include <netinet/ip6.h> | ||
38 | |||
39 | #include <string.h> | ||
40 | #include <stdio.h> | ||
41 | |||
42 | static int ip6optlen(u_int8_t *opt, u_int8_t *lim); | ||
43 | |||
44 | /* | ||
45 | * Calculate the length of a given IPv6 option. Also checks | ||
46 | * if the option is safely stored in user's buffer according to the | ||
47 | * calculated length and the limitation of the buffer. | ||
48 | */ | ||
49 | static int | ||
50 | ip6optlen(u_int8_t *opt, u_int8_t *lim) | ||
51 | { | ||
52 | int optlen; | ||
53 | |||
54 | if (*opt == IP6OPT_PAD1) | ||
55 | optlen = 1; | ||
56 | else { | ||
57 | /* is there enough space to store type and len? */ | ||
58 | if (opt + 2 > lim) | ||
59 | return (0); | ||
60 | optlen = *(opt + 1) + 2; | ||
61 | } | ||
62 | if (opt + optlen <= lim) | ||
63 | return (optlen); | ||
64 | |||
65 | return (0); | ||
66 | } | ||
67 | |||
68 | /* | ||
69 | * The following functions are defined in RFC3542, which is a successor | ||
70 | * of RFC2292. | ||
71 | */ | ||
72 | |||
73 | int | ||
74 | inet6_opt_init(void *extbuf, socklen_t extlen) | ||
75 | { | ||
76 | struct ip6_ext *ext = (struct ip6_ext *)extbuf; | ||
77 | |||
78 | if (ext) { | ||
79 | if (extlen <= 0 || (extlen % 8)) | ||
80 | return (-1); | ||
81 | ext->ip6e_len = (extlen >> 3) - 1; | ||
82 | } | ||
83 | |||
84 | return (2); /* sizeof the next and the length fields */ | ||
85 | } | ||
86 | |||
87 | int | ||
88 | inet6_opt_append(void *extbuf, socklen_t extlen, int offset, u_int8_t type, | ||
89 | socklen_t len, u_int8_t align, void **databufp) | ||
90 | { | ||
91 | int currentlen = offset, padlen = 0; | ||
92 | |||
93 | /* | ||
94 | * The option type must have a value from 2 to 255, inclusive. | ||
95 | * (0 and 1 are reserved for the Pad1 and PadN options, respectively.) | ||
96 | */ | ||
97 | #if 0 /* always false */ | ||
98 | if (type < 2 || type > 255) | ||
99 | #else | ||
100 | if (type < 2) | ||
101 | #endif | ||
102 | return (-1); | ||
103 | |||
104 | /* | ||
105 | * The option data length must have a value between 0 and 255, | ||
106 | * inclusive, and is the length of the option data that follows. | ||
107 | */ | ||
108 | if (len > 255) | ||
109 | return (-1); | ||
110 | |||
111 | /* | ||
112 | * The align parameter must have a value of 1, 2, 4, or 8. | ||
113 | * The align value can not exceed the value of len. | ||
114 | */ | ||
115 | if (align != 1 && align != 2 && align != 4 && align != 8) | ||
116 | return (-1); | ||
117 | if (align > len) | ||
118 | return (-1); | ||
119 | |||
120 | /* Calculate the padding length. */ | ||
121 | currentlen += 2 + len; /* 2 means "type + len" */ | ||
122 | if (currentlen % align) | ||
123 | padlen = align - (currentlen % align); | ||
124 | |||
125 | /* The option must fit in the extension header buffer. */ | ||
126 | currentlen += padlen; | ||
127 | if (extlen && /* XXX: right? */ | ||
128 | currentlen > extlen) | ||
129 | return (-1); | ||
130 | |||
131 | if (extbuf) { | ||
132 | u_int8_t *optp = (u_int8_t *)extbuf + offset; | ||
133 | |||
134 | if (padlen == 1) { | ||
135 | /* insert a Pad1 option */ | ||
136 | *optp = IP6OPT_PAD1; | ||
137 | optp++; | ||
138 | } else if (padlen > 0) { | ||
139 | /* insert a PadN option for alignment */ | ||
140 | *optp++ = IP6OPT_PADN; | ||
141 | *optp++ = padlen - 2; | ||
142 | memset(optp, 0, padlen - 2); | ||
143 | optp += (padlen - 2); | ||
144 | } | ||
145 | |||
146 | *optp++ = type; | ||
147 | *optp++ = len; | ||
148 | |||
149 | *databufp = optp; | ||
150 | } | ||
151 | |||
152 | return (currentlen); | ||
153 | } | ||
154 | |||
155 | int | ||
156 | inet6_opt_finish(void *extbuf, socklen_t extlen, int offset) | ||
157 | { | ||
158 | int updatelen = offset > 0 ? (1 + ((offset - 1) | 7)) : 0; | ||
159 | |||
160 | if (extbuf) { | ||
161 | u_int8_t *padp; | ||
162 | int padlen = updatelen - offset; | ||
163 | |||
164 | if (updatelen > extlen) | ||
165 | return (-1); | ||
166 | |||
167 | padp = (u_int8_t *)extbuf + offset; | ||
168 | if (padlen == 1) | ||
169 | *padp = IP6OPT_PAD1; | ||
170 | else if (padlen > 0) { | ||
171 | *padp++ = IP6OPT_PADN; | ||
172 | *padp++ = (padlen - 2); | ||
173 | memset(padp, 0, padlen - 2); | ||
174 | } | ||
175 | } | ||
176 | |||
177 | return (updatelen); | ||
178 | } | ||
179 | |||
180 | int | ||
181 | inet6_opt_set_val(void *databuf, int offset, void *val, socklen_t vallen) | ||
182 | { | ||
183 | |||
184 | memcpy((u_int8_t *)databuf + offset, val, vallen); | ||
185 | return (offset + vallen); | ||
186 | } | ||
187 | |||
188 | int | ||
189 | inet6_opt_next(void *extbuf, socklen_t extlen, int offset, u_int8_t *typep, | ||
190 | socklen_t *lenp, void **databufp) | ||
191 | { | ||
192 | u_int8_t *optp, *lim; | ||
193 | int optlen; | ||
194 | |||
195 | /* Validate extlen. XXX: is the variable really necessary?? */ | ||
196 | if (extlen == 0 || (extlen % 8)) | ||
197 | return (-1); | ||
198 | lim = (u_int8_t *)extbuf + extlen; | ||
199 | |||
200 | /* | ||
201 | * If this is the first time this function called for this options | ||
202 | * header, simply return the 1st option. | ||
203 | * Otherwise, search the option list for the next option. | ||
204 | */ | ||
205 | if (offset == 0) | ||
206 | optp = (u_int8_t *)((struct ip6_hbh *)extbuf + 1); | ||
207 | else | ||
208 | optp = (u_int8_t *)extbuf + offset; | ||
209 | |||
210 | /* Find the next option skipping any padding options. */ | ||
211 | while (optp < lim) { | ||
212 | switch(*optp) { | ||
213 | case IP6OPT_PAD1: | ||
214 | optp++; | ||
215 | break; | ||
216 | case IP6OPT_PADN: | ||
217 | if ((optlen = ip6optlen(optp, lim)) == 0) | ||
218 | goto optend; | ||
219 | optp += optlen; | ||
220 | break; | ||
221 | default: /* found */ | ||
222 | if ((optlen = ip6optlen(optp, lim)) == 0) | ||
223 | goto optend; | ||
224 | *typep = *optp; | ||
225 | *lenp = optlen - 2; | ||
226 | *databufp = optp + 2; | ||
227 | return (optp + optlen - (u_int8_t *)extbuf); | ||
228 | } | ||
229 | } | ||
230 | |||
231 | optend: | ||
232 | *databufp = NULL; /* for safety */ | ||
233 | return (-1); | ||
234 | } | ||
235 | |||
236 | int | ||
237 | inet6_opt_find(void *extbuf, socklen_t extlen, int offset, u_int8_t type, | ||
238 | socklen_t *lenp, void **databufp) | ||
239 | { | ||
240 | u_int8_t *optp, *lim; | ||
241 | int optlen; | ||
242 | |||
243 | /* Validate extlen. XXX: is the variable really necessary?? */ | ||
244 | if (extlen == 0 || (extlen % 8)) | ||
245 | return (-1); | ||
246 | lim = (u_int8_t *)extbuf + extlen; | ||
247 | |||
248 | /* | ||
249 | * If this is the first time this function called for this options | ||
250 | * header, simply return the 1st option. | ||
251 | * Otherwise, search the option list for the next option. | ||
252 | */ | ||
253 | if (offset == 0) | ||
254 | optp = (u_int8_t *)((struct ip6_hbh *)extbuf + 1); | ||
255 | else | ||
256 | optp = (u_int8_t *)extbuf + offset; | ||
257 | |||
258 | /* Find the specified option */ | ||
259 | while (optp < lim) { | ||
260 | if ((optlen = ip6optlen(optp, lim)) == 0) | ||
261 | goto optend; | ||
262 | |||
263 | if (*optp == type) { /* found */ | ||
264 | *lenp = optlen - 2; | ||
265 | *databufp = optp + 2; | ||
266 | return (optp + optlen - (u_int8_t *)extbuf); | ||
267 | } | ||
268 | |||
269 | optp += optlen; | ||
270 | } | ||
271 | |||
272 | optend: | ||
273 | *databufp = NULL; /* for safety */ | ||
274 | return (-1); | ||
275 | } | ||
276 | |||
277 | int | ||
278 | inet6_opt_get_val(void *databuf, int offset, void *val, socklen_t vallen) | ||
279 | { | ||
280 | |||
281 | /* we can't assume alignment here */ | ||
282 | memcpy(val, (u_int8_t *)databuf + offset, vallen); | ||
283 | |||
284 | return (offset + vallen); | ||
285 | } | ||