sync with recent kame.
avoid use of macros to manipulate sockaddrs (hides error case too much). correct IPv4 packet handling when ip option is present. preparations for ipsec policy engine upgrades.
This commit is contained in:
parent
6ae2cb140a
commit
d7e34999be
|
@ -1,10 +1,10 @@
|
|||
/* $NetBSD: ipsec.c,v 1.20 2000/05/08 18:31:10 thorpej Exp $ */
|
||||
/* $KAME: ipsec.c,v 1.53 2000/03/09 13:02:05 sakane Exp $ */
|
||||
/* $NetBSD: ipsec.c,v 1.21 2000/06/03 16:14:02 itojun Exp $ */
|
||||
/* $KAME: ipsec.c,v 1.65 2000/06/03 15:51:28 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
|
@ -16,7 +16,7 @@
|
|||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
|
@ -593,7 +593,6 @@ ipsec_setspidx_mbuf(spidx, dir, family, m)
|
|||
u_int dir, family;
|
||||
struct mbuf *m;
|
||||
{
|
||||
struct sockaddr *sa1, *sa2;
|
||||
|
||||
/* sanity check */
|
||||
if (spidx == NULL || m == NULL)
|
||||
|
@ -606,11 +605,6 @@ ipsec_setspidx_mbuf(spidx, dir, family, m)
|
|||
bzero(spidx, sizeof(*spidx));
|
||||
|
||||
spidx->dir = dir;
|
||||
sa1 = (struct sockaddr *)&spidx->src;
|
||||
sa2 = (struct sockaddr *)&spidx->dst;
|
||||
sa1->sa_len = sa2->sa_len = _SALENBYAF(family);
|
||||
sa1->sa_family = sa2->sa_family = family;
|
||||
spidx->prefs = spidx->prefd = _INALENBYAF(family) << 3;
|
||||
|
||||
{
|
||||
/* sanity check for packet length. */
|
||||
|
@ -635,6 +629,7 @@ ipsec_setspidx_mbuf(spidx, dir, family, m)
|
|||
{
|
||||
struct ip *ip;
|
||||
struct ip ipbuf;
|
||||
struct sockaddr_in *sin;
|
||||
|
||||
/* sanity check 1 for minimum ip header length */
|
||||
if (m->m_pkthdr.len < sizeof(struct ip)) {
|
||||
|
@ -657,23 +652,32 @@ ipsec_setspidx_mbuf(spidx, dir, family, m)
|
|||
ip = &ipbuf;
|
||||
}
|
||||
|
||||
/* some more checks on IPv4 header. */
|
||||
bcopy(&ip->ip_src, _INADDRBYSA(&spidx->src),
|
||||
sizeof(ip->ip_src));
|
||||
bcopy(&ip->ip_dst, _INADDRBYSA(&spidx->dst),
|
||||
sizeof(ip->ip_dst));
|
||||
/* XXX some more checks on IPv4 header. */
|
||||
|
||||
sin = (struct sockaddr_in *)&spidx->src;
|
||||
sin->sin_family = AF_INET;
|
||||
sin->sin_len = sizeof(*sin);
|
||||
bcopy(&ip->ip_src, &sin->sin_addr, sizeof(sin->sin_addr));
|
||||
sin->sin_port = IPSEC_PORT_ANY;
|
||||
|
||||
sin = (struct sockaddr_in *)&spidx->dst;
|
||||
sin->sin_family = AF_INET;
|
||||
sin->sin_len = sizeof(*sin);
|
||||
bcopy(&ip->ip_dst, &sin->sin_addr, sizeof(sin->sin_addr));
|
||||
sin->sin_port = IPSEC_PORT_ANY;
|
||||
|
||||
spidx->prefs = spidx->prefd = sizeof(struct in_addr) << 3;
|
||||
|
||||
spidx->ul_proto = ip->ip_p;
|
||||
_INPORTBYSA(&spidx->src) = IPSEC_PORT_ANY;
|
||||
_INPORTBYSA(&spidx->dst) = IPSEC_PORT_ANY;
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
{
|
||||
struct ip6_hdr *ip6_hdr;
|
||||
struct ip6_hdr *ip6;
|
||||
struct ip6_hdr ip6buf;
|
||||
struct sockaddr_in6 *sin6;
|
||||
|
||||
/* sanity check 1 for minimum ip header length */
|
||||
if (m->m_pkthdr.len < sizeof(struct ip6_hdr)) {
|
||||
|
@ -689,15 +693,15 @@ ipsec_setspidx_mbuf(spidx, dir, family, m)
|
|||
* get IPv6 header packet. usually the mbuf is contiguous
|
||||
* and we need no copies.
|
||||
*/
|
||||
if (m->m_len >= sizeof(*ip6_hdr))
|
||||
ip6_hdr = mtod(m, struct ip6_hdr *);
|
||||
if (m->m_len >= sizeof(*ip6))
|
||||
ip6 = mtod(m, struct ip6_hdr *);
|
||||
else {
|
||||
m_copydata(m, 0, sizeof(ip6buf), (caddr_t)&ip6buf);
|
||||
ip6_hdr = &ip6buf;
|
||||
ip6 = &ip6buf;
|
||||
}
|
||||
|
||||
/* some more checks on IPv4 header. */
|
||||
if ((ip6_hdr->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) {
|
||||
if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) {
|
||||
KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
|
||||
printf("ipsec_setspidx_mbuf: "
|
||||
"wrong ip version on packet "
|
||||
|
@ -705,10 +709,29 @@ ipsec_setspidx_mbuf(spidx, dir, family, m)
|
|||
goto bad;
|
||||
}
|
||||
|
||||
bcopy(&ip6_hdr->ip6_src, _INADDRBYSA(&spidx->src),
|
||||
sizeof(ip6_hdr->ip6_src));
|
||||
bcopy(&ip6_hdr->ip6_dst, _INADDRBYSA(&spidx->dst),
|
||||
sizeof(ip6_hdr->ip6_dst));
|
||||
sin6 = (struct sockaddr_in6 *)&spidx->src;
|
||||
sin6->sin6_family = AF_INET6;
|
||||
sin6->sin6_len = sizeof(*sin6);
|
||||
bcopy(&ip6->ip6_src, &sin6->sin6_addr, sizeof(sin6->sin6_addr));
|
||||
sin6->sin6_port = IPSEC_PORT_ANY;
|
||||
if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src)) {
|
||||
/* fix scope id for comparing SPD */
|
||||
sin6->sin6_addr.s6_addr16[1] = 0;
|
||||
sin6->sin6_scope_id = ntohs(ip6->ip6_src.s6_addr16[1]);
|
||||
}
|
||||
|
||||
sin6 = (struct sockaddr_in6 *)&spidx->dst;
|
||||
sin6->sin6_family = AF_INET6;
|
||||
sin6->sin6_len = sizeof(*sin6);
|
||||
bcopy(&ip6->ip6_dst, &sin6->sin6_addr, sizeof(sin6->sin6_addr));
|
||||
sin6->sin6_port = IPSEC_PORT_ANY;
|
||||
if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst)) {
|
||||
/* fix scope id for comparing SPD */
|
||||
sin6->sin6_addr.s6_addr16[1] = 0;
|
||||
sin6->sin6_scope_id = ntohs(ip6->ip6_dst.s6_addr16[1]);
|
||||
}
|
||||
|
||||
spidx->prefs = spidx->prefd = sizeof(struct in6_addr) << 3;
|
||||
|
||||
ipsec6_get_ulp(m, spidx);
|
||||
break;
|
||||
|
@ -753,8 +776,8 @@ ipsec6_get_ulp(m, spidx)
|
|||
|
||||
/* set default */
|
||||
spidx->ul_proto = IPSEC_ULPROTO_ANY;
|
||||
_INPORTBYSA(&spidx->src) = IPSEC_PORT_ANY;
|
||||
_INPORTBYSA(&spidx->dst) = IPSEC_PORT_ANY;
|
||||
((struct sockaddr_in6 *)&spidx->src)->sin6_port = IPSEC_PORT_ANY;
|
||||
((struct sockaddr_in6 *)&spidx->dst)->sin6_port = IPSEC_PORT_ANY;
|
||||
|
||||
nxt = -1;
|
||||
off = ip6_lasthdr(m, 0, IPPROTO_IPV6, &nxt);
|
||||
|
@ -767,8 +790,10 @@ ipsec6_get_ulp(m, spidx)
|
|||
if (off + sizeof(struct tcphdr) <= m->m_pkthdr.len) {
|
||||
struct tcphdr th;
|
||||
m_copydata(m, off, sizeof(th), (caddr_t)&th);
|
||||
_INPORTBYSA(&spidx->src) = th.th_sport;
|
||||
_INPORTBYSA(&spidx->dst) = th.th_dport;
|
||||
((struct sockaddr_in6 *)&spidx->src)->sin6_port =
|
||||
th.th_sport;
|
||||
((struct sockaddr_in6 *)&spidx->dst)->sin6_port =
|
||||
th.th_dport;
|
||||
}
|
||||
break;
|
||||
case IPPROTO_UDP:
|
||||
|
@ -776,8 +801,10 @@ ipsec6_get_ulp(m, spidx)
|
|||
if (off + sizeof(struct udphdr) <= m->m_pkthdr.len) {
|
||||
struct udphdr uh;
|
||||
m_copydata(m, off, sizeof(uh), (caddr_t)&uh);
|
||||
_INPORTBYSA(&spidx->src) = uh.uh_sport;
|
||||
_INPORTBYSA(&spidx->dst) = uh.uh_dport;
|
||||
((struct sockaddr_in6 *)&spidx->src)->sin6_port =
|
||||
uh.uh_sport;
|
||||
((struct sockaddr_in6 *)&spidx->dst)->sin6_port =
|
||||
uh.uh_dport;
|
||||
}
|
||||
break;
|
||||
case IPPROTO_ICMPV6:
|
||||
|
@ -795,7 +822,7 @@ ipsec4_setspidx_inpcb(m, pcb)
|
|||
struct inpcb *pcb;
|
||||
{
|
||||
struct secpolicyindex *spidx;
|
||||
struct sockaddr *sa1, *sa2;
|
||||
struct sockaddr_in *sin1, *sin2;
|
||||
|
||||
/* sanity check */
|
||||
if (pcb == NULL)
|
||||
|
@ -810,28 +837,28 @@ ipsec4_setspidx_inpcb(m, pcb)
|
|||
|
||||
spidx = &pcb->inp_sp->sp_in->spidx;
|
||||
spidx->dir = IPSEC_DIR_INBOUND;
|
||||
sa1 = (struct sockaddr *)&spidx->src;
|
||||
sa2 = (struct sockaddr *)&spidx->dst;
|
||||
sa1->sa_len = sa2->sa_len = _SALENBYAF(AF_INET);
|
||||
sa1->sa_family = sa2->sa_family = AF_INET;
|
||||
spidx->prefs = _INALENBYAF(AF_INET) << 3;
|
||||
spidx->prefd = _INALENBYAF(AF_INET) << 3;
|
||||
sin1 = (struct sockaddr_in *)&spidx->src;
|
||||
sin2 = (struct sockaddr_in *)&spidx->dst;
|
||||
sin1->sin_len = sin2->sin_len = sizeof(struct sockaddr_in);
|
||||
sin1->sin_family = sin2->sin_family = AF_INET;
|
||||
spidx->prefs = sizeof(struct in_addr) << 3;
|
||||
spidx->prefd = sizeof(struct in_addr) << 3;
|
||||
spidx->ul_proto = pcb->inp_socket->so_proto->pr_protocol;
|
||||
_INPORTBYSA(&spidx->src) = pcb->inp_fport;
|
||||
_INPORTBYSA(&spidx->dst) = pcb->inp_lport;
|
||||
sin1->sin_port = pcb->inp_fport;
|
||||
sin2->sin_port = pcb->inp_lport;
|
||||
ipsec4_setspidx_ipaddr(m, spidx);
|
||||
|
||||
spidx = &pcb->inp_sp->sp_out->spidx;
|
||||
spidx->dir = IPSEC_DIR_OUTBOUND;
|
||||
sa1 = (struct sockaddr *)&spidx->src;
|
||||
sa2 = (struct sockaddr *)&spidx->dst;
|
||||
sa1->sa_len = sa2->sa_len = _SALENBYAF(AF_INET);
|
||||
sa1->sa_family = sa2->sa_family = AF_INET;
|
||||
spidx->prefs = _INALENBYAF(AF_INET) << 3;
|
||||
spidx->prefd = _INALENBYAF(AF_INET) << 3;
|
||||
sin1 = (struct sockaddr_in *)&spidx->src;
|
||||
sin2 = (struct sockaddr_in *)&spidx->dst;
|
||||
sin1->sin_len = sin2->sin_len = sizeof(struct sockaddr_in);
|
||||
sin1->sin_family = sin2->sin_family = AF_INET;
|
||||
spidx->prefs = sizeof(struct in_addr) << 3;
|
||||
spidx->prefd = sizeof(struct in_addr) << 3;
|
||||
spidx->ul_proto = pcb->inp_socket->so_proto->pr_protocol;
|
||||
_INPORTBYSA(&spidx->src) = pcb->inp_lport;
|
||||
_INPORTBYSA(&spidx->dst) = pcb->inp_fport;
|
||||
sin1->sin_port = pcb->inp_lport;
|
||||
sin2->sin_port = pcb->inp_fport;
|
||||
ipsec4_setspidx_ipaddr(m, spidx);
|
||||
|
||||
return;
|
||||
|
@ -865,8 +892,10 @@ ipsec4_setspidx_ipaddr(m, spidx)
|
|||
ip = &ipbuf;
|
||||
}
|
||||
|
||||
bcopy(&ip->ip_src, _INADDRBYSA(&spidx->src), sizeof(ip->ip_src));
|
||||
bcopy(&ip->ip_dst, _INADDRBYSA(&spidx->dst), sizeof(ip->ip_dst));
|
||||
bcopy(&ip->ip_src, &((struct sockaddr_in *)&spidx->src)->sin_addr,
|
||||
sizeof(ip->ip_src));
|
||||
bcopy(&ip->ip_dst, &((struct sockaddr_in *)&spidx->dst)->sin_addr,
|
||||
sizeof(ip->ip_dst));
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -878,7 +907,7 @@ ipsec6_setspidx_in6pcb(m, pcb)
|
|||
struct in6pcb *pcb;
|
||||
{
|
||||
struct secpolicyindex *spidx;
|
||||
struct sockaddr *sa1, *sa2;
|
||||
struct sockaddr_in6 *sin1, *sin2;
|
||||
|
||||
/* sanity check */
|
||||
if (pcb == NULL)
|
||||
|
@ -893,28 +922,28 @@ ipsec6_setspidx_in6pcb(m, pcb)
|
|||
|
||||
spidx = &pcb->in6p_sp->sp_in->spidx;
|
||||
spidx->dir = IPSEC_DIR_INBOUND;
|
||||
sa1 = (struct sockaddr *)&spidx->src;
|
||||
sa2 = (struct sockaddr *)&spidx->dst;
|
||||
sa1->sa_len = sa2->sa_len = _SALENBYAF(AF_INET6);
|
||||
sa1->sa_family = sa2->sa_family = AF_INET6;
|
||||
spidx->prefs = _INALENBYAF(AF_INET6) << 3;
|
||||
spidx->prefd = _INALENBYAF(AF_INET6) << 3;
|
||||
sin1 = (struct sockaddr_in6 *)&spidx->src;
|
||||
sin2 = (struct sockaddr_in6 *)&spidx->dst;
|
||||
sin1->sin6_len = sin2->sin6_len = sizeof(struct sockaddr_in6);
|
||||
sin1->sin6_family = sin2->sin6_family = AF_INET6;
|
||||
spidx->prefs = sizeof(struct in6_addr) << 3;
|
||||
spidx->prefd = sizeof(struct in6_addr) << 3;
|
||||
spidx->ul_proto = pcb->in6p_socket->so_proto->pr_protocol;
|
||||
_INPORTBYSA(&spidx->src) = pcb->in6p_fport;
|
||||
_INPORTBYSA(&spidx->dst) = pcb->in6p_lport;
|
||||
sin1->sin6_port = pcb->in6p_fport;
|
||||
sin2->sin6_port = pcb->in6p_lport;
|
||||
ipsec6_setspidx_ipaddr(m, spidx);
|
||||
|
||||
spidx = &pcb->in6p_sp->sp_out->spidx;
|
||||
spidx->dir = IPSEC_DIR_OUTBOUND;
|
||||
sa1 = (struct sockaddr *)&spidx->src;
|
||||
sa2 = (struct sockaddr *)&spidx->dst;
|
||||
sa1->sa_len = sa2->sa_len = _SALENBYAF(AF_INET6);
|
||||
sa1->sa_family = sa2->sa_family = AF_INET6;
|
||||
spidx->prefs = _INALENBYAF(AF_INET6) << 3;
|
||||
spidx->prefd = _INALENBYAF(AF_INET6) << 3;
|
||||
sin1 = (struct sockaddr_in6 *)&spidx->src;
|
||||
sin2 = (struct sockaddr_in6 *)&spidx->dst;
|
||||
sin1->sin6_len = sin2->sin6_len = sizeof(struct sockaddr_in6);
|
||||
sin1->sin6_family = sin2->sin6_family = AF_INET6;
|
||||
spidx->prefs = sizeof(struct in6_addr) << 3;
|
||||
spidx->prefd = sizeof(struct in6_addr) << 3;
|
||||
spidx->ul_proto = pcb->in6p_socket->so_proto->pr_protocol;
|
||||
_INPORTBYSA(&spidx->src) = pcb->in6p_lport;
|
||||
_INPORTBYSA(&spidx->dst) = pcb->in6p_fport;
|
||||
sin1->sin6_port = pcb->in6p_lport;
|
||||
sin2->sin6_port = pcb->in6p_fport;
|
||||
ipsec6_setspidx_ipaddr(m, spidx);
|
||||
|
||||
return;
|
||||
|
@ -925,8 +954,9 @@ ipsec6_setspidx_ipaddr(m, spidx)
|
|||
struct mbuf *m;
|
||||
struct secpolicyindex *spidx;
|
||||
{
|
||||
struct ip6_hdr *ip6_hdr = NULL;
|
||||
struct ip6_hdr *ip6 = NULL;
|
||||
struct ip6_hdr ip6buf;
|
||||
struct sockaddr_in6 *sin6;
|
||||
|
||||
/* sanity check 1 for minimum ip header length */
|
||||
if (m == NULL)
|
||||
|
@ -941,14 +971,14 @@ ipsec6_setspidx_ipaddr(m, spidx)
|
|||
return;
|
||||
}
|
||||
|
||||
if (m->m_len >= sizeof(*ip6_hdr))
|
||||
ip6_hdr = mtod(m, struct ip6_hdr *);
|
||||
if (m->m_len >= sizeof(*ip6))
|
||||
ip6 = mtod(m, struct ip6_hdr *);
|
||||
else {
|
||||
m_copydata(m, 0, sizeof(ip6buf), (caddr_t)&ip6buf);
|
||||
ip6_hdr = &ip6buf;
|
||||
ip6 = &ip6buf;
|
||||
}
|
||||
|
||||
if ((ip6_hdr->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) {
|
||||
if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) {
|
||||
KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
|
||||
printf("ipsec_setspidx_mbuf: "
|
||||
"wrong ip version on packet "
|
||||
|
@ -956,10 +986,19 @@ ipsec6_setspidx_ipaddr(m, spidx)
|
|||
return;
|
||||
}
|
||||
|
||||
bcopy(&ip6_hdr->ip6_src, _INADDRBYSA(&spidx->src),
|
||||
sizeof(ip6_hdr->ip6_src));
|
||||
bcopy(&ip6_hdr->ip6_dst, _INADDRBYSA(&spidx->dst),
|
||||
sizeof(ip6_hdr->ip6_dst));
|
||||
sin6 = (struct sockaddr_in6 *)&spidx->src;
|
||||
bcopy(&ip6->ip6_src, &sin6->sin6_addr, sizeof(ip6->ip6_src));
|
||||
if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src)) {
|
||||
sin6->sin6_addr.s6_addr16[1] = 0;
|
||||
sin6->sin6_scope_id = ntohs(ip6->ip6_src.s6_addr16[1]);
|
||||
}
|
||||
|
||||
sin6 = (struct sockaddr_in6 *)&spidx->dst;
|
||||
bcopy(&ip6->ip6_dst, &sin6->sin6_addr, sizeof(ip6->ip6_dst));
|
||||
if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst)) {
|
||||
sin6->sin6_addr.s6_addr16[1] = 0;
|
||||
sin6->sin6_scope_id = ntohs(ip6->ip6_dst.s6_addr16[1]);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -1263,6 +1302,9 @@ ipsec4_delete_pcbpolicy(inp)
|
|||
if (inp == NULL)
|
||||
panic("ipsec4_delete_pcbpolicy: NULL pointer was passed.\n");
|
||||
|
||||
if (inp->inp_sp == NULL)
|
||||
return 0;
|
||||
|
||||
if (inp->inp_sp->sp_in != NULL) {
|
||||
key_freesp(inp->inp_sp->sp_in);
|
||||
inp->inp_sp->sp_in = NULL;
|
||||
|
@ -1359,6 +1401,9 @@ ipsec6_delete_pcbpolicy(in6p)
|
|||
if (in6p == NULL)
|
||||
panic("ipsec6_delete_pcbpolicy: NULL pointer was passed.\n");
|
||||
|
||||
if (in6p->in6p_sp == NULL)
|
||||
return 0;
|
||||
|
||||
if (in6p->in6p_sp->sp_in != NULL) {
|
||||
key_freesp(in6p->in6p_sp->sp_in);
|
||||
in6p->in6p_sp->sp_in = NULL;
|
||||
|
@ -1852,6 +1897,9 @@ ipsec4_encapsulate(m, sav)
|
|||
}
|
||||
#endif
|
||||
|
||||
if (m->m_len < sizeof(*ip))
|
||||
panic("ipsec4_encapsulate: assumption failed (first mbuf length)");
|
||||
|
||||
ip = mtod(m, struct ip *);
|
||||
#ifdef _IP_VHL
|
||||
hlen = _IP_VHL_HL(ip->ip_vhl) << 2;
|
||||
|
@ -1859,6 +1907,9 @@ ipsec4_encapsulate(m, sav)
|
|||
hlen = ip->ip_hl << 2;
|
||||
#endif
|
||||
|
||||
if (m->m_len != hlen)
|
||||
panic("ipsec4_encapsulate: assumption failed (first mbuf length)");
|
||||
|
||||
/* generate header checksum */
|
||||
ip->ip_sum = 0;
|
||||
#ifdef _IP_VHL
|
||||
|
@ -1876,8 +1927,6 @@ ipsec4_encapsulate(m, sav)
|
|||
* grow the mbuf to accomodate the new IPv4 header.
|
||||
* NOTE: IPv4 options will never be copied.
|
||||
*/
|
||||
if (m->m_len != hlen)
|
||||
panic("ipsec4_encapsulate: assumption failed (first mbuf length)");
|
||||
if (M_LEADINGSPACE(m->m_next) < hlen) {
|
||||
struct mbuf *n;
|
||||
MGET(n, M_DONTWAIT, MT_DATA);
|
||||
|
@ -2351,7 +2400,7 @@ ipsec4_output(state, sp, flags)
|
|||
struct in_ifaddr *ia;
|
||||
#endif
|
||||
struct sockaddr_in *dst4;
|
||||
struct sockaddr *sa;
|
||||
struct sockaddr_in *sin;
|
||||
|
||||
if (!state)
|
||||
panic("state == NULL in ipsec4_output");
|
||||
|
@ -2382,21 +2431,21 @@ ipsec4_output(state, sp, flags)
|
|||
/* make SA index for search proper SA */
|
||||
ip = mtod(state->m, struct ip *);
|
||||
bcopy(&isr->saidx, &saidx, sizeof(saidx));
|
||||
sa = (struct sockaddr *)&saidx.src;
|
||||
if (sa->sa_len == 0) {
|
||||
sa->sa_len = _SALENBYAF(AF_INET);
|
||||
sa->sa_family = AF_INET;
|
||||
_INPORTBYSA(&saidx.src) = IPSEC_PORT_ANY;
|
||||
bcopy(&ip->ip_src, _INADDRBYSA(&saidx.src),
|
||||
sizeof(ip->ip_src));
|
||||
sin = (struct sockaddr_in *)&saidx.src;
|
||||
if (sin->sin_len == 0) {
|
||||
sin->sin_len = sizeof(*sin);
|
||||
sin->sin_family = AF_INET;
|
||||
sin->sin_port = IPSEC_PORT_ANY;
|
||||
bcopy(&ip->ip_src, &sin->sin_addr,
|
||||
sizeof(sin->sin_addr));
|
||||
}
|
||||
sa = (struct sockaddr *)&saidx.dst;
|
||||
if (sa->sa_len == 0) {
|
||||
sa->sa_len = _SALENBYAF(AF_INET);
|
||||
sa->sa_family = AF_INET;
|
||||
_INPORTBYSA(&saidx.dst) = IPSEC_PORT_ANY;
|
||||
bcopy(&ip->ip_dst, _INADDRBYSA(&saidx.dst),
|
||||
sizeof(ip->ip_dst));
|
||||
sin = (struct sockaddr_in *)&saidx.dst;
|
||||
if (sin->sin_len == 0) {
|
||||
sin->sin_len = sizeof(*sin);
|
||||
sin->sin_family = AF_INET;
|
||||
sin->sin_port = IPSEC_PORT_ANY;
|
||||
bcopy(&ip->ip_dst, &sin->sin_addr,
|
||||
sizeof(sin->sin_addr));
|
||||
}
|
||||
|
||||
if ((error = key_checkrequest(isr, &saidx)) != 0) {
|
||||
|
@ -2456,8 +2505,6 @@ ipsec4_output(state, sp, flags)
|
|||
goto bad;
|
||||
}
|
||||
|
||||
ip = mtod(state->m, struct ip *);
|
||||
|
||||
state->m = ipsec4_splithdr(state->m);
|
||||
if (!state->m) {
|
||||
splx(s);
|
||||
|
@ -2583,7 +2630,7 @@ ipsec6_output_trans(state, nexthdrp, mprev, sp, flags, tun)
|
|||
struct secasindex saidx;
|
||||
int error = 0;
|
||||
int plen;
|
||||
struct sockaddr *sa;
|
||||
struct sockaddr_in6 *sin6;
|
||||
|
||||
if (!state)
|
||||
panic("state == NULL in ipsec6_output");
|
||||
|
@ -2612,21 +2659,31 @@ ipsec6_output_trans(state, nexthdrp, mprev, sp, flags, tun)
|
|||
/* make SA index for search proper SA */
|
||||
ip6 = mtod(state->m, struct ip6_hdr *);
|
||||
bcopy(&isr->saidx, &saidx, sizeof(saidx));
|
||||
sa = (struct sockaddr *)&saidx.src;
|
||||
if (sa->sa_len == 0) {
|
||||
sa->sa_len = _SALENBYAF(AF_INET6);
|
||||
sa->sa_family = AF_INET6;
|
||||
_INPORTBYSA(&saidx.src) = IPSEC_PORT_ANY;
|
||||
bcopy(&ip6->ip6_src, _INADDRBYSA(&saidx.src),
|
||||
sizeof(ip6->ip6_src));
|
||||
sin6 = (struct sockaddr_in6 *)&saidx.src;
|
||||
if (sin6->sin6_len == 0) {
|
||||
sin6->sin6_len = sizeof(*sin6);
|
||||
sin6->sin6_family = AF_INET6;
|
||||
sin6->sin6_port = IPSEC_PORT_ANY;
|
||||
bcopy(&ip6->ip6_src, &sin6->sin6_addr,
|
||||
sizeof(ip6->ip6_src));
|
||||
if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src)) {
|
||||
/* fix scope id for comparing SPD */
|
||||
sin6->sin6_addr.s6_addr16[1] = 0;
|
||||
sin6->sin6_scope_id = ntohs(ip6->ip6_src.s6_addr16[1]);
|
||||
}
|
||||
}
|
||||
sa = (struct sockaddr *)&saidx.dst;
|
||||
if (sa->sa_len == 0) {
|
||||
sa->sa_len = _SALENBYAF(AF_INET6);
|
||||
sa->sa_family = AF_INET6;
|
||||
_INPORTBYSA(&saidx.dst) = IPSEC_PORT_ANY;
|
||||
bcopy(&ip6->ip6_dst, _INADDRBYSA(&saidx.dst),
|
||||
sizeof(ip6->ip6_dst));
|
||||
sin6 = (struct sockaddr_in6 *)&saidx.dst;
|
||||
if (sin6->sin6_len == 0) {
|
||||
sin6->sin6_len = sizeof(*sin6);
|
||||
sin6->sin6_family = AF_INET6;
|
||||
sin6->sin6_port = IPSEC_PORT_ANY;
|
||||
bcopy(&ip6->ip6_dst, &sin6->sin6_addr,
|
||||
sizeof(ip6->ip6_dst));
|
||||
if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst)) {
|
||||
/* fix scope id for comparing SPD */
|
||||
sin6->sin6_addr.s6_addr16[1] = 0;
|
||||
sin6->sin6_scope_id = ntohs(ip6->ip6_dst.s6_addr16[1]);
|
||||
}
|
||||
}
|
||||
|
||||
if (key_checkrequest(isr, &saidx) == ENOENT) {
|
||||
|
@ -2814,8 +2871,6 @@ ipsec6_output_tunnel(state, sp, flags)
|
|||
goto bad;
|
||||
}
|
||||
|
||||
ip6 = mtod(state->m, struct ip6_hdr *);
|
||||
|
||||
state->m = ipsec6_splithdr(state->m);
|
||||
if (!state->m) {
|
||||
splx(s);
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
/* $NetBSD: ipsec.h,v 1.12 2000/03/01 12:49:48 itojun Exp $ */
|
||||
/* $NetBSD: ipsec.h,v 1.13 2000/06/03 16:14:03 itojun Exp $ */
|
||||
/* $KAME: ipsec.h,v 1.31 2000/05/18 12:32:32 sumikawa Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
|
@ -15,7 +16,7 @@
|
|||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
|
@ -73,6 +74,7 @@ struct secpolicy {
|
|||
|
||||
int refcnt; /* reference count */
|
||||
struct secpolicyindex spidx; /* selector */
|
||||
u_int32_t id; /* It's unique number on the system. */
|
||||
u_int state; /* 0: dead, others: alive */
|
||||
#define IPSEC_SPSTATE_DEAD 0
|
||||
#define IPSEC_SPSTATE_ALIVE 1
|
||||
|
@ -102,6 +104,17 @@ struct inpcbpolicy {
|
|||
struct secpolicy *sp_out;
|
||||
int priv; /* privileged socket ? */
|
||||
};
|
||||
|
||||
/* SP acquiring list table. */
|
||||
struct secspacq {
|
||||
LIST_ENTRY(secspacq) chain;
|
||||
|
||||
struct secpolicyindex spidx;
|
||||
|
||||
u_int32_t tick; /* for lifetime */
|
||||
int count; /* for lifetime */
|
||||
/* XXX: here is mbuf place holder to be sent ? */
|
||||
};
|
||||
#endif /*_KERNEL*/
|
||||
|
||||
/* according to IANA assignment, port 0x0000 and proto 0xff are reserved. */
|
||||
|
@ -176,7 +189,7 @@ struct ipsecstat {
|
|||
u_quad_t in_ahhist[256];
|
||||
u_quad_t in_comphist[256];
|
||||
u_quad_t out_success; /* succeeded outbound process */
|
||||
u_quad_t out_polvio;
|
||||
u_quad_t out_polvio;
|
||||
/* security policy violation for outbound process */
|
||||
u_quad_t out_nosa; /* outbound SA is unavailable */
|
||||
u_quad_t out_inval; /* outbound process failed due to EINVAL */
|
||||
|
|
Loading…
Reference in New Issue