bug in IP broadcast packet recognition
bill at cu-arpa
bill at cu-arpa
Tue Dec 18 04:25:33 AEST 1984
From: bill at cu-arpa (William A. Nesheim)
Subject: IP sometimes doesn't recognize broadcast packets
Index: sys/netinet/ip_input.c 4.2BSD
Description:
ip_input does not recognize broadcast IP datagrams for addresses
other than the first interface on a machine. This breaks rwho,
and any other programs which depend on UDP broadcasts.
Repeat-By:
get a machine with 2 or more ethernet (or other broadcast) net
interfaces, and run rwhod on it. You will only see information
from the 1st ethernet on the system, NOT from the second.
Fix:
In ip_input(), a "quick test" for an address match of the
incoming packet and the first interface is done, testing
for both the full address, and the broadcast address, if the
interface is marked as a broadcast interface. This works
for packets with the address of the FIRST interface as their
destination, but if the dest. is the broadcast address of
any other interface, the test in if_ifwithaddr() fails, and
the packet is handed to ip_forward(), which drops it.
I replaced the test of the "first" interface with a quick
trip through ALL the interfaces, and eliminated the call to
if_ifwithaddr(), as its return value was never used anyway.
A diff of sys/netinet/ip_input.c follows.
The line numbers are undoubtedly not what you expect.
RCS file: RCS/ip_input.c,v
retrieving revision 1.4
diff -c -r1.4 ip_input.c
*** /tmp/,RCSt1000175 Mon Dec 17 13:18:09 1984
--- ip_input.c Mon Dec 17 13:11:49 1984
***************
*** 1,4
! /* $Header: ip_input.c,v 1.4 84/10/12 12:08:33 bill Exp $ */
/* ip_input.c 6.3 84/05/25 */
#include "../h/param.h"
--- 1,4 -----
! /* $Header: ip_input.c,v 1.5 84/12/17 13:10:41 bill Exp $ */
/* ip_input.c 6.3 84/05/25 */
#include "../h/param.h"
***************
*** 146,153
goto next;
/*
! * Fast check on the first internet
! * interface in the list.
*/
if (ifinet) {
struct sockaddr_in *sin;
--- 146,152 -----
goto next;
/*
! * check for our address
*/
{
register struct sockaddr_in *sin;
***************
*** 149,156
* Fast check on the first internet
* interface in the list.
*/
! if (ifinet) {
! struct sockaddr_in *sin;
sin = (struct sockaddr_in *)&ifinet->if_addr;
if (sin->sin_addr.s_addr == ip->ip_dst.s_addr)
--- 148,156 -----
/*
* check for our address
*/
! {
! register struct sockaddr_in *sin;
! register struct ifnet *ifp;
for(ifp = ifnet; ifp; ifp = ifp->if_next) {
if (ifp->if_addr.sa_family != AF_INET)
***************
*** 152,158
if (ifinet) {
struct sockaddr_in *sin;
! sin = (struct sockaddr_in *)&ifinet->if_addr;
if (sin->sin_addr.s_addr == ip->ip_dst.s_addr)
goto ours;
sin = (struct sockaddr_in *)&ifinet->if_broadaddr;
--- 152,161 -----
register struct sockaddr_in *sin;
register struct ifnet *ifp;
! for(ifp = ifnet; ifp; ifp = ifp->if_next) {
! if (ifp->if_addr.sa_family != AF_INET)
! continue;
! sin = (struct sockaddr_in *)&ifp->if_addr;
if (sin->sin_addr.s_addr == ip->ip_dst.s_addr)
goto ours;
sin = (struct sockaddr_in *)&ifp->if_broadaddr;
***************
*** 155,162
sin = (struct sockaddr_in *)&ifinet->if_addr;
if (sin->sin_addr.s_addr == ip->ip_dst.s_addr)
goto ours;
! sin = (struct sockaddr_in *)&ifinet->if_broadaddr;
! if ((ifinet->if_flags & IFF_BROADCAST) &&
sin->sin_addr.s_addr == ip->ip_dst.s_addr)
goto ours;
}
--- 158,165 -----
sin = (struct sockaddr_in *)&ifp->if_addr;
if (sin->sin_addr.s_addr == ip->ip_dst.s_addr)
goto ours;
! sin = (struct sockaddr_in *)&ifp->if_broadaddr;
! if ((ifp->if_flags & IFF_BROADCAST) &&
sin->sin_addr.s_addr == ip->ip_dst.s_addr)
goto ours;
}
***************
*** 160,165
sin->sin_addr.s_addr == ip->ip_dst.s_addr)
goto ours;
}
/* BEGIN GROT */
#include "nd.h"
#if NND > 0
--- 163,170 -----
sin->sin_addr.s_addr == ip->ip_dst.s_addr)
goto ours;
}
+ /* not for us at this point */
+ }
/* BEGIN GROT */
#include "nd.h"
#if NND > 0
***************
*** 174,184
goto ours;
#endif
/* END GROT */
! ipaddr.sin_addr = ip->ip_dst;
! if (if_ifwithaddr((struct sockaddr *)&ipaddr) == 0) {
! ip_forward(ip);
! goto next;
! }
ours:
/*
--- 179,187 -----
goto ours;
#endif
/* END GROT */
!
! ip_forward(ip);
! goto next;
ours:
/*
More information about the Comp.unix.wizards
mailing list