diff options
Diffstat (limited to 'ttcn3-tcpdump-start.sh')
-rwxr-xr-x | ttcn3-tcpdump-start.sh | 79 |
1 files changed, 63 insertions, 16 deletions
diff --git a/ttcn3-tcpdump-start.sh b/ttcn3-tcpdump-start.sh index 3ad14c0a..9575a681 100755 --- a/ttcn3-tcpdump-start.sh +++ b/ttcn3-tcpdump-start.sh @@ -1,18 +1,30 @@ #!/bin/sh PIDFILE_PCAP=/tmp/pcap.pid -TCPDUMP=/usr/sbin/tcpdump -DUMPCAP=/usr/bin/dumpcap +TCPDUMP=$(command -v tcpdump) +DUMPCAP=$(command -v dumpcap) PIDFILE_NETCAT=/tmp/netcat.pid -NETCAT=/bin/nc +NETCAT=$(command -v nc) GSMTAP_PORT=4729 TESTCASE=$1 + +SUDOSTR="" +if ! [ "$(id -u)" = "0" ]; then + SUDOSTR="sudo -n" + # Otherwise, if sudo /usr/bin/kill, sudo /usr/bin/tcpdump cannot be run without a password prompt, + # and this script will hang indefinitely +fi + kill_rm_pidfile() { - if [ -e $1 ]; then - kill "$(cat "$1")" + # NOTE: This requires you to be root or something like + # "laforge ALL=NOPASSWD: /usr/sbin/tcpdump, /bin/kill" in your sudoers file + if [ -e "$1" ]; then + if [ -s "$1" ]; then + $SUDOSTR kill "$(cat "$1")" 2>&1 | grep -v "No such process" + fi rm $1 fi } @@ -27,23 +39,35 @@ fi kill_rm_pidfile $PIDFILE_NETCAT kill_rm_pidfile $PIDFILE_PCAP -if [ "$(id -u)" = "0" ]; then - CMD="$TCPDUMP -U" -else -# NOTE: This requires you to be root or something like -# "laforge ALL=NOPASSWD: /usr/sbin/tcpdump, /bin/kill" in your sudoers file - CMD="sudo $TCPDUMP -U" -fi +CMD="$SUDOSTR $TCPDUMP -U" -if [ -x $DUMPCAP ]; then +if [ -x "$DUMPCAP" ]; then CAP_ERR="1" if [ -x /sbin/setcap ]; then # N. B: this check requires libcap2-bin package - setcap -q -v 'cap_net_admin,cap_net_raw=pie' $DUMPCAP + /sbin/setcap -q -v 'cap_net_admin,cap_net_raw=pie' $DUMPCAP + CAP_ERR="$?" + fi + + # did we implicitly inherit all those caps because we're root in a netns? + if [ -u $DUMPCAP -o "$CAP_ERR" = "1" ]; then + getpcaps 0 2>&1 | grep -e cap_net_admin | grep -q -e cap_net_raw + CAP_ERR="$?" + fi + + # did we implicitly inherit all those caps because we're root in a netns? + if [ -u $DUMPCAP -o "$CAP_ERR" = "1" ]; then + getpcaps 0 2>&1 | grep -q -e " =ep" # all perms CAP_ERR="$?" fi + if [ -u $DUMPCAP -o "$CAP_ERR" = "0" ]; then - CMD="$DUMPCAP -q" + # dumpcap, *after dropping permissions*, needs to be able to write to the directory to create the pcap file: + if [ "$(stat -L -c "%u" "$TTCN3_PCAP_PATH")" = "$(id -u)" ] && [ "$(stat -L -c "%A" "$TTCN3_PCAP_PATH" | head -c 4)" = "drwx" ]; then + CMD="$DUMPCAP -q" + else + echo "NOTE: unable to use dumpcap due to missing permissions in $TTCN3_PCAP_PATH" + fi else echo "NOTE: unable to use dumpcap due to missing capabilities or suid bit" fi @@ -54,9 +78,29 @@ $NETCAT -l -u -k -p $GSMTAP_PORT >/dev/null 2>$TESTCASE.netcat.stderr & PID=$! echo $PID > $PIDFILE_NETCAT -$CMD -s 1500 -n -i any -w "$TTCN3_PCAP_PATH/$TESTCASE.pcap" >$TTCN3_PCAP_PATH/$TESTCASE.pcap.stdout 2>&1 & +CMD_OUTFILE=$TTCN3_PCAP_PATH/$TESTCASE.pcap.stdout +CMD_OUTFILE_ERR=$TTCN3_PCAP_PATH/$TESTCASE.pcap.stderr +FIFO=/tmp/cmderr +if ! [ -e $FIFO ]; then + mkfifo $FIFO +else + echo "Warning: Named pipe already exists: $FIFO" +fi + +# Log stderr to CMD_OUTFILE and a dedicated error log file +tee $CMD_OUTFILE < $FIFO > $CMD_OUTFILE_ERR & +CMD_STR="$CMD -s 1520 -n -i any -w \"$TTCN3_PCAP_PATH/$TESTCASE.pcap\" >$CMD_OUTFILE 2>$FIFO &" +echo "$CMD_STR" +eval $CMD_STR +# $CMD -s 1520 -n -i any -w \"$TTCN3_PCAP_PATH/$TESTCASE.pcap\" >$CMD_OUTFILE & PID=$! echo $PID > $PIDFILE_PCAP +if [ -f $CMD_OUTFILE_ERR ] && [ $(wc -l $CMD_OUTFILE_ERR | awk '{print $1}') -ne 0 ]; then + echo "Warnings or error messages from command:" >&2 + echo " $CMD_STR" >&2 + echo "Message:" >&2 + echo "$(cat $CMD_OUTFILE_ERR)" | sed 's/^/\t/' >&2 +fi # Wait until packet dumper creates the pcap file and starts recording. # We generate some traffic until we see packet dumper catches it. @@ -71,7 +115,10 @@ do sleep 1 i=$((i+1)) if [ $i -eq 10 ]; then + echo "Packet dumper didn't start filling pcap file after $i seconds!!!" break fi done kill $PID + +echo "$TESTCASE" > "$TTCN3_PCAP_PATH/.current_test" |