Ethereal-dev: [Ethereal-dev] ethereal 0.8.12: ICMP checksum, ICMP payload dissect, capture sta

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

From: Santeri Paavolainen <santtu@xxxxxxx>
Date: Sat, 21 Oct 2000 00:31:34 +0300 (EEST)
The attached patch contains the following changes:

	- ICMPv4 checksum checking

	- ICMPv4 payload dissection, if the ICMP type contains IP payload
	  (paramprob etc.)

	- Capture statistics dialog has been changed, it's a lot more
	  better looking and also adding new stats fields will be a lot
	  easier

This patch is against 0.8.12 tree which contains the patches I've posted
before, but it should go pretty smoothly on a vanilla 0.8.12.

-- 
santtu@xxxxxx                    I have become death, destroyer of the worlds.
*** ethereal-0.8.12-orig/capture.c	Tue Aug 22 09:04:40 2000
--- ethereal-0.8.12/capture.c	Sat Oct 21 00:22:30 2000
***************
*** 942,949 ****
  int
  capture(void)
  {
!   GtkWidget  *cap_w, *main_vb, *count_lb, *sctp_lb, *tcp_lb, *udp_lb, *icmp_lb,
!              *ospf_lb, *gre_lb, *netbios_lb, *ipx_lb, *vines_lb, *other_lb, *stop_bt;
    pcap_t     *pch;
    int         pcap_encap;
    int         snaplen;
--- 942,948 ----
  int
  capture(void)
  {
!   GtkWidget  *cap_w, *main_vb, *stop_bt, *counts_tb;
    pcap_t     *pch;
    int         pcap_encap;
    int         snaplen;
***************
*** 951,957 ****
    loop_data   ld;
    bpf_u_int32 netnum, netmask;
    time_t      upd_time, cur_time;
!   int         err, inpkts;
    char        errmsg[4096+1];
  #ifndef _WIN32
    static const char ppamsg[] = "can't find PPA for ";
--- 950,956 ----
    loop_data   ld;
    bpf_u_int32 netnum, netmask;
    time_t      upd_time, cur_time;
!   int         err, inpkts, i;
    char        errmsg[4096+1];
  #ifndef _WIN32
    static const char ppamsg[] = "can't find PPA for ";
***************
*** 970,975 ****
--- 969,993 ----
    int         pipe_fd = -1;
    struct pcap_hdr hdr;
  #endif
+   struct {
+       const gchar *title;
+       gint *value_ptr;
+       GtkWidget *label, *value, *percent;
+   } stats[] = {
+       { "Total", &ld.counts.total },
+       { "SCTP", &ld.counts.sctp },
+       { "TCP", &ld.counts.tcp },
+       { "UDP", &ld.counts.udp },
+       { "ICMP", &ld.counts.icmp },
+       { "OSPF", &ld.counts.ospf },
+       { "GRE", &ld.counts.gre },
+       { "NetBIOS", &ld.counts.netbios },
+       { "IPX", &ld.counts.ipx },
+       { "VINES", &ld.counts.vines },
+       { "Other", &ld.counts.other }
+   };
+ 
+ #define N_STATS (sizeof stats / sizeof stats[0])
  
    /* Initialize Windows Socket if we are in a WIN32 OS
       This needs to be done before querying the interface for network/netmask */
***************
*** 1176,1224 ****
    gtk_container_add(GTK_CONTAINER(cap_w), main_vb);
    gtk_widget_show(main_vb);
  
!   count_lb = gtk_label_new("Count: 0");
!   gtk_box_pack_start(GTK_BOX(main_vb), count_lb, FALSE, FALSE, 3);
!   gtk_widget_show(count_lb);
! 
!   sctp_lb = gtk_label_new("SCTP: 0 (0.0%)");
!   gtk_box_pack_start(GTK_BOX(main_vb), sctp_lb, FALSE, FALSE, 3);
!   gtk_widget_show(sctp_lb);
! 
!   tcp_lb = gtk_label_new("TCP: 0 (0.0%)");
!   gtk_box_pack_start(GTK_BOX(main_vb), tcp_lb, FALSE, FALSE, 3);
!   gtk_widget_show(tcp_lb);
! 
!   udp_lb = gtk_label_new("UDP: 0 (0.0%)");
!   gtk_box_pack_start(GTK_BOX(main_vb), udp_lb, FALSE, FALSE, 3);
!   gtk_widget_show(udp_lb);
! 
!   icmp_lb = gtk_label_new("ICMP: 0 (0.0%)");
!   gtk_box_pack_start(GTK_BOX(main_vb), icmp_lb, FALSE, FALSE, 3);
!   gtk_widget_show(icmp_lb);
! 
!   ospf_lb = gtk_label_new("OSPF: 0 (0.0%)");
!   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);
! 
!   netbios_lb = gtk_label_new("NetBIOS: 0 (0.0%)");
!   gtk_box_pack_start(GTK_BOX(main_vb), netbios_lb, FALSE, FALSE, 3);
!   gtk_widget_show(netbios_lb);
! 
!   ipx_lb = gtk_label_new("IPX: 0 (0.0%)");
!   gtk_box_pack_start(GTK_BOX(main_vb), ipx_lb, FALSE, FALSE, 3);
!   gtk_widget_show(ipx_lb);
! 
!   vines_lb = gtk_label_new("VINES: 0 (0.0%)");
!   gtk_box_pack_start(GTK_BOX(main_vb), vines_lb, FALSE, FALSE, 3);
!   gtk_widget_show(vines_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);
  
    /* allow user to either click a stop button, or the close button on
  	the window to stop a capture in progress. */
--- 1194,1228 ----
    gtk_container_add(GTK_CONTAINER(cap_w), main_vb);
    gtk_widget_show(main_vb);
  
!   /* Individual statistic elements */
!   counts_tb = gtk_table_new(N_STATS, 3, TRUE);
!   gtk_box_pack_start(GTK_BOX(main_vb), counts_tb, TRUE, TRUE, 3);
!   gtk_widget_show(counts_tb);
! 
!   for (i = 0; i < N_STATS; i++) {
!       stats[i].label = gtk_label_new(stats[i].title);
!       gtk_misc_set_alignment(GTK_MISC(stats[i].label), 0.0f, 0.0f);
! 
!       stats[i].value = gtk_label_new("0");
!       gtk_misc_set_alignment(GTK_MISC(stats[i].value), 0.0f, 0.0f);
! 
!       stats[i].percent = gtk_label_new("0.0%");
!       gtk_misc_set_alignment(GTK_MISC(stats[i].percent), 0.0f, 0.0f);
! 
!       gtk_table_attach_defaults(GTK_TABLE(counts_tb),
!                                 stats[i].label, 0, 1, i, i + 1);
! 
!       gtk_table_attach(GTK_TABLE(counts_tb),
!                        stats[i].value,
!                        1, 2, i, i + 1, 0, 0, 5, 0);
! 
!       gtk_table_attach_defaults(GTK_TABLE(counts_tb),
!                                 stats[i].percent, 2, 3, i, i + 1);
! 
!       gtk_widget_show(stats[i].label);
!       gtk_widget_show(stats[i].value);
!       gtk_widget_show(stats[i].percent);
!   }
  
    /* allow user to either click a stop button, or the close button on
  	the window to stop a capture in progress. */
***************
*** 1302,1349 ****
      if (cur_time > upd_time) {
        upd_time = cur_time;
  
!       sprintf(label_str, "Count: %d", ld.counts.total);
!       gtk_label_set(GTK_LABEL(count_lb), label_str);
  
!       sprintf(label_str, "SCTP: %d (%.1f%%)", ld.counts.sctp,
!                 pct(ld.counts.sctp, ld.counts.total));
!       gtk_label_set(GTK_LABEL(sctp_lb), label_str);
! 
!       sprintf(label_str, "TCP: %d (%.1f%%)", ld.counts.tcp,
! 		pct(ld.counts.tcp, ld.counts.total));
!       gtk_label_set(GTK_LABEL(tcp_lb), label_str);
! 
!       sprintf(label_str, "UDP: %d (%.1f%%)", ld.counts.udp,
! 		pct(ld.counts.udp, ld.counts.total));
!       gtk_label_set(GTK_LABEL(udp_lb), label_str);
! 
!       sprintf(label_str, "ICMP: %d (%.1f%%)", ld.counts.icmp,
! 		pct(ld.counts.icmp, ld.counts.total));
!       gtk_label_set(GTK_LABEL(icmp_lb), label_str);
! 
!       sprintf(label_str, "OSPF: %d (%.1f%%)", ld.counts.ospf,
! 		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, "NetBIOS: %d (%.1f%%)", ld.counts.netbios,
! 		pct(ld.counts.netbios, ld.counts.total));
!       gtk_label_set(GTK_LABEL(netbios_lb), label_str);
! 
!       sprintf(label_str, "IPX: %d (%.1f%%)", ld.counts.ipx,
! 		pct(ld.counts.ipx, ld.counts.total));
!       gtk_label_set(GTK_LABEL(ipx_lb), label_str);
! 
!       sprintf(label_str, "VINES: %d (%.1f%%)", ld.counts.vines,
! 		pct(ld.counts.vines, ld.counts.total));
!       gtk_label_set(GTK_LABEL(vines_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);
  
        /* do sync here, too */
        fflush(wtap_dump_file(ld.pdh));
--- 1306,1322 ----
      if (cur_time > upd_time) {
        upd_time = cur_time;
  
!       for (i = 0; i < N_STATS; i++) {
!           snprintf(label_str, sizeof(label_str), "%d",
!                    *stats[i].value_ptr);
! 
!           gtk_label_set(GTK_LABEL(stats[i].value), label_str);
  
!           snprintf(label_str, sizeof(label_str), "(%.1f%%)",
!                    pct(*stats[i].value_ptr, ld.counts.total));
! 
!           gtk_label_set(GTK_LABEL(stats[i].percent), label_str);
!       }
  
        /* do sync here, too */
        fflush(wtap_dump_file(ld.pdh));
*** ethereal-0.8.12-orig/packet-ip.c	Sun Aug 13 17:08:16 2000
--- ethereal-0.8.12/packet-ip.c	Fri Oct 20 22:47:37 2000
***************
*** 1001,1013 ****
  static void
  dissect_icmp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
    e_icmp     ih;
!   proto_tree *icmp_tree;
    proto_item *ti;
    guint16    cksum;
    gchar      type_str[64], code_str[64] = "";
    guint8     num_addrs = 0;
    guint8     addr_entry_size = 0;
    int        i;
  
    OLD_CHECK_DISPLAY_AS_DATA(proto_icmp, pd, offset, fd, tree);
  
--- 1001,1014 ----
  static void
  dissect_icmp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
    e_icmp     ih;
!   proto_tree *icmp_tree = NULL;
    proto_item *ti;
    guint16    cksum;
    gchar      type_str[64], code_str[64] = "";
    guint8     num_addrs = 0;
    guint8     addr_entry_size = 0;
    int        i;
+   gboolean dissect_payload = FALSE;
  
    OLD_CHECK_DISPLAY_AS_DATA(proto_icmp, pd, offset, fd, tree);
  
***************
*** 1027,1035 ****
--- 1028,1038 ----
        } else {
          strcpy(code_str, "(Unknown - error?)");
        }
+       dissect_payload = TRUE;
        break;
      case ICMP_SOURCEQUENCH:
        strcpy(type_str, "Source quench (flow control)");
+       dissect_payload = TRUE;
        break;
      case ICMP_REDIRECT:
        strcpy(type_str, "Redirect");
***************
*** 1038,1043 ****
--- 1041,1047 ----
        } else {
          strcpy(code_str, "(Unknown - error?)");
        }
+       dissect_payload = TRUE;
        break;
      case ICMP_ECHO:
        strcpy(type_str, "Echo (ping) request");
***************
*** 1055,1060 ****
--- 1059,1065 ----
        } else {
          strcpy(code_str, "(Unknown - error?)");
        }
+       dissect_payload = TRUE;
        break;
      case ICMP_PARAMPROB:
        strcpy(type_str, "Parameter problem");
***************
*** 1063,1068 ****
--- 1068,1074 ----
        } else {
          strcpy(code_str, "(Unknown - error?)");
        }
+       dissect_payload = TRUE;
        break;
      case ICMP_TSTAMP:
        strcpy(type_str, "Timestamp request");
***************
*** 1102,1109 ****
  			       ih.icmp_code,
  			       "Code: %u %s",
  			       ih.icmp_code, code_str);
!     proto_tree_add_uint(icmp_tree, hf_icmp_checksum, NullTVB, offset +  2, 2, 
! 			cksum);
  
      /* Decode the second 4 bytes of the packet. */
      switch (ih.icmp_type) {
--- 1108,1123 ----
  			       ih.icmp_code,
  			       "Code: %u %s",
  			       ih.icmp_code, code_str);
! 
!     if (pi.captured_len >= pi.len)
!         proto_tree_add_uint_format(icmp_tree, hf_icmp_checksum, NullTVB,
!                                    offset + 2, 2, cksum,
!                                    "Checksum: 0x%04x (%s)", cksum,
!                                    ip_checksum(pd+offset, END_OF_FRAME) == 0 ?
!                                    "correct" : "incorrect");
!     else
!         proto_tree_add_uint(icmp_tree, hf_icmp_checksum, NullTVB,
!                             offset +  2, 2, cksum);
  
      /* Decode the second 4 bytes of the packet. */
      switch (ih.icmp_type) {
***************
*** 1202,1207 ****
--- 1216,1228 ----
  	break;
      }
    }
+ 
+   /* The packet type contains (some parts of) the original IP packet
+      which caused the ICMP message. We can try to dissect those,
+      also. */
+   if (dissect_payload && tree) {
+       dissect_ip(pd, offset + 8, fd, icmp_tree);
+   }
  }
  
  static void