3 # Copyright 2014 Roland Knall <rknall [AT] gmail.com>
5 # Wireshark - Network traffic analyzer
6 # By Gerald Combs <gerald@wireshark.org>
7 # Copyright 1998 Gerald Combs
9 # This program is free software; you can redistribute it and/or
10 # modify it under the terms of the GNU General Public License
11 # as published by the Free Software Foundation; either version 2
12 # of the License, or (at your option) any later version.
14 # This program is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 # GNU General Public License for more details.
19 # You should have received a copy of the GNU General Public License
20 # along with this program; if not, write to the Free Software
21 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 This is a generic example, which produces pcap packages every n seconds, and
25 is configurable via extcap options.
29 To use this script on Windows, please generate an extcap_example.bat inside
30 the extcap folder, with the following content:
34 <Path to python interpreter> <Path to script file> %*
37 Windows is not able to execute Python scripts directly, which also goes for all
38 other script-based formates beside VBScript
51 from threading import Thread
61 def signalHandler(signal, frame):
65 #### EXTCAP FUNCTIONALITY
67 """@brief Extcap configuration
68 This method prints the extcap configuration, which will be picked up by the
69 interface in Wireshark to present a interface specific configuration for
72 def extcap_config(interface):
76 args.append ( (0, '--delay', 'Time delay', 'Time delay between packages', 'integer', '{range=1,15}') )
77 args.append ( (1, '--message', 'Message', 'Package message content', 'string', '{required=true}') )
78 args.append ( (2, '--verify', 'Verify', 'Verify package content', 'boolflag', '') )
79 args.append ( (3, '--remote', 'Remote Channel', 'Remote Channel Selector', 'selector', ''))
80 args.append ( (4, '--fake_ip', 'Fake IP Address', 'Use this ip address as sender', 'string', '{validation=\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b}'))
82 values.append ( (3, "if1", "Remote1", "true" ) )
83 values.append ( (3, "if2", "Remote2", "false" ) )
86 print ("arg {number=%d}{call=%s}{display=%s}{tooltip=%s}{type=%s}%s" % arg)
89 print ("value {arg=%d}{value=%s}{display=%s}{default=%s}" % value)
92 def extcap_interfaces():
93 print ("interface {value=example1}{display=Example interface usage for extcap}")
95 def extcap_dlts(interface):
96 if ( interface == '1' ):
97 print ("dlt {number=147}{name=USER0}{display=Demo Implementation for Extcap}")
101 ### FAKE DATA GENERATOR
103 Extcap capture routine
104 This routine simulates a capture by any kind of user defined device. The parameters
105 are user specified and must be handled by the extcap.
107 The data captured inside this routine is fake, so change this routine to present
108 your own input data, or call your own capture program via Popen for example. See
114 return int(n) & 0xFFFFFFFF
116 def append_bytes(ba, blist):
117 for c in range(0, len(blist)):
121 def pcap_fake_header():
124 header = append_bytes(header, struct.pack('<L', int ('a1b2c3d4', 16) ))
125 header = append_bytes(header, struct.pack('<H', unsigned(2)) ) # Pcap Major Version
126 header = append_bytes(header, struct.pack('<H', unsigned(4)) ) # Pcap Minor Version
127 header = append_bytes(header, struct.pack('<I', int(0))) # Timezone
128 header = append_bytes(header, struct.pack('<I', int(0))) # Accurancy of timestamps
129 header = append_bytes(header, struct.pack('<L', int ('0000ffff', 16) )) # Max Length of capture frame
130 header = append_bytes(header, struct.pack('<L', unsigned(1))) # Ethernet
133 # Calculates and returns the IP checksum based on the given IP Header
134 def ip_checksum(iph):
136 words = splitN(''.join(iph.split()),4)
139 csum += int(word, base=16)
141 csum = csum & 0xFFFF ^ 0xFFFF
144 def pcap_fake_package ( message, fake_ip ):
147 #length = 14 bytes [ eth ] + 20 bytes [ ip ] + messagelength
149 caplength = len(message) + 14 + 20
150 timestamp = int(time.time())
152 pcap = append_bytes(pcap, struct.pack('<L', unsigned(timestamp) ) ) # timestamp seconds
153 pcap = append_bytes(pcap, struct.pack('<L', 0x00 ) ) # timestamp nanoseconds
154 pcap = append_bytes(pcap, struct.pack('<L', unsigned(caplength) ) ) # length captured
155 pcap = append_bytes(pcap, struct.pack('<L', unsigned(caplength) ) ) # length in frame
158 pcap = append_bytes(pcap, struct.pack('h', 0 )) # source mac
159 pcap = append_bytes(pcap, struct.pack('h', 0 )) # source mac
160 pcap = append_bytes(pcap, struct.pack('h', 0 )) # source mac
161 pcap = append_bytes(pcap, struct.pack('h', 0 )) # dest mac
162 pcap = append_bytes(pcap, struct.pack('h', 0 )) # dest mac
163 pcap = append_bytes(pcap, struct.pack('h', 0 )) # dest mac
164 pcap = append_bytes(pcap, struct.pack('<h', unsigned(8) )) # protocol (ip)
167 pcap = append_bytes(pcap, struct.pack('b', int ( '45', 16) )) # IP version
168 pcap = append_bytes(pcap, struct.pack('b', int ( '0', 16) )) #
169 pcap = append_bytes(pcap, struct.pack('>H', unsigned(len(message)+20) )) # length of data + payload
170 pcap = append_bytes(pcap, struct.pack('<H', int ( '0', 16) )) # Identification
171 pcap = append_bytes(pcap, struct.pack('b', int ( '40', 16) )) # Don't fragment
172 pcap = append_bytes(pcap, struct.pack('b', int ( '0', 16) )) # Fragment Offset
173 pcap = append_bytes(pcap, struct.pack('b', int ( '40', 16) ))
174 pcap = append_bytes(pcap, struct.pack('B', 0xFE )) # Protocol (2 = unspecified)
175 pcap = append_bytes(pcap, struct.pack('<H', int ( '0000', 16) )) # Checksum
177 parts = fake_ip.split('.')
178 ipadr = (int(parts[0]) << 24) + (int(parts[1]) << 16) + (int(parts[2]) << 8) + int(parts[3])
179 pcap = append_bytes(pcap, struct.pack('>L', ipadr )) # Source IP
180 pcap = append_bytes(pcap, struct.pack('>L', int ( '7F000001', 16) )) # Dest IP
182 pcap = append_bytes(pcap, message)
185 def extcap_capture(interface, fifo, delay, verify, message, remote, fake_ip):
188 signal.signal(signal.SIGINT, signalHandler)
189 signal.signal(signal.SIGTERM , signalHandler)
191 tdelay = delay if delay != 0 else 5
197 print ( "Fifo does not exist, exiting!" )
199 fh = open(fifo, 'w+b', 0 )
200 fh.write (pcap_fake_header())
202 while doExit == False:
203 out = str( "%s|%04X%s|%s" % ( remote.strip(), len(message), message, verify ) )
205 fh.write (pcap_fake_package(out, fake_ip))
215 print ( "Usage: %s <--extcap-interfaces | --extcap-dlts | --extcap-interface | --extcap-config | --capture | --extcap-capture-filter | --fifo>" % sys.argv[0] )
217 if __name__ == '__main__':
225 parser = argparse.ArgumentParser(
226 prog="Extcap Example",
227 description="Extcap example program for python"
231 parser.add_argument("--capture", help="Start the capture routine", action="store_true" )
232 parser.add_argument("--extcap-interfaces", help="Provide a list of interfaces to capture from", action="store_true")
233 parser.add_argument("--extcap-interface", help="Provide the interface to capture from")
234 parser.add_argument("--extcap-dlts", help="Provide a list of dlts for the given interface", action="store_true")
235 parser.add_argument("--extcap-config", help="Provide a list of configurations for the given interface", action="store_true")
236 parser.add_argument("--extcap-capture-filter", help="Used together with capture to provide a capture filter")
237 parser.add_argument("--fifo", help="Use together with capture to provide the fifo to dump data to")
239 # Interface Arguments
240 parser.add_argument("--verify", help="Demonstrates a verification bool flag", action="store_true" )
241 parser.add_argument("--delay", help="Demonstrates an integer variable", type=int, default=0, choices=[0, 1, 2, 3, 4, 5] )
242 parser.add_argument("--remote", help="Demonstrates a selector choice", default="if1", choices=["if1", "if2"] )
243 parser.add_argument("--message", help="Demonstrates string variable", nargs='?', default="" )
244 parser.add_argument("--fake_ip", help="Add a fake sender IP adress", nargs='?', default="127.0.0.1" )
246 args, unknown = parser.parse_known_args()
247 if ( len(sys.argv) <= 1 ):
248 parser.exit("No arguments given!")
250 if ( args.extcap_interfaces == False and args.extcap_interface == None ):
251 parser.exit("An interface must be provided or the selection must be displayed")
253 if ( args.extcap_interfaces == True or args.extcap_interface == None ):
257 if ( len(unknown) > 1 ):
258 print("Extcap Example %d unknown arguments given" % len(unknown) )
260 m = re.match ( 'example(\d+)', args.extcap_interface )
262 sys.exit(ERROR_INTERFACE)
263 interface = m.group(1)
265 message = args.message
266 if ( args.message == None or len(args.message) == 0 ):
267 message = "Extcap Test"
269 fake_ip = args.fake_ip
270 if ( args.fake_ip == None or len(args.fake_ip) < 7 or len(args.fake_ip.split('.')) != 4 ):
271 fake_ip = "127.0.0.1"
273 if args.extcap_config:
274 extcap_config(interface)
275 elif args.extcap_dlts:
276 extcap_dlts(interface)
278 if args.fifo is None:
280 extcap_capture(interface, args.fifo, args.delay, args.verify, message, args.remote, fake_ip)
283 sys.exit(ERROR_USAGE)