1 /* $FreeBSD$ */ 2 /* $KAME: ip_encap.c,v 1.41 2001/03/15 08:35:08 itojun 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 * My grandfather said that there's a devil inside tunnelling technology... 34 * 35 * We have surprisingly many protocols that want packets with IP protocol 36 * #4 or #41. Here's a list of protocols that want protocol #41: 37 * RFC1933 configured tunnel 38 * RFC1933 automatic tunnel 39 * RFC2401 IPsec tunnel 40 * RFC2473 IPv6 generic packet tunnelling 41 * RFC2529 6over4 tunnel 42 * mobile-ip6 (uses RFC2473) 43 * RFC3056 6to4 tunnel 44 * isatap tunnel 45 * Here's a list of protocol that want protocol #4: 46 * RFC1853 IPv4-in-IPv4 tunnelling 47 * RFC2003 IPv4 encapsulation within IPv4 48 * RFC2344 reverse tunnelling for mobile-ip4 49 * RFC2401 IPsec tunnel 50 * Well, what can I say. They impose different en/decapsulation mechanism 51 * from each other, so they need separate protocol handler. The only one 52 * we can easily determine by protocol # is IPsec, which always has 53 * AH/ESP/IPComp header right after outer IP header. 54 * 55 * So, clearly good old protosw does not work for protocol #4 and #41. 56 * The code will let you match protocol via src/dst address pair. 57 */ 58 /* XXX is M_NETADDR correct? */ 59 60 #include "opt_mrouting.h" 61 #include "opt_inet.h" 62 #include "opt_inet6.h" 63 64 #include <sys/param.h> 65 #include <sys/systm.h> 66 #include <sys/socket.h> 67 #include <sys/sockio.h> 68 #include <sys/mbuf.h> 69 #include <sys/errno.h> 70 #include <sys/protosw.h> 71 #include <sys/queue.h> 72 73 #include <net/if.h> 74 #include <net/route.h> 75 76 #include <netinet/in.h> 77 #include <netinet/in_systm.h> 78 #include <netinet/ip.h> 79 #include <netinet/ip_var.h> 80 #include <netinet/ip_encap.h> 81 82 #ifdef INET6 83 #include <netinet/ip6.h> 84 #include <netinet6/ip6_var.h> 85 #include <netinet6/ip6protosw.h> 86 #endif 87 88 #include <machine/stdarg.h> 89 90 #include <sys/kernel.h> 91 #include <sys/malloc.h> 92 static MALLOC_DEFINE(M_NETADDR, "encap_export_host", "Export host address structure"); 93 94 static void encap_add(struct encaptab *); 95 static int mask_match(const struct encaptab *, const struct sockaddr *, 96 const struct sockaddr *); 97 static void encap_fillarg(struct mbuf *, const struct encaptab *); 98 99 /* 100 * All global variables in ip_encap.c are locked using encapmtx. 101 */ 102 static struct mtx encapmtx; 103 MTX_SYSINIT(encapmtx, &encapmtx, "encapmtx", MTX_DEF); 104 LIST_HEAD(, encaptab) encaptab = LIST_HEAD_INITIALIZER(&encaptab); 105 106 /* 107 * We currently keey encap_init() for source code compatibility reasons -- 108 * it's referenced by KAME pieces in netinet6. 109 */ 110 void 111 encap_init() 112 { 113 } 114 115 #ifdef INET 116 void 117 encap4_input(m, off) 118 struct mbuf *m; 119 int off; 120 { 121 struct ip *ip; 122 int proto; 123 struct sockaddr_in s, d; 124 const struct protosw *psw; 125 struct encaptab *ep, *match; 126 int prio, matchprio; 127 128 ip = mtod(m, struct ip *); 129 proto = ip->ip_p; 130 131 bzero(&s, sizeof(s)); 132 s.sin_family = AF_INET; 133 s.sin_len = sizeof(struct sockaddr_in); 134 s.sin_addr = ip->ip_src; 135 bzero(&d, sizeof(d)); 136 d.sin_family = AF_INET; 137 d.sin_len = sizeof(struct sockaddr_in); 138 d.sin_addr = ip->ip_dst; 139 140 match = NULL; 141 matchprio = 0; 142 mtx_lock(&encapmtx); 143 LIST_FOREACH(ep, &encaptab, chain) { 144 if (ep->af != AF_INET) 145 continue; 146 if (ep->proto >= 0 && ep->proto != proto) 147 continue; 148 if (ep->func) 149 prio = (*ep->func)(m, off, proto, ep->arg); 150 else { 151 /* 152 * it's inbound traffic, we need to match in reverse 153 * order 154 */ 155 prio = mask_match(ep, (struct sockaddr *)&d, 156 (struct sockaddr *)&s); 157 } 158 159 /* 160 * We prioritize the matches by using bit length of the 161 * matches. mask_match() and user-supplied matching function 162 * should return the bit length of the matches (for example, 163 * if both src/dst are matched for IPv4, 64 should be returned). 164 * 0 or negative return value means "it did not match". 165 * 166 * The question is, since we have two "mask" portion, we 167 * cannot really define total order between entries. 168 * For example, which of these should be preferred? 169 * mask_match() returns 48 (32 + 16) for both of them. 170 * src=3ffe::/16, dst=3ffe:501::/32 171 * src=3ffe:501::/32, dst=3ffe::/16 172 * 173 * We need to loop through all the possible candidates 174 * to get the best match - the search takes O(n) for 175 * n attachments (i.e. interfaces). 176 */ 177 if (prio <= 0) 178 continue; 179 if (prio > matchprio) { 180 matchprio = prio; 181 match = ep; 182 } 183 } 184 mtx_unlock(&encapmtx); 185 186 if (match) { 187 /* found a match, "match" has the best one */ 188 psw = match->psw; 189 if (psw && psw->pr_input) { 190 encap_fillarg(m, match); 191 (*psw->pr_input)(m, off); 192 } else 193 m_freem(m); 194 return; 195 } 196 197 /* last resort: inject to raw socket */ 198 rip_input(m, off); 199 } 200 #endif 201 202 #ifdef INET6 203 int 204 encap6_input(mp, offp, proto) 205 struct mbuf **mp; 206 int *offp; 207 int proto; 208 { 209 struct mbuf *m = *mp; 210 struct ip6_hdr *ip6; 211 struct sockaddr_in6 s, d; 212 const struct ip6protosw *psw; 213 struct encaptab *ep, *match; 214 int prio, matchprio; 215 216 ip6 = mtod(m, struct ip6_hdr *); 217 218 bzero(&s, sizeof(s)); 219 s.sin6_family = AF_INET6; 220 s.sin6_len = sizeof(struct sockaddr_in6); 221 s.sin6_addr = ip6->ip6_src; 222 bzero(&d, sizeof(d)); 223 d.sin6_family = AF_INET6; 224 d.sin6_len = sizeof(struct sockaddr_in6); 225 d.sin6_addr = ip6->ip6_dst; 226 227 match = NULL; 228 matchprio = 0; 229 mtx_lock(&encapmtx); 230 LIST_FOREACH(ep, &encaptab, chain) { 231 if (ep->af != AF_INET6) 232 continue; 233 if (ep->proto >= 0 && ep->proto != proto) 234 continue; 235 if (ep->func) 236 prio = (*ep->func)(m, *offp, proto, ep->arg); 237 else { 238 /* 239 * it's inbound traffic, we need to match in reverse 240 * order 241 */ 242 prio = mask_match(ep, (struct sockaddr *)&d, 243 (struct sockaddr *)&s); 244 } 245 246 /* see encap4_input() for issues here */ 247 if (prio <= 0) 248 continue; 249 if (prio > matchprio) { 250 matchprio = prio; 251 match = ep; 252 } 253 } 254 mtx_unlock(&encapmtx); 255 256 if (match) { 257 /* found a match */ 258 psw = (const struct ip6protosw *)match->psw; 259 if (psw && psw->pr_input) { 260 encap_fillarg(m, match); 261 return (*psw->pr_input)(mp, offp, proto); 262 } else { 263 m_freem(m); 264 return IPPROTO_DONE; 265 } 266 } 267 268 /* last resort: inject to raw socket */ 269 return rip6_input(mp, offp, proto); 270 } 271 #endif 272 273 /*lint -sem(encap_add, custodial(1)) */ 274 static void 275 encap_add(ep) 276 struct encaptab *ep; 277 { 278 279 mtx_assert(&encapmtx, MA_OWNED); 280 LIST_INSERT_HEAD(&encaptab, ep, chain); 281 } 282 283 /* 284 * sp (src ptr) is always my side, and dp (dst ptr) is always remote side. 285 * length of mask (sm and dm) is assumed to be same as sp/dp. 286 * Return value will be necessary as input (cookie) for encap_detach(). 287 */ 288 const struct encaptab * 289 encap_attach(af, proto, sp, sm, dp, dm, psw, arg) 290 int af; 291 int proto; 292 const struct sockaddr *sp, *sm; 293 const struct sockaddr *dp, *dm; 294 const struct protosw *psw; 295 void *arg; 296 { 297 struct encaptab *ep; 298 299 /* sanity check on args */ 300 if (sp->sa_len > sizeof(ep->src) || dp->sa_len > sizeof(ep->dst)) 301 return (NULL); 302 if (sp->sa_len != dp->sa_len) 303 return (NULL); 304 if (af != sp->sa_family || af != dp->sa_family) 305 return (NULL); 306 307 /* check if anyone have already attached with exactly same config */ 308 mtx_lock(&encapmtx); 309 LIST_FOREACH(ep, &encaptab, chain) { 310 if (ep->af != af) 311 continue; 312 if (ep->proto != proto) 313 continue; 314 if (ep->src.ss_len != sp->sa_len || 315 bcmp(&ep->src, sp, sp->sa_len) != 0 || 316 bcmp(&ep->srcmask, sm, sp->sa_len) != 0) 317 continue; 318 if (ep->dst.ss_len != dp->sa_len || 319 bcmp(&ep->dst, dp, dp->sa_len) != 0 || 320 bcmp(&ep->dstmask, dm, dp->sa_len) != 0) 321 continue; 322 323 mtx_unlock(&encapmtx); 324 return (NULL); 325 } 326 327 ep = malloc(sizeof(*ep), M_NETADDR, M_NOWAIT); /*XXX*/ 328 if (ep == NULL) { 329 mtx_unlock(&encapmtx); 330 return (NULL); 331 } 332 bzero(ep, sizeof(*ep)); 333 334 ep->af = af; 335 ep->proto = proto; 336 bcopy(sp, &ep->src, sp->sa_len); 337 bcopy(sm, &ep->srcmask, sp->sa_len); 338 bcopy(dp, &ep->dst, dp->sa_len); 339 bcopy(dm, &ep->dstmask, dp->sa_len); 340 ep->psw = psw; 341 ep->arg = arg; 342 343 encap_add(ep); 344 mtx_unlock(&encapmtx); 345 return (ep); 346 } 347 348 const struct encaptab * 349 encap_attach_func(af, proto, func, psw, arg) 350 int af; 351 int proto; 352 int (*func)(const struct mbuf *, int, int, void *); 353 const struct protosw *psw; 354 void *arg; 355 { 356 struct encaptab *ep; 357 358 /* sanity check on args */ 359 if (!func) 360 return (NULL); 361 362 ep = malloc(sizeof(*ep), M_NETADDR, M_NOWAIT); /*XXX*/ 363 if (ep == NULL) 364 return (NULL); 365 bzero(ep, sizeof(*ep)); 366 367 ep->af = af; 368 ep->proto = proto; 369 ep->func = func; 370 ep->psw = psw; 371 ep->arg = arg; 372 373 mtx_lock(&encapmtx); 374 encap_add(ep); 375 mtx_unlock(&encapmtx); 376 return (ep); 377 } 378 379 int 380 encap_detach(cookie) 381 const struct encaptab *cookie; 382 { 383 const struct encaptab *ep = cookie; 384 struct encaptab *p; 385 386 mtx_lock(&encapmtx); 387 LIST_FOREACH(p, &encaptab, chain) { 388 if (p == ep) { 389 LIST_REMOVE(p, chain); 390 mtx_unlock(&encapmtx); 391 free(p, M_NETADDR); /*XXX*/ 392 return 0; 393 } 394 } 395 mtx_unlock(&encapmtx); 396 397 return EINVAL; 398 } 399 400 static int 401 mask_match(ep, sp, dp) 402 const struct encaptab *ep; 403 const struct sockaddr *sp; 404 const struct sockaddr *dp; 405 { 406 struct sockaddr_storage s; 407 struct sockaddr_storage d; 408 int i; 409 const u_int8_t *p, *q; 410 u_int8_t *r; 411 int matchlen; 412 413 if (sp->sa_len > sizeof(s) || dp->sa_len > sizeof(d)) 414 return 0; 415 if (sp->sa_family != ep->af || dp->sa_family != ep->af) 416 return 0; 417 if (sp->sa_len != ep->src.ss_len || dp->sa_len != ep->dst.ss_len) 418 return 0; 419 420 matchlen = 0; 421 422 p = (const u_int8_t *)sp; 423 q = (const u_int8_t *)&ep->srcmask; 424 r = (u_int8_t *)&s; 425 for (i = 0 ; i < sp->sa_len; i++) { 426 r[i] = p[i] & q[i]; 427 /* XXX estimate */ 428 matchlen += (q[i] ? 8 : 0); 429 } 430 431 p = (const u_int8_t *)dp; 432 q = (const u_int8_t *)&ep->dstmask; 433 r = (u_int8_t *)&d; 434 for (i = 0 ; i < dp->sa_len; i++) { 435 r[i] = p[i] & q[i]; 436 /* XXX rough estimate */ 437 matchlen += (q[i] ? 8 : 0); 438 } 439 440 /* need to overwrite len/family portion as we don't compare them */ 441 s.ss_len = sp->sa_len; 442 s.ss_family = sp->sa_family; 443 d.ss_len = dp->sa_len; 444 d.ss_family = dp->sa_family; 445 446 if (bcmp(&s, &ep->src, ep->src.ss_len) == 0 && 447 bcmp(&d, &ep->dst, ep->dst.ss_len) == 0) { 448 return matchlen; 449 } else 450 return 0; 451 } 452 453 static void 454 encap_fillarg(m, ep) 455 struct mbuf *m; 456 const struct encaptab *ep; 457 { 458 struct m_tag *tag; 459 460 tag = m_tag_get(PACKET_TAG_ENCAP, sizeof (void*), M_NOWAIT); 461 if (tag) { 462 *(void**)(tag+1) = ep->arg; 463 m_tag_prepend(m, tag); 464 } 465 } 466 467 void * 468 encap_getarg(m) 469 struct mbuf *m; 470 { 471 void *p = NULL; 472 struct m_tag *tag; 473 474 tag = m_tag_find(m, PACKET_TAG_ENCAP, NULL); 475 if (tag) { 476 p = *(void**)(tag+1); 477 m_tag_delete(m, tag); 478 } 479 return p; 480 } 481