On 2022/03/19 19:14, David Gwynne wrote:
> On Thu, Mar 17, 2022 at 12:05:16PM -0600, Theo de Raadt wrote:
> > This should not be done in applications.  The kernel must do it.  It means
> > the current kernel code is worng.
> 
> i think this is the right place for raw ipv4 sockets like what
> ping/traceroute uses.
> 
> ipv6 looks like it already does the right thing.

Given that this turned out so similar to the existing v6 support that
I think you didn't notice before writing the v4 version, this looks
like the right place indeed :)

Works for me, OK



> Index: raw_ip.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet/raw_ip.c,v
> retrieving revision 1.123
> diff -u -p -r1.123 raw_ip.c
> --- raw_ip.c  14 Mar 2022 22:38:43 -0000      1.123
> +++ raw_ip.c  19 Mar 2022 03:40:44 -0000
> @@ -222,6 +222,7 @@ int
>  rip_output(struct mbuf *m, struct socket *so, struct sockaddr *dstaddr,
>      struct mbuf *control)
>  {
> +     struct sockaddr_in *dst = satosin(dstaddr);
>       struct ip *ip;
>       struct inpcb *inp;
>       int flags, error;
> @@ -246,8 +247,8 @@ rip_output(struct mbuf *m, struct socket
>               ip->ip_off = htons(0);
>               ip->ip_p = inp->inp_ip.ip_p;
>               ip->ip_len = htons(m->m_pkthdr.len);
> -             ip->ip_src = inp->inp_laddr;
> -             ip->ip_dst = satosin(dstaddr)->sin_addr;
> +             ip->ip_src.s_addr = INADDR_ANY;
> +             ip->ip_dst = dst->sin_addr;
>               ip->ip_ttl = inp->inp_ip.ip_ttl ? inp->inp_ip.ip_ttl : MAXTTL;
>       } else {
>               if (m->m_pkthdr.len > IP_MAXPACKET) {
> @@ -262,11 +263,23 @@ rip_output(struct mbuf *m, struct socket
>               ip = mtod(m, struct ip *);
>               if (ip->ip_id == 0)
>                       ip->ip_id = htons(ip_randomid());
> +             dst->sin_addr = ip->ip_dst;
>  
>               /* XXX prevent ip_output from overwriting header fields */
>               flags |= IP_RAWOUTPUT;
>               ipstat_inc(ips_rawout);
>       }
> +
> +     if (ip->ip_src.s_addr == INADDR_ANY) {
> +             struct in_addr *laddr;
> +
> +             error = in_pcbselsrc(&laddr, dst, inp);
> +             if (error != 0)
> +                     return (error);
> +
> +             ip->ip_src = *laddr;
> +     }
> +
>  #ifdef INET6
>       /*
>        * A thought:  Even though raw IP shouldn't be able to set IPv6
> 

Reply via email to