aboutsummaryrefslogtreecommitdiffstats
path: root/tools/dfilter-test.py
diff options
context:
space:
mode:
authorGilbert Ramirez <gram@alumni.rice.edu>2003-07-09 03:57:34 +0000
committerGilbert Ramirez <gram@alumni.rice.edu>2003-07-09 03:57:34 +0000
commit6a8701fb67032fc4c5658ad4a2018a33e37697bf (patch)
tree3cee702a66d33f881fcb256e37f8592b25acf2bb /tools/dfilter-test.py
parenteabf70db653ba8ebdc3fbe6588069ef9f3d64579 (diff)
Script to unit-test ftype functions via dfilters passed to tethereal.
Uses text2pcap to create pcap trace files from hex-dumps embedded in the test script. svn path=/trunk/; revision=7996
Diffstat (limited to 'tools/dfilter-test.py')
-rwxr-xr-xtools/dfilter-test.py1224
1 files changed, 1224 insertions, 0 deletions
diff --git a/tools/dfilter-test.py b/tools/dfilter-test.py
new file mode 100755
index 0000000000..1e837124d5
--- /dev/null
+++ b/tools/dfilter-test.py
@@ -0,0 +1,1224 @@
+#!/usr/bin/env python
+"""
+Test-suite to test ethereal's dfilter mechanism.
+"""
+
+#
+# $Id: dfilter-test.py,v 1.1 2003/07/09 03:57:34 gram Exp $
+#
+# Copyright (C) 2003 by Gilbert Ramirez <gram@alumni.rice.edu>
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+import os
+import sys
+import atexit
+import tempfile
+import types
+import getopt
+
+# Global variables that can be overridden by user
+
+REMOVE_TEMP_FILES = 1
+VERBOSE = 0
+TEXT2PCAP = os.path.join(".", "text2pcap")
+TETHEREAL = os.path.join(".", "tethereal")
+
+# Some DLT values. Add more from <net/bpf.h> if you need to.
+
+DLT_NULL = 0 # no link-layer encapsulation
+DLT_EN10MB = 1 # Ethernet (10Mb)
+DLT_EN3MB = 2 # Experimental Ethernet (3Mb)
+DLT_AX25 = 3 # Amateur Radio AX.25
+DLT_PRONET = 4 # Proteon ProNET Token Ring
+DLT_CHAOS = 5 # Chaos
+DLT_IEEE802 = 6 # IEEE 802 Networks
+DLT_ARCNET = 7 # ARCNET
+DLT_SLIP = 8 # Serial Line IP
+DLT_PPP = 9 # Point-to-point Protocol
+DLT_FDDI = 10 # FDDI
+DLT_FRELAY = 107 # Frame Relay
+
+################################################################################
+
+class RunCommandError:
+ """The exception that run_cmd can produce."""
+ pass
+
+def run_cmd(cmd):
+ """Run a command. 'cmd' is either a string or
+ a tuple/array of strings. Returns a tuple of
+ the output of the command and the return value.
+ If an error did not occur, the return value is None, not 0.
+ If an error occured while trying to run the command,
+ RunCommandError is raised.
+ Both, or either, the output and the return value, may
+ be None if RunCommandError is raised.."""
+
+ if type(cmd) == types.TupleType:
+ cmd = ' '.join(cmd)
+
+ output = None
+ error = None
+
+ if VERBOSE:
+ print "Running", cmd
+
+ try:
+ pipe = os.popen(cmd)
+ output = pipe.readlines()
+ error = pipe.close()
+
+ except OSError:
+ raise RunCommandError
+
+ return (output, error)
+
+
+def remove_file(filename):
+ """Remove a file. No exceptions are produced even
+ when the file cannot be removed."""
+ try:
+ os.remove(filename)
+ except OSError:
+ pass
+
+
+class Packet:
+ """Knows how to convert a string representing the
+ hex-dump of packet into a libpcap file."""
+
+ def __init__(self, linklayer):
+ """Linklayer is a DLT value."""
+ self.linklayer = linklayer
+ self.data = None
+ self.filename = None
+ self.time_fmt = None
+
+ def Filename(self):
+ """Returns the filename of the packet trace.
+ The first time this is called, the libpcap trace
+ file is created. During subsequent calls, the libpcap
+ tracee file already exists, so the filename is simply
+ returned. Care is taken so that the libpcap trace file
+ is automatically deleted when this Python process
+ exits."""
+ if not self.filename:
+ # Create the temporary text file.
+ hex_filename = tempfile.mktemp("-dfilter-test.txt")
+
+ # Tell Python to remove the file when exiting
+ if REMOVE_TEMP_FILES:
+ atexit.register(remove_file, hex_filename)
+
+ try:
+ hex_fh = open(hex_filename, "w")
+ hex_fh.write(self.data)
+ hex_fh.write("\n")
+ hex_fh.close()
+ except IOError, err:
+ sys.exit("Could not write to %s: %s" % \
+ (hex_filename, err))
+
+
+ # Create the pcap file
+ self.filename = tempfile.mktemp("-dfilter-test.cap")
+
+ # Tell Python to remove the file when exiting
+ if REMOVE_TEMP_FILES:
+ atexit.register(remove_file, self.filename)
+
+ cmd = (TEXT2PCAP, "-q -l", str(self.linklayer))
+
+ if self.time_fmt:
+ cmd = cmd + ("-t", "'" + self.time_fmt + "'")
+
+ cmd = cmd + (hex_filename, self.filename)
+
+ try:
+ (output, error) = run_cmd(cmd)
+ except RunCommandError:
+ sys.exit("Could not produce trace file.")
+
+ if error != None:
+ sys.exit("Could not produce trace file.")
+
+
+ if not REMOVE_TEMP_FILES:
+ print "(", self.filename, ") ...",
+
+ return self.filename
+
+
+OK = 0
+FAILED = 1
+
+class Test:
+ """Base class for test classes."""
+
+ def Run(self):
+ """Run the tests listed in self.tests.
+ Return the score."""
+
+ num_run = 0
+ num_succeeded = 0
+
+ for test in self.tests:
+ print "\t", test.__name__ , "...",
+ retval = test(self)
+ if retval == OK:
+ print "OK"
+ num_succeeded += 1
+ else:
+ print "FAILED"
+ num_run += 1
+
+ return (num_run, num_succeeded)
+
+
+ def DFilterCount(self, packet, dfilter, num_lines_expected):
+ """Run a dfilter on a packet file and expect
+ a certain number of output lines. If num_lines_expected
+ is None, then the tethereal command is expected to fail
+ with a non-zero return value."""
+
+ packet_file = packet.Filename()
+
+ cmd = (TETHEREAL, "-n -r", packet_file, "-R '", dfilter, "'")
+
+ tethereal_failed = 0
+
+ try:
+ (output, retval) = run_cmd(cmd)
+ except RunCommandError:
+ tethereal_failed = 1
+
+# print "GOT", len(output), "lines:", output, retval
+
+ if tethereal_failed:
+ if num_lines_expected == None:
+ if VERBOSE:
+ print "\nGot:", output
+ return OK
+ else:
+ print "\nGot:", output
+ return FAILED
+ elif len(output) == num_lines_expected:
+ if VERBOSE:
+ print "\nGot:", output
+ return OK
+ else:
+ print "\nGot:", output
+ return FAILED
+
+
+################################################################################
+# Add packets here
+# Watch out for trailing backslashes. If the last character in the line is a
+# backslash, the data won't convert properly. Just remove the backslash or
+# replace it with another character. I haven't determined if this is due to
+# Python's "here-document" parsing, or due to text2pcap.
+################################################################################
+
+# IPX RIP Response
+pkt_ipx_rip = Packet(DLT_EN10MB)
+pkt_ipx_rip.data = """
+0000 ff ff ff ff ff ff 00 aa 00 a3 e3 a4 00 28 ff ff ........ .....(..
+0010 00 28 00 01 00 00 00 28 ff ff ff ff ff ff 04 53 .(.....( .......S
+0020 00 00 00 28 00 aa 00 a3 e3 a4 04 53 00 02 39 17 ...(.... ...S..9.
+0030 29 e2 00 01 00 02 00 00 00 00 00 00 )....... ....
+"""
+
+# IPv6
+pkt_ipv6 = Packet(DLT_EN10MB)
+pkt_ipv6.data = """
+0000 33 33 00 00 99 99 00 00 86 05 80 fa 86 dd 60 00 33...... ......`.
+0010 00 00 00 20 00 01 fe 80 00 00 00 00 00 00 02 00 ... .... ........
+0020 86 ff fe 05 80 fa ff 05 00 00 00 00 00 00 00 00 ........ ........
+0030 00 00 00 00 99 99 3a 00 01 00 05 02 00 00 83 00 ......:. ........
+0040 44 ed 00 00 00 00 ff 05 00 00 00 00 00 00 00 00 D....... ........
+0050 00 00 00 00 99 99 ......
+"""
+
+# ARP
+pkt_arp = Packet(DLT_FRELAY)
+pkt_arp.data = """
+0000 18 41 03 00 80 00 00 00 08 06 00 0f 08 00 02 04 .A...... ........
+0010 00 08 00 00 0a ce 01 02 00 64 00 00 00 00 ........ .d....
+"""
+
+# NFS
+pkt_nfs = Packet(DLT_FDDI)
+pkt_nfs.time_fmt = "%Y-%m-%d %H:%M:%S."
+pkt_nfs.data = """
+2002-12-31 07:55:31.3
+0000 51 10 00 d4 cd 59 6f 00 07 4a 01 6e 00 aa aa 03 Q....Yo. .J.n....
+0010 00 00 00 08 00 45 00 00 b4 1c cf 40 00 fc 11 a4 .....E.. ...@....
+0020 cd ac 19 64 0e c6 5f e6 14 03 ff 08 01 00 a0 79 ...d.._. .......y
+0030 f9 7b 55 8a eb 00 00 00 00 00 00 00 02 00 01 86 .{U..... ........
+0040 a3 00 00 00 03 00 00 00 01 00 00 00 01 00 00 00 ........ ........
+0050 4c 36 db 91 97 00 00 00 0a 61 74 6d 63 6c 69 65 L6...... .atmclie
+0060 6e 74 32 00 00 00 00 00 00 00 00 00 01 00 00 00 nt2..... ........
+0070 0b 00 00 00 01 00 00 00 00 00 00 00 02 00 00 00 ........ ........
+0080 03 00 00 00 04 00 00 00 05 00 00 00 06 00 00 00 ........ ........
+0090 07 00 00 00 08 00 00 00 09 00 00 00 0c 00 00 00 ........ ........
+00a0 00 00 00 00 00 00 00 00 20 21 92 13 00 a7 92 59 ........ !.....Y
+00b0 07 20 00 00 00 00 02 4a 77 db b5 19 01 19 00 00 . .....J w.......
+00c0 00 01 a4 06 00 97 1b 05 00 ........ .
+
+2002-12-31 07:55:32.0
+0000 51 00 07 4a 01 6e 00 10 00 d4 cd 59 6f aa aa 03 Q..J.n.. ...Yo...
+0010 00 00 00 08 00 45 00 00 8c 6d 3c 00 00 40 11 50 .....E.. .m<..@.P
+0020 89 c6 5f e6 14 ac 19 64 0e 08 01 03 ff 00 78 1d .._....d ......x.
+0030 99 7b 55 8a eb 00 00 00 01 00 00 00 00 00 00 00 .{U..... ........
+0040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........
+0050 01 00 00 01 ed 00 00 00 01 00 00 00 00 00 00 00 ........ ........
+0060 1e 00 00 00 00 00 04 07 60 00 00 00 00 00 04 20 ........ `......
+0070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........
+0080 19 00 00 00 00 00 02 4a 77 36 db 94 da 0c 84 5c .......J w6......
+0090 68 32 1e 28 e9 00 00 00 00 32 23 d4 10 0a 21 fe h2.(.... .2#...!.
+00a0 80
+"""
+
+# NTP
+pkt_ntp = Packet(DLT_EN10MB)
+pkt_ntp.data = """
+0000 08 00 2b 91 e8 3a 08 00 2b e4 c4 43 08 00 45 00 ..+..:.. +..C..E.
+0010 00 4c 64 4c 00 00 1e 11 02 47 82 dc 18 3e 82 dc .LdL.... .G...>..
+0020 18 18 00 7b 00 7b 00 38 ee 1c 1b 04 06 f5 00 00 ...{.{.8 ........
+0030 10 0d 00 00 05 57 82 dc 18 18 ba 29 66 36 7d d0 .....W.. ...)f6}.
+0040 00 00 ba 29 66 36 7d 58 40 00 ba 29 66 36 7d d0 ...)f6}X @..)f6}.
+0050 00 00 ba 29 66 76 7d 50 50 00 ...)fv}P P.
+"""
+
+
+# HTTP
+pkt_http = Packet(DLT_EN10MB)
+pkt_http.time_fmt = "%Y-%m-%d %H:%M:%S."
+pkt_http.data = """
+2002-12-31 07:55:31.3
+0000 00 e0 81 00 b0 28 00 09 6b 88 f5 c9 08 00 45 00 .....(.. k.....E.
+0010 00 c1 d2 49 40 00 80 06 c8 5b 0a 00 00 05 cf 2e ...I@... .[......
+0020 86 5e 0c c3 00 50 a8 00 76 87 7d e0 14 02 50 18 .^...P.. v.}...P.
+0030 fa f0 ad 62 00 00 48 45 41 44 20 2f 76 34 2f 69 ...b..HE AD /v4/i
+0040 75 69 64 65 6e 74 2e 63 61 62 3f 30 33 30 37 30 uident.c ab?03070
+0050 31 31 32 30 38 20 48 54 54 50 2f 31 2e 31 0d 0a 11208 HT TP/1.1..
+0060 41 63 63 65 70 74 3a 20 2a 2f 2a 0d 0a 55 73 65 Accept: */*..Use
+0070 72 2d 41 67 65 6e 74 3a 20 49 6e 64 75 73 74 72 r-Agent: Industr
+0080 79 20 55 70 64 61 74 65 20 43 6f 6e 74 72 6f 6c y Update Control
+0090 0d 0a 48 6f 73 74 3a 20 77 69 6e 64 6f 77 73 75 ..Host: windowsu
+00a0 70 64 61 74 65 2e 6d 69 63 72 6f 73 6f 66 74 2e pdate.mi crosoft.
+00b0 63 6f 6d 0d 0a 43 6f 6e 6e 65 63 74 69 6f 6e 3a com..Con nection:
+00c0 20 4b 65 65 70 2d 41 6c 69 76 65 0d 0a 0d 0a Keep-Al ive....
+"""
+
+
+# TFTP
+pkt_tftp = Packet(DLT_IEEE802)
+pkt_tftp.data = """
+0000 10 40 00 20 35 01 2b 59 00 06 29 17 93 f8 aa aa .@. 5.+Y ..).....
+0010 03 00 00 00 08 00 45 00 00 37 f9 39 00 00 40 11 ......E. .7.9..@.
+0020 a6 db c0 a8 2c 7b c0 a8 2c d5 f9 39 00 45 00 23 ....,{.. ,..9.E.#
+0030 8d 73 00 01 43 3a 5c 49 42 4d 54 43 50 49 50 5c .s..C:\I BMTCPIP.
+0040 6c 63 63 6d 2e 31 00 6f 63 74 65 74 00 lccm.1.o ctet.
+"""
+
+
+################################################################################
+# Add tests here
+################################################################################
+
+class Ftype_Bytes(Test):
+ """Tests routines in ftype-bytes.c"""
+
+ def __init__(self):
+ print "Note: Ftype_Bytes does not yet test FT_INT64."
+
+ def ck_eq_1(self):
+ return self.DFilterCount(pkt_ipx_rip,
+ "eth.dst == ff:ff:ff:ff:ff:ff", 1)
+
+ def ck_eq_2(self):
+ return self.DFilterCount(pkt_ipx_rip,
+ "eth.src == ff:ff:ff:ff:ff:ff", 0)
+
+ def ck_ne_1(self):
+ return self.DFilterCount(pkt_ipx_rip,
+ "eth.dst != ff:ff:ff:ff:ff:ff", 0)
+
+ def ck_ne_2(self):
+ return self.DFilterCount(pkt_ipx_rip,
+ "eth.src != ff:ff:ff:ff:ff:ff", 1)
+
+ def ck_gt_1(self):
+ return self.DFilterCount(pkt_ipx_rip,
+ "eth.src > 00:aa:00:a3:e3:ff", 0)
+
+ def ck_gt_2(self):
+ return self.DFilterCount(pkt_ipx_rip,
+ "eth.src > 00:aa:00:a3:e3:a4", 0)
+
+ def ck_gt_3(self):
+ return self.DFilterCount(pkt_ipx_rip,
+ "eth.src > 00:aa:00:a3:e3:00", 1)
+
+ def ck_ge_1(self):
+ return self.DFilterCount(pkt_ipx_rip,
+ "eth.src >= 00:aa:00:a3:e3:ff", 0)
+
+ def ck_ge_2(self):
+ return self.DFilterCount(pkt_ipx_rip,
+ "eth.src >= 00:aa:00:a3:e3:a4", 1)
+
+ def ck_ge_3(self):
+ return self.DFilterCount(pkt_ipx_rip,
+ "eth.src >= 00:aa:00:a3:e3:00", 1)
+
+ def ck_lt_1(self):
+ return self.DFilterCount(pkt_ipx_rip,
+ "eth.src < 00:aa:00:a3:e3:ff", 1)
+
+ def ck_lt_2(self):
+ return self.DFilterCount(pkt_ipx_rip,
+ "eth.src < 00:aa:00:a3:e3:a4", 0)
+
+ def ck_lt_3(self):
+ return self.DFilterCount(pkt_ipx_rip,
+ "eth.src < 00:aa:00:a3:e3:00", 0)
+
+ def ck_le_1(self):
+ return self.DFilterCount(pkt_ipx_rip,
+ "eth.src <= 00:aa:00:a3:e3:ff", 1)
+
+ def ck_le_2(self):
+ return self.DFilterCount(pkt_ipx_rip,
+ "eth.src <= 00:aa:00:a3:e3:a4", 1)
+
+ def ck_le_3(self):
+ return self.DFilterCount(pkt_ipx_rip,
+ "eth.src <= 00:aa:00:a3:e3:00", 0)
+
+ def ck_slice_1(self):
+ return self.DFilterCount(pkt_ipx_rip,
+ "eth.src[0:3] == 00:aa:00", 1)
+
+ def ck_slice_2(self):
+ return self.DFilterCount(pkt_ipx_rip,
+ "eth.src[-3:3] == a3:e3:a4", 1)
+
+ def ck_slice_3(self):
+ return self.DFilterCount(pkt_ipx_rip,
+ "eth.src[1:4] == aa:00:a3:e3", 1)
+
+ def ck_slice_4(self):
+ return self.DFilterCount(pkt_ipx_rip,
+ "eth.src[0] == 00", 1)
+
+ def ck_ipv6_1(self):
+ return self.DFilterCount(pkt_ipv6,
+ "ipv6.dst == ff05::9999", 1)
+
+ def ck_ipv6_2(self):
+ return self.DFilterCount(pkt_ipv6,
+ "ipv6.dst == ff05::9990", 0)
+
+ # ck_eq_1 checks FT_ETHER; this checks FT_BYTES
+ def ck_bytes_1(self):
+ return self.DFilterCount(pkt_arp,
+ "arp.dst.hw == 00:64", 1)
+
+ # ck_eq_2 checks FT_ETHER; this checks FT_BYTES
+ def ck_bytes_2(self):
+ return self.DFilterCount(pkt_arp,
+ "arp.dst.hw == 00:00", 0)
+
+ # ck_eq_1 checks FT_ETHER; this checks FT_UINT64
+ def ck_uint64_1(self):
+ return self.DFilterCount(pkt_nfs,
+ "nfs.fattr3.size == 264032", 1)
+
+ # ck_eq_2 checks FT_ETHER; this checks FT_UINT64
+ def ck_uint64_2(self):
+ return self.DFilterCount(pkt_nfs,
+ "nfs.fattr3.size == 264000", 0)
+
+
+ tests = [
+ ck_eq_1,
+ ck_eq_2,
+ ck_ne_1,
+ ck_ne_2,
+ ck_gt_1,
+ ck_gt_2,
+ ck_gt_3,
+ ck_ge_1,
+ ck_ge_2,
+ ck_ge_3,
+ ck_lt_1,
+ ck_lt_2,
+ ck_lt_3,
+ ck_le_1,
+ ck_le_2,
+ ck_le_3,
+ ck_slice_1,
+ ck_slice_2,
+ ck_slice_3,
+ ck_slice_4,
+ ck_ipv6_1,
+ ck_ipv6_2,
+ ck_bytes_1,
+ ck_bytes_2,
+ ck_uint64_1,
+ ck_uint64_2,
+ ]
+
+
+class Ftype_Double(Test):
+ """Tests routines in ftype-double.c"""
+
+ def ck_eq_1(self):
+ # This works on ia32/Linux
+ # http://www.cslab.vt.edu/manuals/glibc-2.2.3/html_node/libc_673.html
+ return self.DFilterCount(pkt_ntp,
+ "ntp.rootdelay == 0.0626983642578125", 1)
+
+ def ck_eq_2(self):
+ return self.DFilterCount(pkt_ntp,
+ "ntp.rootdelay == 0.0626", 0)
+
+ def ck_gt_1(self):
+ return self.DFilterCount(pkt_ntp,
+ "ntp.rootdelay > 1.0626", 0)
+
+ def ck_gt_2(self):
+ return self.DFilterCount(pkt_ntp,
+ "ntp.rootdelay > 0.0626983642578125", 0)
+
+ def ck_gt_3(self):
+ return self.DFilterCount(pkt_ntp,
+ "ntp.rootdelay > 0.0026", 1)
+
+ def ck_ge_1(self):
+ return self.DFilterCount(pkt_ntp,
+ "ntp.rootdelay >= 1.0626", 0)
+
+ def ck_ge_2(self):
+ return self.DFilterCount(pkt_ntp,
+ "ntp.rootdelay >= 0.0626983642578125", 1)
+
+ def ck_ge_3(self):
+ return self.DFilterCount(pkt_ntp,
+ "ntp.rootdelay > 0.0026", 1)
+
+ def ck_lt_1(self):
+ return self.DFilterCount(pkt_ntp,
+ "ntp.rootdelay < 1.0626", 1)
+
+ def ck_lt_2(self):
+ return self.DFilterCount(pkt_ntp,
+ "ntp.rootdelay < 0.0626983642578125", 0)
+
+ def ck_lt_3(self):
+ return self.DFilterCount(pkt_ntp,
+ "ntp.rootdelay < 0.0026", 0)
+
+ def ck_le_1(self):
+ return self.DFilterCount(pkt_ntp,
+ "ntp.rootdelay <= 1.0626", 1)
+
+ def ck_le_2(self):
+ return self.DFilterCount(pkt_ntp,
+ "ntp.rootdelay <= 0.0626983642578125", 1)
+
+ def ck_le_3(self):
+ return self.DFilterCount(pkt_ntp,
+ "ntp.rootdelay <= 0.0026", 0)
+
+
+ tests = [
+ ck_eq_1,
+ ck_eq_2,
+ ck_gt_1,
+ ck_gt_2,
+ ck_gt_3,
+ ck_ge_1,
+ ck_ge_2,
+ ck_ge_3,
+ ck_lt_1,
+ ck_lt_2,
+ ck_lt_3,
+ ck_le_1,
+ ck_le_2,
+ ck_le_3,
+ ]
+
+class Ftype_Integer(Test):
+ """Tests routines in ftype-integer.c"""
+
+ def ck_eq_1(self):
+ return self.DFilterCount(pkt_ntp,
+ "ip.version == 4", 1)
+
+ def ck_eq_2(self):
+ return self.DFilterCount(pkt_ntp,
+ "ip.version == 6", 0)
+
+ def ck_ne_1(self):
+ return self.DFilterCount(pkt_ntp,
+ "ip.version != 0", 1)
+
+ def ck_ne_2(self):
+ return self.DFilterCount(pkt_ntp,
+ "ip.version != 4", 0)
+
+ def ck_u_gt_1(self):
+ return self.DFilterCount(pkt_ntp,
+ "ip.version > 3", 1)
+
+ def ck_u_gt_2(self):
+ return self.DFilterCount(pkt_ntp,
+ "ip.version > 4", 0)
+
+ def ck_u_gt_3(self):
+ return self.DFilterCount(pkt_ntp,
+ "ip.version > 5", 0)
+
+ def ck_u_ge_1(self):
+ return self.DFilterCount(pkt_ntp,
+ "ip.version >= 3", 1)
+
+ def ck_u_ge_2(self):
+ return self.DFilterCount(pkt_ntp,
+ "ip.version >= 4", 1)
+
+ def ck_u_ge_3(self):
+ return self.DFilterCount(pkt_ntp,
+ "ip.version >= 5", 0)
+
+ def ck_u_lt_1(self):
+ return self.DFilterCount(pkt_ntp,
+ "ip.version < 3", 0)
+
+ def ck_u_lt_2(self):
+ return self.DFilterCount(pkt_ntp,
+ "ip.version < 4", 0)
+
+ def ck_u_lt_3(self):
+ return self.DFilterCount(pkt_ntp,
+ "ip.version < 5", 1)
+
+ def ck_u_le_1(self):
+ return self.DFilterCount(pkt_ntp,
+ "ip.version <= 3", 0)
+
+ def ck_u_le_2(self):
+ return self.DFilterCount(pkt_ntp,
+ "ip.version <= 4", 1)
+
+ def ck_u_le_3(self):
+ return self.DFilterCount(pkt_ntp,
+ "ip.version <= 5", 1)
+
+ def ck_s_gt_1(self):
+ return self.DFilterCount(pkt_ntp,
+ "ntp.precision > -12", 1)
+
+ def ck_s_gt_2(self):
+ return self.DFilterCount(pkt_ntp,
+ "ntp.precision > -11", 0)
+
+ def ck_s_gt_3(self):
+ return self.DFilterCount(pkt_ntp,
+ "ntp.precision > -10", 0)
+
+ def ck_s_ge_1(self):
+ return self.DFilterCount(pkt_ntp,
+ "ntp.precision >= -12", 1)
+
+ def ck_s_ge_2(self):
+ return self.DFilterCount(pkt_ntp,
+ "ntp.precision >= -11", 1)
+
+ def ck_s_ge_3(self):
+ return self.DFilterCount(pkt_ntp,
+ "ntp.precision >= -10", 0)
+
+ def ck_s_lt_1(self):
+ return self.DFilterCount(pkt_ntp,
+ "ntp.precision < -12", 0)
+
+ def ck_s_lt_2(self):
+ return self.DFilterCount(pkt_ntp,
+ "ntp.precision < -11", 0)
+
+ def ck_s_lt_3(self):
+ return self.DFilterCount(pkt_ntp,
+ "ntp.precision < -10", 1)
+
+ def ck_s_le_1(self):
+ return self.DFilterCount(pkt_ntp,
+ "ntp.precision <= -12", 0)
+
+ def ck_s_le_2(self):
+ return self.DFilterCount(pkt_ntp,
+ "ntp.precision <= -11", 1)
+
+ def ck_s_le_3(self):
+ return self.DFilterCount(pkt_ntp,
+ "ntp.precision <= -10", 1)
+
+ def ck_bool_eq_1(self):
+ return self.DFilterCount(pkt_ntp,
+ "ip.flags.df == 0", 1)
+
+ def ck_bool_eq_2(self):
+ return self.DFilterCount(pkt_ntp,
+ "ip.flags.df == 1", 0)
+
+ def ck_bool_ne_1(self):
+ return self.DFilterCount(pkt_ntp,
+ "ip.flags.df != 1", 1)
+
+ def ck_bool_ne_2(self):
+ return self.DFilterCount(pkt_ntp,
+ "ip.flags.df != 0", 0)
+
+ def ck_ipx_1(self):
+ return self.DFilterCount(pkt_ipx_rip,
+ "ipx.src.net == 0x28", 1)
+
+ def ck_ipx_2(self):
+ return self.DFilterCount(pkt_ipx_rip,
+ "ipx.src.net == 0x29", 0)
+
+
+ tests = [
+ ck_eq_1,
+ ck_eq_2,
+ ck_ne_1,
+ ck_ne_2,
+ ck_u_gt_1,
+ ck_u_gt_2,
+ ck_u_gt_3,
+ ck_u_ge_1,
+ ck_u_ge_2,
+ ck_u_ge_3,
+ ck_u_lt_1,
+ ck_u_lt_2,
+ ck_u_lt_3,
+ ck_u_le_1,
+ ck_u_le_2,
+ ck_u_le_3,
+ ck_s_gt_1,
+ ck_s_gt_2,
+ ck_s_gt_3,
+ ck_s_ge_1,
+ ck_s_ge_2,
+ ck_s_ge_3,
+ ck_s_lt_1,
+ ck_s_lt_2,
+ ck_s_lt_3,
+ ck_s_le_1,
+ ck_s_le_2,
+ ck_s_le_3,
+ ck_bool_eq_1,
+ ck_bool_eq_2,
+ ck_bool_ne_1,
+ ck_bool_ne_2,
+ ck_ipx_1,
+ ck_ipx_2,
+ ]
+
+class Ftype_IPv4(Test):
+ """Tests routines in ftype-ipv4.c"""
+
+ def ck_eq_1(self):
+ return self.DFilterCount(pkt_nfs,
+ "ip.src == 172.25.100.14", 1)
+
+ def ck_eq_2(self):
+ return self.DFilterCount(pkt_nfs,
+ "ip.src == 255.255.255.255", 0)
+
+ def ck_ne_1(self):
+ return self.DFilterCount(pkt_nfs,
+ "ip.src != 172.25.100.14", 1)
+
+ def ck_ne_2(self):
+ return self.DFilterCount(pkt_nfs,
+ "ip.src != 255.255.255.255", 2)
+
+ def ck_gt_1(self):
+ return self.DFilterCount(pkt_nfs,
+ "ip.dst > 198.95.230.200", 0)
+
+ def ck_gt_2(self):
+ return self.DFilterCount(pkt_nfs,
+ "ip.dst > 198.95.230.20", 0)
+
+ def ck_gt_3(self):
+ return self.DFilterCount(pkt_nfs,
+ "ip.dst > 198.95.230.10", 1)
+
+ def ck_ge_1(self):
+ return self.DFilterCount(pkt_nfs,
+ "ip.dst >= 198.95.230.200", 0)
+
+ def ck_ge_2(self):
+ return self.DFilterCount(pkt_nfs,
+ "ip.dst >= 198.95.230.20", 1)
+
+ def ck_ge_3(self):
+ return self.DFilterCount(pkt_nfs,
+ "ip.dst >= 198.95.230.10", 1)
+
+ def ck_lt_1(self):
+ return self.DFilterCount(pkt_nfs,
+ "ip.src < 172.25.100.140", 1)
+
+ def ck_lt_2(self):
+ return self.DFilterCount(pkt_nfs,
+ "ip.src < 172.25.100.14", 0)
+
+ def ck_lt_3(self):
+ return self.DFilterCount(pkt_nfs,
+ "ip.src < 172.25.100.10", 0)
+
+ def ck_le_1(self):
+ return self.DFilterCount(pkt_nfs,
+ "ip.src <= 172.25.100.140", 1)
+
+ def ck_le_2(self):
+ return self.DFilterCount(pkt_nfs,
+ "ip.src <= 172.25.100.14", 1)
+
+ def ck_le_3(self):
+ return self.DFilterCount(pkt_nfs,
+ "ip.src <= 172.25.100.10", 0)
+
+ def ck_cidr_eq_1(self):
+ return self.DFilterCount(pkt_nfs,
+ "ip.src == 172.25.100.14/32", 1)
+
+ def ck_cidr_eq_2(self):
+ return self.DFilterCount(pkt_nfs,
+ "ip.src == 172.25.100.0/24", 1)
+
+ def ck_cidr_eq_3(self):
+ return self.DFilterCount(pkt_nfs,
+ "ip.src == 172.25.0.0/16", 1)
+
+ def ck_cidr_eq_4(self):
+ return self.DFilterCount(pkt_nfs,
+ "ip.src == 172.0.0.0/8", 1)
+
+ def ck_cidr_ne_1(self):
+ return self.DFilterCount(pkt_nfs,
+ "ip.src != 172.25.100.14/32", 1)
+
+ def ck_cidr_ne_2(self):
+ return self.DFilterCount(pkt_nfs,
+ "ip.src != 172.25.100.0/24", 1)
+
+ def ck_cidr_ne_3(self):
+ return self.DFilterCount(pkt_nfs,
+ "ip.src != 172.25.0.0/16", 1)
+
+ def ck_cidr_ne_4(self):
+ return self.DFilterCount(pkt_nfs,
+ "ip.src != 200.0.0.0/8", 2)
+
+ tests = [
+ ck_eq_1,
+ ck_eq_2,
+ ck_ne_1,
+ ck_ne_2,
+ ck_gt_1,
+ ck_gt_2,
+ ck_gt_3,
+ ck_ge_1,
+ ck_ge_2,
+ ck_ge_3,
+ ck_lt_1,
+ ck_lt_2,
+ ck_lt_3,
+ ck_le_1,
+ ck_le_2,
+ ck_le_3,
+ ck_cidr_eq_1,
+ ck_cidr_eq_2,
+ ck_cidr_eq_3,
+ ck_cidr_eq_4,
+ ck_cidr_ne_1,
+ ck_cidr_ne_2,
+ ck_cidr_ne_3,
+ ck_cidr_ne_4,
+ ]
+
+class Ftype_String(Test):
+ """Tests routines in ftype-string.c"""
+
+ def ck_eq_1(self):
+ return self.DFilterCount(pkt_http,
+ 'http.request.method == "HEAD"', 1)
+
+ def ck_eq_2(self):
+ return self.DFilterCount(pkt_http,
+ 'http.request.method == "POST"', 0)
+
+ def ck_gt_1(self):
+ return self.DFilterCount(pkt_http,
+ 'http.request.method > "HEAC"', 1)
+
+ def ck_gt_2(self):
+ return self.DFilterCount(pkt_http,
+ 'http.request.method > "HEAD"', 0)
+
+ def ck_gt_3(self):
+ return self.DFilterCount(pkt_http,
+ 'http.request.method > "HEAE"', 0)
+
+ def ck_ge_1(self):
+ return self.DFilterCount(pkt_http,
+ 'http.request.method >= "HEAC"', 1)
+
+ def ck_ge_2(self):
+ return self.DFilterCount(pkt_http,
+ 'http.request.method >= "HEAD"', 1)
+
+ def ck_ge_3(self):
+ return self.DFilterCount(pkt_http,
+ 'http.request.method >= "HEAE"', 0)
+
+ def ck_lt_1(self):
+ return self.DFilterCount(pkt_http,
+ 'http.request.method < "HEAC"', 0)
+
+ def ck_lt_2(self):
+ return self.DFilterCount(pkt_http,
+ 'http.request.method < "HEAD"', 0)
+
+ def ck_lt_3(self):
+ return self.DFilterCount(pkt_http,
+ 'http.request.method < "HEAE"', 1)
+
+ def ck_le_1(self):
+ return self.DFilterCount(pkt_http,
+ 'http.request.method <= "HEAC"', 0)
+
+ def ck_le_2(self):
+ return self.DFilterCount(pkt_http,
+ 'http.request.method <= "HEAD"', 1)
+
+ def ck_le_3(self):
+ return self.DFilterCount(pkt_http,
+ 'http.request.method <= "HEAE"', 1)
+
+ # XXX - this isn't handled in ethereal yet
+ def ck_slice_1(self):
+ return self.DFilterCount(pkt_http,
+ 'http.request.method[0] == "H"', 1)
+
+ def ck_slice_2(self):
+ return self.DFilterCount(pkt_http,
+ 'http.request.method[0] == "P"', 0)
+
+ def ck_slice_3(self):
+ return self.DFilterCount(pkt_http,
+ 'http.request.method[0:4] == "HEAD"', 1)
+
+ def ck_slice_4(self):
+ return self.DFilterCount(pkt_http,
+ 'http.request.method[0:4] != "HEAD"', 0)
+
+ def ck_slice_5(self):
+ return self.DFilterCount(pkt_http,
+ 'http.request.method[1:2] == "EA"', 1)
+
+ def ck_slice_6(self):
+ return self.DFilterCount(pkt_http,
+ 'http.request.method[1:2] > "EA"', 0)
+
+ def ck_slice_7(self):
+ return self.DFilterCount(pkt_http,
+ 'http.request.method[-1] == "D"', 1)
+
+ def ck_slice_8(self):
+ return self.DFilterCount(pkt_http,
+ 'http.request.method[-2] == "D"', 0)
+
+ def ck_stringz_1(self):
+ return self.DFilterCount(pkt_tftp,
+ 'tftp.type == "octet"', 1)
+
+ def ck_stringz_2(self):
+ return self.DFilterCount(pkt_tftp,
+ 'tftp.type == "junk"', 0)
+
+
+
+ tests = [
+ ck_eq_1,
+ ck_eq_2,
+ ck_gt_1,
+ ck_gt_2,
+ ck_gt_3,
+ ck_ge_1,
+ ck_ge_2,
+ ck_ge_3,
+ ck_lt_1,
+ ck_lt_2,
+ ck_lt_3,
+ ck_le_1,
+ ck_le_2,
+ ck_le_3,
+# XXX
+# ck_slice_1,
+# ck_slice_2,
+# ck_slice_3,
+# ck_slice_4,
+# ck_slice_5,
+# ck_slice_6,
+# ck_slice_7,
+# ck_slice_8,
+ ck_stringz_1,
+ ck_stringz_2,
+ ]
+
+
+class Ftype_Time(Test):
+ """Tests routines in ftype-time.c"""
+
+ def ck_eq_1(self):
+ return self.DFilterCount(pkt_http,
+ 'frame.time == "Dec 31, 2002 07:55:31.3"', 1)
+
+ def ck_eq_2(self):
+ return self.DFilterCount(pkt_http,
+ 'frame.time == "Jan 31, 2002 07:55:31.3"', 0)
+
+ def ck_ne_1(self):
+ return self.DFilterCount(pkt_http,
+ 'frame.time != "Dec 31, 2002 07:55:31.3"', 0)
+
+ def ck_ne_2(self):
+ return self.DFilterCount(pkt_http,
+ 'frame.time != "Jan 31, 2002 07:55:31.3"', 1)
+
+ def ck_gt_1(self):
+ return self.DFilterCount(pkt_http,
+ 'frame.time > "Dec 31, 2002 07:54:31.3"', 1)
+
+ def ck_gt_2(self):
+ return self.DFilterCount(pkt_http,
+ 'frame.time > "Dec 31, 2002 07:55:31.3"', 0)
+
+ def ck_gt_3(self):
+ return self.DFilterCount(pkt_http,
+ 'frame.time > "Dec 31, 2002 07:56:31.3"', 0)
+
+ def ck_ge_1(self):
+ return self.DFilterCount(pkt_http,
+ 'frame.time >= "Dec 31, 2002 07:54:31.3"', 1)
+
+ def ck_ge_2(self):
+ return self.DFilterCount(pkt_http,
+ 'frame.time >= "Dec 31, 2002 07:55:31.3"', 1)
+
+ def ck_ge_3(self):
+ return self.DFilterCount(pkt_http,
+ 'frame.time >= "Dec 31, 2002 07:56:31.3"', 0)
+
+ def ck_lt_1(self):
+ return self.DFilterCount(pkt_http,
+ 'frame.time < "Dec 31, 2002 07:54:31.3"', 0)
+
+ def ck_lt_2(self):
+ return self.DFilterCount(pkt_http,
+ 'frame.time < "Dec 31, 2002 07:55:31.3"', 0)
+
+ def ck_lt_3(self):
+ return self.DFilterCount(pkt_http,
+ 'frame.time < "Dec 31, 2002 07:56:31.3"', 1)
+
+ def ck_le_1(self):
+ return self.DFilterCount(pkt_http,
+ 'frame.time <= "Dec 31, 2002 07:54:31.3"', 0)
+
+ def ck_le_2(self):
+ return self.DFilterCount(pkt_http,
+ 'frame.time <= "Dec 31, 2002 07:55:31.3"', 1)
+
+ def ck_le_3(self):
+ return self.DFilterCount(pkt_http,
+ 'frame.time <= "Dec 31, 2002 07:56:31.3"', 1)
+
+ def ck_relative_time_1(self):
+ return self.DFilterCount(pkt_nfs,
+ "frame.time_delta == 0.7", 1)
+
+ def ck_relative_time_2(self):
+ return self.DFilterCount(pkt_nfs,
+ "frame.time_delta > 0.7", 0)
+
+ def ck_relative_time_3(self):
+ return self.DFilterCount(pkt_nfs,
+ "frame.time_delta < 0.7", 1)
+
+ tests = [
+ ck_eq_1,
+ ck_eq_2,
+ ck_ne_1,
+ ck_ne_2,
+ ck_gt_1,
+ ck_gt_2,
+ ck_gt_3,
+ ck_ge_1,
+ ck_ge_2,
+ ck_ge_3,
+ ck_lt_1,
+ ck_lt_2,
+ ck_lt_3,
+ ck_le_1,
+ ck_le_2,
+ ck_le_3,
+ ck_relative_time_1,
+ ck_relative_time_2,
+ ck_relative_time_3,
+ ]
+
+class Ftype_TVB(Test):
+ """Tests routines in ftype-tvb.c"""
+
+ def ck_slice_1(self):
+ return self.DFilterCount(pkt_http,
+ "ip[0:2] == 45:00", 1)
+
+ def ck_slice_2(self):
+ return self.DFilterCount(pkt_http,
+ "ip[0:2] == 00:00", 0)
+
+ def ck_slice_3(self):
+ return self.DFilterCount(pkt_http,
+ "ip[2:2] == 00:c1", 1)
+
+ # These don't work yet in Ethereal
+ def ck_slice_4(self):
+ return self.DFilterCount(pkt_http,
+ "ip[-5] == 0x86", 1)
+
+ def ck_slice_5(self):
+ return self.DFilterCount(pkt_http,
+ "ip[-1] == 0x86", 0)
+
+
+
+ tests = [
+ ck_slice_1,
+ ck_slice_2,
+ ck_slice_3,
+# XXX
+# ck_slice_4,
+# ck_slice_5,
+ ]
+
+################################################################################
+
+def usage():
+ print "usage: %s [OPTS]" % (sys.argv[0],)
+ print "\t-p PATH : path to find both tethereal and text2pcap (DEFAULT: . )"
+ print "\t-t FILE : location of tethereal binary"
+ print "\t-x FILE : location of text2pcap binary"
+ print "\t-k : keep temporary files"
+ print "\t-v : verbose"
+ sys.exit(1)
+
+def main():
+
+ global TETHEREAL
+ global TEXT2PCAP
+ global VERBOSE
+ global REMOVE_TEMP_FILES
+
+ # Parse the command-line options
+ optstring = "p:t:x:kv"
+ longopts = []
+
+ try:
+ opts, args = getopt.getopt(sys.argv[1:], optstring, longopts)
+ except getopt.GetoptError:
+ usage()
+
+ for opt, arg in opts:
+ if opt == "-t":
+ TETHEREAL = arg
+ elif opt == "-x":
+ TEXT2PCAP = arg
+ elif opt == "-v":
+ VERBOSE = 1
+ elif opt == "-p":
+ TEXT2PCAP = os.path.join(arg, "text2pcap")
+ TETHEREAL = os.path.join(arg, "tethereal")
+ elif opt == "-k":
+ REMOVE_TEMP_FILES = 0
+ else:
+ print "Un-handled option:", opt
+ usage()
+
+ # Sanity test
+ if not os.path.exists(TETHEREAL):
+ sys.exit("tethereal program '%s' does not exist." % (TETHEREAL,))
+
+ if not os.path.exists(TEXT2PCAP):
+ sys.exit("text2pcap program '%s' does not exist." % (TEXT2PCAP,))
+
+
+ # These are the test objects to run.
+ tests = [
+ Ftype_Bytes(),
+ Ftype_Double(),
+ Ftype_Integer(),
+ Ftype_IPv4(),
+ Ftype_String(),
+ Ftype_Time(),
+ Ftype_TVB(),
+ ]
+
+ # Run the tests and keep score.
+ tot_run = 0
+ tot_succeeded = 0
+
+ for test in tests:
+ print test.__class__.__name__
+ (run, succeeded) = test.Run()
+ tot_run += run
+ tot_succeeded += succeeded
+ print
+
+ print
+ print "Total Tests Run:", tot_run
+ print "Total Tests Succeeded:", tot_succeeded
+ print "Total Tests Failed:", tot_run - tot_succeeded
+
+ if tot_succeeded == tot_run:
+ sys.exit(0)
+ else:
+ sys.exit(1)
+
+if __name__ == "__main__":
+ try:
+ main()
+ except KeyboardInterrupt:
+ print "\nInterrupted by user."