3 # Copyright (c) 2017-2018 Apple Inc. All rights reserved.
5 # This script is currently for Apple Internal use only.
9 script=${BASH_SOURCE[0]}
10 dnssdutil
=${dnssdutil:-dnssdutil}
12 #============================================================================================================================
14 #============================================================================================================================
19 echo "Usage: $( basename "${script}" ) [options]"
22 echo " -V Display version of this script and exit."
26 #============================================================================================================================
28 #============================================================================================================================
32 echo "$( date '+%Y-%m-%d %H:%M:%S%z' ): $*"
35 #============================================================================================================================
37 #============================================================================================================================
42 if [ -d "${workPath}" ]; then
43 LogOut
"$*" >> "${workPath}/log.txt"
47 #============================================================================================================================
49 #============================================================================================================================
57 #============================================================================================================================
59 #============================================================================================================================
63 LogMsg
"Exiting due to signal."
64 trap '' SIGINT SIGTERM
70 #============================================================================================================================
72 #============================================================================================================================
76 if [ -d "${tempPath}" ]; then
81 #============================================================================================================================
83 #============================================================================================================================
87 LogMsg
"Running netstat -g -n -s"
88 netstat
-g -n -s &> "${workPath}/netstat-g-n-s.txt"
91 #============================================================================================================================
93 #============================================================================================================================
97 LogMsg
"Starting tcpdump."
98 tcpdump
-n -w "${workPath}/tcpdump.pcapng" &> "${workPath}/tcpdump.txt" &
102 #============================================================================================================================
103 # SaveExistingPacketCaptures
104 #============================================================================================================================
106 SaveExistingPacketCaptures
()
108 LogMsg
"Saving existing mDNS packet captures."
109 mkdir "${workPath}/pcaps"
110 for file in /tmp
/mdns
-tcpdump.pcapng
*; do
111 [ -e "${file}" ] || continue
112 baseName
=$( sed -E 's/^mdns-tcpdump.pcapng([0-9]+)$
/mdns
-tcpdump-\
1.pcapng
/' <<< "$( basename ${file} )" )
113 gzip < ${file} > "${workPath}/pcaps/${baseName}.gz"
117 #============================================================================================================================
119 #============================================================================================================================
123 LogMsg "Stopping tcpdump."
124 kill -TERM ${tcpdumpPID}
127 #============================================================================================================================
128 # RunInterfaceMulticastTests
129 #============================================================================================================================
131 RunInterfaceMulticastTests()
134 local allHostsV4=224.0.0.1
135 local allHostsV6=ff02::1
136 local mDNSV4=224.0.0.251
137 local mDNSV6=ff02::fb
138 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 ) )
139 local log
="${workPath}/mcast-test-log-${ifname}.txt"
141 LogOut
"List of services: ${serviceList[*]}" >> "${log}"
142 # Ping All Hosts IPv4 multicast address.
144 local routeOutput
=$( route -n get -ifscope ${ifname} "${allHostsV4}" 2> /dev/null )
145 if [ -n "${routeOutput}" ]; then
146 LogOut
"Pinging "${allHostsV4}" on interface ${ifname}." >> "${log}"
147 ping -t 5 -b ${ifname} "${allHostsV4}" &> "${workPath}/ping-all-hosts-${ifname}.txt"
149 LogOut
"No route to "${allHostsV4}" on interface ${ifname}." >> "${log}"
152 # Ping mDNS IPv4 multicast address.
154 routeOutput
=$( route -n get -ifscope ${ifname} "${mDNSV4}" 2> /dev/null )
155 if [ -n "${routeOutput}" ]; then
156 LogOut
"Pinging "${mDNSV4}" on interface ${ifname}." >> "${log}"
157 ping -t 5 -b ${ifname} "${mDNSV4}" &> "${workPath}/ping-mDNS-${ifname}.txt"
159 LogOut
"No route to "${mDNSV4}" on interface ${ifname}." >> "${log}"
162 # Ping All Hosts IPv6 multicast address.
164 routeOutput
=$( route -n get -ifscope ${ifname} -inet6 "${allHostsV6}" 2> /dev/null )
165 if [ -n "${routeOutput}" ]; then
166 LogOut
"Pinging "${allHostsV6}" on interface ${ifname}." >> "${log}"
167 ping6
-c 6 -I ${ifname} "${allHostsV6}" &> "${workPath}/ping6-all-hosts-${ifname}.txt"
169 LogOut
"No route to "${allHostsV6}" on interface ${ifname}." >> "${log}"
172 # Ping mDNS IPv6 multicast address.
174 routeOutput
=$( route -n get -ifscope ${ifname} -inet6 "${mDNSV6}" 2> /dev/null )
175 if [ -n "${routeOutput}" ]; then
176 LogOut
"Pinging "${mDNSV6}" on interface ${ifname}." >> "${log}"
177 ping6
-c 6 -I ${ifname} "${mDNSV6}" &> "${workPath}/ping6-mDNS-${ifname}.txt"
179 LogOut
"No route to "${mDNSV6}" on interface ${ifname}." >> "${log}"
182 # Send mDNS queries for services.
184 for service
in "${serviceList[@]}"; do
185 LogOut
"Sending mDNS queries for "${service}" on interface ${ifname}." >> "${log}"
186 for(( i
= 1; i
<= 3; ++i
)); do
188 "${dnssdutil}" mdnsquery
-i "${ifname}" -n "${service}" -t ptr
-r 2
190 "${dnssdutil}" mdnsquery
-i "${ifname}" -n "${service}" -t ptr
-r 1 --QU -p 5353
192 done >> "${workPath}/mdnsquery-${ifname}.txt" 2>&1
196 #============================================================================================================================
198 #============================================================================================================================
202 local interfaces
=( $( ifconfig -l -u ) )
203 local skipPrefixes
=( ap awdl bridge ipsec lo p2p pdp_ip pktap UDC utun
)
208 LogMsg
"List of interfaces: ${interfaces[*]}"
209 for ifname
in "${interfaces[@]}"; do
211 for prefix
in ${skipPrefixes[@]}; do
212 if [[ ${ifname} =~ ^
${prefix}[0-9]*$
]]; then
218 if [ "${skip}" != "true" ]; then
219 ifconfig
${ifname} | grep -q inet
220 if [ $?
-ne 0 ]; then
225 if [ "${skip}" == "true" ]; then
229 LogMsg
"Starting interface multicast tests for ${ifname}."
230 RunInterfaceMulticastTests
"${ifname}" & pids
+=($
!)
233 LogMsg
"Waiting for interface multicast tests to complete..."
234 for pid
in "${pids[@]}"; do
237 LogMsg
"All interface multicast tests completed."
240 #============================================================================================================================
242 #============================================================================================================================
246 LogMsg
"Running dnssdutil browseAll command."
247 "${dnssdutil}" browseAll
-A -d local -b 10 -c 10 &> "${workPath}/browseAll.txt"
250 #============================================================================================================================
252 #============================================================================================================================
256 [[ $( sw_vers -productName ) =~ ^Mac\ OS
]]
259 #============================================================================================================================
261 #============================================================================================================================
265 local workdir
=$( basename "${workPath}" )
266 local archivePath
="${dstPath}/${workdir}.tar.gz"
268 LogMsg
"Archiving logs."
270 tar -C "${tempPath}" -czf "${archivePath}" "${workdir}"
271 if [ -e "${archivePath}" ]; then
272 echo "Created log archive at ${archivePath}"
273 echo "*** Please run sysdiagnose NOW. ***"
274 echo "Attach both the log archive and the sysdiagnose archive to the radar."
279 echo "Failed to create archive at ${archivePath}."
284 #============================================================================================================================
286 #============================================================================================================================
291 local productName
=$( sw_vers -productName )
292 if [ -n "${productName}" ]; then
293 suffix
+="_${productName}"
298 model
=$( sysctl -n hw.model )
301 model
=$( gestalt_query -undecorated DeviceName )
303 if [ -n "${model}" ]; then
307 local buildVersion
=$( sw_vers -buildVersion )
308 if [ -n "${buildVersion}" ]; then
309 suffix
+="_${buildVersion}"
312 suffix
=${suffix//[^A-Za-z0-9._-]/_}
314 printf "bonjour-mcast-diags_$( date '+%Y.%m.%d_%H-%M-%S%z' )${suffix}"
317 #============================================================================================================================
319 #============================================================================================================================
323 while getopts ":hV" option
; do
330 echo "$( basename "${script}" ) version ${version}"
334 ErrQuit
"option '${OPTARG}' requires an argument."
337 ErrQuit
"unknown option '${OPTARG}'."
342 [ "${OPTIND}" -gt "$#" ] || ErrQuit
"unexpected argument \""${!OPTIND}"\"."
345 if [ "${EUID}" -ne 0 ]; then
346 echo "Re-launching with sudo"
351 [ "${EUID}" -eq 0 ] || ErrQuit
"$( basename "${script}" ) needs to be run as root."
352 dstPath
=/var
/mobile
/Library
/Logs
/CrashReporter
355 tempPath
=$( mktemp -d -q ) || ErrQuit
"Failed to make temp directory."
356 workPath
="${tempPath}/$( CreateWorkDirName )"
357 mkdir "${workPath}" || ErrQuit
"Failed to make work directory."
359 trap SignalHandler SIGINT SIGTERM
360 trap ExitHandler EXIT
362 LogMsg
"About: $( basename "${script}" ) version ${version} ($( md5 -q ${script} ))."
363 if [ "${dnssdutil}" != "dnssdutil" ]; then
364 if [ -x "$( which "${dnssdutil}" )" ]; then
365 LogMsg
"Using $( "${dnssdutil}" -V ) at $( which "${dnssdutil}" )."
367 LogMsg
"WARNING: dnssdutil (${dnssdutil}) isn't an executable."
373 SaveExistingPacketCaptures