Added PPPoE, PPTP, GRE, and ISAKMP dissectors.
authorGilbert Ramirez <gram@alumni.rice.edu>
Fri, 11 Jun 1999 15:30:55 +0000 (15:30 -0000)
committerGilbert Ramirez <gram@alumni.rice.edu>
Fri, 11 Jun 1999 15:30:55 +0000 (15:30 -0000)
svn path=/trunk/; revision=303

22 files changed:
AUTHORS
Makefile.am
Makefile.in
NEWS
aclocal.m4
capture.c
config.h.in
configure
doc/ethereal.pod
ethereal.c
ethertype.c
etypes.h
packet-gre.c [new file with mode: 0644]
packet-ip.c
packet-ip.h
packet-isakmp.c [new file with mode: 0644]
packet-ppp.c
packet-pppoe.c [new file with mode: 0644]
packet-pptp.c [new file with mode: 0644]
packet-tcp.c
packet-udp.c
packet.h

diff --git a/AUTHORS b/AUTHORS
index 31ab322d33ffdb8e24ca1caee5e2868d1f67bce9..5214007f892f347e2763392ada783e5b4f2c7a08 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -88,6 +88,14 @@ John McDermott <jjm@jkintl.com> {
        Pseudo-real-time capture
 }
 
+Jeff Jahr <jjahr@shastanets.com> {
+       PPP over Ethernet (PPPoe)
+}
+
+Brad Robel-Forrest <bradr@watchguard.com> {
+       ISAKMP, GRE, PPTP
+}
+
 Alain Magloire <alainm@rcsm.ece.mcgill.ca> was kind enough to
 give his permission to use his version of snprintf.c.
 
index e6dbe005ebef75aa64ac5c719373c0bfa28c0971..141c7d9d5b2e54c139eeb10184715acf8b998ed5 100644 (file)
@@ -37,8 +37,9 @@ ethereal_SOURCES = \
        packet-fddi.c  \
        packet-ftp.c   \
        packet-giop.c  \
+       packet-gre.c   \
        packet-http.c  \
-       packet-icmpv6.c \
+       packet-icmpv6.c\
        packet-ip.c    \
        packet-ip.h    \
        packet-ipsec.c \
@@ -46,6 +47,7 @@ ethereal_SOURCES = \
        packet-ipv6.h  \
        packet-ipx.c   \
        packet-ipx.h   \
+       packet-isakmp.c\
        packet-llc.c   \
        packet-lpd.c   \
        packet-nbipx.c \
@@ -59,12 +61,14 @@ ethereal_SOURCES = \
        packet-ospf.h  \
        packet-pop.c   \
        packet-ppp.c   \
+       packet-pppoe.c \
+       packet-pptp.c  \
        packet-raw.c   \
        packet-rip.c   \
        packet-rip.h   \
        packet-smb.c   \
        packet-tcp.c   \
-       packet-telnet.c \
+       packet-telnet.c\
        packet-tftp.c  \
        packet-tr.c    \
        packet-trmac.c \
index 0ee5f264cd9489a58fabc69fefc3a7d401318a5f..e63b37d979c9ac80bfbe197b0661d54702ce7b9d 100644 (file)
@@ -80,7 +80,7 @@ man_MANS = ethereal.1
 
 sysconf_DATA = manuf
 
-ethereal_SOURCES =     alignment.h     capture.c       capture.h       column.c        column.h        config.h        ethereal.c      ethereal.h      ethertype.c     etypes.h        file.c          file.h          filter.c        filter.h        follow.c        follow.h        gtkpacket.c     gtkpacket.h     menu.c          menu.h          packet-aarp.c   packet-arp.c    packet-atalk.c  packet-bootp.c  packet-cdp.c    packet-data.c   packet-dns.c    packet-dns.h    packet-eth.c    packet-fddi.c   packet-ftp.c    packet-giop.c   packet-http.c   packet-icmpv6.c         packet-ip.c     packet-ip.h     packet-ipsec.c  packet-ipv6.c   packet-ipv6.h   packet-ipx.c    packet-ipx.h    packet-llc.c    packet-lpd.c    packet-nbipx.c  packet-nbns.c   packet-ncp.c    packet-ncp.h    packet-nntp.c   packet-null.c   packet-osi.c    packet-ospf.c   packet-ospf.h   packet-pop.c    packet-ppp.c    packet-raw.c    packet-rip.c    packet-rip.h    packet-smb.c    packet-tcp.c    packet-telnet.c         packet-tftp.c   packet-tr.c     packet-trmac.c  packet-udp.c    packet-vines.c  packet-vines.h  packet.c        packet.h        prefs.c         prefs.h         print.c         print.h         ps.c            ps.h            resolv.c        resolv.h        smb.h           util.c          util.h
+ethereal_SOURCES =     alignment.h     capture.c       capture.h       column.c        column.h        config.h        ethereal.c      ethereal.h      ethertype.c     etypes.h        file.c          file.h          filter.c        filter.h        follow.c        follow.h        gtkpacket.c     gtkpacket.h     menu.c          menu.h          packet-aarp.c   packet-arp.c    packet-atalk.c  packet-bootp.c  packet-cdp.c    packet-data.c   packet-dns.c    packet-dns.h    packet-eth.c    packet-fddi.c   packet-ftp.c    packet-giop.c   packet-gre.c    packet-http.c   packet-icmpv6.c         packet-ip.c     packet-ip.h     packet-ipsec.c  packet-ipv6.c   packet-ipv6.h   packet-ipx.c    packet-ipx.h    packet-isakmp.c         packet-llc.c    packet-lpd.c    packet-nbipx.c  packet-nbns.c   packet-ncp.c    packet-ncp.h    packet-nntp.c   packet-null.c   packet-osi.c    packet-ospf.c   packet-ospf.h   packet-pop.c    packet-ppp.c    packet-pppoe.c  packet-pptp.c   packet-raw.c    packet-rip.c    packet-rip.h    packet-smb.c    packet-tcp.c    packet-telnet.c         packet-tftp.c   packet-tr.c     packet-trmac.c  packet-udp.c    packet-vines.c  packet-vines.h  packet.c        packet.h        prefs.c         prefs.h         print.c         print.h         ps.c            ps.h            resolv.c        resolv.h        smb.h           util.c          util.h
 
 
 EXTRA_ethereal_SOURCES =       packet-snmp.c           snprintf.c              snprintf.h              snprintf-imp.h
@@ -110,13 +110,14 @@ LIBS = @LIBS@
 ethereal_OBJECTS =  capture.o column.o ethereal.o ethertype.o file.o \
 filter.o follow.o gtkpacket.o menu.o packet-aarp.o packet-arp.o \
 packet-atalk.o packet-bootp.o packet-cdp.o packet-data.o packet-dns.o \
-packet-eth.o packet-fddi.o packet-ftp.o packet-giop.o packet-http.o \
-packet-icmpv6.o packet-ip.o packet-ipsec.o packet-ipv6.o packet-ipx.o \
-packet-llc.o packet-lpd.o packet-nbipx.o packet-nbns.o packet-ncp.o \
-packet-nntp.o packet-null.o packet-osi.o packet-ospf.o packet-pop.o \
-packet-ppp.o packet-raw.o packet-rip.o packet-smb.o packet-tcp.o \
-packet-telnet.o packet-tftp.o packet-tr.o packet-trmac.o packet-udp.o \
-packet-vines.o packet.o prefs.o print.o ps.o resolv.o util.o
+packet-eth.o packet-fddi.o packet-ftp.o packet-giop.o packet-gre.o \
+packet-http.o packet-icmpv6.o packet-ip.o packet-ipsec.o packet-ipv6.o \
+packet-ipx.o packet-isakmp.o packet-llc.o packet-lpd.o packet-nbipx.o \
+packet-nbns.o packet-ncp.o packet-nntp.o packet-null.o packet-osi.o \
+packet-ospf.o packet-pop.o packet-ppp.o packet-pppoe.o packet-pptp.o \
+packet-raw.o packet-rip.o packet-smb.o packet-tcp.o packet-telnet.o \
+packet-tftp.o packet-tr.o packet-trmac.o packet-udp.o packet-vines.o \
+packet.o prefs.o print.o ps.o resolv.o util.o
 ethereal_LDFLAGS = 
 CFLAGS = @CFLAGS@
 COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
@@ -144,17 +145,18 @@ DEP_FILES =  .deps/capture.P .deps/column.P .deps/ethereal.P \
 .deps/packet-atalk.P .deps/packet-bootp.P .deps/packet-cdp.P \
 .deps/packet-data.P .deps/packet-dns.P .deps/packet-eth.P \
 .deps/packet-fddi.P .deps/packet-ftp.P .deps/packet-giop.P \
-.deps/packet-http.P .deps/packet-icmpv6.P .deps/packet-ip.P \
-.deps/packet-ipsec.P .deps/packet-ipv6.P .deps/packet-ipx.P \
-.deps/packet-llc.P .deps/packet-lpd.P .deps/packet-nbipx.P \
-.deps/packet-nbns.P .deps/packet-ncp.P .deps/packet-nntp.P \
-.deps/packet-null.P .deps/packet-osi.P .deps/packet-ospf.P \
-.deps/packet-pop.P .deps/packet-ppp.P .deps/packet-raw.P \
-.deps/packet-rip.P .deps/packet-smb.P .deps/packet-snmp.P \
-.deps/packet-tcp.P .deps/packet-telnet.P .deps/packet-tftp.P \
-.deps/packet-tr.P .deps/packet-trmac.P .deps/packet-udp.P \
-.deps/packet-vines.P .deps/packet.P .deps/prefs.P .deps/print.P \
-.deps/ps.P .deps/resolv.P .deps/snprintf.P .deps/util.P
+.deps/packet-gre.P .deps/packet-http.P .deps/packet-icmpv6.P \
+.deps/packet-ip.P .deps/packet-ipsec.P .deps/packet-ipv6.P \
+.deps/packet-ipx.P .deps/packet-isakmp.P .deps/packet-llc.P \
+.deps/packet-lpd.P .deps/packet-nbipx.P .deps/packet-nbns.P \
+.deps/packet-ncp.P .deps/packet-nntp.P .deps/packet-null.P \
+.deps/packet-osi.P .deps/packet-ospf.P .deps/packet-pop.P \
+.deps/packet-ppp.P .deps/packet-pppoe.P .deps/packet-pptp.P \
+.deps/packet-raw.P .deps/packet-rip.P .deps/packet-smb.P \
+.deps/packet-snmp.P .deps/packet-tcp.P .deps/packet-telnet.P \
+.deps/packet-tftp.P .deps/packet-tr.P .deps/packet-trmac.P \
+.deps/packet-udp.P .deps/packet-vines.P .deps/packet.P .deps/prefs.P \
+.deps/print.P .deps/ps.P .deps/resolv.P .deps/snprintf.P .deps/util.P
 SOURCES = $(ethereal_SOURCES) $(EXTRA_ethereal_SOURCES)
 OBJECTS = $(ethereal_OBJECTS)
 
diff --git a/NEWS b/NEWS
index 9c26a94511ce4d27ce14d072fc8d19e0f76b5820..ee928e5a8319cc1bcbc1c8e8916919f414863c28 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,7 @@
+Overview of changes in Ethereal 0.6.3:
+* PPPoE (PPP over Ethernet) added (Jeff Jahr)
+* ISAKMP, GRE, PPTP added (Brad Robel-Forrest)
+
 Overview of changes in Ethereal 0.6.2:
 * Almost-real-time capture and display (John, Laurent)
 * Initial support for SMB (Richard)
index 5fd4db5b31931668903fe906ac566e05b48b1276..aa9e319f1ed800ad33ab80629d280a6ed9ed9807 100644 (file)
@@ -1,7 +1,7 @@
-dnl aclocal.m4 generated automatically by aclocal 1.4
+dnl aclocal.m4 generated automatically by aclocal 1.3
 
-dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
-dnl This file is free software; the Free Software Foundation
+dnl Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+dnl This Makefile.in is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
 dnl with or without modifications, as long as this notice is preserved.
 
@@ -192,8 +192,8 @@ if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
   AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
 fi
 ifelse([$3],,
-AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
-AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package]))
+AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE")
+AC_DEFINE_UNQUOTED(VERSION, "$VERSION"))
 AC_REQUIRE([AM_SANITY_CHECK])
 AC_REQUIRE([AC_ARG_PROGRAM])
 dnl FIXME This is truly gross.
@@ -205,6 +205,15 @@ AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir)
 AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir)
 AC_REQUIRE([AC_PROG_MAKE_SET])])
 
+
+# serial 1
+
+AC_DEFUN(AM_PROG_INSTALL,
+[AC_REQUIRE([AC_PROG_INSTALL])
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+AC_SUBST(INSTALL_SCRIPT)dnl
+])
+
 #
 # Check to make sure that the build environment is sane.
 #
@@ -267,7 +276,7 @@ AC_SUBST($1)])
 # Configure paths for GTK+
 # Owen Taylor     97-11-3
 
-dnl AM_PATH_GTK([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND [, MODULES]]]])
+dnl AM_PATH_GTK([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
 dnl Test for GTK, and define GTK_CFLAGS and GTK_LIBS
 dnl
 AC_DEFUN(AM_PATH_GTK,
@@ -281,15 +290,6 @@ AC_ARG_WITH(gtk-exec-prefix,[  --with-gtk-exec-prefix=PFX Exec prefix where GTK
 AC_ARG_ENABLE(gtktest, [  --disable-gtktest       Do not try to compile and run a test GTK program],
                    , enable_gtktest=yes)
 
-  for module in . $4
-  do
-      case "$module" in
-         gthread) 
-             gtk_config_args="$gtk_config_args gthread"
-         ;;
-      esac
-  done
-
   if test x$gtk_config_exec_prefix != x ; then
      gtk_config_args="$gtk_config_args --exec-prefix=$gtk_config_exec_prefix"
      if test x${GTK_CONFIG+set} != xset ; then
@@ -322,7 +322,7 @@ AC_ARG_ENABLE(gtktest, [  --disable-gtktest       Do not try to compile and run
       ac_save_CFLAGS="$CFLAGS"
       ac_save_LIBS="$LIBS"
       CFLAGS="$CFLAGS $GTK_CFLAGS"
-      LIBS="$GTK_LIBS $LIBS"
+      LIBS="$LIBS $GTK_LIBS"
 dnl
 dnl Now check if the installed GTK is sufficiently new. (Also sanity
 dnl checks the results of gtk-config to some extent
@@ -331,7 +331,6 @@ dnl
       AC_TRY_RUN([
 #include <gtk/gtk.h>
 #include <stdio.h>
-#include <stdlib.h>
 
 int 
 main ()
@@ -364,17 +363,6 @@ main ()
       printf("*** to point to the correct copy of gtk-config, and remove the file config.cache\n");
       printf("*** before re-running configure\n");
     } 
-#if defined (GTK_MAJOR_VERSION) && defined (GTK_MINOR_VERSION) && defined (GTK_MICRO_VERSION)
-  else if ((gtk_major_version != GTK_MAJOR_VERSION) ||
-          (gtk_minor_version != GTK_MINOR_VERSION) ||
-           (gtk_micro_version != GTK_MICRO_VERSION))
-    {
-      printf("*** GTK+ header files (version %d.%d.%d) do not match\n",
-            GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION);
-      printf("*** library (version %d.%d.%d)\n",
-            gtk_major_version, gtk_minor_version, gtk_micro_version);
-    }
-#endif /* defined (GTK_MAJOR_VERSION) ... */
   else
     {
       if ((gtk_major_version > major) ||
index da5dfb5f41ac6f11ab21df3a127a457e2dd6cb96..73c226b663eff1ae22d624d701a9ca3cecb586a8 100644 (file)
--- a/capture.c
+++ b/capture.c
@@ -1,7 +1,7 @@
 /* capture.c
  * Routines for packet capture windows
  *
- * $Id: capture.c,v 1.24 1999/06/05 01:44:11 guy Exp $
+ * $Id: capture.c,v 1.25 1999/06/11 15:30:34 gram Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -435,7 +435,7 @@ capture_prep_close_cb(GtkWidget *w, gpointer win) {
 void
 capture(void) {
   GtkWidget  *cap_w, *main_vb, *count_lb, *tcp_lb, *udp_lb, 
-             *ospf_lb, *other_lb, *stop_bt;
+             *ospf_lb, *gre_lb, *other_lb, *stop_bt;
   pcap_t     *pch;
   gchar       err_str[PCAP_ERRBUF_SIZE], label_str[32];
   loop_data   ld;
@@ -451,6 +451,7 @@ capture(void) {
   ld.counts.tcp   = 0;
   ld.counts.udp   = 0;
   ld.counts.ospf  = 0;
+  ld.counts.gre   = 0;
   ld.counts.other = 0;
   ld.pdh          = NULL;
 
@@ -510,6 +511,10 @@ capture(void) {
     gtk_box_pack_start(GTK_BOX(main_vb), ospf_lb, FALSE, FALSE, 3);
     gtk_widget_show(ospf_lb);
 
+    gre_lb = gtk_label_new("GRE: 0 (0.0%)");
+    gtk_box_pack_start(GTK_BOX(main_vb), gre_lb, FALSE, FALSE, 3);
+    gtk_widget_show(gre_lb);
+
     other_lb = gtk_label_new("Other: 0 (0.0%)");
     gtk_box_pack_start(GTK_BOX(main_vb), other_lb, FALSE, FALSE, 3);
     gtk_widget_show(other_lb);
@@ -553,6 +558,10 @@ capture(void) {
          pct(ld.counts.ospf, ld.counts.total));
         gtk_label_set(GTK_LABEL(ospf_lb), label_str);
 
+        sprintf(label_str, "GRE: %d (%.1f%%)", ld.counts.gre,
+         pct(ld.counts.gre, ld.counts.total));
+        gtk_label_set(GTK_LABEL(gre_lb), label_str);
+
         sprintf(label_str, "Other: %d (%.1f%%)", ld.counts.other,
           pct(ld.counts.other, ld.counts.total));
         gtk_label_set(GTK_LABEL(other_lb), label_str);
index bfca2a5851a232586c327291e1dedb53e08c315e..1793da99196a1d7249bf3afe2aeb5a75c50d591f 100644 (file)
@@ -7,6 +7,10 @@
    byte first (like Motorola and SPARC, unlike Intel and VAX).  */
 #undef WORDS_BIGENDIAN
 
+#undef PACKAGE
+
+#undef VERSION
+
 #undef HAVE_SA_LEN
 
 #undef DATAFILE_DIR
 
 /* Define if you have the pcap library (-lpcap).  */
 #undef HAVE_LIBPCAP
-
-/* Name of package */
-#undef PACKAGE
-
-/* Version number of package */
-#undef VERSION
-
index c324e93ac5ad26eb1d8d3eb579663f20e217743c..35dcb147c67eb3c6e05fcdb7b0252b4d484462e4 100755 (executable)
--- a/configure
+++ b/configure
@@ -1133,15 +1133,6 @@ else
 fi
 
 
-  for module in . 
-  do
-      case "$module" in
-         gthread) 
-             gtk_config_args="$gtk_config_args gthread"
-         ;;
-      esac
-  done
-
   if test x$gtk_config_exec_prefix != x ; then
      gtk_config_args="$gtk_config_args --exec-prefix=$gtk_config_exec_prefix"
      if test x${GTK_CONFIG+set} != xset ; then
@@ -1158,7 +1149,7 @@ fi
   # Extract the first word of "gtk-config", so it can be a program name with args.
 set dummy gtk-config; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1162: checking for $ac_word" >&5
+echo "configure:1153: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_GTK_CONFIG'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1193,7 +1184,7 @@ fi
 
   min_gtk_version=1.0.0
   echo $ac_n "checking for GTK - version >= $min_gtk_version""... $ac_c" 1>&6
-echo "configure:1197: checking for GTK - version >= $min_gtk_version" >&5
+echo "configure:1188: checking for GTK - version >= $min_gtk_version" >&5
   no_gtk=""
   if test "$GTK_CONFIG" = "no" ; then
     no_gtk=yes
@@ -1210,18 +1201,17 @@ echo "configure:1197: checking for GTK - version >= $min_gtk_version" >&5
       ac_save_CFLAGS="$CFLAGS"
       ac_save_LIBS="$LIBS"
       CFLAGS="$CFLAGS $GTK_CFLAGS"
-      LIBS="$GTK_LIBS $LIBS"
+      LIBS="$LIBS $GTK_LIBS"
       rm -f conf.gtktest
       if test "$cross_compiling" = yes; then
   echo $ac_n "cross compiling; assumed OK... $ac_c"
 else
   cat > conftest.$ac_ext <<EOF
-#line 1220 "configure"
+#line 1211 "configure"
 #include "confdefs.h"
 
 #include <gtk/gtk.h>
 #include <stdio.h>
-#include <stdlib.h>
 
 int 
 main ()
@@ -1254,17 +1244,6 @@ main ()
       printf("*** to point to the correct copy of gtk-config, and remove the file config.cache\n");
       printf("*** before re-running configure\n");
     } 
-#if defined (GTK_MAJOR_VERSION) && defined (GTK_MINOR_VERSION) && defined (GTK_MICRO_VERSION)
-  else if ((gtk_major_version != GTK_MAJOR_VERSION) ||
-          (gtk_minor_version != GTK_MINOR_VERSION) ||
-           (gtk_micro_version != GTK_MICRO_VERSION))
-    {
-      printf("*** GTK+ header files (version %d.%d.%d) do not match\n",
-            GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION);
-      printf("*** library (version %d.%d.%d)\n",
-            gtk_major_version, gtk_minor_version, gtk_micro_version);
-    }
-#endif /* defined (GTK_MAJOR_VERSION) ... */
   else
     {
       if ((gtk_major_version > major) ||
@@ -1294,7 +1273,7 @@ main ()
 }
 
 EOF
-if { (eval echo configure:1298: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:1277: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   :
 else
@@ -1328,7 +1307,7 @@ fi
           CFLAGS="$CFLAGS $GTK_CFLAGS"
           LIBS="$LIBS $GTK_LIBS"
           cat > conftest.$ac_ext <<EOF
-#line 1332 "configure"
+#line 1311 "configure"
 #include "confdefs.h"
 
 #include <gtk/gtk.h>
@@ -1338,7 +1317,7 @@ int main() {
  return ((gtk_major_version) || (gtk_minor_version) || (gtk_micro_version)); 
 ; return 0; }
 EOF
-if { (eval echo configure:1342: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1321: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
    echo "*** The test program compiled, but did not run. This usually means"
           echo "*** that the run-time linker is not finding GTK or finding the wrong"
@@ -1379,7 +1358,7 @@ rm -f conftest*
 
 # Evidently, some systems have pcap.h, etc. in */include/pcap
 echo $ac_n "checking for extraneous pcap header directories""... $ac_c" 1>&6
-echo "configure:1383: checking for extraneous pcap header directories" >&5
+echo "configure:1362: checking for extraneous pcap header directories" >&5
 found_pcap_dir=""
 for pcap_dir in /usr/include/pcap /usr/local/include/pcap
 do
@@ -1399,7 +1378,7 @@ fi
 
 # Pcap checks
 echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-echo "configure:1403: checking how to run the C preprocessor" >&5
+echo "configure:1382: checking how to run the C preprocessor" >&5
 # On Suns, sometimes $CPP names a directory.
 if test -n "$CPP" && test -d "$CPP"; then
   CPP=
@@ -1414,13 +1393,13 @@ else
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp.
   cat > conftest.$ac_ext <<EOF
-#line 1418 "configure"
+#line 1397 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1424: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1403: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
@@ -1431,13 +1410,13 @@ else
   rm -rf conftest*
   CPP="${CC-cc} -E -traditional-cpp"
   cat > conftest.$ac_ext <<EOF
-#line 1435 "configure"
+#line 1414 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1441: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1420: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
@@ -1448,13 +1427,13 @@ else
   rm -rf conftest*
   CPP="${CC-cc} -nologo -E"
   cat > conftest.$ac_ext <<EOF
-#line 1452 "configure"
+#line 1431 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1458: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1437: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
@@ -1480,17 +1459,17 @@ echo "$ac_t""$CPP" 1>&6
 
 ac_safe=`echo "net/bpf.h" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for net/bpf.h""... $ac_c" 1>&6
-echo "configure:1484: checking for net/bpf.h" >&5
+echo "configure:1463: checking for net/bpf.h" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1489 "configure"
+#line 1468 "configure"
 #include "confdefs.h"
 #include <net/bpf.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1494: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1473: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -1514,17 +1493,17 @@ fi
 
 ac_safe=`echo "pcap.h" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for pcap.h""... $ac_c" 1>&6
-echo "configure:1518: checking for pcap.h" >&5
+echo "configure:1497: checking for pcap.h" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1523 "configure"
+#line 1502 "configure"
 #include "confdefs.h"
 #include <pcap.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1528: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1507: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -1547,7 +1526,7 @@ else
 fi
 
 echo $ac_n "checking for pcap_open_offline in -lpcap""... $ac_c" 1>&6
-echo "configure:1551: checking for pcap_open_offline in -lpcap" >&5
+echo "configure:1530: checking for pcap_open_offline in -lpcap" >&5
 ac_lib_var=`echo pcap'_'pcap_open_offline | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1555,7 +1534,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lpcap  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1559 "configure"
+#line 1538 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1566,7 +1545,7 @@ int main() {
 pcap_open_offline()
 ; return 0; }
 EOF
-if { (eval echo configure:1570: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1549: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1597,7 +1576,7 @@ fi
 
 # Wiretap check
 echo $ac_n "checking whether to include wiretap library""... $ac_c" 1>&6
-echo "configure:1601: checking whether to include wiretap library" >&5
+echo "configure:1580: checking whether to include wiretap library" >&5
 # Check whether --with-wiretap or --without-wiretap was given.
 if test "${with_wiretap+set}" = set; then
   withval="$with_wiretap"
@@ -1639,7 +1618,7 @@ fi
 
 
 echo $ac_n "checking whether to enable ipv6 name resolution if available""... $ac_c" 1>&6
-echo "configure:1643: checking whether to enable ipv6 name resolution if available" >&5
+echo "configure:1622: checking whether to enable ipv6 name resolution if available" >&5
 if test "x$enable_ipv6" = "xno" ; then
        echo "$ac_t""no" 1>&6
 else
@@ -1649,12 +1628,12 @@ else
        v6lib=none
 
        echo $ac_n "checking ipv6 stack type""... $ac_c" 1>&6
-echo "configure:1653: checking ipv6 stack type" >&5
+echo "configure:1632: checking ipv6 stack type" >&5
        for i in v6d toshiba kame inria zeta linux; do
                case $i in
                v6d)
                        cat > conftest.$ac_ext <<EOF
-#line 1658 "configure"
+#line 1637 "configure"
 #include "confdefs.h"
 dnl
 #include </usr/local/v6/include/sys/types.h>
@@ -1674,7 +1653,7 @@ rm -f conftest*
                        ;;
                toshiba)
                        cat > conftest.$ac_ext <<EOF
-#line 1678 "configure"
+#line 1657 "configure"
 #include "confdefs.h"
 dnl
 #include <sys/param.h>
@@ -1694,7 +1673,7 @@ rm -f conftest*
                        ;;
                kame)
                        cat > conftest.$ac_ext <<EOF
-#line 1698 "configure"
+#line 1677 "configure"
 #include "confdefs.h"
 dnl
 #include <netinet/in.h>
@@ -1714,7 +1693,7 @@ rm -f conftest*
                        ;;
                inria)
                        cat > conftest.$ac_ext <<EOF
-#line 1718 "configure"
+#line 1697 "configure"
 #include "confdefs.h"
 dnl
 #include <netinet/in.h>
@@ -1732,7 +1711,7 @@ rm -f conftest*
                        ;;
                zeta)
                        cat > conftest.$ac_ext <<EOF
-#line 1736 "configure"
+#line 1715 "configure"
 #include "confdefs.h"
 dnl
 #include <sys/param.h>
@@ -1781,12 +1760,12 @@ fi
 
 
 echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-echo "configure:1785: checking for ANSI C header files" >&5
+echo "configure:1764: checking for ANSI C header files" >&5
 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1790 "configure"
+#line 1769 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 #include <stdarg.h>
@@ -1794,7 +1773,7 @@ else
 #include <float.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1798: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1777: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -1811,7 +1790,7 @@ rm -f conftest*
 if test $ac_cv_header_stdc = yes; then
   # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
 cat > conftest.$ac_ext <<EOF
-#line 1815 "configure"
+#line 1794 "configure"
 #include "confdefs.h"
 #include <string.h>
 EOF
@@ -1829,7 +1808,7 @@ fi
 if test $ac_cv_header_stdc = yes; then
   # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
 cat > conftest.$ac_ext <<EOF
-#line 1833 "configure"
+#line 1812 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 EOF
@@ -1850,7 +1829,7 @@ if test "$cross_compiling" = yes; then
   :
 else
   cat > conftest.$ac_ext <<EOF
-#line 1854 "configure"
+#line 1833 "configure"
 #include "confdefs.h"
 #include <ctype.h>
 #define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
@@ -1861,7 +1840,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
 exit (0); }
 
 EOF
-if { (eval echo configure:1865: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:1844: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   :
 else
@@ -1888,17 +1867,17 @@ for ac_hdr in fcntl.h sys/ioctl.h sys/time.h unistd.h stdarg.h
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1892: checking for $ac_hdr" >&5
+echo "configure:1871: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1897 "configure"
+#line 1876 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1902: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1881: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -1929,17 +1908,17 @@ for ac_hdr in sys/sockio.h sys/types.h netinet/in.h
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1933: checking for $ac_hdr" >&5
+echo "configure:1912: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1938 "configure"
+#line 1917 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1943: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1922: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -1979,7 +1958,7 @@ fi
 SNMP_A=''
 SNMP_O=''
 echo $ac_n "checking whether to use SNMP library if available""... $ac_c" 1>&6
-echo "configure:1983: checking whether to use SNMP library if available" >&5
+echo "configure:1962: checking whether to use SNMP library if available" >&5
 if test "x$enable_snmp" = "xno" ; then
        echo "$ac_t""no" 1>&6
 else
@@ -1988,17 +1967,17 @@ else
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1992: checking for $ac_hdr" >&5
+echo "configure:1971: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1997 "configure"
+#line 1976 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2002: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1981: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -2025,7 +2004,7 @@ fi
 done
 
        echo $ac_n "checking for asn_parse_header in -lsnmp""... $ac_c" 1>&6
-echo "configure:2029: checking for asn_parse_header in -lsnmp" >&5
+echo "configure:2008: checking for asn_parse_header in -lsnmp" >&5
 ac_lib_var=`echo snmp'_'asn_parse_header | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -2033,7 +2012,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lsnmp  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 2037 "configure"
+#line 2016 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -2044,7 +2023,7 @@ int main() {
 asn_parse_header()
 ; return 0; }
 EOF
-if { (eval echo configure:2048: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2027: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -2077,12 +2056,12 @@ fi
 # for get_interface_list().
 
 echo $ac_n "checking for sa_len in struct sockaddr""... $ac_c" 1>&6
-echo "configure:2081: checking for sa_len in struct sockaddr" >&5
+echo "configure:2060: checking for sa_len in struct sockaddr" >&5
 if eval "test \"`echo '$''{'ac_cv_ethereal_struct_sa_len'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2086 "configure"
+#line 2065 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/socket.h>
@@ -2090,7 +2069,7 @@ int main() {
 struct sockaddr s; s.sa_len;
 ; return 0; }
 EOF
-if { (eval echo configure:2094: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2073: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_ethereal_struct_sa_len=yes
 else
@@ -2113,14 +2092,14 @@ fi
 
 # We must know our byte order
 echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6
-echo "configure:2117: checking whether byte ordering is bigendian" >&5
+echo "configure:2096: checking whether byte ordering is bigendian" >&5
 if eval "test \"`echo '$''{'ac_cv_c_bigendian'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_cv_c_bigendian=unknown
 # See if sys/param.h defines the BYTE_ORDER macro.
 cat > conftest.$ac_ext <<EOF
-#line 2124 "configure"
+#line 2103 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/param.h>
@@ -2131,11 +2110,11 @@ int main() {
 #endif
 ; return 0; }
 EOF
-if { (eval echo configure:2135: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2114: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   # It does; now see whether it defined to BIG_ENDIAN or not.
 cat > conftest.$ac_ext <<EOF
-#line 2139 "configure"
+#line 2118 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/param.h>
@@ -2146,7 +2125,7 @@ int main() {
 #endif
 ; return 0; }
 EOF
-if { (eval echo configure:2150: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2129: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_bigendian=yes
 else
@@ -2166,7 +2145,7 @@ if test "$cross_compiling" = yes; then
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
   cat > conftest.$ac_ext <<EOF
-#line 2170 "configure"
+#line 2149 "configure"
 #include "confdefs.h"
 main () {
   /* Are we little or big endian?  From Harbison&Steele.  */
@@ -2179,7 +2158,7 @@ main () {
   exit (u.c[sizeof (long) - 1] == 1);
 }
 EOF
-if { (eval echo configure:2183: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2162: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_c_bigendian=no
 else
@@ -2205,13 +2184,13 @@ fi
 
 if test $ac_cv_prog_gcc = yes; then
     echo $ac_n "checking whether ${CC-cc} needs -traditional""... $ac_c" 1>&6
-echo "configure:2209: checking whether ${CC-cc} needs -traditional" >&5
+echo "configure:2188: checking whether ${CC-cc} needs -traditional" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_gcc_traditional'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
     ac_pattern="Autoconf.*'x'"
   cat > conftest.$ac_ext <<EOF
-#line 2215 "configure"
+#line 2194 "configure"
 #include "confdefs.h"
 #include <sgtty.h>
 Autoconf TIOCGETP
@@ -2229,7 +2208,7 @@ rm -f conftest*
 
   if test $ac_cv_prog_gcc_traditional = no; then
     cat > conftest.$ac_ext <<EOF
-#line 2233 "configure"
+#line 2212 "configure"
 #include "confdefs.h"
 #include <termio.h>
 Autoconf TCGETA
@@ -2251,12 +2230,12 @@ echo "$ac_t""$ac_cv_prog_gcc_traditional" 1>&6
 fi
 
 echo $ac_n "checking for socket""... $ac_c" 1>&6
-echo "configure:2255: checking for socket" >&5
+echo "configure:2234: checking for socket" >&5
 if eval "test \"`echo '$''{'ac_cv_func_socket'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2260 "configure"
+#line 2239 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char socket(); below.  */
@@ -2279,7 +2258,7 @@ socket();
 
 ; return 0; }
 EOF
-if { (eval echo configure:2283: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2262: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_socket=yes"
 else
@@ -2305,12 +2284,12 @@ fi
 SNPRINTF_C=""
 SNPRINTF_O=""
 echo $ac_n "checking for snprintf""... $ac_c" 1>&6
-echo "configure:2309: checking for snprintf" >&5
+echo "configure:2288: checking for snprintf" >&5
 if eval "test \"`echo '$''{'ac_cv_func_snprintf'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2314 "configure"
+#line 2293 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char snprintf(); below.  */
@@ -2333,7 +2312,7 @@ snprintf();
 
 ; return 0; }
 EOF
-if { (eval echo configure:2337: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2316: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_snprintf=yes"
 else
index dcd9357dc9f432c86f32e21b6b1315bd9778f5da..050d3082cb54ff0c9565032fbdc6bcb739a8cdf3 100644 (file)
@@ -362,6 +362,10 @@ B<http://ethereal.zing.org>.
   Jun-ichiro itojun Hagino <itojun@iijlab.net>
   Richard Sharpe           <sharpe@ns.aus.com>
   John McDermott           <jjm@jkintl.com> 
+  Jeff Jahr                <jjahr@shastanets.com>
+  Brad Robel-Forrest       <bradr@watchguard.com>
+
+Brad Robel-Forrest <bradr@watchguard.com> {
 
 Alain Magloire <alainm@rcsm.ece.mcgill.ca> was kind enough to give his
 permission to use his version of snprintf.c.
index 1c2efe3bab63fe517a7af700778204ccbe85899b..be24d81eabfc2353c5073652c35644a2460446b1 100644 (file)
@@ -1,6 +1,6 @@
 /* ethereal.c
  *
- * $Id: ethereal.c,v 1.34 1999/05/12 06:04:46 gram Exp $
+ * $Id: ethereal.c,v 1.35 1999/06/11 15:30:36 gram Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -132,6 +132,8 @@ about_ethereal( GtkWidget *w, gpointer data ) {
                "Jun-ichiro itojun Hagino <itojun@iijlab.net>\n"
                "Richard Sharpe           <sharpe@ns.aus.com>\n"
                "John McDermott           <jjm@jkintl.com>\n"
+               "Jeff Jahr                <jjahr@shastanets.com>\n"
+               "Brad Robel-Forrest       <bradr@watchguard.com>\n"
 
                "\nSee http://ethereal.zing.org for more information",
                 VERSION, comp_info_str);
index a3772fec9cb5ffe5731df848e74e28c1d86889be..952723e7291aab13901f09bdda9b98e9987eaec6 100644 (file)
@@ -2,7 +2,7 @@
  * Routines for calling the right protocol for the ethertype.
  * This is called by both packet-eth.c (Ethernet II) and packet-llc.c (SNAP)
  *
- * $Id: ethertype.c,v 1.13 1999/03/23 03:14:34 gram Exp $
+ * $Id: ethertype.c,v 1.14 1999/06/11 15:30:37 gram Exp $
  *
  * Gilbert Ramirez <gram@verdict.uthscsa.edu>
  *
@@ -52,6 +52,8 @@ ethertype_to_str(guint16 etype, const char *fmt)
     {ETHERTYPE_VINES,  "Vines"          },
     {ETHERTYPE_CDP,    "CDP"            }, /* Cisco Discovery Protocol */
     {ETHERTYPE_LOOP,   "Loopback"       }, /* Ethernet Loopback */
+               {ETHERTYPE_PPPOED, "PPPoE Discovery"}, 
+               {ETHERTYPE_PPPOES, "PPPoE Session"  }, 
     {0,                 NULL            } };
 
     return val_to_str(etype, etype_vals, fmt);
@@ -112,6 +114,12 @@ ethertype(guint16 etype, int offset,
       dissect_data(pd, offset, fd, tree);
       if (check_col(fd, COL_PROTOCOL)) { col_add_fstr(fd, COL_PROTOCOL, "LOOP"); }
       break;
+               case ETHERTYPE_PPPOED:
+                       dissect_pppoed(pd, offset, fd, tree);
+                       break;
+               case ETHERTYPE_PPPOES:
+                       dissect_pppoes(pd, offset, fd, tree);
+                       break;
     default:
       dissect_data(pd, offset, fd, tree);
       if (check_col(fd, COL_PROTOCOL)) { col_add_fstr(fd, COL_PROTOCOL, "0x%04x", etype); }
index e5d2ff48dd6cef1bf90c673465d7999c189f779b..3447b5305ece88904cfcd4985b59a783af90f0ab 100644 (file)
--- a/etypes.h
+++ b/etypes.h
@@ -1,7 +1,7 @@
 /* etypes.h
  * Defines ethernet packet types, similar to tcpdump's ethertype.h
  *
- * $Id: etypes.h,v 1.4 1998/12/19 00:12:20 hannes Exp $
+ * $Id: etypes.h,v 1.5 1999/06/11 15:30:37 gram Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
 #define ETHERTYPE_LOOP 0x9000  /* used for layer 2 testing (do i see my own frames on the wire) */
 #endif
 
+#ifndef ETHERTYPE_PPPOED
+#define ETHERTYPE_PPPOED 0x8863 /* PPPoE Discovery Protocol */
+#endif
+
+#ifndef ETHERTYPE_PPPOES
+#define ETHERTYPE_PPPOES 0x8864 /* PPPoE Session Protocol */
+#endif
+
+
 #endif /* etypes.h */
diff --git a/packet-gre.c b/packet-gre.c
new file mode 100644 (file)
index 0000000..c03d8dd
--- /dev/null
@@ -0,0 +1,237 @@
+/* packet-gre.c
+ * Routines for the Generic Routing Encapsulation (GRE) protocol
+ * Brad Robel-Forrest <brad.robel-forrest@watchguard.com>
+ *
+ * $Id: packet-gre.c,v 1.1 1999/06/11 15:30:37 gram Exp $
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@unicom.net>
+ * 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
+
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#include <netinet/in.h>
+#include <glib.h>
+#include "packet.h"
+
+/* bit positions for flags in header */
+#define GH_B_C         0x8000
+#define GH_B_R         0x4000
+#define GH_B_K         0x2000
+#define GH_B_S         0x1000
+#define GH_B_s         0x0800
+#define GH_B_RECUR     0x0700
+#define GH_P_A         0x0080  /* only in special PPTPized GRE header */
+#define GH_P_FLAGS     0x0078  /* only in special PPTPized GRE header */
+#define GH_R_FLAGS     0x00F8
+#define GH_B_VER       0x0007
+
+#define GRE_PPP                0x880B
+
+static int calc_len(guint16, int);
+static void add_flags_and_ver(proto_tree *, guint16, int, int);
+
+void
+dissect_gre(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
+  
+  guint16      flags_and_ver = pntohs(pd + offset);
+  guint16      type          = pntohs(pd + offset + sizeof(flags_and_ver));
+  static const value_string typevals[] = {
+    { GRE_PPP, "PPP" },
+    { 0,       NULL  }
+  };
+
+  if (check_col(fd, COL_PROTOCOL))
+    col_add_str(fd, COL_PROTOCOL, "GRE");
+       
+  if (check_col(fd, COL_INFO)) {
+    if (type == GRE_PPP)
+      col_add_str(fd, COL_INFO, "Encapsulated PPP");
+    else
+      col_add_str(fd, COL_INFO, "Encapsulated unknown");
+  }
+               
+  if (fd->cap_len > offset && tree) {
+    int                        is_ppp;
+    proto_item *       ti;
+    proto_tree *       gre_tree;
+
+    if (type == GRE_PPP) {
+      is_ppp = 1;
+      ti = proto_tree_add_item(tree, offset, calc_len(flags_and_ver, 1),
+       "Generic Routing Encapsulation (PPP)");
+      gre_tree = proto_tree_new();
+      proto_item_add_subtree(ti, gre_tree, ETT_GRE);
+      add_flags_and_ver(gre_tree, flags_and_ver, offset, 1);
+    }
+    else {
+      is_ppp = 0;
+      ti = proto_tree_add_item(tree, offset, calc_len(flags_and_ver, 1),
+       "Generic Routing Encapsulation");
+      gre_tree = proto_tree_new();
+      proto_item_add_subtree(ti, gre_tree, ETT_GRE);
+      add_flags_and_ver(gre_tree, flags_and_ver, offset, 0);
+    }
+
+    offset += sizeof(flags_and_ver);
+
+    proto_tree_add_item(gre_tree, offset, sizeof(type),
+                       "Protocol Type: %s (%#04x)",
+                       val_to_str(type, typevals, "Unknown"), type);
+    offset += sizeof(type);    
+
+    if (flags_and_ver & GH_B_C || flags_and_ver & GH_B_R) {
+      guint16 checksum = pntohs(pd + offset);
+      proto_tree_add_item(gre_tree, offset, sizeof(checksum),
+                         "Checksum: %u", checksum);
+      offset += sizeof(checksum);
+    }
+    
+    if (flags_and_ver & GH_B_C || flags_and_ver & GH_B_R) {
+      guint16 rtoffset = pntohs(pd + offset);
+      proto_tree_add_item(gre_tree, offset, sizeof(rtoffset),
+                         "Offset: %u", rtoffset);
+      offset += sizeof(rtoffset);
+    }
+
+    if (flags_and_ver & GH_B_K) {
+      if (is_ppp) {
+       guint16 paylen;
+       guint16 callid;
+       
+       paylen = pntohs(pd + offset);
+       proto_tree_add_item(gre_tree, offset, sizeof(paylen),
+                           "Payload length: %u", paylen);
+       offset += sizeof(paylen);
+
+       callid = pntohs(pd + offset);
+       proto_tree_add_item(gre_tree, offset, sizeof(callid),
+                           "Call ID: %u", callid);
+       offset += sizeof(callid);
+      }
+      else {
+       guint32 key = pntohl(pd + offset);
+       proto_tree_add_item(gre_tree, offset, sizeof(key),
+                           "Key: %u", key);
+       offset += sizeof(key);
+      }
+    }
+    
+    if (flags_and_ver & GH_B_S) {
+      guint32 seqnum = pntohl(pd + offset);
+      proto_tree_add_item(gre_tree, offset, sizeof(seqnum),
+                         "Sequence number: %u", seqnum);
+      offset += sizeof(seqnum);
+    }
+
+    if (is_ppp && flags_and_ver & GH_P_A) {
+      guint32 acknum = pntohl(pd + offset);
+      proto_tree_add_item(gre_tree, offset, sizeof(acknum),
+                         "Acknowledgement number: %u", acknum);
+      offset += sizeof(acknum);
+    }
+
+    if (flags_and_ver & GH_B_R) {
+      proto_tree_add_item(gre_tree, offset, sizeof(guint16),
+                         "Address family: %u", pntohs(pd + offset));
+      offset += sizeof(guint16);
+      proto_tree_add_item(gre_tree, offset, 1,
+                         "SRE offset: %u", pd[offset++]);
+      proto_tree_add_item(gre_tree, offset, 1,
+                         "SRE length: %u", pd[offset++]);
+    }
+
+    switch (type) {
+       case GRE_PPP:
+       dissect_payload_ppp(pd, offset, fd, tree);
+       break;
+      default:
+       dissect_data(pd, offset, fd, gre_tree);
+    }
+  }
+}
+
+static int
+calc_len(guint16 flags_and_ver, int is_ppp) {
+  
+  int  len = 4;
+  
+  if (flags_and_ver & GH_B_C || flags_and_ver & GH_B_R) len += 4;
+  if (flags_and_ver & GH_B_K) len += 4;
+  if (flags_and_ver & GH_B_S) len += 4;
+  if (is_ppp && flags_and_ver & GH_P_A) len += 4;
+  
+  return len;
+}
+
+static void
+add_flags_and_ver(proto_tree *tree, guint16 flags_and_ver, int offset, int is_ppp) {
+
+  proto_item * ti;
+  proto_tree * fv_tree;
+  int          nbits = sizeof(flags_and_ver) * 8;
+  
+  ti = proto_tree_add_item(tree, offset, 2, 
+                          "Flags and version: %#08x", flags_and_ver);
+  fv_tree = proto_tree_new();
+  proto_item_add_subtree(ti, fv_tree, ETT_GRE_FLAGS);
+  
+  proto_tree_add_item(fv_tree, offset, sizeof(flags_and_ver), "%s",
+                     decode_boolean_bitfield(flags_and_ver, GH_B_C, nbits,
+                                             "Checksum", "No checksum"));
+  proto_tree_add_item(fv_tree, offset, sizeof(flags_and_ver), "%s",
+                     decode_boolean_bitfield(flags_and_ver, GH_B_R, nbits,
+                                             "Routing", "No routing"));
+  proto_tree_add_item(fv_tree, offset, sizeof(flags_and_ver), "%s",
+                     decode_boolean_bitfield(flags_and_ver, GH_B_K, nbits,
+                                             "Key", "No key"));
+  proto_tree_add_item(fv_tree, offset, sizeof(flags_and_ver), "%s",
+                     decode_boolean_bitfield(flags_and_ver, GH_B_S, nbits,
+                                             "Sequence number", "No sequence number"));
+  proto_tree_add_item(fv_tree, offset, sizeof(flags_and_ver), "%s",
+                     decode_boolean_bitfield(flags_and_ver, GH_B_s, nbits,
+                                             "Strict source route", "No strict source route"));
+  proto_tree_add_item(fv_tree, offset, sizeof(flags_and_ver), "%s",
+                     decode_numeric_bitfield(flags_and_ver, GH_B_RECUR, nbits,
+                                             "Recursion control: %u"));
+  if (is_ppp) {
+    proto_tree_add_item(fv_tree, offset, sizeof(flags_and_ver), "%s",
+                       decode_boolean_bitfield(flags_and_ver, GH_P_A, nbits,
+                                               "Acknowledgment number", "No acknowledgment number"));
+    proto_tree_add_item(fv_tree, offset, sizeof(flags_and_ver), "%s",
+                       decode_numeric_bitfield(flags_and_ver, GH_P_FLAGS, nbits,
+                                               "Flags: %u"));
+  }
+  else {
+    proto_tree_add_item(fv_tree, offset, sizeof(flags_and_ver), "%s",
+                       decode_numeric_bitfield(flags_and_ver, GH_R_FLAGS, nbits,
+                                               "Flags: %u"));
+  }
+
+  proto_tree_add_item(fv_tree, offset, sizeof(flags_and_ver), "%s",
+                     decode_numeric_bitfield(flags_and_ver, GH_B_VER, nbits,
+                                             "Version: %u"));
+ }
index 3ded99b78e4db8a1059c779e969e5fe0ae96dd00..d1384f35b0a9da7d6a6b9c779abf34f99d3c05c1 100644 (file)
@@ -1,7 +1,7 @@
 /* packet-ip.c
  * Routines for IP and miscellaneous IP protocol packet disassembly
  *
- * $Id: packet-ip.c,v 1.23 1999/05/20 02:41:22 guy Exp $
+ * $Id: packet-ip.c,v 1.24 1999/06/11 15:30:37 gram Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -203,6 +203,9 @@ capture_ip(const u_char *pd, int offset, guint32 cap_len, packet_counts *ld) {
     case IP_PROTO_OSPF:
       ld->ospf++;
       break;
+    case IP_PROTO_GRE:
+      ld->gre++;
+      break;
     default:
       ld->other++;
   }
@@ -586,6 +589,7 @@ dissect_ip(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
     case IP_PROTO_TCP:
     case IP_PROTO_UDP:
     case IP_PROTO_OSPF:
+    case IP_PROTO_GRE:
     case IP_PROTO_ESP:
     case IP_PROTO_AH:
     case IP_PROTO_IPV6:
@@ -741,6 +745,9 @@ again:
       nxt = pd[offset];
       offset += advance;
       goto again;
+    case IP_PROTO_GRE:
+      dissect_gre(pd, offset, fd, tree);
+      break;
     case IP_PROTO_ESP:
       dissect_esp(pd, offset, fd, tree);
       break;
index a05bfac0d096e76962f62e045d2644c38f7f7e68..ab7ccdf76c070de55b9280cfe949d345b3a8c0ca 100644 (file)
@@ -1,7 +1,7 @@
 /* packet-ip.h
  * Definitions for IP packet disassembly structures and routines
  *
- * $Id: packet-ip.h,v 1.2 1999/03/28 18:31:59 gram Exp $
+ * $Id: packet-ip.h,v 1.3 1999/06/11 15:30:38 gram Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -49,6 +49,7 @@
 #define IP_PROTO_IPV6          41              /* IP6 header */
 #define IP_PROTO_ROUTING       43              /* IP6 routing header */
 #define IP_PROTO_FRAGMENT      44              /* IP6 fragmentation header */
+#define IP_PROTO_GRE           47              /* GRE */
 #define IP_PROTO_ESP           50              /* ESP */
 #define IP_PROTO_AH            51              /* AH */
 #define IP_PROTO_ICMPV6                58              /* ICMP6 */
diff --git a/packet-isakmp.c b/packet-isakmp.c
new file mode 100644 (file)
index 0000000..b2d5a8a
--- /dev/null
@@ -0,0 +1,1040 @@
+/* packet-gre.c
+ * Routines for the Internet Security Association and Key Management Protocol (ISAKMP)
+ * Brad Robel-Forrest <brad.robel-forrest@watchguard.com>
+ *
+ * $Id: packet-isakmp.c,v 1.1 1999/06/11 15:30:38 gram Exp $
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@unicom.net>
+ * 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
+
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#include <stdio.h>
+#include <netinet/in.h>
+#include <glib.h>
+#include "packet.h"
+
+#define NUM_PROTO_TYPES        5
+#define proto2str(t)   \
+  ((t < NUM_PROTO_TYPES) ? prototypestr[t] : "UNKNOWN-PROTO-TYPE")
+
+static const char *prototypestr[NUM_PROTO_TYPES] = {
+  "RESERVED",
+  "ISAKMP",
+  "IPSEC_AH",
+  "IPSEC_ESP",
+  "IPCOMP"
+};
+
+#define NUM_ATT_TYPES  13
+#define atttype2str(t) \
+  ((t < NUM_ATT_TYPES) ? atttypestr[t] : "UNKNOWN-ATTRIBUTE-TYPE")
+
+static const char *atttypestr[NUM_ATT_TYPES] = {
+  "UNKNOWN-ATTRIBUTE-TYPE",
+  "SA-Life-Type",
+  "SA-Life-Duration",
+  "Group-Description",
+  "Encapsulation-Mode",
+  "Authentication-Algorithm",
+  "Key-Length",
+  "Key-Rounds",
+  "Compress-Dictinary-Size",
+  "Compress-Private-Algorithm"
+  "UNKNOWN-ATTRIBUTE-TYPE",
+  "Oakley-Life",
+  "Oakley-Value",
+  "Oakley-Life-Duration"
+};
+
+#define NUM_TRANS_TYPES        2
+#define trans2str(t)   \
+  ((t < NUM_TRANS_TYPES) ? transtypestr[t] : "UNKNOWN-TRANS-TYPE")
+
+static const char *transtypestr[NUM_TRANS_TYPES] = {
+  "RESERVED",
+  "KEY_IKE"
+};
+
+#define NUM_ID_TYPES   12
+#define id2str(t)      \
+  ((t < NUM_ID_TYPES) ? idtypestr[t] : "UNKNOWN-ID-TYPE")
+
+static const char *idtypestr[NUM_ID_TYPES] = {
+  "RESERVED",
+  "IPV4_ADDR",
+  "FQDN",
+  "USER_FQDN",
+  "IPV4_ADDR_SUBNET",
+  "IPV6_ADDR",
+  "IPV6_ADDR_SUBNET",
+  "IPV4_ADDR_RANGE",
+  "IPV6_ADDR_RANGE",
+  "DER_ASN1_DN",
+  "DER_ASN1_GN",
+  "KEY_ID"
+};
+
+struct isakmp_hdr {
+  guint8       icookie[8];
+  guint8       rcookie[8];
+  guint8       next_payload;
+  guint8       version;
+  guint8       exch_type;
+  guint8       flags;
+#define E_FLAG         0x01
+#define C_FLAG         0x02
+#define A_FLAG         0x04
+  guint32      message_id;
+  guint32      length;
+};
+
+struct sa_hdr {
+  guint8       next_payload;
+  guint8       reserved;
+  guint16      length;
+  guint32      doi;
+  guint32      situation;
+};
+
+struct proposal_hdr {
+  guint8       next_payload;
+  guint8       reserved;
+  guint16      length;
+  guint8       proposal_num;
+  guint8       protocol_id;
+  guint8       spi_size;
+  guint8       num_transforms;
+};
+
+struct trans_hdr {
+  guint8       next_payload;
+  guint8       reserved;
+  guint16      length;
+  guint8       transform_num;
+  guint8       transform_id;
+  guint16      reserved2;
+};
+
+#define TRANS_LEN(p)   (pntohs(&((struct trans_hdr *)(p))->length))
+
+struct ke_hdr {
+  guint8       next_payload;
+  guint8       reserved;
+  guint16      length;
+};
+
+struct id_hdr {
+  guint8       next_payload;
+  guint8       reserved;
+  guint16      length;
+  guint8       id_type;
+  guint8       protocol_id;
+  guint16      port;
+};
+
+struct cert_hdr {
+  guint8       next_payload;
+  guint8       reserved;
+  guint16      length;
+  guint8       cert_enc;
+};
+
+struct certreq_hdr {
+  guint8       next_payload;
+  guint8       reserved;
+  guint16      length;
+  guint8       cert_type;
+};
+
+struct hash_hdr {
+  guint8       next_payload;
+  guint8       reserved;
+  guint16      length;
+};
+
+struct sig_hdr {
+  guint8       next_payload;
+  guint8       reserved;
+  guint16      length;
+};
+
+struct nonce_hdr {
+  guint8       next_payload;
+  guint8       reserved;
+  guint16      length;
+};
+
+struct notif_hdr {
+  guint8       next_payload;
+  guint8       reserved;
+  guint16      length;
+  guint32      doi;
+  guint8       protocol_id;
+  guint8       spi_size;
+  guint16      msgtype;
+};
+
+struct delete_hdr {
+  guint8       next_payload;
+  guint8       reserved;
+  guint16      length;
+  guint32      doi;
+  guint8       protocol_id;
+  guint8       spi_size;
+  guint16      num_spis;
+};
+
+struct vid_hdr {
+  guint8       next_payload;
+  guint8       reserved;
+  guint16      length;
+};
+
+static void dissect_none(const u_char *, int, frame_data *, proto_tree *);
+static void dissect_sa(const u_char *, int, frame_data *, proto_tree *);
+static void dissect_proposal(const u_char *, int, frame_data *, proto_tree *);
+static void dissect_transform(const u_char *, int, frame_data *, proto_tree *);
+static void dissect_key_exch(const u_char *, int, frame_data *, proto_tree *);
+static void dissect_id(const u_char *, int, frame_data *, proto_tree *);
+static void dissect_cert(const u_char *, int, frame_data *, proto_tree *);
+static void dissect_certreq(const u_char *, int, frame_data *, proto_tree *);
+static void dissect_hash(const u_char *, int, frame_data *, proto_tree *);
+static void dissect_sig(const u_char *, int, frame_data *, proto_tree *);
+static void dissect_nonce(const u_char *, int, frame_data *, proto_tree *);
+static void dissect_notif(const u_char *, int, frame_data *, proto_tree *);
+static void dissect_delete(const u_char *, int, frame_data *, proto_tree *);
+static void dissect_vid(const u_char *, int, frame_data *, proto_tree *);
+
+static const char *payloadtype2str(guint8);
+static const char *exchtype2str(guint8);
+static const char *doitype2str(guint32);
+static const char *msgtype2str(guint16);
+static const char *situation2str(guint32);
+static const char *value2str(guint16, guint16);
+static const char *num2str(const guint8 *, guint16);
+
+#define NUM_LOAD_TYPES         14
+#define loadtype2str(t)        \
+  ((t < NUM_LOAD_TYPES) ? strfuncs[t].str : "Unknown payload type")
+
+static struct strfunc {
+  const char * str;
+  void          (*func)(const u_char *, int, frame_data *, proto_tree *);
+} strfuncs[NUM_LOAD_TYPES] = {
+  {"NONE",                     dissect_none      },
+  {"Security Association",     dissect_sa        },
+  {"Proposal",                 dissect_proposal  },
+  {"Transform",                        dissect_transform },
+  {"Key Exchange",             dissect_key_exch  },
+  {"Identification",           dissect_id        },
+  {"Certificate",              dissect_cert      },
+  {"Certificate Request",      dissect_certreq   },
+  {"Hash",                     dissect_hash      },
+  {"Signature",                        dissect_sig       },
+  {"Nonce",                    dissect_nonce     },
+  {"Notification",             dissect_notif     },
+  {"Delete",                   dissect_delete    },
+  {"Vendor ID",                        dissect_vid       }
+};
+
+void dissect_isakmp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
+  
+  struct isakmp_hdr *  hdr = (struct isakmp_hdr *)(pd + offset);
+  guint32              len;
+  
+  if (check_col(fd, COL_PROTOCOL))
+    col_add_str(fd, COL_PROTOCOL, "ISAKMP");
+  
+  len = pntohl(&hdr->length);
+  
+  if (check_col(fd, COL_INFO))
+    col_add_fstr(fd, COL_INFO, "%s", exchtype2str(hdr->exch_type));
+  
+  if (fd->cap_len > offset && tree) {
+    proto_item *       ti;
+    proto_tree *       isakmp_tree;
+    
+    ti = proto_tree_add_item(tree, offset, len,
+                            "Internet Security Association and Key Management Protocol");
+    isakmp_tree = proto_tree_new();
+    proto_item_add_subtree(ti, isakmp_tree, ETT_ISAKMP);
+    
+    proto_tree_add_item(isakmp_tree, offset, sizeof(hdr->icookie),
+                       "Initiator cookie");
+    offset += sizeof(hdr->icookie);
+    
+    proto_tree_add_item(isakmp_tree, offset, sizeof(hdr->rcookie),
+                       "Responder cookie");
+    offset += sizeof(hdr->rcookie);
+
+    proto_tree_add_item(isakmp_tree, offset, sizeof(hdr->next_payload),
+                       "Next payload: %s (%u)",
+                       payloadtype2str(hdr->next_payload), hdr->next_payload);
+    offset += sizeof(hdr->next_payload);
+
+    proto_tree_add_item(isakmp_tree, offset, sizeof(hdr->version),
+                       "Version: %u.%u",
+                       hi_nibble(hdr->version), lo_nibble(hdr->version));
+    offset += sizeof(hdr->version);
+    
+    proto_tree_add_item(isakmp_tree, offset, sizeof(hdr->exch_type),
+                       "Exchange type: %s (%u)",
+                       exchtype2str(hdr->exch_type), hdr->exch_type);
+    offset += sizeof(hdr->exch_type);
+    
+    {
+      proto_item *     fti;
+      proto_tree *     ftree;
+      
+      fti   = proto_tree_add_item(isakmp_tree, offset, sizeof(hdr->flags), "Flags");
+      ftree = proto_tree_new();
+      proto_item_add_subtree(fti, ftree, ETT_ISAKMP_FLAGS);
+      
+      proto_tree_add_item(ftree, offset, 1, "%s",
+                         decode_boolean_bitfield(hdr->flags, E_FLAG, sizeof(hdr->flags)*8,
+                                                 "Encryption", "No encryption"));
+      proto_tree_add_item(ftree, offset, 1, "%s",
+                         decode_boolean_bitfield(hdr->flags, C_FLAG, sizeof(hdr->flags)*8,
+                                                 "Commit", "No commit"));
+      proto_tree_add_item(ftree, offset, 1, "%s",
+                         decode_boolean_bitfield(hdr->flags, A_FLAG, sizeof(hdr->flags)*8,
+                                                 "Authentication", "No authentication"));
+      offset += sizeof(hdr->flags);
+    }
+
+    proto_tree_add_item(isakmp_tree, offset, sizeof(hdr->message_id), "Message ID");
+    offset += sizeof(hdr->message_id);
+    
+    proto_tree_add_item(isakmp_tree, offset, sizeof(hdr->length),
+                       "Length: %u", len);
+    offset += sizeof(hdr->length);
+
+    if (hdr->next_payload < NUM_LOAD_TYPES)
+      (*strfuncs[hdr->next_payload].func)(pd, offset, fd, isakmp_tree);
+    else
+      dissect_data(pd, offset, fd, isakmp_tree);
+  }
+}
+
+static void
+dissect_none(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
+}
+
+static void
+dissect_sa(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
+
+  struct sa_hdr *      hdr       = (struct sa_hdr *)(pd + offset);
+  guint16              length    = pntohs(&hdr->length);
+  guint32              doi       = pntohl(&hdr->doi);
+  guint32              situation = pntohl(&hdr->situation);
+  proto_item *         ti        = proto_tree_add_item(tree, offset, length, "Security Association payload");
+  proto_tree *         ntree     = proto_tree_new();
+
+  proto_item_add_subtree(ti, ntree, ETT_ISAKMP_PAYLOAD);
+  
+  proto_tree_add_item(ntree, offset, sizeof(hdr->next_payload),
+                     "Next payload: %s (%u)",
+                     payloadtype2str(hdr->next_payload), hdr->next_payload);
+  offset += sizeof(hdr->next_payload) * 2;
+  
+  proto_tree_add_item(ntree, offset, sizeof(length),
+                     "Length: %u", length);
+  offset += sizeof(length);
+  
+  proto_tree_add_item(ntree, offset, sizeof(doi),
+                     "Domain of interpretation: %s (%u)",
+                     doitype2str(doi), doi);
+  offset += sizeof(doi);
+  
+  proto_tree_add_item(ntree, offset, sizeof(situation),
+                     "Situation: %s (%u)",
+                     situation2str(situation), situation);
+  offset += sizeof(situation);
+  
+  dissect_proposal(pd, offset, fd, ntree);
+  offset += (length - sizeof(*hdr));
+  
+  if (hdr->next_payload < NUM_LOAD_TYPES)
+    (*strfuncs[hdr->next_payload].func)(pd, offset, fd, tree);
+  else
+    dissect_data(pd, offset, fd, tree);
+}
+
+static void
+dissect_proposal(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
+
+  struct proposal_hdr *        hdr     = (struct proposal_hdr *)(pd + offset);
+  guint16              length  = pntohs(&hdr->length);
+  proto_item *         ti      = proto_tree_add_item(tree, offset, length, "Proposal payload");
+  proto_tree *         ntree   = proto_tree_new();
+  guint8               i;
+  
+  proto_item_add_subtree(ti, ntree, ETT_ISAKMP_PAYLOAD);
+  
+  proto_tree_add_item(ntree, offset, sizeof(hdr->next_payload),
+                     "Next payload: %s (%u)",
+                     payloadtype2str(hdr->next_payload), hdr->next_payload);
+  offset += sizeof(hdr->next_payload) * 2;
+  
+  proto_tree_add_item(ntree, offset, sizeof(length),
+                     "Length: %u", length);
+  offset += sizeof(length);
+  
+  proto_tree_add_item(ntree, offset, sizeof(hdr->proposal_num),
+                     "Proposal number: %u", hdr->proposal_num);
+  offset += sizeof(hdr->proposal_num);
+  
+  proto_tree_add_item(ntree, offset, sizeof(hdr->protocol_id),
+                     "Protocol ID: %s (%u)",
+                     proto2str(hdr->protocol_id), hdr->protocol_id);
+  offset += sizeof(hdr->protocol_id);
+  
+  proto_tree_add_item(ntree, offset, sizeof(hdr->spi_size),
+                     "SPI size: %u", hdr->spi_size);
+  offset += sizeof(hdr->spi_size);
+  
+  if (hdr->spi_size) {
+    proto_tree_add_item(ntree, offset, hdr->spi_size, "SPI");
+    offset += hdr->spi_size;
+  }
+
+  proto_tree_add_item(ntree, offset, sizeof(hdr->num_transforms),
+                     "Number of transforms: %u", hdr->num_transforms);
+  offset += sizeof(hdr->num_transforms);
+  
+  for (i = 0; i < hdr->num_transforms; ++i) {
+    dissect_transform(pd, offset, fd, ntree);
+    offset += TRANS_LEN(pd+offset);
+  }
+
+  if (hdr->next_payload < NUM_LOAD_TYPES)
+    (*strfuncs[hdr->next_payload].func)(pd, offset, fd, tree);
+  else
+    dissect_data(pd, offset, fd, tree);
+}
+
+static void
+dissect_transform(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
+
+  struct trans_hdr *   hdr     = (struct trans_hdr *)(pd + offset);
+  guint16              length  = pntohs(&hdr->length);
+  proto_item *         ti      = proto_tree_add_item(tree, offset, length, "Transform payload");
+  proto_tree *         ntree   = proto_tree_new();
+
+  proto_item_add_subtree(ti, ntree, ETT_ISAKMP_PAYLOAD);
+  
+  proto_tree_add_item(ntree, offset, sizeof(hdr->next_payload),
+                     "Next payload: %s (%u)",
+                     payloadtype2str(hdr->next_payload), hdr->next_payload);
+  offset += sizeof(hdr->next_payload) * 2;
+  
+  proto_tree_add_item(ntree, offset, sizeof(length),
+                     "Length: %u", length);
+  offset += sizeof(length);
+  
+  proto_tree_add_item(ntree, offset, sizeof(hdr->transform_num),
+                     "Transform number: %u", hdr->transform_num);
+  offset += sizeof(hdr->transform_num);
+  
+  proto_tree_add_item(ntree, offset, sizeof(hdr->transform_id),
+                     "Transform ID: %s (%u)",
+                     trans2str(hdr->transform_id), hdr->transform_id);
+  offset += sizeof(hdr->transform_id) + sizeof(hdr->reserved2);
+  
+  length -= sizeof(*hdr);
+  while (length) {
+    guint16 type    = pntohs(pd + offset) & 0x7fff;
+    guint16 val_len = pntohs(pd + offset + 2);
+    
+    if (pd[offset] & 0xf0) {
+      proto_tree_add_item(ntree, offset, 4,
+                         "%s (%u): %s (%u)",
+                         atttype2str(type), type,
+                         value2str(type, val_len), val_len);
+      offset += 4;
+      length -= 4;
+    }
+    else {
+      guint16  pack_len = 4 + val_len;
+      
+      proto_tree_add_item(ntree, offset, pack_len,
+                         "%s (%u): %s",
+                         atttype2str(type), type,
+                         num2str(pd + offset + 4, val_len));
+      offset += pack_len;
+      length -= pack_len;
+    }
+  }
+
+  if (hdr->next_payload < NUM_LOAD_TYPES)
+    (*strfuncs[hdr->next_payload].func)(pd, offset, fd, tree);
+  else
+    dissect_data(pd, offset, fd, tree);
+}
+
+static void
+dissect_key_exch(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
+
+  struct ke_hdr *      hdr     = (struct ke_hdr *)(pd + offset);
+  guint16              length  = pntohs(&hdr->length);
+  proto_item *         ti      = proto_tree_add_item(tree, offset, length, "Key Exchange payload");
+  proto_tree *         ntree   = proto_tree_new();
+
+  proto_item_add_subtree(ti, ntree, ETT_ISAKMP_PAYLOAD);
+  
+  proto_tree_add_item(ntree, offset, sizeof(hdr->next_payload),
+                     "Next payload: %s (%u)",
+                     payloadtype2str(hdr->next_payload), hdr->next_payload);
+  offset += sizeof(hdr->next_payload) * 2;
+  
+  proto_tree_add_item(ntree, offset, sizeof(length),
+                     "Length: %u", length);
+  offset += sizeof(length);
+  
+  proto_tree_add_item(ntree, offset, length - sizeof(*hdr), "Key Exchange Data");
+  offset += (length - sizeof(*hdr));
+  
+  if (hdr->next_payload < NUM_LOAD_TYPES)
+    (*strfuncs[hdr->next_payload].func)(pd, offset, fd, tree);
+  else
+    dissect_data(pd, offset, fd, tree);
+}
+
+static void
+dissect_id(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
+
+  struct id_hdr *      hdr     = (struct id_hdr *)(pd + offset);
+  guint16              length  = pntohs(&hdr->length);
+  proto_item *         ti      = proto_tree_add_item(tree, offset, length, "Identification payload");
+  proto_tree *         ntree   = proto_tree_new();
+
+  proto_item_add_subtree(ti, ntree, ETT_ISAKMP_PAYLOAD);
+  
+  proto_tree_add_item(ntree, offset, sizeof(hdr->next_payload),
+                     "Next payload: %s (%u)",
+                     payloadtype2str(hdr->next_payload), hdr->next_payload);
+  offset += sizeof(hdr->next_payload) * 2;
+  
+  proto_tree_add_item(ntree, offset, sizeof(length),
+                     "Length: %u", length);
+  offset += sizeof(length);
+  
+  proto_tree_add_item(ntree, offset, sizeof(hdr->id_type),
+                     "ID type: %s (%u)", id2str(hdr->id_type), hdr->id_type);
+  offset += sizeof(hdr->id_type);
+
+  proto_tree_add_item(ntree, offset, sizeof(hdr->protocol_id),
+                     "Protocol ID: %u", hdr->protocol_id);
+  offset += sizeof(hdr->protocol_id);
+  
+  proto_tree_add_item(ntree, offset, sizeof(hdr->port),
+                     "Port: %u", pntohs(&hdr->port));
+  offset += sizeof(hdr->port);
+  
+  switch (hdr->id_type) {
+    case 1:
+    case 4:
+      proto_tree_add_item(ntree, offset, length-sizeof(*hdr),
+                         "Identification data: %s", ip_to_str(pd+offset));
+      break;
+    case 2:
+    case 3:
+      proto_tree_add_item(ntree, offset, length-sizeof(*hdr),
+                         "Identification data: %s", (char *)(pd+offset));
+      break;
+    default:
+      proto_tree_add_item(ntree, offset, length - sizeof(*hdr), "Identification Data");
+  }
+  offset += (length - sizeof(*hdr));
+  
+  if (hdr->next_payload < NUM_LOAD_TYPES)
+    (*strfuncs[hdr->next_payload].func)(pd, offset, fd, tree);
+  else
+    dissect_data(pd, offset, fd, tree);
+}
+
+static void
+dissect_cert(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
+
+  struct cert_hdr *    hdr     = (struct cert_hdr *)(pd + offset);
+  guint16              length  = pntohs(&hdr->length);
+  proto_item *         ti      = proto_tree_add_item(tree, offset, length, "Certificate payload");
+  proto_tree *         ntree   = proto_tree_new();
+
+  proto_item_add_subtree(ti, ntree, ETT_ISAKMP_PAYLOAD);
+  
+  proto_tree_add_item(ntree, offset, sizeof(hdr->next_payload),
+                     "Next payload: %s (%u)",
+                     payloadtype2str(hdr->next_payload), hdr->next_payload);
+  offset += sizeof(hdr->next_payload) * 2;
+  
+  proto_tree_add_item(ntree, offset, sizeof(length),
+                     "Length: %u", length);
+  offset += sizeof(length);
+  
+  proto_tree_add_item(ntree, offset, sizeof(hdr->cert_enc),
+                     "Certificate encoding: %u", hdr->cert_enc);
+  offset += sizeof(hdr->cert_enc);
+
+  proto_tree_add_item(ntree, offset, length - sizeof(*hdr), "Certificate Data");
+  offset += (length - sizeof(*hdr));
+  
+  if (hdr->next_payload < NUM_LOAD_TYPES)
+    (*strfuncs[hdr->next_payload].func)(pd, offset, fd, tree);
+  else
+    dissect_data(pd, offset, fd, tree);
+}
+
+static void
+dissect_certreq(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
+
+  struct certreq_hdr * hdr     = (struct certreq_hdr *)(pd + offset);
+  guint16              length  = pntohs(&hdr->length);
+  proto_item *         ti      = proto_tree_add_item(tree, offset, length, "Certificate Request payload");
+  proto_tree *         ntree   = proto_tree_new();
+
+  proto_item_add_subtree(ti, ntree, ETT_ISAKMP_PAYLOAD);
+  
+  proto_tree_add_item(ntree, offset, sizeof(hdr->next_payload),
+                     "Next payload: %s (%u)",
+                     payloadtype2str(hdr->next_payload), hdr->next_payload);
+  offset += sizeof(hdr->next_payload) * 2;
+  
+  proto_tree_add_item(ntree, offset, sizeof(length),
+                     "Length: %u", length);
+  offset += sizeof(length);
+  
+  proto_tree_add_item(ntree, offset, sizeof(hdr->cert_type),
+                     "Certificate type: %u", hdr->cert_type);
+  offset += sizeof(hdr->cert_type);
+
+  proto_tree_add_item(ntree, offset, length - sizeof(*hdr), "Certificate Authority");
+  offset += (length - sizeof(*hdr));
+  
+  if (hdr->next_payload < NUM_LOAD_TYPES)
+    (*strfuncs[hdr->next_payload].func)(pd, offset, fd, tree);
+  else
+    dissect_data(pd, offset, fd, tree);
+}
+
+static void
+dissect_hash(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
+
+  struct hash_hdr *    hdr     = (struct hash_hdr *)(pd + offset);
+  guint16              length  = pntohs(&hdr->length);
+  proto_item *         ti      = proto_tree_add_item(tree, offset, length, "Hash payload");
+  proto_tree *         ntree   = proto_tree_new();
+
+  proto_item_add_subtree(ti, ntree, ETT_ISAKMP_PAYLOAD);
+  
+  proto_tree_add_item(ntree, offset, sizeof(hdr->next_payload),
+                     "Next payload: %s (%u)",
+                     payloadtype2str(hdr->next_payload), hdr->next_payload);
+  offset += sizeof(hdr->next_payload) * 2;
+  
+  proto_tree_add_item(ntree, offset, sizeof(length),
+                     "Length: %u", length);
+  offset += sizeof(length);
+  
+  proto_tree_add_item(ntree, offset, length - sizeof(*hdr), "Hash Data");
+  offset += (length - sizeof(*hdr));
+  
+  if (hdr->next_payload < NUM_LOAD_TYPES)
+    (*strfuncs[hdr->next_payload].func)(pd, offset, fd, tree);
+  else
+    dissect_data(pd, offset, fd, tree);
+}
+
+static void
+dissect_sig(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
+
+  struct sig_hdr *     hdr     = (struct sig_hdr *)(pd + offset);
+  guint16              length  = pntohs(&hdr->length);
+  proto_item *         ti      = proto_tree_add_item(tree, offset, length, "Signature payload");
+  proto_tree *         ntree   = proto_tree_new();
+
+  proto_item_add_subtree(ti, ntree, ETT_ISAKMP_PAYLOAD);
+  
+  proto_tree_add_item(ntree, offset, sizeof(hdr->next_payload),
+                     "Next payload: %s (%u)",
+                     payloadtype2str(hdr->next_payload), hdr->next_payload);
+  offset += sizeof(hdr->next_payload) * 2;
+  
+  proto_tree_add_item(ntree, offset, sizeof(length),
+                     "Length: %u", length);
+  offset += sizeof(length);
+  
+  proto_tree_add_item(ntree, offset, length - sizeof(*hdr), "Signature Data");
+  offset += (length - sizeof(*hdr));
+  
+  if (hdr->next_payload < NUM_LOAD_TYPES)
+    (*strfuncs[hdr->next_payload].func)(pd, offset, fd, tree);
+  else
+    dissect_data(pd, offset, fd, tree);
+}
+
+static void
+dissect_nonce(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
+
+  struct nonce_hdr *   hdr     = (struct nonce_hdr *)(pd + offset);
+  guint16              length  = pntohs(&hdr->length);
+  proto_item *         ti      = proto_tree_add_item(tree, offset, length, "Nonce payload");
+  proto_tree *         ntree   = proto_tree_new();
+
+  proto_item_add_subtree(ti, ntree, ETT_ISAKMP_PAYLOAD);
+  
+  proto_tree_add_item(ntree, offset, sizeof(hdr->next_payload),
+                     "Next payload: %s (%u)",
+                     payloadtype2str(hdr->next_payload), hdr->next_payload);
+  offset += sizeof(hdr->next_payload) * 2;
+  
+  proto_tree_add_item(ntree, offset, sizeof(length),
+                     "Length: %u", length);
+  offset += sizeof(length);
+  
+  proto_tree_add_item(ntree, offset, length - sizeof(*hdr), "Nonce Data");
+  offset += (length - sizeof(*hdr));
+  
+  if (hdr->next_payload < NUM_LOAD_TYPES)
+    (*strfuncs[hdr->next_payload].func)(pd, offset, fd, tree);
+  else
+    dissect_data(pd, offset, fd, tree);
+}
+
+static void
+dissect_notif(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
+
+  struct notif_hdr *   hdr     = (struct notif_hdr *)(pd + offset);
+  guint16              length  = pntohs(&hdr->length);
+  guint32              doi     = pntohl(&hdr->doi);
+  guint16              msgtype = pntohs(&hdr->msgtype);
+  proto_item *         ti      = proto_tree_add_item(tree, offset, length, "Notification payload");
+  proto_tree *         ntree   = proto_tree_new();
+
+  proto_item_add_subtree(ti, ntree, ETT_ISAKMP_PAYLOAD);
+  
+  proto_tree_add_item(ntree, offset, sizeof(hdr->next_payload),
+                     "Next payload: %s (%u)",
+                     payloadtype2str(hdr->next_payload), hdr->next_payload);
+  offset += sizeof(hdr->next_payload) * 2;
+  
+  proto_tree_add_item(ntree, offset, sizeof(length),
+                     "Length: %u", length);
+  offset += sizeof(length);
+  
+  proto_tree_add_item(ntree, offset, sizeof(doi),
+                     "Domain of Interpretation: %s (%u)", doitype2str(doi), doi);
+  offset += sizeof(doi);
+
+  proto_tree_add_item(ntree, offset, sizeof(hdr->protocol_id),
+                     "Protocol ID: %s (%u)",
+                     proto2str(hdr->protocol_id), hdr->protocol_id);
+  offset += sizeof(hdr->protocol_id);
+  
+  proto_tree_add_item(ntree, offset, sizeof(hdr->spi_size),
+                     "SPI size: %u", hdr->spi_size);
+  offset += sizeof(hdr->spi_size);
+  
+  proto_tree_add_item(ntree, offset, sizeof(msgtype),
+                     "Message type: %s (%u)", msgtype2str(msgtype), msgtype);
+  offset += sizeof(msgtype);
+
+  if (hdr->spi_size) {
+    proto_tree_add_item(ntree, offset, hdr->spi_size, "Security Parameter Index");
+    offset += hdr->spi_size;
+  }
+
+  if (length - sizeof(*hdr)) {
+    proto_tree_add_item(ntree, offset, length - sizeof(*hdr) - hdr->spi_size,
+                       "Notification Data");
+    offset += (length - sizeof(*hdr) - hdr->spi_size);
+  }
+  
+  if (hdr->next_payload < NUM_LOAD_TYPES)
+    (*strfuncs[hdr->next_payload].func)(pd, offset, fd, tree);
+  else
+    dissect_data(pd, offset, fd, tree);
+}
+
+static void
+dissect_delete(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
+
+  struct delete_hdr *  hdr      = (struct delete_hdr *)(pd + offset);
+  guint16              length   = pntohs(&hdr->length);
+  guint32              doi      = pntohl(&hdr->doi);
+  guint16              num_spis = pntohs(&hdr->num_spis);
+  proto_item *         ti       = proto_tree_add_item(tree, offset, length, "Delete payload");
+  proto_tree *         ntree    = proto_tree_new();
+  guint16              i;
+  
+  proto_item_add_subtree(ti, ntree, ETT_ISAKMP_PAYLOAD);
+  
+  proto_tree_add_item(ntree, offset, sizeof(hdr->next_payload),
+                     "Next payload: %s (%u)",
+                     payloadtype2str(hdr->next_payload), hdr->next_payload);
+  offset += sizeof(hdr->next_payload) * 2;
+  
+  proto_tree_add_item(ntree, offset, sizeof(length),
+                     "Length: %u", length);
+  offset += sizeof(length);
+  
+  proto_tree_add_item(ntree, offset, sizeof(doi),
+                     "Domain of Interpretation: %s (%u)", doitype2str(doi), doi);
+  offset += sizeof(doi);
+
+  proto_tree_add_item(ntree, offset, sizeof(hdr->protocol_id),
+                     "Protocol ID: %s (%u)",
+                     proto2str(hdr->protocol_id), hdr->protocol_id);
+  offset += sizeof(hdr->protocol_id);
+  
+  proto_tree_add_item(ntree, offset, sizeof(hdr->spi_size),
+                     "SPI size: %u", hdr->spi_size);
+  offset += sizeof(hdr->spi_size);
+  
+  proto_tree_add_item(ntree, offset, num_spis,
+                     "Number of SPIs: %u", num_spis);
+  offset += sizeof(hdr->num_spis);
+  
+  for (i = 0; i < num_spis; ++i) {
+    proto_tree_add_item(ntree, offset, hdr->spi_size,
+                       "SPI (%d)", i);
+    offset += hdr->spi_size;
+  }
+
+  if (hdr->next_payload < NUM_LOAD_TYPES)
+    (*strfuncs[hdr->next_payload].func)(pd, offset, fd, tree);
+  else
+    dissect_data(pd, offset, fd, tree);
+}
+
+static void
+dissect_vid(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
+
+  struct vid_hdr *     hdr     = (struct vid_hdr *)(pd + offset);
+  guint16              length  = pntohs(&hdr->length);
+  proto_item *         ti      = proto_tree_add_item(tree, offset, length, "Vendor ID payload");
+  proto_tree *         ntree   = proto_tree_new();
+
+  proto_item_add_subtree(ti, ntree, ETT_ISAKMP_PAYLOAD);
+  
+  proto_tree_add_item(ntree, offset, sizeof(hdr->next_payload),
+                     "Next payload: %s (%u)",
+                     payloadtype2str(hdr->next_payload), hdr->next_payload);
+  offset += sizeof(hdr->next_payload) * 2;
+  
+  proto_tree_add_item(ntree, offset, sizeof(length),
+                     "Length: %u", length);
+  offset += sizeof(length);
+  
+  proto_tree_add_item(ntree, offset, length - sizeof(*hdr), "Vendor ID");
+  offset += (length - sizeof(*hdr));
+  
+  if (hdr->next_payload < NUM_LOAD_TYPES)
+    (*strfuncs[hdr->next_payload].func)(pd, offset, fd, tree);
+  else
+    dissect_data(pd, offset, fd, tree);
+}
+
+static const char *
+payloadtype2str(guint8 type) {
+
+  if (type < NUM_LOAD_TYPES) return strfuncs[type].str;
+  if (type < 128)            return "RESERVED";
+  if (type < 256)            return "Private USE";
+
+  return "Huh? You should never see this! Shame on you!";
+}
+
+static const char *
+exchtype2str(guint8 type) {
+
+#define NUM_EXCHSTRS   6
+  static const char * exchstrs[NUM_EXCHSTRS] = {
+    "NONE",
+    "Base",
+    "Identity Protection",
+    "Authentication Only",
+    "Aggressive",
+    "Informational"
+  };
+  
+  if (type < NUM_EXCHSTRS) return exchstrs[type];
+  if (type < 32)           return "ISAKMP Future Use";
+  if (type < 240)          return "DOI Specific Use";
+  if (type < 256)          return "Private Use";
+  
+  return "Huh? You should never see this! Shame on you!";
+}
+
+static const char *
+doitype2str(guint32 type) {
+  if (type == 1) return "IPSEC";
+  return "Unknown DOI Type";
+}
+
+static const char *
+msgtype2str(guint16 type) {
+
+#define NUM_PREDEFINED 31
+  static const char *msgs[NUM_PREDEFINED] = {
+    "<UNKNOWN>",
+    "INVALID-PAYLOAD-TYPE",
+    "DOI-NOT-SUPPORTED",
+    "SITUATION-NOT-SUPPORTED",
+    "INVALID-COOKIE",
+    "INVALID-MAJOR-VERSION",
+    "INVALID-MINOR-VERSION",
+    "INVALID-EXCHANGE-TYPE",
+    "INVALID-FLAGS",
+    "INVALID-MESSAGE-ID",
+    "INVALID-PROTOCOL-ID",
+    "INVALID-SPI",
+    "INVALID-TRANSFORM-ID",
+    "ATTRIBUTES-NOT-SUPPORTED",
+    "NO-PROPOSAL-CHOSEN",
+    "BAD-PROPOSAL-SYNTAX",
+    "PAYLOAD-MALFORMED",
+    "INVALID-KEY-INFORMATION",
+    "INVALID-ID-INFORMATION",
+    "INVALID-CERT-ENCODING",
+    "INVALID-CERTIFICATE",
+    "CERT-TYPE-UNSUPPORTED",
+    "INVALID-CERT-AUTHORITY",
+    "INVALID-HASH-INFORMATION",
+    "AUTHENTICATION-FAILED",
+    "INVALID-SIGNATURE",
+    "ADDRESS-NOTIFICATION",
+    "NOTIFY-SA-LIFETIME",
+    "CERTIFICATE-UNAVAILABLE",
+    "UNSUPPORTED-EXCHANGE-TYPE",
+    "UNEQUAL-PAYLOAD-LENGTHS"
+  };
+
+  if (type < NUM_PREDEFINED) return msgs[type];
+  if (type < 8192)           return "RESERVED (Future Use)";
+  if (type < 16384)          return "Private Use";
+  if (type < 16385)          return "CONNECTED";
+  if (type < 24576)          return "RESERVED (Future Use) - status";
+  if (type < 24577)          return "RESPONDER-LIFETIME";
+  if (type < 24578)          return "REPLAY-STATUS";
+  if (type < 24579)          return "INITIAL-CONTACT";
+  if (type < 32768)          return "DOI-specific codes";
+  if (type < 40960)          return "Private Use - status";
+  if (type < 65535)          return "RESERVED (Future Use) - status (2)";
+
+  return "Huh? You should never see this! Shame on you!";
+}
+
+static const char *
+situation2str(guint32 type) {
+
+#define SIT_MSG_NUM    1024
+#define SIT_IDENTITY   0x01
+#define SIT_SECRECY    0x02
+#define SIT_INTEGRITY  0x04
+
+  static char  msg[SIT_MSG_NUM];
+  int          n = 0;
+  char *       sep = "";
+  
+  if (type & SIT_IDENTITY) {
+    n += snprintf(msg, SIT_MSG_NUM-n, "%sIDENTITY", sep);
+    sep = " & ";
+  }
+  if (type & SIT_SECRECY) {
+    n += snprintf(msg, SIT_MSG_NUM-n, "%sSECRECY", sep);
+    sep = " & ";
+  }
+  if (type & SIT_INTEGRITY) {
+    n += snprintf(msg, SIT_MSG_NUM-n, "%sINTEGRITY", sep);
+    sep = " & ";
+  }
+
+  return msg;
+}
+
+static const char *
+value2str(guint16 att_type, guint16 value) {
+  
+  if (value == 0) return "RESERVED";
+  
+  switch (att_type) {
+    case 1:
+    case 2:
+      switch (value) {
+        case 1:  return "Seconds";
+        case 2:  return "Kilobytes";
+        default: return "UNKNOWN-SA-VALUE";
+      }
+    case 3:
+      return "Group-Value";
+    case 4:
+      switch (value) {
+        case 1:  return "Tunnel";
+        case 2:  return "Transport";
+        default: return "UNKNOWN-ENCAPSULATION-VALUE";
+      }
+    case 5:
+      switch (value) {
+        case 1:  return "HMAC-MD5";
+        case 2:  return "HMAC-SHA";
+        case 3:  return "DES-MAC";
+        case 4:  return "KPDK";
+        default: return "UNKNOWN-AUTHENTICATION-VALUE";
+      }
+    case 11:
+      return "Life-Type";
+    default: return "UNKNOWN-ATTRIBUTE-TYPE";
+  }
+}
+
+static const char *
+num2str(const guint8 *pd, guint16 len) {
+
+#define NUMSTR_LEN     1024
+  static char          numstr[NUMSTR_LEN];
+  
+  switch (len) {
+  case 1:
+    snprintf(numstr, NUMSTR_LEN, "%u", *pd);
+    break;
+  case 2:
+    snprintf(numstr, NUMSTR_LEN, "%u", pntohs(pd));
+    break;
+  case 3:
+    snprintf(numstr, NUMSTR_LEN, "%lu", pntohl(pd) & 0x0fff);
+    break;
+  case 4:
+    snprintf(numstr, NUMSTR_LEN, "%lu", pntohl(pd));
+    break;
+  default:
+    snprintf(numstr, NUMSTR_LEN, "<too big>");
+  }
+
+  return numstr;
+}
+
index 31b8c7f8f68660f90ac14098440554ea9d4a3b69..a96217f9cc37571e5ac9cfd1a33c6812aa0e5012 100644 (file)
@@ -1,7 +1,7 @@
 /* packet-ppp.c
  * Routines for ppp packet disassembly
  *
- * $Id: packet-ppp.c,v 1.10 1999/03/23 03:14:43 gram Exp $
+ * $Id: packet-ppp.c,v 1.11 1999/06/11 15:30:39 gram Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -67,6 +67,116 @@ typedef struct _e_ppphdr {
 #define PPP_CHAP       0xc223  /* Cryptographic Handshake Auth. Protocol */
 #define PPP_CBCP       0xc029  /* Callback Control Protocol */
 
+
+static const value_string ppp_vals[] = {
+       {PPP_IP,        "IP"             },
+       {PPP_AT,        "Appletalk"      },
+       {PPP_IPX,       "Netware IPX/SPX"},
+       {PPP_VJC_COMP,  "VJ compressed TCP"},
+       {PPP_VJC_UNCOMP,"VJ uncompressed TCP"}, 
+       {PPP_VINES,     "Vines"          },
+       {PPP_IPV6,      "IPv6"           },
+       {PPP_COMP,                "compressed packet" },
+       {PPP_IPCP,                "IP Control Protocol" },
+       {PPP_ATCP,                "AppleTalk Control Protocol" },
+       {PPP_IPXCP,         "IPX Control Protocol" },
+       {PPP_CCP,                   "Compression Control Protocol" },
+       {PPP_LCP,                   "Link Control Protocol" },
+       {PPP_PAP,                   "Password Authentication Protocol"  },
+       {PPP_LQR,                   "Link Quality Report protocol" },
+       {PPP_CHAP,                "Cryptographic Handshake Auth. Protocol" },
+       {PPP_CBCP,                "Callback Control Protocol" },
+       {0,             NULL            } };
+
+/* CP (LCP, IPCP, etc.) codes.
+ * from pppd fsm.h 
+ */
+#define CONFREQ   1 /* Configuration Request */
+#define CONFACK   2 /* Configuration Ack */
+#define CONFNAK   3 /* Configuration Nak */
+#define CONFREJ   4 /* Configuration Reject */
+#define TERMREQ   5 /* Termination Request */
+#define TERMACK   6 /* Termination Ack */
+#define CODEREJ   7 /* Code Reject */
+
+static const value_string cp_vals[] = {
+       {CONFREQ,    "Configuration Request " },
+       {CONFACK,    "Configuration Ack " },
+       {CONFNAK,    "Configuration Nak " },
+       {CONFREJ,    "Configuration Reject " },
+       {TERMREQ,    "Termination Request " },
+       {TERMACK,    "Termination Ack " },
+       {CODEREJ,    "Code Reject " },
+       {0,             NULL            } };
+
+/*
+ * LCP-specific packet types.
+ */
+#define PROTREJ   8 /* Protocol Reject */
+#define ECHOREQ   9 /* Echo Request */
+#define ECHOREP   10  /* Echo Reply */
+#define DISCREQ   11  /* Discard Request */
+#define CBCP_OPT  6 /* Use callback control protocol */
+
+static const value_string lcp_vals[] = {
+       {CONFREQ,    "Configuration Request " },
+       {CONFACK,    "Configuration Ack " },
+       {CONFNAK,    "Configuration Nak " },
+       {CONFREJ,    "Configuration Reject " },
+       {TERMREQ,    "Termination Request " },
+       {TERMACK,    "Termination Ack " },
+       {CODEREJ,    "Code Reject " },
+       {PROTREJ, "Protocol Reject " },
+       {ECHOREQ, "Echo Request " },
+       {ECHOREP, "Echo Reply " },
+       {DISCREQ, "Discard Request " },
+       {CBCP_OPT, "Use callback control protocol" },
+       {0,             NULL            } };
+
+/*
+ * Options.  (LCP)
+ */
+#define CI_MRU    1 /* Maximum Receive Unit */
+#define CI_ASYNCMAP 2 /* Async Control Character Map */
+#define CI_AUTHTYPE 3 /* Authentication Type */
+#define CI_QUALITY  4 /* Quality Protocol */
+#define CI_MAGICNUMBER  5 /* Magic Number */
+#define CI_PCOMPRESSION 7 /* Protocol Field Compression */
+#define CI_ACCOMPRESSION 8  /* Address/Control Field Compression */
+#define CI_CALLBACK 13  /* callback */
+
+static const value_string lcp_opt_vals[] = {
+       {CI_MRU,          "Maximum Receive Unit" },
+       {CI_ASYNCMAP,     "Async Control Character Map" },
+       {CI_AUTHTYPE,     "Authentication Type" },
+       {CI_QUALITY,      "Quality Protocol" },
+       {CI_MAGICNUMBER,  "Magic Number" },
+       {CI_PCOMPRESSION, "Protocol Field Compression" },
+       {CI_ACCOMPRESSION,"Address/Control Field Compression" },
+       {CI_CALLBACK,     "callback" },
+       {0,             NULL            } };
+
+/*
+ * Options.  (IPCP)
+ */
+#define CI_ADDRS  1 /* IP Addresses */
+#define CI_COMPRESSTYPE 2 /* Compression Type */
+#define CI_ADDR   3
+#define CI_MS_DNS1  129 /* Primary DNS value */
+#define CI_MS_WINS1 130 /* Primary WINS value */
+#define CI_MS_DNS2  131 /* Secondary DNS value */
+#define CI_MS_WINS2 132 /* Secondary WINS value */
+
+static const value_string ipcp_opt_vals[] = {
+       {CI_ADDRS,       "IP Addresses" },
+       {CI_COMPRESSTYPE,"Compression Type" },
+       {CI_ADDR,        "Address" }, 
+       {CI_MS_DNS1,     "Primary DNS value" },
+       {CI_MS_WINS1,    "Primary WINS value" },
+       {CI_MS_DNS2,     "Secondary DNS value" },
+       {CI_MS_WINS2,    "Secondary WINS value" },
+       {0,             NULL            } };
+
 void
 capture_ppp( const u_char *pd, guint32 cap_len, packet_counts *ld ) {
   switch (pntohs(&pd[2])) {
@@ -79,6 +189,131 @@ capture_ppp( const u_char *pd, guint32 cap_len, packet_counts *ld ) {
   }
 }
 
+void
+dissect_ipcp( const u_char *pd, int offset, frame_data *fd, proto_tree *tree ) {
+  proto_tree *fh_tree;
+  proto_item *ti;
+
+       int ipcpcode;
+       int ipcpid;
+       int optionslength;
+
+       ipcpcode = pd[0+offset];
+       ipcpid = pd[1+offset];
+       optionslength= pntohs(&pd[2+offset]);
+       
+       if(check_col(fd, COL_INFO))
+               col_add_fstr(fd, COL_INFO, "IPCP %s", 
+                       val_to_str(ipcpcode, cp_vals, "Unknown"));
+
+  if(tree) {
+    ti = proto_tree_add_item(tree, 0+offset, 4, "IP Control Protocol" );
+    fh_tree = proto_tree_new();
+    proto_item_add_subtree(ti, fh_tree, ETT_IPCP);
+    proto_tree_add_item(fh_tree, 0+offset, 1, "Code: %s (0x%02x)",
+      val_to_str(ipcpcode, cp_vals, "Unknown"), ipcpcode);
+    proto_tree_add_item(fh_tree, 1+offset, 1, "Identifier: 0x%02x",
+                       ipcpid);
+    proto_tree_add_item(fh_tree, 2+offset, 2, "Length: %d",
+                       optionslength);
+  }
+
+  switch (ipcpcode) {
+               /* decode lcp options here. */
+    default:
+      dissect_data(pd, 4+offset, fd, tree);
+      break;
+  }
+}
+
+void
+dissect_lcp( const u_char *pd, int offset, frame_data *fd, proto_tree *tree ) {
+  proto_tree *fh_tree;
+  proto_item *ti;
+
+       int lcpcode;
+       int lcpid;
+       int optionslength;
+
+       lcpcode = pd[0+offset];
+       lcpid = pd[1+offset];
+       optionslength= pntohs(&pd[2+offset]);
+       
+       if(check_col(fd, COL_INFO))
+               col_add_fstr(fd, COL_INFO, "LCP %s", 
+                       val_to_str(lcpcode, lcp_vals, "Unknown"));
+
+  if(tree) {
+    ti = proto_tree_add_item(tree, 0+offset, 4, "Link Control Protocol" );
+    fh_tree = proto_tree_new();
+    proto_item_add_subtree(ti, fh_tree, ETT_LCP);
+    proto_tree_add_item(fh_tree, 0+offset, 1, "Code: %s (0x%02x)",
+      val_to_str(lcpcode, lcp_vals, "Unknown"), lcpcode);
+    proto_tree_add_item(fh_tree, 1+offset, 1, "Identifier: 0x%02x",
+                       lcpid);
+    proto_tree_add_item(fh_tree, 2+offset, 2, "Length: %d",
+                       optionslength);
+  }
+
+  switch (lcpcode) {
+               /* decode lcp options here. */
+    default:
+      dissect_data(pd, 4+offset, fd, tree);
+      break;
+  }
+}
+
+void
+dissect_payload_ppp( const u_char *pd, int offset, frame_data *fd, proto_tree *tree ) {
+  e_ppphdr   ph;
+  proto_tree *fh_tree;
+  proto_item *ti;
+
+/*  ph.ppp_addr = pd[0+offset]; */
+/* ph.ppp_ctl  = pd[1+offset]; */
+  ph.ppp_prot = pntohs(&pd[0+offset]);
+
+  /* populate a tree in the second pane with the status of the link
+     layer (ie none) */
+  if(tree) {
+    ti = proto_tree_add_item(tree, 0+offset, 2, "Point-to-Point Protocol" );
+    fh_tree = proto_tree_new();
+    proto_item_add_subtree(ti, fh_tree, ETT_PPP);
+    proto_tree_add_item(fh_tree, 0+offset, 2, "Protocol: %s (0x%04x)",
+      val_to_str(ph.ppp_prot, ppp_vals, "Unknown"), ph.ppp_prot);
+  }
+
+  switch (ph.ppp_prot) {
+    case PPP_IP:
+      dissect_ip(pd, 2+offset, fd, tree);
+      break;
+    case PPP_AT:
+      dissect_ddp(pd, 2+offset, fd, tree);
+      break;
+    case PPP_IPX:
+      dissect_ipx(pd, 2+offset, fd, tree);
+      break;
+    case PPP_VINES:
+      dissect_vines(pd, 2+offset, fd, tree);
+      break;
+    case PPP_IPV6:
+      dissect_ipv6(pd, 2+offset, fd, tree);
+      break;
+    case PPP_LCP:
+      dissect_lcp(pd, 2+offset, fd, tree);
+      break;
+    case PPP_IPCP:
+      dissect_ipcp(pd, 2+offset, fd, tree);
+      break;
+    default:
+      dissect_data(pd, 2+offset, fd, tree);
+      if (check_col(fd, COL_INFO))
+        col_add_fstr(fd, COL_INFO, "PPP %s (0x%04x)", 
+                                       val_to_str(ph.ppp_prot, ppp_vals, "Unknown"), ph.ppp_prot);
+      break;
+  }
+}
+
 void
 dissect_ppp( const u_char *pd, frame_data *fd, proto_tree *tree ) {
   e_ppphdr   ph;
@@ -99,14 +334,15 @@ dissect_ppp( const u_char *pd, frame_data *fd, proto_tree *tree ) {
 
   /* load the top pane info. This should be overwritten by
      the next protocol in the stack */
-  if(check_col(fd, COL_RES_DL_SRC))
-    col_add_str(fd, COL_RES_DL_SRC, "N/A" );
-  if(check_col(fd, COL_RES_DL_DST))
-    col_add_str(fd, COL_RES_DL_DST, "N/A" );
-  if(check_col(fd, COL_PROTOCOL))
-    col_add_str(fd, COL_PROTOCOL, "N/A" );
-  if(check_col(fd, COL_INFO))
-    col_add_str(fd, COL_INFO, "PPP" );
+
+        if(check_col(fd, COL_RES_DL_SRC))
+          col_add_str(fd, COL_RES_DL_SRC, "N/A" );
+        if(check_col(fd, COL_RES_DL_DST))
+          col_add_str(fd, COL_RES_DL_DST, "N/A" );
+        if(check_col(fd, COL_PROTOCOL))
+          col_add_str(fd, COL_PROTOCOL, "N/A" );
+        if(check_col(fd, COL_INFO))
+          col_add_str(fd, COL_INFO, "PPP" );
 
   /* populate a tree in the second pane with the status of the link
      layer (ie none) */
diff --git a/packet-pppoe.c b/packet-pppoe.c
new file mode 100644 (file)
index 0000000..9da3f40
--- /dev/null
@@ -0,0 +1,237 @@
+/* packet-arp.c
+ * Routines for ARP packet disassembly
+ *
+ * $Id: packet-pppoe.c,v 1.1 1999/06/11 15:30:39 gram Exp $
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@zing.org>
+ * 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
+
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#include <glib.h>
+#include "packet.h"
+#include "etypes.h"
+
+/* For lack of a better source, I made up the following defines. -jsj */
+
+#define PPPOE_CODE_SESSION 0x00
+#define PPPOE_CODE_PADO 0x7
+#define PPPOE_CODE_PADI 0x9
+#define PPPOE_CODE_PADR 0x19
+#define PPPOE_CODE_PADS 0x65
+#define PPPOE_CODE_PADT 0xa7
+
+#define PPPOE_TAG_EOL 0x0000 
+#define PPPOE_TAG_SVC_NAME 0x0101
+#define PPPOE_TAG_AC_NAME 0x0102 
+#define PPPOE_TAG_HOST_UNIQ 0x0103
+#define PPPOE_TAG_AC_COOKIE 0x0104
+#define PPPOE_TAG_VENDOR 0x0105 
+#define PPPOE_TAG_RELAY_ID 0x0110 
+#define PPPOE_TAG_SVC_ERR 0x0201 
+#define PPPOE_TAG_AC_ERR 0x0202 
+#define PPPOE_TAG_GENERIC_ERR 0x0203
+
+gchar *
+pppoecode_to_str(guint8 codetype, const char *fmt) {
+       static const value_string code_vals[] = {
+               {PPPOE_CODE_SESSION, "Session Data"                             },
+               {PPPOE_CODE_PADO, "Active Discovery Offer (PADO)"               },
+               {PPPOE_CODE_PADI, "Active Discovery Initiation (PADI)"          },
+               {PPPOE_CODE_PADR, "Active Discovery Request (PADR)"             },
+               {PPPOE_CODE_PADS, "Active Discovery Session-confirmation (PADS)"},
+               {PPPOE_CODE_PADT, "Active Discovery Terminate (PADT)"           },
+               {0,     NULL                                                        } };
+
+               return val_to_str(codetype, code_vals, fmt);
+}
+
+gchar *
+pppoetag_to_str(guint16 tag_type, const char *fmt) {
+       static const value_string code_vals[] = {
+               {PPPOE_TAG_EOL,        "End-Of-List"       },
+               {PPPOE_TAG_SVC_NAME,   "Service-Name"      },
+               {PPPOE_TAG_AC_NAME,    "AC-Name"           },
+               {PPPOE_TAG_HOST_UNIQ,  "Host-Uniq"         },
+               {PPPOE_TAG_AC_COOKIE,  "AC-Cookie"         },
+               {PPPOE_TAG_VENDOR,     "Vendor-Specific"   },
+               {PPPOE_TAG_RELAY_ID,   "Relay-Session-Id"  },
+               {PPPOE_TAG_SVC_ERR,    "Service-Name-Error"},
+               {PPPOE_TAG_AC_ERR,     "AC-System-Error"   },
+               {PPPOE_TAG_GENERIC_ERR,"Generic-Error"     },
+               {0,                    NULL                } };
+
+               return val_to_str(tag_type, code_vals, fmt);
+}
+
+
+void
+dissect_pppoe_tags(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int payload_length) {
+
+       guint16 poe_tag;
+       guint16 poe_tag_length;
+       int tagstart;
+
+       proto_tree  *pppoe_tree;
+       proto_item  *ti;
+
+       /* Start Decoding Here. */
+
+       if (tree) {
+               ti = proto_tree_add_item(tree,offset,payload_length,"PPPoE Tags");
+               pppoe_tree = proto_tree_new();
+               proto_item_add_subtree(ti, pppoe_tree, ETT_PPPOED_TAGS);
+
+               tagstart = offset;
+               while(tagstart <= payload_length-2 ) {
+
+                       poe_tag = pntohs(&pd[tagstart]);
+                       poe_tag_length = pntohs(&pd[tagstart + 2]);
+
+                       proto_tree_add_item(pppoe_tree,tagstart,4,
+                               "Tag: %s", pppoetag_to_str(poe_tag,"Unknown (0x%02x)"));
+                       
+                       switch(poe_tag) {
+                       case PPPOE_TAG_SVC_NAME:
+                       case PPPOE_TAG_AC_NAME:
+                       case PPPOE_TAG_SVC_ERR:
+                       case PPPOE_TAG_AC_ERR:
+                       case PPPOE_TAG_GENERIC_ERR:
+                               /* tag value should be interpreted as a utf-8 unterminated string.*/
+                               if(poe_tag_length > 0 ) {
+                                       /* really should do some limit checking here.  :( */
+                                       proto_tree_add_item(pppoe_tree,tagstart+4,poe_tag_length,
+                                               "  String Data: %s", format_text(&pd[tagstart+4],poe_tag_length ));
+                               }
+                               break;
+                       default:
+                               if(poe_tag_length > 0 ) {
+                                proto_tree_add_item(pppoe_tree,tagstart+4,poe_tag_length,
+                                               "  Binary Data: (%d bytes)", poe_tag_length );
+                               }
+                       }
+
+                       if (poe_tag == PPPOE_TAG_EOL) break;
+
+                       tagstart += 4 + poe_tag_length;
+               }
+       }
+}
+
+void
+dissect_pppoed(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
+       guint8 pppoe_ver;
+       guint8 pppoe_type;
+       guint8  pppoe_code;
+       guint16 pppoe_session_id;
+       guint16 pppoe_length;
+
+       proto_tree  *pppoe_tree;
+       proto_item  *ti;
+
+       /* Start Decoding Here. */
+       pppoe_ver = (guint8) ((pd[offset] >> 4) & 0x0f);
+       pppoe_type = (guint8) (pd[offset] & 0x0f);
+       pppoe_code = (guint8) pd[offset + 1];
+       pppoe_session_id = pntohs(&pd[offset + 2]);
+       pppoe_length = pntohs(&pd[offset + 4]);
+
+       if (check_col(fd, COL_PROTOCOL)) {
+               col_add_str(fd,COL_PROTOCOL, "PPPoED");
+       }
+
+       if (check_col(fd,COL_INFO)) {
+               col_add_fstr(fd,COL_INFO,pppoecode_to_str(pppoe_code,"Unknown code (0x%02x)"));
+       }
+
+       if (tree) {
+               ti = proto_tree_add_item(tree,offset,pppoe_length+6,"PPPoE Discovery");
+               pppoe_tree = proto_tree_new();
+               proto_item_add_subtree(ti, pppoe_tree, ETT_PPPOED);
+               proto_tree_add_item(pppoe_tree,offset,1,
+                       "Version: %d", pppoe_ver);
+               proto_tree_add_item(pppoe_tree,offset,1,
+                       "Type: %d", pppoe_type);
+               proto_tree_add_item(pppoe_tree,offset+1,1,
+                       "Code: %s", pppoecode_to_str(pppoe_code,"Unknown (0x%02x)"));
+               proto_tree_add_item(pppoe_tree,offset+2,2,
+                       "Session ID: %04x", pppoe_session_id);
+               proto_tree_add_item(pppoe_tree,offset+4,2,
+                       "Payload Length: %d", pppoe_length);
+       }
+       dissect_pppoe_tags(pd,offset+6,fd,tree,offset+6+pppoe_length);
+
+}
+
+void
+dissect_pppoes(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
+       guint8 pppoe_ver;
+       guint8 pppoe_type;
+       guint8  pppoe_code;
+       guint16 pppoe_session_id;
+       guint16 pppoe_length;
+
+       proto_tree  *pppoe_tree;
+       proto_item  *ti;
+
+       /* Start Decoding Here. */
+       pppoe_ver = (guint8) ((pd[offset] >> 4) & 0x0f);
+       pppoe_type = (guint8) (pd[offset] & 0x0f);
+       pppoe_code = (guint8) pd[offset + 1];
+       pppoe_session_id = pntohs(&pd[offset + 2]);
+       pppoe_length = pntohs(&pd[offset + 4]);
+
+       if (check_col(fd, COL_PROTOCOL)) {
+               col_add_str(fd,COL_PROTOCOL, "PPPoES");
+       }
+
+       if (check_col(fd,COL_INFO)) {
+               col_add_fstr(fd,COL_INFO,pppoecode_to_str(pppoe_code,"Unknown code (0x%02x)"));
+       }
+
+       if (tree) {
+               ti = proto_tree_add_item(tree,offset,pppoe_length+6,"PPPoE Session");
+               pppoe_tree = proto_tree_new();
+               proto_item_add_subtree(ti, pppoe_tree, ETT_PPPOED);
+               proto_tree_add_item(pppoe_tree,offset,1,
+                       "Version: %d", pppoe_ver);
+               proto_tree_add_item(pppoe_tree,offset,1,
+                       "Type: %d", pppoe_type);
+               proto_tree_add_item(pppoe_tree,offset+1,1,
+                       "Code: %s", pppoecode_to_str(pppoe_code,"Unknown (0x%02x)"));
+               proto_tree_add_item(pppoe_tree,offset+2,2,
+                       "Session ID: %04x", pppoe_session_id);
+               proto_tree_add_item(pppoe_tree,offset+4,2,
+                       "Payload Length: %d", pppoe_length);
+       }
+       /* dissect_ppp is apparently done as a 'top level' dissector,
+               * so this doesn't work:  
+               * dissect_ppp(pd,offset+6,fd,tree);
+               * Im gonna try fudging it.
+               */
+
+       dissect_payload_ppp(pd,offset+6,fd,tree);
+}
diff --git a/packet-pptp.c b/packet-pptp.c
new file mode 100644 (file)
index 0000000..06bfea9
--- /dev/null
@@ -0,0 +1,884 @@
+/* packet-pptp.c
+ * Routines for the Point-to-Point Tunnelling Protocol (PPTP)
+ * Brad Robel-Forrest <brad.robel-forrest@watchguard.com>
+ *
+ * $Id: packet-pptp.c,v 1.1 1999/06/11 15:30:39 gram Exp $
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@unicom.net>
+ * 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
+
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#include <stdio.h>
+#include <netinet/in.h>
+#include <glib.h>
+#include "packet.h"
+
+#define NUM_MSG_TYPES          3
+#define msgtype2str(t) \
+  ((t < NUM_MSG_TYPES) ? msgtypestr[t] : "UNKNOWN-MESSAGES-TYPE")
+
+static const char *msgtypestr[NUM_MSG_TYPES] = {
+  "UNKNOWN-MESSAGE-TYPE",
+  "CONTROL-MESSAGE",
+  "MANAGEMENT-MESSAGE"
+};
+
+#define NUM_FRAME_TYPES                4
+#define frametype2str(t)       \
+  ((t < NUM_FRAME_TYPES) ? frametypestr[t] : "UNKNOWN-FRAMING-TYPE")
+
+static const char *frametypestr[NUM_FRAME_TYPES] = {
+  "UNKNOWN-FRAMING-TYPE",
+  "ASYNCHRONOUS",
+  "SYNCHRONOUS",
+  "EITHER"
+};
+
+#define NUM_BEARER_TYPES       4
+#define bearertype2str(t)      \
+  ((t < NUM_BEARER_TYPES) ? bearertypestr[t] : "UNKNOWN-BEARER-TYPE")
+
+static const char *bearertypestr[NUM_BEARER_TYPES] = {
+  "UNKNOWN-BEARER-TYPE",
+  "ANALOG",
+  "DIGITAL",
+  "EITHER"
+};
+
+#define NUM_CNTRLRESULT_TYPES  6
+#define cntrlresulttype2str(t) \
+  ((t < NUM_CNTRLRESULT_TYPES) ? cntrlresulttypestr[t] : "UNKNOWN-CNTRLRESULT-TYPE")
+
+static const char *cntrlresulttypestr[NUM_CNTRLRESULT_TYPES] = {
+  "UNKNOWN-CNTRLRESULT-TYPE",
+  "SUCCESS",
+  "GENERAL-ERROR",
+  "COMMAND-CHANNEL-EXISTS",
+  "NOT-AUTHORIZED",
+  "VERSION-NOT-SUPPORTED"
+};
+
+#define NUM_ERROR_TYPES                7
+#define errortype2str(t)       \
+  ((t < NUM_ERROR_TYPES) ? errortypestr[t] : "UNKNOWN-ERROR-TYPE")
+
+static const char *errortypestr[NUM_ERROR_TYPES] = {
+  "NONE",
+  "NOT-CONNECTED",
+  "BAD-FORMAT",
+  "BAD-VALUE",
+  "NO-RESOURCE",
+  "BAD-CALL-ID",
+  "PAC-ERROR"
+};
+
+#define NUM_REASON_TYPES       4
+#define reasontype2str(t)      \
+  ((t < NUM_REASON_TYPES) ? reasontypestr[t] : "UNKNOWN-REASON-TYPE")
+
+static const char *reasontypestr[NUM_REASON_TYPES] = {
+  "UNKNOWN-REASON-TYPE",
+  "NONE",
+  "STOP-PROTOCOL",
+  "STOP-LOCAL-SHUTDOWN"
+};
+
+#define NUM_STOPRESULT_TYPES   3
+#define stopresulttype2str(t)  \
+  ((t < NUM_STOPRESULT_TYPES) ? stopresulttypestr[t] : "UNKNOWN-STOPRESULT-TYPE")
+
+static const char *stopresulttypestr[NUM_STOPRESULT_TYPES] = {
+  "UNKNOWN-STOPRESULT-TYPE",
+  "SUCCESS",
+  "GENERAL-ERROR"
+};
+
+#define NUM_ECHORESULT_TYPES   3
+#define echoresulttype2str(t)  \
+  ((t < NUM_ECHORESULT_TYPES) ? echoresulttypestr[t] : "UNKNOWN-ECHORESULT-TYPE")
+
+static const char *echoresulttypestr[NUM_ECHORESULT_TYPES] = {
+  "UNKNOWN-ECHORESULT-TYPE",
+  "SUCCESS",
+  "GENERAL-ERROR"
+};
+
+#define NUM_OUTRESULT_TYPES    8
+#define outresulttype2str(t)   \
+  ((t < NUM_OUTRESULT_TYPES) ? outresulttypestr[t] : "UNKNOWN-OUTRESULT-TYPE")
+
+static const char *outresulttypestr[NUM_OUTRESULT_TYPES] = {
+  "UNKNOWN-OUTRESULT-TYPE",
+  "CONNECTED",
+  "GENERAL-ERROR",
+  "NO-CARRIER",
+  "BUSY",
+  "NO-DIAL-TONE",
+  "TIME-OUT",
+  "DO-NOT-ACCEPT"
+};
+
+#define NUM_INRESULT_TYPES     4
+#define inresulttype2str(t)    \
+  ((t < NUM_INRESULT_TYPES) ? inresulttypestr[t] : "UNKNOWN-INRESULT-TYPE")
+
+static const char *inresulttypestr[NUM_INRESULT_TYPES] = {
+  "UNKNOWN-INRESULT-TYPE",
+  "CONNECT",
+  "GENERAL-ERROR",
+  "DO-NOT-ACCEPT"
+};
+
+#define NUM_DISCRESULT_TYPES   5
+#define discresulttype2str(t)  \
+  ((t < NUM_DISCRESULT_TYPES) ? discresulttypestr[t] : "UNKNOWN-DISCRESULT-TYPE")
+
+static const char *discresulttypestr[NUM_DISCRESULT_TYPES] = {
+  "UNKNOWN-DISCRESULT-TYPE",
+  "LOST-CARRIER",
+  "GENERAL-ERROR",
+  "ADMIN-SHUTDOWN",
+  "REQUEST"
+};
+
+static void dissect_unknown(const u_char *, int, frame_data *, proto_tree *);
+static void dissect_cntrl_req(const u_char *, int, frame_data *, proto_tree *);
+static void dissect_cntrl_reply(const u_char *, int, frame_data *, proto_tree *);
+static void dissect_stop_req(const u_char *, int, frame_data *, proto_tree *);
+static void dissect_stop_reply(const u_char *, int, frame_data *, proto_tree *);
+static void dissect_echo_req(const u_char *, int, frame_data *, proto_tree *);
+static void dissect_echo_reply(const u_char *, int, frame_data *, proto_tree *);
+static void dissect_out_req(const u_char *, int, frame_data *, proto_tree *);
+static void dissect_out_reply(const u_char *, int, frame_data *, proto_tree *);
+static void dissect_in_req(const u_char *, int, frame_data *, proto_tree *);
+static void dissect_in_reply(const u_char *, int, frame_data *, proto_tree *);
+static void dissect_in_connected(const u_char *, int, frame_data *, proto_tree *);
+static void dissect_clear_req(const u_char *, int, frame_data *, proto_tree *);
+static void dissect_disc_notify(const u_char *, int, frame_data *, proto_tree *);
+static void dissect_error_notify(const u_char *, int, frame_data *, proto_tree *);
+static void dissect_set_link(const u_char *, int, frame_data *, proto_tree *);
+
+#define NUM_CNTRL_TYPES                16
+#define cntrltype2str(t)       \
+  ((t < NUM_CNTRL_TYPES) ? strfuncs[t].str : "UNKNOWN-CONTROL-TYPE")
+
+static struct strfunc {
+  const char * str;
+  void          (*func)(const u_char *, int, frame_data *, proto_tree *);
+} strfuncs[NUM_CNTRL_TYPES] = {
+  {"UNKNOWN-CONTROL-TYPE",    dissect_unknown      },
+  {"START-CONTROL-REQUEST",   dissect_cntrl_req    },
+  {"START-CONTROL-REPLY",     dissect_cntrl_reply  },
+  {"STOP-CONTROL-REQUEST",    dissect_stop_req     },
+  {"STOP-CONTROL-REPLY",      dissect_stop_reply   },
+  {"ECHO-REQUEST",            dissect_echo_req     },
+  {"ECHO-REPLY",              dissect_echo_reply   },
+  {"OUTGOING-CALL-REQUEST",   dissect_out_req      },
+  {"OUTGOING-CALL-REPLY",     dissect_out_reply    },
+  {"INCOMING-CALL-REQUEST",   dissect_in_req       },
+  {"INCOMING-CALL-REPLY",     dissect_in_reply     },
+  {"INCOMING-CALL-CONNECTED", dissect_in_connected },
+  {"CLEAR-CALL-REQUEST",      dissect_clear_req    },
+  {"DISCONNECT-NOTIFY",       dissect_disc_notify  },
+  {"ERROR-NOTIFY",            dissect_error_notify },
+  {"SET-LINK",                dissect_set_link     }
+};
+
+struct pptp_hdr
+{
+  guint16      len;
+  guint16      type;
+  guint32      cookie;
+  guint16      cntrl_type;
+  guint16      resv;
+};
+
+struct cntrl_req
+{
+  guint8       major_ver;
+  guint8       minor_ver;
+  guint16      resv;
+  guint32      frame;
+  guint32      bearer;
+  guint16      max_chan;
+  guint16      firm_rev;
+  guint8       host[64];
+  guint8       vendor[64];
+};
+
+struct cntrl_reply
+{
+  guint8       major_ver;
+  guint8       minor_ver;
+  guint8       result;
+  guint8       error;
+  guint32      frame;
+  guint32      bearer;
+  guint16      max_chan;
+  guint16      firm_rev;
+  guint8       host[64];
+  guint8       vendor[64];
+};
+
+struct stop_req
+{
+  guint8       reason;
+  guint8       resv0;
+  guint16      resv1;
+};
+
+struct stop_reply
+{
+  guint8       result;
+  guint8       error;
+  guint16      resv;
+};
+
+struct echo_req
+{
+  guint32      ident;
+};
+
+struct echo_reply
+{
+  guint32      ident;
+  guint8       result;
+  guint8       error;
+  guint16      resv;
+};
+
+struct out_req
+{
+  guint16      call_id;
+  guint16      call_serial;
+  guint32      min_bps;
+  guint32      max_bps;
+  guint32      bearer;
+  guint32      frame;
+  guint16      win_size;
+  guint16      delay;
+  guint16      phone_len;
+  guint16      resv;
+  guint8       phone[64];
+  guint8       subaddr[64];
+};
+
+struct out_reply
+{
+  guint16      call_id;
+  guint16      peer_id;
+  guint8       result;
+  guint8       error;
+  guint16      cause;
+  guint32      speed;
+  guint16      win_size;
+  guint16      delay;
+  guint32      channel_id;
+};
+
+struct in_req
+{
+  guint16      call_id;
+  guint16      call_serial;
+  guint32      bearer;
+  guint32      channel_id;
+  guint16      dialed_len;
+  guint16      dialing_len;
+  guint8       dialed[64];
+  guint8       dialing[64];
+  guint8       subaddr[64];
+};
+
+struct in_reply
+{
+  guint16      call_id;
+  guint16      peer_id;
+  guint8       result;
+  guint8       error;
+  guint16      win_size;
+  guint16      delay;
+  guint16      resv;
+};
+
+struct in_connected
+{
+  guint16      peer_id;
+  guint16      resv;
+  guint32      speed;
+  guint16      win_size;
+  guint16      delay;
+  guint32      frame;
+};
+
+struct clear_req
+{
+  guint16      call_id;
+  guint16      resv;
+};
+
+struct disc_notify
+{
+  guint16      call_id;
+  guint8       result;
+  guint8       error;
+  guint16      cause;
+  guint16      resv;
+  guint8       stats[128];
+};
+
+struct error_notify
+{
+  guint16      peer_id;
+  guint16      resv;
+  guint32      crc;
+  guint32      frame;
+  guint32      hardware;
+  guint32      buffer;
+  guint32      timeout;
+  guint32      alignment;
+};
+
+struct set_link
+{
+  guint16      peer_id;
+  guint16      resv;
+  guint32      send_acm;
+  guint32      recv_acm;
+};
+
+void
+dissect_pptp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
+
+  struct pptp_hdr *    hdr = (struct pptp_hdr *)(pd + offset);
+  guint16              len;
+  guint16              cntrl_type;
+  
+  if (check_col(fd, COL_PROTOCOL))
+    col_add_str(fd, COL_PROTOCOL, "PPTP");
+  
+  len       = pntohs(&hdr->len);
+  cntrl_type = pntohs(&hdr->cntrl_type);
+
+  if (check_col(fd, COL_INFO))
+    col_add_fstr(fd, COL_INFO, "%s", cntrltype2str(cntrl_type));
+    
+  if (fd->cap_len > offset && tree) {
+    guint16            msg_type;
+    proto_item *       ti;
+    proto_tree *       pptp_tree;
+
+    ti = proto_tree_add_item(tree, offset, len, "PPTP Control Channel");
+    pptp_tree = proto_tree_new();
+    proto_item_add_subtree(ti, pptp_tree, ETT_PPTP);
+    
+    proto_tree_add_item(pptp_tree, offset, sizeof(hdr->len), 
+                       "Length: %u", len);
+    offset += sizeof(hdr->len);
+
+    msg_type = pntohs(&hdr->type);
+    proto_tree_add_item(pptp_tree, offset, sizeof(hdr->type),
+                       "Message type: %s (%u)", msgtype2str(msg_type), msg_type);
+    offset += sizeof(hdr->type);
+
+    proto_tree_add_item(pptp_tree, offset, sizeof(hdr->cookie),
+                       "Cookie: %#08x", pntohl(&hdr->cookie));
+    offset += sizeof(hdr->cookie);
+    
+    proto_tree_add_item(pptp_tree, offset, sizeof(hdr->cntrl_type),
+                       "Control type: %s (%u)", cntrltype2str(cntrl_type), cntrl_type);
+    offset += sizeof(hdr->cntrl_type);
+
+    proto_tree_add_item(pptp_tree, offset, sizeof(hdr->resv),
+                       "Reserved: %u", pntohs(&hdr->resv));
+    offset += sizeof(hdr->resv);
+
+    if (cntrl_type < NUM_CNTRL_TYPES)
+      ( *(strfuncs[cntrl_type].func))(pd, offset, fd, pptp_tree);
+    else
+      dissect_data(pd, offset, fd, pptp_tree);
+  }
+}
+
+static void
+dissect_unknown(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
+  dissect_data(pd, offset, fd, tree);
+}
+
+static void
+dissect_cntrl_req(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
+
+  struct cntrl_req *   hdr = (struct cntrl_req *)(pd + offset);
+  guint32              frame;
+  guint32              bearer;
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->major_ver) + sizeof(hdr->minor_ver), 
+                     "Protocol version: %u.%u", hdr->major_ver, hdr->minor_ver );
+  offset += sizeof(hdr->major_ver) + sizeof(hdr->minor_ver);
+
+  proto_tree_add_item(tree, offset, sizeof(hdr->resv),
+                     "Reserved: %u", hdr->resv);
+  offset += sizeof(hdr->resv);
+
+  frame = pntohl(&hdr->frame);
+  proto_tree_add_item(tree, offset, sizeof(hdr->frame),
+                     "Framing capabilities: %s (%u)", frametype2str(frame), frame);
+  offset += sizeof(hdr->frame);
+
+  bearer = pntohl(&hdr->bearer);
+  proto_tree_add_item(tree, offset, sizeof(hdr->bearer),
+                     "Bearer capabilities: %s (%u)", bearertype2str(bearer), bearer);
+  offset += sizeof(hdr->bearer);
+
+  proto_tree_add_item(tree, offset, sizeof(hdr->max_chan),
+                     "Maximum channels: %u", hdr->max_chan);
+  offset += sizeof(hdr->max_chan);
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->firm_rev),
+                     "Firmware revision: %u", hdr->firm_rev);
+  offset += sizeof(hdr->firm_rev);
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->host),
+                     "Hostname: %s", hdr->host);
+  offset += sizeof(hdr->host);
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->vendor),
+                     "Vendor: %s", hdr->vendor);
+}
+
+static void
+dissect_cntrl_reply(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
+  struct cntrl_reply * hdr = (struct cntrl_reply *)(pd + offset);
+  guint32              frame;
+  guint32              bearer;
+
+  proto_tree_add_item(tree, offset, sizeof(hdr->major_ver) + sizeof(hdr->minor_ver), 
+                     "Protocol version: %u.%u", hdr->major_ver, hdr->minor_ver );
+  offset += sizeof(hdr->major_ver) + sizeof(hdr->minor_ver);
+
+  proto_tree_add_item(tree, offset, sizeof(hdr->result),
+                     "Result: %s (%u)", cntrlresulttype2str(hdr->result), hdr->result);
+  offset += sizeof(hdr->result);
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->error),
+                     "Error: %s (%u)", errortype2str(hdr->error), hdr->error);
+  offset += sizeof(hdr->error);
+  
+  frame = pntohl(&hdr->frame);
+  proto_tree_add_item(tree, offset, sizeof(hdr->frame),
+                     "Framing capabilities: %s (%u)", frametype2str(frame), frame);
+  offset += sizeof(hdr->frame);
+
+  bearer = pntohl(&hdr->bearer);
+  proto_tree_add_item(tree, offset, sizeof(hdr->bearer),
+                     "Bearer capabilities: %s (%u)", bearertype2str(bearer), bearer);
+  offset += sizeof(hdr->bearer);
+
+  proto_tree_add_item(tree, offset, sizeof(hdr->max_chan),
+                     "Maximum channels: %u", hdr->max_chan);
+  offset += sizeof(hdr->max_chan);
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->firm_rev),
+                     "Firmware revision: %u", hdr->firm_rev);
+  offset += sizeof(hdr->firm_rev);
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->host),
+                     "Hostname: %s", hdr->host);
+  offset += sizeof(hdr->host);
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->vendor),
+                     "Vendor: %s", hdr->vendor);
+}
+
+static void
+dissect_stop_req(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
+  struct stop_req *    hdr = (struct stop_req *)(pd + offset);
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->reason),
+                     "Reason: %s (%u)", reasontype2str(hdr->reason), hdr->reason);
+  offset += sizeof(hdr->reason);
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->resv0),
+                     "Reserved: %u", hdr->resv0);
+  offset += sizeof(hdr->resv0);
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->resv1),
+                     "Reserved: %u", hdr->resv1);
+  offset += sizeof(hdr->resv1);
+}
+
+static void
+dissect_stop_reply(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
+  struct stop_reply *  hdr = (struct stop_reply *)(pd + offset);
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->result),
+                     "Result: %s (%u)", stopresulttype2str(hdr->result), hdr->result);
+  offset += sizeof(hdr->result);
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->error),
+                     "Error: %s (%u)", errortype2str(hdr->error), hdr->error);
+  offset += sizeof(hdr->error);
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->resv),
+                     "Reserved: %u", hdr->resv);
+  offset += sizeof(hdr->resv);
+}
+
+static void
+dissect_echo_req(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
+  struct echo_req *    hdr = (struct echo_req *)(pd + offset);
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->ident),
+                     "Identifier: %u", hdr->ident);
+  offset += sizeof(hdr->ident);
+}
+
+static void
+dissect_echo_reply(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
+  struct echo_reply *  hdr = (struct echo_reply *)(pd + offset);
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->ident),
+                     "Identifier: %u", hdr->ident);
+  offset += sizeof(hdr->ident);
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->result),
+                     "Result: %s (%u)", echoresulttype2str(hdr->result), hdr->result);
+  offset += sizeof(hdr->result);
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->error),
+                     "Error: %s (%u)", errortype2str(hdr->error), hdr->error);
+  offset += sizeof(hdr->error);
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->resv),
+                     "Reserved: %u", hdr->resv);
+  offset += sizeof(hdr->resv);
+}
+
+static void
+dissect_out_req(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
+  struct out_req *     hdr = (struct out_req *)(pd + offset);
+  guint32              bearer;
+  guint32              frame;
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->call_id),
+                     "Call ID: %u", hdr->call_id);
+  offset += sizeof(hdr->call_id);
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->call_serial),
+                     "Call Serial Number: %u", hdr->call_serial);
+  offset += sizeof(hdr->call_serial);
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->min_bps),
+                     "Minimum BPS: %u", hdr->min_bps);
+  offset += sizeof(hdr->min_bps);
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->max_bps),
+                     "Maximum BPS: %u", hdr->max_bps);
+  offset += sizeof(hdr->max_bps);
+  
+  bearer = pntohl(&hdr->bearer);
+  proto_tree_add_item(tree, offset, sizeof(hdr->bearer),
+                     "Bearer capabilities: %s (%u)", bearertype2str(bearer), bearer);
+  offset += sizeof(hdr->bearer);
+
+  frame = pntohl(&hdr->frame);
+  proto_tree_add_item(tree, offset, sizeof(hdr->frame),
+                     "Framing capabilities: %s (%u)", frametype2str(frame), frame);
+  offset += sizeof(hdr->frame);
+
+  proto_tree_add_item(tree, offset, sizeof(hdr->win_size),
+                     "Receive window size: %u", hdr->win_size);
+  offset += sizeof(hdr->win_size);
+
+  proto_tree_add_item(tree, offset, sizeof(hdr->delay),
+                     "Processing delay: %u", hdr->delay);
+  offset += sizeof(hdr->delay);
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->phone_len),
+                     "Phone number length: %u", hdr->phone_len);
+  offset += sizeof(hdr->phone_len);
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->resv),
+                     "Reserved: %u", hdr->resv);
+  offset += sizeof(hdr->resv);
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->phone),
+                     "Phone number: %s", hdr->phone);
+  offset += sizeof(hdr->phone);
+
+  proto_tree_add_item(tree, offset, sizeof(hdr->subaddr),
+                     "Subaddress: %s", hdr->subaddr);
+  offset += sizeof(hdr->subaddr);
+}
+
+static void
+dissect_out_reply(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
+  struct out_reply *   hdr = (struct out_reply *)(pd + offset);
+
+  proto_tree_add_item(tree, offset, sizeof(hdr->call_id),
+                     "Call ID: %u", hdr->call_id);
+  offset += sizeof(hdr->call_id);
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->peer_id),
+                     "Peer's call ID: %u", hdr->peer_id);
+  offset += sizeof(hdr->peer_id);
+
+  proto_tree_add_item(tree, offset, sizeof(hdr->result),
+                     "Result: %s (%u)", outresulttype2str(hdr->result), hdr->result);
+  offset += sizeof(hdr->result);
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->error),
+                     "Error: %s (%u)", errortype2str(hdr->error), hdr->error);
+  offset += sizeof(hdr->error);
+
+  proto_tree_add_item(tree, offset, sizeof(hdr->cause),
+                     "Cause code: %u", hdr->cause);
+  offset += sizeof(hdr->cause);
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->speed),
+                     "Connect speed: %u", hdr->speed);
+  offset += sizeof(hdr->speed);
+
+  proto_tree_add_item(tree, offset, sizeof(hdr->win_size),
+                     "Receive window size: %u", hdr->win_size);
+  offset += sizeof(hdr->win_size);
+
+  proto_tree_add_item(tree, offset, sizeof(hdr->delay),
+                     "Processing delay: %u", hdr->delay);
+  offset += sizeof(hdr->delay);
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->channel_id),
+                     "Physical channel ID: %u", hdr->channel_id);
+  offset += sizeof(hdr->channel_id);
+}
+
+
+static void
+dissect_in_req(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
+  struct in_req *      hdr = (struct in_req *)(pd + offset);
+  guint32              bearer;
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->call_id),
+                     "Call ID: %u", hdr->call_id);
+  offset += sizeof(hdr->call_id);
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->call_serial),
+                     "Call serial number: %u", hdr->call_serial);
+  offset += sizeof(hdr->call_serial);
+  
+  bearer = pntohl(&hdr->bearer);
+  proto_tree_add_item(tree, offset, sizeof(hdr->bearer),
+                     "Bearer capabilities: %s (%u)", bearertype2str(bearer), bearer);
+  offset += sizeof(hdr->bearer);
+
+  proto_tree_add_item(tree, offset, sizeof(hdr->channel_id),
+                     "Physical channel ID: %u", hdr->channel_id);
+  offset += sizeof(hdr->channel_id);
+
+  proto_tree_add_item(tree, offset, sizeof(hdr->dialed_len),
+                     "Dialed number length: %u", hdr->dialed_len);
+  offset += sizeof(hdr->dialed_len);
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->dialing_len),
+                     "Dialing number length: %u", hdr->dialing_len);
+  offset += sizeof(hdr->dialing_len);
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->dialed),
+                     "Dialed number: %s", hdr->dialed);
+  offset += sizeof(hdr->dialed);
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->dialing),
+                     "Dialing number: %s", hdr->dialing);
+  offset += sizeof(hdr->dialing);
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->subaddr),
+                     "Subaddress: %s", hdr->subaddr);
+  offset += sizeof(hdr->subaddr);
+}
+
+static void
+dissect_in_reply(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
+  struct in_reply *    hdr = (struct in_reply *)(pd + offset);
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->call_id),
+                     "Call ID: %u", hdr->call_id);
+  offset += sizeof(hdr->call_id);
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->peer_id),
+                     "Peer's call ID: %u", hdr->peer_id);
+  offset += sizeof(hdr->peer_id);
+
+  proto_tree_add_item(tree, offset, sizeof(hdr->result),
+                     "Result: %s (%u)", inresulttype2str(hdr->result), hdr->result);
+  offset += sizeof(hdr->result);
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->error),
+                     "Error: %s (%u)", errortype2str(hdr->error), hdr->error);
+  offset += sizeof(hdr->error);
+
+  proto_tree_add_item(tree, offset, sizeof(hdr->win_size),
+                     "Receive window size: %u", hdr->win_size);
+  offset += sizeof(hdr->win_size);
+
+  proto_tree_add_item(tree, offset, sizeof(hdr->delay),
+                     "Processing delay: %u", hdr->delay);
+  offset += sizeof(hdr->delay);
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->resv),
+                     "Reserved: %u", hdr->resv);
+  offset += sizeof(hdr->resv);
+}
+
+static void
+dissect_in_connected(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
+  struct in_connected *        hdr = (struct in_connected *)(pd + offset);
+  guint32              frame;
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->peer_id),
+                     "Peer's call ID: %u", hdr->peer_id);
+  offset += sizeof(hdr->peer_id);
+
+  proto_tree_add_item(tree, offset, sizeof(hdr->resv),
+                     "Reserved: %u", hdr->resv);
+  offset += sizeof(hdr->resv);
+
+  proto_tree_add_item(tree, offset, sizeof(hdr->speed),
+                     "Connect speed: %u", hdr->speed);
+  offset += sizeof(hdr->speed);
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->win_size),
+                     "Receive window size: %u", hdr->win_size);
+  offset += sizeof(hdr->win_size);
+
+  proto_tree_add_item(tree, offset, sizeof(hdr->delay),
+                     "Processing delay: %u", hdr->delay);
+  offset += sizeof(hdr->delay);
+  
+  frame = pntohl(&hdr->frame);
+  proto_tree_add_item(tree, offset, sizeof(hdr->frame),
+                     "Framing capabilities: %s (%u)", frametype2str(frame), frame);
+  offset += sizeof(hdr->frame);
+}
+
+static void
+dissect_clear_req(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
+  struct clear_req *   hdr = (struct clear_req *)(pd + offset);
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->call_id),
+                     "Call ID: %u", hdr->call_id);
+  offset += sizeof(hdr->call_id);
+
+  proto_tree_add_item(tree, offset, sizeof(hdr->resv),
+                     "Reserved: %u", hdr->resv);
+  offset += sizeof(hdr->resv);
+}
+
+static void
+dissect_disc_notify(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
+  struct disc_notify * hdr = (struct disc_notify *)(pd + offset);
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->call_id),
+                     "Call ID: %u", hdr->call_id);
+  offset += sizeof(hdr->call_id);
+
+  proto_tree_add_item(tree, offset, sizeof(hdr->result),
+                     "Result: %s (%u)", discresulttype2str(hdr->result), hdr->result);
+  offset += sizeof(hdr->result);
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->error),
+                     "Error: %s (%u)", errortype2str(hdr->error), hdr->error);
+  offset += sizeof(hdr->error);
+
+  proto_tree_add_item(tree, offset, sizeof(hdr->cause),
+                     "Cause code: %u", hdr->cause);
+  offset += sizeof(hdr->cause);
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->resv),
+                     "Reserved: %u", hdr->resv);
+  offset += sizeof(hdr->resv);
+
+  proto_tree_add_item(tree, offset, sizeof(hdr->stats),
+                     "Call statistics: %s", hdr->stats);
+  offset += sizeof(hdr->stats);
+}
+
+static void
+dissect_error_notify(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
+  struct error_notify *        hdr = (struct error_notify *)(pd + offset);
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->peer_id),
+                     "Peer's call ID: %u", hdr->peer_id);
+  offset += sizeof(hdr->peer_id);
+
+  proto_tree_add_item(tree, offset, sizeof(hdr->resv),
+                     "Reserved: %u", hdr->resv);
+  offset += sizeof(hdr->resv);
+
+  proto_tree_add_item(tree, offset, sizeof(hdr->crc),
+                     "CRC errors: %u", hdr->crc);
+  offset += sizeof(hdr->crc);
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->frame),
+                     "Framing errors: %u", hdr->frame);
+  offset += sizeof(hdr->frame);
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->hardware),
+                     "Hardware overruns: %u", hdr->hardware);
+  offset += sizeof(hdr->hardware);
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->buffer),
+                     "Buffer overruns: %u", hdr->buffer);
+  offset += sizeof(hdr->buffer);
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->timeout),
+                     "Time-out errors: %u", hdr->timeout);
+  offset += sizeof(hdr->timeout);
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->alignment),
+                     "Alignment errors: %u", hdr->alignment);
+  offset += sizeof(hdr->alignment);
+}
+
+static void
+dissect_set_link(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
+  struct set_link *    hdr = (struct set_link *)(pd + offset);
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->peer_id),
+                     "Peer's call ID: %u", hdr->peer_id);
+  offset += sizeof(hdr->peer_id);
+
+  proto_tree_add_item(tree, offset, sizeof(hdr->resv),
+                     "Reserved: %u", hdr->resv);
+  offset += sizeof(hdr->resv);
+
+  proto_tree_add_item(tree, offset, sizeof(hdr->send_acm),
+                     "Send ACCM: %#08x", hdr->send_acm);
+  offset += sizeof(hdr->send_acm);
+  
+  proto_tree_add_item(tree, offset, sizeof(hdr->recv_acm),
+                     "Recv ACCM: %#08x", hdr->recv_acm);
+  offset += sizeof(hdr->recv_acm);
+}
index 128ce650746c47d4d3f1a5aec49cd033c035e72f..23d874f47b7dfc35ee8a92c27025e33faec51ff6 100644 (file)
@@ -1,7 +1,7 @@
 /* packet-tcp.c
  * Routines for TCP packet disassembly
  *
- * $Id: packet-tcp.c,v 1.23 1999/06/02 01:28:47 guy Exp $
+ * $Id: packet-tcp.c,v 1.24 1999/06/11 15:30:40 gram Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -73,6 +73,7 @@ static int   info_len;
 #define TCP_PORT_NBSS     139
 #define TCP_PORT_PRINTER  515
 #define TCP_ALT_PORT_HTTP 8080
+#define TCP_PORT_PPTP     1723
 
 /* TCP structs and definitions */
 
@@ -474,6 +475,9 @@ dissect_tcp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
     } else if (PORT_IS(TCP_PORT_NNTP)) {
       pi.match_port = TCP_PORT_NNTP;
       dissect_nntp(pd, offset, fd, tree, payload);
+    } else if (PORT_IS(TCP_PORT_PPTP)) {
+      pi.match_port = TCP_PORT_PPTP;
+      dissect_pptp(pd, offset, fd, tree);
     } else if (PORT_IS(TCP_PORT_HTTP) || PORT_IS(TCP_ALT_PORT_HTTP))
       dissect_http(pd, offset, fd, tree);
     else if (PORT_IS(TCP_PORT_NBSS)) {
index 7d7a499c74452033c1b9ac51e1ebca35e2c5ffb8..f8b633a33b55de1328984d2a56cd41fe552aea3d 100644 (file)
@@ -1,7 +1,7 @@
 /* packet-udp.c
  * Routines for UDP packet disassembly
  *
- * $Id: packet-udp.c,v 1.16 1999/05/12 05:56:42 gram Exp $
+ * $Id: packet-udp.c,v 1.17 1999/06/11 15:30:40 gram Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -64,6 +64,7 @@ typedef struct _e_udphdr {
 #define UDP_PORT_NBNS  137
 #define UDP_PORT_NBDGM 138
 #define UDP_PORT_SNMP   161
+#define UDP_PORT_ISAKMP        500
 #define UDP_PORT_RIP    520
 #define UDP_PORT_VINES 573
 
@@ -212,6 +213,9 @@ dissect_udp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
     case UDP_PORT_DNS:
       dissect_dns(pd, offset, fd, tree);
       break;
+    case UDP_PORT_ISAKMP:
+      dissect_isakmp(pd, offset, fd, tree);
+      break;
     case UDP_PORT_RIP:
       /* we should check the source port too (RIP: UDP src and dst port 520) */
       dissect_rip(pd, offset, fd, tree);
index f2ee3b5045497116a12849edd1cc1f1815dd13e5..160cd7f97952588b1af733e3cb304077516d981f 100644 (file)
--- a/packet.h
+++ b/packet.h
@@ -1,7 +1,7 @@
 /* packet.h
  * Definitions for packet disassembly structures and routines
  *
- * $Id: packet.h,v 1.56 1999/05/13 16:42:43 gram Exp $
+ * $Id: packet.h,v 1.57 1999/06/11 15:30:40 gram Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -84,6 +84,7 @@ typedef struct _packet_counts {
   gint           tcp;
   gint           udp;
   gint           ospf;
+  gint           gre;
   gint           other;
   gint           total;
 } packet_counts;
@@ -174,6 +175,9 @@ enum {
        ETT_DNS_QD,
        ETT_DNS_ANS,
        ETT_DNS_RR,
+       ETT_ISAKMP,
+       ETT_ISAKMP_FLAGS,
+       ETT_ISAKMP_PAYLOAD,
        ETT_RIP,
        ETT_RIP_VEC,
        ETT_OSPF,
@@ -236,6 +240,14 @@ enum {
        ETT_SMB_CAPS,
        ETT_SMB_RAWMODE,
        ETT_SMB_AFLAGS,
+       ETT_PPTP,
+       ETT_GRE,
+       ETT_GRE_FLAGS,
+       ETT_PPPOED,
+       ETT_PPPOED_TAGS,
+       ETT_PPPOES,
+       ETT_LCP,
+       ETT_IPCP,
        NUM_TREE_TYPES  /* last item number plus one */
 };
 
@@ -374,6 +386,9 @@ void dissect_nwlink_dg(const u_char *, int, frame_data *, proto_tree *, int);
 void dissect_osi(const u_char *, int, frame_data *, proto_tree *);
 void dissect_ospf(const u_char *, int, frame_data *, proto_tree *);
 void dissect_ospf_hello(const u_char *, int, frame_data *, proto_tree *);
+void dissect_pppoed(const u_char *, int, frame_data *, proto_tree *);
+void dissect_pppoes(const u_char *, int, frame_data *, proto_tree *);
+void dissect_isakmp(const u_char *, int, frame_data *, proto_tree *);
 void dissect_rip(const u_char *, int, frame_data *, proto_tree *);
 void dissect_snmp(const u_char *, int, frame_data *, proto_tree *);
 void dissect_tcp(const u_char *, int, frame_data *, proto_tree *);
@@ -387,6 +402,7 @@ void dissect_vines_icp(const u_char *, int, frame_data *, proto_tree *);
 void dissect_vines_ipc(const u_char *, int, frame_data *, proto_tree *);
 void dissect_vines_rtp(const u_char *, int, frame_data *, proto_tree *);
 void dissect_vines_spp(const u_char *, int, frame_data *, proto_tree *);
+void dissect_payload_ppp(const u_char *, int, frame_data *, proto_tree *);
 
 void dissect_ftp(const u_char *, int, frame_data *, proto_tree *, int);
 void dissect_ftpdata(const u_char *, int, frame_data *, proto_tree *, int);
@@ -395,6 +411,8 @@ void dissect_nntp(const u_char *, int, frame_data *, proto_tree *, int);
 void dissect_pop(const u_char *, int, frame_data *, proto_tree *, int);
 void dissect_smb(const u_char *, int, frame_data *, proto_tree *, int);
 void dissect_telnet(const u_char *, int, frame_data *, proto_tree *, int);
+void dissect_pptp(const u_char *, int, frame_data *, proto_tree *);
+void dissect_gre(const u_char *, int, frame_data *, proto_tree *);
 
 void init_dissect_udp(void);