> -----Original Message-----
> From: Alexandr Nedvedicky <[email protected]>
> Sent: Mittwoch, 24. März 2021 23:09
> To: Schreilechner, Dominik (RC-AT DI FA DH-GRAZ ICO)
> <[email protected]>
> Cc: [email protected]
> Subject: Re: [External] : [ICMP] IP options lead to malformed reply
>
> 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.
Maybe I have overlooked something, but I see two problems with this.
When the IP_RAWOUTPUT flag is set, all packets send via ip_send() are
no longer included in the ips_localout statistic. Also, all callers of
ip_send() need to fill out the IP header themselves (as it would be
done in the beginning of ip_output() without the IP_RAWOUTPUT flag). As
far as I can tell this is not done for packets in a gif tunnel (e.g.
the ip_id is not calculated/added).
>
> 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
Regards
Dominik
>
> --------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);
> }
>