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