6 * Copyright (c) 2006 by Ravi Kondamuru <Ravi.Kondamuru@citrix.com>
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 #include "file_wrappers.h"
31 #include "netscaler.h"
33 /* Defines imported from netscaler code: nstypes.h */
35 #define ns_min(a, b) ((a<b)?a:b)
37 /* Defines imported from netscaler code: nsperfrc.h */
39 #define NSPR_SIGSTR_V10 "NetScaler Performance Data"
40 #define NSPR_SIGSTR_V20 "NetScaler V20 Performance Data"
41 #define NSPR_SIGSTR NSPR_SIGSTR_V20
42 /* Defined but not used */
43 #define NSPR_SIGSTR_V21 "NetScaler V21 Performance Data"
44 #define NSPR_SIGSTR_V22 "NetScaler V22 Performance Data"
46 #define NSPR_PAGESIZE 8192
48 /* The different record types
49 ** NOTE: The Record Type is two byte fields and unused space is recognized by
50 ** either bytes being zero, therefore no record should any byte value as
53 ** New Performance Record Type is only one byte.
55 #define NSPR_UNUSEDSPACE_V10 0x0000 /* rest of the page is unused */
56 #define NSPR_UNUSEDSPACE_V20 0x00 /* rest of the page is unused */
57 #define NSPR_SIGNATURE_V10 0x0101 /* signature */
58 #define NSPR_SIGNATURE_V20 0x01 /* signature */
59 #define NSPR_ABSTIME_V10 0x0107 /* data capture time in secs from 1970*/
60 #define NSPR_ABSTIME_V20 0x07 /* data capture time in secs from 1970*/
61 #define NSPR_RELTIME_V10 0x0108 /* relative time in ms from last time */
62 #define NSPR_RELTIME_V20 0x08 /* relative time in ms from last time */
63 #define NSPR_RELTIMEHR_V10 0x0109 /* high resolution relative time */
64 #define NSPR_RELTIMEHR_V20 0x09 /* high resolution relative time */
65 #define NSPR_SYSTARTIME_V10 0x010A /* system start time */
66 #define NSPR_SYSTARTIME_V20 0x0A /* system start time */
67 #define NSPR_RELTIME2B_V10 0x010B /* relative time in ms from last time */
68 #define NSPR_RELTIME2B_V20 0x0B /* relative time in ms from last time */
71 /* The high resolution relative time format.
72 ** The MS 2 bits of the high resoltion time is defined as follows:
73 ** 00 : time value is in second
74 ** 01 : time value is in mili second
75 ** 10 : time value is in micro second
76 ** 11 : time value is in nano second
78 #define NSPR_HRTIME_MASKTM 0x3FFFFFFF /* mask to get time value */
79 #define NSPR_HRTIME_MASKFMT 0xC0000000 /* time value format mask */
80 #define NSPR_HRTIME_SEC 0x00000000 /* time value in second */
81 #define NSPR_HRTIME_MSEC 0x40000000 /* time value in mili second */
82 #define NSPR_HRTIME_USEC 0x80000000 /* time value in micro second */
83 #define NSPR_HRTIME_NSEC 0xC0000000 /* time value in nano second */
86 typedef struct nspr_header_v10
88 guint16 ph_RecordType; /* Record Type */
89 guint16 ph_RecordSize; /* Record Size including header */
91 #define nspr_header_v10_s sizeof(nspr_header_v10_t)
93 /* This is V20 short header (2 bytes long) to be included where needed */
94 #define NSPR_HEADER_V20(prefix) \
95 guint8 prefix##_RecordType; /* Record Type */ \
96 guint8 prefix##_RecordSize /* Record Size including header */ \
97 /* end of declaration */
99 /* This is new long header (3 bytes long) to be included where needed */
100 #define NSPR_HEADER3B_V20(prefix) \
101 guint8 prefix##_RecordType; /* Record Type */ \
102 guint8 prefix##_RecordSizeLow; /* Record Size including header */ \
103 guint8 prefix##_RecordSizeHigh /* Record Size including header */ \
104 /* end of declaration */
105 #define NSPR_HEADER3B_V21 NSPR_HEADER3B_V20
106 #define NSPR_HEADER3B_V22 NSPR_HEADER3B_V20
108 typedef struct nspr_hd_v20
110 NSPR_HEADER3B_V20(phd); /* long performance header */
113 #define nspr_hd_v20_s sizeof(nspr_hd_v20_t)
117 ** How to know if header size is short or long?
118 ** The short header size can be 0-127 bytes long. If MS Bit of ph_RecordSize
119 ** is set then record size has 2 bytes
121 #define NSPR_V20RECORDSIZE_2BYTES 0x80
123 /* get the record size from performance record */
124 #define nspr_getv20recordsize(hdp) \
125 (((hdp)->phd_RecordSizeLow & NSPR_V20RECORDSIZE_2BYTES)? \
126 (((hdp)->phd_RecordSizeHigh * NSPR_V20RECORDSIZE_2BYTES)+ \
127 ((hdp)->phd_RecordSizeLow & ~NSPR_V20RECORDSIZE_2BYTES)) : \
128 (hdp)->phd_RecordSizeLow)
132 /* Performance Data Header with device number */
133 typedef struct nspr_headerdev_v10
135 guint16 ph_RecordType; /* Record Type */
136 guint16 ph_RecordSize; /* Record Size including header */
137 guint32 ph_DevNo; /* Network Device (NIC/CONN) number */
138 } nspr_headerdev_v10_t;
139 #define nspr_headerdev_v10_s sizeof(nspr_headerdev_v10_t)
141 typedef struct nspr_hd_v10
143 nspr_header_v10_t phd; /* performance header */
145 #define nspr_hd_v10_s sizeof(nspr_hd_v10_t)
147 typedef struct nspr_hdev_v10
149 nspr_headerdev_v10_t phd; /* performance header */
151 #define nspr_hdev_v10_s sizeof(nspr_hdev_v10_t)
153 /* if structure has defined phd as first field, it can use following names */
154 #define nsprRecordType phd.ph_RecordType
155 #define nsprRecordSize phd.ph_RecordSize
156 #define nsprReserved phd.ph_Reserved
157 #define nsprRecordTypeOrg phd.ph_Reserved
158 #define nsprDevNo phd.ph_DevNo
160 /* NSPR_SIGNATURE_V10 structure */
161 #define NSPR_SIGSIZE_V10 56 /* signature value size in bytes */
164 typedef struct nspr_signature_v10
166 nspr_header_v10_t phd; /* performance header */
167 guint8 sig_EndianType; /* Endian Type for the data */
168 guint8 sig_Reserved0;
169 guint16 sig_Reserved1;
170 gchar sig_Signature[NSPR_SIGSIZE_V10]; /* Signature value */
171 } nspr_signature_v10_t;
172 #define nspr_signature_v10_s sizeof(nspr_signature_v10_t)
174 /* NSPR_SIGNATURE_V20 structure */
175 typedef struct nspr_signature_v20
177 NSPR_HEADER_V20(sig); /* short performance header */
178 guint8 sig_EndianType; /* Endian Type for the data */
179 gchar sig_Signature[1]; /* Signature value */
180 } nspr_signature_v20_t;
181 #define nspr_signature_v20_s (sizeof(nspr_signature_v20_t) -1)
183 /* NSPR_ABSTIME_V10 and NSPR_SYSTARTIME_V10 structure */
184 typedef struct nspr_abstime_v10
186 nspr_header_v10_t phd; /* performance header */
187 guint32 abs_RelTime; /* relative time is ms from last time */
188 guint32 abs_Time; /* absolute time in seconds from 1970 */
189 } nspr_abstime_v10_t;
190 #define nspr_abstime_v10_s sizeof(nspr_abstime_v10_t)
193 /* NSPR_ABSTIME_V20 and NSPR_SYSTARTIME_V20 structure */
194 typedef struct nspr_abstime_v20
196 NSPR_HEADER_V20(abs); /* short performance header */
197 guint16 abs_RelTime; /* relative time is ms from last time */
198 guint32 abs_Time; /* absolute time in seconds from 1970 */
199 } nspr_abstime_v20_t;
200 #define nspr_abstime_v20_s sizeof(nspr_abstime_v20_t)
204 /* full packet trace structure */
205 typedef struct nspr_pktracefull_v10
207 nspr_headerdev_v10_t phd; /* performance header */
208 guint32 fp_RelTimeHr; /* High resolution relative time */
209 guint8 fp_Data[1]; /* packet data starts here */
210 } nspr_pktracefull_v10_t;
211 #define nspr_pktracefull_v10_s (nspr_hdev_v10_s + 4)
213 /* new full packet trace structure v20 */
214 typedef struct nspr_pktracefull_v20
216 NSPR_HEADER3B_V20(fp); /* long performance header */
217 guint8 fp_DevNo; /* Network Device (NIC) number */
218 guint32 fp_RelTimeHr; /* High resolution relative time */
219 guint8 fp_Data[4]; /* packet data starts here */
220 } nspr_pktracefull_v20_t;
221 #define nspr_pktracefull_v20_s (sizeof(nspr_pktracefull_v20_t) - 4)
223 /* new full packet trace structure v21 */
224 typedef struct nspr_pktracefull_v21
226 NSPR_HEADER3B_V21(fp); /* long performance header */
227 guint8 fp_DevNo; /* Network Device (NIC) number */
228 guint32 fp_RelTimeHr; /* High resolution relative time */
229 guint32 fp_PcbDevNo; /* PCB devno */
230 guint32 fp_lPcbDevNo; /* link PCB devno */
231 guint8 fp_Data[4]; /* packet data starts here */
232 } nspr_pktracefull_v21_t;
233 #define nspr_pktracefull_v21_s (sizeof(nspr_pktracefull_v21_t) - 4)
235 /* new full packet trace structure v22 */
236 typedef struct nspr_pktracefull_v22
238 NSPR_HEADER3B_V22(fp); /* long performance header */
239 guint8 fp_DevNo; /* Network Device (NIC) number */
240 guint32 fp_RelTimeHr; /* High resolution relative time */
241 guint32 fp_PcbDevNo; /* PCB devno */
242 guint32 fp_lPcbDevNo; /* link PCB devno */
244 guint8 fp_Data[4]; /* packet data starts here */
245 } nspr_pktracefull_v22_t;
246 #define nspr_pktracefull_v22_s (sizeof(nspr_pktracefull_v22_t) - 4)
248 typedef struct nspr_pktracefull_v23
250 NSPR_HEADER3B_V22(fp); /* long performance header */
251 guint8 fp_DevNo; /* Network Device (NIC) number */
252 guint32 fp_AbsTimeLowHdr; /* High resolution low time */
253 guint32 fp_AbsTimeHighHdr; /* Higher value of the absolute time */
254 guint32 fp_PcbDevNo; /* PCB devno */
255 guint32 fp_lPcbDevNo; /* link PCB devno */
256 guint16 fp_VlanTag; /* vlan tag */
257 guint16 fp_Coreid; /* coreid of the packet */
258 guint8 fp_Data[4]; /* packet data starts here */
259 } nspr_pktracefull_v23_t;
260 #define nspr_pktracefull_v23_s (sizeof(nspr_pktracefull_v23_t) - 4)
262 /* partial packet trace structure */
263 typedef struct nspr_pktracepart_v10
265 nspr_headerdev_v10_t phd; /* performance header */
266 guint32 pp_RelTimeHr; /* High resolution relative time */
267 guint16 pp_PktSizeOrg; /* Original packet size */
268 guint16 pp_PktOffset; /* starting offset in packet */
269 guint8 pp_Data[1]; /* packet data starts here */
270 } nspr_pktracepart_v10_t;
271 #define nspr_pktracepart_v10_s (nspr_pktracefull_v10_s + 4)
273 /* new partial packet trace structure */
274 typedef struct nspr_pktracepart_v20
276 NSPR_HEADER3B_V20(pp); /* long performance header */
277 guint8 pp_DevNo; /* Network Device (NIC) number */
278 guint32 pp_RelTimeHr; /* High resolution relative time */
279 guint16 pp_PktSizeOrg; /* Original packet size */
280 guint16 pp_PktOffset; /* starting offset in packet */
281 guint8 pp_Data[4]; /* packet data starts here */
282 } nspr_pktracepart_v20_t;
283 #define nspr_pktracepart_v20_s (sizeof(nspr_pktracepart_v20_t) -4)
285 /* new partial packet trace structure */
286 typedef struct nspr_pktracepart_v21
288 NSPR_HEADER3B_V21(pp); /* long performance header */
289 guint8 pp_DevNo; /* Network Device (NIC) number */
290 guint32 pp_RelTimeHr; /* High resolution relative time */
291 guint16 pp_PktSizeOrg; /* Original packet size */
292 guint16 pp_PktOffset; /* starting offset in packet */
293 guint32 pp_PcbDevNo; /* PCB devno */
294 guint32 pp_lPcbDevNo; /* link PCB devno */
295 guint8 pp_Data[4]; /* packet data starts here */
296 } nspr_pktracepart_v21_t;
297 #define nspr_pktracepart_v21_s (sizeof(nspr_pktracepart_v21_t) -4)
299 /* new partial packet trace structure v22 */
300 typedef struct nspr_pktracepart_v22
302 NSPR_HEADER3B_V22(pp); /* long performance header */
303 guint8 pp_DevNo; /* Network Device (NIC) number */
304 guint32 pp_RelTimeHr; /* High resolution relative time */
305 guint16 pp_PktSizeOrg; /* Original packet size */
306 guint16 pp_PktOffset; /* starting offset in packet */
307 guint32 pp_PcbDevNo; /* PCB devno */
308 guint32 pp_lPcbDevNo; /* link PCB devno */
309 guint16 pp_VlanTag; /* Vlan Tag */
310 guint8 pp_Data[4]; /* packet data starts here */
311 } nspr_pktracepart_v22_t;
312 #define nspr_pktracepart_v22_s (sizeof(nspr_pktracepart_v22_t) -4)
314 typedef struct nspr_pktracepart_v23
316 NSPR_HEADER3B_V22(pp); /* long performance header */
317 guint8 pp_DevNo; /* Network Device (NIC) number */
318 guint32 pp_AbsTimeLowHdr; /* High resolution low time */
319 guint32 pp_AbsTimeHighHdr; /* Higher value of the absolute time */
320 guint16 pp_PktSizeOrg; /* Original packet size */
321 guint16 pp_PktOffset; /* starting offset in packet */
322 guint32 pp_PcbDevNo; /* PCB devno */
323 guint32 pp_lPcbDevNo; /* link PCB devno */
324 guint16 pp_VlanTag; /* vlan tag */
325 guint16 pp_Coreid; /* Coreid of the packet */
326 guint8 pp_Data[4]; /* packet data starts here */
327 } nspr_pktracepart_v23_t;
328 #define nspr_pktracepart_v23_s (sizeof(nspr_pktracepart_v23_t) -4)
330 #define TRACE_V10_REC_LEN_OFF(enumprefix,structprefix,structname) \
331 __TNV1O(enumprefix,structprefix,structname,dir,phd.ph_RecordType)\
332 __TNV1L(enumprefix,structprefix,structname,dir,phd.ph_RecordType)\
333 __TNV1O(enumprefix,structprefix,structname,nicno,phd.ph_DevNo)\
334 __TNV1L(enumprefix,structprefix,structname,nicno,phd.ph_DevNo)\
335 __TNO(enumprefix,structprefix,structname,eth,Data)
337 #define TRACE_V20_REC_LEN_OFF(enumprefix,structprefix,structname) \
338 __TNO(enumprefix,structprefix,structname,dir,RecordType)\
339 __TNL(enumprefix,structprefix,structname,dir,RecordType)\
340 __TNO(enumprefix,structprefix,structname,nicno,DevNo)\
341 __TNL(enumprefix,structprefix,structname,nicno,DevNo)\
342 __TNO(enumprefix,structprefix,structname,eth,Data)
344 #define TRACE_V21_REC_LEN_OFF(enumprefix,structprefix,structname) \
345 TRACE_V20_REC_LEN_OFF(enumprefix,structprefix,structname)\
346 __TNO(enumprefix,structprefix,structname,pcb,PcbDevNo)\
347 __TNO(enumprefix,structprefix,structname,l_pcb,lPcbDevNo)
349 #define TRACE_V22_REC_LEN_OFF(enumprefix,structprefix,structname) \
350 TRACE_V21_REC_LEN_OFF(enumprefix,structprefix,structname)\
351 __TNO(enumprefix,structprefix,structname,vlantag,VlanTag)\
353 #define TRACE_V23_REC_LEN_OFF(enumprefix,structprefix,structname) \
354 TRACE_V22_REC_LEN_OFF(enumprefix,structprefix,structname)\
355 __TNO(enumprefix,structprefix,structname,coreid,Coreid)\
357 #define myoffsetof(type,fieldname) (&(((type*)0)->fieldname))
358 #define __TNO(enumprefix,structprefix,structname,hdrname,structfieldname) \
359 guint8 enumprefix##_##hdrname##_offset = (guint8)GPOINTER_TO_INT(myoffsetof(nspr_##structname##_t,structprefix##_##structfieldname));
361 #define __TNL(enumprefix,structprefix,structname,hdrname,structfieldname) \
362 guint8 enumprefix##_##hdrname##_len = (guint8)sizeof(((nspr_##structname##_t*)0)->structprefix##_##structfieldname);
364 #define __TNV1O(enumprefix,structprefix,structname,hdrname,structfieldname) \
365 guint8 enumprefix##_##hdrname##_offset = (guint8)GPOINTER_TO_INT(myoffsetof(nspr_##structname##_t,structfieldname));
367 #define __TNV1L(enumprefix,structprefix,structname,hdrname,structfieldname) \
368 guint8 enumprefix##_##hdrname##_len = (guint8)sizeof(((nspr_##structname##_t*)0)->structfieldname);
370 TRACE_V10_REC_LEN_OFF(v10_part,pp,pktracepart_v10)
371 TRACE_V10_REC_LEN_OFF(v10_full,fp,pktracefull_v10)
372 TRACE_V20_REC_LEN_OFF(v20_part,pp,pktracepart_v20)
373 TRACE_V20_REC_LEN_OFF(v20_full,fp,pktracefull_v20)
374 TRACE_V21_REC_LEN_OFF(v21_part,pp,pktracepart_v21)
375 TRACE_V21_REC_LEN_OFF(v21_full,fp,pktracefull_v21)
376 TRACE_V22_REC_LEN_OFF(v22_part,pp,pktracepart_v22)
377 TRACE_V22_REC_LEN_OFF(v22_full,fp,pktracefull_v22)
378 TRACE_V23_REC_LEN_OFF(v23_part,pp,pktracepart_v23)
379 TRACE_V23_REC_LEN_OFF(v23_full,fp,pktracefull_v23)
386 #define ns_setabstime(wth, AbsoluteTime, RelativeTimems) \
388 wth->capture.nstrace->nspm_curtime = AbsoluteTime; \
389 wth->capture.nstrace->nspm_curtimemsec += RelativeTimems; \
390 wth->capture.nstrace->nspm_curtimelastmsec = wth->capture.nstrace->nspm_curtimemsec; \
394 #define ns_setrelativetime(wth, RelativeTimems) \
397 wth->capture.nstrace->nspm_curtimemsec += RelativeTimems; \
398 rsec = (guint32)(wth->capture.nstrace->nspm_curtimemsec - wth->capture.nstrace->nspm_curtimelastmsec)/1000; \
399 wth->capture.nstrace->nspm_curtime += rsec; \
400 wth->capture.nstrace->nspm_curtimelastmsec += rsec * 1000; \
404 guint32 nspm_signature_isv10(gchar *sigp);
405 guint32 nspm_signature_isv20(gchar *sigp);
406 guint32 nspm_signature_version(wtap*, gchar*, gint32);
407 gboolean nstrace_read(wtap *wth, int *err, gchar **err_info,
408 gint64 *data_offset);
409 gboolean nstrace_read_v10(wtap *wth, int *err, gchar **err_info,
410 gint64 *data_offset);
411 gboolean nstrace_read_v20(wtap *wth, int *err, gchar **err_info,
412 gint64 *data_offset);
413 gboolean nstrace_seek_read(wtap *wth, gint64 seek_off,
414 union wtap_pseudo_header *pseudo_header,
415 guchar *pd, int length,
416 int *err, gchar **err_info _U_);
417 void nstrace_close(wtap *wth);
418 void nstrace_sequential_close(wtap *wth);
420 gboolean nstrace_set_start_time_v10(wtap *wth);
421 gboolean nstrace_set_start_time_v20(wtap *wth);
422 gboolean nstrace_set_start_time(wtap *wth);
423 guint64 ns_hrtime2nsec(guint32 tm);
425 static gboolean nstrace_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
426 const union wtap_pseudo_header *pseudo_header, const guchar *pd, int *err);
427 gboolean nstrace_add_signature(wtap_dumper *wdh);
428 gboolean nstrace_add_abstime(wtap_dumper *wdh, const struct wtap_pkthdr *phdr, const guchar *pd);
431 #define GET_READ_PAGE_SIZE(remaining_file_size) ((gint32)((remaining_file_size>NSPR_PAGESIZE)?NSPR_PAGESIZE:remaining_file_size))
434 guint64 ns_hrtime2nsec(guint32 tm)
436 guint32 val = tm & NSPR_HRTIME_MASKTM;
437 switch(tm & NSPR_HRTIME_MASKFMT)
439 case NSPR_HRTIME_SEC: return (guint64)val*1000000000;
440 case NSPR_HRTIME_MSEC: return (guint64)val*1000000;
441 case NSPR_HRTIME_USEC: return (guint32)val*1000;
442 case NSPR_HRTIME_NSEC: return val;
449 ** Netscaler trace format open routines
451 int nstrace_open(wtap *wth, int *err, gchar **err_info)
457 errno = WTAP_ERR_CANT_READ;
459 if ((file_size = wtap_file_size(wth, err)) == -1)
462 nstrace_buf = g_malloc(NSPR_PAGESIZE);
463 page_size = GET_READ_PAGE_SIZE(file_size);
465 switch ((wth->file_type = nspm_signature_version(wth, nstrace_buf, page_size)))
467 case WTAP_FILE_NETSCALER_1_0:
468 wth->file_encap = WTAP_ENCAP_NSTRACE_1_0;
471 case WTAP_FILE_NETSCALER_2_0:
472 wth->file_encap = WTAP_ENCAP_NSTRACE_2_0;
476 *err = WTAP_ERR_UNSUPPORTED;
477 *err_info = g_strdup_printf("nstrace: file type %d unsupported", wth->file_type);
482 if ((file_seek(wth->fh, 0, SEEK_SET, err)) == -1)
484 *err = file_error(wth->fh);
489 if (page_size != file_read(nstrace_buf, 1, page_size, wth->fh))
491 *err = file_error(wth->fh);
496 wth->subtype_read = nstrace_read;
497 wth->subtype_seek_read = nstrace_seek_read;
498 wth->subtype_close = nstrace_close;
500 wth->capture.nstrace = g_malloc(sizeof(nstrace_t));
501 wth->capture.nstrace->pnstrace_buf = nstrace_buf;
502 wth->capture.nstrace->nstrace_buflen = page_size;
503 wth->capture.nstrace->nstrace_buf_offset = 0;
504 wth->capture.nstrace->nspm_curtime = 0;
505 wth->capture.nstrace->nspm_curtimemsec = 0;
506 wth->capture.nstrace->nspm_curtimelastmsec = 0;
507 wth->capture.nstrace->nsg_creltime = 0;
508 wth->capture.nstrace->file_size = file_size;
511 /* Set the start time by looking for the abstime record */
512 if ((nstrace_set_start_time(wth)) == FALSE)
514 /* Reset the read pointer to start of the file. */
515 if ((file_seek(wth->fh, 0, SEEK_SET, err)) == -1)
517 *err = file_error(wth->fh);
518 g_free(wth->capture.nstrace->pnstrace_buf);
519 g_free(wth->capture.nstrace);
523 /* Read the first page of data */
524 if (page_size != file_read(nstrace_buf, 1, page_size, wth->fh))
526 *err = file_error(wth->fh);
527 g_free(wth->capture.nstrace->pnstrace_buf);
528 g_free(wth->capture.nstrace);
532 /* reset the buffer offset */
533 wth->capture.nstrace->nstrace_buf_offset = 0;
536 wth->tsprecision = WTAP_FILE_TSPREC_NSEC;
537 wth->phdr.ts.secs = wth->capture.nstrace->nspm_curtime;
538 wth->phdr.ts.nsecs = 0;
545 #define nspm_signature_func(ver) \
546 guint32 nspm_signature_isv##ver(gchar *sigp) {\
547 return strncmp(sigp,NSPR_SIGSTR_V##ver,(sizeof(NSPR_SIGSTR_V##ver)-1));\
550 nspm_signature_func(10)
551 nspm_signature_func(20)
554 ** Check signature and return the version number of the signature.
555 ** If not found, it returns 0. At the time of return from this function
556 ** we might not be at the first page. So after a call to this function, there
557 ** has to be a file seek to return to the start of the first page.
560 nspm_signature_version(wtap *wth, gchar *nstrace_buf, gint32 len)
562 gchar *dp = nstrace_buf;
564 if (len == file_read(dp, 1, len, wth->fh)) {
566 for ( ; len > (gint32)(ns_min(sizeof(NSPR_SIGSTR_V10), sizeof(NSPR_SIGSTR_V20))); dp++, len--)
568 #define sigv10p ((nspr_signature_v10_t*)dp)
569 if ((sigv10p->nsprRecordType == NSPR_SIGNATURE_V10) &&
570 (sigv10p->nsprRecordSize <= len) &&
571 ((gint32)sizeof(NSPR_SIGSTR_V10) <= len) &&
572 (!nspm_signature_isv10(sigv10p->sig_Signature)))
573 return WTAP_FILE_NETSCALER_1_0;
576 #define sigv20p ((nspr_signature_v20_t*)dp)
577 if ((sigv20p->sig_RecordType == NSPR_SIGNATURE_V20) &&
578 (sigv20p->sig_RecordSize <= len) &&
579 ((gint32)sizeof(NSPR_SIGSTR_V20) <= len) &&
580 (!nspm_signature_isv20(sigv20p->sig_Signature)))
581 return WTAP_FILE_NETSCALER_2_0;
586 return 0; /* no version found */
589 #define nspr_getv10recordsize(hdp) (hdp->nsprRecordSize)
590 #define nspr_getv10recordtype(hdp) (hdp->nsprRecordType)
591 #define nspr_getv20recordtype(hdp) (hdp->phd_RecordType)
593 #define nstrace_set_start_time_ver(ver) \
594 gboolean nstrace_set_start_time_v##ver(wtap *wth) \
596 gchar* nstrace_buf = wth->capture.nstrace->pnstrace_buf;\
597 gint32 nstrace_buf_offset = wth->capture.nstrace->nstrace_buf_offset;\
598 gint32 nstrace_buflen = wth->capture.nstrace->nstrace_buflen;\
601 while (nstrace_buf_offset < nstrace_buflen)\
603 nspr_hd_v##ver##_t *fp = (nspr_hd_v##ver##_t *) &nstrace_buf[nstrace_buf_offset];\
604 switch (nspr_getv##ver##recordtype(fp))\
606 case NSPR_ABSTIME_V##ver:\
607 ns_setabstime(wth, ((nspr_abstime_v##ver##_t *) fp)->abs_Time, ((nspr_abstime_v##ver##_t *) fp)->abs_RelTime);\
608 wth->capture.nstrace->nstrace_buf_offset = nstrace_buf_offset + nspr_getv##ver##recordsize(fp);\
609 wth->capture.nstrace->nstrace_buflen = nstrace_buflen;\
611 case NSPR_UNUSEDSPACE_V10:\
612 nstrace_buf_offset = nstrace_buflen;\
615 nstrace_buf_offset += nspr_getv##ver##recordsize(fp);\
618 nstrace_buf_offset = 0;\
619 wth->data_offset += nstrace_buflen;\
620 nstrace_buflen = GET_READ_PAGE_SIZE((wth->capture.nstrace->file_size - wth->data_offset));\
621 }while((nstrace_buflen > 0) && (nstrace_buflen == (file_read(nstrace_buf, 1, nstrace_buflen, wth->fh))));\
625 nstrace_set_start_time_ver(10)
626 nstrace_set_start_time_ver(20)
628 #undef nspr_getv10recordtype
629 #undef nspr_getv20recordtype
630 #undef nspr_getv10recordsize
633 ** Set the start time of the trace file. We look for the first ABSTIME record. We use that
634 ** to set the start time. Apart from that we also make sure that we remember the position of
635 ** the next record after the ABSTIME record. Inorder to report correct time values, all trace
636 ** records before the ABSTIME record are ignored.
638 gboolean nstrace_set_start_time(wtap *wth)
640 if (wth->file_type == WTAP_FILE_NETSCALER_1_0)
641 return nstrace_set_start_time_v10(wth);
642 else if (wth->file_type == WTAP_FILE_NETSCALER_2_0)
643 return nstrace_set_start_time_v20(wth);
648 #define __TNO(enumprefix,structprefix,structname,hdrname,structfieldname) \
649 wth->pseudo_header.nstr.hdrname##_offset = enumprefix##_##hdrname##_offset;
651 #define __TNL(enumprefix,structprefix,structname,hdrname,structfieldname) \
652 wth->pseudo_header.nstr.hdrname##_len = enumprefix##_##hdrname##_len;
654 #define __TNV1O(enumprefix,structprefix,structname,hdrname,structfieldname) \
655 __TNO(enumprefix,structprefix,structname,hdrname,structfieldname)
657 #define __TNV1L(enumprefix,structprefix,structname,hdrname,structfieldname) \
658 __TNL(enumprefix,structprefix,structname,hdrname,structfieldname)
663 ** Netscaler trace format read routines.
665 gboolean nstrace_read_v10(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
668 guint64 nsg_creltime = wth->capture.nstrace->nsg_creltime;
669 gchar *nstrace_buf = wth->capture.nstrace->pnstrace_buf;
670 gint32 nstrace_buf_offset = wth->capture.nstrace->nstrace_buf_offset;
671 gint32 nstrace_buflen = wth->capture.nstrace->nstrace_buflen;
672 nspr_pktracefull_v10_t *fp;
673 nspr_pktracepart_v10_t *pp;
679 while ((nstrace_buf_offset < nstrace_buflen) &&
680 ((nstrace_buflen - nstrace_buf_offset) >= ((gint32)sizeof(fp->nsprRecordType))))
683 fp = (nspr_pktracefull_v10_t *) &nstrace_buf[nstrace_buf_offset];
684 pp = (nspr_pktracepart_v10_t *) fp;
686 switch (fp->nsprRecordType)
688 case NSPR_PDPKTRACEFULLTX_V10:
689 case NSPR_PDPKTRACEFULLTXB_V10:
690 case NSPR_PDPKTRACEFULLRX_V10:
692 nsg_creltime += ns_hrtime2nsec(fp->fp_RelTimeHr);
693 wth->phdr.ts.secs = wth->capture.nstrace->nspm_curtime + (guint32) (nsg_creltime / 1000000000);
694 wth->phdr.ts.nsecs = (guint32) (nsg_creltime % 1000000000);
696 wth->phdr.len = fp->nsprRecordSize;
697 wth->phdr.caplen = wth->phdr.len;
700 TRACE_V10_REC_LEN_OFF(v10_full,fp,pktracefull_v10);
702 buffer_assure_space(wth->frame_buffer, wth->phdr.caplen);
703 memcpy(buffer_start_ptr(wth->frame_buffer), fp, wth->phdr.caplen);
704 *data_offset = wth->data_offset + nstrace_buf_offset;
706 wth->capture.nstrace->nstrace_buf_offset = nstrace_buf_offset + fp->nsprRecordSize;
707 wth->capture.nstrace->nstrace_buflen = nstrace_buflen;
708 wth->capture.nstrace->nsg_creltime = nsg_creltime;
712 case NSPR_PDPKTRACEPARTTX_V10:
713 case NSPR_PDPKTRACEPARTTXB_V10:
714 case NSPR_PDPKTRACEPARTRX_V10:
716 nsg_creltime += ns_hrtime2nsec(pp->pp_RelTimeHr);
717 wth->phdr.ts.secs = wth->capture.nstrace->nspm_curtime + (guint32) (nsg_creltime / 1000000000);
718 wth->phdr.ts.nsecs = (guint32) (nsg_creltime % 1000000000);
720 wth->phdr.len = pp->pp_PktSizeOrg + nspr_pktracepart_v10_s;
721 wth->phdr.caplen = pp->nsprRecordSize;
723 TRACE_V10_REC_LEN_OFF(v10_part,pp,pktracepart_v10);
725 buffer_assure_space(wth->frame_buffer, wth->phdr.caplen);
726 memcpy(buffer_start_ptr(wth->frame_buffer), pp, wth->phdr.caplen);
727 *data_offset = wth->data_offset + nstrace_buf_offset;
729 wth->capture.nstrace->nstrace_buf_offset = nstrace_buf_offset + pp->nsprRecordSize;
730 wth->capture.nstrace->nsg_creltime = nsg_creltime;
731 wth->capture.nstrace->nstrace_buflen = nstrace_buflen;
735 case NSPR_ABSTIME_V10:
737 ns_setabstime(wth, ((nspr_abstime_v10_t *) fp)->abs_Time, ((nspr_abstime_v10_t *) fp)->abs_RelTime);
738 nstrace_buf_offset += fp->nsprRecordSize;
741 case NSPR_RELTIME_V10:
743 ns_setrelativetime(wth, ((nspr_abstime_v10_t *) fp)->abs_RelTime);
744 nstrace_buf_offset += fp->nsprRecordSize;
747 case NSPR_UNUSEDSPACE_V10:
749 nstrace_buf_offset = nstrace_buflen;
754 nstrace_buf_offset += fp->nsprRecordSize;
759 nstrace_buf_offset = 0;
760 wth->data_offset += nstrace_buflen;
761 nstrace_buflen = GET_READ_PAGE_SIZE((wth->capture.nstrace->file_size - wth->data_offset));
762 }while((nstrace_buflen > 0) && (nstrace_buflen == (file_read(nstrace_buf, 1, nstrace_buflen, wth->fh))));
767 #define TIMEDEFV20(fp,type) \
769 nsg_creltime += ns_hrtime2nsec(fp->type##_RelTimeHr);\
770 wth->phdr.ts.secs = wth->capture.nstrace->nspm_curtime + (guint32) (nsg_creltime / 1000000000);\
771 wth->phdr.ts.nsecs = (guint32) (nsg_creltime % 1000000000);\
774 #define TIMEDEFV23(fp,type) \
776 /* access _AbsTimeHighHdr as a 64bit value */\
777 nsg_creltime = (((guint64)fp->type##_AbsTimeHighHdr<<32) | (fp->type##_AbsTimeLowHdr));\
778 wth->phdr.ts.secs = (guint32) (nsg_creltime / 1000000000);\
779 wth->phdr.ts.nsecs = (guint32) (nsg_creltime % 1000000000);\
782 #define TIMEDEFV21(fp,type) TIMEDEFV20(fp,type)
783 #define TIMEDEFV22(fp,type) TIMEDEFV20(fp,type)
785 #define PPSIZEDEFV20(pp,ver) \
787 wth->phdr.len = pp->pp_PktSizeOrg + nspr_pktracepart_v##ver##_s;\
788 wth->phdr.caplen = nspr_getv20recordsize((nspr_hd_v20_t *)pp);\
791 #define PPSIZEDEFV21(pp,ver) PPSIZEDEFV20(pp,ver)
792 #define PPSIZEDEFV22(pp,ver) PPSIZEDEFV20(pp,ver)
793 #define PPSIZEDEFV23(pp,ver) PPSIZEDEFV20(pp,ver)
795 #define FPSIZEDEFV20(fp,ver)\
797 wth->phdr.len = nspr_getv20recordsize((nspr_hd_v20_t *)fp);\
798 wth->phdr.caplen = wth->phdr.len;\
801 #define FPSIZEDEFV21(pp,ver) FPSIZEDEFV20(fp,ver)
802 #define FPSIZEDEFV22(pp,ver) FPSIZEDEFV20(fp,ver)
803 #define FPSIZEDEFV23(pp,ver) FPSIZEDEFV20(fp,ver)
805 #define PACKET_DESCRIBE(FPTIMEDEF,SIZEDEF,ver,enumprefix,type,structname,TYPE)\
807 nspr_##structname##_t *fp= (nspr_##structname##_t*)&nstrace_buf[nstrace_buf_offset];\
808 TIMEDEFV##ver(fp,type);\
809 SIZEDEF##ver(fp,ver);\
810 TRACE_V##ver##_REC_LEN_OFF(enumprefix,type,structname);\
811 buffer_assure_space(wth->frame_buffer, wth->phdr.caplen);\
812 memcpy(buffer_start_ptr(wth->frame_buffer), fp, wth->phdr.caplen);\
813 *data_offset = wth->data_offset + nstrace_buf_offset;\
814 wth->capture.nstrace->nstrace_buf_offset = nstrace_buf_offset + nspr_getv20recordsize((nspr_hd_v20_t *)fp);\
815 wth->capture.nstrace->nstrace_buflen = nstrace_buflen;\
816 wth->capture.nstrace->nsg_creltime = nsg_creltime;\
817 wth->pseudo_header.nstr.rec_type = NSPR_HEADER_VERSION##TYPE;\
821 gboolean nstrace_read_v20(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
823 guint64 nsg_creltime = wth->capture.nstrace->nsg_creltime;
824 gchar *nstrace_buf = wth->capture.nstrace->pnstrace_buf;
825 gint32 nstrace_buf_offset = wth->capture.nstrace->nstrace_buf_offset;
826 gint32 nstrace_buflen = wth->capture.nstrace->nstrace_buflen;
827 nspr_pktracefull_v20_t *fp20;
828 nspr_pktracefull_v21_t *fp21;
834 while ((nstrace_buf_offset < nstrace_buflen) &&
835 ((nstrace_buflen - nstrace_buf_offset) >= ((gint32)sizeof(fp21->fp_RecordType))))
837 fp21 = (nspr_pktracefull_v21_t *) &nstrace_buf[nstrace_buf_offset];
839 switch (fp21->fp_RecordType)
842 #define GENERATE_CASE(type,acttype) \
843 case NSPR_PDPKTRACEFULLTX_V##type:\
844 case NSPR_PDPKTRACEFULLTXB_V##type:\
845 case NSPR_PDPKTRACEFULLRX_V##type:\
846 PACKET_DESCRIBE(TIMEDEF,FPSIZEDEFV,type,v##type##_full,fp,pktracefull_v##type,acttype);
847 GENERATE_CASE(23,203);
848 GENERATE_CASE(22,202);
849 GENERATE_CASE(21,201);
850 GENERATE_CASE(20,200);
853 #define GENERATE_CASE(type,acttype) \
854 case NSPR_PDPKTRACEPARTTX_V##type:\
855 case NSPR_PDPKTRACEPARTTXB_V##type:\
856 case NSPR_PDPKTRACEPARTRX_V##type:\
857 PACKET_DESCRIBE(TIMEDEF,PPSIZEDEFV,type,v##type##_part,pp,pktracepart_v##type,acttype);
858 GENERATE_CASE(23,203);
859 GENERATE_CASE(22,202);
860 GENERATE_CASE(21,201);
861 GENERATE_CASE(20,200);
864 case NSPR_ABSTIME_V20:
866 fp20 = (nspr_pktracefull_v20_t *) &nstrace_buf[nstrace_buf_offset];
867 nstrace_buf_offset += nspr_getv20recordsize((nspr_hd_v20_t *)fp20);
868 ns_setabstime(wth, ((nspr_abstime_v20_t *) fp20)->abs_Time, ((nspr_abstime_v20_t *) fp20)->abs_RelTime);
872 case NSPR_RELTIME_V20:
874 fp20 = (nspr_pktracefull_v20_t *) &nstrace_buf[nstrace_buf_offset];
875 ns_setrelativetime(wth, ((nspr_abstime_v20_t *) fp20)->abs_RelTime);
876 nstrace_buf_offset += nspr_getv20recordsize((nspr_hd_v20_t *)fp20);
880 case NSPR_UNUSEDSPACE_V20:
882 if (nstrace_buf_offset >= NSPR_PAGESIZE/2)
883 nstrace_buf_offset = nstrace_buflen;
885 nstrace_buf_offset = NSPR_PAGESIZE/2;
891 fp20 = (nspr_pktracefull_v20_t *) &nstrace_buf[nstrace_buf_offset];
892 nstrace_buf_offset += nspr_getv20recordsize((nspr_hd_v20_t *)fp20);
898 nstrace_buf_offset = 0;
899 wth->data_offset += nstrace_buflen;
900 nstrace_buflen = GET_READ_PAGE_SIZE((wth->capture.nstrace->file_size - wth->data_offset));
901 }while((nstrace_buflen > 0) && (nstrace_buflen == (file_read(nstrace_buf, 1, nstrace_buflen, wth->fh))));
913 gboolean nstrace_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
916 if (wth->file_type == WTAP_FILE_NETSCALER_1_0)
917 return nstrace_read_v10(wth, err, err_info, data_offset);
918 else if (wth->file_type == WTAP_FILE_NETSCALER_2_0)
919 return nstrace_read_v20(wth, err, err_info, data_offset);
925 #define __TNO(enumprefix,structprefix,structname,hdrname,structfieldname) \
926 pseudo_header->nstr.hdrname##_offset = (guint8) enumprefix##_##hdrname##_offset;
927 #define __TNL(enumprefix,structprefix,structname,hdrname,structfieldname) \
928 pseudo_header->nstr.hdrname##_len = (guint8) enumprefix##_##hdrname##_len;;
930 #define __TNV1O(enumprefix,structprefix,structname,hdrname,structfieldname) \
931 __TNO(enumprefix,structprefix,structname,hdrname,structfieldname)
932 #define __TNV1L(enumprefix,structprefix,structname,hdrname,structfieldname) \
933 __TNL(enumprefix,structprefix,structname,hdrname,structfieldname)
936 gboolean nstrace_seek_read(wtap *wth, gint64 seek_off,
937 union wtap_pseudo_header *pseudo_header, guchar *pd, int length,
938 int *err, gchar **err_info _U_)
942 if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
946 ** Read the packet data.
948 if ((file_read(pd, 1, length, wth->random_fh)) != length)
951 if (wth->file_type == WTAP_FILE_NETSCALER_1_0)
954 #define GENERATE_CASE_FULL(type,acttype) \
955 case NSPR_PDPKTRACEFULLTX_V##type:\
956 case NSPR_PDPKTRACEFULLTXB_V##type:\
957 case NSPR_PDPKTRACEFULLRX_V##type:\
958 TRACE_V##type##_REC_LEN_OFF(v##type##_full,fp,pktracefull_v##type);\
959 pseudo_header->nstr.rec_type = NSPR_HEADER_VERSION##acttype;\
962 #define GENERATE_CASE_PART(type,acttype) \
963 case NSPR_PDPKTRACEPARTTX_V##type:\
964 case NSPR_PDPKTRACEPARTTXB_V##type:\
965 case NSPR_PDPKTRACEPARTRX_V##type:\
966 TRACE_V##type##_REC_LEN_OFF(v##type##_part,pp,pktracepart_v##type);\
967 pseudo_header->nstr.rec_type = NSPR_HEADER_VERSION##acttype;\
970 switch ((( nspr_header_v10_t*)pd)->ph_RecordType)
972 GENERATE_CASE_FULL(10,100)
973 GENERATE_CASE_PART(10,100)
975 } else if (wth->file_type == WTAP_FILE_NETSCALER_2_0)
977 switch ((( nspr_hd_v20_t*)pd)->phd_RecordType)
979 GENERATE_CASE_FULL(20,200)
980 GENERATE_CASE_PART(20,200)
981 GENERATE_CASE_FULL(21,201)
982 GENERATE_CASE_PART(21,201)
983 GENERATE_CASE_FULL(22,202)
984 GENERATE_CASE_PART(22,202)
985 GENERATE_CASE_FULL(23,203)
986 GENERATE_CASE_PART(23,203)
1000 ** Netscaler trace format close routines.
1002 void nstrace_close(wtap *wth)
1005 g_free(wth->capture.nstrace->pnstrace_buf);
1006 g_free(wth->capture.nstrace);
1011 /* Returns 0 if we could write the specified encapsulation type,
1012 ** an error indication otherwise. */
1013 int nstrace_10_dump_can_write_encap(int encap)
1015 if (encap == WTAP_ENCAP_NSTRACE_1_0)
1018 return WTAP_ERR_UNSUPPORTED_ENCAP;
1022 /* Returns 0 if we could write the specified encapsulation type,
1023 ** an error indication otherwise. */
1024 int nstrace_20_dump_can_write_encap(int encap)
1026 if (encap == WTAP_ENCAP_NSTRACE_2_0)
1029 return WTAP_ERR_UNSUPPORTED_ENCAP;
1033 /* Returns TRUE on success, FALSE on failure; sets "*err" to an error code on
1035 gboolean nstrace_dump_open(wtap_dumper *wdh, gboolean cant_seek, int *err)
1039 *err = WTAP_ERR_CANT_WRITE_TO_PIPE;
1043 wdh->subtype_write = nstrace_dump;
1045 wdh->dump.nstr = g_malloc(sizeof(nstrace_dump_t));
1046 wdh->dump.nstr->page_offset = 0;
1047 wdh->dump.nstr->page_len = NSPR_PAGESIZE;
1048 wdh->dump.nstr->absrec_time = 0;
1054 gboolean nstrace_add_signature(wtap_dumper *wdh)
1058 if (wdh->file_type == WTAP_FILE_NETSCALER_1_0)
1060 nspr_signature_v10_t sig10;
1062 /* populate the record */
1063 sig10.phd.ph_RecordType = NSPR_SIGNATURE_V10;
1064 sig10.phd.ph_RecordSize = nspr_signature_v10_s;
1065 memcpy(sig10.sig_Signature, NSPR_SIGSTR_V10, NSPR_SIGSIZE_V10);
1067 /* Write the record into the file */
1068 nwritten = fwrite(&sig10, 1, nspr_signature_v10_s, wdh->fh);
1069 if (nwritten != nspr_signature_v10_s)
1072 /* Move forward the page offset */
1073 wdh->dump.nstr->page_offset += (guint16) nwritten;
1075 } else if (wdh->file_type == WTAP_FILE_NETSCALER_2_0)
1077 gchar sig[nspr_signature_v20_s + sizeof(NSPR_SIGSTR_V20)];
1078 nspr_signature_v20_t *sig20;
1080 sig20 = (nspr_signature_v20_t *)&sig;
1081 sig20->sig_RecordType = NSPR_SIGNATURE_V20;
1082 sig20->sig_RecordSize = nspr_signature_v20_s + sizeof(NSPR_SIGSTR_V20);
1083 memcpy(sig20->sig_Signature, NSPR_SIGSTR_V20, sizeof(NSPR_SIGSTR_V20));
1085 /* Write the record into the file */
1086 nwritten = fwrite(sig20, 1, sig20->sig_RecordSize, wdh->fh);
1087 if (nwritten != sig20->sig_RecordSize)
1090 /* Move forward the page offset */
1091 wdh->dump.nstr->page_offset += (guint16) nwritten;
1095 g_assert_not_reached();
1103 gboolean nstrace_add_abstime(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
1107 guint64 nsg_creltime;
1109 if (wdh->file_type == WTAP_FILE_NETSCALER_1_0)
1111 nspr_abstime_v10_t abs10;
1112 nspr_pktracefull_v10_t fp10;
1114 /* populate the record */
1115 abs10.phd.ph_RecordType = NSPR_ABSTIME_V10;
1116 abs10.phd.ph_RecordSize = nspr_abstime_v10_s;
1118 memcpy(&fp10, pd, nspr_pktracefull_v10_s);
1119 nsg_creltime = ns_hrtime2nsec(fp10.fp_RelTimeHr);
1121 abs10.abs_RelTime = 0;
1122 abs10.abs_Time = (guint32)phdr->ts.secs - (guint32)(nsg_creltime/1000000000);
1124 /* Write the record into the file */
1125 nwritten = fwrite(&abs10, 1, nspr_abstime_v10_s, wdh->fh);
1126 if (nwritten != nspr_abstime_v10_s)
1129 /* Move forward the page offset */
1130 wdh->dump.nstr->page_offset += nspr_abstime_v10_s;
1132 } else if (wdh->file_type == WTAP_FILE_NETSCALER_2_0)
1134 nspr_abstime_v20_t abs20;
1135 nspr_pktracefull_v20_t fp20;
1137 abs20.abs_RecordType = NSPR_ABSTIME_V20;
1138 abs20.abs_RecordSize = nspr_abstime_v20_s;
1140 memcpy(&fp20, pd, nspr_pktracefull_v20_s);
1141 nsg_creltime = ns_hrtime2nsec(fp20.fp_RelTimeHr);
1143 abs20.abs_RelTime = 0;
1144 abs20.abs_Time = (guint32)phdr->ts.secs - (guint32)(nsg_creltime/1000000000);
1146 /* Write the record into the file */
1147 nwritten = fwrite(&abs20, 1, nspr_abstime_v20_s, wdh->fh);
1148 if (nwritten != nspr_abstime_v20_s)
1151 /* Move forward the page offset */
1152 wdh->dump.nstr->page_offset += nspr_abstime_v20_s;
1156 g_assert_not_reached();
1164 /* Write a record for a packet to a dump file.
1165 Returns TRUE on success, FALSE on failure. */
1166 static gboolean nstrace_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
1167 const union wtap_pseudo_header *pseudo_header, const guchar *pd, int *err)
1171 if (wdh->dump.nstr->page_offset == 0)
1173 /* Add the signature record and abs time record */
1174 if (wdh->file_type == WTAP_FILE_NETSCALER_1_0)
1176 if ((nstrace_add_signature(wdh) == FALSE) || (nstrace_add_abstime(wdh, phdr, pd) == FALSE))
1178 } else if (wdh->file_type == WTAP_FILE_NETSCALER_2_0)
1180 if ((nstrace_add_signature(wdh) == FALSE) || (nstrace_add_abstime(wdh, phdr, pd) == FALSE))
1184 g_assert_not_reached();
1189 switch (pseudo_header->nstr.rec_type)
1191 case NSPR_HEADER_VERSION100:
1193 if (wdh->file_type == WTAP_FILE_NETSCALER_1_0)
1195 if (wdh->dump.nstr->page_offset + phdr->caplen >= wdh->dump.nstr->page_len)
1197 /* Start on the next page */
1198 if (fseek(wdh->fh, (wdh->dump.nstr->page_len - wdh->dump.nstr->page_offset), SEEK_CUR) == -1)
1204 wdh->dump.nstr->page_offset = 0;
1206 /* Possibly add signature and abstime records and increment offset */
1207 if (nstrace_add_signature(wdh) == FALSE)
1211 /* Write the actual record as is */
1212 nwritten = fwrite(pd, 1, phdr->caplen, wdh->fh);
1213 if (nwritten != phdr->caplen)
1215 if (nwritten == 0 && ferror(wdh->fh))
1218 *err = WTAP_ERR_SHORT_WRITE;
1223 wdh->dump.nstr->page_offset += (guint16) nwritten;
1224 } else if (wdh->file_type == WTAP_FILE_NETSCALER_2_0)
1226 *err = WTAP_ERR_UNSUPPORTED_FILE_TYPE;
1232 case NSPR_HEADER_VERSION200:
1233 case NSPR_HEADER_VERSION201:
1234 case NSPR_HEADER_VERSION202:
1235 case NSPR_HEADER_VERSION203:
1237 if (wdh->file_type == WTAP_FILE_NETSCALER_1_0)
1239 *err = WTAP_ERR_UNSUPPORTED_FILE_TYPE;
1241 } else if (wdh->file_type == WTAP_FILE_NETSCALER_2_0)
1243 if (wdh->dump.nstr->page_offset + phdr->caplen >= wdh->dump.nstr->page_len)
1245 /* Start on the next page */
1246 if (fseek(wdh->fh, (wdh->dump.nstr->page_len - wdh->dump.nstr->page_offset), SEEK_CUR) == -1)
1252 wdh->dump.nstr->page_offset = 0;
1254 /* Possibly add signature and abstime records and increment offset */
1255 if (nstrace_add_signature(wdh) == FALSE)
1259 /* Write the actual record as is */
1260 nwritten = fwrite(pd, 1, phdr->caplen, wdh->fh);
1262 if (nwritten != phdr->caplen)
1264 if (nwritten == 0 && ferror(wdh->fh))
1267 *err = WTAP_ERR_SHORT_WRITE;
1272 wdh->dump.nstr->page_offset += (guint16) nwritten;
1278 g_assert_not_reached();