diff options
author | Balint Reczey <balint@balintreczey.hu> | 2017-03-14 02:22:45 +0100 |
---|---|---|
committer | Balint Reczey <balint@balintreczey.hu> | 2017-03-15 16:59:48 +0000 |
commit | 8b8ad47820a8d7de978442448aff58099cbe8236 (patch) | |
tree | f7921805282b94e560e45516c68a5ea3d8bf597a | |
parent | e8fe96cdca53cbfabc9247639676275a2483ac3d (diff) | |
download | wireshark-lts-1.12.1.tar.gz wireshark-lts-1.12.1.tar.bz2 wireshark-lts-1.12.1.zip |
Backport wiretap/netscaler.c from 2.0.11lts-1.12.1
This fixes several bugs most notably the following vulnerabilities:
CVE-2017-6474, CVE-2017-6468, CVE-2017-6467
The backport omits the support for netscaler 3.5 format
Bug: 13429 13430 12083
Change-Id: I0a63bd79437551e7effd31cce29930ed9f4fb4e9
Reviewed-on: https://code.wireshark.org/review/20538
Reviewed-by: Balint Reczey <balint@balintreczey.hu>
-rw-r--r-- | wiretap/netscaler.c | 967 |
1 files changed, 557 insertions, 410 deletions
diff --git a/wiretap/netscaler.c b/wiretap/netscaler.c index dd3cb22c3b..779f08f424 100644 --- a/wiretap/netscaler.c +++ b/wiretap/netscaler.c @@ -23,7 +23,6 @@ #include <string.h> #include "wtap-int.h" #include "file_wrappers.h" -#include <wsutil/buffer.h> #include "netscaler.h" /* Defines imported from netscaler code: nsperfrc.h */ @@ -127,7 +126,7 @@ typedef struct nspr_hd_v20 ** The short header size can be 0-127 bytes long. If MS Bit of ph_RecordSize ** is set then record size has 2 bytes */ -#define NSPR_V20RECORDSIZE_2BYTES 0x80 +#define NSPR_V20RECORDSIZE_2BYTES 0x80U /* Performance Data Header with device number */ typedef struct nspr_headerdev_v10 @@ -215,9 +214,8 @@ typedef struct nspr_pktracefull_v10 { nspr_headerdev_v10_t phd; /* performance header */ guint8 fp_RelTimeHr[4]; /* High resolution relative time */ - guint8 fp_Data[1]; /* packet data starts here */ } nspr_pktracefull_v10_t; -#define nspr_pktracefull_v10_s (nspr_hdev_v10_s + 4) +#define nspr_pktracefull_v10_s ((guint32)(sizeof(nspr_pktracefull_v10_t))) /* new full packet trace structure v20 */ typedef struct nspr_pktracefull_v20 @@ -225,9 +223,8 @@ typedef struct nspr_pktracefull_v20 NSPR_HEADER3B_V20(fp); /* long performance header */ guint8 fp_DevNo; /* Network Device (NIC) number */ guint8 fp_RelTimeHr[4]; /* High resolution relative time */ - guint8 fp_Data[4]; /* packet data starts here */ } nspr_pktracefull_v20_t; -#define nspr_pktracefull_v20_s ((guint32)(sizeof(nspr_pktracefull_v20_t) - 4)) +#define nspr_pktracefull_v20_s ((guint32)(sizeof(nspr_pktracefull_v20_t))) /* new full packet trace structure v21 */ typedef struct nspr_pktracefull_v21 @@ -237,9 +234,8 @@ typedef struct nspr_pktracefull_v21 guint8 fp_RelTimeHr[4]; /* High resolution relative time */ guint8 fp_PcbDevNo[4]; /* PCB devno */ guint8 fp_lPcbDevNo[4]; /* link PCB devno */ - guint8 fp_Data[4]; /* packet data starts here */ } nspr_pktracefull_v21_t; -#define nspr_pktracefull_v21_s ((guint32)(sizeof(nspr_pktracefull_v21_t) - 4)) +#define nspr_pktracefull_v21_s ((guint32)(sizeof(nspr_pktracefull_v21_t))) /* new full packet trace structure v22 */ typedef struct nspr_pktracefull_v22 @@ -250,9 +246,8 @@ typedef struct nspr_pktracefull_v22 guint8 fp_PcbDevNo[4]; /* PCB devno */ guint8 fp_lPcbDevNo[4]; /* link PCB devno */ guint8 fp_VlanTag[2]; /* vlan tag */ - guint8 fp_Data[2]; /* packet data starts here */ } nspr_pktracefull_v22_t; -#define nspr_pktracefull_v22_s ((guint32)(sizeof(nspr_pktracefull_v22_t) - 2)) +#define nspr_pktracefull_v22_s ((guint32)(sizeof(nspr_pktracefull_v22_t))) typedef struct nspr_pktracefull_v23 { @@ -263,9 +258,8 @@ typedef struct nspr_pktracefull_v23 guint8 fp_lPcbDevNo[4]; /* link PCB devno */ guint8 fp_VlanTag[2]; /* vlan tag */ guint8 fp_Coreid[2]; /* coreid of the packet */ - guint8 fp_Data[2]; /* packet data starts here */ } nspr_pktracefull_v23_t; -#define nspr_pktracefull_v23_s ((guint32)(sizeof(nspr_pktracefull_v23_t) - 2)) +#define nspr_pktracefull_v23_s ((guint32)(sizeof(nspr_pktracefull_v23_t))) /* New full packet trace structure v24 for cluster tracing */ typedef struct nspr_pktracefull_v24 @@ -280,9 +274,8 @@ typedef struct nspr_pktracefull_v24 guint8 fp_srcNodeId[2]; /* source node # */ guint8 fp_destNodeId[2]; /* destination node # */ guint8 fp_clFlags; /* cluster flags */ - guint8 fp_Data[2]; /* packet data starts here */ } nspr_pktracefull_v24_t; -#define nspr_pktracefull_v24_s ((guint32)(sizeof(nspr_pktracefull_v24_t) - 4)) +#define nspr_pktracefull_v24_s ((guint32)(sizeof(nspr_pktracefull_v24_t))) /* New full packet trace structure v25 for vm info tracing */ typedef struct nspr_pktracefull_v25 @@ -299,11 +292,8 @@ typedef struct nspr_pktracefull_v25 guint8 fp_clFlags; /* cluster flags */ guint8 fp_src_vmname_len; /* vm src info */ guint8 fp_dst_vmname_len; /* vm src info */ - guint8 fp_Data[4]; /* packet data starts here */ } nspr_pktracefull_v25_t; -#define nspr_pktracefull_v25_s ((guint32)(sizeof(nspr_pktracefull_v25_t) - 4)) -#define fp_src_vmname fp_Data -#define fp_src_vmname fp_Data +#define nspr_pktracefull_v25_s ((guint32)(sizeof(nspr_pktracefull_v25_t))) /* New full packet trace structure v26 for vm info tracing */ typedef struct nspr_pktracefull_v26 @@ -323,9 +313,8 @@ typedef struct nspr_pktracefull_v26 guint8 fp_reserved; guint8 fp_ns_activity[4]; guint8 fp_reserved_32[12]; /* Adding more field to reduce wireshark changes every time */ - guint8 fp_Data[4]; /* packet data starts here */ } nspr_pktracefull_v26_t; -#define nspr_pktracefull_v26_s ((guint32)(sizeof(nspr_pktracefull_v26_t) - 4)) +#define nspr_pktracefull_v26_s ((guint32)(sizeof(nspr_pktracefull_v26_t))) /* partial packet trace structure */ typedef struct nspr_pktracepart_v10 @@ -334,9 +323,8 @@ typedef struct nspr_pktracepart_v10 guint8 pp_RelTimeHr[4]; /* High resolution relative time */ guint8 pp_PktSizeOrg[2]; /* Original packet size */ guint8 pp_PktOffset[2]; /* starting offset in packet */ - guint8 pp_Data[1]; /* packet data starts here */ } nspr_pktracepart_v10_t; -#define nspr_pktracepart_v10_s (nspr_pktracefull_v10_s + 4) +#define nspr_pktracepart_v10_s ((guint32)(sizeof(nspr_pktracepart_v10_t))) /* new partial packet trace structure */ typedef struct nspr_pktracepart_v20 @@ -346,9 +334,8 @@ typedef struct nspr_pktracepart_v20 guint8 pp_RelTimeHr[4]; /* High resolution relative time */ guint8 pp_PktSizeOrg[2]; /* Original packet size */ guint8 pp_PktOffset[2]; /* starting offset in packet */ - guint8 pp_Data[4]; /* packet data starts here */ } nspr_pktracepart_v20_t; -#define nspr_pktracepart_v20_s ((guint32)(sizeof(nspr_pktracepart_v20_t) -4)) +#define nspr_pktracepart_v20_s ((guint32)(sizeof(nspr_pktracepart_v20_t))) /* new partial packet trace structure */ typedef struct nspr_pktracepart_v21 @@ -360,9 +347,8 @@ typedef struct nspr_pktracepart_v21 guint8 pp_PktOffset[2]; /* starting offset in packet */ guint8 pp_PcbDevNo[4]; /* PCB devno */ guint8 pp_lPcbDevNo[4]; /* link PCB devno */ - guint8 pp_Data[4]; /* packet data starts here */ } nspr_pktracepart_v21_t; -#define nspr_pktracepart_v21_s ((guint32)(sizeof(nspr_pktracepart_v21_t) -4)) +#define nspr_pktracepart_v21_s ((guint32)(sizeof(nspr_pktracepart_v21_t))) /* new partial packet trace structure v22 */ typedef struct nspr_pktracepart_v22 @@ -375,9 +361,8 @@ typedef struct nspr_pktracepart_v22 guint8 pp_PcbDevNo[4]; /* PCB devno */ guint8 pp_lPcbDevNo[4]; /* link PCB devno */ guint8 pp_VlanTag[2]; /* Vlan Tag */ - guint8 pp_Data[2]; /* packet data starts here */ } nspr_pktracepart_v22_t; -#define nspr_pktracepart_v22_s ((guint32)(sizeof(nspr_pktracepart_v22_t) -2)) +#define nspr_pktracepart_v22_s ((guint32)(sizeof(nspr_pktracepart_v22_t))) typedef struct nspr_pktracepart_v23 { @@ -390,9 +375,8 @@ typedef struct nspr_pktracepart_v23 guint8 pp_lPcbDevNo[4]; /* link PCB devno */ guint8 pp_VlanTag[2]; /* vlan tag */ guint8 pp_Coreid[2]; /* Coreid of the packet */ - guint8 pp_Data[4]; /* packet data starts here */ } nspr_pktracepart_v23_t; -#define nspr_pktracepart_v23_s ((guint32)(sizeof(nspr_pktracepart_v23_t) -4)) +#define nspr_pktracepart_v23_s ((guint32)(sizeof(nspr_pktracepart_v23_t))) /* New partial packet trace structure v24 for cluster tracing */ typedef struct nspr_pktracepart_v24 @@ -409,9 +393,8 @@ typedef struct nspr_pktracepart_v24 guint8 pp_srcNodeId[2]; /* source node # */ guint8 pp_destNodeId[2]; /* destination node # */ guint8 pp_clFlags; /* cluster flags */ - guint8 pp_Data[4]; /* packet data starts here */ } nspr_pktracepart_v24_t; -#define nspr_pktracepart_v24_s ((guint32)(sizeof(nspr_pktracepart_v24_t) -4)) +#define nspr_pktracepart_v24_s ((guint32)(sizeof(nspr_pktracepart_v24_t))) /* New partial packet trace structure v25 for vm info tracing */ typedef struct nspr_pktracepart_v25 @@ -430,12 +413,8 @@ typedef struct nspr_pktracepart_v25 guint8 pp_clFlags; /* cluster flags */ guint8 pp_src_vmname_len; /* vm info */ guint8 pp_dst_vmname_len; /* vm info */ - guint8 pp_Data[4]; /* packet data starts here */ } nspr_pktracepart_v25_t; -#define nspr_pktracepart_v25_s ((guint32)(sizeof(nspr_pktracepart_v25_t) -4)) -#define pp_src_vmname pp_Data -#define pp_dst_vmname pp_Data - +#define nspr_pktracepart_v25_s ((guint32)(sizeof(nspr_pktracepart_v25_t))) /* New full packet trace structure v30 for multipage spanning data */ typedef struct nspr_pktracefull_v30 @@ -456,11 +435,8 @@ typedef struct nspr_pktracefull_v30 guint8 fp_reserved[3]; guint8 fp_ns_activity[4]; guint8 fp_reserved_32[12]; - guint8 fp_Data[0]; /* packet data starts here */ } nspr_pktracefull_v30_t; #define nspr_pktracefull_v30_s ((guint32)(sizeof(nspr_pktracefull_v30_t))) -#define fp_src_vmname fp_Data -#define fp_dst_vmname fp_Data /* New partial packet trace structure v26 for vm info tracing */ typedef struct nspr_pktracepart_v26 @@ -482,49 +458,39 @@ typedef struct nspr_pktracepart_v26 guint8 pp_reserved; guint8 pp_ns_activity[4]; guint8 pp_reserved_32[12]; /* Adding more field to reduce wireshark changes every time */ - guint8 pp_Data[4]; /* packet data starts here */ } nspr_pktracepart_v26_t; -#define nspr_pktracepart_v26_s ((guint32)(sizeof(nspr_pktracepart_v26_t) -4)) +#define nspr_pktracepart_v26_s ((guint32)(sizeof(nspr_pktracepart_v26_t))) #define myoffsetof(type,fieldname) (&(((type*)0)->fieldname)) +#define __TNDO(phdr,enumprefix,structname,hdrname)\ + static const guint8 enumprefix##_##hdrname##_offset = (guint8)sizeof(nspr_##structname##_t); + #define __TNO(phdr,enumprefix,structprefix,structname,hdrname,structfieldname) \ - guint8 enumprefix##_##hdrname##_offset = (guint8)GPOINTER_TO_INT(myoffsetof(nspr_##structname##_t,structprefix##_##structfieldname)); + static const guint8 enumprefix##_##hdrname##_offset = (guint8)GPOINTER_TO_INT(myoffsetof(nspr_##structname##_t,structprefix##_##structfieldname)); #define __TNL(phdr,enumprefix,structprefix,structname,hdrname,structfieldname) \ - guint8 enumprefix##_##hdrname##_len = (guint8)sizeof(((nspr_##structname##_t*)0)->structprefix##_##structfieldname); + static const guint8 enumprefix##_##hdrname##_len = (guint8)sizeof(((nspr_##structname##_t*)0)->structprefix##_##structfieldname); #define __TNV1O(phdr,enumprefix,structprefix,structname,hdrname,structfieldname) \ - guint8 enumprefix##_##hdrname##_offset = (guint8)GPOINTER_TO_INT(myoffsetof(nspr_##structname##_t,structfieldname)); + static const guint8 enumprefix##_##hdrname##_offset = (guint8)GPOINTER_TO_INT(myoffsetof(nspr_##structname##_t,structfieldname)); #define __TNV1L(phdr,enumprefix,structprefix,structname,hdrname,structfieldname) \ - guint8 enumprefix##_##hdrname##_len = (guint8)sizeof(((nspr_##structname##_t*)0)->structfieldname); + static const guint8 enumprefix##_##hdrname##_len = (guint8)sizeof(((nspr_##structname##_t*)0)->structfieldname); #define TRACE_V10_REC_LEN_OFF(phdr,enumprefix,structprefix,structname) \ __TNV1O(phdr,enumprefix,structprefix,structname,dir,phd.ph_RecordType)\ __TNV1L(phdr,enumprefix,structprefix,structname,dir,phd.ph_RecordType)\ __TNV1O(phdr,enumprefix,structprefix,structname,nicno,phd.ph_DevNo)\ __TNV1L(phdr,enumprefix,structprefix,structname,nicno,phd.ph_DevNo)\ - __TNO(phdr,enumprefix,structprefix,structname,eth,Data) - -#define TRACE_FULL_V10_REC_LEN_OFF(phdr,enumprefix,structprefix,structname) \ - (phdr)->len = pletoh16(&(fp)->nsprRecordSize);\ - (phdr)->caplen = (phdr)->len;\ - TRACE_V10_REC_LEN_OFF(phdr,enumprefix,structprefix,structname) - -#define TRACE_PART_V10_REC_LEN_OFF(phdr,enumprefix,structprefix,structname) \ - (phdr)->rec_type = REC_TYPE_PACKET;\ - (phdr)->presence_flags |= WTAP_HAS_CAP_LEN;\ - (phdr)->len = pletoh16(&pp->pp_PktSizeOrg) + nspr_pktracepart_v10_s;\ - (phdr)->caplen = pletoh16(&pp->nsprRecordSize);\ - TRACE_V10_REC_LEN_OFF(phdr,enumprefix,structprefix,structname) + __TNDO(phdr,enumprefix,structname,eth) #define TRACE_V20_REC_LEN_OFF(phdr,enumprefix,structprefix,structname) \ __TNO(phdr,enumprefix,structprefix,structname,dir,RecordType)\ __TNL(phdr,enumprefix,structprefix,structname,dir,RecordType)\ __TNO(phdr,enumprefix,structprefix,structname,nicno,DevNo)\ __TNL(phdr,enumprefix,structprefix,structname,nicno,DevNo)\ - __TNO(phdr,enumprefix,structprefix,structname,eth,Data) + __TNDO(phdr,enumprefix,structname,eth) #define TRACE_V21_REC_LEN_OFF(phdr,enumprefix,structprefix,structname) \ TRACE_V20_REC_LEN_OFF(phdr,enumprefix,structprefix,structname)\ @@ -549,7 +515,7 @@ typedef struct nspr_pktracepart_v26 TRACE_V24_REC_LEN_OFF(phdr,enumprefix,structprefix,structname)\ __TNO(phdr,enumprefix,structprefix,structname,src_vmname_len,src_vmname_len)\ __TNO(phdr,enumprefix,structprefix,structname,dst_vmname_len,dst_vmname_len)\ - __TNO(phdr,enumprefix,structprefix,structname,data,Data) + __TNDO(phdr,enumprefix,structname,data) #define TRACE_V26_REC_LEN_OFF(phdr,enumprefix,structprefix,structname) \ TRACE_V25_REC_LEN_OFF(phdr,enumprefix,structprefix,structname)\ @@ -579,6 +545,7 @@ typedef struct nspr_pktracepart_v26 #undef __TNV1O #undef __TNV1L #undef __TNO +#undef __TNDO #undef __TNL @@ -603,8 +570,8 @@ typedef struct nspr_pktracepart_v26 typedef struct { gchar *pnstrace_buf; gint64 xxx_offset; - gint32 nstrace_buf_offset; - gint32 nstrace_buflen; + guint32 nstrace_buf_offset; + guint32 nstrace_buflen; /* Performance Monitor Time variables */ guint32 nspm_curtime; /* current time since 1970 */ guint64 nspm_curtimemsec; /* current time in milliseconds */ @@ -642,6 +609,49 @@ static guint64 ns_hrtime2nsec(guint32 tm); static gboolean nstrace_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr, const guint8 *pd, int *err); +/* backported compatibility defines */ +#define WTAP_ERR_UNWRITABLE_FILE_TYPE WTAP_ERR_UNSUPPORTED +#define WTAP_ERR_UNWRITABLE_REC_TYPE WTAP_ERR_UNSUPPORTED +#define WTAP_ERR_UNWRITABLE_ENCAP WTAP_ERR_UNSUPPORTED_ENCAP + +#define wtap_open_return_val int +#define WTAP_OPEN_ERROR -1 +#define WTAP_OPEN_NOT_MINE 0 +#define WTAP_OPEN_MINE 1 + +#define ws_buffer_assure_space buffer_assure_space +#define ws_buffer_free buffer_free +#define ws_buffer_init buffer_init +#define ws_buffer_start_ptr buffer_start_ptr + +/* + * Read a given number of bytes from a file. + * + * If we succeed, return TRUE. + * + * If we get fewer bytes than the specified number, including getting + * an EOF, return FALSE with *err set to WTAP_ERR_SHORT_READ, reporting + * this as a short read error. + * + * If we get a read error, return FALSE with *err and *err_info set + * appropriately. + */ +static gboolean +wtap_read_bytes(FILE_T fh, void *buf, unsigned int count, int *err, + gchar **err_info) +{ + int bytes_read; + + bytes_read = file_read(buf, count, fh); + if (bytes_read < 0 || (guint)bytes_read != count) { + *err = file_error(fh, err_info); + if (*err == 0) + *err = WTAP_ERR_SHORT_READ; + return FALSE; + } + return TRUE; +} + /* * Minimum of the page size and the amount of data left in the file; @@ -667,18 +677,16 @@ static guint64 ns_hrtime2nsec(guint32 tm) /* ** Netscaler trace format open routines */ -int nstrace_open(wtap *wth, int *err, gchar **err_info) +wtap_open_return_val nstrace_open(wtap *wth, int *err, gchar **err_info) { gchar *nstrace_buf; gint64 file_size; gint32 page_size; nstrace_t *nstrace; - int bytes_read; - errno = WTAP_ERR_CANT_READ; if ((file_size = wtap_file_size(wth, err)) == -1) - return 0; + return WTAP_OPEN_NOT_MINE; nstrace_buf = (gchar *)g_malloc(NSPR_PAGESIZE); page_size = GET_READ_PAGE_SIZE(file_size); @@ -703,24 +711,21 @@ int nstrace_open(wtap *wth, int *err, gchar **err_info) default: /* No known signature found, assume it's not NetScaler */ g_free(nstrace_buf); - return 0; + return WTAP_OPEN_NOT_MINE; } if ((file_seek(wth->fh, 0, SEEK_SET, err)) == -1) { - *err = file_error(wth->fh, err_info); g_free(nstrace_buf); - return 0; + return WTAP_OPEN_ERROR; } - bytes_read = file_read(nstrace_buf, page_size, wth->fh); - if (bytes_read != page_size) + if (!wtap_read_bytes(wth->fh, nstrace_buf, page_size, err, err_info)) { - *err = file_error(wth->fh, err_info); g_free(nstrace_buf); - if (*err != 0 && *err != WTAP_ERR_SHORT_READ) - return -1; - return 0; + if (*err != WTAP_ERR_SHORT_READ) + return WTAP_OPEN_ERROR; + return WTAP_OPEN_NOT_MINE; } switch (wth->file_type_subtype) @@ -761,20 +766,17 @@ int nstrace_open(wtap *wth, int *err, gchar **err_info) /* Reset the read pointer to start of the file. */ if ((file_seek(wth->fh, 0, SEEK_SET, err)) == -1) { - *err = file_error(wth->fh, err_info); g_free(nstrace->pnstrace_buf); g_free(nstrace); - return 0; + return WTAP_OPEN_ERROR; } /* Read the first page of data */ - bytes_read = file_read(nstrace_buf, page_size, wth->fh); - if (bytes_read != page_size) + if (!wtap_read_bytes(wth->fh, nstrace_buf, page_size, err, err_info)) { - *err = file_error(wth->fh, err_info); g_free(nstrace->pnstrace_buf); g_free(nstrace); - return 0; + return WTAP_OPEN_ERROR; } /* reset the buffer offset */ @@ -786,7 +788,7 @@ int nstrace_open(wtap *wth, int *err, gchar **err_info) wth->phdr.ts.nsecs = 0; *err = 0; - return 1; + return WTAP_OPEN_MINE; } @@ -831,10 +833,11 @@ nspm_signature_version(wtap *wth, gchar *nstrace_buf, gint32 len) (sigv20p->sig_RecordSize <= len) && ((gint32)sizeof(NSPR_SIGSTR_V20) <= len)) { - if (!nspm_signature_isv20(sigv20p->sig_Signature)) + if (!nspm_signature_isv20(sigv20p->sig_Signature)){ return WTAP_FILE_TYPE_SUBTYPE_NETSCALER_2_0; - else if (!nspm_signature_isv30(sigv20p->sig_Signature)) + } else if (!nspm_signature_isv30(sigv20p->sig_Signature)){ return WTAP_FILE_TYPE_SUBTYPE_NETSCALER_3_0; + } } #undef sigv20p } @@ -847,7 +850,7 @@ nspm_signature_version(wtap *wth, gchar *nstrace_buf, gint32 len) #define nspr_getv10recordsize(hdp) (pletoh16(&(hdp)->nsprRecordSize)) #define nspr_getv20recordtype(hdp) ((hdp)->phd_RecordType) #define nspr_getv20recordsize(hdp) \ - (((hdp)->phd_RecordSizeLow & NSPR_V20RECORDSIZE_2BYTES)? \ + (guint32)(((hdp)->phd_RecordSizeLow & NSPR_V20RECORDSIZE_2BYTES)? \ (((hdp)->phd_RecordSizeHigh * NSPR_V20RECORDSIZE_2BYTES)+ \ ((hdp)->phd_RecordSizeLow & ~NSPR_V20RECORDSIZE_2BYTES)) : \ (hdp)->phd_RecordSizeLow) @@ -858,9 +861,10 @@ nspm_signature_version(wtap *wth, gchar *nstrace_buf, gint32 len) {\ nstrace_t *nstrace = (nstrace_t *)wth->priv;\ gchar* nstrace_buf = nstrace->pnstrace_buf;\ - gint32 nstrace_buf_offset = nstrace->nstrace_buf_offset;\ - gint32 nstrace_buflen = nstrace->nstrace_buflen;\ + guint32 nstrace_buf_offset = nstrace->nstrace_buf_offset;\ + guint32 nstrace_buflen = nstrace->nstrace_buflen;\ int bytes_read;\ + guint32 record_size;\ do\ {\ while (nstrace_buf_offset < nstrace_buflen)\ @@ -877,13 +881,16 @@ nspm_signature_version(wtap *wth, gchar *nstrace_buf, gint32 len) nstrace_buf_offset = nstrace_buflen;\ break;\ default:\ - nstrace_buf_offset += nspr_getv##ver##recordsize(fp);\ + record_size = nspr_getv##ver##recordsize(fp);\ + if (record_size == 0)\ + return FALSE;\ + nstrace_buf_offset += record_size;\ }\ }\ nstrace_buf_offset = 0;\ nstrace->xxx_offset += nstrace_buflen;\ nstrace_buflen = GET_READ_PAGE_SIZE((nstrace->file_size - nstrace->xxx_offset));\ - }while((nstrace_buflen > 0) && (bytes_read = file_read(nstrace_buf, nstrace_buflen, wth->fh)) && bytes_read == nstrace_buflen); \ + }while((nstrace_buflen > 0) && (bytes_read = file_read(nstrace_buf, nstrace_buflen, wth->fh)) > 0 && (guint32)bytes_read == nstrace_buflen); \ return FALSE;\ } @@ -910,6 +917,9 @@ static gboolean nstrace_set_start_time(wtap *wth) return FALSE; } +#define __TNDO(phdr,enumprefix,structname,hdrname)\ + (phdr)->pseudo_header.nstr.hdrname##_offset = enumprefix##_##hdrname##_offset; + #define __TNO(phdr,enumprefix,structprefix,structname,hdrname,structfieldname) \ (phdr)->pseudo_header.nstr.hdrname##_offset = enumprefix##_##hdrname##_offset; @@ -927,15 +937,68 @@ static gboolean nstrace_set_start_time(wtap *wth) /* ** Netscaler trace format read routines. */ +#define TIMEDEFV10(phdr,fp,type) \ + do {\ + (phdr)->presence_flags = WTAP_HAS_TS;\ + nsg_creltime += ns_hrtime2nsec(pletoh32(&type->type##_RelTimeHr));\ + (phdr)->ts.secs = nstrace->nspm_curtime + (guint32) (nsg_creltime / 1000000000);\ + (phdr)->ts.nsecs = (guint32) (nsg_creltime % 1000000000);\ + }while(0) + +#define PARTSIZEDEFV10(phdr,pp,ver) \ + do {\ + (phdr)->presence_flags |= WTAP_HAS_CAP_LEN;\ + (phdr)->len = pletoh16(&pp->pp_PktSizeOrg) + nspr_pktracepart_v##ver##_s;\ + (phdr)->caplen = pletoh16(&pp->nsprRecordSize);\ + }while(0) + +#define FULLSIZEDEFV10(phdr,fp,ver) \ + do {\ + (phdr)->len = pletoh16(&(fp)->nsprRecordSize);\ + (phdr)->caplen = (phdr)->len;\ + }while(0) + +#define PACKET_DESCRIBE(phdr,FULLPART,fullpart,ver,type,HEADERVER) \ + do {\ + nspr_pktrace##fullpart##_v##ver##_t *type = (nspr_pktrace##fullpart##_v##ver##_t *) &nstrace_buf[nstrace_buf_offset];\ + /* Make sure the record header is entirely contained in the page */\ + if ((nstrace_buflen - nstrace_buf_offset) < sizeof *type) {\ + *err = WTAP_ERR_BAD_FILE;\ + *err_info = g_strdup("nstrace: record header crosses page boundary");\ + return FALSE;\ + }\ + /* Check sanity of record size */\ + if (pletoh16(&type->nsprRecordSize) < sizeof *type) {\ + *err = WTAP_ERR_BAD_FILE;\ + *err_info = g_strdup("nstrace: record size is less than record header size");\ + return FALSE;\ + }\ + (phdr)->rec_type = REC_TYPE_PACKET;\ + TIMEDEFV##ver((phdr),fp,type);\ + FULLPART##SIZEDEFV##ver((phdr),type,ver);\ + TRACE_V##ver##_REC_LEN_OFF((phdr),v##ver##_##fullpart,type,pktrace##fullpart##_v##ver);\ + /* Make sure the record is entirely contained in the page */\ + if ((nstrace_buflen - nstrace_buf_offset) < (phdr)->caplen) {\ + *err = WTAP_ERR_BAD_FILE;\ + *err_info = g_strdup("nstrace: record crosses page boundary");\ + return FALSE;\ + }\ + ws_buffer_assure_space(wth->frame_buffer, (phdr)->caplen);\ + memcpy(ws_buffer_start_ptr(wth->frame_buffer), type, (phdr)->caplen);\ + *data_offset = nstrace->xxx_offset + nstrace_buf_offset;\ + nstrace->nstrace_buf_offset = nstrace_buf_offset + (phdr)->caplen;\ + nstrace->nstrace_buflen = nstrace_buflen;\ + nstrace->nsg_creltime = nsg_creltime;\ + return TRUE;\ + }while(0) + static gboolean nstrace_read_v10(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) { nstrace_t *nstrace = (nstrace_t *)wth->priv; guint64 nsg_creltime = nstrace->nsg_creltime; gchar *nstrace_buf = nstrace->pnstrace_buf; - gint32 nstrace_buf_offset = nstrace->nstrace_buf_offset; - gint32 nstrace_buflen = nstrace->nstrace_buflen; - nspr_pktracefull_v10_t *fp; - nspr_pktracepart_v10_t *pp; + guint32 nstrace_buf_offset = nstrace->nstrace_buf_offset; + guint32 nstrace_buflen = nstrace->nstrace_buflen; int bytes_read; *err = 0; @@ -943,56 +1006,20 @@ static gboolean nstrace_read_v10(wtap *wth, int *err, gchar **err_info, gint64 * do { while ((nstrace_buf_offset < nstrace_buflen) && - ((nstrace_buflen - nstrace_buf_offset) >= ((gint32)sizeof(fp->nsprRecordType)))) + ((nstrace_buflen - nstrace_buf_offset) >= ((gint32)sizeof((( nspr_header_v10_t*)&nstrace_buf[nstrace_buf_offset])->ph_RecordType)))) { -#define GENERATE_CASE_FULL(phdr,type,acttype) \ - case NSPR_PDPKTRACEFULLTX_V##type:\ - case NSPR_PDPKTRACEFULLTXB_V##type:\ - case NSPR_PDPKTRACEFULLRX_V##type:\ - fp = (nspr_pktracefull_v10_t *) &nstrace_buf[nstrace_buf_offset];\ - /*\ - * XXX - we can't do this in the seek-read routine,\ - * as the time stamps in the records are relative to\ - * the previous packet.\ - */\ - (phdr)->rec_type = REC_TYPE_PACKET;\ - (phdr)->presence_flags = WTAP_HAS_TS;\ - nsg_creltime += ns_hrtime2nsec(pletoh32(&fp->fp_RelTimeHr));\ - (phdr)->ts.secs = nstrace->nspm_curtime + (guint32) (nsg_creltime / 1000000000);\ - (phdr)->ts.nsecs = (guint32) (nsg_creltime % 1000000000);\ - TRACE_FULL_V##type##_REC_LEN_OFF(phdr,v##type##_full,fp,pktracefull_v##type);\ - buffer_assure_space(wth->frame_buffer, (phdr)->caplen);\ - memcpy(buffer_start_ptr(wth->frame_buffer), fp, (phdr)->caplen);\ - *data_offset = nstrace->xxx_offset + nstrace_buf_offset;\ - nstrace->nstrace_buf_offset = nstrace_buf_offset + (phdr)->len;\ - nstrace->nstrace_buflen = nstrace_buflen;\ - nstrace->nsg_creltime = nsg_creltime;\ - return TRUE; - -#define GENERATE_CASE_PART(phdr,type,acttype) \ - case NSPR_PDPKTRACEPARTTX_V##type:\ - case NSPR_PDPKTRACEPARTTXB_V##type:\ - case NSPR_PDPKTRACEPARTRX_V##type:\ - pp = (nspr_pktracepart_v10_t *) &nstrace_buf[nstrace_buf_offset];\ - /*\ - * XXX - we can't do this in the seek-read routine,\ - * as the time stamps in the records are relative to\ - * the previous packet.\ - */\ - (phdr)->rec_type = REC_TYPE_PACKET;\ - (phdr)->presence_flags = WTAP_HAS_TS;\ - nsg_creltime += ns_hrtime2nsec(pletoh32(&pp->pp_RelTimeHr));\ - (phdr)->ts.secs = nstrace->nspm_curtime + (guint32) (nsg_creltime / 1000000000);\ - (phdr)->ts.nsecs = (guint32) (nsg_creltime % 1000000000);\ - TRACE_PART_V##type##_REC_LEN_OFF(phdr,v##type##_part,pp,pktracepart_v##type);\ - buffer_assure_space(wth->frame_buffer, (phdr)->caplen);\ - memcpy(buffer_start_ptr(wth->frame_buffer), pp, (phdr)->caplen);\ - *data_offset = nstrace->xxx_offset + nstrace_buf_offset;\ - nstrace->nstrace_buf_offset = nstrace_buf_offset + (phdr)->caplen;\ - nstrace->nsg_creltime = nsg_creltime;\ - nstrace->nstrace_buflen = nstrace_buflen;\ - return TRUE;\ +#define GENERATE_CASE_FULL(phdr,ver,HEADERVER) \ + case NSPR_PDPKTRACEFULLTX_V##ver:\ + case NSPR_PDPKTRACEFULLTXB_V##ver:\ + case NSPR_PDPKTRACEFULLRX_V##ver:\ + PACKET_DESCRIBE(phdr,FULL,full,ver,fp,HEADERVER); + +#define GENERATE_CASE_PART(phdr,ver,HEADERVER) \ + case NSPR_PDPKTRACEPARTTX_V##ver:\ + case NSPR_PDPKTRACEPARTTXB_V##ver:\ + case NSPR_PDPKTRACEPARTRX_V##ver:\ + PACKET_DESCRIBE(phdr,PART,part,ver,pp,HEADERVER); switch (pletoh16(&(( nspr_header_v10_t*)&nstrace_buf[nstrace_buf_offset])->ph_RecordType)) { @@ -1002,121 +1029,138 @@ static gboolean nstrace_read_v10(wtap *wth, int *err, gchar **err_info, gint64 * #undef GENERATE_CASE_FULL #undef GENERATE_CASE_PART - case NSPR_ABSTIME_V10: - - fp = (nspr_pktracefull_v10_t *) &nstrace_buf[nstrace_buf_offset]; - ns_setabstime(nstrace, pletoh32(((nspr_abstime_v10_t *) fp)->abs_Time), pletoh32(&((nspr_abstime_v10_t *) fp)->abs_RelTime)); - nstrace_buf_offset += pletoh16(&fp->nsprRecordSize); - break; - - case NSPR_RELTIME_V10: - - fp = (nspr_pktracefull_v10_t *) &nstrace_buf[nstrace_buf_offset]; - ns_setrelativetime(nstrace, pletoh32(((nspr_abstime_v10_t *) fp)->abs_RelTime)); - nstrace_buf_offset += pletoh16(&fp->nsprRecordSize); - break; - - case NSPR_UNUSEDSPACE_V10: + case NSPR_ABSTIME_V10: + { + nspr_pktracefull_v10_t *fp = (nspr_pktracefull_v10_t *) &nstrace_buf[nstrace_buf_offset]; + if (pletoh16(&fp->nsprRecordSize) == 0) { + *err = WTAP_ERR_BAD_FILE; + *err_info = g_strdup("nstrace: zero size record found"); + return FALSE; + } + ns_setabstime(nstrace, pletoh32(((nspr_abstime_v10_t *) fp)->abs_Time), pletoh32(&((nspr_abstime_v10_t *) fp)->abs_RelTime)); + nstrace_buf_offset += pletoh16(&fp->nsprRecordSize); + break; + } - nstrace_buf_offset = nstrace_buflen; - break; + case NSPR_RELTIME_V10: + { + nspr_pktracefull_v10_t *fp = (nspr_pktracefull_v10_t *) &nstrace_buf[nstrace_buf_offset]; + if (pletoh16(&fp->nsprRecordSize) == 0) { + *err = WTAP_ERR_BAD_FILE; + *err_info = g_strdup("nstrace: zero size record found"); + return FALSE; + } + ns_setrelativetime(nstrace, pletoh32(((nspr_abstime_v10_t *) fp)->abs_RelTime)); + nstrace_buf_offset += pletoh16(&fp->nsprRecordSize); + break; + } - default: + case NSPR_UNUSEDSPACE_V10: + nstrace_buf_offset = nstrace_buflen; + break; - fp = (nspr_pktracefull_v10_t *) &nstrace_buf[nstrace_buf_offset]; - nstrace_buf_offset += pletoh16(&fp->nsprRecordSize); - break; + default: + { + nspr_pktracefull_v10_t *fp = (nspr_pktracefull_v10_t *) &nstrace_buf[nstrace_buf_offset]; + if (pletoh16(&fp->nsprRecordSize) == 0) { + *err = WTAP_ERR_BAD_FILE; + *err_info = g_strdup("nstrace: zero size record found"); + return FALSE; + } + nstrace_buf_offset += pletoh16(&fp->nsprRecordSize); + break; + } } } nstrace_buf_offset = 0; nstrace->xxx_offset += nstrace_buflen; nstrace_buflen = GET_READ_PAGE_SIZE((nstrace->file_size - nstrace->xxx_offset)); - }while((nstrace_buflen > 0) && (bytes_read = file_read(nstrace_buf, nstrace_buflen, wth->fh)) && (bytes_read == nstrace_buflen)); + }while((nstrace_buflen > 0) && (bytes_read = file_read(nstrace_buf, nstrace_buflen, wth->fh)) > 0 && ((guint32)bytes_read == nstrace_buflen)); return FALSE; } -#define TIMEDEFV20(fp,type) \ - do {\ - wth->phdr.rec_type = REC_TYPE_PACKET;\ - wth->phdr.presence_flags |= WTAP_HAS_TS;\ - nsg_creltime += ns_hrtime2nsec(pletoh32(fp->type##_RelTimeHr));\ - wth->phdr.ts.secs = nstrace->nspm_curtime + (guint32) (nsg_creltime / 1000000000);\ - wth->phdr.ts.nsecs = (guint32) (nsg_creltime % 1000000000);\ - }while(0) +#undef PACKET_DESCRIBE -#define TIMEDEFV23(fp,type) \ +#define TIMEDEFV20(phdr,fp,type) \ do {\ - wth->phdr.rec_type = REC_TYPE_PACKET;\ - wth->phdr.presence_flags |= WTAP_HAS_TS;\ - /* access _AbsTimeHr as a 64bit value */\ - nsg_creltime = pletoh64(fp->type##_AbsTimeHr);\ - wth->phdr.ts.secs = (guint32) (nsg_creltime / 1000000000);\ - wth->phdr.ts.nsecs = (guint32) (nsg_creltime % 1000000000);\ + (phdr)->presence_flags = WTAP_HAS_TS;\ + nsg_creltime += ns_hrtime2nsec(pletoh32(fp->type##_RelTimeHr));\ + (phdr)->ts.secs = nstrace->nspm_curtime + (guint32) (nsg_creltime / 1000000000);\ + (phdr)->ts.nsecs = (guint32) (nsg_creltime % 1000000000);\ }while(0) -#define TIMEDEFV30(fp,type) \ +#define TIMEDEFV23(phdr,fp,type) \ do {\ - wth->phdr.rec_type = REC_TYPE_PACKET;\ - wth->phdr.presence_flags |= WTAP_HAS_TS;\ + (phdr)->presence_flags = WTAP_HAS_TS;\ /* access _AbsTimeHr as a 64bit value */\ nsg_creltime = pletoh64(fp->type##_AbsTimeHr);\ - wth->phdr.ts.secs = (guint32) (nsg_creltime / 1000000000);\ - wth->phdr.ts.nsecs = (guint32) (nsg_creltime % 1000000000);\ + (phdr)->ts.secs = (guint32) (nsg_creltime / 1000000000);\ + (phdr)->ts.nsecs = (guint32) (nsg_creltime % 1000000000);\ }while(0) -#define TIMEDEFV21(fp,type) TIMEDEFV20(fp,type) -#define TIMEDEFV22(fp,type) TIMEDEFV20(fp,type) -#define TIMEDEFV24(fp,type) TIMEDEFV23(fp,type) -#define TIMEDEFV25(fp,type) TIMEDEFV24(fp,type) -#define TIMEDEFV26(fp,type) TIMEDEFV24(fp,type) +#define TIMEDEFV21(phdr,fp,type) TIMEDEFV20(phdr,fp,type) +#define TIMEDEFV22(phdr,fp,type) TIMEDEFV20(phdr,fp,type) +#define TIMEDEFV24(phdr,fp,type) TIMEDEFV23(phdr,fp,type) +#define TIMEDEFV25(phdr,fp,type) TIMEDEFV24(phdr,fp,type) +#define TIMEDEFV26(phdr,fp,type) TIMEDEFV24(phdr,fp,type) -#define PPSIZEDEFV20(phdr,pp,ver) \ +#define PARTSIZEDEFV20(phdr,pp,ver) \ do {\ - (phdr)->rec_type = REC_TYPE_PACKET;\ (phdr)->presence_flags |= WTAP_HAS_CAP_LEN;\ (phdr)->len = pletoh16(&pp->pp_PktSizeOrg) + nspr_pktracepart_v##ver##_s;\ (phdr)->caplen = nspr_getv20recordsize((nspr_hd_v20_t *)pp);\ }while(0) -#define PPSIZEDEFV21(phdr,pp,ver) PPSIZEDEFV20(phdr,pp,ver) -#define PPSIZEDEFV22(phdr,pp,ver) PPSIZEDEFV20(phdr,pp,ver) -#define PPSIZEDEFV23(phdr,pp,ver) PPSIZEDEFV20(phdr,pp,ver) -#define PPSIZEDEFV24(phdr,pp,ver) PPSIZEDEFV20(phdr,pp,ver) -#define PPSIZEDEFV25(phdr,pp,ver) PPSIZEDEFV20(phdr,pp,ver) -#define PPSIZEDEFV26(phdr,pp,ver) PPSIZEDEFV20(phdr,pp,ver) +#define PARTSIZEDEFV21(phdr,pp,ver) PARTSIZEDEFV20(phdr,pp,ver) +#define PARTSIZEDEFV22(phdr,pp,ver) PARTSIZEDEFV20(phdr,pp,ver) +#define PARTSIZEDEFV23(phdr,pp,ver) PARTSIZEDEFV20(phdr,pp,ver) +#define PARTSIZEDEFV24(phdr,pp,ver) PARTSIZEDEFV20(phdr,pp,ver) +#define PARTSIZEDEFV25(phdr,pp,ver) PARTSIZEDEFV20(phdr,pp,ver) +#define PARTSIZEDEFV26(phdr,pp,ver) PARTSIZEDEFV20(phdr,pp,ver) -#define FPSIZEDEFV20(phdr,fp,ver)\ +#define FULLSIZEDEFV20(phdr,fp,ver)\ do {\ (phdr)->len = nspr_getv20recordsize((nspr_hd_v20_t *)fp);\ (phdr)->caplen = (phdr)->len;\ }while(0) -#define FPSIZEDEFV21(phdr,fp,ver) FPSIZEDEFV20(phdr,fp,ver) -#define FPSIZEDEFV22(phdr,fp,ver) FPSIZEDEFV20(phdr,fp,ver) -#define FPSIZEDEFV23(phdr,fp,ver) FPSIZEDEFV20(phdr,fp,ver) -#define FPSIZEDEFV24(phdr,fp,ver) FPSIZEDEFV20(phdr,fp,ver) -#define FPSIZEDEFV25(phdr,fp,ver) FPSIZEDEFV20(phdr,fp,ver) -#define FPSIZEDEFV26(phdr,fp,ver) FPSIZEDEFV20(phdr,fp,ver) +#define FULLSIZEDEFV21(phdr,fp,ver) FULLSIZEDEFV20(phdr,fp,ver) +#define FULLSIZEDEFV22(phdr,fp,ver) FULLSIZEDEFV20(phdr,fp,ver) +#define FULLSIZEDEFV23(phdr,fp,ver) FULLSIZEDEFV20(phdr,fp,ver) +#define FULLSIZEDEFV24(phdr,fp,ver) FULLSIZEDEFV20(phdr,fp,ver) +#define FULLSIZEDEFV25(phdr,fp,ver) FULLSIZEDEFV20(phdr,fp,ver) +#define FULLSIZEDEFV26(phdr,fp,ver) FULLSIZEDEFV20(phdr,fp,ver) -#define FPSIZEDEFV30(phdr,fp,ver)\ - do {\ - (phdr)->rec_type = REC_TYPE_PACKET;\ - (phdr)->presence_flags |= WTAP_HAS_CAP_LEN;\ - (phdr)->len = pletoh16(&fp->fp_PktSizeOrg) + nspr_pktracefull_v##ver##_s;\ - (phdr)->caplen = nspr_getv20recordsize((nspr_hd_v20_t *)fp);\ - }while(0) - -#define PACKET_DESCRIBE(phdr,FPTIMEDEF,SIZEDEF,ver,enumprefix,type,structname,TYPE)\ +#define PACKET_DESCRIBE(phdr,FULLPART,ver,enumprefix,type,structname,HEADERVER)\ do {\ nspr_##structname##_t *fp= (nspr_##structname##_t*)&nstrace_buf[nstrace_buf_offset];\ - TIMEDEFV##ver(fp,type);\ - SIZEDEF##ver((phdr),fp,ver);\ + /* Make sure the record header is entirely contained in the page */\ + if ((nstrace_buflen - nstrace_buf_offset) < sizeof *fp) {\ + *err = WTAP_ERR_BAD_FILE;\ + *err_info = g_strdup("nstrace: record header crosses page boundary");\ + return FALSE;\ + }\ + /* Check sanity of record size */\ + if (nspr_getv20recordsize((nspr_hd_v20_t *)fp) < sizeof *fp) {\ + *err = WTAP_ERR_BAD_FILE;\ + *err_info = g_strdup("nstrace: record size is less than record header size");\ + return FALSE;\ + }\ + (phdr)->rec_type = REC_TYPE_PACKET;\ + TIMEDEFV##ver((phdr),fp,type);\ + FULLPART##SIZEDEFV##ver((phdr),fp,ver);\ TRACE_V##ver##_REC_LEN_OFF((phdr),enumprefix,type,structname);\ - (phdr)->pseudo_header.nstr.rec_type = NSPR_HEADER_VERSION##TYPE;\ - buffer_assure_space(wth->frame_buffer, (phdr)->caplen);\ - memcpy(buffer_start_ptr(wth->frame_buffer), fp, (phdr)->caplen);\ + (phdr)->pseudo_header.nstr.rec_type = NSPR_HEADER_VERSION##HEADERVER;\ + /* Make sure the record is entirely contained in the page */\ + if ((nstrace_buflen - nstrace_buf_offset) < (phdr)->caplen) {\ + *err = WTAP_ERR_BAD_FILE;\ + *err_info = g_strdup("nstrace: record crosses page boundary");\ + return FALSE;\ + }\ + ws_buffer_assure_space(wth->frame_buffer, (phdr)->caplen);\ + memcpy(ws_buffer_start_ptr(wth->frame_buffer), fp, (phdr)->caplen);\ *data_offset = nstrace->xxx_offset + nstrace_buf_offset;\ nstrace->nstrace_buf_offset = nstrace_buf_offset + nspr_getv20recordsize((nspr_hd_v20_t *)fp);\ nstrace->nstrace_buflen = nstrace_buflen;\ @@ -1129,8 +1173,8 @@ static gboolean nstrace_read_v20(wtap *wth, int *err, gchar **err_info, gint64 * nstrace_t *nstrace = (nstrace_t *)wth->priv; guint64 nsg_creltime = nstrace->nsg_creltime; gchar *nstrace_buf = nstrace->pnstrace_buf; - gint32 nstrace_buf_offset = nstrace->nstrace_buf_offset; - gint32 nstrace_buflen = nstrace->nstrace_buflen; + guint32 nstrace_buf_offset = nstrace->nstrace_buf_offset; + guint32 nstrace_buflen = nstrace->nstrace_buflen; int bytes_read; *err = 0; @@ -1143,31 +1187,31 @@ static gboolean nstrace_read_v20(wtap *wth, int *err, gchar **err_info, gint64 * switch ((( nspr_hd_v20_t*)&nstrace_buf[nstrace_buf_offset])->phd_RecordType) { -#define GENERATE_CASE_FULL(phdr,type,acttype) \ - case NSPR_PDPKTRACEFULLTX_V##type:\ - case NSPR_PDPKTRACEFULLTXB_V##type:\ - case NSPR_PDPKTRACEFULLRX_V##type:\ - PACKET_DESCRIBE(phdr,TIMEDEF,FPSIZEDEFV,type,v##type##_full,fp,pktracefull_v##type,acttype); - -#define GENERATE_CASE_FULL_V25(phdr,type,acttype) \ - case NSPR_PDPKTRACEFULLTX_V##type:\ - case NSPR_PDPKTRACEFULLTXB_V##type:\ - case NSPR_PDPKTRACEFULLRX_V##type:\ - case NSPR_PDPKTRACEFULLNEWRX_V##type:\ - PACKET_DESCRIBE(phdr,TIMEDEF,FPSIZEDEFV,type,v##type##_full,fp,pktracefull_v##type,acttype); - -#define GENERATE_CASE_PART(phdr,type,acttype) \ - case NSPR_PDPKTRACEPARTTX_V##type:\ - case NSPR_PDPKTRACEPARTTXB_V##type:\ - case NSPR_PDPKTRACEPARTRX_V##type:\ - PACKET_DESCRIBE(phdr,TIMEDEF,PPSIZEDEFV,type,v##type##_part,pp,pktracepart_v##type,acttype); - -#define GENERATE_CASE_PART_V25(phdr,type,acttype) \ - case NSPR_PDPKTRACEPARTTX_V##type:\ - case NSPR_PDPKTRACEPARTTXB_V##type:\ - case NSPR_PDPKTRACEPARTRX_V##type:\ - case NSPR_PDPKTRACEPARTNEWRX_V##type:\ - PACKET_DESCRIBE(phdr,TIMEDEF,PPSIZEDEFV,type,v##type##_part,pp,pktracepart_v##type,acttype); +#define GENERATE_CASE_FULL(phdr,ver,HEADERVER) \ + case NSPR_PDPKTRACEFULLTX_V##ver:\ + case NSPR_PDPKTRACEFULLTXB_V##ver:\ + case NSPR_PDPKTRACEFULLRX_V##ver:\ + PACKET_DESCRIBE(phdr,FULL,ver,v##ver##_full,fp,pktracefull_v##ver,HEADERVER); + +#define GENERATE_CASE_FULL_V25(phdr,ver,HEADERVER) \ + case NSPR_PDPKTRACEFULLTX_V##ver:\ + case NSPR_PDPKTRACEFULLTXB_V##ver:\ + case NSPR_PDPKTRACEFULLRX_V##ver:\ + case NSPR_PDPKTRACEFULLNEWRX_V##ver:\ + PACKET_DESCRIBE(phdr,FULL,ver,v##ver##_full,fp,pktracefull_v##ver,HEADERVER); + +#define GENERATE_CASE_PART(phdr,ver,HEADERVER) \ + case NSPR_PDPKTRACEPARTTX_V##ver:\ + case NSPR_PDPKTRACEPARTTXB_V##ver:\ + case NSPR_PDPKTRACEPARTRX_V##ver:\ + PACKET_DESCRIBE(phdr,PART,ver,v##ver##_part,pp,pktracepart_v##ver,HEADERVER); + +#define GENERATE_CASE_PART_V25(phdr,ver,HEADERVER) \ + case NSPR_PDPKTRACEPARTTX_V##ver:\ + case NSPR_PDPKTRACEPARTTXB_V##ver:\ + case NSPR_PDPKTRACEPARTRX_V##ver:\ + case NSPR_PDPKTRACEPARTNEWRX_V##ver:\ + PACKET_DESCRIBE(phdr,PART,ver,v##ver##_part,pp,pktracepart_v##ver,HEADERVER); GENERATE_CASE_FULL(&wth->phdr,20,200); GENERATE_CASE_PART(&wth->phdr,20,200); @@ -1192,6 +1236,11 @@ static gboolean nstrace_read_v20(wtap *wth, int *err, gchar **err_info, gint64 * case NSPR_ABSTIME_V20: { nspr_pktracefull_v20_t *fp20 = (nspr_pktracefull_v20_t *) &nstrace_buf[nstrace_buf_offset]; + if (nspr_getv20recordsize((nspr_hd_v20_t *)fp20) == 0) { + *err = WTAP_ERR_BAD_FILE; + *err_info = g_strdup("nstrace: zero size record found"); + return FALSE; + } nstrace_buf_offset += nspr_getv20recordsize((nspr_hd_v20_t *)fp20); ns_setabstime(nstrace, pletoh32(&((nspr_abstime_v20_t *) fp20)->abs_Time), pletoh16(&((nspr_abstime_v20_t *) fp20)->abs_RelTime)); break; @@ -1200,6 +1249,11 @@ static gboolean nstrace_read_v20(wtap *wth, int *err, gchar **err_info, gint64 * case NSPR_RELTIME_V20: { nspr_pktracefull_v20_t *fp20 = (nspr_pktracefull_v20_t *) &nstrace_buf[nstrace_buf_offset]; + if (nspr_getv20recordsize((nspr_hd_v20_t *)fp20) == 0) { + *err = WTAP_ERR_BAD_FILE; + *err_info = g_strdup("nstrace: zero size record found"); + return FALSE; + } ns_setrelativetime(nstrace, pletoh16(&((nspr_abstime_v20_t *) fp20)->abs_RelTime)); nstrace_buf_offset += nspr_getv20recordsize((nspr_hd_v20_t *)fp20); break; @@ -1217,6 +1271,11 @@ static gboolean nstrace_read_v20(wtap *wth, int *err, gchar **err_info, gint64 * default: { nspr_pktracefull_v20_t *fp20 = (nspr_pktracefull_v20_t *) &nstrace_buf[nstrace_buf_offset]; + if (nspr_getv20recordsize((nspr_hd_v20_t *)fp20) == 0) { + *err = WTAP_ERR_BAD_FILE; + *err_info = g_strdup("nstrace: zero size record found"); + return FALSE; + } nstrace_buf_offset += nspr_getv20recordsize((nspr_hd_v20_t *)fp20); break; } @@ -1226,86 +1285,140 @@ static gboolean nstrace_read_v20(wtap *wth, int *err, gchar **err_info, gint64 * nstrace_buf_offset = 0; nstrace->xxx_offset += nstrace_buflen; nstrace_buflen = GET_READ_PAGE_SIZE((nstrace->file_size - nstrace->xxx_offset)); - }while((nstrace_buflen > 0) && (bytes_read = file_read(nstrace_buf, nstrace_buflen, wth->fh)) && (bytes_read == nstrace_buflen)); + }while((nstrace_buflen > 0) && (bytes_read = file_read(nstrace_buf, nstrace_buflen, wth->fh)) > 0 && ((guint32)bytes_read == nstrace_buflen)); return FALSE; } #undef PACKET_DESCRIBE -#define PACKET_DESCRIBE(phdr,FPTIMEDEF,SIZEDEF,ver,enumprefix,type,structname,TYPE)\ +#define SETETHOFFSET_30(phdr) ;\ + +#define TIMEDEFV30(phdr,fp,type) \ do {\ - nspr_##structname##_t *fp = (nspr_##structname##_t *) &nstrace_buf[nstrace_buf_offset];\ - TIMEDEFV##ver(fp,type);\ - SIZEDEF##ver((phdr),fp,ver);\ - TRACE_V##ver##_REC_LEN_OFF((phdr),enumprefix,type,structname);\ - (phdr)->pseudo_header.nstr.rec_type = NSPR_HEADER_VERSION##TYPE;\ - buffer_assure_space(wth->frame_buffer, (phdr)->caplen);\ - *data_offset = nstrace->xxx_offset + nstrace_buf_offset;\ - while (nstrace_tmpbuff_off < nspr_##structname##_s) {\ - nstrace_tmpbuff[nstrace_tmpbuff_off++] = nstrace_buf[nstrace_buf_offset++];\ - }\ - nst_dataSize = nspr_getv20recordsize(hdp);\ - rec_size = nst_dataSize - nstrace_tmpbuff_off;\ - nsg_nextPageOffset = ((nstrace_buf_offset + rec_size) >= NSPR_PAGESIZE_TRACE) ?\ - ((nstrace_buf_offset + rec_size) - (NSPR_PAGESIZE_TRACE - 1)) : 0;\ - while (nsg_nextPageOffset) {\ - while (nstrace_buf_offset < NSPR_PAGESIZE_TRACE) {\ - nstrace_tmpbuff[nstrace_tmpbuff_off++] = nstrace_buf[nstrace_buf_offset++];\ + (phdr)->presence_flags = WTAP_HAS_TS;\ + /* access _AbsTimeHr as a 64bit value */\ + nsg_creltime = pletoh64(fp->type##_AbsTimeHr);\ + (phdr)->ts.secs = (guint32) (nsg_creltime / 1000000000);\ + (phdr)->ts.nsecs = (guint32) (nsg_creltime % 1000000000);\ + }while(0) + +#define FULLSIZEDEFV30(phdr,fp,ver)\ + do {\ + (phdr)->presence_flags |= WTAP_HAS_CAP_LEN;\ + (phdr)->len = pletoh16(&fp->fp_PktSizeOrg) + nspr_pktracefull_v##ver##_s + fp->fp_src_vmname_len + fp->fp_dst_vmname_len;\ + (phdr)->caplen = nspr_getv20recordsize((nspr_hd_v20_t *)fp);\ + }while(0) + +#define PACKET_DESCRIBE(phdr,FULLPART,ver,enumprefix,type,structname,HEADERVER)\ + do {\ + nspr_##structname##_t *fp = (nspr_##structname##_t *) &nstrace_buf[nstrace_buf_offset];\ + /* Make sure the record header is entirely contained in the page */\ + if ((nstrace->nstrace_buflen - nstrace_buf_offset) < sizeof *fp) {\ + *err = WTAP_ERR_BAD_FILE;\ + *err_info = g_strdup("nstrace: record header crosses page boundary");\ + return FALSE;\ }\ - nstrace_buflen = NSPR_PAGESIZE_TRACE;\ - nstrace->xxx_offset += nstrace_buflen;\ - bytes_read = file_read(nstrace_buf, NSPR_PAGESIZE_TRACE, wth->fh);\ - if (bytes_read != NSPR_PAGESIZE_TRACE) {\ + (phdr)->rec_type = REC_TYPE_PACKET;\ + TIMEDEFV##ver((phdr),fp,type);\ + FULLPART##SIZEDEFV##ver((phdr),fp,ver);\ + TRACE_V##ver##_REC_LEN_OFF((phdr),enumprefix,type,structname);\ + SETETHOFFSET_##ver(phdr)\ + (phdr)->pseudo_header.nstr.rec_type = NSPR_HEADER_VERSION##HEADERVER;\ + /* Check sanity of record size */\ + if ((phdr)->caplen < sizeof *fp) {\ + *err = WTAP_ERR_BAD_FILE;\ + *err_info = g_strdup("nstrace: record size is less than record header size");\ return FALSE;\ - } else {\ - nstrace_buf_offset = 0;\ }\ + ws_buffer_assure_space(wth->frame_buffer, (phdr)->caplen);\ + *data_offset = nstrace->xxx_offset + nstrace_buf_offset;\ + /* Copy record header */\ + while (nstrace_tmpbuff_off < nspr_##structname##_s) {\ + nstrace_tmpbuff[nstrace_tmpbuff_off++] = nstrace_buf[nstrace_buf_offset++];\ + }\ + nst_dataSize = nspr_getv20recordsize(hdp);\ rec_size = nst_dataSize - nstrace_tmpbuff_off;\ - nsg_nextPageOffset = ((nstrace_buf_offset + rec_size) >= NSPR_PAGESIZE_TRACE) ?\ - ((nstrace_buf_offset + rec_size) - (NSPR_PAGESIZE_TRACE- 1)): 0;\ - } \ - while (nstrace_tmpbuff_off < nst_dataSize) {\ - nstrace_tmpbuff[nstrace_tmpbuff_off++] = nstrace_buf[nstrace_buf_offset++];\ - }\ - memcpy(buffer_start_ptr(wth->frame_buffer), nstrace_tmpbuff, (phdr)->caplen);\ - nstrace->nstrace_buf_offset = nstrace_buf_offset;\ - nstrace->nstrace_buflen = nstrace_buflen = ((gint32)NSPR_PAGESIZE_TRACE);\ - nstrace->nsg_creltime = nsg_creltime;\ - return TRUE;\ -} while(0) + nsg_nextPageOffset = ((nstrace_buf_offset + rec_size) >= (guint)nstrace->nstrace_buflen) ?\ + ((nstrace_buf_offset + rec_size) - (NSPR_PAGESIZE_TRACE - 1)) : 0;\ + /* Copy record data */\ + while (nsg_nextPageOffset) {\ + /* Copy everything from this page */\ + while (nstrace_buf_offset < nstrace->nstrace_buflen) {\ + nstrace_tmpbuff[nstrace_tmpbuff_off++] = nstrace_buf[nstrace_buf_offset++];\ + }\ + nstrace->xxx_offset += nstrace_buflen;\ + nstrace_buflen = NSPR_PAGESIZE_TRACE;\ + /* Read the next page */\ + bytes_read = file_read(nstrace_buf, NSPR_PAGESIZE_TRACE, wth->fh);\ + if ( !file_eof(wth->fh) && bytes_read != NSPR_PAGESIZE_TRACE) {\ + return FALSE;\ + } else {\ + nstrace_buf_offset = 0;\ + }\ + nstrace_buflen = bytes_read;\ + rec_size = nst_dataSize - nstrace_tmpbuff_off;\ + nsg_nextPageOffset = ((nstrace_buf_offset + rec_size) >= (guint)nstrace->nstrace_buflen) ?\ + ((nstrace_buf_offset + rec_size) - (NSPR_PAGESIZE_TRACE- 1)): 0;\ + } \ + /* Copy the rest of the record */\ + while (nstrace_tmpbuff_off < nst_dataSize) {\ + nstrace_tmpbuff[nstrace_tmpbuff_off++] = nstrace_buf[nstrace_buf_offset++];\ + }\ + memcpy(ws_buffer_start_ptr(wth->frame_buffer), nstrace_tmpbuff, (phdr)->caplen);\ + nstrace->nstrace_buf_offset = nstrace_buf_offset;\ + nstrace->nstrace_buflen = nstrace_buflen;\ + nstrace->nsg_creltime = nsg_creltime;\ + return TRUE;\ + } while(0) static gboolean nstrace_read_v30(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) { nstrace_t *nstrace = (nstrace_t *)wth->priv; - guint64 nsg_creltime = nstrace->nsg_creltime; + guint64 nsg_creltime; gchar *nstrace_buf = nstrace->pnstrace_buf; - gint32 nstrace_buf_offset = nstrace->nstrace_buf_offset; - gint32 nstrace_buflen = nstrace->nstrace_buflen; + guint32 nstrace_buf_offset = nstrace->nstrace_buf_offset; + guint32 nstrace_buflen = nstrace->nstrace_buflen; guint8 nstrace_tmpbuff[65536]; guint32 nstrace_tmpbuff_off=0,nst_dataSize=0,rec_size=0,nsg_nextPageOffset=0; nspr_hd_v20_t *hdp; - int bytes_read; + int bytes_read = 0; *err = 0; *err_info = NULL; + if(nstrace_buflen == 0){ + return FALSE; /* Reached End Of File */ + } do { + if (!nstrace_buf[nstrace_buf_offset] && nstrace_buf_offset <= NSPR_PAGESIZE_TRACE){ + nstrace_buf_offset = NSPR_PAGESIZE_TRACE; + } + if (file_eof(wth->fh) && bytes_read > 0 && bytes_read < NSPR_PAGESIZE_TRACE){ + memset(&nstrace_buf[bytes_read], 0, NSPR_PAGESIZE_TRACE-bytes_read); + } while ((nstrace_buf_offset < NSPR_PAGESIZE_TRACE) && nstrace_buf[nstrace_buf_offset]) { hdp = (nspr_hd_v20_t *) &nstrace_buf[nstrace_buf_offset]; + if (nspr_getv20recordsize(hdp) == 0) { + *err = WTAP_ERR_BAD_FILE; + *err_info = g_strdup("nstrace: zero size record found"); + return FALSE; + } switch (hdp->phd_RecordType) { -#define GENERATE_CASE_V30(phdr,type,acttype) \ - case NSPR_PDPKTRACEFULLTX_V##type:\ - case NSPR_PDPKTRACEFULLTXB_V##type:\ - case NSPR_PDPKTRACEFULLRX_V##type:\ - case NSPR_PDPKTRACEFULLNEWRX_V##type:\ - PACKET_DESCRIBE(phdr, TIMEDEF, FPSIZEDEFV,type,v##type##_full,fp,pktracefull_v##type,acttype); - GENERATE_CASE_V30(&wth->phdr,30, 300); -#undef GENERATE_CASE_V30 +#define GENERATE_CASE_FULL_V30(phdr,ver,HEADERVER) \ + case NSPR_PDPKTRACEFULLTX_V##ver:\ + case NSPR_PDPKTRACEFULLTXB_V##ver:\ + case NSPR_PDPKTRACEFULLRX_V##ver:\ + case NSPR_PDPKTRACEFULLNEWRX_V##ver:\ + PACKET_DESCRIBE(phdr,FULL,ver,v##ver##_full,fp,pktracefull_v##ver,HEADERVER); + + GENERATE_CASE_FULL_V30(&wth->phdr,30,300); + +#undef GENERATE_CASE_FULL_V30 case NSPR_ABSTIME_V20: { @@ -1331,23 +1444,40 @@ static gboolean nstrace_read_v30(wtap *wth, int *err, gchar **err_info, gint64 * nstrace_buf_offset = 0; nstrace->xxx_offset += nstrace_buflen; nstrace_buflen = NSPR_PAGESIZE_TRACE; - } while((nstrace_buflen > 0) && (bytes_read = file_read(nstrace_buf, nstrace_buflen, wth->fh)) && (bytes_read == nstrace_buflen)); + } while((nstrace_buflen > 0) && (bytes_read = file_read(nstrace_buf, nstrace_buflen, wth->fh)) > 0 && (file_eof(wth->fh) || (guint32)bytes_read == nstrace_buflen)); return FALSE; } #undef PACKET_DESCRIBE +/* + * XXX - for these, we can't set the time stamp in the seek-read + * routine, because the time stamps are relative. + */ +#undef TIMEDEFV10 +#define TIMEDEFV10(phdr,fp,type) \ + do {\ + (phdr)->presence_flags = 0;\ + }while(0) + +#define PACKET_DESCRIBE(phdr,FULLPART,fullpart,ver,type,HEADERVER) \ + do {\ + nspr_pktrace##fullpart##_v##ver##_t *type = (nspr_pktrace##fullpart##_v##ver##_t *) pd;\ + (phdr)->rec_type = REC_TYPE_PACKET;\ + TIMEDEFV##ver((phdr),fp,type);\ + FULLPART##SIZEDEFV##ver((phdr),type,ver);\ + TRACE_V##ver##_REC_LEN_OFF(phdr,v##ver##_##fullpart,type,pktrace##fullpart##_v##ver);\ + (phdr)->pseudo_header.nstr.rec_type = NSPR_HEADER_VERSION##HEADERVER;\ + }while(0) + static gboolean nstrace_seek_read_v10(wtap *wth, gint64 seek_off, struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info) { nspr_hd_v10_t hdr; - int bytes_read; guint record_length; guint8 *pd; unsigned int bytes_to_read; - nspr_pktracefull_v10_t *fp; - nspr_pktracepart_v10_t *pp; *err = 0; @@ -1357,13 +1487,9 @@ static gboolean nstrace_seek_read_v10(wtap *wth, gint64 seek_off, /* ** Read the record header. */ - bytes_read = file_read((void *)&hdr, sizeof hdr, wth->random_fh); - if (bytes_read != sizeof hdr) { - *err = file_error(wth->random_fh, err_info); - if (*err == 0) - *err = WTAP_ERR_SHORT_READ; + if (!wtap_read_bytes(wth->random_fh, (void *)&hdr, sizeof hdr, + err, err_info)) return FALSE; - } /* ** Get the record length. @@ -1373,39 +1499,31 @@ static gboolean nstrace_seek_read_v10(wtap *wth, gint64 seek_off, /* ** Copy the header to the buffer and read the rest of the record.. */ - buffer_assure_space(buf, record_length); - pd = buffer_start_ptr(buf); + ws_buffer_assure_space(buf, record_length); + pd = ws_buffer_start_ptr(buf); memcpy(pd, (void *)&hdr, sizeof hdr); if (record_length > sizeof hdr) { - bytes_to_read = (unsigned int)(record_length - sizeof hdr); - bytes_read = file_read(pd + sizeof hdr, bytes_to_read, wth->random_fh); - if (bytes_read < 0 || (unsigned int)bytes_read != bytes_to_read) { - *err = file_error(wth->random_fh, err_info); - if (*err == 0) - *err = WTAP_ERR_SHORT_READ; + bytes_to_read = (unsigned int)(record_length - sizeof hdr); + if (!wtap_read_bytes(wth->random_fh, pd + sizeof hdr, bytes_to_read, + err, err_info)) return FALSE; - } } /* ** Fill in what part of the struct wtap_pkthdr we can. */ -#define GENERATE_CASE_FULL(phdr,type,acttype) \ +#define GENERATE_CASE_FULL(phdr,type,HEADERVER) \ case NSPR_PDPKTRACEFULLTX_V##type:\ case NSPR_PDPKTRACEFULLTXB_V##type:\ case NSPR_PDPKTRACEFULLRX_V##type:\ - fp = (nspr_pktracefull_v10_t *) pd;\ - TRACE_FULL_V##type##_REC_LEN_OFF(phdr,v##type##_full,fp,pktracefull_v##type);\ - (phdr)->pseudo_header.nstr.rec_type = NSPR_HEADER_VERSION##acttype;\ + PACKET_DESCRIBE(phdr,FULL,full,type,fp,HEADERVER);\ break; -#define GENERATE_CASE_PART(phdr,type,acttype) \ +#define GENERATE_CASE_PART(phdr,type,HEADERVER) \ case NSPR_PDPKTRACEPARTTX_V##type:\ case NSPR_PDPKTRACEPARTTXB_V##type:\ case NSPR_PDPKTRACEPARTRX_V##type:\ - pp = (nspr_pktracepart_v10_t *) pd;\ - TRACE_PART_V##type##_REC_LEN_OFF(phdr,v##type##_part,pp,pktracepart_v##type);\ - (phdr)->pseudo_header.nstr.rec_type = NSPR_HEADER_VERSION##acttype;\ + PACKET_DESCRIBE(phdr,PART,part,type,pp,HEADERVER);\ break; switch (pletoh16(&(( nspr_header_v10_t*)pd)->ph_RecordType)) @@ -1420,12 +1538,31 @@ static gboolean nstrace_seek_read_v10(wtap *wth, gint64 seek_off, return TRUE; } -#define PACKET_DESCRIBE(phdr,FPTIMEDEF,SIZEDEF,ver,enumprefix,type,structname,TYPE)\ +#undef PACKET_DESCRIBE + +/* + * XXX - for these, we can't set the time stamp in the seek-read + * routine, because the time stamps are relative. + */ +#undef TIMEDEFV20 +#define TIMEDEFV20(phdr,fp,type) \ + do {\ + (phdr)->presence_flags = 0;\ + }while(0) + +#undef TIMEDEFV21 +#undef TIMEDEFV22 +#define TIMEDEFV21(phdr,fp,type) TIMEDEFV20(phdr,fp,type) +#define TIMEDEFV22(phdr,fp,type) TIMEDEFV20(phdr,fp,type) + +#define PACKET_DESCRIBE(phdr,FULLPART,ver,enumprefix,type,structname,HEADERVER)\ do {\ nspr_##structname##_t *fp= (nspr_##structname##_t*)pd;\ - SIZEDEF##ver((phdr),fp,ver);\ + (phdr)->rec_type = REC_TYPE_PACKET;\ + TIMEDEFV##ver((phdr),fp,type);\ + FULLPART##SIZEDEFV##ver((phdr),fp,ver);\ TRACE_V##ver##_REC_LEN_OFF((phdr),enumprefix,type,structname);\ - (phdr)->pseudo_header.nstr.rec_type = NSPR_HEADER_VERSION##TYPE;\ + (phdr)->pseudo_header.nstr.rec_type = NSPR_HEADER_VERSION##HEADERVER;\ return TRUE;\ }while(0) @@ -1433,11 +1570,11 @@ static gboolean nstrace_seek_read_v20(wtap *wth, gint64 seek_off, struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info) { nspr_hd_v20_t hdr; - int bytes_read; guint record_length; guint hdrlen; guint8 *pd; unsigned int bytes_to_read; + guint64 nsg_creltime; *err = 0; @@ -1447,26 +1584,17 @@ static gboolean nstrace_seek_read_v20(wtap *wth, gint64 seek_off, /* ** Read the first 2 bytes of the record header. */ - bytes_read = file_read((void *)&hdr, 2, wth->random_fh); - if (bytes_read != 2) { - *err = file_error(wth->random_fh, err_info); - if (*err == 0) - *err = WTAP_ERR_SHORT_READ; + if (!wtap_read_bytes(wth->random_fh, (void *)&hdr, 2, err, err_info)) return FALSE; - } hdrlen = 2; /* ** Is there a third byte? If so, read it. */ if (hdr.phd_RecordSizeLow & NSPR_V20RECORDSIZE_2BYTES) { - bytes_read = file_read((void *)&hdr.phd_RecordSizeHigh, 1, wth->random_fh); - if (bytes_read != 1) { - *err = file_error(wth->random_fh, err_info); - if (*err == 0) - *err = WTAP_ERR_SHORT_READ; + if (!wtap_read_bytes(wth->random_fh, (void *)&hdr.phd_RecordSizeHigh, 1, + err, err_info)) return FALSE; - } hdrlen = 3; } @@ -1478,45 +1606,41 @@ static gboolean nstrace_seek_read_v20(wtap *wth, gint64 seek_off, /* ** Copy the header to the buffer and read the rest of the record.. */ - buffer_assure_space(buf, record_length); - pd = buffer_start_ptr(buf); + ws_buffer_assure_space(buf, record_length); + pd = ws_buffer_start_ptr(buf); memcpy(pd, (void *)&hdr, hdrlen); if (record_length > hdrlen) { - bytes_to_read = (unsigned int)(record_length - hdrlen); - bytes_read = file_read(pd + hdrlen, bytes_to_read, wth->random_fh); - if (bytes_read < 0 || (unsigned int)bytes_read != bytes_to_read) { - *err = file_error(wth->random_fh, err_info); - if (*err == 0) - *err = WTAP_ERR_SHORT_READ; + bytes_to_read = (unsigned int)(record_length - hdrlen); + if (!wtap_read_bytes(wth->random_fh, pd + hdrlen, bytes_to_read, + err, err_info)) return FALSE; - } } -#define GENERATE_CASE_FULL(phdr,type,acttype) \ - case NSPR_PDPKTRACEFULLTX_V##type:\ - case NSPR_PDPKTRACEFULLTXB_V##type:\ - case NSPR_PDPKTRACEFULLRX_V##type:\ - PACKET_DESCRIBE(phdr,TIMEDEF,FPSIZEDEFV,type,v##type##_full,fp,pktracefull_v##type,acttype); - -#define GENERATE_CASE_FULL_V25(phdr,type,acttype) \ - case NSPR_PDPKTRACEFULLTX_V##type:\ - case NSPR_PDPKTRACEFULLTXB_V##type:\ - case NSPR_PDPKTRACEFULLRX_V##type:\ - case NSPR_PDPKTRACEFULLNEWRX_V##type:\ - PACKET_DESCRIBE(phdr,TIMEDEF,FPSIZEDEFV,type,v##type##_full,fp,pktracefull_v##type,acttype); - -#define GENERATE_CASE_PART(phdr,type,acttype) \ - case NSPR_PDPKTRACEPARTTX_V##type:\ - case NSPR_PDPKTRACEPARTTXB_V##type:\ - case NSPR_PDPKTRACEPARTRX_V##type:\ - PACKET_DESCRIBE(phdr,TIMEDEF,PPSIZEDEFV,type,v##type##_part,pp,pktracepart_v##type,acttype); - -#define GENERATE_CASE_PART_V25(phdr,type,acttype) \ - case NSPR_PDPKTRACEPARTTX_V##type:\ - case NSPR_PDPKTRACEPARTTXB_V##type:\ - case NSPR_PDPKTRACEPARTRX_V##type:\ - case NSPR_PDPKTRACEPARTNEWRX_V##type:\ - PACKET_DESCRIBE(phdr,TIMEDEF,PPSIZEDEFV,type,v##type##_part,pp,pktracepart_v##type,acttype); +#define GENERATE_CASE_FULL(phdr,ver,HEADERVER) \ + case NSPR_PDPKTRACEFULLTX_V##ver:\ + case NSPR_PDPKTRACEFULLTXB_V##ver:\ + case NSPR_PDPKTRACEFULLRX_V##ver:\ + PACKET_DESCRIBE(phdr,FULL,ver,v##ver##_full,fp,pktracefull_v##ver,HEADERVER); + +#define GENERATE_CASE_FULL_V25(phdr,ver,HEADERVER) \ + case NSPR_PDPKTRACEFULLTX_V##ver:\ + case NSPR_PDPKTRACEFULLTXB_V##ver:\ + case NSPR_PDPKTRACEFULLRX_V##ver:\ + case NSPR_PDPKTRACEFULLNEWRX_V##ver:\ + PACKET_DESCRIBE(phdr,FULL,ver,v##ver##_full,fp,pktracefull_v##ver,HEADERVER); + +#define GENERATE_CASE_PART(phdr,ver,HEADERVER) \ + case NSPR_PDPKTRACEPARTTX_V##ver:\ + case NSPR_PDPKTRACEPARTTXB_V##ver:\ + case NSPR_PDPKTRACEPARTRX_V##ver:\ + PACKET_DESCRIBE(phdr,PART,ver,v##ver##_part,pp,pktracepart_v##ver,HEADERVER); + +#define GENERATE_CASE_PART_V25(phdr,ver,HEADERVER) \ + case NSPR_PDPKTRACEPARTTX_V##ver:\ + case NSPR_PDPKTRACEPARTTXB_V##ver:\ + case NSPR_PDPKTRACEPARTRX_V##ver:\ + case NSPR_PDPKTRACEPARTNEWRX_V##ver:\ + PACKET_DESCRIBE(phdr,PART,ver,v##ver##_part,pp,pktracepart_v##ver,HEADERVER); switch ((( nspr_hd_v20_t*)pd)->phd_RecordType) { @@ -1544,16 +1668,32 @@ static gboolean nstrace_seek_read_v20(wtap *wth, gint64 seek_off, return TRUE; } +#undef PACKET_DESCRIBE +#undef SETETHOFFSET_30 + +#define SETETHOFFSET_30(phdr) ;\ + +#define PACKET_DESCRIBE(phdr,FULLPART,ver,enumprefix,type,structname,HEADERVER)\ + do {\ + nspr_##structname##_t *fp= (nspr_##structname##_t*)pd;\ + (phdr)->rec_type = REC_TYPE_PACKET;\ + TIMEDEFV##ver((phdr),fp,type);\ + SETETHOFFSET_##ver(phdr);\ + FULLPART##SIZEDEFV##ver((phdr),fp,ver);\ + TRACE_V##ver##_REC_LEN_OFF((phdr),enumprefix,type,structname);\ + (phdr)->pseudo_header.nstr.rec_type = NSPR_HEADER_VERSION##HEADERVER;\ + return TRUE;\ + }while(0) static gboolean nstrace_seek_read_v30(wtap *wth, gint64 seek_off, struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info) { nspr_hd_v20_t hdr; - int bytes_read; guint record_length; guint hdrlen; guint8 *pd; unsigned int bytes_to_read; + guint64 nsg_creltime; *err = 0; @@ -1562,26 +1702,17 @@ static gboolean nstrace_seek_read_v30(wtap *wth, gint64 seek_off, /* ** Read the first 2 bytes of the record header. */ - bytes_read = file_read((void *)&hdr, 2, wth->random_fh); - if (bytes_read != 2) { - *err = file_error(wth->random_fh, err_info); - if (*err == 0) - *err = WTAP_ERR_SHORT_READ; + if (!wtap_read_bytes(wth->random_fh, (void *)&hdr, 2, err, err_info)) return FALSE; - } hdrlen = 2; /* ** Is there a third byte? If so, read it. */ if (hdr.phd_RecordSizeLow & NSPR_V20RECORDSIZE_2BYTES) { - bytes_read = file_read((void *)&hdr.phd_RecordSizeHigh, 1, wth->random_fh); - if (bytes_read != 1) { - *err = file_error(wth->random_fh, err_info); - if (*err == 0) - *err = WTAP_ERR_SHORT_READ; + if (!wtap_read_bytes(wth->random_fh, (void *)&hdr.phd_RecordSizeHigh, 1, + err, err_info)) return FALSE; - } hdrlen = 3; } @@ -1593,28 +1724,24 @@ static gboolean nstrace_seek_read_v30(wtap *wth, gint64 seek_off, /* ** Copy the header to the buffer and read the rest of the record.. */ - buffer_assure_space(buf, record_length); - pd = buffer_start_ptr(buf); + ws_buffer_assure_space(buf, record_length); + pd = ws_buffer_start_ptr(buf); memcpy(pd, (void *)&hdr, hdrlen); if (record_length > hdrlen) { bytes_to_read = (unsigned int)(record_length - hdrlen); - bytes_read = file_read(pd + hdrlen, bytes_to_read, wth->random_fh); - if (bytes_read < 0 || (unsigned int)bytes_read != bytes_to_read) { - *err = file_error(wth->random_fh, err_info); - if (*err == 0) - *err = WTAP_ERR_SHORT_READ; + if (!wtap_read_bytes(wth->random_fh, pd + hdrlen, bytes_to_read, + err, err_info)) return FALSE; - } } -#define GENERATE_CASE_V30(phdr,type,acttype) \ - case NSPR_PDPKTRACEFULLTX_V##type:\ - case NSPR_PDPKTRACEFULLTXB_V##type:\ - case NSPR_PDPKTRACEFULLRX_V##type:\ - case NSPR_PDPKTRACEFULLNEWRX_V##type:\ - TRACE_V##type##_REC_LEN_OFF((phdr),v##type##_full,fp,pktracefull_v##type);\ - (phdr)->pseudo_header.nstr.rec_type = NSPR_HEADER_VERSION##acttype;\ - break; + (phdr)->caplen = (phdr)->len = record_length; + +#define GENERATE_CASE_V30(phdr,ver,HEADERVER) \ + case NSPR_PDPKTRACEFULLTX_V##ver:\ + case NSPR_PDPKTRACEFULLTXB_V##ver:\ + case NSPR_PDPKTRACEFULLRX_V##ver:\ + case NSPR_PDPKTRACEFULLNEWRX_V##ver:\ + PACKET_DESCRIBE(phdr,FULL,ver,v##ver##_full,fp,pktracefull_v##ver,HEADERVER); switch ((( nspr_hd_v20_t*)pd)->phd_RecordType) { @@ -1640,6 +1767,7 @@ typedef struct { guint16 page_offset; guint16 page_len; guint32 absrec_time; + gboolean newfile; } nstrace_dump_t; /* Returns 0 if we could write the specified encapsulation type, @@ -1649,7 +1777,7 @@ int nstrace_10_dump_can_write_encap(int encap) if (encap == WTAP_ENCAP_NSTRACE_1_0) return 0; - return WTAP_ERR_UNSUPPORTED_ENCAP; + return WTAP_ERR_UNWRITABLE_ENCAP; } @@ -1660,7 +1788,7 @@ int nstrace_20_dump_can_write_encap(int encap) if (encap == WTAP_ENCAP_NSTRACE_2_0) return 0; - return WTAP_ERR_UNSUPPORTED_ENCAP; + return WTAP_ERR_UNWRITABLE_ENCAP; } /* Returns 0 if we could write the specified encapsulation type, @@ -1670,7 +1798,7 @@ int nstrace_30_dump_can_write_encap(int encap) if (encap == WTAP_ENCAP_NSTRACE_3_0) return 0; - return WTAP_ERR_UNSUPPORTED_ENCAP; + return WTAP_ERR_UNWRITABLE_ENCAP; } /* Returns TRUE on success, FALSE on failure; sets "*err" to an error code on @@ -1684,8 +1812,13 @@ gboolean nstrace_dump_open(wtap_dumper *wdh, int *err _U_) nstrace = (nstrace_dump_t *)g_malloc(sizeof(nstrace_dump_t)); wdh->priv = (void *)nstrace; nstrace->page_offset = 0; - nstrace->page_len = NSPR_PAGESIZE; + if (wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_3_0) + nstrace->page_len = NSPR_PAGESIZE_TRACE; + else + nstrace->page_len = NSPR_PAGESIZE; + nstrace->absrec_time = 0; + nstrace->newfile = TRUE; return TRUE; } @@ -1833,12 +1966,13 @@ static gboolean nstrace_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr, /* We can only write packet records. */ if (phdr->rec_type != REC_TYPE_PACKET) { - *err = WTAP_ERR_REC_TYPE_UNSUPPORTED; + *err = WTAP_ERR_UNWRITABLE_REC_TYPE; return FALSE; } - if (nstrace->page_offset == 0) + if (nstrace->newfile == TRUE) { + nstrace->newfile = FALSE; /* Add the signature record and abs time record */ if (wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_1_0) { @@ -1888,7 +2022,7 @@ static gboolean nstrace_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr, nstrace->page_offset += (guint16) phdr->caplen; } else if (wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_2_0) { - *err = WTAP_ERR_UNSUPPORTED_FILE_TYPE; + *err = WTAP_ERR_UNWRITABLE_FILE_TYPE; return FALSE; } @@ -1903,7 +2037,7 @@ static gboolean nstrace_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr, case NSPR_HEADER_VERSION206: if (wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_1_0) { - *err = WTAP_ERR_UNSUPPORTED_FILE_TYPE; + *err = WTAP_ERR_UNWRITABLE_FILE_TYPE; return FALSE; } else if (wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_2_0) { @@ -1932,11 +2066,11 @@ static gboolean nstrace_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr, case NSPR_HEADER_VERSION300: if (wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_1_0) { - *err = WTAP_ERR_UNSUPPORTED_FILE_TYPE; + *err = WTAP_ERR_UNWRITABLE_FILE_TYPE; return FALSE; } else if (wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_2_0) { - *err = WTAP_ERR_UNSUPPORTED_FILE_TYPE; + *err = WTAP_ERR_UNWRITABLE_FILE_TYPE; return FALSE; } else if (wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_3_0) { @@ -1972,3 +2106,16 @@ static gboolean nstrace_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr, return TRUE; } + +/* + * Editor modelines - http://www.wireshark.org/tools/modelines.html + * + * Local variables: + * c-basic-offset: 4 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * vi: set shiftwidth=4 tabstop=8 expandtab: + * :indentSize=4:tabSize=8:noTabs=true: + */ |