diff options
-rw-r--r-- | epan/dissectors/packet-nstrace.c | 11 | ||||
-rw-r--r-- | wiretap/file_access.c | 7 | ||||
-rw-r--r-- | wiretap/netscaler.c | 350 | ||||
-rw-r--r-- | wiretap/netscaler.h | 10 | ||||
-rw-r--r-- | wiretap/wtap.c | 3 | ||||
-rw-r--r-- | wiretap/wtap.h | 2 |
6 files changed, 372 insertions, 11 deletions
diff --git a/epan/dissectors/packet-nstrace.c b/epan/dissectors/packet-nstrace.c index 8b841ba12d..a143ca4d46 100644 --- a/epan/dissectors/packet-nstrace.c +++ b/epan/dissectors/packet-nstrace.c @@ -68,10 +68,13 @@ static gint ett_ns_activity_flags = -1; static const value_string ns_dir_vals[] = { { NSPR_PDPKTRACEFULLTX_V10, "TX" }, { NSPR_PDPKTRACEFULLTX_V20, "TX" }, + { NSPR_PDPKTRACEFULLTX_V30, "TX" }, { NSPR_PDPKTRACEFULLTXB_V10, "TXB" }, { NSPR_PDPKTRACEFULLTXB_V20, "TXB" }, + { NSPR_PDPKTRACEFULLTXB_V30, "TXB" }, { NSPR_PDPKTRACEFULLRX_V10, "RX" }, { NSPR_PDPKTRACEFULLRX_V20, "RX" }, + { NSPR_PDPKTRACEFULLRX_V30, "RX" }, { NSPR_PDPKTRACEPARTTX_V10, "TX" }, { NSPR_PDPKTRACEPARTTX_V20, "TX" }, { NSPR_PDPKTRACEPARTTXB_V10, "TXB" }, @@ -102,6 +105,7 @@ static const value_string ns_dir_vals[] = { { NSPR_PDPKTRACEFULLNEWRX_V24, "NEW_RX" }, { NSPR_PDPKTRACEFULLNEWRX_V25, "NEW_RX" }, { NSPR_PDPKTRACEFULLNEWRX_V26, "NEW_RX" }, + { NSPR_PDPKTRACEFULLNEWRX_V30, "NEW_RX" }, { NSPR_PDPKTRACEPARTTX_V22, "TX" }, { NSPR_PDPKTRACEPARTTX_V23, "TX" }, { NSPR_PDPKTRACEPARTTX_V24, "TX" }, @@ -157,13 +161,12 @@ dissect_nstrace(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) wmem_strbuf_append(flags_strbuf, "None"); - if (pnstr->rec_type == NSPR_HEADER_VERSION205) - { + if (pnstr->rec_type == NSPR_HEADER_VERSION205 || pnstr->rec_type == NSPR_HEADER_VERSION300 || pnstr->rec_type == NSPR_HEADER_VERSION206) { src_vmname_len = tvb_get_guint8(tvb,pnstr->src_vmname_len_offset); dst_vmname_len = tvb_get_guint8(tvb,pnstr->dst_vmname_len_offset); variable_ns_len = src_vmname_len + dst_vmname_len; pnstr->eth_offset += variable_ns_len; - } + } ti = proto_tree_add_protocol_format(tree, proto_nstrace, tvb, 0, pnstr->eth_offset, "NetScaler Packet Trace"); ns_tree = proto_item_add_subtree(ti, ett_ns); @@ -173,6 +176,7 @@ dissect_nstrace(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) switch (pnstr->rec_type) { + case NSPR_HEADER_VERSION300: case NSPR_HEADER_VERSION206: flagoffset = pnstr->ns_activity_offset; flagval32 = tvb_get_letohl(tvb, flagoffset); @@ -429,4 +433,5 @@ void proto_reg_handoff_ns(void) nstrace_handle = create_dissector_handle(dissect_nstrace, proto_nstrace); dissector_add_uint("wtap_encap", WTAP_ENCAP_NSTRACE_1_0, nstrace_handle); dissector_add_uint("wtap_encap", WTAP_ENCAP_NSTRACE_2_0, nstrace_handle); + dissector_add_uint("wtap_encap", WTAP_ENCAP_NSTRACE_3_0, nstrace_handle); } diff --git a/wiretap/file_access.c b/wiretap/file_access.c index 06048bba40..1be8b35a72 100644 --- a/wiretap/file_access.c +++ b/wiretap/file_access.c @@ -1289,7 +1289,12 @@ static const struct file_type_subtype_info dump_open_table_base[] = { /* WTAP_FILE_TYPE_SUBTYPE_STANAG_4607 */ { "STANAG 4607 Format", "stanag4607", NULL, NULL, FALSE, FALSE, 0, - NULL, NULL } + NULL, NULL }, + + /* WTAP_FILE_NETSCALER_3_0 */ + { "NetScaler Trace (Version 3.0)", "nstrace30", "cap", NULL, + TRUE, FALSE, 0, + nstrace_30_dump_can_write_encap, nstrace_dump_open } }; diff --git a/wiretap/netscaler.c b/wiretap/netscaler.c index 05c824f145..9772567ae7 100644 --- a/wiretap/netscaler.c +++ b/wiretap/netscaler.c @@ -31,6 +31,7 @@ #define NSPR_SIGSTR_V10 "NetScaler Performance Data" #define NSPR_SIGSTR_V20 "NetScaler V20 Performance Data" #define NSPR_SIGSTR NSPR_SIGSTR_V20 +#define NSPR_SIGSTR_V30 "Netscaler V30 Performance Data" /* Defined but not used */ #define NSPR_SIGSTR_V21 "NetScaler V21 Performance Data" #define NSPR_SIGSTR_V22 "NetScaler V22 Performance Data" @@ -49,6 +50,7 @@ * other than the type and zero or more additional padding bytes). */ #define NSPR_PAGESIZE 8192 +#define NSPR_PAGESIZE_TRACE (2*NSPR_PAGESIZE) /* The different record types ** NOTE: The Record Type is two byte fields and unused space is recognized by @@ -61,6 +63,7 @@ #define NSPR_UNUSEDSPACE_V20 0x00 /* rest of the page is unused */ #define NSPR_SIGNATURE_V10 0x0101 /* signature */ #define NSPR_SIGNATURE_V20 0x01 /* signature */ +#define NSPR_SIGNATURE_V30 NSPR_SIGNATURE_V20 #define NSPR_ABSTIME_V10 0x0107 /* data capture time in secs from 1970*/ #define NSPR_ABSTIME_V20 0x07 /* data capture time in secs from 1970*/ #define NSPR_RELTIME_V10 0x0108 /* relative time in ms from last time */ @@ -109,6 +112,7 @@ typedef struct nspr_header_v10 /* end of declaration */ #define NSPR_HEADER3B_V21 NSPR_HEADER3B_V20 #define NSPR_HEADER3B_V22 NSPR_HEADER3B_V20 +#define NSPR_HEADER3B_V30 NSPR_HEADER3B_V20 typedef struct nspr_hd_v20 { @@ -175,6 +179,16 @@ typedef struct nspr_signature_v20 } nspr_signature_v20_t; #define nspr_signature_v20_s ((guint32)sizeof(nspr_signature_v20_t)) +/* NSPR_SIGNATURE_V30 structure */ +#define NSPR_SIGSIZE_V30 sizeof(NSPR_SIGSTR_V30) /* signature value size in bytes */ +typedef struct nspr_signature_v30 +{ + NSPR_HEADER_V20(sig); /* short performance header */ + guint8 sig_EndianType; /* Endian Type for the data */ + gchar sig_Signature[NSPR_SIGSIZE_V30]; /* Signature value */ +} nspr_signature_v30_t; +#define nspr_signature_v30_s ((guint32)sizeof(nspr_signature_v30_t)) + /* NSPR_ABSTIME_V10 and NSPR_SYSTARTIME_V10 structure */ typedef struct nspr_abstime_v10 { @@ -422,6 +436,32 @@ typedef struct nspr_pktracepart_v25 #define pp_src_vmname pp_Data #define pp_dst_vmname pp_Data + +/* New full packet trace structure v30 for multipage spanning data */ +typedef struct nspr_pktracefull_v30 +{ + NSPR_HEADER3B_V30(fp); /* long performance header */ + guint8 fp_DevNo; /* Network Device (NIC) number */ + guint8 fp_AbsTimeHr[8]; /*High resolution absolute time in nanosec*/ + guint8 fp_PcbDevNo[4]; /* PCB devno */ + guint8 fp_lPcbDevNo[4]; /* link PCB devno */ + guint8 fp_PktSizeOrg[2]; /* Original packet size */ + guint8 fp_VlanTag[2]; /* vlan tag */ + guint8 fp_Coreid[2]; /* coreid of the packet */ + guint8 fp_srcNodeId[2]; /* cluster nodeid of the packet */ + guint8 fp_destNodeId[2]; + guint8 fp_clFlags; + guint8 fp_src_vmname_len; + guint8 fp_dst_vmname_len; + 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 { @@ -514,6 +554,9 @@ typedef struct nspr_pktracepart_v26 TRACE_V25_REC_LEN_OFF(phdr,enumprefix,structprefix,structname)\ __TNO(phdr,enumprefix,structprefix,structname,ns_activity,ns_activity)\ +#define TRACE_V30_REC_LEN_OFF(phdr, enumprefix, structprefix, structname) \ + TRACE_V26_REC_LEN_OFF(phdr,enumprefix,structprefix,structname)\ + TRACE_V10_REC_LEN_OFF(NULL,v10_part,pp,pktracepart_v10) TRACE_V10_REC_LEN_OFF(NULL,v10_full,fp,pktracefull_v10) TRACE_V20_REC_LEN_OFF(NULL,v20_part,pp,pktracepart_v20) @@ -530,6 +573,7 @@ typedef struct nspr_pktracepart_v26 TRACE_V25_REC_LEN_OFF(NULL,v25_full,fp,pktracefull_v25) TRACE_V26_REC_LEN_OFF(NULL,v26_part,pp,pktracepart_v26) TRACE_V26_REC_LEN_OFF(NULL,v26_full,fp,pktracefull_v26) + TRACE_V30_REC_LEN_OFF(NULL,v30_full,fp,pktracefull_v30) #undef __TNV1O #undef __TNV1L @@ -573,6 +617,8 @@ static gboolean nstrace_read_v10(wtap *wth, int *err, gchar **err_info, gint64 *data_offset); static gboolean nstrace_read_v20(wtap *wth, int *err, gchar **err_info, gint64 *data_offset); +static gboolean nstrace_read_v30(wtap *wth, int *err, gchar **err_info, + gint64 *data_offset); static gboolean nstrace_seek_read_v10(wtap *wth, gint64 seek_off, struct wtap_pkthdr *phdr, Buffer *buf, @@ -581,6 +627,10 @@ static gboolean nstrace_seek_read_v20(wtap *wth, gint64 seek_off, struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info); +static gboolean nstrace_seek_read_v30(wtap *wth, gint64 seek_off, + struct wtap_pkthdr *phdr, + Buffer *buf, + int *err, gchar **err_info); static void nstrace_close(wtap *wth); static gboolean nstrace_set_start_time_v10(wtap *wth); @@ -597,7 +647,7 @@ static gboolean nstrace_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr, * the last page of a file can be short. */ #define GET_READ_PAGE_SIZE(remaining_file_size) ((gint32)((remaining_file_size>NSPR_PAGESIZE)?NSPR_PAGESIZE:remaining_file_size)) - +#define GET_READ_PAGE_SIZEV3(remaining_file_size) ((gint32)((remaining_file_size>NSPR_PAGESIZE_TRACE)?NSPR_PAGESIZE_TRACE:remaining_file_size)) static guint64 ns_hrtime2nsec(guint32 tm) { @@ -642,6 +692,13 @@ int nstrace_open(wtap *wth, int *err, gchar **err_info) wth->file_encap = WTAP_ENCAP_NSTRACE_2_0; break; + case WTAP_FILE_TYPE_SUBTYPE_NETSCALER_3_0: + wth->file_encap = WTAP_ENCAP_NSTRACE_3_0; + g_free(nstrace_buf); + nstrace_buf = (gchar *)g_malloc(NSPR_PAGESIZE_TRACE); + page_size = GET_READ_PAGE_SIZEV3(file_size); + break; + default: *err = WTAP_ERR_UNSUPPORTED; *err_info = g_strdup_printf("nstrace: file type %d unsupported", wth->file_type_subtype); @@ -677,6 +734,11 @@ int nstrace_open(wtap *wth, int *err, gchar **err_info) wth->subtype_read = nstrace_read_v20; wth->subtype_seek_read = nstrace_seek_read_v20; break; + + case WTAP_FILE_TYPE_SUBTYPE_NETSCALER_3_0: + wth->subtype_read = nstrace_read_v30; + wth->subtype_seek_read = nstrace_seek_read_v30; + break; } wth->subtype_close = nstrace_close; @@ -735,6 +797,7 @@ int nstrace_open(wtap *wth, int *err, gchar **err_info) nspm_signature_func(10) nspm_signature_func(20) +nspm_signature_func(30) /* ** Check signature and return the version number of the signature. @@ -764,9 +827,13 @@ nspm_signature_version(wtap *wth, gchar *nstrace_buf, gint32 len) #define sigv20p ((nspr_signature_v20_t*)dp) if ((sigv20p->sig_RecordType == NSPR_SIGNATURE_V20) && (sigv20p->sig_RecordSize <= len) && - ((gint32)sizeof(NSPR_SIGSTR_V20) <= len) && - (!nspm_signature_isv20(sigv20p->sig_Signature))) - return WTAP_FILE_TYPE_SUBTYPE_NETSCALER_2_0; + ((gint32)sizeof(NSPR_SIGSTR_V20) <= len)) + { + if (!nspm_signature_isv20(sigv20p->sig_Signature)) + return WTAP_FILE_TYPE_SUBTYPE_NETSCALER_2_0; + else if (!nspm_signature_isv30(sigv20p->sig_Signature)) + return WTAP_FILE_TYPE_SUBTYPE_NETSCALER_3_0; + } #undef sigv20p } } @@ -836,7 +903,8 @@ static gboolean nstrace_set_start_time(wtap *wth) return nstrace_set_start_time_v10(wth); else if (wth->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_2_0) return nstrace_set_start_time_v20(wth); - + else if (wth->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_3_0) + return nstrace_set_start_time_v20(wth); return FALSE; } @@ -982,11 +1050,21 @@ static gboolean nstrace_read_v10(wtap *wth, int *err, gchar **err_info, gint64 * wth->phdr.ts.nsecs = (guint32) (nsg_creltime % 1000000000);\ }while(0) +#define TIMEDEFV30(fp,type) \ + do {\ + 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);\ + }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 PPSIZEDEFV20(phdr,pp,ver) \ do {\ (phdr)->presence_flags |= WTAP_HAS_CAP_LEN;\ @@ -1014,6 +1092,13 @@ static gboolean nstrace_read_v10(wtap *wth, int *err, gchar **err_info, gint64 * #define FPSIZEDEFV25(phdr,fp,ver) FPSIZEDEFV20(phdr,fp,ver) #define FPSIZEDEFV26(phdr,fp,ver) FPSIZEDEFV20(phdr,fp,ver) +#define FPSIZEDEFV30(phdr,fp,ver)\ + do {\ + (phdr)->len = pletoh16(&fp->fp_PktSizeOrg) + nspr_pktracefull_v##ver##_s;\ + (phdr)->caplen = nspr_getv20recordsize((nspr_hd_v20_t *)fp);\ + (phdr)->presence_flags |= WTAP_HAS_CAP_LEN;\ + }while(0) + #define PACKET_DESCRIBE(phdr,FPTIMEDEF,SIZEDEF,ver,enumprefix,type,structname,TYPE)\ do {\ nspr_##structname##_t *fp= (nspr_##structname##_t*)&nstrace_buf[nstrace_buf_offset];\ @@ -1139,6 +1224,111 @@ static gboolean nstrace_read_v20(wtap *wth, int *err, gchar **err_info, gint64 * #undef PACKET_DESCRIBE +#define PACKET_DESCRIBE(phdr,FPTIMEDEF,SIZEDEF,ver,enumprefix,type,structname,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++];\ + }\ + 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) {\ + return FALSE;\ + } else {\ + nstrace_buf_offset = 0;\ + }\ + 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) + +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; + gchar *nstrace_buf = nstrace->pnstrace_buf; + gint32 nstrace_buf_offset = nstrace->nstrace_buf_offset; + gint32 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; + *err = 0; + *err_info = NULL; + + do + { + while ((nstrace_buf_offset < NSPR_PAGESIZE_TRACE) && + nstrace_buf[nstrace_buf_offset]) + { + hdp = (nspr_hd_v20_t *) &nstrace_buf[nstrace_buf_offset]; + 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 + + case NSPR_ABSTIME_V20: + { + nstrace_buf_offset += nspr_getv20recordsize(hdp); + ns_setabstime(nstrace, pletoh32(&((nspr_abstime_v20_t *) &nstrace_buf[nstrace_buf_offset])->abs_Time), pletoh16(&((nspr_abstime_v20_t *) &nstrace_buf[nstrace_buf_offset])->abs_RelTime)); + break; + } + + case NSPR_RELTIME_V20: + { + ns_setrelativetime(nstrace, pletoh16(&((nspr_abstime_v20_t *) &nstrace_buf[nstrace_buf_offset])->abs_RelTime)); + nstrace_buf_offset += nspr_getv20recordsize(hdp); + break; + } + + default: + { + nstrace_buf_offset += nspr_getv20recordsize(hdp); + break; + } + } + } + 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)); + + return FALSE; +} + +#undef PACKET_DESCRIBE + static gboolean nstrace_seek_read_v10(wtap *wth, gint64 seek_off, struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info) { @@ -1345,6 +1535,87 @@ static gboolean nstrace_seek_read_v20(wtap *wth, gint64 seek_off, return TRUE; } + +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; + + *err = 0; + + if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1) + return FALSE; + /* + ** 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; + 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; + return FALSE; + } + hdrlen = 3; + } + + /* + ** Get the record length. + */ + record_length = nspr_getv20recordsize(&hdr); + + /* + ** Copy the header to the buffer and read the rest of the record.. + */ + buffer_assure_space(buf, record_length); + pd = 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; + 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; + + switch ((( nspr_hd_v20_t*)pd)->phd_RecordType) + { + GENERATE_CASE_V30(phdr,30, 300); + } + + return TRUE; +} + + /* ** Netscaler trace format close routines. */ @@ -1383,6 +1654,15 @@ int nstrace_20_dump_can_write_encap(int encap) return WTAP_ERR_UNSUPPORTED_ENCAP; } +/* Returns 0 if we could write the specified encapsulation type, +** an error indication otherwise. */ +int nstrace_30_dump_can_write_encap(int encap) +{ + if (encap == WTAP_ENCAP_NSTRACE_3_0) + return 0; + + return WTAP_ERR_UNSUPPORTED_ENCAP; +} /* Returns TRUE on success, FALSE on failure; sets "*err" to an error code on ** failure */ @@ -1443,6 +1723,21 @@ static gboolean nstrace_add_signature(wtap_dumper *wdh, int *err) /* Move forward the page offset */ nstrace->page_offset += (guint16) sig20.sig_RecordSize; + } else if (wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_3_0) + { + nspr_signature_v30_t sig30; + + sig30.sig_RecordType = NSPR_SIGNATURE_V30; + sig30.sig_RecordSize = nspr_signature_v30_s; + memcpy(sig30.sig_Signature, NSPR_SIGSTR_V30, sizeof(NSPR_SIGSTR_V30)); + + /* Write the record into the file */ + if (!wtap_dump_file_write(wdh, &sig30, sig30.sig_RecordSize, + err)) + return FALSE; + + /* Move forward the page offset */ + nstrace->page_offset += (guint16) sig30.sig_RecordSize; } else { g_assert_not_reached(); @@ -1487,8 +1782,8 @@ nstrace_add_abstime(wtap_dumper *wdh, const struct wtap_pkthdr *phdr, /* Move forward the page offset */ nstrace->page_offset += nspr_abstime_v10_s; - } else if (wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_2_0) - { + } else if ((wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_2_0) || + (wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_3_0)) { guint32 reltime; guint64 abstime; nspr_abstime_v20_t abs20; @@ -1540,6 +1835,11 @@ static gboolean nstrace_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr, if (!nstrace_add_signature(wdh, err) || !nstrace_add_abstime(wdh, phdr, pd, err)) return FALSE; + } else if (wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_3_0) + { + if (!nstrace_add_signature(wdh, err) || + !nstrace_add_abstime(wdh, phdr, pd, err)) + return FALSE; } else { g_assert_not_reached(); @@ -1614,6 +1914,42 @@ static gboolean nstrace_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr, break; + case NSPR_HEADER_VERSION300: + if (wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_1_0) + { + *err = WTAP_ERR_UNSUPPORTED_FILE_TYPE; + return FALSE; + } else if (wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_2_0) + { + *err = WTAP_ERR_UNSUPPORTED_FILE_TYPE; + return FALSE; + } else if (wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_3_0) + { + if (nstrace->page_offset + phdr->caplen >= nstrace->page_len) + { + /* Start on the next page */ + if (wtap_dump_file_seek(wdh, (nstrace->page_len - nstrace->page_offset), SEEK_CUR, err) == -1) + return FALSE; + + nstrace->page_offset = 0; + + /* Possibly add signature and abstime records and increment offset */ + if (!nstrace_add_signature(wdh, err)) + return FALSE; + } + + /* Write the actual record as is */ + if (!wtap_dump_file_write(wdh, pd, phdr->caplen, err)) + return FALSE; + + nstrace->page_offset += (guint16) phdr->caplen; + } else + { + g_assert_not_reached(); + return FALSE; + } + break; + default: g_assert_not_reached(); return FALSE; diff --git a/wiretap/netscaler.h b/wiretap/netscaler.h index e3896b5345..b269ff9e1f 100644 --- a/wiretap/netscaler.h +++ b/wiretap/netscaler.h @@ -95,6 +95,13 @@ #define NSPR_PDPKTRACEPARTRX_V26 0xA6 /* Received packets before NIC pipelining */ #define NSPR_PDPKTRACEPARTNEWRX_V26 0xA7 /* Received packets after NIC pipelining */ +/* Jumbo Frame Support */ +#define NSPR_PDPKTRACEFULLTX_V30 0xA8 /* Transmitted */ +#define NSPR_PDPKTRACEFULLTXB_V30 0xA9 /* In transmit buffer */ +#define NSPR_PDPKTRACEFULLRX_V30 0xAA /* Received packets before NIC pipelining */ +#define NSPR_PDPKTRACEFULLNEWRX_V30 0xAB /* Received packets after NIC pipelining */ + + /* Record types */ #define NSPR_HEADER_VERSION100 0x10 #define NSPR_HEADER_VERSION200 0x20 @@ -104,9 +111,12 @@ #define NSPR_HEADER_VERSION204 0x24 #define NSPR_HEADER_VERSION205 0x25 #define NSPR_HEADER_VERSION206 0x26 +#define NSPR_HEADER_VERSION300 0x30 + int nstrace_open(wtap *wth, int *err, gchar **err_info); int nstrace_10_dump_can_write_encap(int encap); int nstrace_20_dump_can_write_encap(int encap); +int nstrace_30_dump_can_write_encap(int encap); gboolean nstrace_dump_open(wtap_dumper *wdh, int *err); diff --git a/wiretap/wtap.c b/wiretap/wtap.c index 07e5004bd1..8774f35e1f 100644 --- a/wiretap/wtap.c +++ b/wiretap/wtap.c @@ -702,6 +702,9 @@ static struct encap_type_info encap_table_base[] = { /* WTAP_ENCAP_BLUETOOTH_LE_LL_WITH_PHDR */ { "Bluetooth Low Energy Link Layer RF", "bluetooth-le-ll-rf" }, + + /* WTAP_ENCAP_NSTRACE_3_0 */ + { "NetScaler Encapsulation 3.0 of Ethernet", "nstrace30" }, }; WS_DLL_LOCAL diff --git a/wiretap/wtap.h b/wiretap/wtap.h index 1f18b1298e..f61b51f111 100644 --- a/wiretap/wtap.h +++ b/wiretap/wtap.h @@ -253,6 +253,7 @@ extern "C" { #define WTAP_ENCAP_BLUETOOTH_LINUX_MONITOR 160 #define WTAP_ENCAP_BLUETOOTH_BREDR_BB 161 #define WTAP_ENCAP_BLUETOOTH_LE_LL_WITH_PHDR 162 +#define WTAP_ENCAP_NSTRACE_3_0 163 /* After adding new item here, please also add new item to encap_table_base array */ #define WTAP_NUM_ENCAP_TYPES wtap_get_num_encap_types() @@ -328,6 +329,7 @@ extern "C" { #define WTAP_FILE_TYPE_SUBTYPE_VWR_ETH 63 #define WTAP_FILE_TYPE_SUBTYPE_CAMINS 64 #define WTAP_FILE_TYPE_SUBTYPE_STANAG_4607 65 +#define WTAP_FILE_TYPE_SUBTYPE_NETSCALER_3_0 66 #define WTAP_NUM_FILE_TYPES_SUBTYPES wtap_get_num_file_types_subtypes() |