1 # Hey Emacs, this is a -*- shell-script -*- !!! :-)
3 # Thanks/blame to Stephen Rothwell for suggesting that this can be
4 # done in the shell. ;-)
9 # Replace "::" by something special.
10 local foo
="${addr/::/:@:}"
12 # Join the groups of digits together, 0-padding each group of
13 # digits out to 4 digits, and count the number of (non-@) groups
17 for i
in $
(IFS
=":" ; echo $foo ) ; do
18 if [ "$i" = "@" ] ; then
21 out
="${out}$(printf '%04x' 0x${i})"
26 # Replace '@' with correct number of zeroes
27 local zeroes
=$
(printf "%0$((32 - $count))x" 0)
28 echo "${out/@/${zeroes}}"
31 #######################################
40 local pat
="^${proto}6?[[:space:]]+[[:digit:]]+[[:space:]]+[[:digit:]]+[[:space:]]+[^[:space:]]+[[:space:]]+${dst_socket//./\\.}[[:space:]]+ESTABLISHED[[:space:]]+${pid}/${prog}[[:space:]]*\$"
48 wait_until_get_src_socket
()
55 echo "Waiting for ${prog} to establish connection to ${dst_socket}..."
57 wait_until
5 get_src_socket
"$@"
60 #######################################
68 try_command_on_node
$node ctdb gettickles
$test_ip $test_port
69 # SRC: 10.0.2.45:49091 DST: 10.0.2.143:445
70 [ "${out/SRC: ${src_socket} /}" != "$out" ]
80 try_command_on_node all ctdb gettickles
$test_ip $test_port
81 # SRC: 10.0.2.45:49091 DST: 10.0.2.143:445
82 local t
="${src_socket//./\\.}"
83 local count
=$
(grep -E -c "SRC: ${t} " <<<"$out" || true
)
84 [ $count -eq $numnodes ]
89 #######################################
91 # filename will be in $tcpdump_filename, pid in $tcpdump_pid
94 tcpdump_filter
="$1" # global
96 echo "Running tcpdump..."
97 tcpdump_filename
=$
(mktemp
)
98 ctdb_test_exit_hook_add
"rm -f $tcpdump_filename"
100 # The only way of being sure that tcpdump is listening is to send
101 # some packets that it will see. So we use dummy pings - the -U
102 # option to tcpdump ensures that packets are flushed to the file
103 # as they are captured.
104 local dummy_addr
="127.3.2.1"
105 local dummy
="icmp and dst host ${dummy_addr} and icmp[icmptype] == icmp-echo"
106 tcpdump
-n -p -s 0 -e -U -w $tcpdump_filename -i any
"($tcpdump_filter) or ($dummy)" &
107 ctdb_test_exit_hook_add
"kill $! >/dev/null 2>&1"
109 echo "Waiting for tcpdump output file to be ready..."
110 ping -q "$dummy_addr" >/dev
/null
2>&1 &
111 ctdb_test_exit_hook_add
"kill $! >/dev/null 2>&1"
113 tcpdump_listen_for_dummy
()
115 tcpdump
-n -r $tcpdump_filename -c 1 "$dummy" >/dev
/null
2>&1
118 wait_until
10 tcpdump_listen_for_dummy
121 # By default, wait for 1 matching packet.
124 local count
="${1:-1}"
125 local filter
="${2:-${tcpdump_filter}}"
129 local found
=$
(tcpdump
-n -r $tcpdump_filename "$filter" 2>/dev
/null |
wc -l)
130 [ $found -ge $count ]
133 echo "Waiting for tcpdump to capture some packets..."
134 if ! wait_until
30 tcpdump_check
; then
135 echo "DEBUG AT $(date '+%F %T'):"
137 for i
in "onnode -q 0 $CTDB status" "netstat -tanp" "tcpdump -n -e -r $tcpdump_filename" ; do
147 local filter
="${1:-${tcpdump_filter}}"
149 tcpdump
-n -r $tcpdump_filename "$filter" 2>/dev
/null
152 tcp4tickle_sniff_start
()
157 local in="src host ${dst%:*} and tcp src port ${dst##*:} and dst host ${src%:*} and tcp dst port ${src##*:}"
158 local out
="src host ${src%:*} and tcp src port ${src##*:} and dst host ${dst%:*} and tcp dst port ${dst##*:}"
159 local tickle_ack
="${in} and (tcp[tcpflags] & tcp-ack != 0) and (tcp[14:2] == 1234)" # win == 1234
160 local ack_ack
="${out} and (tcp[tcpflags] & tcp-ack != 0)"
161 tcptickle_reset
="${in} and tcp[tcpflags] & tcp-rst != 0"
162 local filter
="(${tickle_ack}) or (${ack_ack}) or (${tcptickle_reset})"
164 tcpdump_start
"$filter"
167 # tcp[] does not work for IPv6 (in some versions of tcpdump)
168 tcp6tickle_sniff_start
()
173 local in="src host ${dst%:*} and tcp src port ${dst##*:} and dst host ${src%:*} and tcp dst port ${src##*:}"
174 local out
="src host ${src%:*} and tcp src port ${src##*:} and dst host ${dst%:*} and tcp dst port ${dst##*:}"
175 local tickle_ack
="${in} and (ip6[53] & tcp-ack != 0) and (ip6[54:2] == 1234)" # win == 1234
176 local ack_ack
="${out} and (ip6[53] & tcp-ack != 0)"
177 tcptickle_reset
="${in} and ip6[53] & tcp-rst != 0"
178 local filter
="(${tickle_ack}) or (${ack_ack}) or (${tcptickle_reset})"
180 tcpdump_start
"$filter"
183 tcptickle_sniff_start
()
189 *:*) tcp6tickle_sniff_start
"$src" "$dst" ;;
190 *) tcp4tickle_sniff_start
"$src" "$dst" ;;
194 tcptickle_sniff_wait_show
()
196 tcpdump_wait
1 "$tcptickle_reset"
198 echo "GOOD: here are some TCP tickle packets:"
202 gratarp4_sniff_start
()
204 tcpdump_start
"arp host ${test_ip}"
207 gratarp6_sniff_start
()
209 local neighbor_advertisement
="icmp6 and ip6[40] == 136"
210 local hex
=$
(ipv6_to_hex
"$test_ip")
211 local match_target
="ip6[48:4] == 0x${hex:0:8} and ip6[52:4] == 0x${hex:8:8} and ip6[56:4] == 0x${hex:16:8} and ip6[60:4] == 0x${hex:24:8}"
213 tcpdump_start
"${neighbor_advertisement} and ${match_target}"
216 gratarp_sniff_start
()
219 *:*) gratarp6_sniff_start
;;
220 *) gratarp4_sniff_start
;;
224 gratarp_sniff_wait_show
()
228 echo "GOOD: this should be the some gratuitous ARPs:"
233 ctdb_test_check_real_cluster
()
235 [ -z "$TEST_LOCAL_DAEMONS" ] || \
236 die
"ERROR: This test must be run against a real/virtual cluster, not local daemons."
241 for i
in $
(onnode
-q all hostname
) ; do
242 [ "$h" != "$i" ] || \
243 die
"ERROR: This test must not be run from a cluster node."