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
Obtained from:  BSD/OS
Reviewed by:    mini, sam
Approved by:    jake (mentor)
This commit is contained in:
Bruce M Simpson 2003-08-20 14:46:40 +00:00
parent 2d81cd746b
commit 8afa230470
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=119178
7 changed files with 66 additions and 2 deletions

View File

@ -175,6 +175,47 @@ can be used directly as a control message for
.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

View File

@ -388,6 +388,8 @@ __END_DECLS
#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 */

View File

@ -142,6 +142,7 @@ struct inpcb {
#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 */

View File

@ -477,6 +477,8 @@ ip_output(struct mbuf *m0, struct mbuf *opt, struct route *ro,
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;
@ -1473,6 +1475,7 @@ ip_ctloutput(so, sopt)
case IP_RECVTTL:
case IP_RECVIF:
case IP_FAITH:
case IP_ONESBCAST:
error = sooptcopyin(sopt, &optval, sizeof optval,
sizeof optval);
if (error)
@ -1515,6 +1518,10 @@ ip_ctloutput(so, sopt)
case IP_FAITH:
OPTSET(INP_FAITH);
break;
case IP_ONESBCAST:
OPTSET(INP_ONESBCAST);
break;
}
break;
#undef OPTSET
@ -1608,6 +1615,7 @@ ip_ctloutput(so, sopt)
case IP_RECVIF:
case IP_PORTRANGE:
case IP_FAITH:
case IP_ONESBCAST:
switch (sopt->sopt_name) {
case IP_TOS:
@ -1652,6 +1660,10 @@ ip_ctloutput(so, sopt)
case IP_FAITH:
optval = OPTBIT(INP_FAITH);
break;
case IP_ONESBCAST:
optval = OPTBIT(INP_ONESBCAST);
break;
}
error = sooptcopyout(sopt, &optval, sizeof optval);
break;

View File

@ -139,6 +139,7 @@ struct ipstat {
/* 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 */

View File

@ -322,6 +322,9 @@ rip_output(m, so, dst)
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));
}

View File

@ -693,6 +693,7 @@ udp_output(inp, m, addr, control, td)
struct cmsghdr *cm;
struct sockaddr_in *sin, src;
int error = 0;
int ipflags;
u_short fport, lport;
#ifdef MAC
@ -821,6 +822,10 @@ udp_output(inp, m, addr, control, td)
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 @@ udp_output(inp, m, addr, control, td)
((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);