summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--wiretap/iseries.c571
1 files changed, 245 insertions, 326 deletions
diff --git a/wiretap/iseries.c b/wiretap/iseries.c
index 764f2401ae..7c885333cb 100644
--- a/wiretap/iseries.c
+++ b/wiretap/iseries.c
@@ -68,17 +68,32 @@
Format Broadcast data . . . : Y Y=Yes, N=No
*/
-/* iSeries IPv4 formatted packet records consist of a header line identifying the packet number,direction,size,
- * timestamp,source/destination MAC addresses and packet type.
+/* iSeries IPv4 formatted packet records consist of a packet header line
+ * identifying the packet number, direction, size, timestamp,
+ * source/destination MAC addresses and packet type.
*
- * Thereafter there will be a formated display of the IP and TCP headers as well as a hex string dump
- * of the headers themselves displayed in the the "IP Header" and "TCP header" fields.
+ * Thereafter there will be a formated display of the headers above
+ * the link layer, such as ARP, IP, TCP, UDP, and ICMP (all but
+ * ICMP have either been seen in captures or on pages such as the ones
+ * at
*
- * If the packet contains data this is displayed as 4 groups of 16 hex digits followed by an ASCII
- * representaion of the data line.
+ * http://www-912.ibm.com/s_dir/SLKBase.nsf/1ac66549a21402188625680b0002037e/e05fb0515bc3449686256ce600512c37?OpenDocument
*
- * Information from the header line, IP header, TCP header and if available data lines are extracted
- * by the module for displaying.
+ * and
+ *
+ * http://publib.boulder.ibm.com/infocenter/javasdk/v5r0/index.jsp?topic=%2Fcom.ibm.java.doc.diagnostics.50%2Fdiag%2Fproblem_determination%2Fi5os_perf_io_commstrace.html
+ *
+ * so we cannot assume that "IP Header" or "TCP Header" will appear). The
+ * formatted display includes lines that show the contents of some of the
+ * fields in the header, as well as hex strings dumps of the headers
+ * themselves, with tags such as "IP Header :", "ARP Header :",
+ * "TCP Header :", "UDP Header :", and (presumably) "ICMP Header:".
+ *
+ * If the packet contains data this is displayed as 4 groups of 16 hex digits
+ * followed by an ASCII representaion of the data line.
+ *
+ * Information from the packet header line, higher-level headers and, if
+ * available, data lines are extracted by the module for displaying.
*
*
Record Data Record Controller Destination Source Frame
@@ -98,8 +113,11 @@
FC276228786B3EB0 EF34F5F1D27EF8DF 20926820E7B322AA 739F1FB20D **'B(XK>**4***.** *H **"*S*.*. *
*/
-/* iSeries IPv6 formatted traces are similar to the IPv4 version above but data is no longer output as 4 hex sections
-*
+/* iSeries IPv6 formatted traces are similar to the IPv4 version above,
+ * except that the higher-level headers have "IPv6 Header:" and
+ * "ICMPv6 Hdr:", and data data is no longer output in groups of 16 hex
+ * digits.
+ *
Record Data Record Destination Source Frame
Number S/R Length Timer MAC Address MAC Address Format
@@ -120,8 +138,9 @@ Number S/R Length Timer MAC Address MAC Address
4040404040404040404040404040404040404040404040404040404040404040 *@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*
*/
-/* iSeries unformatted packet record consist of the same header record as the formatted trace but all
- * other records are simply unformatted data containing IP, TCP and packet data combined.
+/* iSeries unformatted packet record consist of the same header record as
+ * the formatted trace but all other records are simply unformatted data
+ * containing higher-level headers and packet data combined.
*
Record Data Record Controller Destination Source Frame Number Number Poll/
Number S/R Length Timer Name MAC Address MAC Address Format Command Sent Received Final DSAP SSAP
@@ -154,15 +173,13 @@ Number S/R Length Timer MAC Address MAC Address
#define ISERIES_PKT_LINES_TO_CHECK 4
#define ISERIES_MAX_PACKET_LEN 16384
#define ISERIES_MAX_TRACE_LEN 99999999
-#define ISERIES_PKT_ALLOC_SIZE (cap_len*2)+1
+#define ISERIES_PKT_ALLOC_SIZE (pkt_len*2)+1
#define ISERIES_FORMAT_ASCII 1
#define ISERIES_FORMAT_UNICODE 2
typedef struct {
gboolean have_date; /* TRUE if we found a capture start date */
int year, month, day; /* The start date */
- gboolean tcp_formatted; /* TCP/IP data formated Y/N */
- gboolean ipv6_trace; /* IPv4 or IPv6 */
int format; /* Trace format type */
} iseries_t;
@@ -301,7 +318,7 @@ iseries_check_file_type (wtap * wth, int *err, gchar **err_info, int format)
{
guint line;
int num_items_scanned;
- char buf[ISERIES_LINE_LENGTH], protocol[9], type[5], work[2];
+ char buf[ISERIES_LINE_LENGTH], protocol[9];
iseries_t *iseries;
/* Save trace format for passing between packets */
@@ -309,8 +326,6 @@ iseries_check_file_type (wtap * wth, int *err, gchar **err_info, int format)
wth->priv = (void *) iseries;
iseries->have_date = FALSE;
iseries->format = format;
- iseries->tcp_formatted = FALSE;
- iseries->ipv6_trace = FALSE;
for (line = 0; line < ISERIES_HDR_LINES_TO_CHECK; line++)
{
@@ -345,48 +360,6 @@ iseries_check_file_type (wtap * wth, int *err, gchar **err_info, int format)
{
iseries->have_date = TRUE;
}
-
-
- /*
- * Determine if this is a IPv4 or IPv6 trace
- */
- num_items_scanned =
- sscanf (buf+78,
- "%*[ \n\t]ETHV2%*[ .:\n\t]TYPE%*[ .:\n\t]%4s", type);
- if (num_items_scanned == 1)
- {
- if (strncmp (type, "0800", 1) == 0)
- {
- iseries->ipv6_trace = FALSE;
- }
- if (strncmp (type, "86DD", 1) == 0)
- {
- iseries->ipv6_trace = TRUE;
- }
- }
-
- /*
- * Determine if the data has been formatted
- */
- /* IPv6 formatted */
- num_items_scanned = sscanf (buf,
- "%*[ \n\t]IPV6 HEADER%1s",
- work);
- if (num_items_scanned == 1)
- {
- iseries->tcp_formatted = TRUE;
- return TRUE;
- }
- /* IPv4 formatted */
- num_items_scanned = sscanf (buf,
- "%*[ \n\t]IP HEADER %1s",
- work);
- if (num_items_scanned == 1)
- {
- iseries->tcp_formatted = TRUE;
- return TRUE;
- }
-
}
else
{
@@ -409,7 +382,7 @@ static gboolean
iseries_read (wtap * wth, int *err, gchar ** err_info, gint64 *data_offset)
{
gint64 offset;
- int pkt_len;
+ int cap_len;
/*
* Locate the next packet
@@ -421,10 +394,10 @@ iseries_read (wtap * wth, int *err, gchar ** err_info, gint64 *data_offset)
/*
* Parse the packet and extract the various fields
*/
- pkt_len =
+ cap_len =
iseries_parse_packet (wth, wth->fh, &wth->pseudo_header, NULL, err,
err_info);
- if (pkt_len == -1)
+ if (cap_len == -1)
return FALSE;
*data_offset = offset;
@@ -515,7 +488,7 @@ iseries_seek_read (wtap * wth, gint64 seek_off,
union wtap_pseudo_header *pseudo_header, guint8 * pd,
int len, int *err, gchar ** err_info)
{
- int pkt_len;
+ int cap_len;
/* seek to packet location */
if (file_seek (wth->random_fh, seek_off - 1, SEEK_SET, err) == -1)
@@ -524,23 +497,103 @@ iseries_seek_read (wtap * wth, gint64 seek_off,
/*
* Parse the packet and extract the various fields
*/
- pkt_len = iseries_parse_packet (wth, wth->random_fh, pseudo_header, pd,
+ cap_len = iseries_parse_packet (wth, wth->random_fh, pseudo_header, pd,
err, err_info);
- if (pkt_len != len)
+ if (cap_len != len)
{
- if (pkt_len != -1)
+ if (cap_len != -1)
{
*err = WTAP_ERR_BAD_FILE;
*err_info =
g_strdup_printf ("iseries: requested length %d doesn't match record length %d",
- len, pkt_len);
+ len, cap_len);
}
return FALSE;
}
return TRUE;
}
+static int
+append_hex_digits(char *ascii_buf, int ascii_offset, int max_offset,
+ char *data, int *err, gchar **err_info)
+{
+ int in_offset, out_offset;
+ int c;
+ unsigned int i;
+ gboolean overflow = FALSE;
+
+ in_offset = 0;
+ out_offset = ascii_offset;
+ for (;;)
+ {
+ /*
+ * Process a block of up to 16 hex digits.
+ * The block is terminated early by an end-of-line indication (NUL,
+ * CR, or LF), by a space (which terminates the last block of the
+ * data we're processing), or by a "*", which introduces the ASCII representation
+ * of the data.
+ * All characters in the block must be upper-case hex digits;
+ * there might or might not be a space *after* a block, but, if so,
+ * that will be skipped over after the block is processed.
+ */
+ for (i = 0; i < 16; i++, in_offset++)
+ {
+ /*
+ * If we see an end-of-line indication, or an early-end-of-block
+ * indication (space), we're done. (Only the last block ends
+ * early.)
+ */
+ c = data[in_offset] & 0xFF;
+ if (c == '\0' || c == ' ' || c == '*' || c == '\r' || c == '\n')
+ {
+ goto done;
+ }
+ if (!isxdigit(c) || islower(c))
+ {
+ /*
+ * Not a hex digit, or a lower-case hex digit.
+ * Treat this as an indication that the line isn't a data
+ * line, so we just ignore it.
+ *
+ * XXX - do so only for continuation lines; treat non-hex-digit
+ * characters as errors for other lines?
+ */
+ return ascii_offset; /* pretend we appended nothing */
+ }
+ if (out_offset >= max_offset)
+ overflow = TRUE;
+ else
+ {
+ ascii_buf[out_offset] = c;
+ out_offset++;
+ }
+ }
+ /*
+ * Skip blanks, if any.
+ */
+ for (; (data[in_offset] & 0xFF) == ' '; in_offset++)
+ ;
+ }
+done:
+ /*
+ * If we processed an *odd* number of hex digits, report an error.
+ */
+ if ((i % 2) != 0)
+ {
+ *err = WTAP_ERR_BAD_FILE;
+ *err_info = g_strdup("iseries: odd number of hex digits in a line");
+ return -1;
+ }
+ if (overflow)
+ {
+ *err = WTAP_ERR_BAD_FILE;
+ *err_info = g_strdup("iseries: more packet data than the packet length indicated");
+ return -1;
+ }
+ return out_offset;
+}
+
/* Parses a packet. */
static int
iseries_parse_packet (wtap * wth, FILE_T fh,
@@ -549,16 +602,15 @@ iseries_parse_packet (wtap * wth, FILE_T fh,
{
iseries_t *iseries = (iseries_t *)wth->priv;
gint64 cur_off;
- gboolean isValid, isCurrentPacket, IPread, TCPread, isDATA, isDataHandled;
+ gboolean isValid, isCurrentPacket;
int num_items_scanned, line, pktline, buflen;
- guint32 pkt_len;
- int cap_len, pktnum, hr, min, sec, csec;
- char direction[2], destmac[13], srcmac[13], type[5];
- char ipheader[41], tcpheader[81];
- char hex1[17], hex2[17], hex3[17], hex4[17];
+ int pkt_len, pktnum, hr, min, sec;
+ char direction[2], destmac[13], srcmac[13], type[5], csec[9+1];
char data[ISERIES_LINE_LENGTH * 2];
+ int offset;
guint8 *buf;
- char *tcpdatabuf, *workbuf, *asciibuf;
+ char *ascii_buf;
+ int ascii_offset;
struct tm tm;
/*
@@ -586,19 +638,19 @@ iseries_parse_packet (wtap * wth, FILE_T fh,
ascii_strup_inplace (data);
num_items_scanned =
sscanf (data,
- "%*[ \n\t]%6d%*[ *\n\t]%1s%*[ \n\t]%6d%*[ \n\t]%2d:%2d:%2d.%9d%*[ \n\t]"
+ "%*[ \n\t]%6d%*[ *\n\t]%1s%*[ \n\t]%6d%*[ \n\t]%2d:%2d:%2d.%9[0-9]%*[ \n\t]"
"%12s%*[ \n\t]%12s%*[ \n\t]ETHV2%*[ \n\t]TYPE:%*[ \n\t]%4s",
- &pktnum, direction, &cap_len, &hr, &min, &sec, &csec, destmac,
+ &pktnum, direction, &pkt_len, &hr, &min, &sec, csec, destmac,
srcmac, type);
if (num_items_scanned == 10)
{
/* OK! We found the packet header line */
isValid = TRUE;
/*
- * XXX - The Capture length returned by the iSeries trace doesn't seem to include the src/dest MAC
- * addresses or the packet type. So we add them here.
+ * XXX - The Capture length returned by the iSeries trace doesn't
+ * seem to include the Ethernet header, so we add its length here.
*/
- cap_len += 14;
+ pkt_len += 14;
break;
}
}
@@ -618,9 +670,8 @@ iseries_parse_packet (wtap * wth, FILE_T fh,
/*
* If we have Wiretap Header then populate it here
*
- * XXX - Timer resolution on the iSeries is hardware dependant; the value for csec may be
- * different on other platforms though all the traces I've seen seem to show resolution
- * to Milliseconds (i.e HH:MM:SS.nnnnn) or Nanoseconds (i.e HH:MM:SS.nnnnnn)
+ * Timer resolution on the iSeries is hardware dependent. We determine
+ * the resolution based on how many digits we see.
*/
if (iseries->have_date)
{
@@ -633,37 +684,53 @@ iseries_parse_packet (wtap * wth, FILE_T fh,
tm.tm_sec = sec;
tm.tm_isdst = -1;
wth->phdr.ts.secs = mktime (&tm);
- /* Handle Millisecond precision for timer */
- if (csec > 99999)
- {
- wth->phdr.ts.nsecs = csec * 1000;
- }
- /* Handle Nanosecond precision for timer */
- else
+ switch (strlen(csec))
{
- wth->phdr.ts.nsecs = csec * 10000;
+ case 0:
+ wth->phdr.ts.nsecs = 0;
+ break;
+ case 1:
+ wth->phdr.ts.nsecs = atoi(csec) * 100000000;
+ break;
+ case 2:
+ wth->phdr.ts.nsecs = atoi(csec) * 10000000;
+ break;
+ case 3:
+ wth->phdr.ts.nsecs = atoi(csec) * 1000000;
+ break;
+ case 4:
+ wth->phdr.ts.nsecs = atoi(csec) * 100000;
+ break;
+ case 5:
+ wth->phdr.ts.nsecs = atoi(csec) * 10000;
+ break;
+ case 6:
+ wth->phdr.ts.nsecs = atoi(csec) * 1000;
+ break;
+ case 7:
+ wth->phdr.ts.nsecs = atoi(csec) * 100;
+ break;
+ case 8:
+ wth->phdr.ts.nsecs = atoi(csec) * 10;
+ break;
+ case 9:
+ wth->phdr.ts.nsecs = atoi(csec);
+ break;
}
}
- wth->phdr.caplen = cap_len;
+ wth->phdr.len = pkt_len;
wth->phdr.pkt_encap = WTAP_ENCAP_ETHERNET;
pseudo_header->eth.fcs_len = -1;
+ ascii_buf = g_malloc (ISERIES_PKT_ALLOC_SIZE);
+ g_snprintf(ascii_buf, ISERIES_PKT_ALLOC_SIZE, "%s%s%s", destmac, srcmac, type);
+ ascii_offset = 14*2; /* 14-byte Ethernet header, 2 characters per byte */
+
/*
* Start Reading packet contents
*/
isCurrentPacket = TRUE;
- IPread = FALSE;
- TCPread = FALSE;
- isDATA = FALSE;
-
- /*
- * Allocate 2 work buffers to handle concatentation of the hex data block
- */
- tcpdatabuf = g_malloc (ISERIES_PKT_ALLOC_SIZE);
- workbuf = g_malloc (ISERIES_PKT_ALLOC_SIZE);
- tcpdatabuf[0] = '\0';
- workbuf[0] = '\0';
/* loop through packet lines and breakout when the next packet header is read */
pktline = 0;
@@ -700,173 +767,86 @@ iseries_parse_packet (wtap * wth, FILE_T fh,
}
/*
- * Decode data for IPv4 traces and unformatted IPv6 traces
+ * Skip leading white space.
*/
- if ((!iseries->ipv6_trace) || ((iseries->ipv6_trace) && (!iseries->tcp_formatted)))
- {
- /* If this is a IP header hex string then set flag */
- num_items_scanned = sscanf (data + 22, "IP Header%*[ .:\n\t]%40s", ipheader);
- if (num_items_scanned == 1)
- {
- IPread = TRUE;
- }
-
- /* If this is TCP header hex string then set flag */
- num_items_scanned = sscanf (data + 22, "TCP Header%*[ .:\n\t]%80s", tcpheader);
- if (num_items_scanned == 1)
- {
- TCPread = TRUE;
- }
+ for (offset = 0; isspace(data[offset]); offset++)
+ ;
- /*
- * If there is data in the packet handle it here.
- *
- * The data header line will have the "Data . . " identifier, subsequent lines don't
- */
- num_items_scanned =
- sscanf (data + 27, "%16[A-F0-9] %16[A-F0-9] %16[A-F0-9] %16[A-F0-9]",
- hex1, hex2, hex3, hex4);
- if (num_items_scanned > 0)
+ /*
+ * The higher-level header information starts at an offset of
+ * 22 characters. The header tags are 14 characters long.
+ *
+ * XXX - for IPv6, if the next header isn't the last header,
+ * the intermediate headers do *NOT* appear to be shown in
+ * the dump file *at all*, so the packet *cannot* be
+ * reconstructed!
+ */
+ if (offset == 22)
+ {
+ if (strncmp(data + 22, "IP Header : ", 14) == 0 ||
+ strncmp(data + 22, "IPv6 Header: ", 14) == 0 ||
+ strncmp(data + 22, "ARP Header : ", 14) == 0 ||
+ strncmp(data + 22, "TCP Header : ", 14) == 0 ||
+ strncmp(data + 22, "UDP Header : ", 14) == 0 ||
+ strncmp(data + 22, "ICMP Header: ", 14) == 0 ||
+ strncmp(data + 22, "ICMPv6 Hdr: ", 14) == 0 ||
+ strncmp(data + 22, "Option Hdr: ", 14) == 0)
{
- isDATA = TRUE;
- /*
- * Scan the data line for data blocks, depending on the number of blocks scanned
- * add them along with current tcpdata buffer to the work buffer and then copy
- * work buffer to tcpdata buffer to continue building up tcpdata buffer to contain
- * a single hex string.
- */
- switch (num_items_scanned)
+ ascii_offset = append_hex_digits(ascii_buf, ascii_offset,
+ ISERIES_PKT_ALLOC_SIZE - 1,
+ data + 22 + 14, err,
+ err_info);
+ if (ascii_offset == -1)
{
- case 1:
- g_snprintf (workbuf, ISERIES_PKT_ALLOC_SIZE, "%s%s", tcpdatabuf,
- hex1);
- break;
- case 2:
- g_snprintf (workbuf, ISERIES_PKT_ALLOC_SIZE, "%s%s%s",
- tcpdatabuf, hex1, hex2);
- break;
- case 3:
- g_snprintf (workbuf, ISERIES_PKT_ALLOC_SIZE, "%s%s%s%s",
- tcpdatabuf, hex1, hex2, hex3);
- break;
- default:
- g_snprintf (workbuf, ISERIES_PKT_ALLOC_SIZE, "%s%s%s%s%s",
- tcpdatabuf, hex1, hex2, hex3, hex4);
+ /* Bad line. */
+ return -1;
}
- memcpy (tcpdatabuf, workbuf, ISERIES_PKT_ALLOC_SIZE);
+ continue;
}
}
/*
- * Decode data for IPv6 formatted traces
+ * Is this a data line?
+ *
+ * The "Data" starts at an offset of 8.
*/
- if ((iseries->ipv6_trace) && (iseries->tcp_formatted))
+ if (offset == 9)
{
- /*
- * If there are IPv6 headers in the packet handle it here.
- *
- * iSeries IPv6 headers are aligned after column 36 and appears as a single hex string
- * of 16,32,48 or 64 bytes
- */
- isDataHandled=FALSE;
- num_items_scanned =
- sscanf (data + 35, "%*[ \n\t]%16[A-F0-9]%16[A-F0-9]%16[A-F0-9]%16[A-F0-9]",
- hex1, hex2, hex3, hex4);
- if (num_items_scanned > 0)
+ if (strncmp(data + 9, "Data . . . . . : ", 18) == 0)
{
- isDATA = TRUE;
- /*
- * Scan the data line for data blocks, depending on the number of blocks scanned
- * add them along with current tcpdata buffer to the work buffer and then copy
- * work buffer to tcpdata buffer to continue building up tcpdata buffer to contain
- * a single hex string.
- */
- switch (num_items_scanned)
+ ascii_offset = append_hex_digits(ascii_buf, ascii_offset,
+ ISERIES_PKT_ALLOC_SIZE - 1,
+ data + 9 + 18, err,
+ err_info);
+ if (ascii_offset == -1)
{
- case 1:
- if (strlen(hex1)==16)
- {
- g_snprintf (workbuf, ISERIES_PKT_ALLOC_SIZE, "%s%s", tcpdatabuf,
- hex1);
- isDataHandled=TRUE;
- }
- break;
- case 2:
- if ((strlen(hex1)==16) && (strlen(hex2)==16))
- {
- g_snprintf (workbuf, ISERIES_PKT_ALLOC_SIZE, "%s%s%s",
- tcpdatabuf, hex1, hex2);
- isDataHandled=TRUE;
- }
- break;
- case 3:
- if ((strlen(hex1)==16) && (strlen(hex2)==16) && (strlen(hex3)==16))
- {
- g_snprintf (workbuf, ISERIES_PKT_ALLOC_SIZE, "%s%s%s%s",
- tcpdatabuf, hex1, hex2, hex3);
- isDataHandled=TRUE;
- }
- break;
- default:
- if ((strlen(hex1)==16) && (strlen(hex2)==16) && (strlen(hex3)==16) && (strlen(hex4)==16))
- {
- g_snprintf (workbuf, ISERIES_PKT_ALLOC_SIZE, "%s%s%s%s%s",
- tcpdatabuf, hex1, hex2, hex3, hex4);
- isDataHandled=TRUE;
- }
+ /* Bad line. */
+ return -1;
}
- memcpy (tcpdatabuf, workbuf, ISERIES_PKT_ALLOC_SIZE);
+ continue;
}
- /*
- * If there is data in the packet handle it here.
- *
- * The data header line will have the "Data . . " identifier, subsequent lines don't
- * Check to ensure we haven't already captured and used this data block already above
- */
- num_items_scanned =
- sscanf (data + 26, "%*[ \n\t]%16[A-F0-9]%16[A-F0-9]%16[A-F0-9]%16[A-F0-9]",
- hex1, hex2, hex3, hex4);
- if ((num_items_scanned > 0) && (isDataHandled==FALSE))
+ }
+
+ /*
+ * Is this a continuation of a previous header or data line?
+ * That's blanks followed by hex digits; first try the
+ * "no column separators" form.
+ *
+ * Continuations of header lines begin at an offset of 36;
+ * continuations of data lines begin at an offset of 27.
+ */
+ if (offset == 36 || offset == 27)
+ {
+ ascii_offset = append_hex_digits(ascii_buf, ascii_offset,
+ ISERIES_PKT_ALLOC_SIZE - 1,
+ data + offset, err,
+ err_info);
+ if (ascii_offset == -1)
{
- isDATA = TRUE;
- /*
- * Scan the data line for data blocks, depending on the number of blocks scanned
- * add them along with current tcpdata buffer to the work buffer and then copy
- * work buffer to tcpdata buffer to continue building up tcpdata buffer to contain
- * a single hex string.
- */
- switch (num_items_scanned)
- {
- case 1:
- if (strlen(hex1)==16)
- {
- g_snprintf (workbuf, ISERIES_PKT_ALLOC_SIZE, "%s%s", tcpdatabuf,
- hex1);
- }
- break;
- case 2:
- if ((strlen(hex1)==16) && (strlen(hex2)==16))
- {
- g_snprintf (workbuf, ISERIES_PKT_ALLOC_SIZE, "%s%s%s",
- tcpdatabuf, hex1, hex2);
- }
- break;
- case 3:
- if ((strlen(hex1)==16) && (strlen(hex2)==16) && (strlen(hex3)==16))
- {
- g_snprintf (workbuf, ISERIES_PKT_ALLOC_SIZE, "%s%s%s%s",
- tcpdatabuf, hex1, hex2, hex3);
- }
- break;
- default:
- if ((strlen(hex1)==16) && (strlen(hex2)==16) && (strlen(hex3)==16) && (strlen(hex4)==16))
- {
- g_snprintf (workbuf, ISERIES_PKT_ALLOC_SIZE, "%s%s%s%s%s",
- tcpdatabuf, hex1, hex2, hex3, hex4);
- }
- }
- memcpy (tcpdatabuf, workbuf, ISERIES_PKT_ALLOC_SIZE);
+ /* Bad line. */
+ return -1;
}
+ continue;
}
/*
@@ -895,74 +875,16 @@ iseries_parse_packet (wtap * wth, FILE_T fh,
}
}
}
+ ascii_buf[ascii_offset] = '\0';
/*
- * For a IPV4 formated trace ensure we have read at least the IP and TCP headers otherwise
- * exit and pass error message to user.
- */
- if ((iseries->tcp_formatted) && (iseries->ipv6_trace == FALSE))
- {
- if (!IPread)
- {
- *err = WTAP_ERR_BAD_FILE;
- *err_info = g_strdup ("iseries: IP header isn't valid");
- goto errxit;
- }
- if (!TCPread)
- {
- *err = WTAP_ERR_BAD_FILE;
- *err_info = g_strdup ("iseries: TCP header isn't valid");
- goto errxit;
- }
- }
-
- /*
- * Create a buffer to hold all the ASCII Hex data and populate with all the
- * extracted data.
- */
- asciibuf = g_malloc (ISERIES_PKT_ALLOC_SIZE);
- if (isDATA)
- {
- /* packet contained data */
- if ((iseries->tcp_formatted) && (iseries->ipv6_trace == FALSE))
- {
- /* build string for formatted fields */
- g_snprintf (asciibuf, ISERIES_PKT_ALLOC_SIZE, "%s%s%s%s%s%s",
- destmac, srcmac, type, ipheader, tcpheader, tcpdatabuf);
- }
- else
- {
- /* build string for unformatted data fields and IPV6 data*/
- g_snprintf (asciibuf, ISERIES_PKT_ALLOC_SIZE, "%s%s%s%s", destmac,
- srcmac, type, tcpdatabuf);
- }
- }
- else
- {
- /* No data in the packet */
- g_snprintf (asciibuf, ISERIES_PKT_ALLOC_SIZE, "%s%s%s%s%s", destmac,
- srcmac, type, ipheader, tcpheader);
- }
-
- /*
- * Note: iSeries comms traces pad data blocks out with zeros
- * Extract the packet length from the actual IP header; this may
- * differ from the capture length reported by the formatted trace.
- * IPv4 and IPv6 headers contain the length at different offsets so
- * read from the correct location.
+ * Make the captured length be the amount of bytes we've read (which
+ * is half the number of characters of hex dump we have).
+ *
+ * XXX - this can happen for IPv6 packets if the next header isn't the
+ * last header.
*/
- if (!iseries->ipv6_trace)
- {
- sscanf (asciibuf + 32, "%4x", &pkt_len);
- wth->phdr.len = pkt_len + 14;
- }
- else
- {
- sscanf (asciibuf + 36, "%4x", &pkt_len);
- wth->phdr.len = pkt_len + 14;
- }
- if (wth->phdr.caplen > wth->phdr.len)
- wth->phdr.len = wth->phdr.caplen;
+ wth->phdr.caplen = ((guint32) strlen (ascii_buf))/2;
/* Make sure we have enough room for the packet, only create buffer if none supplied */
if (pd == NULL)
@@ -970,24 +892,21 @@ iseries_parse_packet (wtap * wth, FILE_T fh,
buffer_assure_space (wth->frame_buffer, ISERIES_MAX_PACKET_LEN);
buf = buffer_start_ptr (wth->frame_buffer);
/* Convert ascii data to binary and return in the frame buffer */
- iseries_parse_hex_string (asciibuf, buf, (int) strlen (asciibuf));
+ iseries_parse_hex_string (ascii_buf, buf, (int) strlen (ascii_buf));
}
else
{
/* Convert ascii data to binary and return in the frame buffer */
- iseries_parse_hex_string (asciibuf, pd, (int) strlen (asciibuf));
+ iseries_parse_hex_string (ascii_buf, pd, (int) strlen (ascii_buf));
}
/* free buffer allocs and return */
*err = 0;
- g_free (asciibuf);
- g_free (tcpdatabuf);
- g_free (workbuf);
- return wth->phdr.len;
+ g_free (ascii_buf);
+ return wth->phdr.caplen;
errxit:
- g_free (tcpdatabuf);
- g_free (workbuf);
+ g_free (ascii_buf);
return -1;
}