From owner-freebsd-net@FreeBSD.ORG Thu Feb 26 10:33:18 2004 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 4D4A316A4CE for ; Thu, 26 Feb 2004 10:33:18 -0800 (PST) Received: from mercury.dgim.crc.ca (mercury.dgim.crc.ca [142.92.39.129]) by mx1.FreeBSD.org (Postfix) with ESMTP id 7D82043D2D for ; Thu, 26 Feb 2004 10:33:17 -0800 (PST) (envelope-from don@mainframe.dgrc.crc.ca) Received: from janus.dgrc.crc.ca (janus.dgrc.crc.ca [142.92.34.101]) i1QIXG5N024484 for ; Thu, 26 Feb 2004 13:33:16 -0500 Received: (from don@localhost) by janus.dgrc.crc.ca (8.11.6+Sun/8.11.6) id i1QIX3w02239 for freebsd-net@freebsd.org; Thu, 26 Feb 2004 13:33:03 -0500 (EST) Date: Thu, 26 Feb 2004 13:33:03 -0500 (EST) Message-Id: <200402261833.i1QIX3w02239@janus.dgrc.crc.ca> To: freebsd-net@freebsd.org From: Donald.McLachlan@crc.ca X-Sun-Charset: US-ASCII Subject: followup: IPv6 multicast sendto() 'operation not supported' X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 26 Feb 2004 18:33:18 -0000 Hello again, I think I have found a work around, but it does not explain why my test code works on linux (RedHat) and on Solaris, but not on FreeBSD. I found another test program which is *very* similar to mine. The differences being: - instead of fork()'ing the other program binds to in6addr_any instead of to the multcast group address. - the other program does not fork(). Instead it uses select() to multiplex I/O on the socket. - oh ya, and the other program works. ;) I'm guessing it is fork() that cause the problem. Why? Thanks, Don ----- Begin Included Message ----- >From owner-freebsd-net@freebsd.org Thu Feb 26 11:28:55 2004 From: Donald McLachlan Hello, [ I'm new to freebsd. This seems like the most related mailing list. If there is a better mailing list I should post to, please point me in the right direction. ] In preparation for writing an IPv6 multicast application I wrote a little test program (shown below). This program worked on linux (RedHat), but when I try it on a FreeBSD box (5.0, running zebra router and pim6dd) sendto() fails with "Operation not supported" ... ??? To verify my app was OK, I installed a solaris box on the LAN beside the linux box and the app compiled and worked fine. Thinking it might be a bug in 5.0 or an interaction with zebra/pim6dd I installed a FreeBSD 5.2 box on the lan beside the other 2 app boxes and I get the same error again. Anyone know what is missing/wrong in my test app? [ I'm guessing FreeBSD wants some extra socket options set, but I don't know which ones. ] Thanks, Don /* mcast6.c */ #include #include #include #include #include #include #include #include #include #include #include #include #include extern int errno; void start_sender(int sock, struct sockaddr_in6 *sin); void start_listener(int sock); int main(int argc, char *argv[]) { int sock, hops; unsigned int ifindex; struct sockaddr_in6 sin; struct ipv6_mreq mreq; char ifname[IF_NAMESIZE]; static unsigned char the_addr[16]; inet_pton(AF_INET6, "ff05::abcd", the_addr); if ((sock=socket(AF_INET6, SOCK_DGRAM, 0)) < 0) /* connect to socket */ { perror("socket"); exit(3); } bzero((char *)&sin, (int)sizeof(sin)); /* setup address info */ bcopy(the_addr, (char *)&sin.sin6_addr, sizeof(the_addr)); sin.sin6_family = AF_INET6; sin.sin6_port = htons(3000); /* bind addr to sock */ if(bind(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0) { perror("bind"); exit(errno); } hops = 255; if(setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &hops, sizeof(hops)) < 0) { perror("setsockopt(IPV6_MULTICAST_HOPS)"); exit(errno); } ifindex = 0; #ifdef ORIG strcpy(ifname, "xl1"); ifindex = if_nametoindex(ifname); if(ifindex == 0) { perror("if_nametoindex()"); exit(errno); } if(setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_IF, &ifindex, sizeof(ifindex)) < 0) { perror("setsockopt(IPV6_MULTICAST_IF)"); exit(errno); } #endif /* setup group info */ bcopy(the_addr, (char *)&mreq.ipv6mr_multiaddr, sizeof(the_addr)); mreq.ipv6mr_interface = ifindex; /* and I/F index */ /* join group */ if(setsockopt(sock, IPPROTO_IPV6, IPV6_JOIN_GROUP, (char *)&mreq, sizeof(mreq)) < 0) { perror("setsockopt(IPV6_JOIN_GROUP)"); exit(21); } start_sender(sock, &sin); start_listener(sock); while(wait((int *)0) != -1); /* wait for all children to die */ return(0); } void start_sender(int sock, struct sockaddr_in6 *sin) { char bitbucket[2000]; pid_t pid; pid = fork(); switch(pid) { case 0: /* child */ while(1) { /* TX mcast PDU */ strcpy(bitbucket, "How now brown cow?"); if(sendto(sock, bitbucket, strlen(bitbucket)+1, 0, (struct sockaddr *)sin, sizeof(*sin)) < 0) { perror("sendto(sender)"); exit(23); } sleep(10); } break; case -1: /* parent fork failed */ printf("fork(sender): failed\n"); fflush(stdout); break; default: /* parent fork passed */ printf("sender PID = %d\n", (int)pid); fflush(stdout); break; } } void start_listener(int sock) { pid_t pid; unsigned int fromlen; struct sockaddr_in6 from; char bitbucket[2000], addrstr[INET6_ADDRSTRLEN]; pid = fork(); switch(pid) { case 0: /* child */ while(1) { bitbucket[0] = '\0'; fromlen = sizeof(from); if(recvfrom(sock, bitbucket, sizeof(bitbucket), 0, (struct sockaddr *)&from, &fromlen) < 0) { perror("listener: recvfrom()"); exit(21); } inet_ntop(AF_INET6, &from.sin6_addr, addrstr, sizeof(addrstr)); printf("< %s : \"%s\"\n", addrstr, bitbucket); fflush(stdout); } break; case -1: /* parent fork failed */ printf("fork(listerner): failed\n"); fflush(stdout); break; default: /* parent fork passed */ printf("listener PID = %d\n", (int)pid); fflush(stdout); break; } } _______________________________________________ freebsd-net@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-net To unsubscribe, send any mail to "freebsd-net-unsubscribe@freebsd.org" ----- End Included Message -----