1 // Copyright 2011 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
14 var multicast = flag.Bool("multicast", false, "enable multicast tests")
16 var multicastUDPTests = []struct {
23 // cf. RFC 4727: Experimental Values in IPv4, IPv6, ICMPv4, ICMPv6, UDP, and TCP Headers
24 {"udp", IPv4zero, IPv4(224, 0, 0, 254), (FlagUp | FlagLoopback), false},
25 {"udp4", IPv4zero, IPv4(224, 0, 0, 254), (FlagUp | FlagLoopback), false},
26 {"udp", IPv6unspecified, ParseIP("ff0e::114"), (FlagUp | FlagLoopback), true},
27 {"udp6", IPv6unspecified, ParseIP("ff01::114"), (FlagUp | FlagLoopback), true},
28 {"udp6", IPv6unspecified, ParseIP("ff02::114"), (FlagUp | FlagLoopback), true},
29 {"udp6", IPv6unspecified, ParseIP("ff04::114"), (FlagUp | FlagLoopback), true},
30 {"udp6", IPv6unspecified, ParseIP("ff05::114"), (FlagUp | FlagLoopback), true},
31 {"udp6", IPv6unspecified, ParseIP("ff08::114"), (FlagUp | FlagLoopback), true},
32 {"udp6", IPv6unspecified, ParseIP("ff0e::114"), (FlagUp | FlagLoopback), true},
35 func TestMulticastUDP(t *testing.T) {
36 if runtime.GOOS == "plan9" || runtime.GOOS == "windows" {
40 t.Logf("test disabled; use --multicast to enable")
44 for _, tt := range multicastUDPTests {
49 if tt.ipv6 && (!supportsIPv6 || os.Getuid() != 0) {
52 ift, err := Interfaces()
54 t.Fatalf("Interfaces failed: %v", err)
56 for _, x := range ift {
57 if x.Flags&tt.flags == tt.flags {
63 t.Logf("an appropriate multicast interface not found")
66 c, err := ListenUDP(tt.net, &UDPAddr{IP: tt.laddr})
68 t.Fatalf("ListenUDP failed: %v", err)
71 if err := c.JoinGroup(ifi, tt.gaddr); err != nil {
72 t.Fatalf("JoinGroup failed: %v", err)
75 testIPv4MulticastSocketOptions(t, c.fd, ifi)
77 testIPv6MulticastSocketOptions(t, c.fd, ifi)
79 ifmat, err := ifi.MulticastAddrs()
81 t.Fatalf("MulticastAddrs failed: %v", err)
83 for _, ifma := range ifmat {
84 if ifma.(*IPAddr).IP.Equal(tt.gaddr) {
90 t.Fatalf("%q not found in RIB", tt.gaddr.String())
92 if err := c.LeaveGroup(ifi, tt.gaddr); err != nil {
93 t.Fatalf("LeaveGroup failed: %v", err)
98 func TestSimpleMulticastUDP(t *testing.T) {
99 if runtime.GOOS == "plan9" {
103 t.Logf("test disabled; use --multicast to enable")
107 for _, tt := range multicastUDPTests {
112 tt.flags = FlagUp | FlagMulticast
113 ift, err := Interfaces()
115 t.Fatalf("Interfaces failed: %v", err)
117 for _, x := range ift {
118 if x.Flags&tt.flags == tt.flags {
124 t.Logf("an appropriate multicast interface not found")
127 c, err := ListenUDP(tt.net, &UDPAddr{IP: tt.laddr})
129 t.Fatalf("ListenUDP failed: %v", err)
132 if err := c.JoinGroup(ifi, tt.gaddr); err != nil {
133 t.Fatalf("JoinGroup failed: %v", err)
135 if err := c.LeaveGroup(ifi, tt.gaddr); err != nil {
136 t.Fatalf("LeaveGroup failed: %v", err)
141 func testIPv4MulticastSocketOptions(t *testing.T, fd *netFD, ifi *Interface) {
142 ifmc, err := ipv4MulticastInterface(fd)
144 t.Fatalf("ipv4MulticastInterface failed: %v", err)
146 t.Logf("IPv4 multicast interface: %v", ifmc)
147 err = setIPv4MulticastInterface(fd, ifi)
149 t.Fatalf("setIPv4MulticastInterface failed: %v", err)
152 ttl, err := ipv4MulticastTTL(fd)
154 t.Fatalf("ipv4MulticastTTL failed: %v", err)
156 t.Logf("IPv4 multicast TTL: %v", ttl)
157 err = setIPv4MulticastTTL(fd, 1)
159 t.Fatalf("setIPv4MulticastTTL failed: %v", err)
162 loop, err := ipv4MulticastLoopback(fd)
164 t.Fatalf("ipv4MulticastLoopback failed: %v", err)
166 t.Logf("IPv4 multicast loopback: %v", loop)
167 err = setIPv4MulticastLoopback(fd, false)
169 t.Fatalf("setIPv4MulticastLoopback failed: %v", err)
173 func testIPv6MulticastSocketOptions(t *testing.T, fd *netFD, ifi *Interface) {
174 ifmc, err := ipv6MulticastInterface(fd)
176 t.Fatalf("ipv6MulticastInterface failed: %v", err)
178 t.Logf("IPv6 multicast interface: %v", ifmc)
179 err = setIPv6MulticastInterface(fd, ifi)
181 t.Fatalf("setIPv6MulticastInterface failed: %v", err)
184 hoplim, err := ipv6MulticastHopLimit(fd)
186 t.Fatalf("ipv6MulticastHopLimit failed: %v", err)
188 t.Logf("IPv6 multicast hop limit: %v", hoplim)
189 err = setIPv6MulticastHopLimit(fd, 1)
191 t.Fatalf("setIPv6MulticastHopLimit failed: %v", err)
194 loop, err := ipv6MulticastLoopback(fd)
196 t.Fatalf("ipv6MulticastLoopback failed: %v", err)
198 t.Logf("IPv6 multicast loopback: %v", loop)
199 err = setIPv6MulticastLoopback(fd, false)
201 t.Fatalf("setIPv6MulticastLoopback failed: %v", err)