1*c090e5dfSBryan Cantrill#!/usr/perl5/bin/perl -w 210e6dadfSbrendan# 310e6dadfSbrendan# CDDL HEADER START 410e6dadfSbrendan# 510e6dadfSbrendan# The contents of this file are subject to the terms of the 610e6dadfSbrendan# Common Development and Distribution License (the "License"). 710e6dadfSbrendan# You may not use this file except in compliance with the License. 810e6dadfSbrendan# 910e6dadfSbrendan# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 1010e6dadfSbrendan# or http://www.opensolaris.org/os/licensing. 1110e6dadfSbrendan# See the License for the specific language governing permissions 1210e6dadfSbrendan# and limitations under the License. 1310e6dadfSbrendan# 1410e6dadfSbrendan# When distributing Covered Code, include this CDDL HEADER in each 1510e6dadfSbrendan# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1610e6dadfSbrendan# If applicable, add the following below this CDDL HEADER, with the 1710e6dadfSbrendan# fields enclosed by brackets "[]" replaced with your own identifying 1810e6dadfSbrendan# information: Portions Copyright [yyyy] [name of copyright owner] 1910e6dadfSbrendan# 2010e6dadfSbrendan# CDDL HEADER END 2110e6dadfSbrendan# 2210e6dadfSbrendan 2310e6dadfSbrendan# 2410e6dadfSbrendan# Copyright 2008 Sun Microsystems, Inc. All rights reserved. 2510e6dadfSbrendan# Use is subject to license terms. 2610e6dadfSbrendan# 2710e6dadfSbrendan 2810e6dadfSbrendan# 2910e6dadfSbrendan# get.ipv4remote.pl [tcpport] 3010e6dadfSbrendan# 3110e6dadfSbrendan# Find an IPv4 reachable remote host using both ifconfig(1M) and ping(1M). 3210e6dadfSbrendan# If a tcpport is specified, return a host that is also listening on this 3310e6dadfSbrendan# TCP port. Print the local address and the remote address, or an 3410e6dadfSbrendan# error message if no suitable remote host was found. Exit status is 0 if 3510e6dadfSbrendan# a host was found. 3610e6dadfSbrendan# 3710e6dadfSbrendan 3810e6dadfSbrendanuse strict; 3910e6dadfSbrendanuse IO::Socket; 4010e6dadfSbrendan 4110e6dadfSbrendanmy $MAXHOSTS = 32; # max hosts to port scan 4210e6dadfSbrendanmy $TIMEOUT = 3; # connection timeout 4310e6dadfSbrendanmy $tcpport = @ARGV == 1 ? $ARGV[0] : 0; 4410e6dadfSbrendan 4510e6dadfSbrendan# 4610e6dadfSbrendan# Determine local IP address 4710e6dadfSbrendan# 4810e6dadfSbrendanmy $local = ""; 4910e6dadfSbrendanmy $remote = ""; 5010e6dadfSbrendanmy %Broadcast; 5110e6dadfSbrendanmy $up; 5210e6dadfSbrendanopen IFCONFIG, '/usr/sbin/ifconfig -a |' or die "Couldn't run ifconfig: $!\n"; 5310e6dadfSbrendanwhile (<IFCONFIG>) { 5410e6dadfSbrendan next if /^lo/; 5510e6dadfSbrendan 5610e6dadfSbrendan # "UP" is always printed first (see print_flags() in ifconfig.c): 5710e6dadfSbrendan $up = 1 if /^[a-z].*<UP,/; 5810e6dadfSbrendan $up = 0 if /^[a-z].*<,/; 5910e6dadfSbrendan 6010e6dadfSbrendan # assume output is "inet X ... broadcast Z": 6110e6dadfSbrendan if (/inet (\S+) .* broadcast (\S+)/) { 6210e6dadfSbrendan my ($addr, $bcast) = ($1, $2); 6310e6dadfSbrendan $Broadcast{$addr} = $bcast; 6410e6dadfSbrendan $local = $addr if $up and $local eq ""; 6510e6dadfSbrendan $up = 0; 6610e6dadfSbrendan } 6710e6dadfSbrendan} 6810e6dadfSbrendanclose IFCONFIG; 6910e6dadfSbrendandie "Could not determine local IP address" if $local eq ""; 7010e6dadfSbrendan 7110e6dadfSbrendan# 7210e6dadfSbrendan# Find the first remote host that responds to an icmp echo, 7310e6dadfSbrendan# which isn't a local address. 7410e6dadfSbrendan# 7510e6dadfSbrendanopen PING, "/usr/sbin/ping -ns $Broadcast{$local} 56 $MAXHOSTS |" or 7610e6dadfSbrendan die "Couldn't run ping: $!\n"; 7710e6dadfSbrendanwhile (<PING>) { 7810e6dadfSbrendan if (/bytes from (.*): / and not defined $Broadcast{$1}) { 7910e6dadfSbrendan my $addr = $1; 8010e6dadfSbrendan 8110e6dadfSbrendan if ($tcpport != 0) { 8210e6dadfSbrendan # 8310e6dadfSbrendan # Test TCP 8410e6dadfSbrendan # 8510e6dadfSbrendan my $socket = IO::Socket::INET->new( 8610e6dadfSbrendan Proto => "tcp", 8710e6dadfSbrendan PeerAddr => $addr, 8810e6dadfSbrendan PeerPort => $tcpport, 8910e6dadfSbrendan Timeout => $TIMEOUT, 9010e6dadfSbrendan ); 9110e6dadfSbrendan next unless $socket; 9210e6dadfSbrendan close $socket; 9310e6dadfSbrendan } 9410e6dadfSbrendan 9510e6dadfSbrendan $remote = $addr; 9610e6dadfSbrendan last; 9710e6dadfSbrendan } 9810e6dadfSbrendan} 9910e6dadfSbrendanclose PING; 10010e6dadfSbrendandie "Can't find a remote host for testing: No suitable response from " . 10110e6dadfSbrendan "$Broadcast{$local}\n" if $remote eq ""; 10210e6dadfSbrendan 10310e6dadfSbrendanprint "$local $remote\n"; 104