Diff below make the function always iterate on all the interfaces.
After that I'd like to change ifa_ifwithaddr() to only match unicast
addresses and use in_broadcast() in the few places where we also accept
broadcast addresses.
This would prevent people from matching a broadcast address when they
don't want to.
Ok?
Index: netinet/in.c
===================================================================
RCS file: /cvs/src/sys/netinet/in.c,v
retrieving revision 1.109
diff -u -p -r1.109 in.c
--- netinet/in.c 20 Nov 2014 10:06:54 -0000 1.109
+++ netinet/in.c 20 Nov 2014 14:15:30 -0000
@@ -876,36 +876,19 @@ in_scrubprefix(struct in_ifaddr *ia0)
}
/*
- * Return 1 if the address might be a local broadcast address.
+ * Return 1 if the address is a local broadcast address.
*/
int
-in_broadcast(struct in_addr in, struct ifnet *ifp, u_int rtableid)
+in_broadcast(struct in_addr in, u_int rtableid)
{
- struct ifnet *ifn, *if_first, *if_target;
+ struct ifnet *ifn;
struct ifaddr *ifa;
u_int rdomain;
rdomain = rtable_l2(rtableid);
- if (in.s_addr == INADDR_BROADCAST ||
- in.s_addr == INADDR_ANY)
- return 1;
-
- if (ifp == NULL) {
- if_first = TAILQ_FIRST(&ifnet);
- if_target = 0;
- } else {
- if_first = ifp;
- if_target = TAILQ_NEXT(ifp, if_list);
- }
-
#define ia (ifatoia(ifa))
- /*
- * Look through the list of addresses for a match
- * with a broadcast address.
- * If ifp is NULL, check against all the interfaces.
- */
- for (ifn = if_first; ifn != if_target; ifn = TAILQ_NEXT(ifn, if_list))
{
+ TAILQ_FOREACH(ifn, &ifnet, if_list) {
if (ifn->if_rdomain != rdomain)
continue;
if ((ifn->if_flags & IFF_BROADCAST) == 0)
Index: netinet/in.h
===================================================================
RCS file: /cvs/src/sys/netinet/in.h,v
retrieving revision 1.109
diff -u -p -r1.109 in.h
--- netinet/in.h 12 Jul 2014 16:25:08 -0000 1.109
+++ netinet/in.h 20 Nov 2014 14:15:30 -0000
@@ -782,7 +782,7 @@ extern int inetctlerrmap[];
extern struct ifqueue ipintrq; /* ip packet input queue */
extern struct in_addr zeroin_addr;
-int in_broadcast(struct in_addr, struct ifnet *, u_int);
+int in_broadcast(struct in_addr, u_int);
int in_canforward(struct in_addr);
int in_cksum(struct mbuf *, int);
int in4_cksum(struct mbuf *, u_int8_t, int, int);
Index: netinet/tcp_usrreq.c
===================================================================
RCS file: /cvs/src/sys/netinet/tcp_usrreq.c,v
retrieving revision 1.121
diff -u -p -r1.121 tcp_usrreq.c
--- netinet/tcp_usrreq.c 18 Nov 2014 02:37:31 -0000 1.121
+++ netinet/tcp_usrreq.c 20 Nov 2014 14:15:31 -0000
@@ -275,9 +275,9 @@ tcp_usrreq(so, req, m, nam, control, p)
#endif /* INET6 */
{
if ((sin->sin_addr.s_addr == INADDR_ANY) ||
+ (sin->sin_addr.s_addr == INADDR_BROADCAST) ||
IN_MULTICAST(sin->sin_addr.s_addr) ||
- in_broadcast(sin->sin_addr, NULL,
- inp->inp_rtableid)) {
+ in_broadcast(sin->sin_addr, inp->inp_rtableid)) {
error = EINVAL;
break;
}