+++ /dev/null
-#!/bin/sh
-
-#
-# Copyright 1998 VMware, Inc. All rights reserved.
-#
-
-# vmnet: Manages the services needed to run VMware networking
-#
-# description: Manages the services needed to run VMware networking
-#
-# chkconfig: 235 90 8
-#
-# probe: true
-# hide: true
-
-subsys=vmnet
-driver=vmmon
-vnet=vmnet
-bridge=vmnet-bridge
-dhcpd=vmnet-dhcpd
-netifup=vmnet-netifup
-natd=vmnet-natd
-ping=vmware-ping
-smbd=vmware-smbd
-nmbd=vmware-nmbd
-
-# Source config files
-vmware_etc_dir=/etc/vmware
-vmware_locations="$vmware_etc_dir"/locations
-vmnet_cfg="$vmware_etc_dir"/vmnet.conf
-
-for f in $vmware_locations $vmnet_cfg; do
- if [ -r $f ]; then
- . $f
- else
- echo "FATAL: Unable to read $f"
- exit 1
- fi
-done
-
-# System wide functions
-. /etc/rc.d/init.d/functions
-
-# Create /dev/vmnetXX device
-vmware_create_vmnet() {
- local vHubNr="$1" # IN
- local vDevice="/dev/vmnet$vHubNr"
-
- if [ ! -e "$vDevice" ]; then
- mknod -m 600 "$vDevice" c 119 "$vHubNr"
- fi
-}
-
-#
-# Create a temporary directory
-#
-
-# They are a lot of small utility programs to create temporary files in a
-# secure way, but none of them is standard. So I wrote this --hpreg
-make_tmp_dir() {
- local dirname="$1" # OUT
- local prefix="$2" # IN
- local tmp
- local serial
- local loop
-
- tmp="${TMPDIR:-/tmp}"
- # Don't overwrite existing user data
- # -> Create a directory with a name that didn't exist before
- #
- # This may never succeed (if we are racing with a malicious process), but at
- # least it is secure
- serial=0
- loop='yes'
- while [ "$loop" = 'yes' ]; do
- # Check the validity of the temporary directory. We do this in the loop
- # because it can change over time
- if [ ! -d "$tmp" ]; then
- echo 'Error: "'"$tmp"'" is not a directory.'
- echo
- exit 1
- fi
- if [ ! -w "$tmp" -o ! -x "$tmp" ]; then
- echo 'Error: "'"$tmp"'" should be writable and executable.'
- echo
- exit 1
- fi
- # Be secure
- # -> Don't give write access to other users (so that they can not use this
- # directory to launch a symlink attack)
- if mkdir -m 0755 "$tmp"'/'"$prefix$serial" >/dev/null 2>&1; then
- loop='no'
- else
- serial=`expr "$serial" + 1`
- if [ "`expr "$serial" % 200`" = '0' ]; then
- echo 'Warning: The "'"$tmp"'" directory may be under attack.'
- echo
- fi
- fi
- done
- eval "$dirname"'="$tmp"'"'"'/'"'"'"$prefix$serial"'
-}
-
-#
-# Utilities
-#
-
-# Compute the subnet address associated to a couple IP/netmask
-ipv4_subnet() {
- local ip="$1"
- local netmask="$2"
-
- # Split quad-dotted addresses into bytes
- # There is no double quote around the back-quoted expression on purpose
- # There is no double quote around $ip and $netmask on purpose
- set -- `IFS='.'; echo $ip $netmask`
- echo $(($1 & $5)).$(($2 & $6)).$(($3 & $7)).$(($4 & $8))
-}
-
-# Compute the broadcast address associated to a couple IP/netmask
-ipv4_broadcast() {
- local ip="$1"
- local netmask="$2"
-
- # Split quad-dotted addresses into bytes
- # There is no double quote around the back-quoted expression on purpose
- # There is no double quote around $ip and $netmask on purpose
- set -- `IFS='.'; echo $ip $netmask`
- echo $(($1 | (255 - $5))).$(($2 | (255 - $6))).$(($3 | (255 - $7))).$(($4 | (255 - $8)))
-}
-
-# Count the number of running virtual machines by looking at the number of references
-# to the $driver module.
-countVMs() {
- # Beware of module dependancies here. An exact match is important
- /sbin/lsmod | awk 'BEGIN {n = 0;} {if ($1 == "'"$driver"'") n = $3;} END {print n;}'
-}
-
-# Check if there is an IP route for a given subnet via a given interface
-# Return true if there is _NO_ such route
-noRoutePresent() {
- local subnet="$1" # IN
- local intf="$2" # IN
-
- # Beware, there may be several identical routes
- [ "`/sbin/route -n | grep '^'"$subnet"'.*'"$intf"'$'`" = '' ]
-}
-
-
-# Macro definitions
-#
-# Note:
-# . Each daemon must be started from its own directory to avoid busy devices
-# . Each PID file doesn't need to be added to the installer database, because
-# it is going to be automatically removed when it becomes stale (after a
-# reboot). It must go directly under /var/run, or some distributions
-# (RedHat 6.0) won't clean it
-#
-
-# Terminate a process synchronously
-vmware_synchrone_kill() {
- local pid="$1" # IN
- local signal="$2" # IN
- local second
-
- kill -"$signal" "$pid"
- # Wait a bit to see if the dirty job has really been done
- for second in 0 1 2 3 4 5 6 7 8 9 10; do
- if [ ! -d /proc/"$pid" ]; then
- # Success
- return 0
- fi
- sleep 1
- done
- # Timeout
- return 1
-}
-
-# Kill the process associated to a pidfile
-vmware_stop_pidfile() {
- local pidfile="$1" # IN
- local pid
-
- pid=`cat "$pidfile" 2>/dev/null`
- if [ "$pid" = '' ]; then
- # The file probably does not exist or is empty. Success
- return 0
- fi
- # Keep only the first number we find, because some Samba pid files are really
- # trashy: they end with NUL characters
- # There is no double quote around $pid on purpose
- set -- $pid
- pid="$1"
- # First try a nice SIGTERM
- if vmware_synchrone_kill "$pid" 15; then
- return 0
- fi
- # Then send a strong SIGKILL
- if vmware_synchrone_kill "$pid" 9; then
- return 0
- fi
- return 1
-}
-
-# Start the host-only network user service
-vmware_start_hostonly() {
- local vHubNr="$1" # IN
- local vHostIf="$2" # IN
- local ifIp="$3" # IN
- local ifMask="$4" # IN
- local run_dhcpd="$5" # IN
- local run_samba="$6" # IN
- local ifNet
-
- # Do a cursory check to see if the host-only network
- # configuration is still ok. We do this so that mobile
- # hosts don't get setup at install time and then moved to
- # a new locale where the host-only network config is no
- # longer valid.
- #
- # NB: This really needs to be done at power-on time when
- # VM is configured to use host-only networking so that
- # we aren't fooled by dynamic changes in the network.
- #
- # XXX ping takes 10 seconds to timeout if nobody answers
- # that slows boot too much so we do this bit in the
- # background.
- if "$VM_BINDIR"/"$ping" -q "$ifIp"; then
- echo 'Host-only networking disabled because '"$ifIp"
- echo 'appears to be a real, physical, existing address.'
- echo 'Please modify your host-only network configuration.'
- exit 1
- fi
- cd "$VM_BINDIR" && "$VM_BINDIR"/"$netifup" \
- -d /var/run/"$netifup"-"$vHostIf".pid /dev/vmnet"$vHubNr" "$vHostIf"
- [ "$?" -eq 0 ] || exit 1
- # Configure the virtual host ethernet interface and define the private IP
- # network
- #
- # . We provide the broadcast address explicitly because versions of ifconfig
- # prior to 1.39 (1999-03-18) seem to miscompute it
- # . 2.0.x kernels don't install a route when the interface is marked up, but
- # 2.2.x kernel do. Since we want to see any errors from route we don't
- # just discard messages from route, but instead check if the route got
- # installed before manually adding one.
- ifNet=`ipv4_subnet "$ifIp" "$ifMask"`
- if ifconfig "$vHostIf" inet "$ifIp" netmask "$ifMask" \
- broadcast "`ipv4_broadcast "$ifIp" "$ifMask"`" up \
- && noRoutePresent "$ifNet" "$vHostIf"; then
- route add -net "$ifNet" netmask "$ifMask" "$vHostIf"
- fi
- if [ "$run_dhcpd" = 'yes' ]; then
- # Start a DHCP server on a private IP network
- # The daemon already logs its output in the system log, so we can safely
- # trash it
- cd "$VM_BINDIR" && "$VM_BINDIR"/"$dhcpd" \
- -cf "$vmware_etc_dir"/"$vHostIf"/dhcpd/dhcpd.conf \
- -lf "$vmware_etc_dir"/"$vHostIf"/dhcpd/dhcpd.leases \
- -pf /var/run/"$dhcpd"-"$vHostIf".pid "$vHostIf" >/dev/null 2>&1 || exit 1
- fi
- if [ "$run_samba" = 'yes' ]; then
- # Start a SMB name server on a private IP network
- # Disable logging to avoid the uncontrolled creation of unmanaged files
- cd "$VM_BINDIR" && "$VM_BINDIR"/"$nmbd" -D -l /dev/null \
- -s "$vmware_etc_dir"/"$vHostIf"/smb/smb.conf \
- -f /var/run/"$nmbd"-"$vHostIf".pid || exit 1
- # Start a SMB share server on a private IP network
- # Disable logging to avoid the uncontrolled creation of unmanaged files
- cd "$VM_BINDIR" && "$VM_BINDIR"/"$smbd" -D -l /dev/null \
- -s "$vmware_etc_dir"/"$vHostIf"/smb/smb.conf \
- -f /var/run/"$smbd"-"$vHostIf".pid || exit 1
- fi
-}
-
-# Stop the host-only network user service
-vmware_stop_hostonly() {
- local vHostIf="$1" # IN
- local ifIp="$2" # IN
- local ifMask="$3" # IN
- local ifNet
-
- # Terminate the private network
- ifNet=`ipv4_subnet "$ifIp" "$ifMask"`
- noRoutePresent "$ifNet" "$vHostIf" || route del -net "$ifNet" netmask "$ifMask" || exit 1
- # To test if the interface exists, we can not just look at the exitcode
- # because old versions of ifconfig don't exit with 1 when invoked with a
- # non-existing interface
- if [ "`ifconfig "$vHostIf" 2>/dev/null`" != '' ]; then
- ifconfig "$vHostIf" down || exit 1
- fi
- vmware_stop_pidfile /var/run/"$netifup"-"$vHostIf".pid || exit 1
-}
-
-# See how we were called.
-case "$1" in
- start)
- if [ -f /var/lock/subsys/"$subsys" ]; then
- msg_already_running "VMware Workstation networking"
- fi
- # Try to load parport_pc. Failure is allowed as it does not exist
- # on kernels 2.0
- /sbin/modprobe parport_pc >/dev/null 2>&1
- msg_starting 'Virtual machine monitor'
- busy
- /sbin/modprobe $driver
- [ "$?" -eq "0" ] && ok || fail
- if [ "$VM_NETWORKING" = 'yes' ]; then
- msg_starting 'Virtual ethernet'
- busy
- /sbin/modprobe $vnet
- [ "$?" -eq 0 ] && ok || fail
- vHubNr=0
- while [ $vHubNr -lt 9 ]; do
- eval 'interface="$VNET_'"$vHubNr"'_INTERFACE"'
- eval 'hostaddr="$VNET_'"$vHubNr"'_HOSTONLY_HOSTADDR"'
- eval 'netmask="$VNET_'"$vHubNr"'_HOSTONLY_NETMASK"'
- if [ -n "$interface" ]; then
- vmware_create_vmnet "$vHubNr"
- # Connect a physical host ethernet interface to a virtual ethernet hub
- msg_starting 'Bridged networking on /dev/vmnet'"$vHubNr"
- busy
- cd "$VM_BINDIR" && "$VM_BINDIR"/"$bridge" \
- -d /var/run/"$bridge"-"$vHubNr".pid /dev/vmnet"$vHubNr" "$interface"
- [ "$?" -eq 0 ] && ok || fail
- elif [ -n "$hostaddr" -a -n "$netmask" ]; then
- vmware_create_vmnet "$vHubNr"
- eval 'samba="$VNET_'"$vHubNr"'_SAMBA"'
- msg_starting 'Host-only networking on /dev/vmnet'"$vHubNr"
- busy
- vmware_start_hostonly "$vHubNr" 'vmnet'"$vHubNr" "$hostaddr" \
- "$netmask" 'yes' "$samba"
- [ "$?" -eq 0 ] && ok || fail
- eval 'nat="$VNET_'"$vHubNr"'_NAT"'
- if [ "$nat" = 'yes' ]; then
- # Start the NAT network user service
- msg_starting 'NAT networking on /dev/vmnet'"$vHubNr"
- busy
- cd "$VM_BINDIR" && "$VM_BINDIR"/"$natd" \
- -d /var/run/"$natd"-"$vHubNr".pid \
- -m /var/run/"$natd"-"$vHubNr".mac \
- -c "$vmware_etc_dir"/vmnet"$vHubNr"/nat/nat.conf >/dev/null 2>&1
- [ "$?" -eq 0 ] && ok || fail
- fi
- fi
- vHubNr=$(($vHubNr + 1))
- done
- fi
- touch /var/lock/subsys/"$subsys"
- ;;
-
- stop)
- if [ "`countVMs`" -gt 0 ]; then
- echo 'At least one instance of VMware Workstation is still running.'
- echo 'Please stop all running instances of VMware Workstation first.'
- echo
- fi
- if [ ! -f /var/lock/subsys/"$subsys" ]; then
- msg_not_running "VMware Workstation networking"
- fi
- # Try to unload parport_pc. Failure is allowed as it does not exist
- # on kernels 2.0, and some other process could be using it.
- /sbin/modprobe -r parport_pc >/dev/null 2>&1
- if [ "$VM_NETWORKING" = "yes" ]; then
- # NB: must kill off processes using vmnet before
- # unloading module
- vHubNr=0
- while [ $vHubNr -lt 9 ]; do
- eval 'interface="$VNET_'"$vHubNr"'_INTERFACE"'
- eval 'hostaddr="$VNET_'"$vHubNr"'_HOSTONLY_HOSTADDR"'
- eval 'netmask="$VNET_'"$vHubNr"'_HOSTONLY_NETMASK"'
- if [ -n "$interface" ]; then
- # Disconnect a physical host ethernet interface from a virtual ethernet hub
- msg_stopping "Bridged networking on /dev/vmnet$vHubNr"
- busy
- vmware_stop_pidfile /var/run/"$bridge"-"$vHubNr".pid
- [ "$?" -eq 0 ] && ok || fail
- elif [ -n "$hostaddr" -a -n "$netmask" ]; then
- # Stop a DHCP server on a private IP network
- msg_stopping "DHCP server on /dev/vmnet$vHubNr"
- busy
- vmware_stop_pidfile /var/run/"$dhcpd"-"vmnet$vHubNr".pid
- [ "$?" -eq 0 ] && ok || fail
- eval 'samba="$VNET_'"$vHubNr"'_SAMBA"'
- if [ "$samba" = "yes" ]; then
- # Stop a SMB share server on a private IP network
- msg_stopping 'SMB share server on /dev/vmnet'"$vHubNr"
- busy
- vmware_stop_pidfile /var/run/"$smbd"-'vmnet'"$vHubNr".pid
- [ "$?" -eq 0 ] && ok || fail
- # Stop a SMB name server on a private IP network
- msg_stopping 'SMB name server on /dev/vmnet'"$vHubNr"
- busy
- vmware_stop_pidfile /var/run/"$nmbd"-'vmnet'"$vHubNr".pid
- [ "$?" -eq 0 ] && ok || fail
- fi
- eval 'nat="$VNET_'"$vHubNr"'_NAT"'
- if [ "$nat" = "yes" ]; then
- # Stop the NAT network user service
- msg_stopping 'NAT networking on /dev/vmnet'"$vHubNr"
- busy
- vmware_stop_pidfile /var/run/"$natd"-"$vHubNr".pid
- [ "$?" -eq 0 ] && ok || fail
- fi
- msg_stopping 'Host-only networking on /dev/vmnet'"$vHubNr"
- busy
- vmware_stop_hostonly 'vmnet'"$vHubNr" "$hostaddr" "$netmask"
- [ "$?" -eq 0 ] && ok || fail
-
- fi
- vHubNr=$(($vHubNr + 1))
- done
- msg_stopping 'Virtual machine monitor'
- busy
- if /sbin/lsmod | grep -q ^"$driver"; then
- /sbin/rmmod "$driver"
- fi
- [ "$?" -eq "0" ] && ok || fail
- msg_stopping 'Virtual ethernet'
- busy
- if /sbin/lsmod | grep -q ^"$vnet"; then
- /sbin/rmmod "$vnet"
- fi
- [ "$?" -eq "0" ] && ok || fail
- fi
- rm -f /var/lock/subsys/"$subsys"
- ;;
- status)
- if [ "`countVMs`" -gt 0 ]; then
- echo 'At least one instance of VMware Workstation is still running.'
- echo
- fi
- if [ "$VM_NETWORKING" = "yes" ]; then
- status "$bridge"
- status "$dhcpd"
- status "$netifup"
- fi
- if [ "$VM_NETWORKING" = "yes" ]; then
- echo -n "Module $vnet "
- /sbin/modprobe "$vnet" >/dev/null 2>&1 && echo installed || echo "not installed"
- fi
- ;;
- restart)
- "$0" stop && "$0" start
- ;;
- *)
- echo "Usage: `basename "$0"` {start|stop|status|restart}"
- exit 3
-esac
-
-exit 0