On Fri, Mar 26, 2021 at 11:00:22AM +0000, Schreilechner, Dominik wrote:
> --- 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);
>  }

I think ip_insertoptions() is not intended to insert additional
options, but to set them.  The *phlen is set to htons(ntohs(ip->ip_len)
+ optlen), so the option length is optlen.  The ip->ip_hl += makes
no sense.  I am not sure if ip->ip_hl is always initialized.

ip_insertoptions() returns the option length in &hlen.  I think it
is the callers job to write it into the header.

Instead of touching ip_insertoptions() I would set ip->ip_hl = hlen
>> 2 in this block, like it is done in ip_output().
 
> +       if (opts != NULL) {
>                 m = ip_insertoptions(m, opts, &hlen);
> +               ip->ip_v = IPVERSION;
> +               ip->ip_off &= htons(IP_DF);
> +               ip->ip_id = htons(ip_randomid());
> +               ipstat_inc(ips_localout);
> +               ip_send_raw(m);
> +       } else

Appart from that, adding a special task seems the way to go.

bluhm

Reply via email to