Fix the socket option IP_ONESBCAST by giving it its own case in ip_output()
and skip over the normal IP processing. Add a supporting function ifa_ifwithbroadaddr() to verify and validate the supplied subnet broadcast address. PR: kern/99558 Tested by: Andrey V. Elsukov <bu7cher-at-yandex.ru> Sponsored by: TCP/IP Optimization Fundraise 2005 MFC after: 3 days
This commit is contained in:
parent
e5bec77751
commit
773725a255
27
sys/net/if.c
27
sys/net/if.c
@ -1005,6 +1005,33 @@ ifa_ifwithaddr(struct sockaddr *addr)
|
||||
return (ifa);
|
||||
}
|
||||
|
||||
/*
|
||||
* Locate an interface based on the broadcast address.
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
struct ifaddr *
|
||||
ifa_ifwithbroadaddr(struct sockaddr *addr)
|
||||
{
|
||||
struct ifnet *ifp;
|
||||
struct ifaddr *ifa;
|
||||
|
||||
IFNET_RLOCK();
|
||||
TAILQ_FOREACH(ifp, &ifnet, if_link)
|
||||
TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
|
||||
if (ifa->ifa_addr->sa_family != addr->sa_family)
|
||||
continue;
|
||||
if ((ifp->if_flags & IFF_BROADCAST) &&
|
||||
ifa->ifa_broadaddr &&
|
||||
ifa->ifa_broadaddr->sa_len != 0 &&
|
||||
sa_equal(ifa->ifa_broadaddr, addr))
|
||||
goto done;
|
||||
}
|
||||
ifa = NULL;
|
||||
done:
|
||||
IFNET_RUNLOCK();
|
||||
return (ifa);
|
||||
}
|
||||
|
||||
/*
|
||||
* Locate the point to point interface with a given destination address.
|
||||
*/
|
||||
|
@ -683,6 +683,7 @@ int ifpromisc(struct ifnet *, int);
|
||||
struct ifnet *ifunit(const char *);
|
||||
|
||||
struct ifaddr *ifa_ifwithaddr(struct sockaddr *);
|
||||
struct ifaddr *ifa_ifwithbroadaddr(struct sockaddr *);
|
||||
struct ifaddr *ifa_ifwithdstaddr(struct sockaddr *);
|
||||
struct ifaddr *ifa_ifwithnet(struct sockaddr *);
|
||||
struct ifaddr *ifa_ifwithroute(int, struct sockaddr *, struct sockaddr *);
|
||||
|
@ -198,6 +198,17 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro,
|
||||
ifp = ia->ia_ifp;
|
||||
ip->ip_ttl = 1;
|
||||
isbroadcast = in_broadcast(dst->sin_addr, ifp);
|
||||
} else if (flags & IP_SENDONES) {
|
||||
if ((ia = ifatoia(ifa_ifwithbroadaddr(sintosa(dst)))) == NULL) {
|
||||
ipstat.ips_noroute++;
|
||||
error = ENETUNREACH;
|
||||
goto bad;
|
||||
}
|
||||
ifp = ia->ia_ifp;
|
||||
ip->ip_dst.s_addr = INADDR_BROADCAST;
|
||||
dst->sin_addr = ip->ip_dst;
|
||||
ip->ip_ttl = 1;
|
||||
isbroadcast = 1;
|
||||
} else if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) &&
|
||||
imo != NULL && imo->imo_multicast_ifp != NULL) {
|
||||
/*
|
||||
@ -381,8 +392,6 @@ ip_output(struct mbuf *m, 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;
|
||||
|
Loading…
Reference in New Issue
Block a user