version 1.242.2.4, 2007/04/15 16:04:00 |
version 1.257, 2007/12/20 19:53:32 |
|
|
splx(s); |
splx(s); |
if (m == 0) |
if (m == 0) |
return; |
return; |
MCLAIM(m, &ip_rx_mowner); |
|
ip_input(m); |
ip_input(m); |
} |
} |
} |
} |
|
|
*/ |
*/ |
IPQ_LOCK(); |
IPQ_LOCK(); |
hash = IPREASS_HASH(ip->ip_src.s_addr, ip->ip_id); |
hash = IPREASS_HASH(ip->ip_src.s_addr, ip->ip_id); |
/* XXX LIST_FOREACH(fp, &ipq[hash], ipq_q) */ |
LIST_FOREACH(fp, &ipq[hash], ipq_q) { |
for (fp = LIST_FIRST(&ipq[hash]); fp != NULL; |
|
fp = LIST_NEXT(fp, ipq_q)) { |
|
if (ip->ip_id == fp->ipq_id && |
if (ip->ip_id == fp->ipq_id && |
in_hosteq(ip->ip_src, fp->ipq_src) && |
in_hosteq(ip->ip_src, fp->ipq_src) && |
in_hosteq(ip->ip_dst, fp->ipq_dst) && |
in_hosteq(ip->ip_dst, fp->ipq_dst) && |
|
|
/* XXX error stat??? */ |
/* XXX error stat??? */ |
error = EINVAL; |
error = EINVAL; |
DPRINTF(("ip_input: no SP, packet discarded\n"));/*XXX*/ |
DPRINTF(("ip_input: no SP, packet discarded\n"));/*XXX*/ |
goto bad; |
|
} |
} |
splx(s); |
splx(s); |
if (error) |
if (error) |
|
|
struct in_ifaddr * |
struct in_ifaddr * |
ip_rtaddr(struct in_addr dst) |
ip_rtaddr(struct in_addr dst) |
{ |
{ |
if (!in_hosteq(dst, satocsin(rtcache_getdst(&ipforward_rt))->sin_addr)) |
struct rtentry *rt; |
rtcache_free(&ipforward_rt); |
union { |
else |
struct sockaddr dst; |
rtcache_check(&ipforward_rt); |
struct sockaddr_in dst4; |
|
} u; |
if (ipforward_rt.ro_rt == NULL) { |
|
struct sockaddr_in *sin = satosin(&ipforward_rt.ro_dst); |
sockaddr_in_init(&u.dst4, &dst, 0); |
|
|
sin->sin_family = AF_INET; |
if ((rt = rtcache_lookup(&ipforward_rt, &u.dst)) == NULL) |
sin->sin_len = sizeof(*sin); |
return NULL; |
sin->sin_addr = dst; |
|
|
return ifatoia(rt->rt_ifa); |
rtcache_init(&ipforward_rt); |
|
if (ipforward_rt.ro_rt == NULL) |
|
return NULL; |
|
} |
|
return ifatoia(ipforward_rt.ro_rt->rt_ifa); |
|
} |
} |
|
|
/* |
/* |
Line 1784 ip_srcroute(void) |
|
Line 1775 ip_srcroute(void) |
|
return (m); |
return (m); |
} |
} |
|
|
/* |
|
* Strip out IP options, at higher |
|
* level protocol in the kernel. |
|
* Second argument is buffer to which options |
|
* will be moved, and return value is their length. |
|
* XXX should be deleted; last arg currently ignored. |
|
*/ |
|
void |
|
ip_stripoptions(struct mbuf *m, struct mbuf *mopt) |
|
{ |
|
int i; |
|
struct ip *ip = mtod(m, struct ip *); |
|
void *opts; |
|
int olen; |
|
|
|
olen = (ip->ip_hl << 2) - sizeof (struct ip); |
|
opts = (void *)(ip + 1); |
|
i = m->m_len - (sizeof (struct ip) + olen); |
|
memmove(opts, (char *)opts + olen, (unsigned)i); |
|
m->m_len -= olen; |
|
if (m->m_flags & M_PKTHDR) |
|
m->m_pkthdr.len -= olen; |
|
ip->ip_len = htons(ntohs(ip->ip_len) - olen); |
|
ip->ip_hl = sizeof (struct ip) >> 2; |
|
} |
|
|
|
const int inetctlerrmap[PRC_NCMDS] = { |
const int inetctlerrmap[PRC_NCMDS] = { |
0, 0, 0, 0, |
[PRC_MSGSIZE] = EMSGSIZE, |
0, EMSGSIZE, EHOSTDOWN, EHOSTUNREACH, |
[PRC_HOSTDEAD] = EHOSTDOWN, |
EHOSTUNREACH, EHOSTUNREACH, ECONNREFUSED, ECONNREFUSED, |
[PRC_HOSTUNREACH] = EHOSTUNREACH, |
EMSGSIZE, EHOSTUNREACH, 0, 0, |
[PRC_UNREACH_NET] = EHOSTUNREACH, |
0, 0, 0, 0, |
[PRC_UNREACH_HOST] = EHOSTUNREACH, |
ENOPROTOOPT |
[PRC_UNREACH_PROTOCOL] = ECONNREFUSED, |
|
[PRC_UNREACH_PORT] = ECONNREFUSED, |
|
[PRC_UNREACH_SRCFAIL] = EHOSTUNREACH, |
|
[PRC_PARAMPROB] = ENOPROTOOPT, |
}; |
}; |
|
|
/* |
/* |
Line 1841 ip_forward(struct mbuf *m, int srcrt) |
|
Line 1809 ip_forward(struct mbuf *m, int srcrt) |
|
int error, type = 0, code = 0, destmtu = 0; |
int error, type = 0, code = 0, destmtu = 0; |
struct mbuf *mcopy; |
struct mbuf *mcopy; |
n_long dest; |
n_long dest; |
|
union { |
|
struct sockaddr dst; |
|
struct sockaddr_in dst4; |
|
} u; |
|
|
/* |
/* |
* We are now in the output path. |
* We are now in the output path. |
Line 1869 ip_forward(struct mbuf *m, int srcrt) |
|
Line 1841 ip_forward(struct mbuf *m, int srcrt) |
|
return; |
return; |
} |
} |
|
|
if (!in_hosteq(ip->ip_dst, |
sockaddr_in_init(&u.dst4, &ip->ip_dst, 0); |
satocsin(rtcache_getdst(&ipforward_rt))->sin_addr)) |
if ((rt = rtcache_lookup(&ipforward_rt, &u.dst)) == NULL) { |
rtcache_free(&ipforward_rt); |
icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_NET, dest, 0); |
else |
return; |
rtcache_check(&ipforward_rt); |
|
if (ipforward_rt.ro_rt == NULL) { |
|
struct sockaddr_in *sin = satosin(&ipforward_rt.ro_dst); |
|
|
|
sin->sin_family = AF_INET; |
|
sin->sin_len = sizeof(*sin); |
|
sin->sin_addr = ip->ip_dst; |
|
|
|
rtcache_init(&ipforward_rt); |
|
if (ipforward_rt.ro_rt == NULL) { |
|
icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_NET, dest, 0); |
|
return; |
|
} |
|
} |
} |
rt = ipforward_rt.ro_rt; |
|
|
|
/* |
/* |
* Save at most 68 bytes of the packet in case |
* Save at most 68 bytes of the packet in case |
Line 1910 ip_forward(struct mbuf *m, int srcrt) |
|
Line 1868 ip_forward(struct mbuf *m, int srcrt) |
|
*/ |
*/ |
if (rt->rt_ifp == m->m_pkthdr.rcvif && |
if (rt->rt_ifp == m->m_pkthdr.rcvif && |
(rt->rt_flags & (RTF_DYNAMIC|RTF_MODIFIED)) == 0 && |
(rt->rt_flags & (RTF_DYNAMIC|RTF_MODIFIED)) == 0 && |
!in_nullhost(satosin(rt_key(rt))->sin_addr) && |
!in_nullhost(satocsin(rt_getkey(rt))->sin_addr) && |
ipsendredirects && !srcrt) { |
ipsendredirects && !srcrt) { |
if (rt->rt_ifa && |
if (rt->rt_ifa && |
(ip->ip_src.s_addr & ifatoia(rt->rt_ifa)->ia_subnetmask) == |
(ip->ip_src.s_addr & ifatoia(rt->rt_ifa)->ia_subnetmask) == |
Line 1976 ip_forward(struct mbuf *m, int srcrt) |
|
Line 1934 ip_forward(struct mbuf *m, int srcrt) |
|
type = ICMP_UNREACH; |
type = ICMP_UNREACH; |
code = ICMP_UNREACH_NEEDFRAG; |
code = ICMP_UNREACH_NEEDFRAG; |
#if !defined(IPSEC) && !defined(FAST_IPSEC) |
#if !defined(IPSEC) && !defined(FAST_IPSEC) |
if (ipforward_rt.ro_rt != NULL) |
if ((rt = rtcache_getrt(&ipforward_rt)) != NULL) |
destmtu = ipforward_rt.ro_rt->rt_ifp->if_mtu; |
destmtu = rt->rt_ifp->if_mtu; |
#else |
#else |
/* |
/* |
* If the packet is routed over IPsec tunnel, tell the |
* If the packet is routed over IPsec tunnel, tell the |
Line 1985 ip_forward(struct mbuf *m, int srcrt) |
|
Line 1943 ip_forward(struct mbuf *m, int srcrt) |
|
* tunnel MTU = if MTU - sizeof(IP) - ESP/AH hdrsiz |
* tunnel MTU = if MTU - sizeof(IP) - ESP/AH hdrsiz |
* XXX quickhack!!! |
* XXX quickhack!!! |
*/ |
*/ |
if (ipforward_rt.ro_rt != NULL) { |
if ((rt = rtcache_getrt(&ipforward_rt)) != NULL) { |
struct secpolicy *sp; |
struct secpolicy *sp; |
int ipsecerror; |
int ipsecerror; |
size_t ipsechdr; |
size_t ipsechdr; |
Line 1996 ip_forward(struct mbuf *m, int srcrt) |
|
Line 1954 ip_forward(struct mbuf *m, int srcrt) |
|
&ipsecerror); |
&ipsecerror); |
|
|
if (sp == NULL) |
if (sp == NULL) |
destmtu = ipforward_rt.ro_rt->rt_ifp->if_mtu; |
destmtu = rt->rt_ifp->if_mtu; |
else { |
else { |
/* count IPsec header size */ |
/* count IPsec header size */ |
ipsechdr = ipsec4_hdrsiz(mcopy, |
ipsechdr = ipsec4_hdrsiz(mcopy, |
Line 2011 ip_forward(struct mbuf *m, int srcrt) |
|
Line 1969 ip_forward(struct mbuf *m, int srcrt) |
|
&& sp->req->sav != NULL |
&& sp->req->sav != NULL |
&& sp->req->sav->sah != NULL) { |
&& sp->req->sav->sah != NULL) { |
ro = &sp->req->sav->sah->sa_route; |
ro = &sp->req->sav->sah->sa_route; |
if (ro->ro_rt && ro->ro_rt->rt_ifp) { |
if (rt && rt->rt_ifp) { |
destmtu = |
destmtu = |
ro->ro_rt->rt_rmx.rmx_mtu ? |
rt->rt_rmx.rmx_mtu ? |
ro->ro_rt->rt_rmx.rmx_mtu : |
rt->rt_rmx.rmx_mtu : |
ro->ro_rt->rt_ifp->if_mtu; |
rt->rt_ifp->if_mtu; |
destmtu -= ipsechdr; |
destmtu -= ipsechdr; |
} |
} |
} |
} |
Line 2096 ip_savecontrol(struct inpcb *inp, struct |
|
Line 2054 ip_savecontrol(struct inpcb *inp, struct |
|
if (inp->inp_flags & INP_RECVIF) { |
if (inp->inp_flags & INP_RECVIF) { |
struct sockaddr_dl sdl; |
struct sockaddr_dl sdl; |
|
|
sdl.sdl_len = offsetof(struct sockaddr_dl, sdl_data[0]); |
sockaddr_dl_init(&sdl, sizeof(sdl), |
sdl.sdl_family = AF_LINK; |
(m->m_pkthdr.rcvif != NULL) |
sdl.sdl_index = m->m_pkthdr.rcvif ? |
? m->m_pkthdr.rcvif->if_index |
m->m_pkthdr.rcvif->if_index : 0; |
: 0, |
sdl.sdl_nlen = sdl.sdl_alen = sdl.sdl_slen = 0; |
0, NULL, 0, NULL, 0); |
*mp = sbcreatecontrol((void *) &sdl, sdl.sdl_len, |
*mp = sbcreatecontrol(&sdl, sdl.sdl_len, IP_RECVIF, IPPROTO_IP); |
IP_RECVIF, IPPROTO_IP); |
|
if (*mp) |
if (*mp) |
mp = &(*mp)->m_next; |
mp = &(*mp)->m_next; |
} |
} |