IPv6 multicast packet size
Hideki Yamamoto
hyama99 at gmail.com
Sat Feb 27 06:31:54 UTC 2010
Hi,
I have found the answer to my question.
The following lines resolved my problem.
sock_optval=0;
error = setsockopt(send_s, IPPROTO_IPV6, IPV6_USE_MIN_MTU,
&sock_optval, sizeof(sock_optval));
2010/2/22 Hideki Yamamoto <hyama99 at gmail.com>:
> Hi,
>
> I have encountered IPv6 multicast problem.
> I cannot send UDP packet longer than Shortest MTU.
> It seems the bug of IPv6 multicast kernel.
> I used the same application from FreeBSD 4.11. On that old version,
> any problems happens. When I would like to change the platform of
> this application from 4.11 to 7.2 or later, I encountered this
> problem.
> Does anyone have any information about this problem?
>
> The followings are OS information I have tested, the result of
> Tshark command, and source code of test program.
>
> Best regards,
>
> Hideki Yamamoto
>
> --------------------------------------------------------------------------
> OS information
> --------------------------------------------------------------------------
> # sysctl -a |grep v6
> net.inet.tcp.v6mssdflt: 1024
> net.inet6.ip6.v6only: 1
> # sysctl -a |grep mtu
> net.inet.tcp.path_mtu_discovery: 1
> net.inet.sctp.pmtu_raise_time: 600
> net.inet6.ip6.mcast_pmtu: 0
> # uname -a
> FreeBSD tulip 9.0-CURRENT FreeBSD 9.0-CURRENT #16: Fri Jan 15 05:25:24
> JST 2010 root at tulip:/usr/obj/usr/src/sys/tulip8 i386
> tulip#
>
> --------------------------------------------------------------------------
> Tshark output that shows the packets are devided into two packtet when
> delivering 1400 byte lenghth packets.
> --------------------------------------------------------------------------
> # ./udp -s 1400 -o &
> # tshark -VV -i fxp1 host ff3e::9800:600 |grep -v aaaaaaaaa
> Capturing on fxp1
> Frame 1 (1294 bytes on wire, 1294 bytes captured)
> Arrival Time: Feb 21, 2010 17:35:08.560297000
> [Time delta from previous captured frame: 0.000000000 seconds]
> [Time delta from previous displayed frame: 0.000000000 seconds]
> [Time since reference or first frame: 0.000000000 seconds]
> Frame Number: 1
> Frame Length: 1294 bytes
> Capture Length: 1294 bytes
> [Frame is marked: False]
> [Protocols in frame: eth:ipv6:data]
> Ethernet II, Src: Intel_89:d6:d9 (00:d0:b7:89:d6:d9), Dst:
> IPv6mcast_98:00:06:00 (33:33:98:00:06:00)
> Destination: IPv6mcast_98:00:06:00 (33:33:98:00:06:00)
> Address: IPv6mcast_98:00:06:00 (33:33:98:00:06:00)
> .... ...1 .... .... .... .... = IG bit: Group address
> (multicast/broadcast)
> .... ..1. .... .... .... .... = LG bit: Locally administered
> address (this is NOT the factory default)
> Source: Intel_89:d6:d9 (00:d0:b7:89:d6:d9)
> Address: Intel_89:d6:d9 (00:d0:b7:89:d6:d9)
> .... ...0 .... .... .... .... = IG bit: Individual address (unicast)
> .... ..0. .... .... .... .... = LG bit: Globally unique address
> (factory default)
> Type: IPv6 (0x86dd)
> Internet Protocol Version 6
> 0110 .... = Version: 6
> [0110 .... = This field makes the filter "ip.version == 6" possible: 6]
> .... 0000 0000 .... .... .... .... .... = Traffic class: 0x00000000
> .... .... .... 0000 0000 0000 0000 0000 = Flowlabel: 0x00000000
> Payload length: 1240
> Next header: IPv6 fragment (0x2c)
> Hop limit: 1
> Source: 2001:2a0:806:206:2d0:b7ff:fe89:d6d9
> (2001:2a0:806:206:2d0:b7ff:fe89:d6d9)
> Destination: ff3e::9800:600 (ff3e::9800:600)
> Fragmentation Header
> Next header: UDP (0x11)
> 0000 0000 0000 0... = Offset: 0 (0x0000)
> .... .... .... ...1 = More Fragment: Yes
> Identification: 0xc31d92fa
> Data (1232 bytes)
>
> 0000 5d 61 46 50 05 80 b0 d6 61 61 61 61 61 61 61 61 ]aFP....aaaaaaaa
> Data: 5D6146500580B0D661616161616161616161616161616161...
> [Length: 1232]
>
> Frame 2 (238 bytes on wire, 238 bytes captured)
> Arrival Time: Feb 21, 2010 17:35:08.560324000
> [Time delta from previous captured frame: 0.000027000 seconds]
> [Time delta from previous displayed frame: 0.000027000 seconds]
> [Time since reference or first frame: 0.000027000 seconds]
> Frame Number: 2
> Frame Length: 238 bytes
> Capture Length: 238 bytes
> [Frame is marked: False]
> [Protocols in frame: eth:ipv6:udp:data]
> Ethernet II, Src: Intel_89:d6:d9 (00:d0:b7:89:d6:d9), Dst:
> IPv6mcast_98:00:06:00 (33:33:98:00:06:00)
> Destination: IPv6mcast_98:00:06:00 (33:33:98:00:06:00)
> Address: IPv6mcast_98:00:06:00 (33:33:98:00:06:00)
> .... ...1 .... .... .... .... = IG bit: Group address
> (multicast/broadcast)
> .... ..1. .... .... .... .... = LG bit: Locally administered
> address (this is NOT the factory default)
> Source: Intel_89:d6:d9 (00:d0:b7:89:d6:d9)
> Address: Intel_89:d6:d9 (00:d0:b7:89:d6:d9)
> .... ...0 .... .... .... .... = IG bit: Individual address (unicast)
> .... ..0. .... .... .... .... = LG bit: Globally unique address
> (factory default)
> Type: IPv6 (0x86dd)
>
> ------
> /**********************************************************************
> udp.c (modified for MC Send Support)
> ***********************************************************************/
> #include <sys/param.h>
> #include <sys/types.h>
> #include <sys/socket.h>
> #include <sys/ioctl.h>
> #include <net/if.h>
> #include <netinet/in.h>
> #include <netdb.h>
> #include <stdlib.h>
> #include <stdio.h>
> #include <string.h>
> #include <fcntl.h>
> #include <unistd.h>
> #include <err.h>
> #include <errno.h>
> #include <ifaddrs.h>
>
> // Modify send_addr to Multicast Address
> char *send_addr="ff3e::9800:600";
> char *send_port="18000";
>
> char *recv_addr="2001:99::1";
> char *recv_port="16000";
> int send_s;
> int only_out=0;
> int only_in=0;
> int out_packet_size;
> struct addrinfo *send_res;
>
> // Add for MC support
> char *out_if="fxp1";
>
> main(ac,av)
> int ac;
> char **av;
> {
> int c;
>
> while ((c = getopt(ac, av, "s:oi")) != -1) {
> switch (c) {
> case 'o':
> only_out++;
> break;
> case 'i':
> only_in++;
> break;
> case 's':
> out_packet_size = atoi(optarg);
> break;
> default:
> Usage();
> exit (1);
> }
> }
> if( only_in && only_out ){
> Usage();
> exit (1);
> }
>
> if( only_in == 0 ){
> create_send_socket();
> send_v6_udp();
> exit;
> }
> recv_v6_udp();
> }
> Usage()
> {
> printf("Usage: udpgw [-o][-i][-s output_packet_size]\n");
>
> }
> create_send_socket()
> {
> struct addrinfo hints;
> int error;
> struct sockaddr_in6 *sin6;// Add for MC Support
> int ifindex;// Add for MC Support
>
>
> memset(&hints, 0, sizeof(hints));
> hints.ai_family = PF_UNSPEC;
> hints.ai_socktype = SOCK_DGRAM;
> error = getaddrinfo(send_addr, send_port, &hints, &send_res);
> if (error != 0) errx(1, "%s", gai_strerror(error));
> send_res->ai_family = AF_INET6;
> send_s = socket(send_res->ai_family, send_res->ai_socktype,
> send_res->ai_protocol);
> if (send_s < 0) err(1, "socket");
>
> // Add for MC support
> sin6 = (struct sockaddr_in6 *)send_res->ai_addr;
> if(IN6_IS_ADDR_MULTICAST(&(sin6->sin6_addr))) {
> if ( (ifindex = if_nametoindex(out_if)) == 0 ){
> err(1, "socket-MC");
> }
> error = setsockopt(send_s, IPPROTO_IPV6, IPV6_MULTICAST_IF,
> &ifindex, sizeof(ifindex));
> if (error < 0){
> err(1, "socket-MC");
> }
> }
>
> }
> send_v6_udp()
> {
> int len,cc,i;
> char buf[2000];
>
> for( i=0; i<2000 ; i++ ){
> buf[i]='a';
> }
> if( 1501 > out_packet_size ){
> cc = out_packet_size ;
> }else{
> cc = 1500;
> }
> printf("Let's send %d length packet to %s\n",cc,send_addr);
> while(1){
> len = sendto(send_s, buf, cc, 0, send_res->ai_addr,
> send_res->ai_addrlen);
> sleep(1);
> }
> }
>
> recv_v6_udp()
> {
> int recv_s;
> struct addrinfo hints, *res;
> int error;
> int len,cc,ccout;
> char buf[2000];
> FILE *outfp=stdout;
> int fromlen;
> struct sockaddr_in6 from6;
>
> memset(&hints, 0, sizeof(hints));
> hints.ai_family = PF_UNSPEC;
> hints.ai_socktype = SOCK_DGRAM;
> error = getaddrinfo(recv_addr, recv_port, &hints, &res);
> if (error != 0) errx(1, "%s", gai_strerror(error));
> res->ai_family = AF_INET6;
> recv_s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
> if (recv_s < 0) err(1, "socket");
>
> while(1){
> cc = recvfrom(recv_s, (void *)buf, sizeof(buf), 0,
> (struct sockaddr *)&from6, &fromlen);
> if (cc < 0) {
> warn("recvfrom");
> continue;
> }
> if ( only_in == 0 ){
> len = sendto(send_s, buf, cc, 0, send_res->ai_addr,
> send_res->ai_addrlen);
> } else {
> if ((ccout = fwrite(buf, cc, 1, outfp)) < 1)
> close(recv_s);
> }
>
> }
> }
> -------------
>
More information about the freebsd-net
mailing list