Date: Wed, 20 Aug 2003 12:21:45 +0100 From: Bruce M Simpson <bms@spc.org> To: Sam Leffler <sam@errno.com>, Bill Fenner <fenestro@freebsd.org>, Jake Burkholder <jake@locore.ca>, mini@freebsd.org Cc: freebsd-arch@freebsd.org Message-ID: <20030820112145.GB11682@spc.org> In-Reply-To: <447450569.1061308767@melange.errno.com> References: <447450569.1061308767@melange.errno.com>
next in thread | previous in thread | raw e-mail | index | archive | help
--ALfTUftag+2gvp1h Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Tue, Aug 19, 2003 at 03:59:27PM -0700, Sam Leffler wrote: > this note is to insure "everyone" is aware. If your are actively working > on stuff related to the network code and I haven't already corresponded > with you; please let me know so we can coordinate our work--I have no > interest in duplicating the efforts of others. Otherwise, if you are > working in this area I'd appreciate knowing about any significant changes > planned that might affect what I'm doing. I'm preparing to commit the attached, any objections? (As soon as Jake wakes up, anyway ;). Was loosely following the flow of things from BSD/OS; it doesn't appear to impact on locking but I'm grateful for more expert review in this area. mini@ has looked over it and doesn't see any immediate problems. provisional log message: Add the IP_ONESBCAST option, to enable undirected IP broadcasts to be sent on specific interfaces. This is required by aodvd, and may in future help us in getting rid of the requirement for BPF from our import of isc-dhcp. Suggested by: fenestro Reviewed by: mini Referenced by: wstevens Obtained from: BSD/OS BMS --ALfTUftag+2gvp1h Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="onesbc.col.diff" Generated by diffcoll on Wed 20 Aug 2003 12:08:21 BST diff -uN src/sys/netinet/in.h.orig src/sys/netinet/in.h --- /usr/src/sys/netinet/in.h.orig Tue Aug 19 22:57:16 2003 +++ /usr/src/sys/netinet/in.h Wed Aug 20 12:08:16 2003 @@ -388,6 +388,8 @@ #define IP_IPSEC_POLICY 21 /* int; set/get security policy */ #define IP_FAITH 22 /* bool; accept FAITH'ed connections */ +#define IP_ONESBCAST 23 /* bool: send all-ones broadcast */ + #define IP_FW_ADD 50 /* add a firewall rule to chain */ #define IP_FW_DEL 51 /* delete a firewall rule from chain */ #define IP_FW_FLUSH 52 /* flush firewall rule chain */ diff -uN src/sys/netinet/ip_var.h.orig src/sys/netinet/ip_var.h --- /usr/src/sys/netinet/ip_var.h.orig Tue Aug 19 23:08:49 2003 +++ /usr/src/sys/netinet/ip_var.h Wed Aug 20 12:07:48 2003 @@ -139,6 +139,7 @@ /* flags passed to ip_output as last parameter */ #define IP_FORWARDING 0x1 /* most of ip header exists */ #define IP_RAWOUTPUT 0x2 /* raw ip header exists */ +#define IP_SENDONES 0x4 /* send all-ones broadcast */ #define IP_ROUTETOIF SO_DONTROUTE /* bypass routing tables */ #define IP_ALLOWBROADCAST SO_BROADCAST /* can send broadcast packets */ diff -uN src/sys/netinet/in_pcb.h.orig src/sys/netinet/in_pcb.h --- /usr/src/sys/netinet/in_pcb.h.orig Tue Aug 19 23:00:47 2003 +++ /usr/src/sys/netinet/in_pcb.h Wed Aug 20 12:07:48 2003 @@ -142,6 +142,7 @@ #define INP_IPV6 0x2 #define INP_IPV6PROTO 0x4 /* opened under IPv6 protocol */ #define INP_TIMEWAIT 0x8 /* .. probably doesn't go here */ +#define INP_ONESBCAST 0x10 /* send all-ones broadcast */ u_char inp_ip_ttl; /* time to live proto */ u_char inp_ip_p; /* protocol proto */ diff -uN src/sys/netinet/ip_output.c.orig src/sys/netinet/ip_output.c --- /usr/src/sys/netinet/ip_output.c.orig Tue Aug 19 23:01:37 2003 +++ /usr/src/sys/netinet/ip_output.c Wed Aug 20 12:07:48 2003 @@ -469,6 +469,8 @@ error = EMSGSIZE; goto bad; } + if (flags & IP_SENDONES) + ip->ip_dst.s_addr = INADDR_BROADCAST; m->m_flags |= M_BCAST; } else { m->m_flags &= ~M_BCAST; @@ -1427,6 +1429,7 @@ case IP_RECVTTL: case IP_RECVIF: case IP_FAITH: + case IP_ONESBCAST: error = sooptcopyin(sopt, &optval, sizeof optval, sizeof optval); if (error) @@ -1469,6 +1472,10 @@ case IP_FAITH: OPTSET(INP_FAITH); break; + + case IP_ONESBCAST: + OPTSET(INP_ONESBCAST); + break; } break; #undef OPTSET @@ -1562,6 +1569,7 @@ case IP_RECVIF: case IP_PORTRANGE: case IP_FAITH: + case IP_ONESBCAST: switch (sopt->sopt_name) { case IP_TOS: @@ -1605,6 +1613,10 @@ case IP_FAITH: optval = OPTBIT(INP_FAITH); + break; + + case IP_ONESBCAST: + optval = OPTBIT(INP_ONESBCAST); break; } error = sooptcopyout(sopt, &optval, sizeof optval); diff -uN src/sys/netinet/raw_ip.c.orig src/sys/netinet/raw_ip.c --- /usr/src/sys/netinet/raw_ip.c.orig Tue Aug 19 23:36:29 2003 +++ /usr/src/sys/netinet/raw_ip.c Wed Aug 20 12:07:48 2003 @@ -322,6 +322,9 @@ ipstat.ips_rawout++; } + if (inp->inp_flags & INP_ONESBCAST) + flags |= IP_SENDONES; + return (ip_output(m, inp->inp_options, &inp->inp_route, flags, inp->inp_moptions, inp)); } diff -uN src/sys/netinet/udp_usrreq.c.orig src/sys/netinet/udp_usrreq.c --- /usr/src/sys/netinet/udp_usrreq.c.orig Tue Aug 19 22:46:26 2003 +++ /usr/src/sys/netinet/udp_usrreq.c Wed Aug 20 12:07:48 2003 @@ -693,6 +693,7 @@ struct cmsghdr *cm; struct sockaddr_in *sin, src; int error = 0; + int ipflags; u_short fport, lport; #ifdef MAC @@ -821,6 +822,10 @@ ui->ui_dport = fport; ui->ui_ulen = htons((u_short)len + sizeof(struct udphdr)); + ipflags = inp->inp_socket->so_options & (SO_DONTROUTE | SO_BROADCAST); + if (inp->inp_flags & INP_ONESBCAST) + ipflags |= IP_SENDONES; + /* * Set up checksum and output datagram. */ @@ -837,8 +842,7 @@ ((struct ip *)ui)->ip_tos = inp->inp_ip_tos; /* XXX */ udpstat.udps_opackets++; - error = ip_output(m, inp->inp_options, &inp->inp_route, - (inp->inp_socket->so_options & (SO_DONTROUTE | SO_BROADCAST)), + error = ip_output(m, inp->inp_options, &inp->inp_route, ipflags, inp->inp_moptions, inp); return (error); diff -uN src/share/man/man4/ip.4.orig src/share/man/man4/ip.4 --- /usr/src/share/man/man4/ip.4.orig Tue Aug 19 23:40:22 2003 +++ /usr/src/share/man/man4/ip.4 Wed Aug 20 12:07:48 2003 @@ -175,6 +175,47 @@ .Xr sendmsg 2 . .Pp If the +.Dv IP_ONESBCAST +option is enabled on a +.Dv SOCK_DGRAM +or a +.Dv SOCK_RAW +socket, the destination address of outgoing +broadcast datagrams on that socket will be forced +to the undirected broadcast address, +.Dv INADDR_BROADCAST , +before transmission. +This is in contrast to the default behavior of the +system, which is to transmit undirected broadcasts +via the first network interface with the +.Dv IFF_BROADCAST flag set. +.Pp +This option allows applications to choose which +interface is used to transmit an undirected broadcast +datagram. +For example, the following code would force an +undirected broadcast to be transmitted via the interface +configured with the broadcast address 192.168.2.255: +.Bd -literal +char msg[512]; +struct sockaddr_in sin; +u_char onesbcast = 1; /* 0 = disable (default), 1 = enable */ + +setsockopt(s, IPPROTO_IP, IP_ONESBCAST, &onesbcast, sizeof(onesbcast)); +sin.sin_addr.s_addr = inet_addr("192.168.2.255"); +sin.sin_port = htons(1234); +sendto(s, msg, sizeof(msg), 0, &sin, sizeof(sin)); +.Ed +.Pp +It is the application's responsibility to set the +.Dv IP_TTL option +to an appropriate value in order to prevent broadcast storms. +The application must have sufficient credentials to set the +.Dv SO_BROADCAST +socket level option, otherwise the +.Dv IP_ONESBCAST option has no effect. +.Pp +If the .Dv IP_RECVTTL option is enabled on a .Dv SOCK_DGRAM --ALfTUftag+2gvp1h--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20030820112145.GB11682>