remove assumption on redirect header option processing. from kame

This commit is contained in:
itojun 2003-06-03 05:20:06 +00:00
parent 627957eb53
commit 5c0f142820
1 changed files with 50 additions and 66 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: icmp6.c,v 1.90 2003/05/14 06:47:40 itojun Exp $ */
/* $NetBSD: icmp6.c,v 1.91 2003/06/03 05:20:06 itojun Exp $ */
/* $KAME: icmp6.c,v 1.217 2001/06/20 15:03:29 jinmei Exp $ */
/*
@ -66,7 +66,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: icmp6.c,v 1.90 2003/05/14 06:47:40 itojun Exp $");
__KERNEL_RCSID(0, "$NetBSD: icmp6.c,v 1.91 2003/06/03 05:20:06 itojun Exp $");
#include "opt_inet.h"
#include "opt_ipsec.h"
@ -2571,77 +2571,61 @@ icmp6_redirect_output(m0, rt)
if (p - (u_char *)ip6 > maxlen)
goto noredhdropt;
{
/* redirected header option */
int len;
struct nd_opt_rd_hdr *nd_opt_rh;
{
/* redirected header option */
int len;
struct nd_opt_rd_hdr *nd_opt_rh;
/*
* compute the maximum size for icmp6 redirect header option.
* XXX room for auth header?
*/
len = maxlen - (p - (u_char *)ip6);
len &= ~7;
/*
* compute the maximum size for icmp6 redirect header option.
* XXX room for auth header?
*/
len = maxlen - (p - (u_char *)ip6);
len &= ~7;
/* This is just for simplicity. */
if (m0->m_pkthdr.len != m0->m_len) {
if (m0->m_next) {
m_freem(m0->m_next);
m0->m_next = NULL;
}
m0->m_pkthdr.len = m0->m_len;
}
/*
* Redirected header option spec (RFC2461 4.6.3) talks nothing
* about padding/truncate rule for the original IP packet.
* From the discussion on IPv6imp in Feb 1999,
* the consensus was:
* - "attach as much as possible" is the goal
* - pad if not aligned (original size can be guessed by
* original ip6 header)
* Following code adds the padding if it is simple enough,
* and truncates if not.
*/
if (len - sizeof(*nd_opt_rh) < m0->m_pkthdr.len) {
/* not enough room, truncate */
m_adj(m0, (len - sizeof(*nd_opt_rh)) -
m0->m_pkthdr.len);
} else {
/*
* enough room, truncate if not aligned.
* we don't pad here for simplicity.
*/
size_t extra;
/*
* Redirected header option spec (RFC2461 4.6.3) talks nothing
* about padding/truncate rule for the original IP packet.
* From the discussion on IPv6imp in Feb 1999, the consensus was:
* - "attach as much as possible" is the goal
* - pad if not aligned (original size can be guessed by original
* ip6 header)
* Following code adds the padding if it is simple enough,
* and truncates if not.
*/
if (m0->m_next || m0->m_pkthdr.len != m0->m_len)
panic("assumption failed in %s:%d", __FILE__, __LINE__);
if (len - sizeof(*nd_opt_rh) < m0->m_pkthdr.len) {
/* not enough room, truncate */
m0->m_pkthdr.len = m0->m_len = len - sizeof(*nd_opt_rh);
} else {
/* enough room, pad or truncate */
size_t extra;
extra = m0->m_pkthdr.len % 8;
if (extra) {
/* pad if easy enough, truncate if not */
if (8 - extra <= M_TRAILINGSPACE(m0)) {
/* pad */
m0->m_len += (8 - extra);
m0->m_pkthdr.len += (8 - extra);
} else {
extra = m0->m_pkthdr.len % 8;
if (extra) {
/* truncate */
m0->m_pkthdr.len -= extra;
m0->m_len -= extra;
m_adj(m0, -extra);
}
len = m0->m_pkthdr.len + sizeof(*nd_opt_rh);
}
len = m0->m_pkthdr.len + sizeof(*nd_opt_rh);
m0->m_pkthdr.len = m0->m_len = len - sizeof(*nd_opt_rh);
nd_opt_rh = (struct nd_opt_rd_hdr *)p;
bzero(nd_opt_rh, sizeof(*nd_opt_rh));
nd_opt_rh->nd_opt_rh_type = ND_OPT_REDIRECTED_HEADER;
nd_opt_rh->nd_opt_rh_len = len >> 3;
p += sizeof(*nd_opt_rh);
m->m_pkthdr.len = m->m_len = p - (u_char *)ip6;
/* connect m0 to m */
m_cat(m, m0);
m->m_pkthdr.len += m0->m_pkthdr.len;
m0 = NULL;
}
nd_opt_rh = (struct nd_opt_rd_hdr *)p;
bzero(nd_opt_rh, sizeof(*nd_opt_rh));
nd_opt_rh->nd_opt_rh_type = ND_OPT_REDIRECTED_HEADER;
nd_opt_rh->nd_opt_rh_len = len >> 3;
p += sizeof(*nd_opt_rh);
m->m_pkthdr.len = m->m_len = p - (u_char *)ip6;
/* connect m0 to m */
m->m_next = m0;
m->m_pkthdr.len = m->m_len + m0->m_len;
m0 = NULL;
}
noredhdropt:;
noredhdropt:
if (m0) {
m_freem(m0);
m0 = NULL;