On Wed, Jun 15, 2016 at 07:43:37PM +0200, Vincent Gross wrote:
> rev3 below.
> 
> I fixed the line length, the useless bzero(), and also the wording in
> ip.4
> 
> Ok ?

OK bluhm@

> 
> Index: sys/netinet/in.h
> ===================================================================
> RCS file: /cvs/src/sys/netinet/in.h,v
> retrieving revision 1.115
> diff -u -p -r1.115 in.h
> --- sys/netinet/in.h  20 Oct 2015 20:22:42 -0000      1.115
> +++ sys/netinet/in.h  15 Jun 2016 17:37:11 -0000
> @@ -307,6 +307,7 @@ struct ip_opts {
>  #define IP_RECVRTABLE                35   /* bool; receive rdomain w/dgram */
>  #define IP_IPSECFLOWINFO     36   /* bool; IPsec flow info for dgram */
>  #define IP_IPDEFTTL          37   /* int; IP TTL system default */
> +#define IP_SENDSRCADDR               38   /* struct in_addr; source address 
> to use */
>  
>  #define IP_RTABLE            0x1021  /* int; routing table, see SO_RTABLE */
>  #define IP_DIVERTFL          0x1022  /* int; divert direction flag opt */
> Index: sys/netinet/udp_usrreq.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet/udp_usrreq.c,v
> retrieving revision 1.212
> diff -u -p -r1.212 udp_usrreq.c
> --- sys/netinet/udp_usrreq.c  15 Jun 2016 16:06:35 -0000      1.212
> +++ sys/netinet/udp_usrreq.c  15 Jun 2016 17:37:11 -0000
> @@ -888,6 +888,7 @@ udp_output(struct inpcb *inp, struct mbu
>       struct sockaddr_in *sin = NULL;
>       struct udpiphdr *ui;
>       u_int32_t ipsecflowinfo = 0;
> +     struct sockaddr_in src_sin;
>       int len = m->m_pkthdr.len;
>       struct in_addr *laddr;
>       int error = 0;
> @@ -906,6 +907,8 @@ udp_output(struct inpcb *inp, struct mbu
>               goto release;
>       }
>  
> +     memset(&src_sin, 0, sizeof(src_sin));
> +
>       if (control) {
>               u_int clen;
>               struct cmsghdr *cm;
> @@ -939,9 +942,20 @@ udp_output(struct inpcb *inp, struct mbu
>                           cm->cmsg_level == IPPROTO_IP &&
>                           cm->cmsg_type == IP_IPSECFLOWINFO) {
>                               ipsecflowinfo = *(u_int32_t *)CMSG_DATA(cm);
> -                             break;
> -                     }
> +                     } else
>  #endif
> +                     if (cm->cmsg_len == CMSG_LEN(sizeof(struct in_addr)) &&
> +                         cm->cmsg_level == IPPROTO_IP &&
> +                         cm->cmsg_type == IP_SENDSRCADDR) {
> +                             memcpy(&src_sin.sin_addr, CMSG_DATA(cm),
> +                                 sizeof(struct in_addr));
> +                             src_sin.sin_family = AF_INET;
> +                             src_sin.sin_len = sizeof(src_sin);
> +                             /* no check on reuse when sin->sin_port == 0 */
> +                             if ((error = in_pcbaddrisavail(inp, &src_sin,
> +                                 0, curproc)))
> +                                     goto release;
> +                     }
>                       clen -= CMSG_ALIGN(cm->cmsg_len);
>                       cmsgs += CMSG_ALIGN(cm->cmsg_len);
>               } while (clen);
> @@ -979,6 +993,17 @@ udp_output(struct inpcb *inp, struct mbu
>                       splx(s);
>                       if (error)
>                               goto release;
> +             }
> +
> +             if (src_sin.sin_len > 0 &&
> +                 src_sin.sin_addr.s_addr != INADDR_ANY &&
> +                 src_sin.sin_addr.s_addr != inp->inp_laddr.s_addr) {
> +                     src_sin.sin_port = inp->inp_lport;
> +                     if (inp->inp_laddr.s_addr != INADDR_ANY &&
> +                         (error =
> +                         in_pcbaddrisavail(inp, &src_sin, 0, curproc)))
> +                             goto release;
> +                     laddr = &src_sin.sin_addr;
>               }
>       } else {
>               if (inp->inp_faddr.s_addr == INADDR_ANY) {
> Index: share/man/man4/ip.4
> ===================================================================
> RCS file: /cvs/src/share/man/man4/ip.4,v
> retrieving revision 1.38
> diff -u -p -r1.38 ip.4
> --- share/man/man4/ip.4       20 Oct 2015 22:08:19 -0000      1.38
> +++ share/man/man4/ip.4       15 Jun 2016 17:37:12 -0000
> @@ -290,6 +290,34 @@ cmsg_len = CMSG_LEN(sizeof(u_int))
>  cmsg_level = IPPROTO_IP
>  cmsg_type = IP_RECVRTABLE
>  .Ed
> +.Pp
> +When sending on a
> +.Dv SOCK_DGRAM
> +socket with
> +.Xr sendmsg 2
> +, the source address to be used can be passed as ancillary data with a type 
> code of
> +.Dv IP_SENDSRCADDR .
> +The
> +.Va msg_control
> +field in the
> +.Vt msghdr
> +structure should point to a buffer that contains a
> +.Vt cmsghdr
> +structure followed by the requested source address.
> +The
> +.Vt cmsghdr
> +fields should have the following values:
> +.Bd -literal -offset indent
> +cmsg_len = CMSG_LEN(sizeof(struct in_addr))
> +cmsg_level = IPPROTO_IP
> +cmsg_type = IP_SENDSRCADDR
> +.Ed
> +.Pp
> +The same checks and restrictions as for
> +.Xr bind 2
> +apply, unless the socket is bound to
> +.Dv INADDR_ANY .
> +In this case, there is no source address overlap check.
>  .Ss "Multicast Options"
>  .Tn IP
>  multicasting is supported only on

Reply via email to