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 /* Performance Data Header with device number */
124 typedef struct nspr_headerdev_v10
126 guint16 ph_RecordType; /* Record Type */
127 guint16 ph_RecordSize; /* Record Size including header */
128 guint32 ph_DevNo; /* Network Device (NIC/CONN) number */
129 } nspr_headerdev_v10_t;
130 #define nspr_headerdev_v10_s sizeof(nspr_headerdev_v10_t)
132 typedef struct nspr_hd_v10
134 nspr_header_v10_t phd; /* performance header */
136 #define nspr_hd_v10_s sizeof(nspr_hd_v10_t)
138 typedef struct nspr_hdev_v10
140 nspr_headerdev_v10_t phd; /* performance header */
142 #define nspr_hdev_v10_s sizeof(nspr_hdev_v10_t)
144 /* if structure has defined phd as first field, it can use following names */
145 #define nsprRecordType phd.ph_RecordType
146 #define nsprRecordSize phd.ph_RecordSize
147 #define nsprReserved phd.ph_Reserved
148 #define nsprRecordTypeOrg phd.ph_Reserved
149 #define nsprDevNo phd.ph_DevNo
151 /* NSPR_SIGNATURE_V10 structure */
152 #define NSPR_SIGSIZE_V10 56 /* signature value size in bytes */
155 typedef struct nspr_signature_v10
157 nspr_header_v10_t phd; /* performance header */
158 guint8 sig_EndianType; /* Endian Type for the data */
159 guint8 sig_Reserved0;
160 guint16 sig_Reserved1;
161 gchar sig_Signature[NSPR_SIGSIZE_V10]; /* Signature value */
162 } nspr_signature_v10_t;
163 #define nspr_signature_v10_s sizeof(nspr_signature_v10_t)
165 /* NSPR_SIGNATURE_V20 structure */
166 typedef struct nspr_signature_v20
168 NSPR_HEADER_V20(sig); /* short performance header */
169 guint8 sig_EndianType; /* Endian Type for the data */
170 gchar sig_Signature[1]; /* Signature value */
171 } nspr_signature_v20_t;
172 #define nspr_signature_v20_s (sizeof(nspr_signature_v20_t) -1)
174 /* NSPR_ABSTIME_V10 and NSPR_SYSTARTIME_V10 structure */
175 typedef struct nspr_abstime_v10
177 nspr_header_v10_t phd; /* performance header */
178 guint32 abs_RelTime; /* relative time is ms from last time */
179 guint32 abs_Time; /* absolute time in seconds from 1970 */
180 } nspr_abstime_v10_t;
181 #define nspr_abstime_v10_s sizeof(nspr_abstime_v10_t)
184 /* NSPR_ABSTIME_V20 and NSPR_SYSTARTIME_V20 structure */
185 typedef struct nspr_abstime_v20
187 NSPR_HEADER_V20(abs); /* short performance header */
188 guint16 abs_RelTime; /* relative time is ms from last time */
189 guint32 abs_Time; /* absolute time in seconds from 1970 */
190 } nspr_abstime_v20_t;
191 #define nspr_abstime_v20_s sizeof(nspr_abstime_v20_t)
195 /* full packet trace structure */
196 typedef struct nspr_pktracefull_v10
198 nspr_headerdev_v10_t phd; /* performance header */
199 guint32 fp_RelTimeHr; /* High resolution relative time */
200 guint8 fp_Data[1]; /* packet data starts here */
201 } nspr_pktracefull_v10_t;
202 #define nspr_pktracefull_v10_s (nspr_hdev_v10_s + 4)
204 /* new full packet trace structure v20 */
205 typedef struct nspr_pktracefull_v20
207 NSPR_HEADER3B_V20(fp); /* long performance header */
208 guint8 fp_DevNo; /* Network Device (NIC) number */
209 guint32 fp_RelTimeHr; /* High resolution relative time */
210 guint8 fp_Data[4]; /* packet data starts here */
211 } nspr_pktracefull_v20_t;
212 #define nspr_pktracefull_v20_s (sizeof(nspr_pktracefull_v20_t) - 4)
214 /* new full packet trace structure v21 */
215 typedef struct nspr_pktracefull_v21
217 NSPR_HEADER3B_V21(fp); /* long performance header */
218 guint8 fp_DevNo; /* Network Device (NIC) number */
219 guint32 fp_RelTimeHr; /* High resolution relative time */
220 guint32 fp_PcbDevNo; /* PCB devno */
221 guint32 fp_lPcbDevNo; /* link PCB devno */
222 guint8 fp_Data[4]; /* packet data starts here */
223 } nspr_pktracefull_v21_t;
224 #define nspr_pktracefull_v21_s (sizeof(nspr_pktracefull_v21_t) - 4)
226 /* new full packet trace structure v22 */
227 typedef struct nspr_pktracefull_v22
229 NSPR_HEADER3B_V22(fp); /* long performance header */
230 guint8 fp_DevNo; /* Network Device (NIC) number */
231 guint32 fp_RelTimeHr; /* High resolution relative time */
232 guint32 fp_PcbDevNo; /* PCB devno */
233 guint32 fp_lPcbDevNo; /* link PCB devno */
235 guint8 fp_Data[4]; /* packet data starts here */
236 } nspr_pktracefull_v22_t;
237 #define nspr_pktracefull_v22_s (sizeof(nspr_pktracefull_v22_t) - 4)
239 typedef struct nspr_pktracefull_v23
241 NSPR_HEADER3B_V22(fp); /* long performance header */
242 guint8 fp_DevNo; /* Network Device (NIC) number */
243 guint32 fp_AbsTimeLowHdr; /* High resolution low time */
244 guint32 fp_AbsTimeHighHdr; /* Higher value of the absolute time */
245 guint32 fp_PcbDevNo; /* PCB devno */
246 guint32 fp_lPcbDevNo; /* link PCB devno */
247 guint16 fp_VlanTag; /* vlan tag */
248 guint16 fp_Coreid; /* coreid of the packet */
249 guint8 fp_Data[4]; /* packet data starts here */
250 } nspr_pktracefull_v23_t;
251 #define nspr_pktracefull_v23_s (sizeof(nspr_pktracefull_v23_t) - 4)
253 /* partial packet trace structure */
254 typedef struct nspr_pktracepart_v10
256 nspr_headerdev_v10_t phd; /* performance header */
257 guint32 pp_RelTimeHr; /* High resolution relative time */
258 guint16 pp_PktSizeOrg; /* Original packet size */
259 guint16 pp_PktOffset; /* starting offset in packet */
260 guint8 pp_Data[1]; /* packet data starts here */
261 } nspr_pktracepart_v10_t;
262 #define nspr_pktracepart_v10_s (nspr_pktracefull_v10_s + 4)
264 /* new partial packet trace structure */
265 typedef struct nspr_pktracepart_v20
267 NSPR_HEADER3B_V20(pp); /* long performance header */
268 guint8 pp_DevNo; /* Network Device (NIC) number */
269 guint32 pp_RelTimeHr; /* High resolution relative time */
270 guint16 pp_PktSizeOrg; /* Original packet size */
271 guint16 pp_PktOffset; /* starting offset in packet */
272 guint8 pp_Data[4]; /* packet data starts here */
273 } nspr_pktracepart_v20_t;
274 #define nspr_pktracepart_v20_s (sizeof(nspr_pktracepart_v20_t) -4)
276 /* new partial packet trace structure */
277 typedef struct nspr_pktracepart_v21
279 NSPR_HEADER3B_V21(pp); /* long performance header */
280 guint8 pp_DevNo; /* Network Device (NIC) number */
281 guint32 pp_RelTimeHr; /* High resolution relative time */
282 guint16 pp_PktSizeOrg; /* Original packet size */
283 guint16 pp_PktOffset; /* starting offset in packet */
284 guint32 pp_PcbDevNo; /* PCB devno */
285 guint32 pp_lPcbDevNo; /* link PCB devno */
286 guint8 pp_Data[4]; /* packet data starts here */
287 } nspr_pktracepart_v21_t;
288 #define nspr_pktracepart_v21_s (sizeof(nspr_pktracepart_v21_t) -4)
290 /* new partial packet trace structure v22 */
291 typedef struct nspr_pktracepart_v22
293 NSPR_HEADER3B_V22(pp); /* long performance header */
294 guint8 pp_DevNo; /* Network Device (NIC) number */
295 guint32 pp_RelTimeHr; /* High resolution relative time */
296 guint16 pp_PktSizeOrg; /* Original packet size */
297 guint16 pp_PktOffset; /* starting offset in packet */
298 guint32 pp_PcbDevNo; /* PCB devno */
299 guint32 pp_lPcbDevNo; /* link PCB devno */
300 guint16 pp_VlanTag; /* Vlan Tag */
301 guint8 pp_Data[4]; /* packet data starts here */
302 } nspr_pktracepart_v22_t;
303 #define nspr_pktracepart_v22_s (sizeof(nspr_pktracepart_v22_t) -4)
305 typedef struct nspr_pktracepart_v23
307 NSPR_HEADER3B_V22(pp); /* long performance header */
308 guint8 pp_DevNo; /* Network Device (NIC) number */
309 guint32 pp_AbsTimeLowHdr; /* High resolution low time */
310 guint32 pp_AbsTimeHighHdr; /* Higher value of the absolute time */
311 guint16 pp_PktSizeOrg; /* Original packet size */
312 guint16 pp_PktOffset; /* starting offset in packet */
313 guint32 pp_PcbDevNo; /* PCB devno */
314 guint32 pp_lPcbDevNo; /* link PCB devno */
315 guint16 pp_VlanTag; /* vlan tag */
316 guint16 pp_Coreid; /* Coreid of the packet */
317 guint8 pp_Data[4]; /* packet data starts here */
318 } nspr_pktracepart_v23_t;
319 #define nspr_pktracepart_v23_s (sizeof(nspr_pktracepart_v23_t) -4)
321 #define myoffsetof(type,fieldname) (&(((type*)0)->fieldname))
323 #define __TNO(enumprefix,structprefix,structname,hdrname,structfieldname) \
324 guint8 enumprefix##_##hdrname##_offset = (guint8)GPOINTER_TO_INT(myoffsetof(nspr_##structname##_t,structprefix##_##structfieldname));
326 #define __TNL(enumprefix,structprefix,structname,hdrname,structfieldname) \
327 guint8 enumprefix##_##hdrname##_len = (guint8)sizeof(((nspr_##structname##_t*)0)->structprefix##_##structfieldname);
329 #define __TNV1O(enumprefix,structprefix,structname,hdrname,structfieldname) \
330 guint8 enumprefix##_##hdrname##_offset = (guint8)GPOINTER_TO_INT(myoffsetof(nspr_##structname##_t,structfieldname));
332 #define __TNV1L(enumprefix,structprefix,structname,hdrname,structfieldname) \
333 guint8 enumprefix##_##hdrname##_len = (guint8)sizeof(((nspr_##structname##_t*)0)->structfieldname);
335 #define TRACE_V10_REC_LEN_OFF(enumprefix,structprefix,structname) \
336 __TNV1O(enumprefix,structprefix,structname,dir,phd.ph_RecordType)\
337 __TNV1L(enumprefix,structprefix,structname,dir,phd.ph_RecordType)\
338 __TNV1O(enumprefix,structprefix,structname,nicno,phd.ph_DevNo)\
339 __TNV1L(enumprefix,structprefix,structname,nicno,phd.ph_DevNo)\
340 __TNO(enumprefix,structprefix,structname,eth,Data)
342 #define TRACE_V20_REC_LEN_OFF(enumprefix,structprefix,structname) \
343 __TNO(enumprefix,structprefix,structname,dir,RecordType)\
344 __TNL(enumprefix,structprefix,structname,dir,RecordType)\
345 __TNO(enumprefix,structprefix,structname,nicno,DevNo)\
346 __TNL(enumprefix,structprefix,structname,nicno,DevNo)\
347 __TNO(enumprefix,structprefix,structname,eth,Data)
349 #define TRACE_V21_REC_LEN_OFF(enumprefix,structprefix,structname) \
350 TRACE_V20_REC_LEN_OFF(enumprefix,structprefix,structname)\
351 __TNO(enumprefix,structprefix,structname,pcb,PcbDevNo)\
352 __TNO(enumprefix,structprefix,structname,l_pcb,lPcbDevNo)
354 #define TRACE_V22_REC_LEN_OFF(enumprefix,structprefix,structname) \
355 TRACE_V21_REC_LEN_OFF(enumprefix,structprefix,structname)\
356 __TNO(enumprefix,structprefix,structname,vlantag,VlanTag)
358 #define TRACE_V23_REC_LEN_OFF(enumprefix,structprefix,structname) \
359 TRACE_V22_REC_LEN_OFF(enumprefix,structprefix,structname)\
360 __TNO(enumprefix,structprefix,structname,coreid,Coreid)
363 TRACE_V10_REC_LEN_OFF(v10_part,pp,pktracepart_v10)
364 TRACE_V10_REC_LEN_OFF(v10_full,fp,pktracefull_v10)
365 TRACE_V20_REC_LEN_OFF(v20_part,pp,pktracepart_v20)
366 TRACE_V20_REC_LEN_OFF(v20_full,fp,pktracefull_v20)
367 TRACE_V21_REC_LEN_OFF(v21_part,pp,pktracepart_v21)
368 TRACE_V21_REC_LEN_OFF(v21_full,fp,pktracefull_v21)
369 TRACE_V22_REC_LEN_OFF(v22_part,pp,pktracepart_v22)
370 TRACE_V22_REC_LEN_OFF(v22_full,fp,pktracefull_v22)
371 TRACE_V23_REC_LEN_OFF(v23_part,pp,pktracepart_v23)
372 TRACE_V23_REC_LEN_OFF(v23_full,fp,pktracefull_v23)
380 #define ns_setabstime(nstrace, AbsoluteTime, RelativeTimems) \
382 (nstrace)->nspm_curtime = AbsoluteTime; \
383 (nstrace)->nspm_curtimemsec += RelativeTimems; \
384 (nstrace)->nspm_curtimelastmsec = nstrace->nspm_curtimemsec; \
388 #define ns_setrelativetime(nstrace, RelativeTimems) \
391 (nstrace)->nspm_curtimemsec += RelativeTimems; \
392 rsec = (guint32)((nstrace)->nspm_curtimemsec - (nstrace)->nspm_curtimelastmsec)/1000; \
393 (nstrace)->nspm_curtime += rsec; \
394 (nstrace)->nspm_curtimelastmsec += rsec * 1000; \
400 gint32 nstrace_buf_offset;
401 gint32 nstrace_buflen;
402 /* Performance Monitor Time variables */
403 guint32 nspm_curtime; /* current time since 1970 */
404 guint64 nspm_curtimemsec; /* current time in mili second */
405 guint64 nspm_curtimelastmsec; /* nspm_curtime last update time in milisec */
406 guint64 nsg_creltime;
410 guint32 nspm_signature_isv10(gchar *sigp);
411 guint32 nspm_signature_isv20(gchar *sigp);
412 guint32 nspm_signature_version(wtap*, gchar*, gint32);
413 gboolean nstrace_read(wtap *wth, int *err, gchar **err_info,
414 gint64 *data_offset);
415 gboolean nstrace_read_v10(wtap *wth, int *err, gchar **err_info,
416 gint64 *data_offset);
417 gboolean nstrace_read_v20(wtap *wth, int *err, gchar **err_info,
418 gint64 *data_offset);
419 gboolean nstrace_seek_read(wtap *wth, gint64 seek_off,
420 union wtap_pseudo_header *pseudo_header,
421 guchar *pd, int length,
422 int *err, gchar **err_info _U_);
423 void nstrace_close(wtap *wth);
424 void nstrace_sequential_close(wtap *wth);
426 gboolean nstrace_set_start_time_v10(wtap *wth);
427 gboolean nstrace_set_start_time_v20(wtap *wth);
428 gboolean nstrace_set_start_time(wtap *wth);
429 guint64 ns_hrtime2nsec(guint32 tm);
431 static gboolean nstrace_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
432 const union wtap_pseudo_header *pseudo_header, const guchar *pd, int *err);
433 gboolean nstrace_add_signature(wtap_dumper *wdh);
434 gboolean nstrace_add_abstime(wtap_dumper *wdh, const struct wtap_pkthdr *phdr, const guchar *pd);
437 #define GET_READ_PAGE_SIZE(remaining_file_size) ((gint32)((remaining_file_size>NSPR_PAGESIZE)?NSPR_PAGESIZE:remaining_file_size))
440 guint64 ns_hrtime2nsec(guint32 tm)
442 guint32 val = tm & NSPR_HRTIME_MASKTM;
443 switch(tm & NSPR_HRTIME_MASKFMT)
445 case NSPR_HRTIME_SEC: return (guint64)val*1000000000;
446 case NSPR_HRTIME_MSEC: return (guint64)val*1000000;
447 case NSPR_HRTIME_USEC: return (guint32)val*1000;
448 case NSPR_HRTIME_NSEC: return val;
455 ** Netscaler trace format open routines
457 int nstrace_open(wtap *wth, int *err, gchar **err_info)
465 errno = WTAP_ERR_CANT_READ;
467 if ((file_size = wtap_file_size(wth, err)) == -1)
470 nstrace_buf = g_malloc(NSPR_PAGESIZE);
471 page_size = GET_READ_PAGE_SIZE(file_size);
473 switch ((wth->file_type = nspm_signature_version(wth, nstrace_buf, page_size)))
475 case WTAP_FILE_NETSCALER_1_0:
476 wth->file_encap = WTAP_ENCAP_NSTRACE_1_0;
479 case WTAP_FILE_NETSCALER_2_0:
480 wth->file_encap = WTAP_ENCAP_NSTRACE_2_0;
484 *err = WTAP_ERR_UNSUPPORTED;
485 *err_info = g_strdup_printf("nstrace: file type %d unsupported", wth->file_type);
490 if ((file_seek(wth->fh, 0, SEEK_SET, err)) == -1)
492 *err = file_error(wth->fh);
497 bytes_read = file_read(nstrace_buf, 1, page_size, wth->fh);
498 if (bytes_read != page_size)
500 *err = file_error(wth->fh);
505 wth->subtype_read = nstrace_read;
506 wth->subtype_seek_read = nstrace_seek_read;
507 wth->subtype_close = nstrace_close;
509 nstrace = (nstrace_t *)g_malloc(sizeof(nstrace_t));
510 wth->priv = (void *)nstrace;
511 nstrace->pnstrace_buf = nstrace_buf;
512 nstrace->nstrace_buflen = page_size;
513 nstrace->nstrace_buf_offset = 0;
514 nstrace->nspm_curtime = 0;
515 nstrace->nspm_curtimemsec = 0;
516 nstrace->nspm_curtimelastmsec = 0;
517 nstrace->nsg_creltime = 0;
518 nstrace->file_size = file_size;
521 /* Set the start time by looking for the abstime record */
522 if ((nstrace_set_start_time(wth)) == FALSE)
524 /* Reset the read pointer to start of the file. */
525 if ((file_seek(wth->fh, 0, SEEK_SET, err)) == -1)
527 *err = file_error(wth->fh);
528 g_free(nstrace->pnstrace_buf);
533 /* Read the first page of data */
534 bytes_read = file_read(nstrace_buf, 1, page_size, wth->fh);
535 if (bytes_read != page_size)
537 *err = file_error(wth->fh);
538 g_free(nstrace->pnstrace_buf);
543 /* reset the buffer offset */
544 nstrace->nstrace_buf_offset = 0;
547 wth->tsprecision = WTAP_FILE_TSPREC_NSEC;
548 wth->phdr.ts.secs = nstrace->nspm_curtime;
549 wth->phdr.ts.nsecs = 0;
556 #define nspm_signature_func(ver) \
557 guint32 nspm_signature_isv##ver(gchar *sigp) {\
558 return strncmp(sigp,NSPR_SIGSTR_V##ver,(sizeof(NSPR_SIGSTR_V##ver)-1));\
561 nspm_signature_func(10)
562 nspm_signature_func(20)
565 ** Check signature and return the version number of the signature.
566 ** If not found, it returns 0. At the time of return from this function
567 ** we might not be at the first page. So after a call to this function, there
568 ** has to be a file seek to return to the start of the first page.
571 nspm_signature_version(wtap *wth, gchar *nstrace_buf, gint32 len)
573 gchar *dp = nstrace_buf;
576 bytes_read = file_read(dp, 1, len, wth->fh);
577 if (bytes_read == len) {
579 for ( ; len > (gint32)(ns_min(sizeof(NSPR_SIGSTR_V10), sizeof(NSPR_SIGSTR_V20))); dp++, len--)
581 #define sigv10p ((nspr_signature_v10_t*)dp)
582 if ((pletohs(&sigv10p->nsprRecordType) == NSPR_SIGNATURE_V10) &&
583 (pletohs(&sigv10p->nsprRecordSize) <= len) &&
584 ((gint32)sizeof(NSPR_SIGSTR_V10) <= len) &&
585 (!nspm_signature_isv10(sigv10p->sig_Signature)))
586 return WTAP_FILE_NETSCALER_1_0;
589 #define sigv20p ((nspr_signature_v20_t*)dp)
590 if ((sigv20p->sig_RecordType == NSPR_SIGNATURE_V20) &&
591 (sigv20p->sig_RecordSize <= len) &&
592 ((gint32)sizeof(NSPR_SIGSTR_V20) <= len) &&
593 (!nspm_signature_isv20(sigv20p->sig_Signature)))
594 return WTAP_FILE_NETSCALER_2_0;
599 return 0; /* no version found */
602 #define nspr_getv10recordtype(hdp) (pletohs(&hdp->nsprRecordType))
603 #define nspr_getv10recordsize(hdp) (pletohs(&hdp->nsprRecordSize))
604 #define nspr_getv20recordtype(hdp) (hdp->phd_RecordType)
605 #define nspr_getv20recordsize(hdp) \
606 (((hdp)->phd_RecordSizeLow & NSPR_V20RECORDSIZE_2BYTES)? \
607 (((hdp)->phd_RecordSizeHigh * NSPR_V20RECORDSIZE_2BYTES)+ \
608 ((hdp)->phd_RecordSizeLow & ~NSPR_V20RECORDSIZE_2BYTES)) : \
609 (hdp)->phd_RecordSizeLow)
612 #define nstrace_set_start_time_ver(ver) \
613 gboolean nstrace_set_start_time_v##ver(wtap *wth) \
615 nstrace_t *nstrace = (nstrace_t *)wth->priv;\
616 gchar* nstrace_buf = nstrace->pnstrace_buf;\
617 gint32 nstrace_buf_offset = nstrace->nstrace_buf_offset;\
618 gint32 nstrace_buflen = nstrace->nstrace_buflen;\
622 while (nstrace_buf_offset < nstrace_buflen)\
624 nspr_hd_v##ver##_t *fp = (nspr_hd_v##ver##_t *) &nstrace_buf[nstrace_buf_offset];\
625 switch (nspr_getv##ver##recordtype(fp))\
627 case NSPR_ABSTIME_V##ver:\
628 ns_setabstime(nstrace, pletohl(&((nspr_abstime_v##ver##_t *) fp)->abs_Time), pletohs(&((nspr_abstime_v##ver##_t *) fp)->abs_RelTime));\
629 nstrace->nstrace_buf_offset = nstrace_buf_offset + nspr_getv##ver##recordsize(fp);\
630 nstrace->nstrace_buflen = nstrace_buflen;\
632 case NSPR_UNUSEDSPACE_V10:\
633 nstrace_buf_offset = nstrace_buflen;\
636 nstrace_buf_offset += nspr_getv##ver##recordsize(fp);\
639 nstrace_buf_offset = 0;\
640 wth->data_offset += nstrace_buflen;\
641 nstrace_buflen = GET_READ_PAGE_SIZE((nstrace->file_size - wth->data_offset));\
642 }while((nstrace_buflen > 0) && (bytes_read = file_read(nstrace_buf, 1, nstrace_buflen, wth->fh)) && bytes_read == nstrace_buflen); \
646 nstrace_set_start_time_ver(10)
647 nstrace_set_start_time_ver(20)
649 #undef nspr_getv10recordtype
650 #undef nspr_getv20recordtype
651 #undef nspr_getv10recordsize
654 ** Set the start time of the trace file. We look for the first ABSTIME record. We use that
655 ** to set the start time. Apart from that we also make sure that we remember the position of
656 ** the next record after the ABSTIME record. Inorder to report correct time values, all trace
657 ** records before the ABSTIME record are ignored.
659 gboolean nstrace_set_start_time(wtap *wth)
661 if (wth->file_type == WTAP_FILE_NETSCALER_1_0)
662 return nstrace_set_start_time_v10(wth);
663 else if (wth->file_type == WTAP_FILE_NETSCALER_2_0)
664 return nstrace_set_start_time_v20(wth);
669 #define __TNO(enumprefix,structprefix,structname,hdrname,structfieldname) \
670 wth->pseudo_header.nstr.hdrname##_offset = enumprefix##_##hdrname##_offset;
672 #define __TNL(enumprefix,structprefix,structname,hdrname,structfieldname) \
673 wth->pseudo_header.nstr.hdrname##_len = enumprefix##_##hdrname##_len;
675 #define __TNV1O(enumprefix,structprefix,structname,hdrname,structfieldname) \
676 __TNO(enumprefix,structprefix,structname,hdrname,structfieldname)
678 #define __TNV1L(enumprefix,structprefix,structname,hdrname,structfieldname) \
679 __TNL(enumprefix,structprefix,structname,hdrname,structfieldname)
684 ** Netscaler trace format read routines.
686 gboolean nstrace_read_v10(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
688 nstrace_t *nstrace = (nstrace_t *)wth->priv;
689 guint64 nsg_creltime = nstrace->nsg_creltime;
690 gchar *nstrace_buf = nstrace->pnstrace_buf;
691 gint32 nstrace_buf_offset = nstrace->nstrace_buf_offset;
692 gint32 nstrace_buflen = nstrace->nstrace_buflen;
693 nspr_pktracefull_v10_t *fp;
694 nspr_pktracepart_v10_t *pp;
701 while ((nstrace_buf_offset < nstrace_buflen) &&
702 ((nstrace_buflen - nstrace_buf_offset) >= ((gint32)sizeof(fp->nsprRecordType))))
705 fp = (nspr_pktracefull_v10_t *) &nstrace_buf[nstrace_buf_offset];
706 pp = (nspr_pktracepart_v10_t *) fp;
708 switch (pletohs(&fp->nsprRecordType))
710 case NSPR_PDPKTRACEFULLTX_V10:
711 case NSPR_PDPKTRACEFULLTXB_V10:
712 case NSPR_PDPKTRACEFULLRX_V10:
714 nsg_creltime += ns_hrtime2nsec(pletohl(&fp->fp_RelTimeHr));
715 wth->phdr.ts.secs = nstrace->nspm_curtime + (guint32) (nsg_creltime / 1000000000);
716 wth->phdr.ts.nsecs = (guint32) (nsg_creltime % 1000000000);
718 wth->phdr.len = pletohs(&fp->nsprRecordSize);
719 wth->phdr.caplen = wth->phdr.len;
722 TRACE_V10_REC_LEN_OFF(v10_full,fp,pktracefull_v10);
724 buffer_assure_space(wth->frame_buffer, wth->phdr.caplen);
725 memcpy(buffer_start_ptr(wth->frame_buffer), fp, wth->phdr.caplen);
726 *data_offset = wth->data_offset + nstrace_buf_offset;
728 nstrace->nstrace_buf_offset = nstrace_buf_offset + wth->phdr.len;
729 nstrace->nstrace_buflen = nstrace_buflen;
730 nstrace->nsg_creltime = nsg_creltime;
734 case NSPR_PDPKTRACEPARTTX_V10:
735 case NSPR_PDPKTRACEPARTTXB_V10:
736 case NSPR_PDPKTRACEPARTRX_V10:
738 nsg_creltime += ns_hrtime2nsec(pletohl(&pp->pp_RelTimeHr));
739 wth->phdr.ts.secs = nstrace->nspm_curtime + (guint32) (nsg_creltime / 1000000000);
740 wth->phdr.ts.nsecs = (guint32) (nsg_creltime % 1000000000);
742 wth->phdr.len = pletohs(&pp->pp_PktSizeOrg) + nspr_pktracepart_v10_s;
743 wth->phdr.caplen = pletohs(&pp->nsprRecordSize);
745 TRACE_V10_REC_LEN_OFF(v10_part,pp,pktracepart_v10);
747 buffer_assure_space(wth->frame_buffer, wth->phdr.caplen);
748 memcpy(buffer_start_ptr(wth->frame_buffer), pp, wth->phdr.caplen);
749 *data_offset = wth->data_offset + nstrace_buf_offset;
751 nstrace->nstrace_buf_offset = nstrace_buf_offset + wth->phdr.caplen;
752 nstrace->nsg_creltime = nsg_creltime;
753 nstrace->nstrace_buflen = nstrace_buflen;
757 case NSPR_ABSTIME_V10:
759 ns_setabstime(nstrace, pletohl(&((nspr_abstime_v10_t *) fp)->abs_Time), pletohl(&((nspr_abstime_v10_t *) fp)->abs_RelTime));
760 nstrace_buf_offset += pletohs(&fp->nsprRecordSize);
763 case NSPR_RELTIME_V10:
765 ns_setrelativetime(nstrace, ((nspr_abstime_v10_t *) fp)->abs_RelTime);
766 nstrace_buf_offset += pletohs(&fp->nsprRecordSize);
769 case NSPR_UNUSEDSPACE_V10:
771 nstrace_buf_offset = nstrace_buflen;
776 nstrace_buf_offset += pletohs(&fp->nsprRecordSize);
781 nstrace_buf_offset = 0;
782 wth->data_offset += nstrace_buflen;
783 nstrace_buflen = GET_READ_PAGE_SIZE((nstrace->file_size - wth->data_offset));
784 }while((nstrace_buflen > 0) && (bytes_read = file_read(nstrace_buf, 1, nstrace_buflen, wth->fh)) && (bytes_read == nstrace_buflen));
789 #define TIMEDEFV20(fp,type) \
791 nsg_creltime += ns_hrtime2nsec(pletohl(&fp->type##_RelTimeHr));\
792 wth->phdr.ts.secs = nstrace->nspm_curtime + (guint32) (nsg_creltime / 1000000000);\
793 wth->phdr.ts.nsecs = (guint32) (nsg_creltime % 1000000000);\
796 #define TIMEDEFV23(fp,type) \
798 /* access _AbsTimeHighHdr as a 64bit value */\
799 nsg_creltime = (((guint64)fp->type##_AbsTimeHighHdr<<32) | (fp->type##_AbsTimeLowHdr));\
800 wth->phdr.ts.secs = (guint32) (nsg_creltime / 1000000000);\
801 wth->phdr.ts.nsecs = (guint32) (nsg_creltime % 1000000000);\
804 #define TIMEDEFV21(fp,type) TIMEDEFV20(fp,type)
805 #define TIMEDEFV22(fp,type) TIMEDEFV20(fp,type)
807 #define PPSIZEDEFV20(pp,ver) \
809 wth->phdr.len = pletohs(&pp->pp_PktSizeOrg) + nspr_pktracepart_v##ver##_s;\
810 wth->phdr.caplen = nspr_getv20recordsize((nspr_hd_v20_t *)pp);\
813 #define PPSIZEDEFV21(pp,ver) PPSIZEDEFV20(pp,ver)
814 #define PPSIZEDEFV22(pp,ver) PPSIZEDEFV20(pp,ver)
815 #define PPSIZEDEFV23(pp,ver) PPSIZEDEFV20(pp,ver)
817 #define FPSIZEDEFV20(fp,ver)\
819 wth->phdr.len = nspr_getv20recordsize((nspr_hd_v20_t *)fp);\
820 wth->phdr.caplen = wth->phdr.len;\
823 #define FPSIZEDEFV21(pp,ver) FPSIZEDEFV20(fp,ver)
824 #define FPSIZEDEFV22(pp,ver) FPSIZEDEFV20(fp,ver)
825 #define FPSIZEDEFV23(pp,ver) FPSIZEDEFV20(fp,ver)
827 #define PACKET_DESCRIBE(FPTIMEDEF,SIZEDEF,ver,enumprefix,type,structname,TYPE)\
829 nspr_##structname##_t *fp= (nspr_##structname##_t*)&nstrace_buf[nstrace_buf_offset];\
830 TIMEDEFV##ver(fp,type);\
831 SIZEDEF##ver(fp,ver);\
832 TRACE_V##ver##_REC_LEN_OFF(enumprefix,type,structname);\
833 buffer_assure_space(wth->frame_buffer, wth->phdr.caplen);\
834 memcpy(buffer_start_ptr(wth->frame_buffer), fp, wth->phdr.caplen);\
835 *data_offset = wth->data_offset + nstrace_buf_offset;\
836 nstrace->nstrace_buf_offset = nstrace_buf_offset + nspr_getv20recordsize((nspr_hd_v20_t *)fp);\
837 nstrace->nstrace_buflen = nstrace_buflen;\
838 nstrace->nsg_creltime = nsg_creltime;\
839 wth->pseudo_header.nstr.rec_type = NSPR_HEADER_VERSION##TYPE;\
843 gboolean nstrace_read_v20(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
845 nstrace_t *nstrace = (nstrace_t *)wth->priv;
846 guint64 nsg_creltime = nstrace->nsg_creltime;
847 gchar *nstrace_buf = nstrace->pnstrace_buf;
848 gint32 nstrace_buf_offset = nstrace->nstrace_buf_offset;
849 gint32 nstrace_buflen = nstrace->nstrace_buflen;
850 nspr_pktracefull_v20_t *fp20;
851 nspr_pktracefull_v21_t *fp21;
858 while ((nstrace_buf_offset < nstrace_buflen) &&
859 ((nstrace_buflen - nstrace_buf_offset) >= ((gint32)sizeof(fp21->fp_RecordType))))
861 fp21 = (nspr_pktracefull_v21_t *) &nstrace_buf[nstrace_buf_offset];
863 switch (fp21->fp_RecordType)
866 #define GENERATE_CASE(type,acttype) \
867 case NSPR_PDPKTRACEFULLTX_V##type:\
868 case NSPR_PDPKTRACEFULLTXB_V##type:\
869 case NSPR_PDPKTRACEFULLRX_V##type:\
870 PACKET_DESCRIBE(TIMEDEF,FPSIZEDEFV,type,v##type##_full,fp,pktracefull_v##type,acttype);
871 GENERATE_CASE(23,203);
872 GENERATE_CASE(22,202);
873 GENERATE_CASE(21,201);
874 GENERATE_CASE(20,200);
877 #define GENERATE_CASE(type,acttype) \
878 case NSPR_PDPKTRACEPARTTX_V##type:\
879 case NSPR_PDPKTRACEPARTTXB_V##type:\
880 case NSPR_PDPKTRACEPARTRX_V##type:\
881 PACKET_DESCRIBE(TIMEDEF,PPSIZEDEFV,type,v##type##_part,pp,pktracepart_v##type,acttype);
882 GENERATE_CASE(23,203);
883 GENERATE_CASE(22,202);
884 GENERATE_CASE(21,201);
885 GENERATE_CASE(20,200);
888 case NSPR_ABSTIME_V20:
890 fp20 = (nspr_pktracefull_v20_t *) &nstrace_buf[nstrace_buf_offset];
891 nstrace_buf_offset += nspr_getv20recordsize((nspr_hd_v20_t *)fp20);
892 ns_setabstime(nstrace, pletohl(&((nspr_abstime_v20_t *) fp20)->abs_Time), pletohs(&((nspr_abstime_v20_t *) fp20)->abs_RelTime));
896 case NSPR_RELTIME_V20:
898 fp20 = (nspr_pktracefull_v20_t *) &nstrace_buf[nstrace_buf_offset];
899 ns_setrelativetime(nstrace, pletohs(&((nspr_abstime_v20_t *) fp20)->abs_RelTime));
900 nstrace_buf_offset += nspr_getv20recordsize((nspr_hd_v20_t *)fp20);
904 case NSPR_UNUSEDSPACE_V20:
906 if (nstrace_buf_offset >= NSPR_PAGESIZE/2)
907 nstrace_buf_offset = nstrace_buflen;
909 nstrace_buf_offset = NSPR_PAGESIZE/2;
915 fp20 = (nspr_pktracefull_v20_t *) &nstrace_buf[nstrace_buf_offset];
916 nstrace_buf_offset += nspr_getv20recordsize((nspr_hd_v20_t *)fp20);
922 nstrace_buf_offset = 0;
923 wth->data_offset += nstrace_buflen;
924 nstrace_buflen = GET_READ_PAGE_SIZE((nstrace->file_size - wth->data_offset));
925 }while((nstrace_buflen > 0) && (bytes_read = file_read(nstrace_buf, 1, nstrace_buflen, wth->fh)) && (bytes_read == nstrace_buflen));
937 gboolean nstrace_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
940 if (wth->file_type == WTAP_FILE_NETSCALER_1_0)
941 return nstrace_read_v10(wth, err, err_info, data_offset);
942 else if (wth->file_type == WTAP_FILE_NETSCALER_2_0)
943 return nstrace_read_v20(wth, err, err_info, data_offset);
949 #define __TNO(enumprefix,structprefix,structname,hdrname,structfieldname) \
950 pseudo_header->nstr.hdrname##_offset = (guint8) enumprefix##_##hdrname##_offset;
951 #define __TNL(enumprefix,structprefix,structname,hdrname,structfieldname) \
952 pseudo_header->nstr.hdrname##_len = (guint8) enumprefix##_##hdrname##_len;;
954 #define __TNV1O(enumprefix,structprefix,structname,hdrname,structfieldname) \
955 __TNO(enumprefix,structprefix,structname,hdrname,structfieldname)
956 #define __TNV1L(enumprefix,structprefix,structname,hdrname,structfieldname) \
957 __TNL(enumprefix,structprefix,structname,hdrname,structfieldname)
960 gboolean nstrace_seek_read(wtap *wth, gint64 seek_off,
961 union wtap_pseudo_header *pseudo_header, guchar *pd, int length,
962 int *err, gchar **err_info _U_)
968 if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
972 ** Read the packet data.
974 bytes_read = file_read(pd, 1, length, wth->random_fh);
975 if (bytes_read != length)
978 if (wth->file_type == WTAP_FILE_NETSCALER_1_0)
981 #define GENERATE_CASE_FULL(type,acttype) \
982 case NSPR_PDPKTRACEFULLTX_V##type:\
983 case NSPR_PDPKTRACEFULLTXB_V##type:\
984 case NSPR_PDPKTRACEFULLRX_V##type:\
985 TRACE_V##type##_REC_LEN_OFF(v##type##_full,fp,pktracefull_v##type);\
986 pseudo_header->nstr.rec_type = NSPR_HEADER_VERSION##acttype;\
989 #define GENERATE_CASE_PART(type,acttype) \
990 case NSPR_PDPKTRACEPARTTX_V##type:\
991 case NSPR_PDPKTRACEPARTTXB_V##type:\
992 case NSPR_PDPKTRACEPARTRX_V##type:\
993 TRACE_V##type##_REC_LEN_OFF(v##type##_part,pp,pktracepart_v##type);\
994 pseudo_header->nstr.rec_type = NSPR_HEADER_VERSION##acttype;\
997 switch (pletohs(&(( nspr_header_v10_t*)pd)->ph_RecordType))
999 GENERATE_CASE_FULL(10,100)
1000 GENERATE_CASE_PART(10,100)
1002 } else if (wth->file_type == WTAP_FILE_NETSCALER_2_0)
1004 switch ((( nspr_hd_v20_t*)pd)->phd_RecordType)
1006 GENERATE_CASE_FULL(20,200)
1007 GENERATE_CASE_PART(20,200)
1008 GENERATE_CASE_FULL(21,201)
1009 GENERATE_CASE_PART(21,201)
1010 GENERATE_CASE_FULL(22,202)
1011 GENERATE_CASE_PART(22,202)
1012 GENERATE_CASE_FULL(23,203)
1013 GENERATE_CASE_PART(23,203)
1027 ** Netscaler trace format close routines.
1029 void nstrace_close(wtap *wth)
1031 nstrace_t *nstrace = (nstrace_t *)wth->priv;
1033 g_free(nstrace->pnstrace_buf);
1038 guint16 page_offset;
1040 guint32 absrec_time;
1043 /* Returns 0 if we could write the specified encapsulation type,
1044 ** an error indication otherwise. */
1045 int nstrace_10_dump_can_write_encap(int encap)
1047 if (encap == WTAP_ENCAP_NSTRACE_1_0)
1050 return WTAP_ERR_UNSUPPORTED_ENCAP;
1054 /* Returns 0 if we could write the specified encapsulation type,
1055 ** an error indication otherwise. */
1056 int nstrace_20_dump_can_write_encap(int encap)
1058 if (encap == WTAP_ENCAP_NSTRACE_2_0)
1061 return WTAP_ERR_UNSUPPORTED_ENCAP;
1065 /* Returns TRUE on success, FALSE on failure; sets "*err" to an error code on
1067 gboolean nstrace_dump_open(wtap_dumper *wdh, gboolean cant_seek, int *err)
1069 nstrace_dump_t *nstrace;
1073 *err = WTAP_ERR_CANT_WRITE_TO_PIPE;
1077 wdh->subtype_write = nstrace_dump;
1079 nstrace = (nstrace_dump_t *)g_malloc(sizeof(nstrace_dump_t));
1080 wdh->priv = (void *)nstrace;
1081 nstrace->page_offset = 0;
1082 nstrace->page_len = NSPR_PAGESIZE;
1083 nstrace->absrec_time = 0;
1089 gboolean nstrace_add_signature(wtap_dumper *wdh)
1091 nstrace_dump_t *nstrace = (nstrace_dump_t *)wdh->priv;
1094 if (wdh->file_type == WTAP_FILE_NETSCALER_1_0)
1096 nspr_signature_v10_t sig10;
1098 /* populate the record */
1099 sig10.phd.ph_RecordType = htoles(NSPR_SIGNATURE_V10);
1100 sig10.phd.ph_RecordSize = htoles(nspr_signature_v10_s);
1101 memcpy(sig10.sig_Signature, NSPR_SIGSTR_V10, NSPR_SIGSIZE_V10);
1103 /* Write the record into the file */
1104 nwritten = fwrite(&sig10, 1, nspr_signature_v10_s, wdh->fh);
1105 if (nwritten != nspr_signature_v10_s)
1108 /* Move forward the page offset */
1109 nstrace->page_offset += (guint16) nwritten;
1111 } else if (wdh->file_type == WTAP_FILE_NETSCALER_2_0)
1113 gchar sig[nspr_signature_v20_s + sizeof(NSPR_SIGSTR_V20)];
1114 nspr_signature_v20_t *sig20;
1116 sig20 = (nspr_signature_v20_t *)&sig;
1117 sig20->sig_RecordType = NSPR_SIGNATURE_V20;
1118 sig20->sig_RecordSize = nspr_signature_v20_s + sizeof(NSPR_SIGSTR_V20);
1119 memcpy(sig20->sig_Signature, NSPR_SIGSTR_V20, sizeof(NSPR_SIGSTR_V20));
1121 /* Write the record into the file */
1122 nwritten = fwrite(sig20, 1, sig20->sig_RecordSize, wdh->fh);
1123 if (nwritten != sig20->sig_RecordSize)
1126 /* Move forward the page offset */
1127 nstrace->page_offset += (guint16) nwritten;
1131 g_assert_not_reached();
1139 gboolean nstrace_add_abstime(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
1142 nstrace_dump_t *nstrace = (nstrace_dump_t *)wdh->priv;
1144 guint64 nsg_creltime;
1146 if (wdh->file_type == WTAP_FILE_NETSCALER_1_0)
1148 nspr_abstime_v10_t abs10;
1149 nspr_pktracefull_v10_t fp10;
1151 /* populate the record */
1152 abs10.phd.ph_RecordType = htoles(NSPR_ABSTIME_V10);
1153 abs10.phd.ph_RecordSize = htoles(nspr_abstime_v10_s);
1155 memcpy(&fp10, pd, nspr_pktracefull_v10_s);
1156 nsg_creltime = ns_hrtime2nsec(fp10.fp_RelTimeHr);
1158 abs10.abs_RelTime = 0;
1159 abs10.abs_Time = htolel((guint32)phdr->ts.secs - (guint32)(nsg_creltime/1000000000));
1161 /* Write the record into the file */
1162 nwritten = fwrite(&abs10, 1, nspr_abstime_v10_s, wdh->fh);
1163 if (nwritten != nspr_abstime_v10_s)
1166 /* Move forward the page offset */
1167 nstrace->page_offset += nspr_abstime_v10_s;
1169 } else if (wdh->file_type == WTAP_FILE_NETSCALER_2_0)
1171 nspr_abstime_v20_t abs20;
1172 nspr_pktracefull_v20_t fp20;
1174 abs20.abs_RecordType = NSPR_ABSTIME_V20;
1175 abs20.abs_RecordSize = nspr_abstime_v20_s;
1177 memcpy(&fp20, pd, nspr_pktracefull_v20_s);
1178 nsg_creltime = ns_hrtime2nsec(fp20.fp_RelTimeHr);
1180 abs20.abs_RelTime = 0;
1181 abs20.abs_Time = htolel((guint32)phdr->ts.secs - (guint32)(nsg_creltime/1000000000));
1183 /* Write the record into the file */
1184 nwritten = fwrite(&abs20, 1, nspr_abstime_v20_s, wdh->fh);
1185 if (nwritten != nspr_abstime_v20_s)
1188 /* Move forward the page offset */
1189 nstrace->page_offset += nspr_abstime_v20_s;
1193 g_assert_not_reached();
1201 /* Write a record for a packet to a dump file.
1202 Returns TRUE on success, FALSE on failure. */
1203 static gboolean nstrace_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
1204 const union wtap_pseudo_header *pseudo_header, const guchar *pd, int *err)
1206 nstrace_dump_t *nstrace = (nstrace_dump_t *)wdh->priv;
1209 if (nstrace->page_offset == 0)
1211 /* Add the signature record and abs time record */
1212 if (wdh->file_type == WTAP_FILE_NETSCALER_1_0)
1214 if ((nstrace_add_signature(wdh) == FALSE) || (nstrace_add_abstime(wdh, phdr, pd) == FALSE))
1216 } else if (wdh->file_type == WTAP_FILE_NETSCALER_2_0)
1218 if ((nstrace_add_signature(wdh) == FALSE) || (nstrace_add_abstime(wdh, phdr, pd) == FALSE))
1222 g_assert_not_reached();
1227 switch (pseudo_header->nstr.rec_type)
1229 case NSPR_HEADER_VERSION100:
1231 if (wdh->file_type == WTAP_FILE_NETSCALER_1_0)
1233 if (nstrace->page_offset + phdr->caplen >= nstrace->page_len)
1235 /* Start on the next page */
1236 if (fseek(wdh->fh, (nstrace->page_len - nstrace->page_offset), SEEK_CUR) == -1)
1242 nstrace->page_offset = 0;
1244 /* Possibly add signature and abstime records and increment offset */
1245 if (nstrace_add_signature(wdh) == FALSE)
1249 /* Write the actual record as is */
1250 nwritten = fwrite(pd, 1, phdr->caplen, wdh->fh);
1251 if (nwritten != phdr->caplen)
1253 if (nwritten == 0 && ferror(wdh->fh))
1256 *err = WTAP_ERR_SHORT_WRITE;
1261 nstrace->page_offset += (guint16) nwritten;
1262 } else if (wdh->file_type == WTAP_FILE_NETSCALER_2_0)
1264 *err = WTAP_ERR_UNSUPPORTED_FILE_TYPE;
1270 case NSPR_HEADER_VERSION200:
1271 case NSPR_HEADER_VERSION201:
1272 case NSPR_HEADER_VERSION202:
1273 case NSPR_HEADER_VERSION203:
1275 if (wdh->file_type == WTAP_FILE_NETSCALER_1_0)
1277 *err = WTAP_ERR_UNSUPPORTED_FILE_TYPE;
1279 } else if (wdh->file_type == WTAP_FILE_NETSCALER_2_0)
1281 if (nstrace->page_offset + phdr->caplen >= nstrace->page_len)
1283 /* Start on the next page */
1284 if (fseek(wdh->fh, (nstrace->page_len - nstrace->page_offset), SEEK_CUR) == -1)
1290 nstrace->page_offset = 0;
1292 /* Possibly add signature and abstime records and increment offset */
1293 if (nstrace_add_signature(wdh) == FALSE)
1297 /* Write the actual record as is */
1298 nwritten = fwrite(pd, 1, phdr->caplen, wdh->fh);
1300 if (nwritten != phdr->caplen)
1302 if (nwritten == 0 && ferror(wdh->fh))
1305 *err = WTAP_ERR_SHORT_WRITE;
1310 nstrace->page_offset += (guint16) nwritten;
1316 g_assert_not_reached();