aboutsummaryrefslogtreecommitdiffstats
path: root/docs/dev/addingviews.html
blob: f6ba645c60099fffe971db0e1396f04ea7384490 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
As discussed in [the Flow View section of the mitmproxy
overview](@!urlTo("mitmproxy.html")!@), mitmproxy allows you to inspect and
manipulate flows.  When inspecting a single flow, mitmproxy uses a number of
heuristics to show a friendly view of various content types; if mitmproxy
cannot show a friendly view, mitmproxy defaults to a __raw__ view.

Each content type invokes a different flow viewer to parse the data and display
the friendly view. Users can add custom content viewers by adding a view class
to contentview.py, discussed below.

## Adding a new View class to contentview.py

The content viewers used by mitmproxy to present a friendly view of various
content types are stored in contentview.py.  Reviewing this file shows a number
of classes named ViewSomeDataType, each with the properties: __name__,
__prompt__, and __content\_types__ and a function named __\_\_call\_\___.

Adding a new content viewer to parse a data type is as simple as writing a new
View class.  Your new content viewer View class should have the same properties
as the other View classes: __name__, __prompt__, and __content\_types__ and a
__\_\_call\_\___ function to parse the content of the request/response.

* The __name__ property should be a string describing the contents and new content viewer;
* The __prompt__ property should be a two item tuple:

  - __1__: A string that will be used to display the new content viewer's type; and
  - __2__: A one character string that will be the hotkey used to select the new content viewer from the Flow View screen;

* The __content\_types__ property should be a list of strings of HTTP Content\-Types that the new content viewer can parse.
  * Note that mitmproxy will use the content\_types to try and heuristically show a friendly view of content and that you can override the built-in views by populating content\_types with values for content\_types that are already parsed -- e.g. "image/png".

After defining the __name__, __prompt__, and __content\_types__ properties of
the class, you should write the __\_\_call\_\___ function, which will parse the
request/response data and provide a friendly view of the data.  The
__\_\_call\_\___ function should take the following arguments: __self__,
__hdrs__, __content__, __limit__; __hdrs__ is a MultiDict object containing
the headers of the request/response; __content__ is the content of the
request/response, and __limit__ is an integer representing the amount of data
to display in the view window.

The __\_\_call\_\___ function returns two values: (1) a string describing the
parsed data; and (2) the parsed data for friendly display.  The parsed data to
be displayed should be a list of strings formatted for display.  You can use
the __\_view\_text__ function in contentview.py to format text for display.
Alternatively, you can display content as a series of key-value pairs; to do
so, prepare a list of lists, where each list item is a two item list -- a key
that describes the data, and then the data itself; after preparing the list of
lists, use the __common.format\_keyvals__ function on it to prepare it as text
for display.

If the new content viewer fails or throws an exception, mitmproxy will default
to a __raw__ view.
ghlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ .highlight .k { color: #008800; font-weight: bold } /* Keyword */ .highlight .ch { color: #888888 } /* Comment.Hashbang */ .highlight .cm { color: #888888 } /* Comment.Multiline */ .highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */ .highlight .cpf { color: #888888 } /* Comment.PreprocFile */ .highlight .c1 { color: #888888 } /* Comment.Single */ .highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */ .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ .highlight .gr { color: #aa0000 } /* Generic.Error */ .highlight .gh { color: #333333 } /* Generic.Heading */ .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ .highlight .go { color: #888888 } /* Generic.Output */ .highlight .gp { color: #555555 } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #666666 } /* Generic.Subheading */ .highlight .gt { color: #aa0000 } /* Generic.Traceback */ .highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #008800 } /* Keyword.Pseudo */ .highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
#ifndef	_IA64_CONFIG_H_
#define _IA64_CONFIG_H_

#define VHPT_GLOBAL

#undef DEBUG_PFMON

// manufactured from component pieces

// defined in linux/arch/ia64/defconfig
//#define	CONFIG_IA64_GENERIC
#define	CONFIG_IA64_HP_SIM
#define	CONFIG_IA64_L1_CACHE_SHIFT 7
// needed by include/asm-ia64/page.h
#define	CONFIG_IA64_PAGE_SIZE_16KB	// 4KB doesn't work?!?
#define	CONFIG_IA64_GRANULE_16MB

// this needs to be on to run on system with large memory hole
#define	CONFIG_VIRTUAL_FRAME_TABLE

#define CONFIG_EFI_PCDP
#define CONFIG_SERIAL_SGI_L1_CONSOLE

#define CONFIG_XEN_SMP

#ifdef CONFIG_XEN_SMP
#define CONFIG_SMP 1
#define NR_CPUS 64
#define CONFIG_NUMA
#define CONFIG_ACPI_NUMA
#define NODES_SHIFT 3
#define MAX_NUMNODES (1 << NODES_SHIFT)
#define NR_NODE_MEMBLKS (MAX_NUMNODES*2)
#define MAX_PXM_DOMAINS 256
#else
#undef CONFIG_SMP
#define NR_CPUS 1
#endif
#define CONFIG_NR_CPUS NR_CPUS

#define CONFIG_IOSAPIC
#define supervisor_mode_kernel (0)

#define CONFIG_DMA_BITSIZE 30

/* If PERFC is used, include privop maps.  */
#ifdef PERF_COUNTERS
#define CONFIG_PRIVOP_ADDRS
#define PRIVOP_COUNT_NADDRS 30
#endif

#define CONFIG_VGA 1

#ifndef __ASSEMBLY__

// can't find where this typedef was before?!?
// needed by include/asm-ia64/processor.h (and other places)
typedef int pid_t;

// now needed for xen/include/mm.h
typedef unsigned long paddr_t;
// from include/linux/kernel.h
#define ALIGN(x,a) (((x)+(a)-1)&~((a)-1))

//////////////////////////////////////

#define FASTCALL(x) x	// see linux/include/linux/linkage.h
#define fastcall	// " "

#define watchdog_disable() ((void)0)
#define watchdog_enable()  ((void)0)
// from linux/include/linux/types.h
#define CLEAR_BITMAP(name,bits) \
	memset(name, 0, BITS_TO_LONGS(bits)*sizeof(unsigned long))

// FIXME?: x86-ism used in xen/mm.h
#define LOCK_PREFIX

extern unsigned long xenheap_phys_end;
extern unsigned long xen_pstart;
extern unsigned long xenheap_size;
//extern struct domain *dom0;
extern unsigned long dom0_size;

// from linux/include/linux/mm.h
extern struct page_info *mem_map;

// xen/include/asm/config.h
extern char _end[]; /* standard ELF symbol */

// linux/include/linux/compiler.h
//#define __kernel
//#define __safe
#define __force
#define __chk_user_ptr(x) (void)0
//#define __chk_io_ptr(x) (void)0
//#define __builtin_warning(x, y...) (1)
//#define __acquires(x)
//#define __releases(x)
//#define __acquire(x) (void)0
//#define __release(x) (void)0
//#define __cond_lock(x) (x)
//#define __must_check
#define __deprecated

// xen/include/asm/config.h
//#define HZ 1000
// FIXME SMP: leave SMP for a later time

#define NR_hypercalls 64

///////////////////////////////////////////////////////////////
// xen/include/asm/config.h
// Natural boundary upon TR size to define xenheap space
#define XENHEAP_DEFAULT_MB (1 << (KERNEL_TR_PAGE_SHIFT - 20))
#define XENHEAP_DEFAULT_SIZE	(1 << KERNEL_TR_PAGE_SHIFT)
#define	ELFSIZE	64

///////////////////////////////////////////////////////////////

// get rid of difficult circular include dependency
#define CMPXCHG_BUGCHECK(v)
#define CMPXCHG_BUGCHECK_DECL

// from include/asm-ia64/smp.h
#define	get_cpu()	smp_processor_id()
#define put_cpu()	do {} while(0)
#define put_cpu_no_resched()	do{} while (0)

// needed for common/dom0_ops.c until hyperthreading is supported
#ifdef CONFIG_SMP
extern int smp_num_siblings;
#else
#define smp_num_siblings 1
#endif

// function calls; see decl in xen/include/xen/sched.h
#undef free_task_struct
#undef alloc_task_struct
#define get_thread_info(v) alloc_thread_info(v)

// avoid redefining task_t in asm/thread_info.h
#define task_t	struct domain

// avoid redefining task_struct in asm/current.h
#define task_struct vcpu

// linux/include/asm-ia64/machvec.h (linux/arch/ia64/lib/io.c)
#define platform_inb	__ia64_inb
#define platform_inw	__ia64_inw
#define platform_inl	__ia64_inl
#define platform_outb	__ia64_outb
#define platform_outw	__ia64_outw
#define platform_outl	__ia64_outl

#include <xen/cache.h>
#ifndef CONFIG_SMP
#define __cacheline_aligned_in_smp
#else
#define __cacheline_aligned_in_smp __cacheline_aligned
#endif

#define ____cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES)))
#ifndef CONFIG_SMP
#define ____cacheline_aligned_in_smp
#else
#define ____cacheline_aligned_in_smp ____cacheline_aligned
#endif

#define CONFIG_PERFMON

#ifndef __ASSEMBLY__
#include "asm/types.h"	// for u64
#include "linux/linkage.h"	// for asmlinkage which is used by
                                // xen/include/acpi/acpixf.h
#endif

// warning: unless search_extable is declared, the return value gets
// truncated to 32-bits, causing a very strange error in privop handling
struct exception_table_entry;

const struct exception_table_entry *
search_extable(const struct exception_table_entry *first,
	       const struct exception_table_entry *last,
	       unsigned long value);
void sort_extable(struct exception_table_entry *start,
		  struct exception_table_entry *finish);
void sort_main_extable(void);

#define find_first_set_bit(x)	(ffs(x)-1)	// FIXME: Is this right???

// see drivers/char/console.c
#ifndef VALIDATE_VT
#define	OPT_CONSOLE_STR "com1"
#else
#define	OPT_CONSOLE_STR "com2"
#endif

#define __nocast

// see include/asm-x86/atomic.h (different from standard linux)
#define _atomic_set(v,i) (((v).counter) = (i))
#define _atomic_read(v) ((v).counter)
#define atomic_compareandswap(old, new, v) ((atomic_t){ cmpxchg(v, _atomic_read(old), _atomic_read(new)) })

// Deprivated linux inf and put here for short time compatibility
#define kmalloc(s, t) xmalloc_bytes((s))
#define kfree(s) xfree((s))

// see common/keyhandler.c
#define	nop()	asm volatile ("nop 0")

// from include/linux/preempt.h (needs including from interrupt.h or smp.h)
#define preempt_enable()	do { } while (0)
#define preempt_disable()	do { } while (0)

// needed for include/xen/linuxtime.h
typedef s64 time_t;
typedef s64 suseconds_t;

// needed for include/linux/jiffies.h
typedef long clock_t;

// from include/linux/kernel.h, needed by jiffies.h
#define typecheck(type,x) \
({	type __dummy; \
	typeof(x) __dummy2; \
	(void)(&__dummy == &__dummy2); \
	1; \
})

// from include/linux/timex.h, needed by arch/ia64/time.c
#define	TIME_SOURCE_CPU 0

// used in common code
#define softirq_pending(cpu)	(cpu_data(cpu)->softirq_pending)

// dup'ed from signal.h to avoid changes to includes
#define	SA_SHIRQ	0x04000000
#define	SA_INTERRUPT	0x20000000

// needed for setup.c
extern unsigned long loops_per_jiffy;
extern char saved_command_line[];
struct screen_info { };
#define seq_printf(a,b...) printk(b)
//#define CONFIG_BLK_DEV_INITRD // needed to reserve memory for domain0

#define CONFIG_SHADOW	1

// xen/include/asm/config.h
/******************************************************************************
 * config.h
 * 
 * A Linux-style configuration list.
 */

#ifndef __XEN_IA64_CONFIG_H__
#define __XEN_IA64_CONFIG_H__

#undef CONFIG_X86

#define CONFIG_MCKINLEY

#undef CONFIG_X86_LOCAL_APIC
#undef CONFIG_X86_IO_APIC
#undef CONFIG_X86_L1_CACHE_SHIFT

//#ifndef CONFIG_IA64_HP_SIM
// looks like this is hard to turn off for Xen
#define CONFIG_ACPI 1
#define CONFIG_ACPI_BOOT 1
//#endif

#define CONFIG_XEN_ATTENTION_KEY 1
#endif /* __ASSEMBLY__ */
#endif /* __XEN_IA64_CONFIG_H__ */

/* Allow .serialize.data/instruction in asm files.
   Old as doesn't handle this.  */
#define HAVE_SERIALIZE_DIRECTIVE

/* Define CONFIG_PRIVIFY to support privified OS (deprecated).  */
#undef CONFIG_PRIVIFY

#endif	/* _IA64_CONFIG_H_ */