Huge thanks to our Platinum Members Endace and LiveAction,
and our Silver Member Veeam, for supporting the Wireshark Foundation and project.

Ethereal-dev: [Ethereal-dev] updated fakelink dissector + (new) README.fakelink

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

From: Jeff Morriss <morriss@xxxxxxxxx>
Date: Tue, 08 Jul 2003 17:04:28 -0400

Hi Navin, Hi list,

I have updated the (still under debate) fakelink dissector.

Major changes include:

- Remove "packet-fakelink.h"
	- move some contents to "packet-fakelink.c"
	- move other contents to "fakelink.h"

- Rename "faketypes.h" to "fakelink.h"
- applications that want to write fakelink files but don't want other Ethereal-specific stuff can simply include this file

- Specify that the fakelink header is in network-byte order (the previous code assumed it was little-endian).

- Added a "README.fakelink" with some (so far incomplete) details about working with the fakelink layer. One question about the contents here: I was contemplating putting some sample code here to help people write PCAP files without the Wiretap library, but I wouldn't want to have that part-of-the-documentation code end up GPL'd (the point of providing such code is so applications that can't use Wiretap for licensing reasons could use this code). Any thoughts?


This isn't intended for inclusion (since we haven't agreed that this is the best method to do this) but I wanted to throw these updates out there since I had made these changes when I was playing with the dissector. (Okay, I didn't write the README for myself, but hey...)

Regards,
-Jeff

/* fakelink.h
 *
 * $Id$
 *
 * Ethereal - Network traffic analyzer
 * By Gerald Combs <gerald@xxxxxxxxxxxx>
 * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

#ifndef __FAKELINK_H__
#define __FAKELINK_H__

typedef struct _fakelink_hdr {
	/* NOTE: These are in network-byte order. */
	guint16 type;
	guint16 length;
} fakelink_hdr;

#define FAKELINK_TYPE_OFFSET 0
#define FAKELINK_TYPE_LENGTH 2
#define FAKELINK_LENGTH_OFFSET FAKELINK_TYPE_LENGTH
#define FAKELINK_LENGTH_LENGTH 2

#define FAKELINK_HEADER_SIZE 4
#define FAKELINK_DATA_OFFSET FAKELINK_HEADER_SIZE


/*  The list of protocols understood by fakelink.
 *  When adding a protocol here, be sure to add a value_string entry for
 *  the protocol in "packet-fakelink.c"
 */
#define FAKETYPE_MTP2           0x0001
#define FAKETYPE_MTP3           0x0002
#define FAKETYPE_SCCP           0x0003

#endif
/* packet-fakelink.c
 * Routines for Fake link layer of Ethereal dissection
 * Copyright 2003, Navin Anand <navinanand@xxxxxxxxxxxxx>
 * Guidance by Martin Regner is acknowledged, thank you Martin Regner.
 *
 * $Id$
 *
 * Ethereal - Network traffic analyzer
 * By Gerald Combs <gerald@xxxxxxxxxxxx>
 * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <glib.h>

#include <epan/packet.h>

#include <fakelink.h>

const value_string faketype_vals[] = {
	{FAKETYPE_MTP2,		"MTP2"	},
	{FAKETYPE_MTP3,		"MTP3"	},
	{FAKETYPE_SCCP,		"SCCP"	},
	{0,			NULL	} };

/* Initialize the protocol and registered fields */
static int proto_fakelink = -1;
static int hf_fakelink_type = -1;
static int hf_fakelink_length = -1;

/* Initialize the subtree pointers */
static gint ett_fakelink = -1;
static gint ett_type = -1;
static gint ett_length = -1;

static dissector_handle_t data_handle;

static dissector_table_t fakelink_type_dissector_table;

/* Code to actually dissect the packets */
static void
dissect_fakelink(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	static fakelink_hdr fakelinkhdr;
	proto_item *ti = NULL;
	proto_tree *fakelink_tree = NULL;
	gint data_length;
	tvbuff_t *data_tvb;

	/* Make entries in Protocol column and Info column on summary display */
	if (check_col(pinfo->cinfo, COL_PROTOCOL))
		col_set_str(pinfo->cinfo, COL_PROTOCOL, "Fake link");

	if (check_col(pinfo->cinfo, COL_INFO))
		col_set_str(pinfo->cinfo, COL_INFO, "Data for the fake link");

	fakelinkhdr.type = tvb_get_ntohs(tvb, FAKELINK_TYPE_OFFSET);
	fakelinkhdr.length = tvb_get_ntohs(tvb, FAKELINK_LENGTH_OFFSET);

	if (tree) {

		/* create display subtree for the protocol */
		ti = proto_tree_add_item(tree, proto_fakelink, tvb, 0, -1, TRUE);

		fakelink_tree = proto_item_add_subtree(ti, ett_fakelink);

		proto_tree_add_item(fakelink_tree, hf_fakelink_type, tvb,
				    FAKELINK_TYPE_OFFSET,
				    FAKELINK_TYPE_LENGTH, FALSE);

		proto_tree_add_item(fakelink_tree, hf_fakelink_length, tvb,
				    FAKELINK_LENGTH_OFFSET,
				    FAKELINK_LENGTH_LENGTH, FALSE);
	}

	data_length = tvb_length(tvb) - FAKELINK_HEADER_SIZE;
	data_tvb = tvb_new_subset(tvb, FAKELINK_DATA_OFFSET, data_length,
				  data_length);

	if (dissector_try_port(fakelink_type_dissector_table,
			       fakelinkhdr.type, data_tvb, pinfo, tree))
		return;

	call_dissector(data_handle, data_tvb, pinfo, tree);
}


/* Register the protocol with Ethereal */
void
proto_register_fakelink(void)
{

	/* Setup list of header fields */
	static hf_register_info hf[] = {
		{ &hf_fakelink_type,
			{ "Protocol type", "fakelink.type",
			FT_UINT16, BASE_HEX, VALS(faketype_vals), 0x0,
			"Protocol type", HFILL }
		},
		{ &hf_fakelink_length,
			{ "Packet length", "fakelink.length",
			FT_UINT16, BASE_DEC, NULL, 0x0,
			"Packet length", HFILL }
		},
	};

	/* Setup protocol subtree array */
	static gint *ett[] = {
		&ett_fakelink,
		&ett_type,
		&ett_length,
	};

	/* Register the protocol name and description */
	proto_fakelink = proto_register_protocol("Fake link layer",
						 "Fake Link", "fakelink");
	register_dissector("fakelink", dissect_fakelink, proto_fakelink);

	proto_register_field_array(proto_fakelink, hf, array_length(hf));
	proto_register_subtree_array(ett, array_length(ett));

	/* subdissector code */
	fakelink_type_dissector_table =
		register_dissector_table("fakelink.type", "Protocol type",
					 FT_UINT16, BASE_HEX);
}


void
proto_reg_handoff_fakelink(void)
{
	dissector_handle_t fakelink_handle;

	data_handle = find_dissector("data");
	fakelink_handle = create_dissector_handle(dissect_fakelink,
						  proto_fakelink);

	dissector_add("wtap_encap", WTAP_ENCAP_FAKE_LINK, fakelink_handle);

}

$Id$

This file is a HOWTO guide for using the fake link layer in Ethereal.  In
particular it explains:
	1) What (and Why) is the fake link layer?
	2) What protocols can be written to (and read from) this fake link
	   layer?
	3) How to write a file that can be read by Ethereal/Tethereal using
	   the fake link layer (so you can write, for example, MTP2 to a
	   file without IP or any other protocol below it).
	4) How to add a protocol to the fake link layer.



1) What is the fake link layer?
---------------------------------

The fake link layer is a dissector in Ethereal that allows Ethereal to read
a capture file (in PCAP format: fake link has (TODO: will have) its own
DLT_ file format identifier reserved in libpcap) that contains some protocol
layer without any of the lower level protocol parts (headers, trailers) on it.
Examples include MTP3 without the MTP2 header or SCCP without MTP3 (or below).
A (TODO: bad?) non-SS7 example would be TCP without IP (and without Ethernet).

Why?  Because there are some protocols that Ethereal understands most of but
could not (prior to Fake Link) decode directly because those protocols don't
run over a link layer that Ethereal understands.  A good example of this is
SS7:  Ethereal understands a good number of the SS7 protocols because people
have developed dissectors for use with SIGTRAN (SS7 over IP) but Ethereal
can not capture directly from SS7 links.

Also it happens that sometimes an application does not have access to the
lower level protocol parts but it would like to save off the parts it *does*
have and allow a user to look at the protocol messages in Ethereal (e.g., for
debugging).


2) What protocols can be written to (and read from) this fake link layer?
---------------------------------------------------------------------------

The list of protocols that the fake link layer currently supports is
available in "fakelink.h".  This list is duplicated as a value_string in
"packet-fakelink.c".


3) How to write a fake link layer PCAP file?
----------------------------------------------

There are 2 methods that you can use to write out a fake link PCAP capture
file: by using the Wiretap library (part of Ethereal) or by writing the file
out directly from your application.  It would make sense that libpcap could
be used directly (which could be advantageous since it has a BSD license) but
the APIs for libpcap do not seem to allow writing protocol packets to a file
directly (it seems geared more towards capture-and-writing).

The choice between using Wiretap and not using Wiretap is mainly a licensing
issue:  The Wiretap library is licensed under the GNU General Public License
which prevents using it in a non-GPL application.  If your appliation is
binary-only (non-GPL) then you can't use the Wiretap library (unless the
license is changed to the LGPL).


3a) Using libwiretap to write fake link layer packets:
	I)   Get the right include files.  You'll need:
		#include <wtap-int.h>
		#include <wtap.h>
		#include <fakelink.h>

	II)  Declare a pointer to a 'wtap_dumper'.  This serves as a descriptor
	     the file you'll be writing to:
		wtap_dumper *wd = 0;

	III) Open the file:
		int error;
		wd = wtap_dump_open("/path/to/your/file.pcap", /* file name */
				    WTAP_FILE_PCAP,	/* It's a PCAP file */
				    WTAP_ENCAP_FAKE_LINK, /* It'll contain fake link data */
				    0, /* TODO: snaplen ??? */
				    &error);  /* Error code (if any) */

		(if 'wd' is NULL then there was an error.)

	IV)  Put a fake link header in front of your data and populate it:
		typedef struct {
			fakelink_hdr hdr;
			guint8 data[max data your protocol can handle];
		} myFakeLinkPacket_t;

		myFakeLinkPacket_t myPacket;

		memset(&myPacket, 0, sizeof(myPacket));

		/*  Here we specify what kind of data we're writing.
		 *  Be sure to convert to network-byte order...
		 */
		myPacket.hdr.type = htons(FAKETYPE_MTP3);

		/*  The length is the length of the payload
		 *  Be sure to convert to network-byte order...
		 */
		myPacket.hdr.length = htons(length_of_my_MTP3_msg);

	V)   Allocate and populate a 'wtap_pkthdr':
		struct wtap_pkthdr whdr

		memset(&whdr, 0, sizeof(whdr));

		/*  Set the time the packet was received; this is what is
		 *  displayed in the "Time" column in Ethereal.
		 *  NOTE: Ethereal gets confused if this is left unset for
		 *  some messages but is set for others...
		 */
		whdr.ts.tv_sec = time_packet_was_received_secs;
		whdr.ts.tv_usec = time_packet_was_received_usecs;

		/*  Set the length of the packet from the PCAP perspective
		 *  (e.g., sizeof(fake link header) + sizeof(data))
		 */
		whdr.len = length_of_my_MTP3_msg + sizeof(fakelink_hdr);
		whdr.caplen = whdr.len;

	VI)  Write the packet:
		if (! wtap_dump(wd,		/* Wiretap descriptor */
				&whdr,		/* The wtap_pkthdr */
				NULL,		/* Not needed for PCAP files */
				(guchar *)&myPacket, /* The data */
				&error))	/* Error code (if any) */
		{
			printf("wtap_dump() failed: %d\n", error);
		}

	VII)  (When you're done writing packets) close the file:
		wtap_dump_close(wd, &error);


3b) Writing a PCAP file directly (without libwiretap)

	TODO: can I put code here and say it's in the public domain?
	And still put this README in Ethereal documentation???


4) How to add a protocol to the fake link layer.
--------------------------------------------------

So, the protocol you're using isn't currently supported by the fake link
layer but you want it to be.  Here's the steps you need to take:


	4a) Reserve a fake link header type. Allocate an entry in "fakelink.h"
	for your protocol and put a value_string entry for it in
	"packet-fakelink.c".

	4b) Modify the dissector for your protocol so that it registers with
	the fake link layer to receive any fake link messages with your
	protocol in it.  Usually this will involve adding:

		- #include<fakelink.h>

		- In 'proto_reg_handoff_<yourProtocol>()':
			/*  These two lines may already be there.  If so,
			 *  don't duplicate them.
			 */
			dissector_handle_t <yourProtocol>_handle;

			<yourProtocol>_handle =
				create_dissector_handle(dissect_<yourProtocol>,
							proto_<yourProtocol>);
		
		
		- dissector_add("fakelink.type",
				FAKETYPE_<yourProtocol>,
				<yourProtocol>_handle);