0% found this document useful (0 votes)
69 views

D02 - Combs - Intro To Writing Wireshark Packet Dissectors

wire shark pdf for basic reference

Uploaded by

Akshay Choudhary
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
69 views

D02 - Combs - Intro To Writing Wireshark Packet Dissectors

wire shark pdf for basic reference

Uploaded by

Akshay Choudhary
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 51

Writing Your Own Dissectors

Introduction
March 31, 2008

Gerald Combs
Lead Developer | Wireshark

SHARKFEST '08
Foothill College
March 31 - April 2, 2008
Overview
 Distributed development

Plain old boring C

Multi-platform
 Multi-interface

Open Source (GPL)

Rapid development pace
Application Architecture
Wireshark / TShark

Tree
Dissectors
libwireshark Plugins
Display
filters
libwiretap

libwiretap
dumpcap
WinPcap / libpcap

Live data Capture file


Build Requirements
 Source code: (Like, duh!)

Compilers: Visual Studio or gcc

Libraries: WinPcap/libpcap, GLib, GTK+, zlib, libsmi, …
 Support tools: Python, Perl, Linux/UNIX shell
Build Requirements - Windows
 Visual C++ 6.0 to 2005 (2008 soon)

Cygwin

Python 2.4
 NSIS, TortoiseSVN
Disk Requirements
 Sources (plain) 220 MB

Sources (compiled) 700 MB

Support libs 250 MB
 Cygwin 650 MB

Python 50 MB

 Total (compiled) 1.65 GB


Getting the Code
 Subversion
http://anonsvn.wireshark.org/wireshark/trunk


Tar files
http://www.wireshark.org/download/src

 Want to send us a patch? Use SVN!


Source Directory Overview

root CLI applications, common code


doc READMEs, man pages
docbook Guides
epan Dissection
dissectors Built-in dissectors
gtk User interface
packaging Platform installers
plugins Plugin dissectors
wiretap File formats
Plugin or Built-in?

Plugin Built-in

Licensing Proprietary? GPL!

Complexity Some Minimal

Modification New DLL New app

We'll focus on built-in


Packet Data + Metainfo

Raw packet Wire

DLT + pkthdr Packet buffer WinPcap/libpcap

FD + tree + cinfo + … tvbuff Wireshark


Parts of a Dissector
 Registration routines

Globals (value strings)

Hfinfo structs
 Dissection routines
Registration
 Initialization: proto_register_XXX();

Preference callbacks
 Handoffs: proto_reg_handoff_XXX();

make-dissector-reg.py  epan/dissectors/register.c

Two-pass initialization
Core Data Structures
 Provided to you:

tvbuff: Protocol data access
 packet_info, frame_data: Packet meta-info
 proto_tree: Detail tree

You provide:
 header_field_info
DNS Dissection Call Stack

dissect_dns_udp() /* packet-dns.c */
decode_udp_ports() /* packet-udp.c */
dissect_udp() /* packet-udp.c */
dissect_ip() /* packet-ip.c */
dissect_eth_common() /* packet-eth.c */
dissect_frame() /* packet-frame.c */
dissect_packet() /* Add top-level structs
*/
process_packet() /* DLT from wiretap */
main()
tv_buff


Testy, virtual buffers

Data buffers & extraction

epan/tvbuff.h

tvb_get_XXX(tvb, offset, …);

Make your own! Impress your friends!

Safe (mostly) except for tvb_get_ptr()
Check Your Inputs

count = tvb_get_ntohl(tvb, offset);


for (i = 0; i < count; i++) {
allocate_some_memory(…);
add_an_item_to_the_tree(…);
}
Speaking of Loops…

guint8 pdu_len, el_len;


int offset;
pdu_len = tvb_get_guint8(tvb, offset);
offset++
while (pdu_len > 0) {
el_len = tvb_get_guint8(tvb, offset);
dissect_our_pdu(…);
offset += el_len;
pdu_len -= el_len;
}
packet_info & frame_data
 High and low-level metainfo

epan/packet_info.h, epan/frame_data.h

Frame data: Wire information
 Length, timestamps, DLT

Packet Info: State information
 Addresses, ports, reassembly, protocol data
header_field_info
 Protocol atoms

Data type, filter name, descriptions

Enums - Value/Range/TF Strings
 epan/proto.h

Unique
proto_tree
 Detail tree (middle pane)

Might be NULL

epan/proto.h
 proto_tree_add_XXX(tree, hf_index, tvb, offset,
length, …);
 Can be hidden or “generated”

Avoid proto_tree_add_text()
Adding Tree Items

proto_item *ti;
proto_tree *sub_tree = NULL;

ti = proto_tree_add_item(tree, …);
sub_tree = proto_item_add_subtree(ti, …);

proto_tree_add_item(sub_tree, …);
proto_tree_add_uint_format(sub_tree, …);
Adding Raw Data

/* Just plain wrong */


proto_tree_add_text(tree, tvb, 0, 50,
tvb_get_ptr(tvb, 0, 50));
/* Better */
proto_tree_add_text(tree, tvb, 0, 50, "%s",
tvb_get_ptr(tvb, 0, 50));
/* Best */
proto_tree_add_text(tree, tvb, 0, 50, "%s",
tvb_format_text(tvb, 0, 50));
proto_tree_add_item(…); /* FT_BYTES */
Columns
 epan/column-utils.h

Accessed via pinfo

Enums for each type (COL_PROTOCOL, COL_INFO)
col_set_str(pinfo->cinfo, COL_PROTOCOL, "TCP");
UI Element Origins

col_set_str()

proto_tree_add_*()
QuickTime™ and a

hfinfo
TIFF (LZW) decompressor
are needed to see this picture.

dissector_add()

tvbuff
Let’s Make a Dissector!
 Copy from README.developer or existing dissector

Place in epan/dissectors (built-in)

Add it to Makefile.common
(CLEAN_DISSECTOR_SRC)

More initial work for plugins
NAT-PMP


Part of Bonjour, IETF draft

UDP port 5351
 Op codes (packet types)
0 Public address request
128 Public address response
1, 2 UDP/TCP port mapping request
129, 130 UDP/TCP port mapping response
NAT-PMP Messages
Address Request
Ver = 0 OP = 0 8 bits
Address Response
Ver = 0 OP = 128 Result
Seconds since start of epoch
External address
Mapping Request (UDP = 1, TCP = 2)
Ver = 0 OP = {1,2} Reserved
Private port Requested public port
Requested mapping lifetime
Mapping Response (UDP = 129, TCP = 130)
Ver = 0 OP = {129,130} Reserved
Seconds since start of epoch
Private port Mapped public port
Mapping lifetime
Example

Minimal NAT-PMP
Value Strings

 Map integers to strings


 val_to_str(), match_strval()

Also range strings, T/F strings and bitfields

static const value_string auth_vals[] = {


{0, "Authentication Request"},
{1, "Authentication Response"},
{847, "Look! A fire engine!"},
{0, NULL}
};
Example

Complete NAT-PMP
TCP Reassembly
 TCP messages & tvbuffs have different boundaries

tcp_dissect_pdus() to the rescue!

epan/dissectors/packet-tcp.h
 What about other reassembly?
Using tcp_dissect_pdus()

#define MIN_MSG_LEN 4
static void dissect_XXX(…) {
tcp_dissect_pdus(tvb, pinfo, tree, TRUE,
MIN_MSG_LEN, get_XXX_message_len,
dissect_XXX_message);
}
static void dissect_XXX_message(…) {
/* Actual dissection */
}
static guint get_foo_message_len(…) {
/* Return message length */
}
Protocol Preferences
 Uints, Bools, Enums, Strings, Ranges

General registration
 Protocol

Callback
 Pref registration

Name
 Data pointer usually global
Preferences Example

static guint g_XXX_tcp_port = TCP_PORT_XXX;

proto_XXX = proto_register_protocol(…);

XXX_module = prefs_register_protocol(proto_XXX,
proto_reg_handoff_XXX);
prefs_register_uint_preference(
XXX_module, "tcp.port", "XXX TCP Port",
"TCP port for XXX messages", 10, &g_XXX_tcp_port);
Memory management
 Manual: GLib

g_malloc(), g_free()
 Automatic: epan/emem.h

ep_alloc()
 se_alloc()
 Strings

Binary trees
 Stacks
 Fast!
Exceptions
 Automatic
offset = 234567890;
uid = tvb_get_ntohs(tvb, offset);

Manual
THROW(ReportedBoundsError);
DISSECTOR_ASSERT(offset < 300);
REPORT_DISSECTOR_BUG("Cheese smells funny");
 epan/except.h, epan/proto.h
Ptvcursors
 Protocol Tree TVBuff Cursor

Easy way to add a bunch of static items
Ptvcursor Example

ptvcursor_t *cursor;
int offset = 0;

cusor = ptvcursor_new(tree, tvb, offset);


ptvcursor_add(cursor, hf_stream_addr, 1,
FALSE);
/* more ptvcursor_add calls */
ptvcursor_add(cursor, hf_salmon_count, 4,
FALSE);
offset = ptvcursor_current_offset(cursor);
ptvcursor_free(cursor);
return offset;
Strings
 GLib internals

g_str*(), g_string_*();
 ep_str*() and tvb_get_str*()

epan/strutil.h, epan/to_str.h
Portability Tips
 We run on Windows, Linux, Solaris, OS X, FreeBSD,
NetBSD, OpenBSD, AIX, HP-UX, …
 GLib types, not C99 (e.g. guint8 instead of uint8_t)

No C++ comments

Check your inputs
 No malloc, sprintf, strcpy, open…

Use ep_ and se_ allocated memory

#ifdef _WIN32 /* and not "WIN32" */
Distributing Your Code
 Can you?

Should you?
Creating a Plugin
 doc/README.plugins
 grep -rl artnet .
Making Your Own Package
 Why?

doc/README.packaging

version.conf
 NSIS
Contributing Your Code

1. Fuzz! Test your stuff! C stinks!


2. Run check scripts
3. Generate a patch
svn diff > ~/Desktop/nat-pmp.patch
4. Put it on bugs.wireshark.org
Fuzzing Example

cd wireshark-gtk2
../tools/fuzz-test.sh /tmp/*.pcap

../tools/fuzz-test.sh: line 56: ulimit: cpu time: cannot modify


limit: Invalid argument
Running ./tshark with args: -nVxr (forever)

Starting pass 1:
c:\cygwin\tmp\nat-pmp.pcap: OK
Starting pass 2:
c:\cygwin\tmp\nat-pmp.pcap: OK

Further Information
 http://anonsvn.wireshark.org/wireshark/trunk
 http://www.wireshark.org/develop.html
 Wireshark Developer’s Guide
 doc/README.developer

[email protected]
 Next session
Questions
Bonus Material
Automatic Generation
 ASN.1

CORBA IDL

Samba PIDL
 Protomatics
Expert Info
expert_add_info_format(pinfo, ti, PI_MALFORMED,
PI_ERROR, "Corrupted data segment");
expert_add_info_format(pinfo, ti, PI_SEQUENCE, PI_NOTE,
"Try socks THEN shoes next time");
 Adds to expert windows
 Similar to syslog

PI_ERROR throws exceptions
 epan/expert.h, epan/expert.c

You might also like