1
0
Fork 0
scripts/wifi/capture-sample.sh

273 Zeilen
6.5 KiB
Bash
Ausführbare Datei

#!/bin/sh
#
# capture-sample.sh, Copyright © 2011 Matteo Cypriani <mcy@lm7.fr>
#
########################################################################
# This program is licensed under the terms of the Expat license.
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
########################################################################
#
# Captures a few packets on a Wi-Fi interface, using Tcpdump, and
# writes them to a Pcap file along with some information about the
# system. A tarball containing all these files is finally created.
#set -x
set -e
## Parameters (tune them if you want) ##
# Number of packet to capture:
NB_PKT=10
# Maximal time of a capture on a given channel:
TIMEOUT=15
# Temporary directory:
TMP=/tmp
# Name of the capture file:
FILE=capture.pcap
# First channel to scan:
CHANNEL=1
## Functions ##
# Displays the message in argument on the error output and exits
error()
{
printf '%s\n' "$1" >&2
clean
exit 1
}
# Deletes the temporary files
clean()
{
rm -fr "$DESTDIR"
}
# Verifies the presence of the needed programs
check_dependencies()
{
command -v tcpdump >/dev/null \
|| error "tcpdump is required to run this program!"
if [ "$OS" = Linux ] ; then
[ -x /sbin/iwconfig ] \
|| error "iwconfig is required to run this program on Linux!"
fi
}
# Switches the capture interface to monitor mode, on the channel in
# argument
iface_set_channel()
{
echo "Setting interface $IFACE on channel $1..."
case "$OS" in
Linux)
iface_down
iwconfig "$IFACE" mode managed
iface_up
iwconfig "$IFACE" channel "$1"
;;
NetBSD | OpenBSD)
iface_down
ifconfig "$IFACE" media autoselect chan "$1"
iface_up
;;
*)
error "Your OS is not supported."
;;
esac \
|| error "Cannot set the channel!"
echo "Channel set."
iface_monitor
}
# Switches the capture interface to monitor mode
iface_monitor()
{
iface_down
printf 'Switching interface %s to monitor mode... ' "$IFACE"
case "$OS" in
Linux)
iwconfig "$IFACE" mode monitor
;;
NetBSD | OpenBSD)
ifconfig "$IFACE" media autoselect mediaopt monitor
;;
*)
error "Your OS is not supported."
;;
esac \
|| error "Cannot switch the interface to monitor mode!"
echo "OK."
iface_up
}
# Shuts down the capture interface
iface_down()
{
printf 'Shuting down interface %s... ' "$IFACE"
ifconfig "$IFACE" down \
|| error "Cannot shut down the interface!"
echo "OK."
}
# Turns on the capture interface
iface_up()
{
printf 'Turning up interface %s... ' "$IFACE"
ifconfig "$IFACE" up \
|| error "Cannot turn the interface up!"
echo "OK."
}
# Invokes tcpdump and displays the number of packets captured
invoke_tcpdump()
{
NCAP=$(tcpdump -i "$IFACE" -c "$NB_PKT" -w "$FILE" 2>&1 \
| sed -nr 's/([[:digit:]]+) packets received by filter$/\1/p')
[ -z "$NCAP" ] \
&& error "Error parsing the tcpdump messages! (NCAP=\"$NCAP\")"
echo "$NCAP"
}
# Waits for a number of seconds, then kills any tcpdump process
wait_tcpdump()
{
sleep "$1"
echo "$1 seconds passed, killing all tcpdump processes..."
pkill tcpdump
}
# Gets some information about the running system
gather_system_information()
{
printf "Gathering system information... "
# Kernel & other information:
uname -a >"$DESTDIR"/uname-a
# Wi-Fi interface information:
ifconfig "$IFACE" >"$DESTDIR/ifconfig_$IFACE"
[ "$OS" = Linux ] \
&& iwconfig "$IFACE" >"$DESTDIR/iwconfig_$IFACE"
# PCI devices:
command -v lspci >/dev/null \
&& lspci >"$DESTDIR"/lspci \
|| echo "lspci not available! Please install pciutils. "
# USB devices:
gather_usb_devices
# Loaded kernel modules:
gather_kernel_modules
echo "OK."
}
# Gets information about the plugged usb devices
gather_usb_devices()
{
case "$OS" in
Linux)
command -v lsusb >/dev/null \
&& lsusb >"$DESTDIR"/lsusb \
|| echo "lsusb not available! Please install usbutils. "
;;
NetBSD | OpenBSD | DragonFly)
command -v usbstats >/dev/null \
&& usbstats >"$DESTDIR"/usbstats \
|| echo "usbstats not available! Please install usbutil. "
;;
esac
}
# Gets information about the loaded kernel modules
gather_kernel_modules()
{
case "$OS" in
Linux)
lsmod >"$DESTDIR"/lsmod
;;
NetBSD | OpenBSD)
modstat >"$DESTDIR"/modstat
;;
DragonFly)
kldstat >"$DESTDIR"/kldstat
;;
esac
}
# Compresses the destination directory to a tarball
create_archive()
{
TARBALL="${DESTDIR}.tar.gz"
DIR=$(basename "$DESTDIR")
tar -C "$TMP" -czf "$TARBALL" "$DIR"
echo "Archive \"$TARBALL\" created."
}
## Main program ##
[ $# -eq 1 ] \
|| error "Usage: $0 <wifi_interface>"
# Interface to capture from:
IFACE=$1
# Machine information:
OS=$(uname)
OS_RELEASE=$(uname -r)
HOSTNAME=$(uname -n)
# Current date:
DATE=$(date +%FT%H%M%S)
# Temporary destination directory:
DESTDIR=$(mktemp -d \
"$TMP/capture_${OS}-${OS_RELEASE}_${IFACE}_${HOSTNAME}_${DATE}_XXX")
# Update capture file with full path:
FILE="$DESTDIR/$FILE"
check_dependencies
echo "Trying to capture $NB_PKT packets..."
CAPTURED=0
while [ "$CAPTURED" -eq 0 ] && [ "$CHANNEL" -le 14 ] ; do
echo
iface_set_channel "$CHANNEL"
wait_tcpdump "$TIMEOUT" &
CAPTURED=$(invoke_tcpdump)
[ "$CAPTURED" -eq 0 ] \
&& echo "No packet captured on channel $CHANNEL." \
|| echo "$CAPTURED packets captured on channel $CHANNEL."
CHANNEL=$((CHANNEL + 1))
done
echo
[ "$CAPTURED" -gt 0 ] \
|| error "Failed to capture any packet!"
echo "Capture file \"$FILE\" created."
gather_system_information
create_archive
clean
printf '\nYou can now shut down the interface %s if you would like:\n' "$IFACE"
printf '\tifconfig %s down\n' "$IFACE"