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