summaryrefslogtreecommitdiffstats
path: root/mDNSResponder/mDNSMacOSX/Scripts/bonjour-mcast-diagnose
diff options
context:
space:
mode:
Diffstat (limited to 'mDNSResponder/mDNSMacOSX/Scripts/bonjour-mcast-diagnose')
-rwxr-xr-xmDNSResponder/mDNSMacOSX/Scripts/bonjour-mcast-diagnose380
1 files changed, 380 insertions, 0 deletions
diff --git a/mDNSResponder/mDNSMacOSX/Scripts/bonjour-mcast-diagnose b/mDNSResponder/mDNSMacOSX/Scripts/bonjour-mcast-diagnose
new file mode 100755
index 00000000..bda53ba8
--- /dev/null
+++ b/mDNSResponder/mDNSMacOSX/Scripts/bonjour-mcast-diagnose
@@ -0,0 +1,380 @@
+#! /bin/bash
+#
+# Copyright (c) 2017-2018 Apple Inc. All rights reserved.
+#
+# This script is currently for Apple Internal use only.
+#
+
+version=1.4
+script=${BASH_SOURCE[0]}
+dnssdutil=${dnssdutil:-dnssdutil}
+
+#============================================================================================================================
+# PrintUsage
+#============================================================================================================================
+
+PrintUsage()
+{
+ echo ""
+ echo "Usage: $( basename "${script}" ) [options]"
+ echo ""
+ echo "Options:"
+ echo " -V Display version of this script and exit."
+ echo ""
+}
+
+#============================================================================================================================
+# LogOut
+#============================================================================================================================
+
+LogOut()
+{
+ echo "$( date '+%Y-%m-%d %H:%M:%S%z' ): $*"
+}
+
+#============================================================================================================================
+# LogMsg
+#============================================================================================================================
+
+LogMsg()
+{
+ echo "$*"
+ if [ -d "${workPath}" ]; then
+ LogOut "$*" >> "${workPath}/log.txt"
+ fi
+}
+
+#============================================================================================================================
+# ErrQuit
+#============================================================================================================================
+
+ErrQuit()
+{
+ echo "error: $*"
+ exit 1
+}
+
+#============================================================================================================================
+# SignalHandler
+#============================================================================================================================
+
+SignalHandler()
+{
+ LogMsg "Exiting due to signal."
+ trap '' SIGINT SIGTERM
+ pkill -TERM -P $$
+ wait
+ exit 2
+}
+
+#============================================================================================================================
+# ExitHandler
+#============================================================================================================================
+
+ExitHandler()
+{
+ if [ -d "${tempPath}" ]; then
+ rm -fr "${tempPath}"
+ fi
+}
+
+#============================================================================================================================
+# RunNetStat
+#============================================================================================================================
+
+RunNetStat()
+{
+ LogMsg "Running netstat -g -n -s"
+ netstat -g -n -s &> "${workPath}/netstat-g-n-s.txt"
+}
+
+#============================================================================================================================
+# StartPacketCapture
+#============================================================================================================================
+
+StartPacketCapture()
+{
+ LogMsg "Starting tcpdump."
+ tcpdump -n -w "${workPath}/tcpdump.pcapng" &> "${workPath}/tcpdump.txt" &
+ tcpdumpPID=$!
+}
+
+#============================================================================================================================
+# SaveExistingPacketCaptures
+#============================================================================================================================
+
+SaveExistingPacketCaptures()
+{
+ LogMsg "Saving existing mDNS packet captures."
+ mkdir "${workPath}/pcaps"
+ for file in /tmp/mdns-tcpdump.pcapng*; do
+ [ -e "${file}" ] || continue
+ baseName=$( sed -E 's/^mdns-tcpdump.pcapng([0-9]+)$/mdns-tcpdump-\1.pcapng/' <<< "$( basename ${file} )" )
+ gzip < ${file} > "${workPath}/pcaps/${baseName}.gz"
+ done
+}
+
+#============================================================================================================================
+# StopPacketCapture
+#============================================================================================================================
+
+StopPacketCapture()
+{
+ LogMsg "Stopping tcpdump."
+ kill -TERM ${tcpdumpPID}
+}
+
+#============================================================================================================================
+# RunInterfaceMulticastTests
+#============================================================================================================================
+
+RunInterfaceMulticastTests()
+{
+ local ifname="$1"
+ local allHostsV4=224.0.0.1
+ local allHostsV6=ff02::1
+ local mDNSV4=224.0.0.251
+ local mDNSV6=ff02::fb
+ local serviceList=( $( "${dnssdutil}" queryrecord -i "${ifname}" -A -t ptr -n _services._dns-sd._udp.local -l 6 | sed -E -n 's/.*(_.*_(tcp|udp)\.local\.)$/\1/p' | sort -u ) )
+ local log="${workPath}/mcast-test-log-${ifname}.txt"
+
+ LogOut "List of services: ${serviceList[*]}" >> "${log}"
+ # Ping All Hosts IPv4 multicast address.
+
+ local routeOutput=$( route -n get -ifscope ${ifname} "${allHostsV4}" 2> /dev/null )
+ if [ -n "${routeOutput}" ]; then
+ LogOut "Pinging "${allHostsV4}" on interface ${ifname}." >> "${log}"
+ ping -t 5 -b ${ifname} "${allHostsV4}" &> "${workPath}/ping-all-hosts-${ifname}.txt"
+ else
+ LogOut "No route to "${allHostsV4}" on interface ${ifname}." >> "${log}"
+ fi
+
+ # Ping mDNS IPv4 multicast address.
+
+ routeOutput=$( route -n get -ifscope ${ifname} "${mDNSV4}" 2> /dev/null )
+ if [ -n "${routeOutput}" ]; then
+ LogOut "Pinging "${mDNSV4}" on interface ${ifname}." >> "${log}"
+ ping -t 5 -b ${ifname} "${mDNSV4}" &> "${workPath}/ping-mDNS-${ifname}.txt"
+ else
+ LogOut "No route to "${mDNSV4}" on interface ${ifname}." >> "${log}"
+ fi
+
+ # Ping All Hosts IPv6 multicast address.
+
+ routeOutput=$( route -n get -ifscope ${ifname} -inet6 "${allHostsV6}" 2> /dev/null )
+ if [ -n "${routeOutput}" ]; then
+ LogOut "Pinging "${allHostsV6}" on interface ${ifname}." >> "${log}"
+ ping6 -c 6 -I ${ifname} "${allHostsV6}" &> "${workPath}/ping6-all-hosts-${ifname}.txt"
+ else
+ LogOut "No route to "${allHostsV6}" on interface ${ifname}." >> "${log}"
+ fi
+
+ # Ping mDNS IPv6 multicast address.
+
+ routeOutput=$( route -n get -ifscope ${ifname} -inet6 "${mDNSV6}" 2> /dev/null )
+ if [ -n "${routeOutput}" ]; then
+ LogOut "Pinging "${mDNSV6}" on interface ${ifname}." >> "${log}"
+ ping6 -c 6 -I ${ifname} "${mDNSV6}" &> "${workPath}/ping6-mDNS-${ifname}.txt"
+ else
+ LogOut "No route to "${mDNSV6}" on interface ${ifname}." >> "${log}"
+ fi
+
+ # Send mDNS queries for services.
+
+ for service in "${serviceList[@]}"; do
+ LogOut "Sending mDNS queries for "${service}" on interface ${ifname}." >> "${log}"
+ for(( i = 1; i <= 3; ++i )); do
+ printf "\n"
+ "${dnssdutil}" mdnsquery -i "${ifname}" -n "${service}" -t ptr -r 2
+ printf "\n"
+ "${dnssdutil}" mdnsquery -i "${ifname}" -n "${service}" -t ptr -r 1 --QU -p 5353
+ printf "\n"
+ done >> "${workPath}/mdnsquery-${ifname}.txt" 2>&1
+ done
+}
+
+#============================================================================================================================
+# RunMulticastTests
+#============================================================================================================================
+
+RunMulticastTests()
+{
+ local interfaces=( $( ifconfig -l -u ) )
+ local skipPrefixes=( ap awdl bridge ipsec lo p2p pdp_ip pktap UDC utun )
+ local ifname=""
+ local pid=""
+ local pids=()
+
+ LogMsg "List of interfaces: ${interfaces[*]}"
+ for ifname in "${interfaces[@]}"; do
+ local skip=false
+ for prefix in ${skipPrefixes[@]}; do
+ if [[ ${ifname} =~ ^${prefix}[0-9]*$ ]]; then
+ skip=true
+ break
+ fi
+ done
+
+ if [ "${skip}" != "true" ]; then
+ ifconfig ${ifname} | grep -q inet
+ if [ $? -ne 0 ]; then
+ skip=true
+ fi
+ fi
+
+ if [ "${skip}" == "true" ]; then
+ continue
+ fi
+
+ LogMsg "Starting interface multicast tests for ${ifname}."
+ RunInterfaceMulticastTests "${ifname}" & pids+=($!)
+ done
+
+ LogMsg "Waiting for interface multicast tests to complete..."
+ for pid in "${pids[@]}"; do
+ wait "${pid}"
+ done
+ LogMsg "All interface multicast tests completed."
+}
+
+#============================================================================================================================
+# RunBrowseTest
+#============================================================================================================================
+
+RunBrowseTest()
+{
+ LogMsg "Running dnssdutil browseAll command."
+ "${dnssdutil}" browseAll -A -d local -b 10 -c 10 &> "${workPath}/browseAll.txt"
+}
+
+#============================================================================================================================
+# IsMacOS
+#============================================================================================================================
+
+IsMacOS()
+{
+ [[ $( sw_vers -productName ) =~ ^Mac\ OS ]]
+}
+
+#============================================================================================================================
+# ArchiveLogs
+#============================================================================================================================
+
+ArchiveLogs()
+{
+ local workdir=$( basename "${workPath}" )
+ local archivePath="${dstPath}/${workdir}.tar.gz"
+
+ LogMsg "Archiving logs."
+ echo "---"
+ tar -C "${tempPath}" -czf "${archivePath}" "${workdir}"
+ if [ -e "${archivePath}" ]; then
+ echo "Created log archive at ${archivePath}"
+ echo "*** Please run sysdiagnose NOW. ***"
+ echo "Attach both the log archive and the sysdiagnose archive to the radar."
+ if IsMacOS; then
+ open "${dstPath}"
+ fi
+ else
+ echo "Failed to create archive at ${archivePath}."
+ fi
+ echo "---"
+}
+
+#============================================================================================================================
+# CreateWorkDirName
+#============================================================================================================================
+
+CreateWorkDirName()
+{
+ local suffix=""
+ local productName=$( sw_vers -productName )
+ if [ -n "${productName}" ]; then
+ suffix+="_${productName}"
+ fi
+
+ local model=""
+ if IsMacOS; then
+ model=$( sysctl -n hw.model )
+ model=${model//,/-}
+ else
+ model=$( gestalt_query -undecorated DeviceName )
+ fi
+ if [ -n "${model}" ]; then
+ suffix+="_${model}"
+ fi
+
+ local buildVersion=$( sw_vers -buildVersion )
+ if [ -n "${buildVersion}" ]; then
+ suffix+="_${buildVersion}"
+ fi
+
+ suffix=${suffix//[^A-Za-z0-9._-]/_}
+
+ printf "bonjour-mcast-diags_$( date '+%Y.%m.%d_%H-%M-%S%z' )${suffix}"
+}
+
+#============================================================================================================================
+# main
+#============================================================================================================================
+
+main()
+{
+ while getopts ":hV" option; do
+ case "${option}" in
+ h)
+ PrintUsage
+ exit 0
+ ;;
+ V)
+ echo "$( basename "${script}" ) version ${version}"
+ exit 0
+ ;;
+ :)
+ ErrQuit "option '${OPTARG}' requires an argument."
+ ;;
+ *)
+ ErrQuit "unknown option '${OPTARG}'."
+ ;;
+ esac
+ done
+
+ [ "${OPTIND}" -gt "$#" ] || ErrQuit "unexpected argument \""${!OPTIND}"\"."
+
+ if IsMacOS; then
+ if [ "${EUID}" -ne 0 ]; then
+ echo "Re-launching with sudo"
+ exec sudo ${script}
+ fi
+ dstPath=/var/tmp
+ else
+ [ "${EUID}" -eq 0 ] || ErrQuit "$( basename "${script}" ) needs to be run as root."
+ dstPath=/var/mobile/Library/Logs/CrashReporter
+ fi
+
+ tempPath=$( mktemp -d -q ) || ErrQuit "Failed to make temp directory."
+ workPath="${tempPath}/$( CreateWorkDirName )"
+ mkdir "${workPath}" || ErrQuit "Failed to make work directory."
+
+ trap SignalHandler SIGINT SIGTERM
+ trap ExitHandler EXIT
+
+ LogMsg "About: $( basename "${script}" ) version ${version} ($( md5 -q ${script} ))."
+ if [ "${dnssdutil}" != "dnssdutil" ]; then
+ if [ -x "$( which "${dnssdutil}" )" ]; then
+ LogMsg "Using $( "${dnssdutil}" -V ) at $( which "${dnssdutil}" )."
+ else
+ LogMsg "WARNING: dnssdutil (${dnssdutil}) isn't an executable."
+ fi
+ fi
+
+ RunNetStat
+ StartPacketCapture
+ SaveExistingPacketCaptures
+ RunBrowseTest
+ RunMulticastTests
+ StopPacketCapture
+ ArchiveLogs
+}
+
+main "$@"