IPv6 multicast packet size
Hideki Yamamoto
hyama99 at gmail.com
Sun Feb 21 22:02:21 UTC 2010
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