2.4.0 and sendmsg problem.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

I've found a problem with 2.4.0-test kernel and sendmsg(2).
I have a computer with two network interfaces: eth0 - 10.0.1.1/24 
                                               eth1 - 10.0.2.1/24

I wrote a small program (attached) that gets two parameters 
interface name ('if') and destination address ('dst'). The program sends
packets to address 'dst' via interface 'if'.

If I run the program in kernel 2.2.x as follows:
# ./sendmsg_test eth1 10.0.1.2
I can see in tcpdump that linux tries to send packets via interface
eth1. It actually sends arp requests for address 10.0.1.2 and never gets
the answer since this host is only reachable via another interface, but
if I add arp entry from command line (arp -i eth1 -s 10.0.1.2 mac_addr)
I see that packets are sent via interface eth1.

If I run the same command in kernel 2.4.0-testX I see that linux sends
packets via eth0 and not eth1 as one would expect.

So two kernels behave in a different way one of them must be wrong.
Which one? 
--
			Gleb.
#include <errno.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <sys/types.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <strings.h>
#include <stdio.h>

struct in_pktinfo
{
    int ipi_ifindex;                    /* Interface index  */
    struct in_addr ipi_spec_dst;        /* Routing destination address  */
    struct in_addr ipi_addr;            /* Header destination address  */
};

int main(int argc, char **argv)
{
	int fd;
	struct sockaddr_in sa;
	static struct msghdr m;
	struct ifreq ifr;
	char buffer[10]={'6',};
	struct iovec iov = {buffer, 0};
	struct {
        	struct cmsghdr cm;
        	struct in_pktinfo ipi;
	} cmsg = { {sizeof(struct cmsghdr) + sizeof(struct in_pktinfo), 
			SOL_IP, IP_PKTINFO}, {0, }};

	if (argc < 3)
		exit(1);

	fd = socket (PF_INET, SOCK_RAW, IPPROTO_UDP);

	if (fd < 0) {
		perror ("socket:");
		exit(1);
	}

	memset(&ifr, 0, sizeof(ifr));
	strncpy(ifr.ifr_name, argv[1], 15);
	if(ioctl(fd, SIOCGIFINDEX, &ifr) < 0) {
		fprintf(stderr, "unknown iface %s\n", argv[1]);
		exit(1);
	}               
	cmsg.ipi.ipi_ifindex = ifr.ifr_ifindex;
	
	sa.sin_family = AF_INET;
	sa.sin_port = htons(0);
	sa.sin_addr.s_addr = inet_addr(argv[2]);

	iov.iov_len = 10;

	m.msg_name = &sa;
	m.msg_namelen = sizeof(sa);
	m.msg_iov = &iov;
	m.msg_iovlen = 1;
	m.msg_control = &cmsg;
	m.msg_controllen = sizeof(cmsg);
	m.msg_flags = 0;
 
	while (1){
		sleep(1);
		sendmsg(fd, &m, 0);
	}
}

[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux 802.1Q VLAN]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Git]     [Bugtraq]     [Yosemite News and Information]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux PCI]     [Linux Admin]     [Samba]

  Powered by Linux