From owner-freebsd-bugs@FreeBSD.ORG Fri Jun 30 10:22:28 2006 Return-Path: X-Original-To: freebsd-bugs@FreeBSD.org Delivered-To: freebsd-bugs@FreeBSD.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 9B59A16A40F for ; Fri, 30 Jun 2006 10:22:28 +0000 (UTC) (envelope-from andre@freebsd.org) Received: from c00l3r.networx.ch (c00l3r.networx.ch [62.48.2.2]) by mx1.FreeBSD.org (Postfix) with ESMTP id 23A43445F3 for ; Fri, 30 Jun 2006 10:22:26 +0000 (GMT) (envelope-from andre@freebsd.org) Received: (qmail 95954 invoked from network); 30 Jun 2006 10:20:09 -0000 Received: from c00l3r.networx.ch (HELO [127.0.0.1]) ([62.48.2.2]) (envelope-sender ) by c00l3r.networx.ch (qmail-ldap-1.03) with SMTP for ; 30 Jun 2006 10:20:09 -0000 Message-ID: <44A4FB69.1070609@freebsd.org> Date: Fri, 30 Jun 2006 12:22:33 +0200 From: Andre Oppermann User-Agent: Thunderbird 1.5.0.4 (Windows/20060516) MIME-Version: 1.0 To: "Andrey V. Elsukov" References: <200606282026.k5SKQF76000393@freefall.freebsd.org> <44A36B44.1030100@yandex.ru> In-Reply-To: <44A36B44.1030100@yandex.ru> Content-Type: text/plain; charset=KOI8-R; format=flowed Content-Transfer-Encoding: 7bit Cc: Robert Watson , freebsd-bugs@FreeBSD.org, Gleb Smirnoff , Bruce M Simpson , citrin@citrin.ru Subject: Re: kern/99558: FreeBSD 6.1 can't send packets to INADDR_BROADCAST X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 30 Jun 2006 10:22:28 -0000 Andrey V. Elsukov wrote: > Bruce M Simpson wrote: >> Please read the manual page ip(4) for information on the IP_ONESBCAST >> option. The INADDR_BROADCAST destination is by its nature non specific >> and link local therefore you need to use the IP_ONESBCAST option to >> cause undirected broadcasts to be sent on a particular interface. >> >> http://www.freebsd.org/cgi/query-pr.cgi?pr=99558 > > Ok. I've tested 5.4-STABLE. > Without IP_ONESBCAST: > 09:24:50.293393 IP 10.0.0.4.5000 > 10.0.7.255.5000: UDP, length: 4 > 0x0000: ffff ffff ffff 0007 e909 d5b3 0800 4500 ..............E. > 0x0010: 0020 24d7 0000 4011 39f4 0a00 0004 0a00 ..$...@.9....... > 0x0020: 07ff 1388 1388 000c 1c20 7465 7374 ..........test > > With IP_ONESBCAST: > 09:28:08.275418 IP 10.0.0.4.54715 > 255.255.255.255.5000: UDP,length:4 > 0x0000: ffff ffff ffff 0007 e909 d5b3 0800 4500 ..............E. > 0x0010: 0020 8987 0000 4011 e742 0a00 0004 ffff ......@..B...... > 0x0020: ffff d5bb 1388 000c 0a21 7465 7374 .........!test > > In result we have difference only in IP destination address. > I want to pay attention that a Ethernet destination address is a > ethernet broadcast! > > Now for 6.1-STABLE. Without IP_ONESBCAST: > 10:43:15.384080 IP 172.21.81.19.58298 > 255.255.255.255.5000: UDP, length 4 > 0x0000: 0011 936b 3c91 0080 4819 86df 0800 4500 ...k<...H.....E. > 0x0010: 0020 a670 0000 4011 d734 ac15 5113 ffff ...p..@..4..Q... > 0x0020: ffff e3ba 1388 000c 2391 7465 7374 0000 ........#.test.. > 0x0030: 0000 0000 0000 0000 0000 0000 ............ > > With IP_ONESBCAST: > 10:44:20.320314 IP 172.21.81.19.53276 > 255.255.255.255.5000: UDP, length 4 > 0x0000: 0011 936b 3c91 0080 4819 86df 0800 4500 ...k<...H.....E. > 0x0010: 0020 a998 0000 4011 d40c ac15 5113 ffff ......@.....Q... > 0x0020: ffff d01c 1388 000c 372f 7465 7374 0000 ........7/test.. > 0x0030: 0000 0000 0000 0000 0000 0000 ............ > > In result we have an identical datagrams with *incorrect* ethernet > destination addresses. When my system don't have default route, he > can not send broadcast. I've got error message "sendto(): Network is > unreachable"! The attached patch should fix the problem with SENDONES (untested). -- Andre Index: net/if.c =================================================================== RCS file: /home/ncvs/src/sys/net/if.c,v retrieving revision 1.259 diff -u -p -r1.259 if.c --- net/if.c 21 Jun 2006 06:02:35 -0000 1.259 +++ net/if.c 30 Jun 2006 10:20:19 -0000 @@ -1007,6 +1007,33 @@ done: } /* + * 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. */ /*ARGSUSED*/ Index: net/if_var.h =================================================================== RCS file: /home/ncvs/src/sys/net/if_var.h,v retrieving revision 1.107 diff -u -p -r1.107 if_var.h --- net/if_var.h 19 Jun 2006 22:20:44 -0000 1.107 +++ net/if_var.h 30 Jun 2006 10:20:19 -0000 @@ -682,6 +682,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 *); Index: netinet/ip_output.c =================================================================== RCS file: /home/ncvs/src/sys/netinet/ip_output.c,v retrieving revision 1.257 diff -u -p -r1.257 ip_output.c --- netinet/ip_output.c 21 May 2006 17:52:08 -0000 1.257 +++ netinet/ip_output.c 30 Jun 2006 10:20:20 -0000 @@ -198,6 +198,15 @@ again: 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; + isbroadcast = 1; } else if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) && imo != NULL && imo->imo_multicast_ifp != NULL) { /* @@ -381,8 +390,6 @@ again: 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;