1#!/usr/bin/env perl 2# 3# CDDL HEADER START 4# 5# The contents of this file are subject to the terms of the 6# Common Development and Distribution License (the "License"). 7# You may not use this file except in compliance with the License. 8# 9# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10# or http://www.opensolaris.org/os/licensing. 11# See the License for the specific language governing permissions 12# and limitations under the License. 13# 14# When distributing Covered Code, include this CDDL HEADER in each 15# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16# If applicable, add the following below this CDDL HEADER, with the 17# fields enclosed by brackets "[]" replaced with your own identifying 18# information: Portions Copyright [yyyy] [name of copyright owner] 19# 20# CDDL HEADER END 21# 22 23# 24# Copyright 2008 Sun Microsystems, Inc. All rights reserved. 25# Use is subject to license terms. 26# 27#pragma ident "%Z%%M% %I% %E% SMI" 28 29# 30# get.ipv6remote.pl 31# 32# Find an IPv6 reachable remote host using both ifconfig(1M) and ping(1M). 33# Print the local address and the remote address, or print nothing if either 34# no IPv6 interfaces or remote hosts were found. (Remote IPv6 testing is 35# considered optional, and so not finding another IPv6 host is not an error 36# state we need to log.) Exit status is 0 if a host was found. 37# 38 39use strict; 40use IO::Socket; 41 42my $MAXHOSTS = 32; # max hosts to scan 43my $TIMEOUT = 3; # connection timeout 44my $MULTICAST = "FF02::1"; # IPv6 multicast address 45 46# 47# Determine local IP address 48# 49my $local = ""; 50my $remote = ""; 51my $interf = ""; 52my %Local; 53my %Addr; 54my $up; 55open IFCONFIG, '/sbin/ifconfig -a inet6 |' 56 or die "Couldn't run ifconfig: $!\n"; 57while (<IFCONFIG>) { 58 next if /^lo/; 59 60 # "UP" is always printed first (see print_flags() in ifconfig.c): 61 $up = 1 if /^[a-z].*<UP,/; 62 $up = 0 if /^[a-z].*<,/; 63 64 if (m:(\S+\d+)\: :) { 65 $interf = $1; 66 } 67 68 # assume output is "inet6 ...": 69 if (m:inet6 (\S+) :) { 70 my $addr = $1; 71 $Local{$addr} = 1; 72 $Addr{$interf} = $addr; 73 $up = 0; 74 $interf = ""; 75 } 76} 77close IFCONFIG; 78 79# 80# Find the first remote host that responds to an icmp echo, 81# which isn't a local address. Try each IPv6-enabled interface. 82# 83foreach $interf (split(' ', `ifconfig -l -u inet6`)) { 84 next if $interf =~ /lo[0-9]+/; 85 open PING, "/sbin/ping6 -n -s 56 -c $MAXHOSTS $MULTICAST\%$interf |" or next; 86 while (<PING>) { 87 if (/bytes from (.*), / and not defined $Local{$1}) { 88 $remote = $1; 89 $local = $Addr{$interf}; 90 last; 91 } 92 } 93} 94close PING; 95exit 2 if $remote eq ""; 96 97print "$local $remote\n"; 98