#!/bin/sh # Copyright (c) 2004-2011 Apple Inc. # # get-mobility-info # # Collect system & network configuration information. # PATH=/bin:/usr/bin:/sbin:/usr/sbin PRIV="" if [ ${EUID} -ne 0 ]; then PRIV="sudo" fi OUT="mobility-info-`date +'%m.%d.%Y.%H%M%S'`" OUTDIR="/var/tmp" if [ -d ~/Desktop ]; then OUTDIR=~/Desktop elif [ "`readlink /tmp`" = "private/var/tmp" ]; then OUTDIR=/Library/Logs/CrashReporter/SystemConfiguration mkdir -p ${OUTDIR} fi umask 077 WORKDIR=`mktemp -d -q "/tmp/${OUT}"` if [ $? -ne 0 ]; then echo "Could not create snapshot directory" exit 1 fi GZ_EXT="" GZ_OPT="" if [ -x /usr/bin/gzip ]; then GZ_EXT=".gz" GZ_OPT="-z" fi ARCHIVE=`mktemp -q "${OUTDIR}/${OUT}.tar${GZ_EXT}"` if [ $? -ne 0 ]; then echo "Could not create snapshot archive" rm -rf "${WORKDIR}" exit 1 fi cd "${WORKDIR}" # # processes # ps axlww > ps 2>&1 # # network interface configuration # ifconfig -a -L -b -m -r -v > ifconfig 2>&1 if [ $? -ne 0 ]; then ifconfig -a > ifconfig 2>&1 fi # # network route configuration # netstat -n -r -a -l > netstat 2>&1 # # DHCP configuration # for if in `ifconfig -l` do case ${if} in lo* ) ;; en* ) ipconfig getpacket ${if} > ipconfig-${if} 2>&1 ;; esac done # # AirPort info # if [ -x /System/Library/PrivateFrameworks/Apple80211.framework/Resources/airport ]; then /System/Library/PrivateFrameworks/Apple80211.framework/Resources/airport --getinfo \ > airport 2>&1 fi # # OS info # if [ -e /System/Library/CoreServices/SystemVersion.plist ]; then cat /System/Library/CoreServices/SystemVersion.plist \ > SystemVersion.plist 2>&1 fi if [ -e /System/Library/CoreServices/ServerVersion.plist ]; then cat /System/Library/CoreServices/ServerVersion.plist \ > ServerVersion.plist 2>&1 fi # # IOKit info # ioreg -i -l -w 0 > ioreg 2>&1 ioreg -i -l -p IODeviceTree -w 0 >> ioreg 2>&1 # # Host name # hostname > hostname 2>&1 # # Host configuration # hostinfo > hostinfo 2>&1 if [ -e /etc/hostconfig ]; then cat /etc/hostconfig > etc.hostconfig 2>&1 fi # # DNS configuration # scutil --dns > dns-configuration 2>&1 if [ -e /etc/resolv.conf ]; then cat /etc/resolv.conf > etc.resolv.conf 2>&1 fi if [ -e /var/run/resolv.conf ]; then cat /var/run/resolv.conf > var.run.resolv.conf 2>&1 fi # # Proxy configuration # scutil --proxy > proxy-configuration 2>&1 # # System / network preferences # for f in \ /Library/Preferences/SystemConfiguration/NetworkInterfaces.plist \ /Library/Preferences/SystemConfiguration/com.apple.PowerManagement.plist \ /Library/Preferences/SystemConfiguration/com.apple.airport.preferences.plist \ /Library/Preferences/SystemConfiguration/com.apple.nat.plist \ /Library/Preferences/SystemConfiguration/com.apple.network.identification.plist \ /Library/Preferences/SystemConfiguration/com.apple.smb.server.plist \ /Library/Preferences/SystemConfiguration/com.apple.wifi.plist \ /Library/Preferences/SystemConfiguration/preferences.plist \ /Library/Preferences/com.apple.alf.plist \ /Library/Preferences/com.apple.sharing.firewall.plist \ /Library/Preferences/com.apple.wwand.plist \ do if [ -e "${f}" ]; then b="`basename ${f}`" cat "${f}" > "${b}" 2>&1 fi done # # InternetSharing # if [ -e /etc/bootpd.plist ]; then cat /etc/bootpd.plist > bootpd.plist 2>&1 cat /etc/com.apple.named.proxy.conf > com.apple.named.proxy.conf 2>&1 elif [ -e /Library/Preferences/SystemConfiguration/bootpd.plist ]; then cat /Library/Preferences/SystemConfiguration/bootpd.plist > bootpd.plist 2>&1 cat /Library/Preferences/SystemConfiguration/com.apple.named.proxy.conf > com.apple.named.proxy.conf 2>&1 fi # # configd's cache # ${PRIV} scutil -p <<_END_OF_INPUT open snapshot quit _END_OF_INPUT if [ -f /var/tmp/configd-store.plist ]; then cat /var/tmp/configd-store.plist > configd-store.plist 2>&1 fi if [ -f /var/tmp/configd-pattern.plist ]; then cat /var/tmp/configd-pattern.plist > configd-pattern.plist 2>&1 fi if [ -f /var/tmp/configd-session.plist ]; then cat /var/tmp/configd-session.plist > configd-session.plist 2>&1 fi if [ -f /var/tmp/configd-state ]; then cat /var/tmp/configd-state > configd-state 2>&1 fi # # check configd's executable # if [ -x /usr/bin/codesign ]; then echo "#" >> configd-state echo "# codesign --verbose --display --entitlements - /usr/libexec/configd" >> configd-state echo "#" >> configd-state /usr/bin/codesign --verbose --display --entitlements - /usr/libexec/configd >> configd-state 2>&1 echo "#" >> configd-state echo "# codesign --verbose --verify /usr/libexec/configd" >> configd-state echo "#" >> configd-state /usr/bin/codesign --verbose --verify /usr/libexec/configd >> configd-state 2>&1 fi # # network reachability # scutil -d -v -r www.apple.com > reachability-info 2>&1 if [ -x /usr/bin/dig -a -f /etc/resolv.conf ]; then /usr/bin/dig -t any -c any www.apple.com > dig-results 2>/dev/null fi # # mounted filesystems # mount > mounted-filesystems 2>&1 # # mDNSResponder info # if [ -x /usr/bin/killall ]; then ${PRIV} killall -INFO mDNSResponder # and wait a short amount of time for mDNSResponder # to actually log the requested information sleep 15 fi # # awacsd info # if [ -x /usr/sbin/awacsd -a -x /usr/bin/killall ]; then ${PRIV} killall -INFO awacsd 2>/dev/null # and wait a short amount of time for awacsd # to actually log the requested information sleep 1 fi # # system log, kernel.log, early boot log messages # if [ -x /usr/bin/syslog ]; then # save the recent activity ${PRIV} syslog | tail -n 25000 > syslog # save just the "kernel" activity (in case some of the # interesting/relevant message are before the messages # captured above. ${PRIV} syslog -k Facility kern | tail -n 25000 > kernel if [ -d /var/log/DiagnosticMessages ]; then # save any MessageTracer activity ${PRIV} syslog -d /var/log/DiagnosticMessages \ -F raw \ -T local \ | tail -n 25000 > DiagnosticMessages fi else if [ -f /var/log/system.log ]; then ${PRIV} tail -n 25000 /var/log/system.log > system.log fi if [ -f /var/log/kernel.log ]; then ${PRIV} tail -n 25000 /var/log/kernel.log > kernel.log fi fi ${PRIV} dmesg > dmesg # # IPConfiguration log # if [ -f /var/log/com.apple.IPConfiguration.bootp ]; then ${PRIV} tail -n 2000 /var/log/com.apple.IPConfiguration.bootp \ > com.apple.IPConfiguration.bootp fi # # ppp log file(s) # scutil <<_END_OF_INPUT \ | awk -F' *: *' \ ' \ /Logfile : / { \ if (index($2, "/") == 1) { print $2 } \ else { print "/var/log/ppp/" $2 } \ } \ END { \ print "/tmp/pppotcp.log" \ } \ ' \ | sort -u \ | while read logFile open show Setup:/Network/Service/[^/]+/PPP pattern quit _END_OF_INPUT do if [ -f "${logFile}" ]; then b="`basename ${logFile}`" cat "${logFile}" > "${b}" 2>&1 fi done # # application firewall log # if [ -f /var/log/appfirewall.log ]; then ${PRIV} tail -n 2000 /var/log/appfirewall.log > appfirewall.log fi # # kernel extensions statistic # if [ -x /usr/sbin/kextstat ]; then kextstat > kextstat 2>&1 elif [ -x /usr/sbin/kmodstat ]; then kmodstat > kmodstat 2>&1 fi # # network statistics # echo "#" > network-statistics echo "# arp -n -a" >> network-statistics echo "#" >> network-statistics arp -n -a >> network-statistics 2>&1 echo "#" >> network-statistics echo "# netstat -n -a -A" >> network-statistics echo "#" >> network-statistics netstat -n -a -A >> network-statistics 2>&1 echo "#" >> network-statistics echo "# netstat -s" >> network-statistics echo "#" >> network-statistics netstat -s >> network-statistics 2>&1 echo "#" >> network-statistics echo "# netstat -mmm" >> network-statistics echo "#" >> network-statistics netstat -mmm >> network-statistics 2>&1 echo "#" >> network-statistics echo "# netstat -i -n -d" >> network-statistics echo "#" >> network-statistics netstat -i -n -d >> network-statistics 2>&1 if [ -x /usr/sbin/ndp ]; then echo "#" >> network-statistics echo "# ndp -n -a" >> network-statistics echo "#" >> network-statistics ndp -n -a >> network-statistics 2>&1 echo "#" >> network-statistics echo "# ndp -n -p" >> network-statistics echo "#" >> network-statistics ndp -n -p >> network-statistics 2>&1 echo "#" >> network-statistics echo "# ndp -n -r" >> network-statistics echo "#" >> network-statistics ndp -n -r >> network-statistics 2>&1 fi if [ -x /sbin/ipfw ]; then echo "#" >> network-statistics echo "# ipfw -at show" >> network-statistics echo "#" >> network-statistics ${PRIV} ipfw -at show >> network-statistics 2>&1 fi if [ -x /sbin/pfctl ]; then echo "#" > pf echo "# pfctl -s all" >> pf echo "#" >> pf ${PRIV} pfctl -s all >> pf 2>&1 echo "==============================" >> pf echo "#" >> pf echo "# pfctl -s References" >> pf echo "#" >> pf ${PRIV} pfctl -s References >> pf 2>&1 for ANCHOR in `pfctl -s Anchors 2>/dev/null` do echo "==============================" >> pf echo "#" >> pf echo "# pfctl -a ${ANCHOR} -s all" >> pf echo "#" >> pf ${PRIV} pfctl -a ${ANCHOR} -s all >> pf 2>&1 done fi if [ -x /usr/sbin/lsof ]; then echo "#" >> network-statistics echo "# lsof -i -U -n -P" >> network-statistics echo "#" >> network-statistics ${PRIV} lsof -i -U -n -P >> network-statistics 2>&1 fi # # DirectoryService info # if [ -x /usr/bin/odutil ]; then echo "#" > od-info echo "# odutil show all" >> od-info echo "#" >> od-info ${PRIV} odutil show all >> od-info 2>&1 elif [ -x /usr/bin/dscacheutil ]; then echo "#" > ds-info echo "# dscacheutil -configuration" >> ds-info echo "#" >> ds-info dscacheutil -configuration >> ds-info 2>&1 echo "#" >> ds-info echo "# dscacheutil -statistics" >> ds-info echo "#" >> ds-info dscacheutil -statistics >> ds-info 2>&1 echo "#" >> ds-info echo "# dscacheutil -cachedump -entries" >> ds-info echo "#" >> ds-info dscacheutil -cachedump -entries >> ds-info 2>&1 fi # # IPsec configuration # echo "#" > ipsec echo "# setkey -D" >> ipsec echo "#" >> ipsec ${PRIV} setkey -D \ | perl -nle ' if (/^(\s+[AE]:\s+\S+\s+)"?(.*)"?\s*$/) { chop($sha1=`echo "$2" | openssl sha1`); printf "%s[SHA-1:%s]\n", $1, $sha1; } else { printf "%s\n", $_; } ' >> ipsec echo "" >> ipsec echo "#" >> ipsec echo "# setkey -Pp -D" >> ipsec echo "#" >> ipsec ${PRIV} setkey -Pp -D >> ipsec for CF in /var/run/racoon/*.conf do if [ ! -r "${CF}" ]; then continue fi echo "" >> ipsec echo "#" >> ipsec echo "# ${CF}" >> ipsec echo "#" >> ipsec ${PRIV} cat ${CF} \ | perl -nle ' if (/^(\s+shared_secret\s+use\s+)"?([^\s;"]+)"?(.*)/) { chop($sha1=`echo "$2" | openssl sha1`); printf "%s[SHA-1:%s]%s\n", $1, $sha1, $3; } else { printf "%s\n", $_; } ' >> ipsec done # # Kerberos configuration # if [ -x /usr/bin/klist ]; then echo "#" > kerberos echo "# klist -e -c -A -f -a -n" >> kerberos echo "#" >> kerberos ${PRIV} klist -e -c -A -f -a -n >> kerberos 2>&1 echo "#" >> kerberos echo "# klist -e -k -t -K" >> kerberos echo "#" >> kerberos ${PRIV} klist -e -k -t -K >> kerberos 2>&1 fi # # BTMM configuration # BTMM_CLEANUP() { rm -f .btmmfifo .btmminfo .digsync } BTMM_SETUP() { BTMM_CLEANUP mkfifo .btmmfifo BTMMPORT=40000 while nc -6z ::1 "${PORT}" > /dev/null 2>&1 do BTMMPORT=$((PORT + 1)) done } BTMM_CHECKMACDOTCOM() { TAIL=`echo "${1}" | cut -d. -f2-` if [ "${TAIL}" = "members.mac.com" ]; then return 0 fi return 1 } # get DNS info # params: QUERYNAME QUERYTYPE BTMM_DIG() { rm -f .digsync nc -6 -l "${BTMMPORT}" < .btmmfifo \ | openssl s_client -connect "${HOSTPORT}" -quiet > .btmmfifo 2>.digsync & N_RETRY=0 while [ $N_RETRY -lt 50 -a ! -s .digsync ] do N_RETRY=$((N_RETRY + 1)) sleep 0.1 done dig @::1 -p "${BTMMPORT}" \ -y "${TSIG}" \ +short \ +tcp \ "${1}" "${2}" 2>/dev/null wait %1 } # get the unique identifier used to lookup the keychain item for a zone # params: ZONE BTMM_UNIQUEIDFROMZONE() { BTMM_CHECKMACDOTCOM "${1}" if [ $? -eq 0 ]; then echo "dns:${1}" else echo "btmmdns:${1}" fi } # get hostname, port, TSIG name and TSIG data from keychain # params: UNIQUEID BTMM_GETINFO() { ${PRIV} security find-generic-password \ -s "${1}" \ -g /Library/Keychains/System.keychain > .btmminfo 2>/dev/null ${PRIV} security find-generic-password \ -s "${1}" \ -g /Library/Keychains/System.keychain \ 2>&1 \ | sed -n 's/^password: \"\(.*\)\"$/\1/p' } # params: ZONE BTMM_URLISH() { BTMM_CHECKMACDOTCOM "${1}" if [ $? -eq 0 ]; then echo "pm-members.mac.com.:443" else cat .btmminfo | sed -n 's/.*0x00000007 =\"\(.*\)\"/\1/p' fi } BTMM_RELAYINFO() { BTMM_CHECKMACDOTCOM "${1}" if [ $? -eq 0 ]; then return fi SECRET=`BTMM_GETINFO "btmmrelay:${1}"` if [ -z "${SECRET}" ]; then echo " No Relay keychain item." >> btmm return fi if [ `echo "${SECRET}" | wc -l` -ne 1 ]; then echo " More than one Relay keychain item." >> btmm return fi URLISH=`BTMM_URLISH "${DOMAIN}"` ACCOUNT=`cat .btmminfo | sed -n 's/.*\"acct\"=\"\(.*\)\"/\1/p'` KEYHASH="[SHA-1:`echo ${SECRET} | openssl sha1`]" echo " RHP: ${URLISH}" >> btmm echo " RAC: ${ACCOUNT}" >> btmm echo " RKY: ${KEYHASH}" >> btmm } BTMM_REPORTZONE() { DOMAIN="${1}" echo >> btmm echo "${DOMAIN}" >> btmm DNSID=`BTMM_UNIQUEIDFROMZONE "${DOMAIN}"` SECRET=`BTMM_GETINFO "${DNSID}"` if [ -z "${SECRET}" ]; then echo " No DNS keychain item." >> btmm return fi if [ `echo "${SECRET}" | wc -l` -ne 1 ]; then echo " More than one DNS keychain item." >> btmm return fi URLISH=`BTMM_URLISH "${DOMAIN}"` HOSTPORT=`echo "${URLISH}" | cut -d@ -f2` ACCOUNT=`cat .btmminfo | sed -n 's/.*\"acct\"=\"\(.*\)\"/\1/p'` TSIG="${ACCOUNT}:${SECRET}" KEYHASH="[SHA-1:`echo ${SECRET} | openssl sha1`]" echo "" >> btmm echo " DHP: ${URLISH}" >> btmm echo " DAC: ${ACCOUNT}" >> btmm echo " DKY: ${KEYHASH}" >> btmm BTMM_RELAYINFO "${DOMAIN}" for TYPE in \ _afpovertcp._tcp \ _airport._tcp \ _adisk._tcp \ _http._tcp \ _rfb._tcp \ _smb._tcp \ _ssh._tcp do BTMM_DIG "${TYPE}.${DOMAIN}" ptr \ | while read -r REG do echo "" >> btmm /bin/echo " ${REG}" >> btmm echo "" >> btmm INF_Q=`/bin/echo "${REG}" | sed -e "s/${TYPE}/_device-info._tcp/"` INF=`BTMM_DIG "${INF_Q}" txt` echo " INF: ${INF}" >> btmm SRV=`BTMM_DIG ${REG} srv` SRV1=`/bin/echo "${SRV}" | head -1` echo " SRV: ${SRV1}" >> btmm SRV2=`/bin/echo "${SRV}" | tail +2` if [ -n "${SRV2}" ]; then SRV="${SRV1}" /bin/echo "${SRV2}" \ | sed -e 's/^/ *****: /' >> btmm fi TXT=`BTMM_DIG ${REG} txt` TXT1=`/bin/echo "${TXT}" | head -1` echo " TXT: ${TXT1}" >> btmm TXT2=`/bin/echo "${TXT}" | tail +2` if [ -n "${TXT2}" ]; then /bin/echo "${TXT2}" \ | sed -e 's/^/ *****: /' >> btmm fi HOST=`/bin/echo "${SRV}" | cut -d ' ' -f 4-` if [ -n "${HOST}" ]; then V4=`BTMM_DIG ${HOST} a` V6=`BTMM_DIG ${HOST} aaaa` KRB=`BTMM_DIG _kerberos.${HOST} txt` TUN=`BTMM_DIG _autotunnel._udp.${HOST} srv` AT6=`BTMM_DIG _autotunnel6.${HOST} aaaa` else V4="" V6="" KRB="" TUN="" AT6="" fi if [ -n "${V4}" ]; then echo " v4: ${V4}" >> btmm fi if [ -n "${V6}" ]; then echo " v6: ${V6}" >> btmm fi if [ -n "${KRB}" ]; then echo " KRB: ${KRB}" >> btmm fi if [ -n "${TUN}" ]; then echo " TUN: ${TUN}" >> btmm HOST=`/bin/echo "${TUN}" | cut -d ' ' -f 4-` if [ -n "${HOST}" ]; then V4=`BTMM_DIG ${HOST} a` V6=`BTMM_DIG ${HOST} aaaa` fi if [ -n "${V4}" ]; then echo " v4: ${V4}" >> btmm fi if [ -n "${V6}" ]; then echo " v6: ${V6}" >> btmm fi fi if [ -n "${AT6}" ]; then echo " AT6: ${AT6}" >> btmm fi done done } BTMM_SETUP scutil <<_END_OF_INPUT \ | sed -n 's@.* : *\(.*\)$@\1@p' \ | sort \ | while read DOMAIN open show Setup:/Network/BackToMyMac quit _END_OF_INPUT do BTMM_REPORTZONE "$DOMAIN" done BTMM_CLEANUP # # collect crash reports # for daemon in \ bootpd \ configd \ eapolclient \ mDNSResponder \ mDNSResponderHelper \ awacsd \ pppd \ racoon \ socketfilterfw \ SCHelper \ SCMonitor \ do /bin/ls -1 /Library/Logs/DiagnosticReports/${daemon}_*.crash \ /Library/Logs/CrashReporter/${daemon}_*.crash \ 2>/dev/null \ | while read log do if [ -f "${log}" ]; then b="`basename ${log}`" ${PRIV} cat "${log}" > "${b}" 2>&1 fi done done # # system usage statistics # echo "#" > system-statistics echo "# uptime" >> system-statistics echo "#" >> system-statistics uptime >> system-statistics 2>&1 echo "#" >> system-statistics echo "# sysctl -a" >> system-statistics echo "#" >> system-statistics sysctl -a >> system-statistics 2>&1 echo "#" >> system-statistics echo "# zprint" >> system-statistics echo "#" >> system-statistics zprint >> system-statistics 2>&1 echo "#" >> system-statistics echo "# top -l5 -s2" >> system-statistics echo "#" >> system-statistics echo "" echo "Please wait, collecting statistics" echo "" top -s 2 -l 5 >> system-statistics 2>&1 # # collect everything into a single archive # cd "${WORKDIR}/.." if [ -x /usr/bin/tar ]; then tar -c ${GZ_OPT} -f "${ARCHIVE}" "${OUT}" else pax -w ${GZ_OPT} -f "${ARCHIVE}" "${OUT}" fi rm -rf "${WORKDIR}" if [ ${UID} -eq 0 ]; then if [ -n "${SUDO_UID}" -a -n "${SUDO_GID}" ]; then if [ ${UID} -ne ${SUDO_UID} ]; then chown ${SUDO_UID}:${SUDO_GID} "${ARCHIVE}" fi fi fi echo "Network data collected to \"${ARCHIVE}\"" # # if requested, generate a crash report # if [ "${OUTDIR}" = "/Library/Logs/CrashReporter/SystemConfiguration" -a "${1}" = "CRASH" ]; then kill -ABRT $$ fi