]>
Commit | Line | Data |
---|---|---|
9de8ab86 A |
1 | #!/bin/sh |
2 | ||
3 | # | |
4 | # Copyright © 2015 Apple Inc. | |
5 | # | |
6 | # get-network-info | |
7 | # | |
8 | # Collect network information. | |
9 | # | |
10 | ||
11 | PATH=/bin:/usr/bin:/sbin:/usr/sbin | |
12 | ||
13 | # __SETUP_ROUTINES_BEGIN__ | |
14 | ||
15 | process_opts () { | |
16 | ||
17 | for i in $ARGS | |
18 | do | |
19 | case "$i" | |
20 | in | |
21 | -s) | |
22 | COLLECT_SENSITIVE_INFO="Y" | |
23 | shift;; | |
24 | -c) | |
25 | COLLECT_CONFIGURATION_FILES="Y" | |
26 | shift;; | |
27 | --) | |
28 | shift;; | |
29 | *) | |
30 | REQUESTED_OUTDIR="${i}" | |
31 | shift;; | |
32 | esac | |
33 | done | |
34 | ||
35 | } | |
36 | ||
37 | set_root () { | |
38 | ||
39 | PRIV="" | |
40 | if [ ${EUID} -ne 0 ]; then | |
41 | PRIV="sudo" | |
42 | fi | |
43 | ||
44 | } | |
45 | ||
46 | # | |
47 | # Setup | |
48 | # | |
49 | setup () { | |
50 | ||
51 | set_root | |
52 | umask 077 | |
53 | cd "${REQUESTED_OUTDIR}" | |
54 | ||
55 | } | |
56 | ||
57 | # __SETUP_ROUTINES_END__ | |
58 | ||
59 | ||
60 | # __COMMAND_ROUTINES_BEGIN__ | |
61 | ||
62 | # note: the daemons dump to syslog so you need to wait a bit before | |
63 | # capturing the logs. | |
64 | collect_state_dump () { | |
65 | ||
66 | ${PRIV} /usr/bin/killall -INFO networkd 2>/dev/null | |
67 | ||
68 | sleep 1 & | |
69 | } | |
70 | ||
71 | collect_state_dump_sensitive () { | |
72 | ||
73 | ${PRIV} /usr/bin/killall -INFO mDNSResponder 2>/dev/null | |
74 | ||
75 | sleep 1 & | |
76 | ||
77 | } | |
78 | ||
79 | # | |
80 | # network interface configuration | |
81 | # | |
82 | run_ifconfig () { | |
83 | ||
84 | if [ ! -x /sbin/ifconfig ]; then | |
85 | return | |
86 | fi | |
87 | ||
88 | /sbin/ifconfig -a -L -b -m -r -v -v > ifconfig.txt 2>&1 | |
89 | if [ $? -ne 0 ]; then | |
90 | /sbin/ifconfig -a > ifconfig.txt 2>&1 | |
91 | fi | |
92 | ||
93 | } | |
94 | ||
95 | # | |
96 | # network route configuration and statistics | |
97 | # | |
98 | run_netstat () { | |
99 | ||
100 | if [ ! -x /usr/sbin/netstat ]; then | |
101 | return | |
102 | fi | |
103 | ||
104 | echo "#" > netstat.txt | |
105 | echo "# netstat -n -r -a -l" >> netstat.txt | |
106 | echo "#" >> netstat.txt | |
107 | /usr/sbin/netstat -n -r -a -l >> netstat.txt 2>&1 | |
108 | ||
109 | echo "#" >> netstat.txt | |
110 | echo "# netstat -A -a -l -n -v" >> netstat.txt | |
111 | echo "#" >> netstat.txt | |
112 | /usr/sbin/netstat -A -a -l -n -v >> netstat.txt 2>&1 | |
113 | ||
114 | echo "#" >> netstat.txt | |
115 | echo "# netstat -s" >> netstat.txt | |
116 | echo "#" >> netstat.txt | |
117 | /usr/sbin/netstat -s >> netstat.txt 2>&1 | |
118 | ||
119 | echo "#" >> netstat.txt | |
120 | echo "# netstat -mmm" >> netstat.txt | |
121 | echo "#" >> netstat.txt | |
122 | /usr/sbin/netstat -mmm >> netstat.txt 2>&1 | |
123 | ||
124 | echo "#" >> netstat.txt | |
125 | echo "# netstat -i -n -d" >> netstat.txt | |
126 | echo "#" >> netstat.txt | |
127 | /usr/sbin/netstat -i -n -d >> netstat.txt 2>&1 | |
128 | ||
129 | echo "#" >> netstat.txt | |
130 | echo "# netstat -i -x R" >> netstat.txt | |
131 | echo "#" >> netstat.txt | |
132 | /usr/sbin/netstat -i -x R >> netstat.txt 2>&1 | |
133 | ||
134 | echo "#" >> netstat.txt | |
135 | echo "# netstat -a -n -p mptcp" >> netstat.txt | |
136 | echo "#" >> netstat.txt | |
137 | /usr/sbin/netstat -anp mptcp >> netstat.txt 2>&1 | |
138 | ||
139 | echo "#" >> netstat.txt | |
140 | echo "# netstat -s -p mptcp" >> netstat.txt | |
141 | echo "#" >> netstat.txt | |
142 | /usr/sbin/netstat -s -p mptcp >> netstat.txt 2>&1 | |
143 | ||
144 | echo "#" >> netstat.txt | |
145 | echo "# netstat -g -n -s" >> netstat.txt | |
146 | echo "#" >> netstat.txt | |
147 | /usr/sbin/netstat -g -n -s >> netstat.txt 2>&1 | |
148 | ||
149 | if [ -x /sbin/ifconfig ]; then | |
150 | for if in ${IF_LIST} | |
151 | do | |
152 | IF_INFO=`/sbin/ifconfig -v ${if}` | |
153 | `echo $IF_INFO | grep -q TXSTART` | |
154 | if [ $? -eq 0 ]; then | |
155 | echo "#" >> netstat.txt | |
156 | echo "# netstat -qq -I ${if}" >> netstat.txt | |
157 | echo "#" >> netstat.txt | |
158 | /usr/sbin/netstat -qq -I ${if} >> netstat.txt 2>&1 | |
159 | fi | |
160 | `echo $IF_INFO | grep -q RXPOLL` | |
161 | if [ $? -eq 0 ]; then | |
162 | echo "#" >> netstat.txt | |
163 | echo "# netstat -Q -I ${if}" >> netstat.txt | |
164 | echo "#" >> netstat.txt | |
165 | /usr/sbin/netstat -Q -I ${if} >> netstat.txt 2>&1 | |
166 | fi | |
167 | done | |
168 | fi | |
169 | ||
170 | } | |
171 | ||
172 | run_ndp () { | |
173 | ||
174 | if [ ! -x /usr/sbin/ndp ]; then | |
175 | return | |
176 | fi | |
177 | ||
178 | echo "#" > ndp-info.txt | |
179 | echo "# ndp -n -a" >> ndp-info.txt | |
180 | echo "#" >> ndp-info.txt | |
181 | /usr/sbin/ndp -n -a >> ndp-info.txt 2>&1 | |
182 | ||
183 | echo "#" >> ndp-info.txt | |
184 | echo "# ndp -n -p" >> ndp-info.txt | |
185 | echo "#" >> ndp-info.txt | |
186 | /usr/sbin/ndp -n -p >> ndp-info.txt 2>&1 | |
187 | ||
188 | echo "#" >> ndp-info.txt | |
189 | echo "# ndp -n -r" >> ndp-info.txt | |
190 | echo "#" >> ndp-info.txt | |
191 | /usr/sbin/ndp -n -r >> ndp-info.txt 2>&1 | |
192 | ||
193 | if [ -x /sbin/ifconfig ]; then | |
194 | for if in ${IF_LIST} | |
195 | do | |
196 | echo "#" >> ndp-info.txt | |
197 | echo "# ndp -i ${if}" >> ndp-info.txt | |
198 | echo "#" >> ndp-info.txt | |
199 | /usr/sbin/ndp -i ${if} >> ndp-info.txt 2>&1 | |
200 | done | |
201 | fi | |
202 | ||
203 | } | |
204 | ||
205 | run_arp () { | |
206 | ||
207 | if [ ! -x /usr/sbin/arp ]; then | |
208 | return | |
209 | fi | |
210 | ||
211 | echo "#" > arp-info.txt | |
212 | echo "# arp -n -a" >> arp-info.txt | |
213 | echo "#" >> arp-info.txt | |
214 | /usr/sbin/arp -n -a >> arp-info.txt 2>&1 | |
215 | ||
216 | } | |
217 | ||
218 | # | |
219 | # DHCP configuration | |
220 | # | |
221 | run_ipconfig () { | |
222 | ||
223 | if [ ! -x /usr/sbin/ipconfig ]; then | |
224 | return | |
225 | fi | |
226 | ||
227 | for if in ${IF_LIST} | |
228 | do | |
229 | case ${if} in | |
230 | lo* ) ;; | |
231 | *) | |
232 | echo "#" >> ipconfig-info.txt | |
233 | echo "# INTERFACE ${if}" >> ipconfig-info.txt | |
234 | echo "#" >> ipconfig-info.txt | |
235 | ||
236 | echo "DHCPv4 information:" >> ipconfig-info.txt | |
237 | ||
238 | IPCONFIG_INFO=`/usr/sbin/ipconfig getpacket ${if}` | |
239 | if [ "${IPCONFIG_INFO}" != "" ]; then | |
240 | echo "${IPCONFIG_INFO}" >> ipconfig-info.txt | |
241 | else | |
242 | echo "not available" >> ipconfig-info.txt | |
243 | fi | |
244 | ||
245 | echo"" >> ipconfig-info.txt | |
246 | ||
247 | echo "DHCPv6 information:" >> ipconfig-info.txt | |
248 | ||
249 | IPCONFIG_INFO=`/usr/sbin/ipconfig getv6packet ${if}` | |
250 | if [ "${IPCONFIG_INFO}" != "" ]; then | |
251 | echo "${IPCONFIG_INFO}" >> ipconfig-info.txt | |
252 | else | |
253 | echo "not available" >> ipconfig-info.txt | |
254 | fi | |
255 | ||
256 | echo"" >> ipconfig-info.txt | |
257 | ;; | |
258 | esac | |
259 | done | |
260 | ||
261 | } | |
262 | ||
263 | # | |
264 | # IPsec configuration | |
265 | # | |
266 | run_setkey () { | |
267 | ||
268 | if [ ! -x /usr/sbin/setkey -o ! -x /usr/bin/perl ]; then | |
269 | return | |
270 | fi | |
271 | ||
272 | echo "#" > ipsec.txt | |
273 | echo "# setkey -D" >> ipsec.txt | |
274 | echo "#" >> ipsec.txt | |
275 | ${PRIV} /usr/sbin/setkey -D \ | |
276 | | /usr/bin/perl -l -n -e ' | |
277 | if (/^(\s+[AE]:\s+\S+\s+)"?(.*)"?\s*$/) { | |
278 | printf "%s[redacted]%s\n", $1, $3; | |
279 | } else { | |
280 | printf "%s\n", $_; | |
281 | } | |
282 | ' >> ipsec.txt | |
283 | ||
284 | echo "" >> ipsec.txt | |
285 | echo "#" >> ipsec.txt | |
286 | echo "# setkey -Pp -D" >> ipsec.txt | |
287 | echo "#" >> ipsec.txt | |
288 | ${PRIV} /usr/sbin/setkey -Pp -D >> ipsec.txt | |
289 | ||
290 | for CF in /var/run/racoon/*.conf | |
291 | do | |
292 | if [ ! -r "${CF}" ]; then | |
293 | continue | |
294 | fi | |
295 | ||
296 | echo "" >> ipsec.txt | |
297 | echo "#" >> ipsec.txt | |
298 | echo "# ${CF}" >> ipsec.txt | |
299 | echo "#" >> ipsec.txt | |
300 | ${PRIV} cat ${CF} \ | |
301 | | /usr/bin/perl -l -n -e ' | |
302 | if (/^(\s+shared_secret\s+use\s+)"?([^\s;"]+)"?(.*)/) { | |
303 | printf "%s[redacted]%s\n", $1, $3; | |
304 | } else { | |
305 | printf "%s\n", $_; | |
306 | } | |
307 | ' >> ipsec.txt | |
308 | done | |
309 | ||
310 | } | |
311 | ||
312 | # | |
313 | # Network preferences | |
314 | # | |
315 | collect_configuration_files () { | |
316 | ||
317 | for f in \ | |
318 | /Library/Preferences/com.apple.networkextension.plist \ | |
319 | /Library/Preferences/com.apple.networkextension.control.plist \ | |
320 | /Library/Preferences/com.apple.networkextension.necp.plist \ | |
321 | /Library/Preferences/SystemConfiguration/com.apple.nat.plist \ | |
322 | /Library/Preferences/SystemConfiguration/com.apple.RemoteAccessServers.plist \ | |
323 | /Library/Preferences/SystemConfiguration/com.apple.smb.server.plist \ | |
324 | /Library/Preferences/com.apple.mDNSResponder.plist \ | |
325 | /Library/Preferences/SystemConfiguration/NetworkInterfaces.plist \ | |
326 | /Library/Preferences/SystemConfiguration/preferences.plist \ | |
327 | ||
328 | do | |
329 | if [ -e "${f}" ]; then | |
330 | b="`basename ${f}`" | |
331 | cat "${f}" > "${b}" 2>&1 | |
332 | fi | |
333 | done | |
334 | ||
335 | if [ -e /etc/resolv.conf ]; then | |
336 | cat /etc/resolv.conf > etc-resolv-conf.txt 2>&1 | |
337 | fi | |
338 | if [ -e /var/run/resolv.conf ]; then | |
339 | cat /var/run/resolv.conf > var-run-resolv-conf.txt 2>&1 | |
340 | fi | |
341 | if [ -e /etc/resolver ]; then | |
342 | tar -c -H /etc/resolver > etc-resolver.tar 2>/dev/null | |
343 | fi | |
344 | } | |
345 | ||
346 | collect_vpn_logs () { | |
347 | ||
348 | for f in \ | |
349 | /var/log/vpnd.log \ | |
350 | /var/log/racoon.log \ | |
351 | ||
352 | do | |
353 | if [ -e "${f}" ]; then | |
354 | b="`basename ${f}`" | |
355 | ${PRIV} cat "${f}" > "${b}".txt 2>&1 | |
356 | fi | |
357 | done | |
358 | } | |
359 | ||
360 | # | |
361 | # Network, DNS, Proxy, Reachability, Cache information | |
362 | # | |
363 | run_scutil () { | |
364 | ||
365 | if [ ! -x /usr/sbin/scutil ]; then | |
366 | return | |
367 | fi | |
368 | ||
369 | echo "#" > network-information.txt | |
370 | echo "# scutil -d -v --nwi" >> network-information.txt | |
371 | echo "#" >> network-information.txt | |
372 | /usr/sbin/scutil -d -v --nwi >> network-information.txt 2>&1 | |
373 | for if in ${IF_LIST} | |
374 | do | |
375 | echo "" >> network-information.txt | |
376 | echo "#" >> network-information.txt | |
377 | echo "# scutil --nwi ${if}" >> network-information.txt | |
378 | echo "#" >> network-information.txt | |
379 | scutil --nwi ${if} >> network-information.txt 2>&1 | |
380 | done | |
381 | ||
382 | echo "#" > dns-configuration.txt | |
383 | echo "# scutil -d -v --dns" >> dns-configuration.txt | |
384 | echo "#" >> dns-configuration.txt | |
385 | /usr/sbin/scutil -d -v --dns >> dns-configuration.txt 2>&1 | |
386 | ||
387 | echo "#" > proxy-configuration.txt | |
388 | echo "# scutil -d -v --proxy" >> proxy-configuration.txt | |
389 | echo "#" >> proxy-configuration.txt | |
390 | /usr/sbin/scutil -d -v --proxy >> proxy-configuration.txt 2>&1 | |
391 | ||
392 | echo "#" > reachability-info.txt | |
393 | echo '# scutil -d -v -r www.apple.com' >> reachability-info.txt | |
394 | echo "#" >> reachability-info.txt | |
395 | /usr/sbin/scutil -d -v -r www.apple.com >> reachability-info.txt 2>&1 | |
396 | ||
397 | echo "#" >> reachability-info.txt | |
398 | echo '# scutil -d -v -r 0.0.0.0' >> reachability-info.txt | |
399 | echo "#" >> reachability-info.txt | |
400 | /usr/sbin/scutil -d -v -r 0.0.0.0 >> reachability-info.txt 2>&1 | |
401 | ||
402 | ${PRIV} /usr/sbin/scutil -p --snapshot | |
403 | if [ -f /var/tmp/configd-store.plist ]; then | |
404 | cat /var/tmp/configd-store.plist > configd-store.plist 2>&1 | |
405 | fi | |
406 | if [ -f /var/tmp/configd-pattern.plist ]; then | |
407 | cat /var/tmp/configd-pattern.plist > configd-pattern.plist 2>&1 | |
408 | fi | |
409 | if [ -f /var/tmp/configd-session.plist ]; then | |
410 | cat /var/tmp/configd-session.plist > configd-session.plist 2>&1 | |
411 | fi | |
412 | if [ -f /var/tmp/configd-state ]; then | |
413 | cat /var/tmp/configd-state > configd-state 2>&1 | |
414 | fi | |
415 | ||
416 | } | |
417 | ||
418 | run_route () { | |
419 | ||
420 | if [ ! -x /sbin/route ]; then | |
421 | return | |
422 | fi | |
423 | ||
424 | echo "#" > route-info.txt | |
425 | echo '# route -n -v get www.apple.com' >> route-info.txt | |
426 | echo "#" >> route-info.txt | |
427 | /sbin/route -n -v get www.apple.com >> route-info.txt 2>&1 | |
428 | ||
429 | echo "#" >> route-info.txt | |
430 | echo '# route -n -v get 0.0.0.0' >> route-info.txt | |
431 | echo "#" >> route-info.txt | |
432 | /sbin/route -n -v get 0.0.0.0 >> route-info.txt 2>&1 | |
433 | ||
434 | } | |
435 | ||
436 | run_dig () { | |
437 | ||
438 | if [ ! -x /usr/bin/dig -o ! -f /etc/resolv.conf ]; then | |
439 | return | |
440 | fi | |
441 | ||
442 | echo "#" > dig-info.txt | |
443 | echo '# dig -t any -c any www.apple.com' >> dig-info.txt | |
444 | echo "#" >> dig-info.txt | |
445 | /usr/bin/dig +time=2 -t any -c any www.apple.com >> dig-info.txt 2>/dev/null | |
446 | ||
447 | } | |
448 | ||
449 | # | |
450 | # Host name | |
451 | # | |
452 | run_hostname () { | |
453 | ||
454 | if [ ! -x /bin/hostname ]; then | |
455 | return | |
456 | fi | |
457 | ||
458 | /bin/hostname > hostname.txt 2>&1 | |
459 | ||
460 | } | |
461 | ||
462 | collect_sensitive_info () { | |
463 | collect_state_dump_sensitive | |
464 | run_ndp | |
465 | run_arp | |
466 | } | |
467 | ||
468 | collect_info () { | |
469 | collect_state_dump | |
470 | ||
471 | if [ "${COLLECT_SENSITIVE_INFO}" == "Y" ]; then | |
472 | collect_sensitive_info | |
473 | fi | |
474 | ||
475 | run_scutil | |
476 | run_dig | |
477 | run_ifconfig | |
478 | run_netstat | |
479 | run_ipconfig | |
480 | run_setkey | |
481 | collect_vpn_logs | |
482 | run_route | |
483 | run_hostname | |
484 | ||
485 | if [ "${COLLECT_CONFIGURATION_FILES}" == "Y" ]; then | |
486 | collect_configuration_files | |
487 | fi | |
488 | } | |
489 | ||
490 | # __COMMAND_ROUTINES_END__ | |
491 | ||
492 | # __HELPER_ROUTINES_BEGIN__ | |
493 | ||
494 | usage () { | |
495 | ||
496 | echo "Usage: get-network-info [-s] [-c] <info-directory>" | |
497 | echo " -s collects sensitive information (ARP/NDP/mDNS cache)" | |
498 | echo " -c collects system configuration files" | |
499 | echo " <info-directory> path to directory where all the information will be collected" | |
500 | ||
501 | } | |
502 | ||
503 | is_outdir_valid () { | |
504 | ||
505 | if [ ! -d ${REQUESTED_OUTDIR} ] || | |
506 | [ "${REQUESTED_OUTDIR}" = "" ]; then | |
507 | usage | |
508 | exit 1 | |
509 | fi | |
510 | ||
511 | if [ ! -w ${REQUESTED_OUTDIR} ]; then | |
512 | echo "${REQUESTED_OUTDIR} is write-protected" | |
513 | exit 1 | |
514 | fi | |
515 | } | |
516 | ||
517 | # | |
518 | # Collect most used command output to be used later | |
519 | # | |
520 | optimize () { | |
521 | ||
522 | if [ ! -x /sbin/ifconfig ]; then | |
523 | return | |
524 | fi | |
525 | ||
526 | IF_LIST=`/sbin/ifconfig -l` | |
527 | ||
528 | } | |
529 | ||
530 | init_globals () { | |
531 | REQUESTED_OUTDIR="" | |
532 | COLLECT_SENSITIVE_INFO="" | |
533 | COLLECT_CONFIGURATION_FILES="" | |
534 | } | |
535 | ||
536 | # __HELPER_ROUTINES_END__ | |
537 | ||
538 | # | |
539 | # __MAIN__ | |
540 | # | |
541 | ARGS=`getopt sc $*` | |
542 | if [ $? != 0 ]; then | |
543 | usage | |
544 | exit 1 | |
545 | fi | |
546 | ||
547 | init_globals | |
548 | process_opts | |
549 | is_outdir_valid | |
550 | setup | |
551 | optimize | |
552 | collect_info | |
553 | wait | |
554 | ||
555 | #TO-DO: Add packet trace | |
556 | ||
557 | exit 0 |