| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: ip_encap.c,v 1.40 2015/04/15 03:32:23 ozaki-r Exp $ */ | | 1 | /* $NetBSD: ip_encap.c,v 1.41 2015/04/15 03:38:50 ozaki-r Exp $ */ |
2 | /* $KAME: ip_encap.c,v 1.73 2001/10/02 08:30:58 itojun Exp $ */ | | 2 | /* $KAME: ip_encap.c,v 1.73 2001/10/02 08:30:58 itojun Exp $ */ |
3 | | | 3 | |
4 | /* | | 4 | /* |
5 | * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. | | 5 | * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. |
6 | * All rights reserved. | | 6 | * All rights reserved. |
7 | * | | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without | | 8 | * Redistribution and use in source and binary forms, with or without |
9 | * modification, are permitted provided that the following conditions | | 9 | * modification, are permitted provided that the following conditions |
10 | * are met: | | 10 | * are met: |
11 | * 1. Redistributions of source code must retain the above copyright | | 11 | * 1. Redistributions of source code must retain the above copyright |
12 | * notice, this list of conditions and the following disclaimer. | | 12 | * notice, this list of conditions and the following disclaimer. |
13 | * 2. Redistributions in binary form must reproduce the above copyright | | 13 | * 2. Redistributions in binary form must reproduce the above copyright |
14 | * notice, this list of conditions and the following disclaimer in the | | 14 | * notice, this list of conditions and the following disclaimer in the |
| @@ -65,27 +65,27 @@ | | | @@ -65,27 +65,27 @@ |
65 | * The code assumes that radix table code can handle non-continuous netmask, | | 65 | * The code assumes that radix table code can handle non-continuous netmask, |
66 | * as it will pass radix table memory region with (src + dst) sockaddr pair. | | 66 | * as it will pass radix table memory region with (src + dst) sockaddr pair. |
67 | * | | 67 | * |
68 | * FreeBSD is excluded here as they make max_keylen a static variable, and | | 68 | * FreeBSD is excluded here as they make max_keylen a static variable, and |
69 | * thus forbid definition of radix table other than proper domains. | | 69 | * thus forbid definition of radix table other than proper domains. |
70 | * | | 70 | * |
71 | * !!!!!!! | | 71 | * !!!!!!! |
72 | * !!NOTE: dom_maxrtkey assumes USE_RADIX is defined. | | 72 | * !!NOTE: dom_maxrtkey assumes USE_RADIX is defined. |
73 | * !!!!!!! | | 73 | * !!!!!!! |
74 | */ | | 74 | */ |
75 | #define USE_RADIX | | 75 | #define USE_RADIX |
76 | | | 76 | |
77 | #include <sys/cdefs.h> | | 77 | #include <sys/cdefs.h> |
78 | __KERNEL_RCSID(0, "$NetBSD: ip_encap.c,v 1.40 2015/04/15 03:32:23 ozaki-r Exp $"); | | 78 | __KERNEL_RCSID(0, "$NetBSD: ip_encap.c,v 1.41 2015/04/15 03:38:50 ozaki-r Exp $"); |
79 | | | 79 | |
80 | #include "opt_mrouting.h" | | 80 | #include "opt_mrouting.h" |
81 | #include "opt_inet.h" | | 81 | #include "opt_inet.h" |
82 | | | 82 | |
83 | #include <sys/param.h> | | 83 | #include <sys/param.h> |
84 | #include <sys/systm.h> | | 84 | #include <sys/systm.h> |
85 | #include <sys/socket.h> | | 85 | #include <sys/socket.h> |
86 | #include <sys/sockio.h> | | 86 | #include <sys/sockio.h> |
87 | #include <sys/mbuf.h> | | 87 | #include <sys/mbuf.h> |
88 | #include <sys/errno.h> | | 88 | #include <sys/errno.h> |
89 | #include <sys/protosw.h> | | 89 | #include <sys/protosw.h> |
90 | #include <sys/queue.h> | | 90 | #include <sys/queue.h> |
91 | | | 91 | |
| @@ -175,30 +175,28 @@ encap_init(void) | | | @@ -175,30 +175,28 @@ encap_init(void) |
175 | #ifdef INET | | 175 | #ifdef INET |
176 | static struct encaptab * | | 176 | static struct encaptab * |
177 | encap4_lookup(struct mbuf *m, int off, int proto, enum direction dir) | | 177 | encap4_lookup(struct mbuf *m, int off, int proto, enum direction dir) |
178 | { | | 178 | { |
179 | struct ip *ip; | | 179 | struct ip *ip; |
180 | struct ip_pack4 pack; | | 180 | struct ip_pack4 pack; |
181 | struct encaptab *ep, *match; | | 181 | struct encaptab *ep, *match; |
182 | int prio, matchprio; | | 182 | int prio, matchprio; |
183 | #ifdef USE_RADIX | | 183 | #ifdef USE_RADIX |
184 | struct radix_node_head *rnh = encap_rnh(AF_INET); | | 184 | struct radix_node_head *rnh = encap_rnh(AF_INET); |
185 | struct radix_node *rn; | | 185 | struct radix_node *rn; |
186 | #endif | | 186 | #endif |
187 | | | 187 | |
188 | #ifdef DIAGNOSTIC | | 188 | KASSERT(m->m_len >= sizeof(*ip)); |
189 | if (m->m_len < sizeof(*ip)) | | 189 | |
190 | panic("encap4_lookup"); | | | |
191 | #endif | | | |
192 | ip = mtod(m, struct ip *); | | 190 | ip = mtod(m, struct ip *); |
193 | | | 191 | |
194 | memset(&pack, 0, sizeof(pack)); | | 192 | memset(&pack, 0, sizeof(pack)); |
195 | pack.p.sp_len = sizeof(pack); | | 193 | pack.p.sp_len = sizeof(pack); |
196 | pack.mine.sin_family = pack.yours.sin_family = AF_INET; | | 194 | pack.mine.sin_family = pack.yours.sin_family = AF_INET; |
197 | pack.mine.sin_len = pack.yours.sin_len = sizeof(struct sockaddr_in); | | 195 | pack.mine.sin_len = pack.yours.sin_len = sizeof(struct sockaddr_in); |
198 | if (dir == INBOUND) { | | 196 | if (dir == INBOUND) { |
199 | pack.mine.sin_addr = ip->ip_dst; | | 197 | pack.mine.sin_addr = ip->ip_dst; |
200 | pack.yours.sin_addr = ip->ip_src; | | 198 | pack.yours.sin_addr = ip->ip_src; |
201 | } else { | | 199 | } else { |
202 | pack.mine.sin_addr = ip->ip_src; | | 200 | pack.mine.sin_addr = ip->ip_src; |
203 | pack.yours.sin_addr = ip->ip_dst; | | 201 | pack.yours.sin_addr = ip->ip_dst; |
204 | } | | 202 | } |
| @@ -299,30 +297,28 @@ encap4_input(struct mbuf *m, ...) | | | @@ -299,30 +297,28 @@ encap4_input(struct mbuf *m, ...) |
299 | #ifdef INET6 | | 297 | #ifdef INET6 |
300 | static struct encaptab * | | 298 | static struct encaptab * |
301 | encap6_lookup(struct mbuf *m, int off, int proto, enum direction dir) | | 299 | encap6_lookup(struct mbuf *m, int off, int proto, enum direction dir) |
302 | { | | 300 | { |
303 | struct ip6_hdr *ip6; | | 301 | struct ip6_hdr *ip6; |
304 | struct ip_pack6 pack; | | 302 | struct ip_pack6 pack; |
305 | int prio, matchprio; | | 303 | int prio, matchprio; |
306 | struct encaptab *ep, *match; | | 304 | struct encaptab *ep, *match; |
307 | #ifdef USE_RADIX | | 305 | #ifdef USE_RADIX |
308 | struct radix_node_head *rnh = encap_rnh(AF_INET6); | | 306 | struct radix_node_head *rnh = encap_rnh(AF_INET6); |
309 | struct radix_node *rn; | | 307 | struct radix_node *rn; |
310 | #endif | | 308 | #endif |
311 | | | 309 | |
312 | #ifdef DIAGNOSTIC | | 310 | KASSERT(m->m_len >= sizeof(*ip6)); |
313 | if (m->m_len < sizeof(*ip6)) | | 311 | |
314 | panic("encap6_lookup"); | | | |
315 | #endif | | | |
316 | ip6 = mtod(m, struct ip6_hdr *); | | 312 | ip6 = mtod(m, struct ip6_hdr *); |
317 | | | 313 | |
318 | memset(&pack, 0, sizeof(pack)); | | 314 | memset(&pack, 0, sizeof(pack)); |
319 | pack.p.sp_len = sizeof(pack); | | 315 | pack.p.sp_len = sizeof(pack); |
320 | pack.mine.sin6_family = pack.yours.sin6_family = AF_INET6; | | 316 | pack.mine.sin6_family = pack.yours.sin6_family = AF_INET6; |
321 | pack.mine.sin6_len = pack.yours.sin6_len = sizeof(struct sockaddr_in6); | | 317 | pack.mine.sin6_len = pack.yours.sin6_len = sizeof(struct sockaddr_in6); |
322 | if (dir == INBOUND) { | | 318 | if (dir == INBOUND) { |
323 | pack.mine.sin6_addr = ip6->ip6_dst; | | 319 | pack.mine.sin6_addr = ip6->ip6_dst; |
324 | pack.yours.sin6_addr = ip6->ip6_src; | | 320 | pack.yours.sin6_addr = ip6->ip6_src; |
325 | } else { | | 321 | } else { |
326 | pack.mine.sin6_addr = ip6->ip6_src; | | 322 | pack.mine.sin6_addr = ip6->ip6_src; |
327 | pack.yours.sin6_addr = ip6->ip6_dst; | | 323 | pack.yours.sin6_addr = ip6->ip6_dst; |
328 | } | | 324 | } |
| @@ -498,30 +494,30 @@ encap_attach(int af, int proto, | | | @@ -498,30 +494,30 @@ encap_attach(int af, int proto, |
498 | /* sanity check on args */ | | 494 | /* sanity check on args */ |
499 | error = encap_afcheck(af, sp, dp); | | 495 | error = encap_afcheck(af, sp, dp); |
500 | if (error) | | 496 | if (error) |
501 | goto fail; | | 497 | goto fail; |
502 | | | 498 | |
503 | /* check if anyone have already attached with exactly same config */ | | 499 | /* check if anyone have already attached with exactly same config */ |
504 | LIST_FOREACH(ep, &encaptab, chain) { | | 500 | LIST_FOREACH(ep, &encaptab, chain) { |
505 | if (ep->af != af) | | 501 | if (ep->af != af) |
506 | continue; | | 502 | continue; |
507 | if (ep->proto != proto) | | 503 | if (ep->proto != proto) |
508 | continue; | | 504 | continue; |
509 | if (ep->func) | | 505 | if (ep->func) |
510 | continue; | | 506 | continue; |
511 | #ifdef DIAGNOSTIC | | 507 | |
512 | if (!ep->src || !ep->dst || !ep->srcmask || !ep->dstmask) | | 508 | KASSERT(ep->src != NULL && ep->dst != NULL && |
513 | panic("null pointers in encaptab"); | | 509 | ep->srcmask != NULL && ep->dstmask != NULL); |
514 | #endif | | 510 | |
515 | if (ep->src->sa_len != sp->sa_len || | | 511 | if (ep->src->sa_len != sp->sa_len || |
516 | memcmp(ep->src, sp, sp->sa_len) != 0 || | | 512 | memcmp(ep->src, sp, sp->sa_len) != 0 || |
517 | memcmp(ep->srcmask, sm, sp->sa_len) != 0) | | 513 | memcmp(ep->srcmask, sm, sp->sa_len) != 0) |
518 | continue; | | 514 | continue; |
519 | if (ep->dst->sa_len != dp->sa_len || | | 515 | if (ep->dst->sa_len != dp->sa_len || |
520 | memcmp(ep->dst, dp, dp->sa_len) != 0 || | | 516 | memcmp(ep->dst, dp, dp->sa_len) != 0 || |
521 | memcmp(ep->dstmask, dm, dp->sa_len) != 0) | | 517 | memcmp(ep->dstmask, dm, dp->sa_len) != 0) |
522 | continue; | | 518 | continue; |
523 | | | 519 | |
524 | error = EEXIST; | | 520 | error = EEXIST; |
525 | goto fail; | | 521 | goto fail; |
526 | } | | 522 | } |
527 | | | 523 | |
| @@ -798,30 +794,28 @@ mask_matchlen(const struct sockaddr *sa) | | | @@ -798,30 +794,28 @@ mask_matchlen(const struct sockaddr *sa) |
798 | #ifndef USE_RADIX | | 794 | #ifndef USE_RADIX |
799 | static int | | 795 | static int |
800 | mask_match(const struct encaptab *ep, | | 796 | mask_match(const struct encaptab *ep, |
801 | const struct sockaddr *sp, | | 797 | const struct sockaddr *sp, |
802 | const struct sockaddr *dp) | | 798 | const struct sockaddr *dp) |
803 | { | | 799 | { |
804 | struct sockaddr_storage s; | | 800 | struct sockaddr_storage s; |
805 | struct sockaddr_storage d; | | 801 | struct sockaddr_storage d; |
806 | int i; | | 802 | int i; |
807 | const u_int8_t *p, *q; | | 803 | const u_int8_t *p, *q; |
808 | u_int8_t *r; | | 804 | u_int8_t *r; |
809 | int matchlen; | | 805 | int matchlen; |
810 | | | 806 | |
811 | #ifdef DIAGNOSTIC | | 807 | KASSERTMSG(ep->func == NULL, "wrong encaptab passed to mask_match"); |
812 | if (ep->func) | | 808 | |
813 | panic("wrong encaptab passed to mask_match"); | | | |
814 | #endif | | | |
815 | if (sp->sa_len > sizeof(s) || dp->sa_len > sizeof(d)) | | 809 | if (sp->sa_len > sizeof(s) || dp->sa_len > sizeof(d)) |
816 | return 0; | | 810 | return 0; |
817 | if (sp->sa_family != ep->af || dp->sa_family != ep->af) | | 811 | if (sp->sa_family != ep->af || dp->sa_family != ep->af) |
818 | return 0; | | 812 | return 0; |
819 | if (sp->sa_len != ep->src->sa_len || dp->sa_len != ep->dst->sa_len) | | 813 | if (sp->sa_len != ep->src->sa_len || dp->sa_len != ep->dst->sa_len) |
820 | return 0; | | 814 | return 0; |
821 | | | 815 | |
822 | matchlen = 0; | | 816 | matchlen = 0; |
823 | | | 817 | |
824 | p = (const u_int8_t *)sp; | | 818 | p = (const u_int8_t *)sp; |
825 | q = (const u_int8_t *)ep->srcmask; | | 819 | q = (const u_int8_t *)ep->srcmask; |
826 | r = (u_int8_t *)&s; | | 820 | r = (u_int8_t *)&s; |
827 | for (i = 0 ; i < sp->sa_len; i++) { | | 821 | for (i = 0 ; i < sp->sa_len; i++) { |