Hello,
</snip>
> We really need to fix ip_send() such the output task will handle IP options
> properly.
took a look at bug reported by Dominik earlier today. Looks like
there are two issues:
1) ip_insertoptions() does not update length of IP header (ip_hl)
2) ip_hl is being overridden anyway later in ip_output() called
by ip_send_dispatch() to send ICMP error packet out. Looks
like ip_send_dispatch() should use IP_RAWOUTPUT flag so
ip_hl won't get overridden.
Diff below fixes both issues. We still have no good story when
ip_insertoptions() fails. I'll send another diff later this week.
diff below makes 'nping --ip-options T ...' to work. OK?
thanks and
regards
sashan
--------8<---------------8<---------------8<------------------8<--------
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index 0ec3f723be4..234c798e7d4 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -1789,7 +1789,7 @@ ip_send_dispatch(void *xmq)
NET_LOCK();
while ((m = ml_dequeue(&ml)) != NULL) {
- ip_output(m, NULL, NULL, 0, NULL, NULL, 0);
+ ip_output(m, NULL, NULL, IP_RAWOUTPUT, NULL, NULL, 0);
}
NET_UNLOCK();
}
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
index c01a3e7803c..ea803077304 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -765,6 +765,11 @@ ip_insertoptions(struct mbuf *m, struct mbuf *opt, int
*phlen)
optlen = opt->m_len - sizeof(p->ipopt_dst);
if (optlen + ntohs(ip->ip_len) > IP_MAXPACKET)
return (m); /* XXX should fail */
+
+ /* check if options will fit to IP header */
+ if ((optlen + (ip->ip_hl << 2)) > (0x0f << 2))
+ return (m);
+
if (p->ipopt_dst.s_addr)
ip->ip_dst = p->ipopt_dst;
if (m->m_flags & M_EXT || m->m_data - optlen < m->m_pktdat) {
@@ -790,6 +795,7 @@ ip_insertoptions(struct mbuf *m, struct mbuf *opt, int
*phlen)
memcpy(ip + 1, p->ipopt_list, optlen);
*phlen = sizeof(struct ip) + optlen;
ip->ip_len = htons(ntohs(ip->ip_len) + optlen);
+ ip->ip_hl += (optlen >> 2);
return (m);
}