#!/bin/sh
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}"
echo ""
echo "Please wait, collecting information and statistics"
echo ""
ps axlww > ps 2>&1
ifconfig -a -L -b -m -r -v > ifconfig 2>&1
if [ $? -ne 0 ]; then
ifconfig -a > ifconfig 2>&1
fi
netstat -n -r -a -l > netstat 2>&1
for if in `ifconfig -l`
do
case ${if} in
lo* ) ;;
en* ) ipconfig getpacket ${if} > ipconfig-${if} 2>&1
;;
esac
done
if [ -x /System/Library/PrivateFrameworks/Apple80211.framework/Resources/airport ]; then
/System/Library/PrivateFrameworks/Apple80211.framework/Resources/airport --getinfo \
> airport 2>&1
fi
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
ioreg -i -l -w 0 > ioreg 2>&1
ioreg -i -l -p IODeviceTree -w 0 >> ioreg 2>&1
echo "#" > pmset
echo "# pmset -g" >> pmset
echo "#" >> pmset
pmset -g >> pmset 2>&1
echo "#" >> pmset
echo "# pmset -g ps" >> pmset
echo "#" >> pmset
pmset -g ps >> pmset 2>&1
echo "#" >> pmset
echo "# pmset -g assertions" >> pmset
echo "#" >> pmset
pmset -g assertions >> pmset 2>&1
echo "#" >> pmset
echo "# pmset -g log" >> pmset
echo "#" >> pmset
pmset -g log | tail -n 25000 >> pmset 2>&1
hostname > hostname 2>&1
hostinfo > hostinfo 2>&1
if [ -e /etc/hostconfig ]; then
cat /etc/hostconfig > etc.hostconfig 2>&1
fi
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
scutil -d -v --proxy > proxy-configuration 2>&1
scutil --nwi > network-information 2>&1
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.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
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>/dev/null
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>/dev/null
fi
${PRIV} scutil -p --snapshot
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
if [ -f /var/tmp/configd-reachability ]; then
cat /var/tmp/configd-reachability > configd-reachability 2>&1
fi
scutil -d -v -r www.apple.com "" no-server > 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
mount > mounted-filesystems 2>&1
if [ -x /usr/bin/killall ]; then
${PRIV} killall -INFO mDNSResponder
${PRIV} killall -INFO networkd
sleep 15
fi
if [ -x /usr/sbin/awacsd -a -x /usr/bin/killall ]; then
${PRIV} killall -INFO awacsd 2>/dev/null
sleep 1
fi
if [ -x /usr/bin/syslog ]; then
${PRIV} syslog | tail -n 25000 > syslog
${PRIV} syslog -k Facility kern | tail -n 25000 > kernel
if [ -d /var/log/DiagnosticMessages ]; then
${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
if [ -f /var/log/com.apple.IPConfiguration.bootp ]; then
${PRIV} tail -n 2000 /var/log/com.apple.IPConfiguration.bootp \
> com.apple.IPConfiguration.bootp
fi
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
if [ -f /var/log/appfirewall.log ]; then
${PRIV} tail -n 2000 /var/log/appfirewall.log > appfirewall.log
fi
if [ -x /usr/sbin/kextstat ]; then
kextstat > kextstat 2>&1
elif [ -x /usr/sbin/kmodstat ]; then
kmodstat > kmodstat 2>&1
fi
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
echo "#" >> network-statistics
echo "# netstat -g -n -s" >> network-statistics
echo "#" >> network-statistics
netstat -g -n -s >> 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
for if in `ifconfig -l`
do
echo "#" >> network-statistics
echo "# ndp -i ${if}" >> network-statistics
echo "#" >> network-statistics
ndp -i ${if} >> network-statistics 2>&1
done
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/ip6fw ]; then
echo "#" >> network-statistics
echo "# ip6fw -at show" >> network-statistics
echo "#" >> network-statistics
${PRIV} ip6fw -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 `${PRIV} pfctl -s Anchors -v 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
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
echo "#" > ipsec
echo "# setkey -D" >> ipsec
echo "#" >> ipsec
${PRIV} setkey -D \
| perl -M'Digest::MD5 qw(md5_hex)' -l -n -e '
if (/^(\s+[AE]:\s+\S+\s+)"?(.*)"?\s*$/) {
printf "%s[MD5:%s]%s\n", $1, md5_hex($2 . "\n"), $3;
} 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 -M'Digest::MD5 qw(md5_hex)' -l -n -e '
if (/^(\s+shared_secret\s+use\s+)"?([^\s;"]+)"?(.*)/) {
printf "%s[MD5:%s]%s\n", $1, md5_hex($2 . "\n"), $3;
} else {
printf "%s\n", $_;
}
' >> ipsec
done
#
# Kerberos configuration
#
if [ -x /usr/bin/klist ]; then
echo " 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_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
}
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
}
BTMM_UNIQUEIDFROMZONE()
{
BTMM_CHECKMACDOTCOM "${1}"
if [ $? -eq 0 ]; then
echo "dns:${1}"
else
echo "btmmdns:${1}"
fi
}
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 > /dev/null \
| 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 <blob>=\"\(.*\)\"/\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\"<blob>=\"\(.*\)\"/\1/p'`
KEYHASH="`perl -M'Digest::SHA1 qw(sha1_hex)' -l -e '
printf "[SHA1:%s]\n", sha1_hex($ARGV[0] . "\n");
' ${SECRET}`"
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\"<blob>=\"\(.*\)\"/\1/p'`
TSIG="${ACCOUNT}:${SECRET}"
KEYHASH="`perl -M'Digest::SHA1 qw(sha1_hex)' -l -e '
printf "[SHA1:%s]\n", sha1_hex($ARGV[0] . "\n");
' ${SECRET}`"
echo "" >> btmm
echo " DHP: ${URLISH}" >> btmm
echo " DAC: ${ACCOUNT}" >> btmm
echo " DKY: ${KEYHASH}" >> btmm
BTMM_RELAYINFO "${DOMAIN}"
REACHHOST=`echo "${HOSTPORT}" | cut -d: -f1`
STATUSES=`scutil -r "${REACHHOST}"`
for REACHSTATUS in `echo ${STATUSES} | tr -d ' ' | tr ',' ' '`; do
if [ "$REACHSTATUS" == "NotReachable" ] \
|| [ "$REACHSTATUS" == "ConnectionRequired" ]; then
echo " Skipping DNS queries, no connectivity" >> btmm
return
fi
done
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 \
InternetSharing \
SCHelper \
SCMonitor \
do
/bin/ls -1 /Library/Logs/DiagnosticReports/${daemon}_*.crash \
/Library/Logs/CrashReporter/${daemon}_*.crash \
/Library/Logs/CrashReporter/${daemon}_*.plist \
2>/dev/null \
| while read log
do
if [ -f "${log}" ]; then
b="`basename ${log}`"
${PRIV} cat "${log}" > "${b}" 2>&1
fi
done
done
#
# system profiler
#
if [ -x /usr/sbin/system_profiler ]; then
system_profiler -xml SPEthernetDataType \
SPFibreChannelDataType \
SPFireWireDataType \
SPFirewallDataType \
SPModemDataType \
SPNetworkDataType \
SPThunderboltDataType \
SPWWANDataType \
SPAirPortDataType > system_profiler.spx 2>&1
fi
#
# system usage statistics
#
echo "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
top -s 2 -l 5 >> system-statistics 2>&1
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 [ "${OUTDIR}" = "/Library/Logs/CrashReporter/SystemConfiguration" -a "${1}" = "CRASH" ]; then
kill -ABRT $$
fi