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:
parent
2d81cd746b
commit
8afa230470
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user