#!/usr/bin/perl # # Copyright (c) 2002 Apple Computer, Inc. All rights reserved. # # @APPLE_LICENSE_HEADER_START@ # # "Portions Copyright (c) 2002 Apple Computer, Inc. All Rights # Reserved. This file contains Original Code and/or Modifications of # Original Code as defined in and that are subject to the Apple Public # Source License Version 1.0 (the 'License'). You may not use this file # except in compliance with the License. Please obtain a copy of the # License at http://www.apple.com/publicsource and read it before using # this file. # # The Original Code and all software distributed under the License are # distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER # EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, # INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the # License for the specific language governing rights and limitations # under the License." # # @APPLE_LICENSE_HEADER_END@ # # Setup IPv6 for Darwin # - Startup/shutdown IPv6 on the given interface # - Startup/shutdown 6to4 on the given interface # - Start/stop router advertisement. # # Setup 6to4 IPv6, for NetBSD (and maybe others) # # (c) Copyright 2000 Hubert Feyrer # # Directory for conf file $etcdir="/private/etc"; require "$etcdir/6to4.conf"; use Getopt::Std; ########################################################################### sub do_6to4_setup { # # Some sanity checks - check for link-local address and stf # if (`ifconfig -a | grep fe80: | wc -l` <= 0 or `ifconfig -a | grep stf | wc -l` <= 0) { die "$0: It seems your kernel does not support IPv6 or 6to4 (stf).\n"; } # # Take the requested interface from the user # Figure out addressing, etc. # $localadr4 = `ifconfig $ARGV[1] inet | grep inet | grep -v "10.*.*.*"| \ grep -v "172.[^16-31].*.*" | grep -v "192.168.*.*" | \ grep -v "169.254.*.*" | grep -v alias`; $localadr4 =~ s/^.*inet\s*//; $localadr4 =~ s/\s.*$//; chomp($localadr4); @l4c = split('\.', $localadr4); $prefix = sprintf("2002:%02x%02x:%02x%02x", @l4c[0..3]); $localadr6 = sprintf("$prefix:%04x", $v6_net); # # Anycast is default in 6to4.conf file # if ($peer eq "6to4-anycast") { # magic values from rfc 3068 $remoteadr4 = "192.88.99.1"; $remoteadr6 = "2002:c058:6301::"; } else { chomp($remoteadr4 = `host $peer`); $remoteadr4 =~ s/^.*address //; chomp($remoteadr6 = `host -t AAAA $peer`); $remoteadr6 =~ s/^.*address //; } } ########################################################################### sub do_usage { print "Usage: $0 \n"; print " start-v6 all | stop-v6 all\n"; print " start-v6 [interface] | stop-v6 [interface]\n"; print " start-stf [interface] | stop-stf\n"; print " start-rtadvd | stop-rtadvd\n"; } ########################################################################### # # Process options - just help for now # getopts('h'); if ($opt_h) { do_usage; exit 0; } # # Handle commands # # Start IPv6 if ($ARGV[0] eq "start-v6" or $ARGV[0] eq "v6-start") { if ($ARGV[1] eq "all") { print "Starting IPv6 on all interfaces.\n"; system "ip6 -a"; } else { print "Starting IPv6 on $ARGV[1].\n"; system "ip6 -u $ARGV[1]"; } } # Stop IPv6 elsif ($ARGV[0] eq "stop-v6" or $ARGV[0] eq "v6-stop") { if ($ARGV[1] eq "all") { print "Stopping IPv6 on all interfaces.\n"; system "ip6 -x"; } else { print "Stopping IPv6 on $ARGV[1].\n"; system "ip6 -d $ARGV[1]"; } } # Start 6to4 elsif ($ARGV[0] eq "start-stf" or $ARGV[0] eq "stf-start") { do_6to4_setup; print "Starting 6to4 on $ARGV[1].\n"; system "ifconfig stf0 inet6 $localadr6:$hostbits6 prefixlen $v6_prefixlen alias"; system "route add -inet6 default $remoteadr6"; if ($in_if ne "") { system "ifconfig $in_if inet6 $prefix:$v6_innernet:$hostbits6"; } } # Stop 6to4 elsif ($ARGV[0] eq "stop-stf" or $ARGV[0] eq "stf-stop") { print "Stopping 6to4.\n"; system "ifconfig stf0 down"; $cmd="ifconfig stf0 inet6 " . "| grep inet6 " . "| sed -e 's/inet6//' " . "-e 's/prefix.*//g' " . "-e 's/^[ ]*//' " . "-e 's/[ ]*\$//'"; foreach $ip ( split('\s+', `$cmd`)) { system "ifconfig stf0 inet6 -alias $ip"; } system "route delete -inet6 default"; } # Start router advertisement elsif ($ARGV[0] eq "rtadvd-start" or $ARGV[0] eq "start-rtadvd") { print "WARNING: Setting up router advertisement should be done with great care\n"; print "because of a number of security issues. You should make sure this is\n"; print "allowed on your network and possibly fine-tune rtadvd.conf.\n"; print "\n"; print "Are you sure you want to start router advertisement (yes/no) ?: "; while () { chomp; if ($_ eq "yes" or $_ eq "y") { if ( -f "/var/run/rtadvd.pid" ) { print "rtadvd already running!\n"; } else { print "Starting router advertisement.\n"; system "sysctl -w net.inet6.ip6.forwarding=1"; system "sysctl -w net.inet6.ip6.accept_rtadv=0"; shift @ARGV; system "rtadvd @ARGV"; } last; } elsif ($_ eq "no" or $_ eq "n") { print "Router advertisement startup aborted.\n"; last; } else { print "Invalid entry! Try again.\n"; print "Are you sure you want to start router advertisement? (yes/no): "; } } } # Stop router advertisement elsif ($ARGV[0] eq "rtadvd-stop" or $ARGV[0] eq "stop-rtadvd") { if ( -f "/var/run/rtadvd.pid" ) { print "Stopping router advertisement.\n"; $pid = `cat /var/run/rtadvd.pid`; system "kill -TERM $pid"; system "rm -f /var/run/rtadvd.pid"; system "rm -f /var/run/6to4-rtadvd.conf.$pid"; } else { print "no rtadvd running!\n"; } } else { do_usage; }