Ethereal-dev: Re: [Ethereal-dev] Creating a new Dissector

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

From: "pevee" <clkuan@xxxxxxxxxxxxxxx>
Date: Mon, 7 Oct 2002 14:50:24 +0800
Hi,

Alas, the dissector code is done...
This is the first time I post such a thing...I will...

(1) Attached the packet-ac.c file
(2) Paste the packet-ac.c file at the mail content itself.

A big thank you to all :).....

============================================================================
=============

/* packet-ac.c
 * Routines for ac packet (Enterprise Packet) dissection
 *
 * Lim Thiam Ern<mercz@xxxxxxxxxxxxxx>
 *
 * $Id: packet-ac.c,v 1.00 2002/10/07 23:36:03 jmayer Exp $
 *
 * Ethereal - Network traffic analyzer
 * By Gerald Combs <gerald@xxxxxxxxxxxx>
 * Copyright 1998 Gerald Combs
 *
 * Copied from packet-tftp.c
 *
 * 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 <glib.h>
#include <epan/packet.h>
#include <epan/conversation.h>

static int proto_ac = -1;
static int ac_version = -1;
static int ac_opcode = -1;
static int ac_pap_chap = -1;
static int ac_psv = -1;
static int ac_serial_number = -1;
static int ac_request_id = -1;
static int ac_user_ip = -1;
static int ac_user_port = -1;
static int ac_error_code = -1;
static int ac_attribute_number = -1;
static int ac_attribute_type = -1;
static int ac_attribute_length = -1;
static int ac_username = -1;
static int ac_challenge = -1;
static int ac_password = -1;
static int ac_chap_password = -1;
static gint ett_ac = -1;

static dissector_handle_t ac_handle;

#define UDP_PORT_AC  2000

#define REQ_CHALLENGE  0x01
#define ACK_CHALLENGE  0x02
#define REQ_AUTHENTICATION 0x03
#define ACK_AUTHENTICATION 0x04
#define REQ_LOGOUT  0x05
#define ACK_LOGOUT  0x06
#define AFF_ACK_AUTHENTICATION 0x07
#define NTF_LOGOUT  0x08
#define REQ_INFO  0x09
#define ACK_INFO  0x0a

static const value_string ac_opcode_vals[] = {
 { REQ_CHALLENGE,   "Request Challenge"},
 { ACK_CHALLENGE,  "Acknowledge Challenge"},
 { REQ_AUTHENTICATION,  "Request Authentication"},
 { ACK_AUTHENTICATION,  "Acknowledge Authentication"},
 { REQ_LOGOUT,   "Request Logout"},
 { ACK_LOGOUT,   "Acknowledge Logout"},
 { AFF_ACK_AUTHENTICATION, "Affliliated ACK Authentication"},
 { NTF_LOGOUT,   "NTF Logout"},
 { REQ_INFO,   "Request Information"},
 { ACK_INFO,    "Acknowledge Information"},
};

static void dissect_ac (tvbuff_t *tvb, packet_info *pinfo, proto_tree
*tree){

 proto_tree *ac_tree = NULL;
 proto_item *ti;
 conversation_t *conversation;

 guint  offset = 0;
 guint   version; //version defined
 guint   opcode;  //opcode defined
 guint  pap_chap; //PAP/CHAP defined
 guint  psv;  //psv defined
 guint  serial_number;  //serial number defined
 guint   request_id; //request id defined
 guint32  user_ip; //user ip defined
 guint  user_port; //user port defined
 guint  error_code; //error code defined
 guint  attribute_number; //attribute number defined
 guint   attribute_type;
 guint  attribute_length;
 guint  il;  //somesort of counter for the offset

 //check whether the connection is ready for transmission
 if(pinfo-> destport == UDP_PORT_AC) {
  conversation = find_conversation(&pinfo ->src, &pinfo ->dst, PT_UDP,
pinfo->srcport, 0, NO_PORT_B);
  if (conversation == NULL) {
   conversation = conversation_new(&pinfo->src, &pinfo -> dst, PT_UDP,
pinfo->srcport, 0, NO_PORT2);
   conversation_set_dissector (conversation, ac_handle);
  }
 }

 //retrieve the VERSION of the packet
 if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "AC_Packet"); }

 version = tvb_get_guint8(tvb, offset);
 if (tree) {
  ti = proto_tree_add_item (tree, proto_ac, tvb, offset, 1, FALSE);
  ac_tree = proto_item_add_subtree(ti, ett_ac);
  proto_tree_add_uint (ac_tree, ac_version, tvb, offset, 1, version);
  }
 offset = offset + 1;

 //retrieve the OPCODE from the packet

 opcode = tvb_get_guint8(tvb, offset);
 if (tree) {
  proto_tree_add_uint (ac_tree, ac_opcode, tvb, offset, 1, opcode);
 }
 offset = offset + 1;

 //retrieve the PAP/CHAP from the packet

 pap_chap = tvb_get_guint8(tvb, offset);
 proto_tree_add_uint (ac_tree, ac_pap_chap, tvb, offset, 1, pap_chap);

 offset = offset + 1;

 //retrieve the PSV from the packet
 psv = tvb_get_guint8(tvb, offset);
 proto_tree_add_uint (ac_tree, ac_psv, tvb, offset, 1, psv);

 offset = offset + 1;

 //retrieve the Serial Number from the packet
 serial_number = tvb_get_ntohs(tvb, offset);
 proto_tree_add_uint (ac_tree, ac_serial_number, tvb, offset, 2,
serial_number);

 offset = offset + 2;

 //retrieve the Request ID from the packet
 request_id = tvb_get_ntohs(tvb, offset);
 proto_tree_add_uint (ac_tree, ac_request_id, tvb, offset, 2, request_id);

 offset = offset + 2;

 //retrieve the User IP Address from the packet
 user_ip = tvb_get_letohl(tvb, offset);
 proto_tree_add_ipv4 (ac_tree, ac_user_ip, tvb, offset + 4, 4, user_ip);

 offset = offset + 4;

 //retrieve the User Port from the packet
 user_port = tvb_get_ntohs(tvb, offset);
 proto_tree_add_uint (ac_tree, ac_user_port, tvb, offset, 2, user_port);

 offset = offset + 2;

 //retrieve the Error Code from the packet
 error_code = tvb_get_guint8(tvb, offset);
 proto_tree_add_uint (ac_tree, ac_error_code, tvb, offset, 1, error_code);

 offset = offset + 1;

 //retrieve the Attribute Number from the packet
 attribute_number = tvb_get_guint8 (tvb, offset);
 proto_tree_add_uint (ac_tree, ac_attribute_number, tvb, offset, 1,
attribute_number);

 offset = offset + 1;

 while (attribute_number!=0){

 //retrieve the Attribute type from the packet
 attribute_type = tvb_get_guint8 (tvb, offset);
 proto_tree_add_uint (ac_tree, ac_attribute_type, tvb, offset, 1,
attribute_type);
 offset += 1;

 //retrieve the Attribute Length from the packet
 attribute_length = tvb_get_guint8 (tvb, offset);
 proto_tree_add_uint (ac_tree, ac_attribute_length, tvb, offset, 1,
attribute_length);
 offset += 1;

 switch (attribute_type) {

  case 0x01: //username
   attribute_length = attribute_length - 2;
   if (tree) {
    ti = proto_tree_add_item (ac_tree, ac_username, tvb, offset,
attribute_length, FALSE);
   }
   //if (check_col(pinfo->cinfo, COL_INFO)) {
   // col_append_fstr(pinfo->cinfo, COL_INFO, " Username: %s",
tvb_get_ptr(tvb, offset, attribute_length));
   //}
   offset = offset + attribute_length;

   break;


  case 0x02: //password
   attribute_length = attribute_length - 2;
   if (tree) {
    ti = proto_tree_add_item (ac_tree, ac_password, tvb, offset,
attribute_length, FALSE);
   }
   //if (check_col(pinfo->cinfo, COL_INFO)) {
   // col_append_fstr (pinfo->cinfo, COL_INFO, " Password: %s",
tvb_get_ptr(tvb, offset, attribute_length));
   //}
   offset = offset +  attribute_length;
   break;

  case 0x03: //challenge
   attribute_length = attribute_length -2;
   if (tree) {
    ti = proto_tree_add_item (ac_tree, ac_challenge, tvb, offset,
attribute_length, FALSE);
   }
   //if (check_col(pinfo->cinfo, COL_INFO)) {
   // col_append_fstr (pinfo->cinfo, COL_INFO, " Challenge: %s",
tvb_get_ptr(tvb,offset,attribute_length));
   //}
   offset = offset + attribute_length;
   break;

  case 0x04: //chap_password
   attribute_length = attribute_length -2;
   if (tree) {
    ti = proto_tree_add_item (ac_tree, ac_chap_password, tvb, offset,
attribute_length, FALSE);
   }
   //if (check_col (pinfo->cinfo, COL_INFO)) {
   // col_append_fstr (pinfo->cinfo, COL_INFO, " ChapPassword: %s",
tvb_get_ptr(tvb, offset, attribute_length));
   //}
   offset = offset + attribute_length;
   break;
 }//end of switch

 attribute_number = attribute_number - 1;

 }//end of if (attribute_number)

}//end of dissect_ac

void proto_register_ac (void) //this function actually decodes the
information
{
 static hf_register_info hf[] = {
  { &ac_opcode,
   { "Opcode","ac.opcode",
    FT_UINT8, BASE_HEX, VALS(ac_opcode_vals), 0x0, "", HFILL }},

  { &ac_version,
   { "Version", "ac.version", FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL}},

  { &ac_pap_chap,
   { "PAP/CHAP", "ac.pap.chap", FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL}},

  { &ac_psv,
   { "PSV", "ac.psv", FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL}},

  { &ac_serial_number,
   { "Serial Number", "ac.serial.number",
    FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL}},

  { &ac_request_id,
   { "Request ID", "ac.request.id",
    FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL}},

  { &ac_user_ip,
   { "User IP", "user.ip",
    FT_IPv4, BASE_NONE, NULL, 0x0, "", HFILL}},

  { &ac_user_port,
   { "User Port", "user.port",
    FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},

  { &ac_error_code,
   { "Error Code", "error.code",
    FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL}},

  { &ac_attribute_number,
   { "Attribute number", "attribute.number",
    FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL}},

  { &ac_attribute_type,
   { "Attribute type", "attribute.type", FT_UINT8, BASE_HEX, NULL, 0x0, "",
HFILL}},

  { &ac_attribute_length,
   { "Attribute length", "attribute.length", FT_UINT8, BASE_DEC, NULL, 0x0,
"", HFILL}},

  { &ac_username,
   { "Username", "username", FT_STRINGZ, BASE_DEC, NULL, 0x0, "", HFILL}},

  { &ac_password,
   { "AC Password", "password", FT_STRINGZ, BASE_DEC, NULL, 0x0, "",
HFILL}},

  { &ac_challenge,
   { "AC Challenge", "ac.challenge", FT_STRINGZ, BASE_DEC, NULL, 0x0, "",
HFILL}},

  { &ac_chap_password,
   { "AC Chap Password", "ac.chap.password", FT_STRINGZ, BASE_DEC, NULL,
0x0, "", HFILL}},
 }; //end of hf_register_info

 static gint *ett[] = {
  &ett_ac,
 };

 proto_ac = proto_register_protocol("AC Transfer Protocol", "AC_Protocol",
"acp");

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

 ac_handle = create_dissector_handle(dissect_ac, proto_ac);
}

void proto_reg_handoff_ac (void)
{
 dissector_add ("udp.port", UDP_PORT_AC, ac_handle);
}

============================================================================
=============


Warm regards,

Thiam Ern<mercz@xxxxxxxxxxxxxx>


Attachment: packet-ac.c
Description: Binary data