From owner-freebsd-net@FreeBSD.ORG Thu Feb 26 08:27:46 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 37E4816A4D1 for ; Thu, 26 Feb 2004 08:27:45 -0800 (PST) Received: from mercury.dgim.crc.ca (unknown [142.92.39.129]) by mx1.FreeBSD.org (Postfix) with ESMTP id 8169143D1D for ; Thu, 26 Feb 2004 08:27:44 -0800 (PST) (envelope-from don@mainframe.dgrc.crc.ca) Received: from janus.dgrc.crc.ca (janus.dgrc.crc.ca [142.92.34.101]) i1QGRh5N000933 for ; Thu, 26 Feb 2004 11:27:43 -0500 Received: (from don@localhost) by janus.dgrc.crc.ca (8.11.6+Sun/8.11.6) id i1QGRVT02174 for freebsd-net@freebsd.org; Thu, 26 Feb 2004 11:27:31 -0500 (EST) Date: Thu, 26 Feb 2004 11:27:31 -0500 (EST) From: Donald McLachlan Message-Id: <200402261627.i1QGRVT02174@janus.dgrc.crc.ca> To: freebsd-net@freebsd.org Subject: 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 16:27:47 -0000 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; } }