From Richard Stearn: support for AX.25, including support for
authorGuy Harris <guy@alum.mit.edu>
Thu, 2 Aug 2012 16:54:43 +0000 (16:54 -0000)
committerGuy Harris <guy@alum.mit.edu>
Thu, 2 Aug 2012 16:54:43 +0000 (16:54 -0000)
LINKTYPE_AX25.

svn path=/trunk/; revision=44211

19 files changed:
capture_info.c
epan/address.h
epan/address_to_str.c
epan/column-utils.c
epan/dfilter/semcheck.c
epan/dissectors/Makefile.common
epan/dissectors/packet-ax25-kiss.c
epan/dissectors/packet-ax25.c [new file with mode: 0644]
epan/dissectors/packet-ax25.h [new file with mode: 0644]
epan/ftypes/ftype-bytes.c
epan/ftypes/ftypes.h
epan/libwireshark.def
epan/proto.c
epan/proto.h
epan/to_str.c
epan/to_str.h
wiretap/pcap-common.c
wiretap/wtap.c
wiretap/wtap.h

index 9e7e5845733577810d269caec05ce64e7bdd6623..27fd1a65818f0784abe58c09dd2280550c1c30aa 100644 (file)
@@ -41,6 +41,7 @@
 #include <epan/dissectors/packet-ap1394.h>
 #include <epan/dissectors/packet-atalk.h>
 #include <epan/dissectors/packet-atm.h>
+#include <epan/dissectors/packet-ax25.h>
 #include <epan/dissectors/packet-clip.h>
 #include <epan/dissectors/packet-eth.h>
 #include <epan/dissectors/packet-fddi.h>
@@ -355,6 +356,9 @@ capture_info_packet(packet_counts *counts, gint wtap_linktype, const guchar *pd,
     case WTAP_ENCAP_AX25_KISS:
         capture_ax25_kiss(pd, 0, caplen, counts);
         break;
+    case WTAP_ENCAP_AX25:
+        capture_ax25(pd, 0, caplen, counts);
+        break;
         /* XXX - some ATM drivers on FreeBSD might prepend a 4-byte ATM
            pseudo-header to DLT_ATM_RFC1483, with LLC header following;
            we might have to implement that at some point. */
index 7c6911e87ae2e7b4edee44d8500a445e3b5d9b42..9c87a9dfcbe3d70ffcaf6c68b66d226eb9478174 100644 (file)
@@ -55,8 +55,9 @@ typedef enum {
   AT_URI,              /* URI/URL/URN */
   AT_TIPC,             /* TIPC Address Zone,Subnetwork,Processor */
   AT_IB,               /* Infiniband GID/LID */
-  AT_USB               /* USB Device address
+  AT_USB,              /* USB Device address
                         * (0xffffffff represents the host) */
+  AT_AX25              /* AX.25 */
 } address_type;
 
 typedef struct _address {
index 9bd344e9f04e5bf352d048d6747bb565ad8c57c5..1965d88cee870884b5dd5ba8a9b604581dd25fd7 100644 (file)
@@ -586,6 +586,13 @@ address_to_str_buf(const address *addr, gchar *buf, int buf_len)
   case AT_IB:
     ib_addr_to_str_buf(addr, buf, buf_len);
     break;
+  case AT_AX25:
+    addrdata = addr->data;
+    g_snprintf(buf, buf_len, "%c%c%c%c%c%c-%02d",
+        (addrdata[0] >> 1) & 0x7f, (addrdata[1] >> 1) & 0x7f, (addrdata[2] >> 1) & 0x7f,
+        (addrdata[3] >> 1) & 0x7f, (addrdata[4] >> 1) & 0x7f, (addrdata[5] >> 1) & 0x7f,
+        (addrdata[6] >> 1) & 0x0f );
+    break;
   default:
     g_assert_not_reached();
   }
index 59b2dae9025e9468dbfb58588c16644a34f9675f..cffe5c5a129bd3c3f54c775f14b2a87e92e9d18e 100644 (file)
@@ -1388,6 +1388,14 @@ col_set_addr(packet_info *pinfo, const int col, const address *addr, const gbool
 
   switch (addr->type) {
 
+  case AT_AX25:
+    if (is_src)
+      pinfo->cinfo->col_expr.col_expr[col] = "ax25.src";
+    else
+      pinfo->cinfo->col_expr.col_expr[col] = "ax25.dst";
+    g_strlcpy(pinfo->cinfo->col_expr.col_expr_val[col], ax25_to_str(addr->data), COL_MAX_LEN);
+    break;
+
   case AT_ETHER:
     if (is_src)
       pinfo->cinfo->col_expr.col_expr[col] = "eth.src";
index 2e27978892343f2815cc66e60a7afb4a74a51707..3db5873c13613b7ff401f573865c54a0f2a52f98 100644 (file)
@@ -83,8 +83,9 @@ compatible_ftypes(ftenum_t a, ftenum_t b)
                case FT_UINT_BYTES:
                case FT_GUID:
                case FT_OID:
+               case FT_AX25:
 
-                       return (b == FT_ETHER || b == FT_BYTES || b == FT_UINT_BYTES || b == FT_GUID || b == FT_OID);
+                       return (b == FT_ETHER || b == FT_BYTES || b == FT_UINT_BYTES || b == FT_GUID || b == FT_OID || b == FT_AX25);
 
                case FT_BOOLEAN:
                case FT_FRAMENUM:
@@ -165,6 +166,7 @@ mk_fvalue_from_val_string(header_field_info *hfinfo, char *s)
                case FT_IPv4:
                case FT_IPv6:
                case FT_IPXNET:
+               case FT_AX25:
                case FT_ETHER:
                case FT_BYTES:
                case FT_UINT_BYTES:
@@ -262,6 +264,7 @@ static gboolean
 is_bytes_type(enum ftenum type)
 {
        switch(type) {
+               case FT_AX25:
                case FT_ETHER:
                case FT_BYTES:
                case FT_UINT_BYTES:
index a1a2ba29523c3a0931c9f2ff67afd606e0caeaf1..348b8a95f32ace8ad20009127ef6ac507124d7bf 100644 (file)
@@ -278,6 +278,7 @@ DISSECTOR_SRC = \
        packet-atm.c            \
        packet-atmtcp.c         \
        packet-auto_rp.c        \
+       packet-ax25.c           \
        packet-ax25-kiss.c      \
        packet-ax4000.c         \
        packet-ayiya.c          \
@@ -1194,6 +1195,7 @@ DISSECTOR_INCLUDES =      \
        packet-arp.h    \
        packet-atalk.h  \
        packet-atm.h    \
+       packet-ax25.h   \
        packet-ax25-kiss.h      \
        packet-bacapp.h \
        packet-ber.h    \
index ac0d3019aad00b1d0a04ecfb75abc56ca6f38456..00c8b857085adc4c4c5c06b41de5a8b9d87b9967 100644 (file)
 #include <epan/etypes.h>
 
 #include "packet-ax25-kiss.h"
+#include "packet-ax25.h"
 
 #define STRLEN 80
 
 void proto_reg_handoff_ax25_kiss(void);
 
 /* Dissector handles - all the possibles are listed */
+static dissector_handle_t ax25_handle;
+
 
 /* Initialize the protocol and registered fields */
 static int proto_ax25_kiss           = -1;
@@ -174,17 +177,14 @@ dissect_ax25_kiss( tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree )
        int kiss_param_len;
        char *frame_type_text;
        char *info_buffer;
-#if 0
        void *saved_private_data;
        tvbuff_t *next_tvb = NULL;
-#endif
 
 
        info_buffer = ep_alloc( STRLEN );
        info_buffer[0]='\0';
 
-       if ( check_col( pinfo->cinfo, COL_PROTOCOL ) )
-               col_set_str( pinfo->cinfo, COL_PROTOCOL, "KISS" );
+       col_set_str( pinfo->cinfo, COL_PROTOCOL, "AX.25 KISS" );
 
        col_clear( pinfo->cinfo, COL_INFO );
 
@@ -280,6 +280,13 @@ dissect_ax25_kiss( tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree )
        }
        /* Call sub-dissectors here */
 
+       if ( kiss_type == KISS_DATA_FRAME )
+               {
+               saved_private_data = pinfo->private_data;
+               next_tvb = tvb_new_subset( tvb, offset, -1, -1 );
+               call_dissector( ax25_handle, next_tvb, pinfo, parent_tree );
+               pinfo->private_data = saved_private_data;
+               }
 }
 
 void
@@ -370,6 +377,9 @@ proto_reg_handoff_ax25_kiss(void)
                kiss_handle = create_dissector_handle( dissect_ax25_kiss, proto_ax25_kiss );
                dissector_add_uint( "wtap_encap", WTAP_ENCAP_AX25_KISS, kiss_handle );
 
+               /* only currently implemented for AX.25 */
+               ax25_handle = find_dissector( "ax25" );
+
                inited = TRUE;
        }
 }
@@ -390,7 +400,7 @@ capture_ax25_kiss( const guchar *pd, int offset, int len, packet_counts *ld)
        l_offset += KISS_HEADER_SIZE; /* step over kiss header */
        switch ( kiss_cmd & KISS_CMD_MASK )
                {
-               case KISS_DATA_FRAME    : break;
+               case KISS_DATA_FRAME    : capture_ax25( pd, l_offset, len, ld ); break;
                case KISS_TXDELAY       : l_offset += 1; break;
                case KISS_PERSISTENCE   : l_offset += 1; break;
                case KISS_SLOT_TIME     : l_offset += 1; break;
diff --git a/epan/dissectors/packet-ax25.c b/epan/dissectors/packet-ax25.c
new file mode 100644 (file)
index 0000000..dc42f02
--- /dev/null
@@ -0,0 +1,630 @@
+/* packet-ax25.c
+ *
+ * Routines for Amateur Packet Radio protocol dissection
+ * Copyright 2005,2006,2007,2008,2009,2010,2012 R.W. Stearn <richard@rns-stearn.demon.co.uk>
+ *
+ * $Id$
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@ethereal.com>
+ * 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.
+ */
+
+/*
+ * This dissector is for:
+ * AX.25 Amateur Packet-Radio Link-Layer Protocol, Version 2.0, October 1984
+ * 
+ * At the time of writing the specification could be found here:
+ *   http://www.tapr.org/pub_ax25.html
+ *
+ * Inspiration on how to build the dissector drawn from
+ *   packet-sdlc.c
+ *   packet-x25.c
+ *   packet-lapb.c
+ *   paket-gprs-llc.c
+ *   xdlc.c
+ * with the base file built from README.developers.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+
+#include <epan/strutil.h>
+#include <epan/packet.h>
+#include <epan/prefs.h>
+#include <epan/emem.h>
+#include <epan/xdlc.h>
+#include <epan/etypes.h>
+#include <epan/ipproto.h>
+#include <packet-ip.h>
+
+#include "packet-ax25.h"
+
+#define STRLEN 80
+
+#define AX25_ADDR_LEN          7  /* length of an AX.25 address */
+#define AX25_HEADER_SIZE       15 /* length of src_addr + dst_addr + cntl */
+#define AX25_MAX_DIGIS         8
+
+/* Layer 3 Protocol ID's (pid) */
+#define AX25_P_ROSE    0x01    /* ISO 8208 / CCITT X.25 PLP */
+#define AX25_P_RFC1144C        0x06    /* Compressed TCP/IP packet. Van Jacobson RFC1144 */
+#define AX25_P_RFC1144 0x07    /* Uncompressed TCP/IP packet. Van Jacobson RFC1144 */
+#define AX25_P_SEGMENT 0x08    /* segmentation fragment */
+#define AX25_P_TEXNET  0xC3    /* TEXNET datagram */
+#define AX25_P_LCP     0xC4    /* Link Quality Protocol */
+#define AX25_P_ATALK   0xCA    /* AppleTalk */
+#define AX25_P_ATALKARP        0xCB    /* AppleTalk ARP */
+#define AX25_P_IP      0xCC    /* ARPA Internet Protocol */
+#define AX25_P_ARP     0xCD    /* ARPA Address Resolution Protocol */
+#define AX25_P_FLEXNET         0xCE    /* FlexNet */
+#define AX25_P_NETROM  0xCF    /* NET/ROM */
+#define AX25_P_NO_L3   0xF0    /* No layer 3 protocol */
+#define AX25_P_L3_ESC  0xFF    /* Escape character. Next octet contains more layer 3 protocol info */
+
+#define I_FRAME( control )  ( ( control & 0x01) == 0 )
+#define UI_FRAME( control ) ( ( ( control & 0x03) == 3 ) && ( ( ( ( ( control >> 5 ) & 0x07) << 2) | ( ( control >> 2 ) & 0x03) ) == 0 ) )
+
+/* Forward declaration we need below */
+void proto_reg_handoff_ax25(void);
+
+/* Dissector handles - all the possibles are listed */
+static dissector_handle_t rose_handle;
+static dissector_handle_t rfc1144c_handle;
+static dissector_handle_t rfc1144_handle;
+static dissector_handle_t segment_handle;
+static dissector_handle_t texnet_handle;
+static dissector_handle_t lcp_handle;
+static dissector_handle_t atalk_handle;
+static dissector_handle_t atalkarp_handle;
+static dissector_handle_t ip_handle;
+static dissector_handle_t arp_handle;
+static dissector_handle_t flexnet_handle;
+static dissector_handle_t netrom_handle;
+static dissector_handle_t no_l3_handle;
+static dissector_handle_t l3_esc_handle;
+static dissector_handle_t default_handle;
+
+/* Initialize the protocol and registered fields */
+static int proto_ax25          = -1;
+static int hf_ax25_dst         = -1;
+static int hf_ax25_src         = -1;
+static int hf_ax25_via[ AX25_MAX_DIGIS ]       = { -1,-1,-1,-1,-1,-1,-1,-1 };
+
+static int hf_ax25_ctl         = -1;
+
+static int hf_ax25_n_r         = -1;
+static int hf_ax25_n_s         = -1;
+
+static int hf_ax25_p           = -1;
+static int hf_ax25_f           = -1;
+
+static int hf_ax25_ftype_s     = -1;
+static int hf_ax25_ftype_i     = -1;
+static int hf_ax25_ftype_su    = -1;
+
+static int hf_ax25_u_cmd       = -1;
+static int hf_ax25_u_resp      = -1;
+
+static int hf_ax25_pid         = -1;
+
+static const xdlc_cf_items ax25_cf_items = {
+       &hf_ax25_n_r,
+       &hf_ax25_n_s,
+       &hf_ax25_p,
+       &hf_ax25_f,
+       &hf_ax25_ftype_s,
+       &hf_ax25_u_cmd,
+       &hf_ax25_u_resp,
+       &hf_ax25_ftype_i,
+       &hf_ax25_ftype_su
+};
+
+/* Global preference ("controls" display of numbers) */
+/*
+static gboolean gPREF_HEX = FALSE;
+*/
+
+/* Initialize the subtree pointers */
+static gint ett_ax25 = -1;
+static gint ett_ax25_ctl = -1;
+
+/* Code to actually dissect the packets */
+static void
+dissect_ax25( tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree )
+{
+       proto_item *ti;
+       proto_tree *ax25_tree;
+       int offset;
+       int control_offset;
+       int hdr_len;
+       int via_index;
+       char *info_buffer;
+       char v2cmdresp;
+       char *ax25_version;
+       int is_response;
+       char *text_ptr;
+       const guint8 *src_addr;
+       const guint8 *dst_addr;
+       const guint8 *via_addr;
+       guint8 control;
+       guint8 pid = AX25_P_NO_L3;
+       char *pid_text = NULL;
+       guint8 src_ssid;
+       guint8 dst_ssid;
+       void *saved_private_data;
+       tvbuff_t *next_tvb = NULL;
+
+
+       info_buffer = ep_alloc( STRLEN );
+       info_buffer[0]='\0';
+
+       col_set_str( pinfo->cinfo, COL_PROTOCOL, "AX.25" );
+    
+       col_clear( pinfo->cinfo, COL_INFO );
+
+       /* protocol offset for an AX.25 packet */
+       /* start at the dst addr */
+       offset = 0;
+
+       dst_addr = tvb_get_ptr( tvb,  offset, AX25_ADDR_LEN );
+       SET_ADDRESS( &pinfo->dl_dst,    AT_AX25, AX25_ADDR_LEN, dst_addr );
+       SET_ADDRESS( &pinfo->dst,       AT_AX25, AX25_ADDR_LEN, dst_addr );
+       dst_ssid = *(dst_addr + 6);
+       offset += AX25_ADDR_LEN; /* step over dst addr point at src addr */
+
+       src_addr = tvb_get_ptr( tvb,  offset, AX25_ADDR_LEN );
+       SET_ADDRESS( &pinfo->dl_src,    AT_AX25, AX25_ADDR_LEN, src_addr );
+       SET_ADDRESS( &pinfo->src,       AT_AX25, AX25_ADDR_LEN, src_addr );
+       src_ssid = *(src_addr + 6);
+       offset += AX25_ADDR_LEN; /* step over src addr point at either 1st via addr or control byte */
+
+       /* step over any vias */
+       while ( ( tvb_get_guint8( tvb, offset - 1 ) & 0x01 ) == 0 )
+               offset += AX25_ADDR_LEN; /* step over a via addr */
+
+       /* decode the cmd/resp field */
+       v2cmdresp = '.';
+       switch ( ( (dst_ssid >> 6) & 0x02) | ( (src_ssid >> 7) & 0x01 ) )
+               {
+               case 1 : /* V2.0 Response */
+                       ax25_version = "V2.0+";
+                       v2cmdresp = 'R';
+                       is_response = TRUE;
+                       break;
+               case 2 : /* V2.0 Command */
+                       ax25_version = "V2.0+";
+                       v2cmdresp = 'C';
+                       is_response = FALSE;
+                       break;
+               default :
+                       ax25_version = "V?.?";
+                       v2cmdresp = '?';
+                       is_response = FALSE;
+                       break;
+               }
+
+       /* decode the control field */
+       control_offset = offset;
+       control  = tvb_get_guint8( tvb, control_offset );
+
+       text_ptr = "????";
+       switch ( control & 0x03 )
+               {
+               case 1 :
+                       switch ( ( control >> 2 ) & 0x03 )
+                               {
+                               case 0 : text_ptr = "RR"; break;
+                               case 1 : text_ptr = "RNR"; break;
+                               case 2 : text_ptr = "REJ"; break;
+                               case 3 : text_ptr = "SREJ"; break;
+                               }
+                       break;
+               case 3 :
+                       switch ( ( ( ( control >> 5 ) & 0x07) << 2) | ( ( control >> 2 ) & 0x03) )
+                               {
+                               case 0  :  text_ptr = "UI"; break;
+                               case 3  :  text_ptr = "DM"; break;
+                               case 7  :  text_ptr = "SABM"; break;
+                               case 8  :  text_ptr = "DISC"; break;
+                               case 12 :  text_ptr = "UA"; break;
+                               case 15 :  text_ptr = "SABME"; break;
+                               case 17 :  text_ptr = "FRMR"; break;
+                               case 23 :  text_ptr = "XID"; break;
+                               case 28 :  text_ptr = "TEST"; break;
+                               default :  text_ptr = "????"; break;
+                               }
+                       break;
+               default :
+                       text_ptr = "I";
+                       break;
+               }
+       g_snprintf( info_buffer, STRLEN, "%s", text_ptr );
+
+       /* decode the pid field (if appropriate) */
+       if ( I_FRAME( control ) || UI_FRAME( control ) )
+               {
+               offset += 1; /* step over control byte point at pid */
+               pid      = tvb_get_guint8( tvb, offset );
+               switch ( pid )
+                       {
+                       case AX25_P_ROSE        : pid_text = "Rose"                     ; break;
+                       case AX25_P_RFC1144C    : pid_text = "RFC1144 (compressed)"     ; break;
+                       case AX25_P_RFC1144     : pid_text = "RFC1144 (uncompressed)"   ; break;
+                       case AX25_P_SEGMENT     : pid_text = "Segment"                  ; break;
+                       case AX25_P_TEXNET      : pid_text = "Texnet"                   ; break;
+                       case AX25_P_LCP         : pid_text = "Link Quality protocol"    ; break;
+                       case AX25_P_ATALK       : pid_text = "AppleTalk"                ; break;
+                       case AX25_P_ATALKARP    : pid_text = "AppleTalk ARP"            ; break;
+                       case AX25_P_IP          : pid_text = "IP"                       ; break;
+                       case AX25_P_ARP         : pid_text = "ARP"                      ; break;
+                       case AX25_P_FLEXNET     : pid_text = "FlexNet"                  ; break;
+                       case AX25_P_NETROM      : pid_text = "NetRom"                   ; break;
+                       case AX25_P_NO_L3       : pid_text = "No L3"                    ; break;
+                       case AX25_P_L3_ESC      : pid_text = "L3 esc"                   ; break;
+                       default                 : pid_text = "Unknown"                  ; break;
+                       }
+               g_snprintf( info_buffer, STRLEN, "%s (%s)", info_buffer, pid_text );
+               }
+
+       col_add_str( pinfo->cinfo, COL_INFO, info_buffer );
+
+       if ( parent_tree )
+               {
+               /* start at the dst addr */
+               offset = 0;
+
+               /* create display subtree for the protocol */
+               hdr_len = AX25_HEADER_SIZE;
+               if ( I_FRAME( control ) || UI_FRAME( control ) )
+                       hdr_len += 1;
+
+               ti = proto_tree_add_protocol_format( parent_tree, proto_ax25, tvb, offset, hdr_len,
+                       "AX.25, Src: %s (%s), Dst: %s (%s), Ver: %s",
+                       get_ax25_name( src_addr ),
+                       ax25_to_str( src_addr ),
+                       get_ax25_name( dst_addr ),
+                       ax25_to_str( dst_addr ),
+                       ax25_version
+                       );
+
+               ax25_tree = proto_item_add_subtree( ti, ett_ax25 );
+
+               proto_tree_add_ax25( ax25_tree, hf_ax25_dst, tvb, offset, AX25_ADDR_LEN, dst_addr );
+
+               /* step over dst addr point at src addr */
+               offset += AX25_ADDR_LEN;
+               proto_tree_add_ax25( ax25_tree, hf_ax25_src, tvb, offset, AX25_ADDR_LEN, src_addr );
+
+               /* step over src addr point at either 1st via addr or control byte */
+               offset += AX25_ADDR_LEN;
+
+               /* handle the vias, if any */
+               via_index = 0;
+               while ( ( tvb_get_guint8( tvb, offset - 1 ) & 0x01 ) == 0 )
+                       {
+                       if ( via_index < AX25_MAX_DIGIS )
+                               {
+                               via_addr = tvb_get_ptr( tvb,  offset, AX25_ADDR_LEN );
+                               proto_tree_add_ax25( ax25_tree, hf_ax25_via[ via_index ], tvb, offset, AX25_ADDR_LEN, via_addr );
+                               via_index++;
+                               }
+                       /* step over a via addr */
+                       offset += AX25_ADDR_LEN;
+                       }
+
+               dissect_xdlc_control(   tvb,
+                                       control_offset,
+                                       pinfo,
+                                       ax25_tree,
+                                       hf_ax25_ctl,
+                                       ett_ax25_ctl,
+                                       &ax25_cf_items,
+                                       NULL,
+                                       NULL,
+                                       NULL,
+                                       is_response,
+                                       FALSE,
+                                       FALSE );
+
+               if ( I_FRAME( control ) || UI_FRAME( control ) )
+                       {
+                       char *s;
+
+                       offset += 1; /* step over control byte point at pid */
+
+                       s = ep_alloc( STRLEN );
+                       g_snprintf( s, STRLEN, "%s (0x%0x)", pid_text, pid );
+                       proto_tree_add_string( ax25_tree, hf_ax25_pid, tvb, offset, 1, s );
+                       }
+               }
+
+       /* Call sub-dissectors here */
+
+       if ( I_FRAME( control ) || UI_FRAME( control ) )
+               {
+               offset += 1; /* step over pid to the 1st byte of the payload */
+
+               saved_private_data = pinfo->private_data;
+
+               next_tvb = tvb_new_subset(tvb, offset, -1, -1);
+
+               switch ( pid )
+                       {
+                       case AX25_P_ROSE        : call_dissector( rose_handle    , next_tvb, pinfo, parent_tree ); break;
+                       case AX25_P_RFC1144C    : call_dissector( rfc1144c_handle, next_tvb, pinfo, parent_tree ); break;
+                       case AX25_P_RFC1144     : call_dissector( rfc1144_handle , next_tvb, pinfo, parent_tree ); break;
+                       case AX25_P_SEGMENT     : call_dissector( segment_handle , next_tvb, pinfo, parent_tree ); break;
+                       case AX25_P_TEXNET      : call_dissector( texnet_handle  , next_tvb, pinfo, parent_tree ); break;
+                       case AX25_P_LCP         : call_dissector( lcp_handle     , next_tvb, pinfo, parent_tree ); break;
+                       case AX25_P_ATALK       : call_dissector( atalk_handle   , next_tvb, pinfo, parent_tree ); break;
+                       case AX25_P_ATALKARP    : call_dissector( atalkarp_handle, next_tvb, pinfo, parent_tree ); break;
+                       case AX25_P_IP          : call_dissector( ip_handle      , next_tvb, pinfo, parent_tree ); break;
+                       case AX25_P_ARP         : call_dissector( arp_handle     , next_tvb, pinfo, parent_tree ); break;
+                       case AX25_P_FLEXNET     : call_dissector( flexnet_handle , next_tvb, pinfo, parent_tree ); break;
+                       case AX25_P_NETROM      : call_dissector( netrom_handle  , next_tvb, pinfo, parent_tree ); break;
+                       case AX25_P_NO_L3       : call_dissector( no_l3_handle   , next_tvb, pinfo, parent_tree ); break;
+                       case AX25_P_L3_ESC      : call_dissector( l3_esc_handle  , next_tvb, pinfo, parent_tree ); break;
+                       default                 : call_dissector( default_handle , next_tvb, pinfo, parent_tree ); break;
+                       }
+               pinfo->private_data = saved_private_data;
+               }
+}
+
+void
+proto_register_ax25(void)
+{                 
+       module_t *ax25_module;
+       static const true_false_string flags_set_truth =
+               {
+               "Set",
+               "Not set"
+               };
+
+
+       /* Setup list of header fields */
+       static hf_register_info hf[] = {
+               { &hf_ax25_dst,
+                       { "Destination",                "ax25.dst",
+                       FT_AX25, BASE_NONE, NULL, 0x0,          
+                       "Destination callsign", HFILL }
+               },
+               { &hf_ax25_src,
+                       { "Source",                     "ax25.src",
+                       FT_AX25, BASE_NONE, NULL, 0x0,          
+                       "Source callsign", HFILL }
+               },
+               { &(hf_ax25_via[ 0 ]),
+                       { "Via 1",                      "ax25.via1",
+                       FT_AX25, BASE_NONE, NULL, 0x0,          
+                       "Via callsign 1", HFILL }
+               },
+               { &(hf_ax25_via[ 1 ]),
+                       { "Via 2",                      "ax25.via2",
+                       FT_AX25, BASE_NONE, NULL, 0x0,          
+                       "Via callsign 2", HFILL }
+               },
+               { &(hf_ax25_via[ 2 ]),
+                       { "Via 3",                      "ax25.via3",
+                       FT_AX25, BASE_NONE, NULL, 0x0,          
+                       "Via callsign 3", HFILL }
+               },
+               { &(hf_ax25_via[ 3 ]),
+                       { "Via 4",                      "ax25.via4",
+                       FT_AX25, BASE_NONE, NULL, 0x0,          
+                       "Via callsign 4", HFILL }
+               },
+               { &(hf_ax25_via[ 4 ]),
+                       { "Via 5",                      "ax25.via5",
+                       FT_AX25, BASE_NONE, NULL, 0x0,          
+                       "Via callsign 5", HFILL }
+               },
+               { &(hf_ax25_via[ 5 ]),
+                       { "Via 6",                      "ax25.via6",
+                       FT_AX25, BASE_NONE, NULL, 0x0,          
+                       "Via callsign 6", HFILL }
+               },
+               { &(hf_ax25_via[ 6 ]),
+                       { "Via 7",                      "ax25.via7",
+                       FT_AX25, BASE_NONE, NULL, 0x0,          
+                       "Via callsign 7", HFILL }
+               },
+               { &(hf_ax25_via[ 7 ]),
+                       { "Via 8",                      "ax25.via8",
+                       FT_AX25, BASE_NONE, NULL, 0x0,          
+                       "Via callsign 8", HFILL }
+               },
+               { &hf_ax25_ctl,
+                       { "Control",                    "ax25.ctl",
+                       FT_UINT8, BASE_HEX, NULL, 0x0,          
+                       "Control field", HFILL }
+               },
+               { &hf_ax25_n_r,
+                       { "n(r)",                       "ax25.ctl.n_r",
+                       FT_UINT8, BASE_DEC, NULL, XDLC_N_R_MASK,          
+                       "", HFILL }
+               },
+               { &hf_ax25_n_s,
+                       { "n(s)",                       "ax25.ctl.n_s",
+                       FT_UINT8, BASE_DEC, NULL, XDLC_N_S_MASK,          
+                       "", HFILL }
+               },
+               { &hf_ax25_p,
+                       { "Poll",                       "ax25.ctl.p",
+                       FT_BOOLEAN, 8, TFS(&flags_set_truth), XDLC_P_F,          
+                       "", HFILL }
+               },
+               { &hf_ax25_f,
+                       { "Final",                      "ax25.ctl.f",
+                       FT_BOOLEAN, 8, TFS(&flags_set_truth), XDLC_P_F,          
+                       "", HFILL }
+               },
+               { &hf_ax25_ftype_s,
+                       { "Frame type",                 "ax25.ctl.ftype_s",
+                       FT_UINT8, BASE_HEX, VALS(stype_vals), XDLC_S_FTYPE_MASK,          
+                       "", HFILL }
+               },
+               { &hf_ax25_ftype_i,
+                       { "Frame type",                 "ax25.ctl.ftype_i",
+                       FT_UINT8, BASE_HEX, VALS(ftype_vals), XDLC_I_MASK,          
+                       "", HFILL }
+               },
+               { &hf_ax25_ftype_su,
+                       { "Frame type",                 "ax25.ctl.ftype_su",
+                       FT_UINT8, BASE_HEX, VALS(ftype_vals), XDLC_S_U_MASK,          
+                       "", HFILL }
+               },
+               { &hf_ax25_u_cmd,
+                       { "Frame type",                 "ax25.ctl.u_cmd",
+                       FT_UINT8, BASE_HEX, VALS(modifier_vals_cmd), XDLC_U_MODIFIER_MASK,          
+                       "", HFILL }
+               },
+               { &hf_ax25_u_resp,
+                       { "Frame type",                 "ax25.ctl.u_resp",
+                       FT_UINT8, BASE_HEX, VALS(modifier_vals_resp), XDLC_U_MODIFIER_MASK,          
+                       "", HFILL }
+               },
+               { &hf_ax25_pid,
+                       { "Packet ID",                  "ax25.pid",
+                       FT_STRING, BASE_NONE, NULL, 0x0,          
+                       "Packet identifier", HFILL }
+               },
+       };
+
+       /* Setup protocol subtree array */
+       static gint *ett[] = {
+               &ett_ax25,
+               &ett_ax25_ctl,
+       };
+
+       /* Register the protocol name and description */
+       proto_ax25 = proto_register_protocol("Amateur Radio AX.25", "AX25", "ax25");
+
+       /* Register the dissector */
+       register_dissector( "ax25", dissect_ax25, proto_ax25 );
+
+       /* Required function calls to register the header fields and subtrees used */
+       proto_register_field_array( proto_ax25, hf, array_length(hf ) );
+       proto_register_subtree_array(ett, array_length(ett ) );
+        
+       /* Register preferences module */       
+        ax25_module = prefs_register_protocol( proto_ax25, proto_reg_handoff_ax25);
+     
+       /* Register any preference */        
+/*
+        prefs_register_bool_preference(ax25_module, "showhex", 
+             "Display numbers in Hex",
+            "Enable to display numerical values in hexadecimal.",
+            &gPREF_HEX );        
+*/
+}
+
+void
+proto_reg_handoff_ax25(void)
+{
+        static gboolean inited = FALSE;
+        
+        if( !inited ) {
+
+       dissector_handle_t ax25_handle;
+
+       ax25_handle = create_dissector_handle( dissect_ax25, proto_ax25 );
+       dissector_add( "wtap_encap", WTAP_ENCAP_AX25, ax25_handle );
+       dissector_add("ip.proto", IP_PROTO_AX25, ax25_handle);
+
+       /*
+         I have added the "data" dissector for all the currently known PID's
+         This is so at least we have an entry in the tree that allows the
+         payload to be hightlighted.
+         When a new dissector is available all that needs to be done is to
+         replace the current dissector name "data" with the new dissector name.
+       */
+       rose_handle     = find_dissector( "data" /* "x.25"      */ );
+       rfc1144c_handle = find_dissector( "data" /* "rfc1144c"  */ );
+       rfc1144_handle  = find_dissector( "data" /* "rfc1144"   */ );
+       segment_handle  = find_dissector( "data" /* "segment"   */ );
+       texnet_handle   = find_dissector( "data" /* "texnet"    */ );
+       lcp_handle      = find_dissector( "data" /* "lcp"       */ );
+       atalk_handle    = find_dissector( "data" /* "atalk"     */ );
+       atalkarp_handle = find_dissector( "data" /* "atalkarp"  */ );
+       ip_handle       = find_dissector( "data" /* "ip"        */ );
+       arp_handle      = find_dissector( "data" /* "arp"       */ );
+       flexnet_handle  = find_dissector( "data" /* "flexnet"   */ );
+       netrom_handle   = find_dissector( "data" /* "netrom"    */ );
+       no_l3_handle    = find_dissector( "data" /* "ax25_nol3" */ );
+       l3_esc_handle   = find_dissector( "data" /* "l3_esc"    */ );
+       default_handle  = find_dissector( "data" );
+
+        inited = TRUE;
+        }
+}
+
+void
+capture_ax25( const guchar *pd, int offset, int len, packet_counts *ld)
+{
+       guint8 control;
+       guint8 pid;
+       int l_offset;
+
+if ( ! BYTES_ARE_IN_FRAME( offset, len, AX25_HEADER_SIZE ) )
+       {
+       ld->other++;
+       return;
+       }
+
+l_offset = offset;
+l_offset += AX25_ADDR_LEN; /* step over dst addr point at src addr */
+l_offset += AX25_ADDR_LEN; /* step over src addr point at either 1st via addr or control byte */
+while ( ( pd[ l_offset - 1 ] & 0x01 ) == 0 )
+       l_offset += AX25_ADDR_LEN; /* step over a via addr */
+
+control = pd[ l_offset ];
+
+/* decode the pid field (if appropriate) */
+if ( I_FRAME( control ) || UI_FRAME( control ) )
+       {
+       l_offset += 1; /* step over control byte point at pid */
+       pid = pd[ l_offset ];
+
+       l_offset += 1; /* step over the pid and point to the first byte of the payload */
+       switch ( pid & 0x0ff )
+               {
+               case AX25_P_ROSE        : break;
+               case AX25_P_RFC1144C    : break;
+               case AX25_P_RFC1144     : break;
+               case AX25_P_SEGMENT     : break;
+               case AX25_P_TEXNET      : break;
+               case AX25_P_LCP         : break;
+               case AX25_P_ATALK       : break;
+               case AX25_P_ATALKARP    : break;
+               case AX25_P_IP          : break;
+               case AX25_P_ARP         : break;
+               case AX25_P_FLEXNET     : break;
+               case AX25_P_NETROM      : break;
+               case AX25_P_NO_L3       : break;
+               case AX25_P_L3_ESC      : break;
+               default                 : break;
+               }
+       }
+}
diff --git a/epan/dissectors/packet-ax25.h b/epan/dissectors/packet-ax25.h
new file mode 100644 (file)
index 0000000..92aa652
--- /dev/null
@@ -0,0 +1,32 @@
+/* packet-ax25.h
+ *
+ * Routines for Amateur Packet Radio protocol dissection
+ * Copyright 2005,2006,2007,2008,2009,2010,2012 R.W. Stearn <richard@rns-stearn.demon.co.uk>
+ *
+ * $Id$
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@ethereal.com>
+ * 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 __PACKET_AX25_H__
+#define __PACKET_AX25_H__
+
+void capture_ax25(const guchar *, int, int, packet_counts *);
+
+#endif
index 77712c71ba7b8d98b810c93b753a36a9728d04e4..4f5ab8ea3b87218658403aea6aab79c5275d2998 100644 (file)
@@ -143,6 +143,13 @@ common_fvalue_set(fvalue_t *fv, guint8* data, guint len)
        g_byte_array_append(fv->value.bytes, data, len);
 }
 
+static void
+ax25_fvalue_set(fvalue_t *fv, gpointer value, gboolean already_copied)
+{
+       g_assert(!already_copied);
+       common_fvalue_set(fv, value, FT_AX25_ADDR_LEN);
+}
+
 static void
 ether_fvalue_set(fvalue_t *fv, gpointer value, gboolean already_copied)
 {
@@ -209,6 +216,42 @@ bytes_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, Log
        return TRUE;
 }
 
+static gboolean
+ax25_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value, LogFunc logfunc)
+{
+       gchar   *mac;
+
+       /*
+        * Don't log a message if this fails; we'll try looking it
+        * up as another way if it does, and if that fails,
+        * we'll log a message.
+        */
+       if (bytes_from_unparsed(fv, s, TRUE, NULL)) {
+               if (fv->value.bytes->len > FT_AX25_ADDR_LEN) {
+                       logfunc("\"%s\" contains too many bytes to be a valid AX.25 address.",
+                           s);
+                       return FALSE;
+               }
+               else if (fv->value.bytes->len < FT_AX25_ADDR_LEN && !allow_partial_value) {
+                       logfunc("\"%s\" contains too few bytes to be a valid AX.25 address.",
+                           s);
+                       return FALSE;
+               }
+
+               return TRUE;
+       }
+
+       mac = get_ax25_name(s);
+       if (!mac) {
+               logfunc("\"%s\" is not a valid AX.25 address.",
+                   s);
+               return FALSE;
+       }
+
+       ax25_fvalue_set(fv, mac, FALSE);
+       return TRUE;
+}
+
 static gboolean
 ether_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value, LogFunc logfunc)
 {
@@ -536,6 +579,44 @@ ftype_register_bytes(void)
                slice,
        };
 
+       static ftype_t ax25_type = {
+               FT_AX25,                        /* ftype */
+               "FT_AX25",                      /* name */
+               "AX.25 address",                /* pretty_name */
+               FT_AX25_ADDR_LEN,               /* wire_size */
+               bytes_fvalue_new,               /* new_value */
+               bytes_fvalue_free,              /* free_value */
+               ax25_from_unparsed,             /* val_from_unparsed */
+               NULL,                           /* val_from_string */
+               bytes_to_repr,                  /* val_to_string_repr */
+               bytes_repr_len,                 /* len_string_repr */
+
+               ax25_fvalue_set,                /* set_value */
+               NULL,                           /* set_value_uinteger */
+               NULL,                           /* set_value_integer */
+               NULL,                           /* set_value_integer64 */
+               NULL,                           /* set_value_floating */
+
+               value_get,                      /* get_value */
+               NULL,                           /* set_value_uinteger */
+               NULL,                           /* get_value_integer */
+               NULL,                           /* get_value_integer64 */
+               NULL,                           /* get_value_floating */
+
+               cmp_eq,
+               cmp_ne,
+               cmp_gt,
+               cmp_ge,
+               cmp_lt,
+               cmp_le,
+               cmp_bitwise_and,
+               cmp_contains,
+               CMP_MATCHES,
+
+               len,
+               slice,
+       };
+
        static ftype_t ether_type = {
                FT_ETHER,                       /* ftype */
                "FT_ETHER",                     /* name */
@@ -614,6 +695,7 @@ ftype_register_bytes(void)
 
        ftype_register(FT_BYTES, &bytes_type);
        ftype_register(FT_UINT_BYTES, &uint_bytes_type);
+       ftype_register(FT_AX25, &ax25_type);
        ftype_register(FT_ETHER, &ether_type);
        ftype_register(FT_OID, &oid_type);
 }
index 3b416646408f44e085fe7f5dcb9c430c45174ab8..2b883908bb448adad3cb7cb183cefb3175b09466 100644 (file)
@@ -63,6 +63,7 @@ enum ftenum {
        FT_GUID,        /* GUID, UUID */
        FT_OID,         /* OBJECT IDENTIFIER */
        FT_EUI64,
+       FT_AX25,
        FT_NUM_TYPES /* last item number plus one */
 };
 
@@ -78,6 +79,7 @@ enum ftenum {
 #define FT_IPv6_LEN         16
 #define FT_IPXNET_LEN       4
 #define FT_EUI64_LEN        8
+#define FT_AX25_ADDR_LEN    7
 
 typedef enum ftenum ftenum_t;
 typedef struct _ftype_t ftype_t;
index f3ea4522ee96d6d0dcc57ee7cfe65d1a10217ad3..1b12e8c91e25f557ef9c7e809d059ac0c432788d 100644 (file)
@@ -49,6 +49,7 @@ camelSRTtype_naming             DATA
 capture_ap1394
 capture_arcnet
 capture_atm
+capture_ax25
 capture_ax25_kiss
 capture_chdlc
 capture_clip
index d79c10b09a2212e86984ca43e06211470d80007c..2871f42061ef8c0148ccb55f7e3bc3b9d7e377e6 100644 (file)
@@ -198,6 +198,10 @@ proto_tree_set_string(field_info *fi, const char* value);
 static void
 proto_tree_set_string_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length, gint encoding);
 static void
+proto_tree_set_ax25(field_info *fi, const guint8* value);
+static void
+proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, gint start);
+static void
 proto_tree_set_ether(field_info *fi, const guint8* value);
 static void
 proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start);
@@ -1342,6 +1346,11 @@ proto_tree_new_item(field_info *new_fi, proto_tree *tree,
                        proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
                        break;
 
+               case FT_AX25:
+                       DISSECTOR_ASSERT(length == 7);
+                       proto_tree_set_ax25_tvb(new_fi, tvb, start);
+                       break;
+
                case FT_ETHER:
                        DISSECTOR_ASSERT(length == FT_ETHER_LEN);
                        proto_tree_set_ether_tvb(new_fi, tvb, start);
@@ -2609,6 +2618,44 @@ proto_tree_set_string_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length
        proto_tree_set_string(fi, string);
 }
 
+
+/* Add a FT_AX25 to a proto_tree */
+proto_item *
+proto_tree_add_ax25(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
+               const guint8* value)
+{
+       proto_item              *pi;
+       field_info              *new_fi;
+       header_field_info       *hfinfo;
+
+       if (!tree)
+               return (NULL);
+
+       TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
+
+       PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
+       DISSECTOR_ASSERT(hfinfo->type == FT_AX25);
+
+       pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
+       proto_tree_set_ax25(new_fi, value);
+
+       return pi;
+}
+
+/* Set the FT_AX25 value */
+static void
+proto_tree_set_ax25(field_info *fi, const guint8* value)
+{
+       fvalue_set(&fi->value, (gpointer) value, FALSE);
+}
+
+static void
+proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, gint start)
+{
+       proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
+}
+
+
 /* Add a FT_ETHER to a proto_tree */
 proto_item *
 proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
@@ -5330,6 +5377,13 @@ proto_item_fill_label(field_info *fi, gchar *label_str)
                                   get_ipxnet_name(integer), integer);
                        break;
 
+               case FT_AX25:
+                       bytes = fvalue_get(&fi->value);
+                       label_fill_descr(label_str, hfinfo,
+                                  get_ax25_name(bytes),
+                                  ax25_to_str(bytes));
+                       break;
+
                case FT_ETHER:
                        bytes = fvalue_get(&fi->value);
                        label_fill_descr(label_str, hfinfo,
index 91e4d04f92fe504e8f5cff5848cdf207c6177e81..541212527959f4d153c4ea9d2003a7f3233dc1e6 100644 (file)
@@ -1039,6 +1039,18 @@ extern proto_item *
 proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
        gint length, const guint8* value_ptr, const char *format, ...) G_GNUC_PRINTF(7,8);
 
+/** Add a FT_AX25 to a proto_tree.
+ @param tree the tree to append this item to
+ @param hfindex field index
+ @param tvb the tv buffer of the current data
+ @param start start of data in tvb
+ @param length length of data in tvb
+ @param value data to display
+ @return the newly created item */
+extern proto_item *
+proto_tree_add_ax25(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
+       gint length, const guint8* value);
+
 /** Add a FT_ETHER to a proto_tree.
  @param tree the tree to append this item to
  @param hfindex field index
index cda834f11c776b4ebc41e83636e12beab917a62a..f173816b656ce99ff03ab494842e9b6a826eab5a 100644 (file)
@@ -1024,6 +1024,30 @@ decode_numeric_bitfield(const guint32 val, const guint32 mask, const int width,
   return buf;
 }
 
+/* XXX FIXME
+remove this one later when every call has been converted to address_to_str()
+*/
+gchar *
+ax25_to_str(const guint8 *ad)
+{
+       return bytestring_to_str(ad, 7, ':');
+}
+
+/* XXX FIXME
+remove this one later when every call has been converted to address_to_str()
+*/
+gchar *
+get_ax25_name(const guint8 *ad)
+{
+       address addr;
+
+       addr.type = AT_AX25;
+       addr.len  = 7;
+       addr.data = ad;
+
+       return address_to_str( &addr );
+}
+
 /*
  This function is very fast and this function is called a lot.
  XXX update the ep_address_to_str stuff to use this function.
index 2dd0d100e27b9a30651da86168162329e6c580d7..cf1dae30d879da7f40eec643c312ff96a20fea1e 100644 (file)
@@ -53,6 +53,8 @@ extern void     address_to_str_buf(const address *addr, gchar *buf, int buf_len)
 extern gchar*   bytestring_to_str(const guint8 *, const guint32, const char);
 extern gchar*  ether_to_str(const guint8 *);
 extern gchar*  tvb_ether_to_str(tvbuff_t *tvb, const gint offset);
+extern gchar*   ax25_to_str(const guint8 *);
+extern gchar*   get_ax25_name(const guint8 *);
 extern const gchar*    ip_to_str(const guint8 *);
 extern const gchar*    tvb_ip_to_str(tvbuff_t *tvb, const gint offset);
 extern void    ip_to_str_buf(const guint8 *ad, gchar *buf, const int buf_len);
index b43a504326a1482e705c114648477d5a20e84911..f1655020d6031909b5ff85d2fbc21a1fc55d51aa 100644 (file)
@@ -87,6 +87,7 @@ static const struct {
         */
        { 0,            WTAP_ENCAP_NULL },      /* null encapsulation */
        { 1,            WTAP_ENCAP_ETHERNET },
+       { 3,            WTAP_ENCAP_AX25 },
        { 6,            WTAP_ENCAP_TOKEN_RING },        /* IEEE 802 Networks - assume token ring */
        { 7,            WTAP_ENCAP_ARCNET },
        { 8,            WTAP_ENCAP_SLIP },
index 9431af403bb92145ff75cd4308f57ea18c912ce1..204c1e2b003f280ce792c77172d6ff667f39dd3b 100644 (file)
@@ -595,6 +595,9 @@ static struct encap_type_info encap_table_base[] = {
 
        /* WTAP_ENCAP_AX25_KISS */
        { "AX.25 with KISS header", "ax25-kiss" },
+
+       /* WTAP_ENCAP_AX25 */
+       { "Amateur Radio AX.25", "ax25" },
 };
 
 gint wtap_num_encap_types = sizeof(encap_table_base) / sizeof(struct encap_type_info);
index 9a55ce543f925b486db5c09fab738155c08bbf88..9e0397af17486f6ec73ff2e9ff29f53cf93ee91f 100644 (file)
@@ -238,6 +238,7 @@ extern "C" {
 #define WTAP_ENCAP_SDH                          146
 #define WTAP_ENCAP_DBUS                         147
 #define WTAP_ENCAP_AX25_KISS                    148
+#define WTAP_ENCAP_AX25                         149
 
 #define WTAP_NUM_ENCAP_TYPES                    wtap_get_num_encap_types()