blob: 3ed03ba70820cb5b38d2d57b9f685d0fc106b3fe (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
# Hey Emacs, this is a -*- shell-script -*- !!! :-)
get_src_socket ()
{
local proto="$1"
local dst_socket="$2"
local pid="$3"
local prog="$4"
local pat="^${proto}[[:space:]]+[[:digit:]]+[[:space:]]+[[:digit:]]+[[:space:]]+[^[:space:]]+[[:space:]]+${dst_socket//./\\.}[[:space:]]+ESTABLISHED[[:space:]]+${pid}/${prog}[[:space:]]*\$"
out=$(netstat -tanp |
egrep "$pat" |
awk '{ print $4 }')
[ -n "$out" ]
}
wait_until_get_src_socket ()
{
local proto="$1"
local dst_socket="$2"
local pid="$3"
local prog="$4"
echo "Waiting for ${prog} to establish connection to ${dst_socket}..."
wait_until 5 get_src_socket "$@"
}
#######################################
# filename will be in $tcpdump_filename, pid in $tcpdump_pid
tcpdump_start ()
{
tcpdump_filter="$1" # global
echo "Running tcpdump..."
tcpdump_filename=$(mktemp)
ctdb_test_exit_hook_add "rm -f $tcpdump_filename"
# The only way of being sure that tcpdump is listening is to send
# some packets that it will see. So we use dummy pings - the -U
# option to tcpdump ensures that packets are flushed to the file
# as they are captured.
local dummy_addr="127.3.2.1"
local dummy="icmp and dst host ${dummy_addr} and icmp[icmptype] == icmp-echo"
tcpdump -n -p -s 0 -e -U -w $tcpdump_filename -i any "($tcpdump_filter) or ($dummy)" &
ctdb_test_exit_hook_add "kill $! >/dev/null 2>&1"
echo "Waiting for tcpdump output file to be ready..."
ping -q "$dummy_addr" >/dev/null 2>&1 &
ctdb_test_exit_hook_add "kill $! >/dev/null 2>&1"
tcpdump_listen_for_dummy ()
{
tcpdump -n -r $tcpdump_filename -c 1 "$dummy" >/dev/null 2>&1
}
wait_until 10 tcpdump_listen_for_dummy
}
# By default, wait for 1 matching packet.
tcpdump_wait ()
{
local count="${1:-1}"
local filter="${2:-${tcpdump_filter}}"
tcpdump_check ()
{
local found=$(tcpdump -n -r $tcpdump_filename "$filter" 2>/dev/null | wc -l)
[ $found -ge $count ]
}
echo "Waiting for tcpdump to capture some packets..."
if ! wait_until 30 tcpdump_check ; then
echo "DEBUG AT $(date '+%F %T'):"
local i
for i in "onnode -q 0 $CTDB status" "netstat -tanp" "tcpdump -n -e -r $tcpdump_filename" ; do
echo "$i"
$i || true
done
return 1
fi
}
tcpdump_show ()
{
local filter="${1:-${tcpdump_filter}}"
tcpdump -n -r $tcpdump_filename "$filter" 2>/dev/null
}
tcptickle_sniff_start ()
{
local src="$1"
local dst="$2"
local in="src host ${dst%:*} and tcp src port ${dst##*:} and dst host ${src%:*} and tcp dst port ${src##*:}"
local out="src host ${src%:*} and tcp src port ${src##*:} and dst host ${dst%:*} and tcp dst port ${dst##*:}"
local tickle_ack="${in} and (tcp[tcpflags] & tcp-ack != 0) and (tcp[14] == 4) and (tcp[15] == 210)" # win == 1234
local ack_ack="${out} and (tcp[tcpflags] & tcp-ack != 0)"
tcptickle_reset="${in} and tcp[tcpflags] & tcp-rst != 0"
local filter="(${tickle_ack}) or (${ack_ack}) or (${tcptickle_reset})"
tcpdump_start "$filter"
}
tcptickle_sniff_wait_show ()
{
tcpdump_wait 1 "$tcptickle_reset"
echo "GOOD: here are some TCP tickle packets:"
tcpdump_show
}
gratarp_sniff_start ()
{
tcpdump_start "arp host ${test_ip}"
}
gratarp_sniff_wait_show ()
{
tcpdump_wait 2
echo "GOOD: this should be the some gratuitous ARPs:"
tcpdump_show
}
|