summaryrefslogtreecommitdiffstats
path: root/sys/netinet/ip_mroute.c
diff options
context:
space:
mode:
authorwollman <wollman@FreeBSD.org>1994-10-13 22:12:42 +0000
committerwollman <wollman@FreeBSD.org>1994-10-13 22:12:42 +0000
commit04264ac71182739687dfc84b8c778b581c7eeb70 (patch)
treee4d86ed53b5a91b4bb23b7e388235c50c7cbe58b /sys/netinet/ip_mroute.c
parentbe3750e0d6e5a1610ff53f95f0a87ed63408a9f2 (diff)
downloadFreeBSD-src-04264ac71182739687dfc84b8c778b581c7eeb70.zip
FreeBSD-src-04264ac71182739687dfc84b8c778b581c7eeb70.tar.gz
Fix some endianness and packet header bugs found in BSDi's port of this code.
(From mbone mailing-list.)
Diffstat (limited to 'sys/netinet/ip_mroute.c')
-rw-r--r--sys/netinet/ip_mroute.c41
1 files changed, 27 insertions, 14 deletions
diff --git a/sys/netinet/ip_mroute.c b/sys/netinet/ip_mroute.c
index 345e4b8..4c5f1c5 100644
--- a/sys/netinet/ip_mroute.c
+++ b/sys/netinet/ip_mroute.c
@@ -1291,11 +1291,20 @@ phyint_send(ip, vifp, m)
struct mbuf *m;
{
register struct mbuf *mb_copy;
+ int hlen = ip->ip_hl << 2;
register struct ip_moptions *imo;
if ((mb_copy = m_copy(m, 0, M_COPYALL)) == NULL)
return;
+ /*
+ * Make sure the header isn't in an cluster, because the sharing
+ * in clusters defeats the whole purpose of making the copy above.
+ */
+ mb_copy = m_pullup(mb_copy, hlen);
+ if (mb_copy == NULL)
+ return;
+
MALLOC(imo, struct ip_moptions *, sizeof *imo, M_IPMOPTS, M_NOWAIT);
if (imo == NULL) {
m_freem(mb_copy);
@@ -1320,6 +1329,7 @@ srcrt_send(ip, vifp, m)
struct mbuf *m;
{
struct mbuf *mb_copy, *mb_opts;
+ int hlen = ip->ip_hl << 2;
register struct ip *ip_copy;
u_char *cp;
@@ -1338,15 +1348,7 @@ srcrt_send(ip, vifp, m)
if ((mb_copy = m_copy(m, 0, M_COPYALL)) == NULL)
return;
- ip_copy = mtod(mb_copy, struct ip *);
- ip_copy->ip_ttl--;
- ip_copy->ip_dst = vifp->v_rmt_addr; /* remote tunnel end-point */
- /*
- * Adjust the ip header length to account for the tunnel options.
- */
- ip_copy->ip_hl += TUNNEL_LEN >> 2;
- ip_copy->ip_len += TUNNEL_LEN;
- MGET(mb_opts, M_DONTWAIT, MT_HEADER);
+ MGETHDR(mb_opts, M_DONTWAIT, MT_HEADER);
if (mb_opts == NULL) {
m_freem(mb_copy);
return;
@@ -1354,19 +1356,28 @@ srcrt_send(ip, vifp, m)
/*
* 'Delete' the base ip header from the mb_copy chain
*/
- mb_copy->m_len -= IP_HDR_LEN;
- mb_copy->m_data += IP_HDR_LEN;
+ mb_copy->m_len -= hlen;
+ mb_copy->m_data += hlen;
/*
* Make mb_opts be the new head of the packet chain.
* Any options of the packet were left in the old packet chain head
*/
mb_opts->m_next = mb_copy;
- mb_opts->m_data += 16;
- mb_opts->m_len = IP_HDR_LEN + TUNNEL_LEN;
+ mb_opts->m_len = hlen + TUNNEL_LEN;
+ mb_opts->m_data += MSIZE - mb_opts->m_len;
+ mb_opts->m_pkthdr.len = mb_copy->m_pkthdr.len + TUNNEL_LEN;
/*
* Copy the base ip header from the mb_copy chain to the new head mbuf
*/
- bcopy((caddr_t)ip_copy, mtod(mb_opts, caddr_t), IP_HDR_LEN);
+ ip_copy = mtod(mb_opts, struct ip *);
+ bcopy((caddr_t)ip_copy, mtod(mb_opts, caddr_t), hlen);
+ ip_copy->ip_ttl--;
+ ip_copy->ip_dst = vifp->v_rmt_addr; /* remote tunnel end-point */
+ /*
+ * Adjust the ip header length to account for the tunnel options.
+ */
+ ip_copy->ip_hl += TUNNEL_LEN >> 2;
+ ip_copy->ip_len += TUNNEL_LEN;
/*
* Add the NOP and LSRR after the base ip header
*/
@@ -1394,6 +1405,7 @@ encap_send(ip, vifp, m)
{
register struct mbuf *mb_copy;
register struct ip *ip_copy;
+ int hlen = ip->ip_hl << 2;
register int i, len = ip->ip_len;
/*
@@ -1417,6 +1429,7 @@ encap_send(ip, vifp, m)
mb_copy = m_pullup(mb_copy, i);
if (mb_copy == NULL)
return;
+ mb_copy->m_pkthdr.len = len + sizeof(multicast_encap_iphdr);
/*
* fill in the encapsulating IP header.
OpenPOWER on IntegriCloud