13742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman/**
23742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman *
33742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */
43742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanpackage javax.jmdns.impl;
53742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
63742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.lang.reflect.Method;
73742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.net.InetAddress;
83742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.net.NetworkInterface;
93742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.net.SocketException;
103742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.Enumeration;
113742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.HashSet;
123742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.Set;
133742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.logging.Level;
143742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.logging.Logger;
153742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
163742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport javax.jmdns.NetworkTopologyDiscovery;
173742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
183742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman/**
193742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * This class implements NetworkTopologyDiscovery.
203742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman *
213742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @author Pierre Frisch
223742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */
233742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanpublic class NetworkTopologyDiscoveryImpl implements NetworkTopologyDiscovery {
243742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    private final static Logger logger = Logger.getLogger(NetworkTopologyDiscoveryImpl.class.getName());
253742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
263742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    private final Method        _isUp;
273742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
283742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    private final Method        _supportsMulticast;
293742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
303742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    /**
313742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     *
323742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     */
333742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    public NetworkTopologyDiscoveryImpl() {
343742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        super();
353742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        Method isUp;
363742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        try {
373742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            isUp = NetworkInterface.class.getMethod("isUp", (Class<?>[]) null);
383742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        } catch (Exception exception) {
393742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            // We do not want to throw anything if the method does not exist.
403742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            isUp = null;
413742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        }
423742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        _isUp = isUp;
433742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        Method supportsMulticast;
443742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        try {
453742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            supportsMulticast = NetworkInterface.class.getMethod("supportsMulticast", (Class<?>[]) null);
463742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        } catch (Exception exception) {
473742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            // We do not want to throw anything if the method does not exist.
483742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            supportsMulticast = null;
493742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        }
503742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        _supportsMulticast = supportsMulticast;
513742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    }
523742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
533742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    /*
543742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * (non-Javadoc)
553742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * @see javax.jmdns.JmmDNS.NetworkTopologyDiscovery#getInetAddresses()
563742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     */
573742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    @Override
583742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    public InetAddress[] getInetAddresses() {
593742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        Set<InetAddress> result = new HashSet<InetAddress>();
603742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        try {
613742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
623742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            for (Enumeration<NetworkInterface> nifs = NetworkInterface.getNetworkInterfaces(); nifs.hasMoreElements();) {
633742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                NetworkInterface nif = nifs.nextElement();
643742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                for (Enumeration<InetAddress> iaenum = nif.getInetAddresses(); iaenum.hasMoreElements();) {
653742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                    InetAddress interfaceAddress = iaenum.nextElement();
663742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                    if (logger.isLoggable(Level.FINEST)) {
673742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                        logger.finest("Found NetworkInterface/InetAddress: " + nif + " -- " + interfaceAddress);
683742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                    }
693742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                    if (this.useInetAddress(nif, interfaceAddress)) {
703742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                        result.add(interfaceAddress);
713742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                    }
723742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                }
733742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            }
743742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        } catch (SocketException se) {
753742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            logger.warning("Error while fetching network interfaces addresses: " + se);
763742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        }
773742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        return result.toArray(new InetAddress[result.size()]);
783742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    }
793742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
803742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    /*
813742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * (non-Javadoc)
823742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * @see javax.jmdns.JmmDNS.NetworkTopologyDiscovery#useInetAddress(java.net.NetworkInterface, java.net.InetAddress)
833742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     */
843742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    @Override
853742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    public boolean useInetAddress(NetworkInterface networkInterface, InetAddress interfaceAddress) {
863742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        try {
873742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            if (_isUp != null) {
883742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                try {
893742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                    if (!((Boolean) _isUp.invoke(networkInterface, (Object[]) null)).booleanValue()) {
903742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                        return false;
913742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                    }
923742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                } catch (Exception exception) {
933742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                    // We should hide that exception.
943742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                }
953742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            }
963742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            if (_supportsMulticast != null) {
973742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                try {
983742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                    if (!((Boolean) _supportsMulticast.invoke(networkInterface, (Object[]) null)).booleanValue()) {
993742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                        return false;
1003742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                    }
1013742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                } catch (Exception exception) {
1023742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                    // We should hide that exception.
1033742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                }
1043742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            }
1053742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            if (interfaceAddress.isLoopbackAddress()) {
1063742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman                return false;
1073742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            }
1083742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            return true;
1093742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        } catch (Exception exception) {
1103742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman            return false;
1113742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        }
1123742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    }
1133742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
1143742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    /*
1153742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * (non-Javadoc)
1163742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * @see javax.jmdns.NetworkTopologyDiscovery#lockInetAddress(java.net.InetAddress)
1173742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     */
1183742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    @Override
1193742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    public void lockInetAddress(InetAddress interfaceAddress) {
1203742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        // Default implementation does nothing.
1213742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    }
1223742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
1233742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    /*
1243742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * (non-Javadoc)
1253742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     * @see javax.jmdns.NetworkTopologyDiscovery#unlockInetAddress(java.net.InetAddress)
1263742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman     */
1273742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    @Override
1283742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    public void unlockInetAddress(InetAddress interfaceAddress) {
1293742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman        // Default implementation does nothing.
1303742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman    }
1313742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman
1323742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman}
133