1/*
2 * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/*
25 * @test
26 * @bug 4488458
27 * @summary IPv4 and IPv6 multicasting broken on Linux
28 */
29import java.net.*;
30import java.io.IOException;
31import java.util.Enumeration;
32
33public class Test {
34
35    static int count = 0;
36    static int failures = 0;
37
38    void doTest(String address) throws Exception {
39        boolean failed = false;
40
41        InetAddress ia = InetAddress.getByName(address);
42
43        count++;
44        System.out.println("**********************");
45        System.out.println("Test " + count + ": " + ia);
46
47        MulticastSocket mc = new MulticastSocket();
48        int port = mc.getLocalPort();
49        DatagramSocket s1 = new DatagramSocket();
50
51        byte msg[] = "Hello".getBytes();
52        DatagramPacket p = new DatagramPacket(msg, msg.length);
53
54        mc.setSoTimeout(2000);
55
56        try {
57            for (int i=0; i<2; i++) {
58
59                System.out.println("Join: " + ia);
60                mc.joinGroup(ia);
61
62                /* packets should be received */
63
64                for (int j=0; j<2; j++) {
65                    p.setAddress(ia);
66                    p.setPort(port);
67
68                    System.out.println("Send packet to: " + ia);
69                    s1.send(p);
70
71                    try {
72                        mc.receive(p);
73                        System.out.println("Got packet! - Good.");
74                    } catch (SocketTimeoutException e) {
75                        failed = true;
76                        System.out.println("Failed: No packet received within timeout!!!");
77                    }
78                }
79
80                System.out.println("Leave: " + ia);
81                mc.leaveGroup(ia);
82
83                /*
84                 * If there are multiple interface we might be a couple of
85                 * copies still in our queue
86                 */
87                try {
88                    while (true) {
89                        mc.receive(p);
90                    }
91                } catch (SocketTimeoutException e) { }
92
93                /* packets should not be received */
94
95                p.setAddress(ia);
96                p.setPort(port);
97
98                s1.send(p);
99
100                try {
101                    mc.receive(p);
102                    System.out.println("Failed: Got packet after leaving group!!!");
103                    failed = true;
104                } catch (SocketTimeoutException e) {
105                    System.out.println("No packet received within timeout! - Good.");
106                }
107            }
108
109         } catch (IOException ioe) {
110            System.out.println("Failed: Unexpected exception thrown: ");
111            ioe.printStackTrace();
112            failed = true;
113        }
114
115        mc.close();
116        s1.close();
117
118        if (failed) {
119            failures++;
120            System.out.println("Test failed!!");
121        } else {
122            System.out.println("Test passed.");
123        }
124    }
125
126    void allTests() throws Exception {
127
128        /*
129         * Assume machine has IPv4 address
130         */
131        doTest("224.80.80.80");
132
133        /*
134         * Check if IPv6 is enabled and the scope of the addresses
135         */
136        boolean has_ipv6 = false;
137        boolean has_siteaddress = false;
138        boolean has_linklocaladdress = false;
139        boolean has_globaladdress = false;
140
141        Enumeration nifs = NetworkInterface.getNetworkInterfaces();
142        while (nifs.hasMoreElements()) {
143            NetworkInterface ni = (NetworkInterface)nifs.nextElement();
144            Enumeration addrs = ni.getInetAddresses();
145
146            while (addrs.hasMoreElements()) {
147                InetAddress ia = (InetAddress)addrs.nextElement();
148
149                if (ia instanceof Inet6Address) {
150                    has_ipv6 = true;
151                    if (ia.isLinkLocalAddress()) has_linklocaladdress = true;
152                    if (ia.isSiteLocalAddress()) has_siteaddress = true;
153
154                    if (!ia.isLinkLocalAddress() &&
155                        !ia.isSiteLocalAddress() &&
156                        !ia.isLoopbackAddress()) {
157                        has_globaladdress = true;
158                    }
159                }
160            }
161        }
162
163        /*
164         * If IPv6 is enabled perform multicast tests with various scopes
165         */
166        if (has_ipv6) {
167            doTest("ff01::a");
168        }
169
170        if (has_linklocaladdress) {
171            doTest("ff02::a");
172        }
173
174        if (has_siteaddress) {
175            doTest("ff05::a");
176        }
177
178        if (has_globaladdress) {
179            doTest("ff0e::a");
180        }
181    }
182
183    public static void main(String args[]) throws Exception {
184        Test t = new Test();
185
186        if (args.length == 0) {
187            t.allTests();
188        } else {
189            for (int i=0; i<args.length; i++) {
190                t.doTest(args[i]);
191            }
192        }
193
194        System.out.println("**********************");
195        System.out.println(count + " test(s) executed. " + failures +
196                           " test(s) failed.");
197
198        if (failures > 0) {
199            throw new Exception("Test failed - see log file for details");
200        }
201    }
202}
203