summaryrefslogtreecommitdiff
path: root/src/lib/libc/net/rthdr.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libc/net/rthdr.c')
-rw-r--r--src/lib/libc/net/rthdr.c181
1 files changed, 1 insertions, 180 deletions
diff --git a/src/lib/libc/net/rthdr.c b/src/lib/libc/net/rthdr.c
index d10334e027..9e917f1009 100644
--- a/src/lib/libc/net/rthdr.c
+++ b/src/lib/libc/net/rthdr.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: rthdr.c,v 1.8 2006/12/09 01:12:28 itojun Exp $ */ 1/* $OpenBSD: rthdr.c,v 1.9 2014/06/13 15:41:06 chrisz Exp $ */
2/* $KAME: rthdr.c,v 1.22 2006/02/09 08:18:58 keiichi Exp $ */ 2/* $KAME: rthdr.c,v 1.22 2006/02/09 08:18:58 keiichi Exp $ */
3 3
4/* 4/*
@@ -41,185 +41,6 @@
41#include <stdio.h> 41#include <stdio.h>
42 42
43/* 43/*
44 * RFC2292 API
45 */
46
47size_t
48inet6_rthdr_space(int type, int seg)
49{
50 switch (type) {
51 case IPV6_RTHDR_TYPE_0:
52 if (seg < 1 || seg > 23)
53 return (0);
54 return (CMSG_SPACE(sizeof(struct in6_addr) * seg +
55 sizeof(struct ip6_rthdr0)));
56 default:
57 return (0);
58 }
59}
60
61struct cmsghdr *
62inet6_rthdr_init(void *bp, int type)
63{
64 struct cmsghdr *ch = (struct cmsghdr *)bp;
65 struct ip6_rthdr *rthdr;
66
67 rthdr = (struct ip6_rthdr *)CMSG_DATA(ch);
68
69 ch->cmsg_level = IPPROTO_IPV6;
70 ch->cmsg_type = IPV6_RTHDR;
71
72 switch (type) {
73 case IPV6_RTHDR_TYPE_0:
74 ch->cmsg_len = CMSG_LEN(sizeof(struct ip6_rthdr0));
75 bzero(rthdr, sizeof(struct ip6_rthdr0));
76 rthdr->ip6r_type = IPV6_RTHDR_TYPE_0;
77 return (ch);
78 default:
79 return (NULL);
80 }
81}
82
83int
84inet6_rthdr_add(struct cmsghdr *cmsg, const struct in6_addr *addr, u_int flags)
85{
86 struct ip6_rthdr *rthdr;
87
88 rthdr = (struct ip6_rthdr *)CMSG_DATA(cmsg);
89
90 switch (rthdr->ip6r_type) {
91 case IPV6_RTHDR_TYPE_0:
92 {
93 struct ip6_rthdr0 *rt0 = (struct ip6_rthdr0 *)rthdr;
94 if (flags != IPV6_RTHDR_LOOSE)
95 return (-1);
96 if (rt0->ip6r0_segleft == 23)
97 return (-1);
98 rt0->ip6r0_segleft++;
99 bcopy(addr, (caddr_t)rt0 + ((rt0->ip6r0_len + 1) << 3),
100 sizeof(struct in6_addr));
101 rt0->ip6r0_len += sizeof(struct in6_addr) >> 3;
102 cmsg->cmsg_len = CMSG_LEN((rt0->ip6r0_len + 1) << 3);
103 break;
104 }
105 default:
106 return (-1);
107 }
108
109 return (0);
110}
111
112int
113inet6_rthdr_lasthop(struct cmsghdr *cmsg, unsigned int flags)
114{
115 struct ip6_rthdr *rthdr;
116
117 rthdr = (struct ip6_rthdr *)CMSG_DATA(cmsg);
118
119 switch (rthdr->ip6r_type) {
120 case IPV6_RTHDR_TYPE_0:
121 {
122 struct ip6_rthdr0 *rt0 = (struct ip6_rthdr0 *)rthdr;
123 if (flags != IPV6_RTHDR_LOOSE)
124 return (-1);
125 if (rt0->ip6r0_segleft > 23)
126 return (-1);
127 break;
128 }
129 default:
130 return (-1);
131 }
132
133 return (0);
134}
135
136#if 0
137int
138inet6_rthdr_reverse(in, out)
139 const struct cmsghdr *in;
140 struct cmsghdr *out;
141{
142
143 return (-1);
144}
145#endif
146
147int
148inet6_rthdr_segments(const struct cmsghdr *cmsg)
149{
150 struct ip6_rthdr *rthdr;
151
152 rthdr = (struct ip6_rthdr *)CMSG_DATA(cmsg);
153
154 switch (rthdr->ip6r_type) {
155 case IPV6_RTHDR_TYPE_0:
156 {
157 struct ip6_rthdr0 *rt0 = (struct ip6_rthdr0 *)rthdr;
158
159 if (rt0->ip6r0_len % 2 || 46 < rt0->ip6r0_len)
160 return (-1);
161
162 return (rt0->ip6r0_len * 8) / sizeof(struct in6_addr);
163 }
164
165 default:
166 return (-1);
167 }
168}
169
170struct in6_addr *
171inet6_rthdr_getaddr(struct cmsghdr *cmsg, int index)
172{
173 struct ip6_rthdr *rthdr;
174
175 rthdr = (struct ip6_rthdr *)CMSG_DATA(cmsg);
176
177 switch (rthdr->ip6r_type) {
178 case IPV6_RTHDR_TYPE_0:
179 {
180 struct ip6_rthdr0 *rt0 = (struct ip6_rthdr0 *)rthdr;
181 int naddr;
182
183 if (rt0->ip6r0_len % 2 || 46 < rt0->ip6r0_len)
184 return NULL;
185 naddr = (rt0->ip6r0_len * 8) / sizeof(struct in6_addr);
186 if (index <= 0 || naddr < index)
187 return NULL;
188 return ((struct in6_addr *)(rt0 + 1)) + index;
189 }
190
191 default:
192 return NULL;
193 }
194}
195
196int
197inet6_rthdr_getflags(const struct cmsghdr *cmsg, int index)
198{
199 struct ip6_rthdr *rthdr;
200
201 rthdr = (struct ip6_rthdr *)CMSG_DATA(cmsg);
202
203 switch (rthdr->ip6r_type) {
204 case IPV6_RTHDR_TYPE_0:
205 {
206 struct ip6_rthdr0 *rt0 = (struct ip6_rthdr0 *)rthdr;
207 int naddr;
208
209 if (rt0->ip6r0_len % 2 || 46 < rt0->ip6r0_len)
210 return (-1);
211 naddr = (rt0->ip6r0_len * 8) / sizeof(struct in6_addr);
212 if (index < 0 || naddr < index)
213 return (-1);
214 return IPV6_RTHDR_LOOSE;
215 }
216
217 default:
218 return (-1);
219 }
220}
221
222/*
223 * RFC3542 (2292bis) API 44 * RFC3542 (2292bis) API
224 */ 45 */
225 46