Ethereal-dev: [Ethereal-dev] Patch: Added wiretap support for reassembled AAL5 in ERF files

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

From: Jesper Peterson <jesper@xxxxxxxxxx>
Date: Fri, 19 Sep 2003 14:59:03 +1200

The attached patch converts AAL5 records in ERF files to PDUS_UNTRUNCATED. The supplied test data contains SNAP headers but no IP so the ethertype is set to loopback.

--
Jesper Peterson, Senior Software Developer
http://www.endace.com, +64 7 839 0540

Index: wiretap/erf.c
===================================================================
RCS file: /cvsroot/ethereal/wiretap/erf.c,v
retrieving revision 1.2
diff -u -r1.2 erf.c
--- wiretap/erf.c	26 Aug 2003 23:07:43 -0000	1.2
+++ wiretap/erf.c	19 Sep 2003 02:43:08 -0000
@@ -69,6 +69,12 @@
 		int length, int *err);
 static void erf_close(wtap *wth);
 static int erf_encap_to_wtap_encap(erf_t *erf, guint8 erf_encap);
+static void erf_guess_atm_traffic_type(
+		guint8 type,
+		erf_t *erf,
+		guchar *pd,
+		int length,
+		union wtap_pseudo_header *pseudo_header);
 
 int erf_open(wtap *wth, int *err)
 {
@@ -128,14 +134,20 @@
 
 #ifdef G_HAVE_GINT64
 		if ((ts = pletohll(&header.ts)) < prevts) {
-			return 0;
+			/* reassembled AAL5 records may not be in time order, so allow 1 sec fudge */
+			if (header.type != TYPE_AAL5 || ((prevts-ts)>>32) > 1) {
+				return 0;
+			}
 		}
 #else
 		ts[0] = pletohl(&header.ts[0]); /* frac */
 		ts[1] = pletohl(&header.ts[1]); /* sec */
 		if ((ts[1] < prevts[1]) ||
 				(ts[1] == prevts[1] && ts[0] < prevts[0])) {
-			return 0;
+			/* reassembled AAL5 records may not be in time order, so allow 1 sec fudge */
+			if (header.type != TYPE_AAL5 || (prevts[1]-ts[1]) > 1) {
+				return 0;
+			}
 		}
 #endif
 		memcpy(&prevts, &ts, sizeof(prevts));
@@ -173,9 +185,14 @@
 	wth->file_type = WTAP_FILE_ERF;
 	wth->snapshot_length = 0;	/* not available in header, only in frame */
 	wth->capture.erf = g_malloc(sizeof(erf_t));
-	wth->capture.erf->atm_encap = atm_encap;
-	wth->capture.erf->is_rawatm = is_rawatm;
 	wth->capture.erf->is_ppp = is_ppp;
+	if (common_type == TYPE_AAL5) {
+		wth->capture.erf->atm_encap = WTAP_ENCAP_ATM_PDUS_UNTRUNCATED;
+		wth->capture.erf->is_rawatm = FALSE;
+	} else {
+		wth->capture.erf->atm_encap = atm_encap;
+		wth->capture.erf->is_rawatm = is_rawatm;
+	}
 
 	/*
 	 * Really want WTAP_ENCAP_PER_PACKET here but that severely limits
@@ -228,11 +245,10 @@
 	);
 	wth->data_offset += packet_size;
 
-	if (erf_header.type == TYPE_ATM && wth->capture.erf->atm_encap == WTAP_ENCAP_ATM_PDUS && !wth->capture.erf->is_rawatm) {
-		atm_guess_traffic_type(
+	erf_guess_atm_traffic_type(
+			erf_header.type, wth->capture.erf,
 			buffer_start_ptr(wth->frame_buffer), packet_size, &wth->pseudo_header
-		);
-	}
+	);
 
 	return TRUE;
 }
@@ -243,6 +259,7 @@
 {
 	erf_header_t erf_header;
 	guint32 packet_size;
+	int offset = 0;
 
 	if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
 		return FALSE;
@@ -251,14 +268,13 @@
 
 	if (wth->capture.erf->is_rawatm) {
 		wtap_file_read_expected_bytes(pd, (int)sizeof(atm_hdr_t), wth->random_fh, err);
-		pd += sizeof(atm_hdr_t)+1;
+		packet_size -= sizeof(atm_hdr_t);
+		offset += sizeof(atm_hdr_t)+1;
 	}
 
-	wtap_file_read_expected_bytes(pd, (int)packet_size, wth->random_fh, err);
+	wtap_file_read_expected_bytes(pd+offset, (int)packet_size, wth->random_fh, err);
 
-	if (erf_header.type == TYPE_ATM && wth->capture.erf->atm_encap == WTAP_ENCAP_ATM_PDUS && !wth->capture.erf->is_rawatm) {
-		atm_guess_traffic_type(pd, length, pseudo_header);
-	}
+	erf_guess_atm_traffic_type(erf_header.type, wth->capture.erf, pd, length, pseudo_header);
 
 	return TRUE;
 }
@@ -322,13 +338,18 @@
 	switch (erf_header->type) {
 
 	case TYPE_ATM:
+	case TYPE_AAL5:
 
 		if (phdr != NULL) {
-			phdr->caplen = ATM_SLEN(erf_header, NULL);
-			phdr->len = ATM_WLEN(erf_header, NULL);
+			if (erf_header->type == TYPE_AAL5) {
+				phdr->caplen = phdr->len = *packet_size - sizeof(atm_hdr_t);
+			} else {
+				phdr->caplen = ATM_SLEN(erf_header, NULL);
+				phdr->len = ATM_WLEN(erf_header, NULL);
+			}
 		}
 
-		if (erf->atm_encap == WTAP_ENCAP_ATM_PDUS) {
+		if (erf->atm_encap == WTAP_ENCAP_ATM_PDUS || erf->atm_encap == WTAP_ENCAP_ATM_PDUS_UNTRUNCATED) {
 			memset(&pseudo_header->atm, 0, sizeof(pseudo_header->atm));
 			if (erf->is_rawatm) {
 				pseudo_header->atm.flags = ATM_RAW_CELL;
@@ -344,7 +365,7 @@
 					*bytes_read += sizeof(atm_hdr);
 				}
 				*packet_size -= sizeof(atm_hdr);
-			
+
 				atm_hdr = g_ntohl(atm_hdr);
 
 				pseudo_header->atm.vpi = ((atm_hdr & 0x0ff00000) >> 20);
@@ -413,3 +434,21 @@
 
 	return wtap_encap;
 }
+
+static void erf_guess_atm_traffic_type(
+	guint8 type, erf_t *erf, guchar *pd, int length, union wtap_pseudo_header *pseudo_header)
+{
+	if (!erf->is_rawatm &&
+			(type == TYPE_ATM || type == TYPE_AAL5) &&
+			(erf->atm_encap == WTAP_ENCAP_ATM_PDUS ||
+			 erf->atm_encap == WTAP_ENCAP_ATM_PDUS_UNTRUNCATED)) { 
+		atm_guess_traffic_type(pd, length, pseudo_header);
+	} else
+	if (type == TYPE_AAL5) {
+		pseudo_header->atm.aal = AAL_5;
+		pseudo_header->atm.type = TRAF_UNKNOWN;
+		pseudo_header->atm.subtype = TRAF_ST_UNKNOWN;
+	}
+}
+
+

Attachment: aal5.erf
Description: Binary data