Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 29 Dec 1995 12:49:46 +0100 (MET)
From:      guido@IAEhv.nl (Guido van Rooij)
To:        freebsd-hackers@freebsd.org
Subject:   bug in UDP stack with our aliasing scheme :-(
Message-ID:  <199512291149.MAA13378@iaehv.IAEhv.nl>

next in thread | raw e-mail | index | archive | help
I discovered a problem with our ip aliasing implementation:

Suppose you have an interface, ed0, with ip 192.1.1.1 netmask 0xffffff00.
Further there is an alias 192.1.1.2, with netmask 0xffffffff.

Run the program attached below with argument 192.1.1.1. Send an UDP
packet to 192.1.1.1. The program will only receive the data on fd1.
When the program is run with argument 192.1.1.2 it receives input
both on fd1 and fd2.

When the alias is set to an ip on another subnet, say 192.1.2.1 with
netmask 0xffffffff, this bug can be seen again. But when the netmask is
changed to 0xffffff00, the UDP data will be deliverd correctly to only
fd1.

This definately is a bug. 

-Guido

#include <sys/param.h>
#include <sys/file.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>

int
main(int argc, char **argv) {
	fd_set	mask;
	int on = 1;
	struct sockaddr_in	sin;
	int	s1,s2;
	long 	temp;

	bzero((char *)&sin, sizeof(sin));
	sin.sin_family = AF_INET;
	temp = inet_addr(argv[1]);;
	if(temp==-1) {
		fprintf(stderr, "temp==-1\n");
	}
	sin.sin_addr.s_addr = inet_addr(argv[1]);;
	sin.sin_port = htons(7787);
	if ((s1 = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
		perror("socket");
		exit(1);
	}	
	if (setsockopt(s1, SOL_SOCKET, SO_REUSEADDR,
	    (char *)&on, sizeof(on)) != 0)
	{
		perror("setsockopt");
	}
	if (bind(s1, (struct sockaddr *)&sin, sizeof(sin))) {
		perror("bind");
	}
	if ((s2 = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
		perror("socket");
		exit(1);
	}	
	if (setsockopt(s2, SOL_SOCKET, SO_REUSEADDR,
	    (char *)&on, sizeof(on)) != 0)
	{
		perror("setsockopt");
	}
	sin.sin_addr.s_addr = INADDR_ANY;
	if (bind(s2, (struct sockaddr *)&sin, sizeof(sin))) {
		perror("bind");
		exit(1);
	}
	FD_ZERO(&mask);
	FD_SET(s1, &mask);
	FD_SET(s2, &mask);
	select(FD_SETSIZE, &mask, (fd_set *)NULL, (fd_set *)NULL, NULL);
	if(FD_ISSET(s1, &mask))
		printf("s1 had input\n");
	if(FD_ISSET(s2, &mask) )
		printf("s2 had input\n");
}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199512291149.MAA13378>