Ethereal-dev: Re: [ethereal-dev] Re: [ethereal-users] A problem when I use it.

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

From: Guy Harris <gharris@xxxxxxxxxxxx>
Date: Fri, 14 Jan 2000 19:51:29 -0800
> I'll let you know following information
> 
> 1. OS: SunOS 5.7
> 2. GTK+: 1.2.6
> 3. Ethereal: 0.8.1, with GTK+ 1.2.3, with libpcap 0.4, with libz 1.1.3

0. Processor: SPARC

(Right?)

> Program terminated with signal 10, Bus Error.

	...

> #0  dissect_bgp_update (pd=0x1d10f8 "", offset=94, fd=0x1d1169, tree=0x1c3f3c) at packet-bgp.c:324
> 324         len = ntohs(*(guint16 *)p);

Yup, it's another unaligned-pointer dereference.

Apply the attached patch to "packet-bgp.c", recompile, and try again
with that capture file.  (I'm at home, so I only have a PC on which to
try this, and x86 processors, by default, don't fault on unaligned
references.)

Developers: if you're going to cast pointers into the packet buffer into
pointers to anything larger than a byte, *PLEASE* do not then
dereference those pointers directly - use "pntohs()" and "pntohl()"
instead.  Otherwise, you'll run the risk of causing crashes such as this
on most non-x86 systems.
Index: packet-bgp.c
===================================================================
RCS file: /usr/local/cvsroot/ethereal/packet-bgp.c,v
retrieving revision 1.16
diff -c -r1.16 packet-bgp.c
*** packet-bgp.c	2000/01/10 17:32:51	1.16
--- packet-bgp.c	2000/01/15 03:51:34
***************
*** 324,330 ****
      p = &pd[offset + BGP_HEADER_SIZE];	/*XXX*/
  
      /* check for withdrawals */
!     len = ntohs(*(guint16 *)p);
      proto_tree_add_text(tree, p - pd, 2, 
  	"Unfeasible routes length: %u %s", len, (len == 1) ? "byte" : "bytes");
      p += 2;
--- 324,330 ----
      p = &pd[offset + BGP_HEADER_SIZE];	/*XXX*/
  
      /* check for withdrawals */
!     len = pntohs(p);
      proto_tree_add_text(tree, p - pd, 2, 
  	"Unfeasible routes length: %u %s", len, (len == 1) ? "byte" : "bytes");
      p += 2;
***************
*** 347,353 ****
      }
  
      /* check for advertisements */
!     len = ntohs(*(guint16 *)p);
      proto_tree_add_text(tree, p - pd, 2, "Total path attribute length: %u %s", 
              len, (len == 1) ? "byte" : "bytes");
  
--- 347,353 ----
      }
  
      /* check for advertisements */
!     len = pntohs(p);
      proto_tree_add_text(tree, p - pd, 2, "Total path attribute length: %u %s", 
              len, (len == 1) ? "byte" : "bytes");
  
***************
*** 366,372 ****
  	    memcpy(&bgpa, &p[i], sizeof(bgpa));
              /* check for the Extended Length bit */
  	    if (bgpa.bgpa_flags & BGP_ATTR_FLAG_EXTENDED_LENGTH) {
! 		alen = ntohs(*(guint16 *)&p[i + sizeof(bgpa)]);
  		aoff = sizeof(bgpa) + 2;
  	    } else {
  		alen = p[i + sizeof(bgpa)];
--- 366,372 ----
  	    memcpy(&bgpa, &p[i], sizeof(bgpa));
              /* check for the Extended Length bit */
  	    if (bgpa.bgpa_flags & BGP_ATTR_FLAG_EXTENDED_LENGTH) {
! 		alen = pntohs(&p[i + sizeof(bgpa)]);
  		aoff = sizeof(bgpa) + 2;
  	    } else {
  		alen = p[i + sizeof(bgpa)];
***************
*** 455,461 ****
  		ti = proto_tree_add_text(subtree, p - pd + i, alen + aoff,
  			"%s: %u (%u %s)",
  			val_to_str(bgpa.bgpa_type, bgpattr_type, "Unknown"),
! 			ntohl(*(guint32 *)&p[i + aoff]), alen + aoff, 
                          (alen + aoff == 1) ? "byte" : "bytes");
  		break;
  	    case BGPTYPE_LOCAL_PREF:
--- 455,461 ----
  		ti = proto_tree_add_text(subtree, p - pd + i, alen + aoff,
  			"%s: %u (%u %s)",
  			val_to_str(bgpa.bgpa_type, bgpattr_type, "Unknown"),
! 			pntohl(&p[i + aoff]), alen + aoff, 
                          (alen + aoff == 1) ? "byte" : "bytes");
  		break;
  	    case BGPTYPE_LOCAL_PREF:
***************
*** 464,470 ****
  		ti = proto_tree_add_text(subtree, p - pd + i, alen + aoff,
  			"%s: %u (%u %s)",
  			val_to_str(bgpa.bgpa_type, bgpattr_type, "Unknown"),
! 			ntohl(*(guint32 *)&p[i + aoff]), alen + aoff,
                          (alen + aoff == 1) ? "byte" : "bytes");
  		break;
              case BGPTYPE_ATOMIC_AGGREGATE:
--- 464,470 ----
  		ti = proto_tree_add_text(subtree, p - pd + i, alen + aoff,
  			"%s: %u (%u %s)",
  			val_to_str(bgpa.bgpa_type, bgpattr_type, "Unknown"),
! 			pntohl(&p[i + aoff]), alen + aoff,
                          (alen + aoff == 1) ? "byte" : "bytes");
  		break;
              case BGPTYPE_ATOMIC_AGGREGATE:
***************
*** 481,487 ****
  		ti = proto_tree_add_text(subtree, p - pd + i, alen + aoff,
  			"%s: AS: %u origin: %s (%u %s)",
  			val_to_str(bgpa.bgpa_type, bgpattr_type, "Unknown"),
! 			ntohs(*(guint16 *)&p[i + aoff]),
  			ip_to_str(&p[i + aoff + 2]), alen + aoff, 
                          (alen + aoff == 1) ? "byte" : "bytes");
  		break;
--- 481,487 ----
  		ti = proto_tree_add_text(subtree, p - pd + i, alen + aoff,
  			"%s: AS: %u origin: %s (%u %s)",
  			val_to_str(bgpa.bgpa_type, bgpattr_type, "Unknown"),
! 			pntohs(&p[i + aoff]),
  			ip_to_str(&p[i + aoff + 2]), alen + aoff, 
                          (alen + aoff == 1) ? "byte" : "bytes");
  		break;
***************
*** 490,507 ****
  		    goto default_attribute_top;
  
                  /* check for well-known communities */
! 		if (ntohl(*(guint32 *)&p[i + aoff]) == BGP_COMM_NO_EXPORT)
                      strncpy(junk_buf, "NO_EXPORT", 10);
! 		else if (ntohl(*(guint32 *)&p[i + aoff]) == 
                          BGP_COMM_NO_ADVERTISE)
                      strncpy(junk_buf, "NO_ADVERTISE", 13);
! 		else if (ntohl(*(guint32 *)&p[i + aoff]) == 
                          BGP_COMM_NO_EXPORT_SUBCONFED)
                      strncpy(junk_buf, "NO_EXPORT_SUBCONFED", 20);
                  else {
                      snprintf(junk_buf, sizeof(junk_buf), "%u:%u",
! 		            ntohs(*(guint16 *)&p[i + aoff]), 
!                             ntohs(*(guint16 *)&p[i + aoff + 2]));
                  }
  
  		ti = proto_tree_add_text(subtree, p - pd + i, alen + aoff,
--- 490,507 ----
  		    goto default_attribute_top;
  
                  /* check for well-known communities */
! 		if (pntohl(&p[i + aoff]) == BGP_COMM_NO_EXPORT)
                      strncpy(junk_buf, "NO_EXPORT", 10);
! 		else if (pntohl(&p[i + aoff]) == 
                          BGP_COMM_NO_ADVERTISE)
                      strncpy(junk_buf, "NO_ADVERTISE", 13);
! 		else if (pntohl(&p[i + aoff]) == 
                          BGP_COMM_NO_EXPORT_SUBCONFED)
                      strncpy(junk_buf, "NO_EXPORT_SUBCONFED", 20);
                  else {
                      snprintf(junk_buf, sizeof(junk_buf), "%u:%u",
! 		            pntohs(&p[i + aoff]), 
!                             pntohs(&p[i + aoff + 2]));
                  }
  
  		ti = proto_tree_add_text(subtree, p - pd + i, alen + aoff,
***************
*** 687,693 ****
  		} else {
  		    proto_tree_add_text(subtree2, p - pd + i + aoff, alen,
  			    "Multi exit discriminator: %u",
! 			    ntohl(*(guint32 *)&p[i + aoff]));
  		}
  		break;
  	    case BGPTYPE_LOCAL_PREF:
--- 687,693 ----
  		} else {
  		    proto_tree_add_text(subtree2, p - pd + i + aoff, alen,
  			    "Multi exit discriminator: %u",
! 			    pntohl(&p[i + aoff]));
  		}
  		break;
  	    case BGPTYPE_LOCAL_PREF:
***************
*** 698,704 ****
  		} else {
  		    proto_tree_add_text(subtree2, p - pd + i + aoff, alen,
  			    "Local preference: %u",
! 			    ntohl(*(guint32 *)&p[i + aoff]));
  		}
  		break;
  	    case BGPTYPE_ATOMIC_AGGREGATE:
--- 698,704 ----
  		} else {
  		    proto_tree_add_text(subtree2, p - pd + i + aoff, alen,
  			    "Local preference: %u",
! 			    pntohl(&p[i + aoff]));
  		}
  		break;
  	    case BGPTYPE_ATOMIC_AGGREGATE:
***************
*** 716,722 ****
  		} else {
  		    proto_tree_add_text(subtree2, p - pd + i + aoff, 2,
  			    "Aggregator AS: %u",
! 			    ntohs(*(guint16 *)&p[i + aoff]));
  		    proto_tree_add_text(subtree2, p - pd + i + aoff + 2, 4,
  			    "Aggregator origin: %s",
  			    ip_to_str(&p[i + aoff + 2]));
--- 716,722 ----
  		} else {
  		    proto_tree_add_text(subtree2, p - pd + i + aoff, 2,
  			    "Aggregator AS: %u",
! 			    pntohs(&p[i + aoff]));
  		    proto_tree_add_text(subtree2, p - pd + i + aoff + 2, 4,
  			    "Aggregator origin: %s",
  			    ip_to_str(&p[i + aoff + 2]));
***************
*** 729,764 ****
                              (alen == 1) ? "byte" : "bytes");
                  }
                  /* check for reserved values */
! 		else if (ntohs(*(guint16 *)&p[i + aoff]) == FOURHEX0 ||
! 		        ntohs(*(guint16 *)&p[i + aoff]) == FOURHEXF) {
                      /* check for well-known communities */
! 		    if (ntohl(*(guint32 *)&p[i + aoff]) == BGP_COMM_NO_EXPORT)
  		        proto_tree_add_text(subtree2, p - pd + i + aoff, 4, 
                                  "Communities: NO_EXPORT (0x%x)", 
!                                 ntohl(*(guint32 *)&p[i + aoff]));
! 		    else if (ntohl(*(guint32 *)&p[i + aoff]) == 
                              BGP_COMM_NO_ADVERTISE)
  		        proto_tree_add_text(subtree2, p - pd + i + aoff, 4, 
                                  "Communities: NO_ADVERTISE (0x%x)",
!                                 ntohl(*(guint32 *)&p[i + aoff]));
! 		    else if (ntohl(*(guint32 *)&p[i + aoff]) == 
                              BGP_COMM_NO_EXPORT_SUBCONFED)
  		        proto_tree_add_text(subtree2, p - pd + i + aoff, 4, 
                                  "Communities: NO_EXPORT_SUBCONFED (0x%x)",
!                                 ntohl(*(guint32 *)&p[i + aoff]));
                      else {
  		        proto_tree_add_text(subtree2, p - pd + i + aoff, 4, 
                                  "Communities (reserved): 0x%x",
! 		                ntohl(*(guint32 *)&p[i + aoff]));
                      }
                  }
                  else {
  		    proto_tree_add_text(subtree2, p - pd + i + aoff, 2, 
                              "Communities AS: %u", 
!                             ntohs(*(guint16 *)&p[i + aoff]));
  		    proto_tree_add_text(subtree2, p - pd + i + aoff + 2, 2, 
                              "Communities value: %u", 
!                             ntohs(*(guint16 *)&p[i + aoff + 2]));
                  }
  		break;
  	    case BGPTYPE_ORIGINATOR_ID:
--- 729,764 ----
                              (alen == 1) ? "byte" : "bytes");
                  }
                  /* check for reserved values */
! 		else if (pntohs(&p[i + aoff]) == FOURHEX0 ||
! 		        pntohs(&p[i + aoff]) == FOURHEXF) {
                      /* check for well-known communities */
! 		    if (pntohl(&p[i + aoff]) == BGP_COMM_NO_EXPORT)
  		        proto_tree_add_text(subtree2, p - pd + i + aoff, 4, 
                                  "Communities: NO_EXPORT (0x%x)", 
!                                 pntohl(&p[i + aoff]));
! 		    else if (pntohl(&p[i + aoff]) == 
                              BGP_COMM_NO_ADVERTISE)
  		        proto_tree_add_text(subtree2, p - pd + i + aoff, 4, 
                                  "Communities: NO_ADVERTISE (0x%x)",
!                                 pntohl(&p[i + aoff]));
! 		    else if (pntohl(&p[i + aoff]) == 
                              BGP_COMM_NO_EXPORT_SUBCONFED)
  		        proto_tree_add_text(subtree2, p - pd + i + aoff, 4, 
                                  "Communities: NO_EXPORT_SUBCONFED (0x%x)",
!                                 pntohl(&p[i + aoff]));
                      else {
  		        proto_tree_add_text(subtree2, p - pd + i + aoff, 4, 
                                  "Communities (reserved): 0x%x",
! 		                pntohl(&p[i + aoff]));
                      }
                  }
                  else {
  		    proto_tree_add_text(subtree2, p - pd + i + aoff, 2, 
                              "Communities AS: %u", 
!                             pntohs(&p[i + aoff]));
  		    proto_tree_add_text(subtree2, p - pd + i + aoff + 2, 2, 
                              "Communities value: %u", 
!                             pntohs(&p[i + aoff + 2]));
                  }
  		break;
  	    case BGPTYPE_ORIGINATOR_ID:
***************
*** 773,779 ****
  		}
  		break;
  	    case BGPTYPE_MP_REACH_NLRI:
! 		af = ntohs(*(guint16 *)&p[i + aoff]);
  		proto_tree_add_text(subtree2, p - pd + i + aoff, 2,
  		    "Address family: %s (%u)",
  		    val_to_str(af, afnumber, "Unknown"), af);
--- 773,779 ----
  		}
  		break;
  	    case BGPTYPE_MP_REACH_NLRI:
! 		af = pntohs(&p[i + aoff]);
  		proto_tree_add_text(subtree2, p - pd + i + aoff, 2,
  		    "Address family: %s (%u)",
  		    val_to_str(af, afnumber, "Unknown"), af);
***************
*** 868,874 ****
  
  		break;
  	    case BGPTYPE_MP_UNREACH_NLRI:
! 		af = ntohs(*(guint16 *)&p[i + aoff]);
  		proto_tree_add_text(subtree2, p - pd + i + aoff, 2,
  		    "Address family: %s (%u)",
  		    val_to_str(af, afnumber, "Unknown"), af);
--- 868,874 ----
  
  		break;
  	    case BGPTYPE_MP_UNREACH_NLRI:
! 		af = pntohs(&p[i + aoff]);
  		proto_tree_add_text(subtree2, p - pd + i + aoff, 2,
  		    "Address family: %s (%u)",
  		    val_to_str(af, afnumber, "Unknown"), af);