Date: Fri, 5 Jan 2007 19:20:22 +0300 From: Eygene Ryabinkin <rea-fbsd@codelabs.ru> To: LI Xin <delphij@delphij.net> Cc: freebsd-net@freebsd.org Subject: Re: Different behavior of ping'ing INADDR_BROADCAST? Message-ID: <20070105162022.GA1503@twilight.mbslab.kiae.ru> In-Reply-To: <20070105113442.GH37482@codelabs.ru> References: <459D4D88.2030708@delphij.net> <20070105113442.GH37482@codelabs.ru>
next in thread | previous in thread | raw e-mail | index | archive | help
--y0ulUmNC+osPPQO6 Content-Type: text/plain; charset=koi8-r Content-Disposition: inline I am CC'ing this message to Gleb Smirnov. Gleb, my apologies if you're not interested in this stuff. > When FBSD is pinging 0xffffffff it does not use the Ethernet broadcasts, > when the link-level destination MAC is set to 0xffffffffffff, using some > 'known MAC' instead. For the network broadcast address -- it does use > link-level broadcasts. > > For me the 'known MAC' is that of our border router that serves as > the default destination. And my box doing the ARP request for the > precisely the IP of the router before pinging 255.255.255.255. You can > try to empty your ARP table and then ping 255.255.255.255 watching > for the ARP requests and the link-level header of the ICMP packets. OK, I've found that in order to ping undirected broadcast address one should add some functionality to the 'ping' utility. The explanation of the behaviour you notes is the following: when ping is requesting 255.255.255.255 as the destination the IP layer does the lookup the route for the 255.255.255.255. In my case the route lookup yielded 'default destination'. And the code in the /sys/netinet/ip_output.c do no checks for the broadcast address if the looked up destination is the gateway (lines 257-258 in the revision 1.242.2.17). So the packet was not recognised as the broadcast and was sent with the destination MAC of the gateway. Our gateway responds to such packets. Your probably responds too. > > Just curious why there is such difference. Literally, I think > > INADDR_BROADCAST is supposed to reach local network nodes, no? Yes, the appendix II of the STD0005 (RFC 791) specifies that it is the case: the packet should go to all hosts 'on the wire'. I've prepared the patch for the ping (RELENG-6, 6.2-PRERELEASE) that adds '-b' option that permits to ping to 255.255.255.255. An argument to '-b' specifies the broadcast address of the interface that will be used for the transmission. If you're interested, please, test the patch. I see one caveat now: no Linux stations respond to my pings with '-b' option. I will try to see why, but later. One use-case for the '-b' is the following: suppose you're on the unknown network in which you know some IPs, but the netmask is not known or you see the errorneous netmask. Then setting the netmask to some value and pinging to the resulting network broadcast will not reveal hosts in the local network. But using '-b' with the resulting network broadcast address and the 255.255.255.255 as the destination will do the work. -- Eygene --y0ulUmNC+osPPQO6 Content-Type: text/plain; charset=koi8-r Content-Disposition: attachment; filename="broadcast.patch" --- /usr/src/sbin/ping/ping.c.orig Fri Jan 5 17:11:24 2007 +++ /usr/src/sbin/ping/ping.c Fri Jan 5 18:48:54 2007 @@ -144,6 +144,7 @@ #define F_TIME 0x100000 #define F_SWEEP 0x200000 #define F_WAITTIME 0x400000 +#define F_BIF 0x800000 /* * MAX_DUP_CHK is the number of bits in received table, i.e. the maximum @@ -219,7 +220,7 @@ char *const *argv; { struct sockaddr_in from, sock_in; - struct in_addr ifaddr; + struct in_addr ifaddr, bifaddr; struct timeval last, intvl; struct iovec iov; struct ip *ip; @@ -264,7 +265,7 @@ outpack = outpackhdr + sizeof(struct ip); while ((ch = getopt(argc, argv, - "Aac:DdfG:g:h:I:i:Ll:M:m:nop:QqRrS:s:T:t:vW:z:" + "Aab:c:DdfG:g:h:I:i:Ll:M:m:nop:QqRrS:s:T:t:vW:z:" #ifdef IPSEC #ifdef IPSEC_POLICY_IPSEC "P:" @@ -279,6 +280,13 @@ case 'a': options |= F_AUDIBLE; break; + case 'b': + if (inet_aton(optarg, &bifaddr) == 0) + errx(EX_USAGE, + "invalid broadcast interface: `%s'", + optarg); + options |= F_BIF; + break; case 'c': ultmp = strtoul(optarg, &ep, 0); if (*ep || ep == optarg || ultmp > LONG_MAX || !ultmp) @@ -584,6 +592,8 @@ && !IN_MULTICAST(ntohl(to->sin_addr.s_addr))) errx(EX_USAGE, "-I, -L, -T flags cannot be used with unicast destination"); + if ((options & F_MIF) && (options & F_BIF)) + errx(EX_USAGE, "-b and -I: incompatible options"); if (datalen >= TIMEVAL_LEN) /* can we time transfer */ timing = 1; @@ -605,6 +615,21 @@ if (options & F_SO_DONTROUTE) (void)setsockopt(s, SOL_SOCKET, SO_DONTROUTE, (char *)&hold, sizeof(hold)); + if (to->sin_addr.s_addr == INADDR_BROADCAST) { + if ((options & F_BIF) == 0) { + errx(EX_USAGE, + "Broadcast ping requested, but '-b' option was not given"); + } + /* Should instruct IP stack to use broadcast destination. */ + if (setsockopt(s, IPPROTO_IP, IP_ONESBCAST, (char *)&hold, + sizeof(hold)) < 0) { + errx(EX_OSERR, + "setsockopt(IPPROTO_IP, IP_ONESBCAST) failed"); + } + bcopy(&bifaddr, &(whereto.sin_addr), sizeof(whereto.sin_addr)); + printf("WARNING: will ping to broadcast address using %s.\n", + inet_ntoa(bifaddr)); + } #ifdef IPSEC #ifdef IPSEC_POLICY_IPSEC if (options & F_POLICY) { --- /usr/src/sbin/ping/ping.8.orig Fri Jan 5 18:48:10 2007 +++ /usr/src/sbin/ping/ping.8 Fri Jan 5 18:55:50 2007 @@ -39,6 +39,7 @@ .Sh SYNOPSIS .Nm .Op Fl AaDdfnoQqRrv +.Op Fl b Ar bcastaddr .Op Fl c Ar count .Op Fl G Ar sweepmaxsize .Op Fl g Ar sweepminsize @@ -112,6 +113,12 @@ character in the output when any packet is received. This option is ignored if other format options are present. +.It Fl b Ar bcastaddr +Ping to the broadcast address (255.255.255.255). Argument +.Ar bcastaddr +specifies the broadcast address of the interface that will be +used for transmission. This option is mutually exclusive with +.Fl I . .It Fl c Ar count Stop after sending (and receiving) @@ -165,6 +172,8 @@ .It Fl I Ar iface Source multicast packets with the given interface address. This flag only applies if the ping destination is a multicast address. +This option is mutually exclusive with +.Fl b . .It Fl i Ar wait Wait .Ar wait --y0ulUmNC+osPPQO6--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20070105162022.GA1503>