Ethereal-dev: [ethereal-dev] Patch to "packet-ip.c" to handle alignement for I[GC]MP

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

From: guy@xxxxxxxxxx (Guy Harris)
Date: Sat, 3 Oct 1998 01:50:05 -0700 (PDT)
FDDI, for example, can hand you quite badly misaligned packets; IP
copies the header to fix the alignment, but ICMP and IGMP don't:

*** packet-ip.c	1998/09/27 04:09:30	1.4
--- packet-ip.c	1998/10/03 08:48:38
***************
*** 181,203 ****
  
  void
  dissect_icmp(const u_char *pd, int offset, frame_data *fd, GtkTree *tree) {
!   e_icmp    *ih;
    GtkWidget *icmp_tree, *ti;
    guint16    cksum;
    gchar      type_str[64], code_str[64] = "";
  
!   ih = (e_icmp *) &pd[offset];
    /* To do: check for runts, errs, etc. */
!   cksum = ntohs(ih->icmp_cksum);
    
!   switch (ih->icmp_type) {
      case ICMP_ECHOREPLY:
        strcpy(type_str, "Echo (ping) reply");
        break;
      case ICMP_UNREACH:
        strcpy(type_str, "Destination unreachable");
!       if (ih->icmp_code < 12) {
!         sprintf(code_str, "(%s)", unreach_str[ih->icmp_code]);
        } else {
          strcpy(code_str, "(Unknown - error?)");
        }
--- 181,204 ----
  
  void
  dissect_icmp(const u_char *pd, int offset, frame_data *fd, GtkTree *tree) {
!   e_icmp     ih;
    GtkWidget *icmp_tree, *ti;
    guint16    cksum;
    gchar      type_str[64], code_str[64] = "";
  
!   /* Avoids alignment problems on many architectures. */
!   memcpy(&ih, &pd[offset], sizeof(e_icmp));
    /* To do: check for runts, errs, etc. */
!   cksum = ntohs(ih.icmp_cksum);
    
!   switch (ih.icmp_type) {
      case ICMP_ECHOREPLY:
        strcpy(type_str, "Echo (ping) reply");
        break;
      case ICMP_UNREACH:
        strcpy(type_str, "Destination unreachable");
!       if (ih.icmp_code < 12) {
!         sprintf(code_str, "(%s)", unreach_str[ih.icmp_code]);
        } else {
          strcpy(code_str, "(Unknown - error?)");
        }
***************
*** 207,214 ****
        break;
      case ICMP_REDIRECT:
        strcpy(type_str, "Redirect");
!       if (ih->icmp_code < 4) {
!         sprintf(code_str, "(%s)", redir_str[ih->icmp_code]);
        } else {
          strcpy(code_str, "(Unknown - error?)");
        }
--- 208,215 ----
        break;
      case ICMP_REDIRECT:
        strcpy(type_str, "Redirect");
!       if (ih.icmp_code < 4) {
!         sprintf(code_str, "(%s)", redir_str[ih.icmp_code]);
        } else {
          strcpy(code_str, "(Unknown - error?)");
        }
***************
*** 218,233 ****
        break;
      case ICMP_TIMXCEED:
        strcpy(type_str, "Time-to-live exceeded");
!       if (ih->icmp_code < 2) {
!         sprintf(code_str, "(%s)", ttl_str[ih->icmp_code]);
        } else {
          strcpy(code_str, "(Unknown - error?)");
        }
        break;
      case ICMP_PARAMPROB:
        strcpy(type_str, "Parameter problem");
!       if (ih->icmp_code < 2) {
!         sprintf(code_str, "(%s)", par_str[ih->icmp_code]);
        } else {
          strcpy(code_str, "(Unknown - error?)");
        }
--- 219,234 ----
        break;
      case ICMP_TIMXCEED:
        strcpy(type_str, "Time-to-live exceeded");
!       if (ih.icmp_code < 2) {
!         sprintf(code_str, "(%s)", ttl_str[ih.icmp_code]);
        } else {
          strcpy(code_str, "(Unknown - error?)");
        }
        break;
      case ICMP_PARAMPROB:
        strcpy(type_str, "Parameter problem");
!       if (ih.icmp_code < 2) {
!         sprintf(code_str, "(%s)", par_str[ih.icmp_code]);
        } else {
          strcpy(code_str, "(Unknown - error?)");
        }
***************
*** 259,284 ****
      icmp_tree = gtk_tree_new();
      add_subtree(ti, icmp_tree, ETT_ICMP);
      add_item_to_tree(icmp_tree, offset,      1, "Type: %d (%s)",
!       ih->icmp_type, type_str);
      add_item_to_tree(icmp_tree, offset +  1, 1, "Code: %d %s",
!       ih->icmp_code, code_str);
      add_item_to_tree(icmp_tree, offset +  2, 2, "Checksum: 0x%04x",
!       ih->icmp_cksum);
    }
  }
  
  void
  dissect_igmp(const u_char *pd, int offset, frame_data *fd, GtkTree *tree) {
!   e_igmp    *ih;
    GtkWidget *igmp_tree, *ti;
    guint16    cksum;
    gchar      type_str[64] = "";
  
!   ih = (e_igmp *) &pd[offset];
    /* To do: check for runts, errs, etc. */
!   cksum = ntohs(ih->igmp_cksum);
    
!   switch (ih->igmp_t) {
      case IGMP_M_QRY:
        strcpy(type_str, "Router query");
        break;
--- 260,286 ----
      icmp_tree = gtk_tree_new();
      add_subtree(ti, icmp_tree, ETT_ICMP);
      add_item_to_tree(icmp_tree, offset,      1, "Type: %d (%s)",
!       ih.icmp_type, type_str);
      add_item_to_tree(icmp_tree, offset +  1, 1, "Code: %d %s",
!       ih.icmp_code, code_str);
      add_item_to_tree(icmp_tree, offset +  2, 2, "Checksum: 0x%04x",
!       ih.icmp_cksum);
    }
  }
  
  void
  dissect_igmp(const u_char *pd, int offset, frame_data *fd, GtkTree *tree) {
!   e_igmp     ih;
    GtkWidget *igmp_tree, *ti;
    guint16    cksum;
    gchar      type_str[64] = "";
  
!   /* Avoids alignment problems on many architectures. */
!   memcpy(&ih, &pd[offset], sizeof(e_igmp));
    /* To do: check for runts, errs, etc. */
!   cksum = ntohs(ih.igmp_cksum);
    
!   switch (ih.igmp_t) {
      case IGMP_M_QRY:
        strcpy(type_str, "Router query");
        break;
***************
*** 317,330 ****
      igmp_tree = gtk_tree_new();
      add_subtree(ti, igmp_tree, ETT_IGMP);
      add_item_to_tree(igmp_tree, offset,     1, "Version: %d",
!       ih->igmp_v);
      add_item_to_tree(igmp_tree, offset    , 1, "Type: %d (%s)",
!       ih->igmp_t, type_str);
      add_item_to_tree(igmp_tree, offset + 1, 1, "Unused: 0x%02x",
!       ih->igmp_unused);
      add_item_to_tree(igmp_tree, offset + 2, 2, "Checksum: 0x%04x",
!       ih->igmp_cksum);
      add_item_to_tree(igmp_tree, offset + 4, 4, "Group address: %s",
!       ip_to_str((guint8 *) &ih->igmp_gaddr));
    }
  }
--- 319,332 ----
      igmp_tree = gtk_tree_new();
      add_subtree(ti, igmp_tree, ETT_IGMP);
      add_item_to_tree(igmp_tree, offset,     1, "Version: %d",
!       ih.igmp_v);
      add_item_to_tree(igmp_tree, offset    , 1, "Type: %d (%s)",
!       ih.igmp_t, type_str);
      add_item_to_tree(igmp_tree, offset + 1, 1, "Unused: 0x%02x",
!       ih.igmp_unused);
      add_item_to_tree(igmp_tree, offset + 2, 2, "Checksum: 0x%04x",
!       ih.igmp_cksum);
      add_item_to_tree(igmp_tree, offset + 4, 4, "Group address: %s",
!       ip_to_str((guint8 *) &ih.igmp_gaddr));
    }
  }