summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client.py15
-rw-r--r--client_proto.py19
-rwxr-xr-xproxy.py31
-rwxr-xr-xspicedump.py47
4 files changed, 79 insertions, 33 deletions
diff --git a/client.py b/client.py
index 30ee1b9..192c8ae 100644
--- a/client.py
+++ b/client.py
@@ -8,6 +8,15 @@ import client_proto
logger = logging.getLogger('client')
+DEBUG_ENABLE_PDB=False
+
+if DEBUG_ENABLE_PDB:
+ def debug_break():
+ import pdb; pdb.set_trace()
+else:
+ def debug_break():
+ pass
+
# TODO - parse spice/protocol.h directly (to keep in sync automatically)
SPICE_MAGIC = "REDQ"
SPICE_VERSION_MAJOR = 2
@@ -47,15 +56,15 @@ class SpiceDataHeader(Struct):
inst = cls(*args, **kw)
if inst.e.sub_list != 0 and inst.e.sub_list >= inst.e.size:
logger.error('too large sub_list packet - %s' % inst)
- import pdb; pdb.set_trace()
+ debug_break()
return None
if inst.e.type < 0 or inst.e.type >= 400:
logger.error('bad type of packet - %s' % inst)
- import pdb; pdb.set_trace()
+ debug_break()
return None
if inst.e.size > 2000000:
logger.error('too large packet - %s' % inst)
- import pdb; pdb.set_trace()
+ debug_break()
return None
return inst
diff --git a/client_proto.py b/client_proto.py
index d5d4515..4f66852 100644
--- a/client_proto.py
+++ b/client_proto.py
@@ -2,18 +2,23 @@
Decode spice protocol using spice demarshaller.
"""
-ANNOTATE = False
+ANNOTATE = True
NO_PRINT_PROTECTION = False
import logging
-
-logger = logging.getLogger('client_proto')
-
+import os
from collections import namedtuple
import struct
import sys
+
+# we assume we are side by side with spice. hopefully, that is so.
+spice_dir = os.path.join(os.path.dirname(sys.modules[__name__].__file__),
+ '../spice')
+
+logger = logging.getLogger('client_proto')
+
if not 'proto' in locals():
- sys.path.append('../spice/python_modules')
+ sys.path.append(os.path.join(spice_dir, 'python_modules'))
import spice_parser
import ptypes
proto = None
@@ -346,9 +351,9 @@ def set_proto(major_version, minor_version):
return
globals().update(dict(major_version=major_version, minor_version=minor_version))
if major_version == 1 :
- proto = spice_parser.parse('../spice/spice1.proto')
+ proto = spice_parser.parse(os.path.join(spice_dir, 'spice1.proto'))
else:
- proto = spice_parser.parse('../spice/spice.proto')
+ proto = spice_parser.parse(os.path.join(spice_dir, 'spice.proto'))
channels = make_channels_dict(proto)
num_spice_messages = sum(len(ch.client) + len(ch.server) for ch in
diff --git a/proxy.py b/proxy.py
index 03af6d6..227d88c 100755
--- a/proxy.py
+++ b/proxy.py
@@ -40,9 +40,9 @@ class twowaydict(dict):
BROKEN_PIPE_ERRNO, TRANSPORT_NOT_CONNECTED_ERRNO = 32, 107
-def make_accepter(port):
+def make_accepter(port, host='127.0.0.1'):
accepter = Socket(AF_INET, SOCK_STREAM)
- accepter.bind(('0.0.0.0', port))
+ accepter.bind((host, port))
accepter.listen(1)
return accepter
@@ -53,9 +53,9 @@ def connect(addr):
return s
class Proxy(object):
- def __init__(self, local_port, remote_addr):
+ def __init__(self, local_port, remote_addr, host='127.0.0.1'):
self._drop_next = False
- self._proxy = _proxy(self, local_port, remote_addr)
+ self._proxy = _proxy(self, local_port, remote_addr, host)
def drop_next(self):
self._drop_next = True
def check_drop_next(self):
@@ -66,9 +66,9 @@ class Proxy(object):
for x in self._proxy:
yield x
-def _proxy(proxy, local_port, remote_addr):
+def _proxy(proxy, local_port, remote_addr, host = '127.0.0.1'):
print "proxying from %s to %s" % (local_port, remote_addr)
- accepter = make_accepter(local_port)
+ accepter = make_accepter(local_port, host)
open_socks = twowaydict()
close_errnos = set([BROKEN_PIPE_ERRNO, TRANSPORT_NOT_CONNECTED_ERRNO])
while True:
@@ -136,6 +136,21 @@ def tests():
from_port, to_port = port_num, port_num+1000
proxy(port_num, ('localhost', port_num+1000))
-if __name__ == '__main__':
- tests()
+def main():
+ import argparse
+ import sys
+ parser = argparse.ArgumentParser()
+ parser.add_argument('-l', '--local-port', type=int, required=True, help='set proxy local port')
+ parser.add_argument('-H', '--remote-host', default='localhost', help='set proxy remote address')
+ parser.add_argument('-p', '--remote-port', type=int, required=True, help='set proxy remote address')
+ parser.add_argument('-v', '--verbose', dest='verbose', action='count', help='verbosity', default=0)
+ opts, rest = parser.parse_known_args(sys.argv[1:])
+ local_port = opts.local_port
+ remote_addr = (opts.remote_host, opts.remote_port)
+ p = proxy(local_port=local_port, remote_addr=remote_addr)
+ for ret in p:
+ if opts.verbose:
+ print repr(ret)
+if __name__ == '__main__':
+ main()
diff --git a/spicedump.py b/spicedump.py
index aac6ff3..9f7c8bb 100755
--- a/spicedump.py
+++ b/spicedump.py
@@ -3,9 +3,10 @@ import sys
from collections import defaultdict
from itertools import izip_longest
from time import time
-from optparse import OptionParser
+import argparse
import textwrap
import logging
+import re
import pcaputil
from proxy import proxy, closeallsockets
@@ -68,14 +69,26 @@ class SurfaceStatistics(object):
for i, l in enumerate(textwrap.wrap(','.join(map(str, v)), width=40)):
yield '%20s: %s' % (k if i == 0 else '', l)
+def debug_break():
+ import rpdb2; rpdb2.start_embedded_debugger('a')
+
def spicedump(p, opts, stdscr=None):
+ show_every_command = True
+ periodic_hist = False
import pcapspice
spice = pcapspice.spice_iter(p)
hist = Histogram()
surface_stat = SurfaceStatistics()
last_print = start_time = time()
messages = []
- filter = opts.filter
+ filter_exp = opts.filter
+ if filter_exp:
+ if filter_exp[0] == '-':
+ def filter(result_name, exp=re.compile(filter_exp[1:])):
+ return exp.match(result_name)
+ else:
+ def filter(result_name, exp=re.compile(filter_exp)):
+ return not exp.match(result_name)
if stdscr:
stdscr.erase()
# replace the "for d in spice:" loop with a select
@@ -87,7 +100,7 @@ def spicedump(p, opts, stdscr=None):
d = spice.next()
result_name = d.msg.data.result_name
result_value = d.msg.data.result_value
- if filter and result_name not in filter:
+ if filter_exp and filter(result_name):
continue
if hasattr(p, 'drop_next'):
pass
@@ -108,7 +121,9 @@ def spicedump(p, opts, stdscr=None):
messages.extend(str(d).split('\n'))
old_time, old_count = hist[result_name]
hist[result_name] = (cur_time, old_count + 1)
- if True or cur_time - last_print > dt:
+ if show_every_command:
+ print result_name
+ if periodic_hist and cur_time - last_print > dt:
show(hist.show(), surface_stat.show())
print '\n'.join(messages[-20:])
last_print = cur_time
@@ -122,22 +137,24 @@ def fromproxy(stdscr, local_port, remote_addr, opts):
return spicedump(p, opts, stdscr=stdscr)
if __name__ == '__main__':
- parser = OptionParser()
- parser.add_option('-p', '--proxy', dest='proxy', help='use proxy',
+ parser = argparse.ArgumentParser()
+ parser.add_argument('-p', '--proxy', dest='proxy', help='use proxy',
action='store_true')
- parser.add_option('-l', '--localport', dest='local_port', help='set proxy local port')
- parser.add_option('-r', '--remoteaddr', dest='remote_addr', help='set proxy remote address')
- parser.add_option('-v', '--verbose', dest='verbose', action='count', help='verbosity', default=0)
- parser.add_option('-c', '--curses', dest='curses', action='store_true', help='use curses')
- parser.add_option('-f', '--filter', dest='filter', help='filter messages')
- opts, rest = parser.parse_args(sys.argv[1:])
+ parser.add_argument('-l', '--local-port', type=int, help='set proxy local port')
+ parser.add_argument('-H', '--remote-host', default='localhost', help='set proxy remote address')
+ parser.add_argument('-p', '--remote-port', type=int, required=True, help='set proxy remote address')
+ parser.add_argument('-v', '--verbose', dest='verbose', action='count', help='verbosity', default=0)
+ parser.add_argument('-c', '--curses', dest='curses', action='store_true', help='use curses')
+ parser.add_argument('-f', '--filter', dest='filter', help='filter messages')
+ parser.add_argument('--record', dest='record', help='TODO: record to file, can be used to playback')
+ parser.add_argument('--playback', dest='playback', help='TODO: playback a previously recorded file')
+ opts, rest = parser.parse_known_args(sys.argv[1:])
if opts.verbose >= 2 in sys.argv:
logging.basicConfig(filename='spicedump.log', level=logging.DEBUG)
print "saving debug log to spicedump.log"
if opts.proxy:
- local_port = int(opts.local_port)
- remote_addr = opts.remote_addr.split(':')
- remote_addr = (remote_addr[0], int(remote_addr[1]))
+ local_port = opts.local_port
+ remote_addr = (opts.remote_host, opts.remote_port)
main = (lambda stdscr, opts, local_port=local_port, remote_addr=remote_addr:
fromproxy(stdscr, local_port, remote_addr, opts))
else: