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);
 }
 

Reply via email to