Ethereal-dev: [Ethereal-dev] Status of dissector generation

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

From: Richard Sharpe <sharpe@xxxxxxxxxx>
Date: Fri, 20 Oct 2000 16:30:05 +0900
Hi,

Attached are the xml file I used to describe the relatively simple ident
protocol and the current state of the output from my dissector generator ...

It assumes a bunch of new routines, and I still have to generate the main
dissector, but I can handle quite a bit ...

My next steps will be to try it on a description of the SMB protocol ...

<proto name="identd" longname="Identification Protocol (RFC1413)" tcp.port="113">
  <struct name="userid">
    <field type="BYTES" size="*" value=" " />
    <field type="BYTES" size="1" value=":" />
    <field type="BYTES" size="*" value=" " />
    <field type="BYTES" name="user" size="1+" term="EOF" /><!-- END_OF_FRAME? -->
  </struct>
  <struct name="error">
    <field type="BYTES" size="*" value=" " />
    <field type="BYTES" size="1" value=":" />
    <field type="BYTES" size="*" value=" " />
    <field type="BYTES" name="error-msg" size="1+" term="EOF" /><!-- END_OF_FRAME? -->
  </struct>
  <struct name="request">
    <field name="port-on-server" type="BYTES" size="1+" convtype="UINT16" />
    <field type="BYTES" size="*" value=" " />
    <field type="BYTES" size="1" value="," />
    <field type="BYTES" size="*" value=" " />
    <field name="port-on-client" size="1+" type="BYTES" convtype="UINT16" />
  </struct>
  <struct name="reply">
    <field name="port-on-client" type="BYTES" size="1+" convtype="UINT16" />
    <field type="BYTES" size="*" value=" " />
    <field type="BYTES" size="1" value="," />
    <field type="BYTES" size="*" value=" " />
    <field name="port-on-server" size="1+" type="BYTES" convtype="UINT16" />
    <field type="BYTES" size="1" value=" " />
    <field type="BYTES" size="1" value=":" />
    <field type="BYTES" size="*" value=" " />
    <alternate basedon="." type="BYTES">
      <field type="userid" bovalue="USERID" />
      <field type="error" bovalue="ERROR" />
    </alternate>
  </struct>
  <exchanges>
    <sequence>
      <request  type="request" />
      <response type="reply" />
    </sequence>
  </exchanges>
</proto>
/* packet-identd.c
 * Routines for identd (Identification Protocol (RFC1413)) packet disassembly
 *
 * $Id: $
 *
 * Copyright (c) 2000 by YOUR NAME HERE <YOUR EMAIL HERE>
 *
 * Ethereal - Network traffic analyzer
 * By Gerald Combs
 * Copyright 1999 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

#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif

#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <time.h>
#include <glib.h>
#include <string.h>
#include "packet.h"
#include "resolv.h"
#include "prefs.h"

#define TCP_PORT_IDENTD 113
void proto_reg_handoff_identd(void);

static int proto_identd = -1;

static int ett_identd = -1;
static int ett_identd_request = -1;
static int ett_identd_reply = -1;

int
dissect_identd_request(tvbuff_t *tvb, int offset, proto_tree *tree)
{
  proto_tree          *ti = NULL, request_tree = NULL;
  int                 cc, st_offset = offset;
  guint32             var_port_on_server;
  guint32             var_port_on_client;

  if (tree) {
    ti = proto_tree_add_text(tree, offset, 0, "request");
    request_tree = proto_tree_add_subtree(ti, ett_identd_request);
  }

  /* Handle the port-on-server field */
  if ((cc = ptvcursor_get_item_uint16(tvb, offset, 0, 0, &var_port_on_server)) < 0){

    /* Error handling code ... */

  }
  else {
    if (tree) {
      ti = proto_tree_add_text(tree, tvb, offset, 1+, "port-on-server: %s", tvb_format_text(tvb, offset, 1+));
    }
  offset += cc;

  /* Handle the un-named field of size *, value   */
  if ((cc = tvb_skip_bytes(tvb, offset, " ", 1, 0, 0)) < 0){

    /* Error handling code ... */

  }
  offset += cc;

  /* Handle the un-named field of size 1, value , */
  if ((cc = tvb_skip_bytes(tvb, offset, ",", 1, 1, 1)) < 0){

    /* Error handling code ... */

  }
  offset += cc;

  /* Handle the un-named field of size *, value   */
  if ((cc = tvb_skip_bytes(tvb, offset, " ", 1, 0, 0)) < 0){

    /* Error handling code ... */

  }
  offset += cc;

  /* Handle the port-on-client field */
  if ((cc = ptvcursor_get_item_uint16(tvb, offset, 0, 0, &var_port_on_client)) < 0){

    /* Error handling code ... */

  }
  else {
    if (tree) {
      ti = proto_tree_add_text(tree, tvb, offset, 1+, "port-on-client: %s", tvb_format_text(tvb, offset, 1+));
    }
  offset += cc;

  return (offset - st_offset);

}

int
dissect_identd_reply(tvbuff_t *tvb, int offset, proto_tree *tree)
{
  proto_tree          *ti = NULL, reply_tree = NULL;
  int                 cc, st_offset = offset;
  guint32             var_port_on_client;
  guint32             var_port_on_server;
  guint32             var_user;
  guint32             var_error_msg;

  if (tree) {
    ti = proto_tree_add_text(tree, offset, 0, "reply");
    reply_tree = proto_tree_add_subtree(ti, ett_identd_reply);
  }

  /* Handle the port-on-client field */
  if ((cc = ptvcursor_get_item_uint16(tvb, offset, 0, 0, &var_port_on_client)) < 0){

    /* Error handling code ... */

  }
  else {
    if (tree) {
      ti = proto_tree_add_text(tree, tvb, offset, 1+, "port-on-client: %s", tvb_format_text(tvb, offset, 1+));
    }
  offset += cc;

  /* Handle the un-named field of size *, value   */
  if ((cc = tvb_skip_bytes(tvb, offset, " ", 1, 0, 0)) < 0){

    /* Error handling code ... */

  }
  offset += cc;

  /* Handle the un-named field of size 1, value , */
  if ((cc = tvb_skip_bytes(tvb, offset, ",", 1, 1, 1)) < 0){

    /* Error handling code ... */

  }
  offset += cc;

  /* Handle the un-named field of size *, value   */
  if ((cc = tvb_skip_bytes(tvb, offset, " ", 1, 0, 0)) < 0){

    /* Error handling code ... */

  }
  offset += cc;

  /* Handle the port-on-server field */
  if ((cc = ptvcursor_get_item_uint16(tvb, offset, 0, 0, &var_port_on_server)) < 0){

    /* Error handling code ... */

  }
  else {
    if (tree) {
      ti = proto_tree_add_text(tree, tvb, offset, 1+, "port-on-server: %s", tvb_format_text(tvb, offset, 1+));
    }
  offset += cc;

  /* Handle the un-named field of size 1, value   */
  if ((cc = tvb_skip_bytes(tvb, offset, " ", 1, 1, 1)) < 0){

    /* Error handling code ... */

  }
  offset += cc;

  /* Handle the un-named field of size 1, value : */
  if ((cc = tvb_skip_bytes(tvb, offset, ":", 1, 1, 1)) < 0){

    /* Error handling code ... */

  }
  offset += cc;

  /* Handle the un-named field of size *, value   */
  if ((cc = tvb_skip_bytes(tvb, offset, " ", 1, 0, 0)) < 0){

    /* Error handling code ... */

  }
  offset += cc;

  if (tvb_strneql(tvb, offset, "USERID", 6) == 0) {

    offset += 6;

    /* Handle the un-named field of size *, value   */
    if ((cc = tvb_skip_bytes(tvb, offset, " ", 1, 0, 0)) < 0){

      /* Error handling code ... */

    }
    offset += cc;

    /* Handle the un-named field of size 1, value : */
    if ((cc = tvb_skip_bytes(tvb, offset, ":", 1, 1, 1)) < 0){

      /* Error handling code ... */

    }
    offset += cc;

    /* Handle the un-named field of size *, value   */
    if ((cc = tvb_skip_bytes(tvb, offset, " ", 1, 0, 0)) < 0){

      /* Error handling code ... */

    }
    offset += cc;

    /* Handle the user field */
    if ((cc = ptvcursor_get_item_(tvb, offset, 0, 0, &var_user)) < 0){

      /* Error handling code ... */

    }
    else {
      if (tree) {
        ti = proto_tree_add_text(tree, tvb, offset, 1+, "user: %s", tvb_format_text(tvb, offset, 1+));
      }
    offset += cc;

  }

  else if (tvb_strneql(tvb, offset, "ERROR", 5) == 0) {

    offset += 5;

    /* Handle the un-named field of size *, value   */
    if ((cc = tvb_skip_bytes(tvb, offset, " ", 1, 0, 0)) < 0){

      /* Error handling code ... */

    }
    offset += cc;

    /* Handle the un-named field of size 1, value : */
    if ((cc = tvb_skip_bytes(tvb, offset, ":", 1, 1, 1)) < 0){

      /* Error handling code ... */

    }
    offset += cc;

    /* Handle the un-named field of size *, value   */
    if ((cc = tvb_skip_bytes(tvb, offset, " ", 1, 0, 0)) < 0){

      /* Error handling code ... */

    }
    offset += cc;

    /* Handle the error-msg field */
    if ((cc = ptvcursor_get_item_(tvb, offset, 0, 0, &var_error_msg)) < 0){

      /* Error handling code ... */

    }
    else {
      if (tree) {
        ti = proto_tree_add_text(tree, tvb, offset, 1+, "error-msg: %s", tvb_format_text(tvb, offset, 1+));
      }
    offset += cc;

  }

  return (offset - st_offset);

}


static void
dissect_identd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
  proto_tree     *identd_tree, *ti;
}


/* Register all the bits needed with the filtering engine */

void
proto_register_identd(void)
{
  static hf_register_info hf[] = {
    { &hf_identd_req,
      /* Change the following to the type you need */
      { "Request", "identd.req", FT_BOOLEAN, BASE_NONE, NULL, 0x0, "" }},

    { &hf_identd_rsp,
      { "Response", "identd.rsp", FT_BOOLEAN, BASE_NONE, NULL, 0x0, "" }},

    /* Add more fields here */
  };
  static gint *ett[] = {
    &ett_identd
  };
  module_t *identd_module;

  /* Register our configuration options for , particularly our port */

  identd_module = prefs_register_module("identd", "IDENTD", proto_reg_handoff_identd);

  prefs_register_uint_preference(identd_module, "tcp.port", " TCP Port",
				 "Set the port for  messages (if other"
				 " than the default of 113)",
				 10, &global_identd_tcp_port);

  proto_identd = proto_register_protocol("Identification Protocol (RFC1413)",
				       "identd");

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

}

/* The registration hand-off routine */
void
proto_reg_handoff_identd(void)
{
  static int identd_prefs_initialized = FALSE;

  if (identd_prefs_initialized) {

    dissector_delete("tcp.port", tcp_port, dissect_identd);

  }
  else {

    identd_prefs_initialized = TRUE;

  }

  /* Set our port number for future use */

  tcp_port = global_identd_tcp_port;

  dissector_add("tcp.port", global_identd_tcp_port, dissect_identd);

}


Regards
-------
Richard Sharpe, sharpe@xxxxxxxxxx
Samba (Team member, www.samba.org), Ethereal (Team member, www.zing.org)
Contributing author, SAMS Teach Yourself Samba in 24 Hours
Author, Special Edition, Using Samba