2014-02-25 13:05:11 +00:00
#!/usr/bin/env python
2014-08-21 14:41:22 +00:00
# Copyright 2014 Roland Knall <rknall [AT] gmail.com>
#
# Wireshark - Network traffic analyzer
# By Gerald Combs <gerald@wireshark.org>
# Copyright 1998 Gerald Combs
#
# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
2014-02-25 13:05:11 +00:00
"""
This is a generic example , which produces pcap packages every n seconds , and
is configurable via extcap options .
@note
{
To use this script on Windows , please generate an extcap_example . bat inside
the extcap folder , with the following content :
- - - - - - -
@echo off
2015-12-07 12:42:26 +00:00
< Path to python interpreter > < Path to script file > % *
2014-02-25 13:05:11 +00:00
- - - - - - -
Windows is not able to execute Python scripts directly , which also goes for all
other script - based formates beside VBScript
}
"""
2016-01-04 17:32:39 +00:00
from __future__ import print_function
2014-02-25 13:05:11 +00:00
import os
import sys
import signal
import re
import argparse
import time
import struct
import binascii
from threading import Thread
ERROR_USAGE = 0
ERROR_ARG = 1
2016-01-04 17:32:39 +00:00
ERROR_INTERFACE = 2
2014-02-25 13:05:11 +00:00
ERROR_FIFO = 3
2016-01-04 17:32:39 +00:00
ERROR_DELAY = 4
2014-02-25 13:05:11 +00:00
doExit = False
globalinterface = 0
2016-01-04 17:32:39 +00:00
"""
This code has been taken from http : / / stackoverflow . com / questions / 5943249 / python - argparse - and - controlling - overriding - the - exit - status - code - originally developed by Rob Cowie http : / / stackoverflow . com / users / 46690 / rob - cowie
"""
class ArgumentParser ( argparse . ArgumentParser ) :
def _get_action_from_name ( self , name ) :
""" Given a name, get the Action instance registered with this parser.
If only it were made available in the ArgumentError object . It is
passed as it ' s first arg...
"""
container = self . _actions
if name is None :
return None
for action in container :
if ' / ' . join ( action . option_strings ) == name :
return action
elif action . metavar == name :
return action
elif action . dest == name :
return action
def error ( self , message ) :
exc = sys . exc_info ( ) [ 1 ]
if exc :
exc . argument = self . _get_action_from_name ( exc . argument_name )
raise exc
super ( ArgumentParser , self ) . error ( message )
2014-02-25 13:05:11 +00:00
def signalHandler ( signal , frame ) :
global doExit
doExit = True
#### EXTCAP FUNCTIONALITY
""" @brief Extcap configuration
This method prints the extcap configuration , which will be picked up by the
interface in Wireshark to present a interface specific configuration for
this extcap plugin
"""
def extcap_config ( interface ) :
args = [ ]
values = [ ]
2016-01-28 09:41:38 +00:00
args . append ( ( 0 , ' --delay ' , ' Time delay ' , ' Time delay between packages ' , ' integer ' , ' { range=1,15} { default=5} ' ) )
2015-12-29 14:35:43 +00:00
args . append ( ( 1 , ' --message ' , ' Message ' , ' Package message content ' , ' string ' , ' { required=true} ' ) )
2016-01-28 09:41:38 +00:00
args . append ( ( 2 , ' --verify ' , ' Verify ' , ' Verify package content ' , ' boolflag ' , ' { default=yes} ' ) )
2014-02-25 13:05:11 +00:00
args . append ( ( 3 , ' --remote ' , ' Remote Channel ' , ' Remote Channel Selector ' , ' selector ' , ' ' ) )
2016-01-28 09:41:38 +00:00
args . append ( ( 4 , ' --fake_ip ' , ' Fake IP Address ' , ' Use this ip address as sender ' , ' string ' , ' { save=false} { 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} ' ) )
2015-12-29 06:57:36 +00:00
args . append ( ( 5 , ' --ltest ' , ' Long Test ' , ' Long Test Value ' , ' long ' , ' { default=123123123123123123} ' ) )
args . append ( ( 6 , ' --d1test ' , ' Double 1 Test ' , ' Long Test Value ' , ' double ' , ' { default=123.456} ' ) )
args . append ( ( 7 , ' --d2test ' , ' Double 2 Test ' , ' Long Test Value ' , ' double ' , ' { default= 123,456} ' ) )
args . append ( ( 8 , ' --password ' , ' Password ' , ' Package message password ' , ' password ' , ' ' ) )
2014-02-25 13:05:11 +00:00
values . append ( ( 3 , " if1 " , " Remote1 " , " true " ) )
values . append ( ( 3 , " if2 " , " Remote2 " , " false " ) )
for arg in args :
print ( " arg { number= %d } { call= %s } { display= %s } { tooltip= %s } { type= %s } %s " % arg )
for value in values :
print ( " value { arg= %d } { value= %s } { display= %s } { default= %s } " % value )
def extcap_interfaces ( ) :
2016-09-05 05:54:47 +00:00
print ( " extcap { version=1.0} { help=http://www.wireshark.org} " )
2014-02-25 13:05:11 +00:00
print ( " interface { value=example1} { display=Example interface usage for extcap} " )
def extcap_dlts ( interface ) :
2014-10-08 17:45:11 +00:00
if ( interface == ' 1 ' ) :
2014-02-25 13:05:11 +00:00
print ( " dlt { number=147} { name=USER0} { display=Demo Implementation for Extcap} " )
"""
### FAKE DATA GENERATOR
Extcap capture routine
This routine simulates a capture by any kind of user defined device . The parameters
are user specified and must be handled by the extcap .
The data captured inside this routine is fake , so change this routine to present
your own input data , or call your own capture program via Popen for example . See
for more details .
"""
def unsigned ( n ) :
return int ( n ) & 0xFFFFFFFF
def pcap_fake_header ( ) :
header = bytearray ( )
2016-10-16 09:59:32 +00:00
header + = struct . pack ( ' <L ' , int ( ' a1b2c3d4 ' , 16 ) )
header + = struct . pack ( ' <H ' , unsigned ( 2 ) ) # Pcap Major Version
header + = struct . pack ( ' <H ' , unsigned ( 4 ) ) # Pcap Minor Version
header + = struct . pack ( ' <I ' , int ( 0 ) ) # Timezone
header + = struct . pack ( ' <I ' , int ( 0 ) ) # Accurancy of timestamps
header + = struct . pack ( ' <L ' , int ( ' 0000ffff ' , 16 ) ) # Max Length of capture frame
header + = struct . pack ( ' <L ' , unsigned ( 1 ) ) # Ethernet
2014-02-25 13:05:11 +00:00
return header
# Calculates and returns the IP checksum based on the given IP Header
def ip_checksum ( iph ) :
#split into bytes
words = splitN ( ' ' . join ( iph . split ( ) ) , 4 )
csum = 0 ;
for word in words :
csum + = int ( word , base = 16 )
csum + = ( csum >> 16 )
csum = csum & 0xFFFF ^ 0xFFFF
return csum
2015-12-29 14:35:43 +00:00
def pcap_fake_package ( message , fake_ip ) :
2014-02-25 13:05:11 +00:00
pcap = bytearray ( )
#length = 14 bytes [ eth ] + 20 bytes [ ip ] + messagelength
caplength = len ( message ) + 14 + 20
timestamp = int ( time . time ( ) )
2016-10-16 09:59:32 +00:00
pcap + = struct . pack ( ' <L ' , unsigned ( timestamp ) ) # timestamp seconds
pcap + = struct . pack ( ' <L ' , 0x00 ) # timestamp nanoseconds
pcap + = struct . pack ( ' <L ' , unsigned ( caplength ) ) # length captured
pcap + = struct . pack ( ' <L ' , unsigned ( caplength ) ) # length in frame
2014-02-25 13:05:11 +00:00
# ETH
2016-10-16 09:59:32 +00:00
pcap + = struct . pack ( ' h ' , 0 ) # source mac
pcap + = struct . pack ( ' h ' , 0 ) # source mac
pcap + = struct . pack ( ' h ' , 0 ) # source mac
pcap + = struct . pack ( ' h ' , 0 ) # dest mac
pcap + = struct . pack ( ' h ' , 0 ) # dest mac
pcap + = struct . pack ( ' h ' , 0 ) # dest mac
pcap + = struct . pack ( ' <h ' , unsigned ( 8 ) ) # protocol (ip)
2014-02-25 13:05:11 +00:00
# IP
2016-10-16 09:59:32 +00:00
pcap + = struct . pack ( ' b ' , int ( ' 45 ' , 16 ) ) # IP version
pcap + = struct . pack ( ' b ' , int ( ' 0 ' , 16 ) ) #
pcap + = struct . pack ( ' >H ' , unsigned ( len ( message ) + 20 ) ) # length of data + payload
pcap + = struct . pack ( ' <H ' , int ( ' 0 ' , 16 ) ) # Identification
pcap + = struct . pack ( ' b ' , int ( ' 40 ' , 16 ) ) # Don't fragment
pcap + = struct . pack ( ' b ' , int ( ' 0 ' , 16 ) ) # Fragment Offset
pcap + = struct . pack ( ' b ' , int ( ' 40 ' , 16 ) )
pcap + = struct . pack ( ' B ' , 0xFE ) # Protocol (2 = unspecified)
pcap + = struct . pack ( ' <H ' , int ( ' 0000 ' , 16 ) ) # Checksum
2015-12-29 14:35:43 +00:00
parts = fake_ip . split ( ' . ' )
ipadr = ( int ( parts [ 0 ] ) << 24 ) + ( int ( parts [ 1 ] ) << 16 ) + ( int ( parts [ 2 ] ) << 8 ) + int ( parts [ 3 ] )
2016-10-16 09:59:32 +00:00
pcap + = struct . pack ( ' >L ' , ipadr ) # Source IP
pcap + = struct . pack ( ' >L ' , int ( ' 7F000001 ' , 16 ) ) # Dest IP
2014-02-25 13:05:11 +00:00
2016-10-16 09:59:32 +00:00
pcap + = message
2014-02-25 13:05:11 +00:00
return pcap
2015-12-29 14:35:43 +00:00
def extcap_capture ( interface , fifo , delay , verify , message , remote , fake_ip ) :
2014-02-25 13:05:11 +00:00
global doExit
signal . signal ( signal . SIGINT , signalHandler )
signal . signal ( signal . SIGTERM , signalHandler )
tdelay = delay if delay != 0 else 5
try :
os . stat ( fifo )
except OSError :
doExit = True
print ( " Fifo does not exist, exiting! " )
fh = open ( fifo , ' w+b ' , 0 )
fh . write ( pcap_fake_header ( ) )
while doExit == False :
2016-10-16 09:59:32 +00:00
out = ( " %s | %04X %s | %s " % ( remote . strip ( ) , len ( message ) , message , verify ) ) . encode ( " utf8 " )
2014-02-25 13:05:11 +00:00
try :
2015-12-29 14:35:43 +00:00
fh . write ( pcap_fake_package ( out , fake_ip ) )
2014-02-25 13:05:11 +00:00
time . sleep ( tdelay )
except IOError :
doExit = True
fh . close ( )
2016-01-04 17:32:39 +00:00
def extcap_close_fifo ( interface , fifo ) :
global doExit
signal . signal ( signal . SIGINT , signalHandler )
signal . signal ( signal . SIGTERM , signalHandler )
tdelay = delay if delay != 0 else 5
try :
os . stat ( fifo )
except OSError :
doExit = True
print ( " Fifo does not exist! " )
fh = open ( fifo , ' w+b ' , 0 )
fh . close ( )
2014-02-25 13:05:11 +00:00
####
def usage ( ) :
2015-10-30 09:48:13 +00:00
print ( " Usage: %s <--extcap-interfaces | --extcap-dlts | --extcap-interface | --extcap-config | --capture | --extcap-capture-filter | --fifo> " % sys . argv [ 0 ] )
2014-02-25 13:05:11 +00:00
if __name__ == ' __main__ ' :
interface = " "
# Capture options
delay = 0
message = " "
2015-12-29 14:35:43 +00:00
fake_ip = " "
2014-02-25 13:05:11 +00:00
2016-01-04 17:32:39 +00:00
parser = ArgumentParser (
2014-02-25 13:05:11 +00:00
prog = " Extcap Example " ,
description = " Extcap example program for python "
)
# Extcap Arguments
parser . add_argument ( " --capture " , help = " Start the capture routine " , action = " store_true " )
parser . add_argument ( " --extcap-interfaces " , help = " Provide a list of interfaces to capture from " , action = " store_true " )
parser . add_argument ( " --extcap-interface " , help = " Provide the interface to capture from " )
parser . add_argument ( " --extcap-dlts " , help = " Provide a list of dlts for the given interface " , action = " store_true " )
parser . add_argument ( " --extcap-config " , help = " Provide a list of configurations for the given interface " , action = " store_true " )
2015-10-30 09:48:13 +00:00
parser . add_argument ( " --extcap-capture-filter " , help = " Used together with capture to provide a capture filter " )
2014-02-25 13:05:11 +00:00
parser . add_argument ( " --fifo " , help = " Use together with capture to provide the fifo to dump data to " )
# Interface Arguments
parser . add_argument ( " --verify " , help = " Demonstrates a verification bool flag " , action = " store_true " )
2016-01-04 17:32:39 +00:00
parser . add_argument ( " --delay " , help = " Demonstrates an integer variable " , type = int , default = 0 , choices = [ 0 , 1 , 2 , 3 , 4 , 5 , 6 ] )
2014-02-25 13:05:11 +00:00
parser . add_argument ( " --remote " , help = " Demonstrates a selector choice " , default = " if1 " , choices = [ " if1 " , " if2 " ] )
parser . add_argument ( " --message " , help = " Demonstrates string variable " , nargs = ' ? ' , default = " " )
2015-12-29 14:35:43 +00:00
parser . add_argument ( " --fake_ip " , help = " Add a fake sender IP adress " , nargs = ' ? ' , default = " 127.0.0.1 " )
2014-02-25 13:05:11 +00:00
2016-01-04 17:32:39 +00:00
try :
args , unknown = parser . parse_known_args ( )
2016-10-16 09:59:32 +00:00
except argparse . ArgumentError as exc :
2016-01-04 17:32:39 +00:00
print ( " %s : %s " % ( exc . argument . dest , exc . message ) , file = sys . stderr )
fifo_found = 0
fifo = " "
for arg in sys . argv :
if ( arg == " --fifo " or arg == " --extcap-fifo " ) :
fifo_found = 1
elif ( fifo_found == 1 ) :
fifo = arg
break
extcap_close_fifo ( " " , fifo )
sys . exit ( ERROR_ARG )
2014-02-25 13:05:11 +00:00
if ( len ( sys . argv ) < = 1 ) :
parser . exit ( " No arguments given! " )
if ( args . extcap_interfaces == False and args . extcap_interface == None ) :
parser . exit ( " An interface must be provided or the selection must be displayed " )
if ( args . extcap_interfaces == True or args . extcap_interface == None ) :
extcap_interfaces ( )
sys . exit ( 0 )
2014-10-13 11:26:21 +00:00
if ( len ( unknown ) > 1 ) :
print ( " Extcap Example %d unknown arguments given " % len ( unknown ) )
2014-02-25 13:05:11 +00:00
m = re . match ( ' example( \ d+) ' , args . extcap_interface )
if not m :
sys . exit ( ERROR_INTERFACE )
interface = m . group ( 1 )
message = args . message
if ( args . message == None or len ( args . message ) == 0 ) :
message = " Extcap Test "
2015-12-29 14:35:43 +00:00
fake_ip = args . fake_ip
if ( args . fake_ip == None or len ( args . fake_ip ) < 7 or len ( args . fake_ip . split ( ' . ' ) ) != 4 ) :
fake_ip = " 127.0.0.1 "
2014-02-25 13:05:11 +00:00
if args . extcap_config :
extcap_config ( interface )
elif args . extcap_dlts :
extcap_dlts ( interface )
elif args . capture :
if args . fifo is None :
sys . exit ( ERROR_FIFO )
2016-01-04 17:32:39 +00:00
# The following code demonstrates error management with extcap
if args . delay > 5 :
print ( " Value for delay [ %d ] too high " % args . delay , file = sys . stderr )
extcap_close_fifo ( interface , args . fifo )
sys . exit ( ERROR_DELAY )
2015-12-29 14:35:43 +00:00
extcap_capture ( interface , args . fifo , args . delay , args . verify , message , args . remote , fake_ip )
2014-02-25 13:05:11 +00:00
else :
usage ( )
sys . exit ( ERROR_USAGE )