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: nsperfrc.h */
35 #define NSPR_SIGSTR_V10 "NetScaler Performance Data"
36 #define NSPR_SIGSTR_V20 "NetScaler V20 Performance Data"
37 #define NSPR_SIGSTR NSPR_SIGSTR_V20
38 /* Defined but not used */
39 #define NSPR_SIGSTR_V21 "NetScaler V21 Performance Data"
40 #define NSPR_SIGSTR_V22 "NetScaler V22 Performance Data"
42 #define NSPR_PAGESIZE 8192
44 /* The different record types
45 ** NOTE: The Record Type is two byte fields and unused space is recognized by
46 ** either bytes being zero, therefore no record should any byte value as
49 ** New Performance Record Type is only one byte.
51 #define NSPR_UNUSEDSPACE_V10 0x0000 /* rest of the page is unused */
52 #define NSPR_UNUSEDSPACE_V20 0x00 /* rest of the page is unused */
53 #define NSPR_SIGNATURE_V10 0x0101 /* signature */
54 #define NSPR_SIGNATURE_V20 0x01 /* signature */
55 #define NSPR_ABSTIME_V10 0x0107 /* data capture time in secs from 1970*/
56 #define NSPR_ABSTIME_V20 0x07 /* data capture time in secs from 1970*/
57 #define NSPR_RELTIME_V10 0x0108 /* relative time in ms from last time */
58 #define NSPR_RELTIME_V20 0x08 /* relative time in ms from last time */
59 #define NSPR_RELTIMEHR_V10 0x0109 /* high resolution relative time */
60 #define NSPR_RELTIMEHR_V20 0x09 /* high resolution relative time */
61 #define NSPR_SYSTARTIME_V10 0x010A /* system start time */
62 #define NSPR_SYSTARTIME_V20 0x0A /* system start time */
63 #define NSPR_RELTIME2B_V10 0x010B /* relative time in ms from last time */
64 #define NSPR_RELTIME2B_V20 0x0B /* relative time in ms from last time */
67 /* The high resolution relative time format.
68 ** The MS 2 bits of the high resoltion time is defined as follows:
69 ** 00 : time value is in second
70 ** 01 : time value is in mili second
71 ** 10 : time value is in micro second
72 ** 11 : time value is in nano second
74 #define NSPR_HRTIME_MASKTM 0x3FFFFFFF /* mask to get time value */
75 #define NSPR_HRTIME_MASKFMT 0xC0000000 /* time value format mask */
76 #define NSPR_HRTIME_SEC 0x00000000 /* time value in second */
77 #define NSPR_HRTIME_MSEC 0x40000000 /* time value in mili second */
78 #define NSPR_HRTIME_USEC 0x80000000 /* time value in micro second */
79 #define NSPR_HRTIME_NSEC 0xC0000000 /* time value in nano second */
82 typedef struct nspr_header_v10
84 guint8 ph_RecordType[2]; /* Record Type */
85 guint8 ph_RecordSize[2]; /* Record Size including header */
87 #define nspr_header_v10_s sizeof(nspr_header_v10_t)
89 /* This is V20 short header (2 bytes long) to be included where needed */
90 #define NSPR_HEADER_V20(prefix) \
91 guint8 prefix##_RecordType; /* Record Type */ \
92 guint8 prefix##_RecordSize /* Record Size including header */ \
93 /* end of declaration */
95 /* This is new long header (3 bytes long) to be included where needed */
96 #define NSPR_HEADER3B_V20(prefix) \
97 guint8 prefix##_RecordType; /* Record Type */ \
98 guint8 prefix##_RecordSizeLow; /* Record Size including header */ \
99 guint8 prefix##_RecordSizeHigh /* Record Size including header */ \
100 /* end of declaration */
101 #define NSPR_HEADER3B_V21 NSPR_HEADER3B_V20
102 #define NSPR_HEADER3B_V22 NSPR_HEADER3B_V20
104 typedef struct nspr_hd_v20
106 NSPR_HEADER3B_V20(phd); /* long performance header */
109 #define nspr_hd_v20_s sizeof(nspr_hd_v20_t)
113 ** How to know if header size is short or long?
114 ** The short header size can be 0-127 bytes long. If MS Bit of ph_RecordSize
115 ** is set then record size has 2 bytes
117 #define NSPR_V20RECORDSIZE_2BYTES 0x80
119 /* Performance Data Header with device number */
120 typedef struct nspr_headerdev_v10
122 guint8 ph_RecordType[2]; /* Record Type */
123 guint8 ph_RecordSize[2]; /* Record Size including header */
124 guint8 ph_DevNo[4]; /* Network Device (NIC/CONN) number */
125 } nspr_headerdev_v10_t;
126 #define nspr_headerdev_v10_s sizeof(nspr_headerdev_v10_t)
128 typedef struct nspr_hd_v10
130 nspr_header_v10_t phd; /* performance header */
132 #define nspr_hd_v10_s sizeof(nspr_hd_v10_t)
134 typedef struct nspr_hdev_v10
136 nspr_headerdev_v10_t phd; /* performance header */
138 #define nspr_hdev_v10_s sizeof(nspr_hdev_v10_t)
140 /* if structure has defined phd as first field, it can use following names */
141 #define nsprRecordType phd.ph_RecordType
142 #define nsprRecordSize phd.ph_RecordSize
143 #define nsprReserved phd.ph_Reserved
144 #define nsprRecordTypeOrg phd.ph_Reserved
145 #define nsprDevNo phd.ph_DevNo
147 /* NSPR_SIGNATURE_V10 structure */
148 #define NSPR_SIGSIZE_V10 56 /* signature value size in bytes */
151 typedef struct nspr_signature_v10
153 nspr_header_v10_t phd; /* performance header */
154 guint8 sig_EndianType; /* Endian Type for the data */
155 guint8 sig_Reserved0;
156 guint8 sig_Reserved1[2];
157 gchar sig_Signature[NSPR_SIGSIZE_V10]; /* Signature value */
158 } nspr_signature_v10_t;
159 #define nspr_signature_v10_s sizeof(nspr_signature_v10_t)
161 /* NSPR_SIGNATURE_V20 structure */
162 typedef struct nspr_signature_v20
164 NSPR_HEADER_V20(sig); /* short performance header */
165 guint8 sig_EndianType; /* Endian Type for the data */
166 gchar sig_Signature[1]; /* Signature value */
167 } nspr_signature_v20_t;
168 #define nspr_signature_v20_s (sizeof(nspr_signature_v20_t) -1)
170 /* NSPR_ABSTIME_V10 and NSPR_SYSTARTIME_V10 structure */
171 typedef struct nspr_abstime_v10
173 nspr_header_v10_t phd; /* performance header */
174 guint8 abs_RelTime[4]; /* relative time is ms from last time */
175 guint8 abs_Time[4]; /* absolute time in seconds from 1970 */
176 } nspr_abstime_v10_t;
177 #define nspr_abstime_v10_s sizeof(nspr_abstime_v10_t)
180 /* NSPR_ABSTIME_V20 and NSPR_SYSTARTIME_V20 structure */
181 typedef struct nspr_abstime_v20
183 NSPR_HEADER_V20(abs); /* short performance header */
184 guint8 abs_RelTime[2]; /* relative time is ms from last time */
185 guint8 abs_Time[4]; /* absolute time in seconds from 1970 */
186 } nspr_abstime_v20_t;
187 #define nspr_abstime_v20_s sizeof(nspr_abstime_v20_t)
191 /* full packet trace structure */
192 typedef struct nspr_pktracefull_v10
194 nspr_headerdev_v10_t phd; /* performance header */
195 guint8 fp_RelTimeHr[4]; /* High resolution relative time */
196 guint8 fp_Data[1]; /* packet data starts here */
197 } nspr_pktracefull_v10_t;
198 #define nspr_pktracefull_v10_s (nspr_hdev_v10_s + 4)
200 /* new full packet trace structure v20 */
201 typedef struct nspr_pktracefull_v20
203 NSPR_HEADER3B_V20(fp); /* long performance header */
204 guint8 fp_DevNo; /* Network Device (NIC) number */
205 guint8 fp_RelTimeHr[4]; /* High resolution relative time */
206 guint8 fp_Data[4]; /* packet data starts here */
207 } nspr_pktracefull_v20_t;
208 #define nspr_pktracefull_v20_s (sizeof(nspr_pktracefull_v20_t) - 4)
210 /* new full packet trace structure v21 */
211 typedef struct nspr_pktracefull_v21
213 NSPR_HEADER3B_V21(fp); /* long performance header */
214 guint8 fp_DevNo; /* Network Device (NIC) number */
215 guint8 fp_RelTimeHr[4]; /* High resolution relative time */
216 guint8 fp_PcbDevNo[4]; /* PCB devno */
217 guint8 fp_lPcbDevNo[4]; /* link PCB devno */
218 guint8 fp_Data[4]; /* packet data starts here */
219 } nspr_pktracefull_v21_t;
220 #define nspr_pktracefull_v21_s (sizeof(nspr_pktracefull_v21_t) - 4)
222 /* new full packet trace structure v22 */
223 typedef struct nspr_pktracefull_v22
225 NSPR_HEADER3B_V22(fp); /* long performance header */
226 guint8 fp_DevNo; /* Network Device (NIC) number */
227 guint8 fp_RelTimeHr[4]; /* High resolution relative time */
228 guint8 fp_PcbDevNo[4]; /* PCB devno */
229 guint8 fp_lPcbDevNo[4]; /* link PCB devno */
230 guint8 fp_VlanTag[2]; /* vlan tag */
231 guint8 fp_Data[2]; /* packet data starts here */
232 } nspr_pktracefull_v22_t;
233 #define nspr_pktracefull_v22_s (sizeof(nspr_pktracefull_v22_t) - 2)
235 typedef struct nspr_pktracefull_v23
237 NSPR_HEADER3B_V22(fp); /* long performance header */
238 guint8 fp_DevNo; /* Network Device (NIC) number */
239 guint8 fp_AbsTimeHr[8]; /* High resolution absolute time */
240 guint8 fp_PcbDevNo[4]; /* PCB devno */
241 guint8 fp_lPcbDevNo[4]; /* link PCB devno */
242 guint8 fp_VlanTag[2]; /* vlan tag */
243 guint8 fp_Coreid[2]; /* coreid of the packet */
244 guint8 fp_Data[2]; /* packet data starts here */
245 } nspr_pktracefull_v23_t;
246 #define nspr_pktracefull_v23_s (sizeof(nspr_pktracefull_v23_t) - 2)
248 /* partial packet trace structure */
249 typedef struct nspr_pktracepart_v10
251 nspr_headerdev_v10_t phd; /* performance header */
252 guint8 pp_RelTimeHr[4]; /* High resolution relative time */
253 guint8 pp_PktSizeOrg[2]; /* Original packet size */
254 guint8 pp_PktOffset[2]; /* starting offset in packet */
255 guint8 pp_Data[1]; /* packet data starts here */
256 } nspr_pktracepart_v10_t;
257 #define nspr_pktracepart_v10_s (nspr_pktracefull_v10_s + 4)
259 /* new partial packet trace structure */
260 typedef struct nspr_pktracepart_v20
262 NSPR_HEADER3B_V20(pp); /* long performance header */
263 guint8 pp_DevNo; /* Network Device (NIC) number */
264 guint8 pp_RelTimeHr[4]; /* High resolution relative time */
265 guint8 pp_PktSizeOrg[2]; /* Original packet size */
266 guint8 pp_PktOffset[2]; /* starting offset in packet */
267 guint8 pp_Data[4]; /* packet data starts here */
268 } nspr_pktracepart_v20_t;
269 #define nspr_pktracepart_v20_s (sizeof(nspr_pktracepart_v20_t) -4)
271 /* new partial packet trace structure */
272 typedef struct nspr_pktracepart_v21
274 NSPR_HEADER3B_V21(pp); /* long performance header */
275 guint8 pp_DevNo; /* Network Device (NIC) number */
276 guint8 pp_RelTimeHr[4]; /* High resolution relative time */
277 guint8 pp_PktSizeOrg[2]; /* Original packet size */
278 guint8 pp_PktOffset[2]; /* starting offset in packet */
279 guint8 pp_PcbDevNo[4]; /* PCB devno */
280 guint8 pp_lPcbDevNo[4]; /* link PCB devno */
281 guint8 pp_Data[4]; /* packet data starts here */
282 } nspr_pktracepart_v21_t;
283 #define nspr_pktracepart_v21_s (sizeof(nspr_pktracepart_v21_t) -4)
285 /* new partial packet trace structure v22 */
286 typedef struct nspr_pktracepart_v22
288 NSPR_HEADER3B_V22(pp); /* long performance header */
289 guint8 pp_DevNo; /* Network Device (NIC) number */
290 guint8 pp_RelTimeHr[4]; /* High resolution relative time */
291 guint8 pp_PktSizeOrg[2]; /* Original packet size */
292 guint8 pp_PktOffset[2]; /* starting offset in packet */
293 guint8 pp_PcbDevNo[4]; /* PCB devno */
294 guint8 pp_lPcbDevNo[4]; /* link PCB devno */
295 guint8 pp_VlanTag[2]; /* Vlan Tag */
296 guint8 pp_Data[2]; /* packet data starts here */
297 } nspr_pktracepart_v22_t;
298 #define nspr_pktracepart_v22_s (sizeof(nspr_pktracepart_v22_t) -2)
300 typedef struct nspr_pktracepart_v23
302 NSPR_HEADER3B_V22(pp); /* long performance header */
303 guint8 pp_DevNo; /* Network Device (NIC) number */
304 guint8 pp_AbsTimeHr[8]; /* High resolution absolute time */
305 guint8 pp_PktSizeOrg[2]; /* Original packet size */
306 guint8 pp_PktOffset[2]; /* starting offset in packet */
307 guint8 pp_PcbDevNo[4]; /* PCB devno */
308 guint8 pp_lPcbDevNo[4]; /* link PCB devno */
309 guint8 pp_VlanTag[2]; /* vlan tag */
310 guint8 pp_Coreid[2]; /* Coreid of the packet */
311 guint8 pp_Data[4]; /* packet data starts here */
312 } nspr_pktracepart_v23_t;
313 #define nspr_pktracepart_v23_s (sizeof(nspr_pktracepart_v23_t) -4)
315 #define myoffsetof(type,fieldname) (&(((type*)0)->fieldname))
317 #define __TNO(enumprefix,structprefix,structname,hdrname,structfieldname) \
318 guint8 enumprefix##_##hdrname##_offset = (guint8)GPOINTER_TO_INT(myoffsetof(nspr_##structname##_t,structprefix##_##structfieldname));
320 #define __TNL(enumprefix,structprefix,structname,hdrname,structfieldname) \
321 guint8 enumprefix##_##hdrname##_len = (guint8)sizeof(((nspr_##structname##_t*)0)->structprefix##_##structfieldname);
323 #define __TNV1O(enumprefix,structprefix,structname,hdrname,structfieldname) \
324 guint8 enumprefix##_##hdrname##_offset = (guint8)GPOINTER_TO_INT(myoffsetof(nspr_##structname##_t,structfieldname));
326 #define __TNV1L(enumprefix,structprefix,structname,hdrname,structfieldname) \
327 guint8 enumprefix##_##hdrname##_len = (guint8)sizeof(((nspr_##structname##_t*)0)->structfieldname);
329 #define TRACE_V10_REC_LEN_OFF(enumprefix,structprefix,structname) \
330 __TNV1O(enumprefix,structprefix,structname,dir,phd.ph_RecordType)\
331 __TNV1L(enumprefix,structprefix,structname,dir,phd.ph_RecordType)\
332 __TNV1O(enumprefix,structprefix,structname,nicno,phd.ph_DevNo)\
333 __TNV1L(enumprefix,structprefix,structname,nicno,phd.ph_DevNo)\
334 __TNO(enumprefix,structprefix,structname,eth,Data)
336 #define TRACE_V20_REC_LEN_OFF(enumprefix,structprefix,structname) \
337 __TNO(enumprefix,structprefix,structname,dir,RecordType)\
338 __TNL(enumprefix,structprefix,structname,dir,RecordType)\
339 __TNO(enumprefix,structprefix,structname,nicno,DevNo)\
340 __TNL(enumprefix,structprefix,structname,nicno,DevNo)\
341 __TNO(enumprefix,structprefix,structname,eth,Data)
343 #define TRACE_V21_REC_LEN_OFF(enumprefix,structprefix,structname) \
344 TRACE_V20_REC_LEN_OFF(enumprefix,structprefix,structname)\
345 __TNO(enumprefix,structprefix,structname,pcb,PcbDevNo)\
346 __TNO(enumprefix,structprefix,structname,l_pcb,lPcbDevNo)
348 #define TRACE_V22_REC_LEN_OFF(enumprefix,structprefix,structname) \
349 TRACE_V21_REC_LEN_OFF(enumprefix,structprefix,structname)\
350 __TNO(enumprefix,structprefix,structname,vlantag,VlanTag)
352 #define TRACE_V23_REC_LEN_OFF(enumprefix,structprefix,structname) \
353 TRACE_V22_REC_LEN_OFF(enumprefix,structprefix,structname)\
354 __TNO(enumprefix,structprefix,structname,coreid,Coreid)
357 TRACE_V10_REC_LEN_OFF(v10_part,pp,pktracepart_v10)
358 TRACE_V10_REC_LEN_OFF(v10_full,fp,pktracefull_v10)
359 TRACE_V20_REC_LEN_OFF(v20_part,pp,pktracepart_v20)
360 TRACE_V20_REC_LEN_OFF(v20_full,fp,pktracefull_v20)
361 TRACE_V21_REC_LEN_OFF(v21_part,pp,pktracepart_v21)
362 TRACE_V21_REC_LEN_OFF(v21_full,fp,pktracefull_v21)
363 TRACE_V22_REC_LEN_OFF(v22_part,pp,pktracepart_v22)
364 TRACE_V22_REC_LEN_OFF(v22_full,fp,pktracefull_v22)
365 TRACE_V23_REC_LEN_OFF(v23_part,pp,pktracepart_v23)
366 TRACE_V23_REC_LEN_OFF(v23_full,fp,pktracefull_v23)
374 #define ns_setabstime(nstrace, AbsoluteTime, RelativeTimems) \
376 (nstrace)->nspm_curtime = AbsoluteTime; \
377 (nstrace)->nspm_curtimemsec += RelativeTimems; \
378 (nstrace)->nspm_curtimelastmsec = nstrace->nspm_curtimemsec; \
382 #define ns_setrelativetime(nstrace, RelativeTimems) \
385 (nstrace)->nspm_curtimemsec += RelativeTimems; \
386 rsec = (guint32)((nstrace)->nspm_curtimemsec - (nstrace)->nspm_curtimelastmsec)/1000; \
387 (nstrace)->nspm_curtime += rsec; \
388 (nstrace)->nspm_curtimelastmsec += rsec * 1000; \
394 gint32 nstrace_buf_offset;
395 gint32 nstrace_buflen;
396 /* Performance Monitor Time variables */
397 guint32 nspm_curtime; /* current time since 1970 */
398 guint64 nspm_curtimemsec; /* current time in mili second */
399 guint64 nspm_curtimelastmsec; /* nspm_curtime last update time in milisec */
400 guint64 nsg_creltime;
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 guint8 *pd, int length,
416 int *err, gchar **err_info);
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 guint8 *pd, int *err);
429 #define GET_READ_PAGE_SIZE(remaining_file_size) ((gint32)((remaining_file_size>NSPR_PAGESIZE)?NSPR_PAGESIZE:remaining_file_size))
432 guint64 ns_hrtime2nsec(guint32 tm)
434 guint32 val = tm & NSPR_HRTIME_MASKTM;
435 switch(tm & NSPR_HRTIME_MASKFMT)
437 case NSPR_HRTIME_SEC: return (guint64)val*1000000000;
438 case NSPR_HRTIME_MSEC: return (guint64)val*1000000;
439 case NSPR_HRTIME_USEC: return (guint32)val*1000;
440 case NSPR_HRTIME_NSEC: return val;
447 ** Netscaler trace format open routines
449 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, err_info);
489 bytes_read = file_read(nstrace_buf, page_size, wth->fh);
490 if (bytes_read != page_size)
492 *err = file_error(wth->fh, err_info);
497 wth->subtype_read = nstrace_read;
498 wth->subtype_seek_read = nstrace_seek_read;
499 wth->subtype_close = nstrace_close;
501 nstrace = (nstrace_t *)g_malloc(sizeof(nstrace_t));
502 wth->priv = (void *)nstrace;
503 nstrace->pnstrace_buf = nstrace_buf;
504 nstrace->nstrace_buflen = page_size;
505 nstrace->nstrace_buf_offset = 0;
506 nstrace->nspm_curtime = 0;
507 nstrace->nspm_curtimemsec = 0;
508 nstrace->nspm_curtimelastmsec = 0;
509 nstrace->nsg_creltime = 0;
510 nstrace->file_size = file_size;
513 /* Set the start time by looking for the abstime record */
514 if ((nstrace_set_start_time(wth)) == FALSE)
516 /* Reset the read pointer to start of the file. */
517 if ((file_seek(wth->fh, 0, SEEK_SET, err)) == -1)
519 *err = file_error(wth->fh, err_info);
520 g_free(nstrace->pnstrace_buf);
525 /* Read the first page of data */
526 bytes_read = file_read(nstrace_buf, page_size, wth->fh);
527 if (bytes_read != page_size)
529 *err = file_error(wth->fh, err_info);
530 g_free(nstrace->pnstrace_buf);
535 /* reset the buffer offset */
536 nstrace->nstrace_buf_offset = 0;
539 wth->tsprecision = WTAP_FILE_TSPREC_NSEC;
540 wth->phdr.ts.secs = nstrace->nspm_curtime;
541 wth->phdr.ts.nsecs = 0;
548 #define nspm_signature_func(ver) \
549 guint32 nspm_signature_isv##ver(gchar *sigp) {\
550 return strncmp(sigp,NSPR_SIGSTR_V##ver,(sizeof(NSPR_SIGSTR_V##ver)-1));\
553 nspm_signature_func(10)
554 nspm_signature_func(20)
557 ** Check signature and return the version number of the signature.
558 ** If not found, it returns 0. At the time of return from this function
559 ** we might not be at the first page. So after a call to this function, there
560 ** has to be a file seek to return to the start of the first page.
563 nspm_signature_version(wtap *wth, gchar *nstrace_buf, gint32 len)
565 gchar *dp = nstrace_buf;
568 bytes_read = file_read(dp, len, wth->fh);
569 if (bytes_read == len) {
571 for ( ; len > (gint32)(MIN(sizeof(NSPR_SIGSTR_V10), sizeof(NSPR_SIGSTR_V20))); dp++, len--)
573 #define sigv10p ((nspr_signature_v10_t*)dp)
574 if ((pletohs(&sigv10p->nsprRecordType) == NSPR_SIGNATURE_V10) &&
575 (pletohs(&sigv10p->nsprRecordSize) <= len) &&
576 ((gint32)sizeof(NSPR_SIGSTR_V10) <= len) &&
577 (!nspm_signature_isv10(sigv10p->sig_Signature)))
578 return WTAP_FILE_NETSCALER_1_0;
581 #define sigv20p ((nspr_signature_v20_t*)dp)
582 if ((sigv20p->sig_RecordType == NSPR_SIGNATURE_V20) &&
583 (sigv20p->sig_RecordSize <= len) &&
584 ((gint32)sizeof(NSPR_SIGSTR_V20) <= len) &&
585 (!nspm_signature_isv20(sigv20p->sig_Signature)))
586 return WTAP_FILE_NETSCALER_2_0;
591 return 0; /* no version found */
594 #define nspr_getv10recordtype(hdp) (pletohs(&hdp->nsprRecordType))
595 #define nspr_getv10recordsize(hdp) (pletohs(&hdp->nsprRecordSize))
596 #define nspr_getv20recordtype(hdp) (hdp->phd_RecordType)
597 #define nspr_getv20recordsize(hdp) \
598 (((hdp)->phd_RecordSizeLow & NSPR_V20RECORDSIZE_2BYTES)? \
599 (((hdp)->phd_RecordSizeHigh * NSPR_V20RECORDSIZE_2BYTES)+ \
600 ((hdp)->phd_RecordSizeLow & ~NSPR_V20RECORDSIZE_2BYTES)) : \
601 (hdp)->phd_RecordSizeLow)
604 #define nstrace_set_start_time_ver(ver) \
605 gboolean nstrace_set_start_time_v##ver(wtap *wth) \
607 nstrace_t *nstrace = (nstrace_t *)wth->priv;\
608 gchar* nstrace_buf = nstrace->pnstrace_buf;\
609 gint32 nstrace_buf_offset = nstrace->nstrace_buf_offset;\
610 gint32 nstrace_buflen = nstrace->nstrace_buflen;\
614 while (nstrace_buf_offset < nstrace_buflen)\
616 nspr_hd_v##ver##_t *fp = (nspr_hd_v##ver##_t *) &nstrace_buf[nstrace_buf_offset];\
617 switch (nspr_getv##ver##recordtype(fp))\
619 case NSPR_ABSTIME_V##ver:\
620 ns_setabstime(nstrace, pletohl(&((nspr_abstime_v##ver##_t *) fp)->abs_Time), pletohs(&((nspr_abstime_v##ver##_t *) fp)->abs_RelTime));\
621 nstrace->nstrace_buf_offset = nstrace_buf_offset + nspr_getv##ver##recordsize(fp);\
622 nstrace->nstrace_buflen = nstrace_buflen;\
624 case NSPR_UNUSEDSPACE_V10:\
625 nstrace_buf_offset = nstrace_buflen;\
628 nstrace_buf_offset += nspr_getv##ver##recordsize(fp);\
631 nstrace_buf_offset = 0;\
632 wth->data_offset += nstrace_buflen;\
633 nstrace_buflen = GET_READ_PAGE_SIZE((nstrace->file_size - wth->data_offset));\
634 }while((nstrace_buflen > 0) && (bytes_read = file_read(nstrace_buf, nstrace_buflen, wth->fh)) && bytes_read == nstrace_buflen); \
638 nstrace_set_start_time_ver(10)
639 nstrace_set_start_time_ver(20)
641 #undef nspr_getv10recordtype
642 #undef nspr_getv20recordtype
643 #undef nspr_getv10recordsize
646 ** Set the start time of the trace file. We look for the first ABSTIME record. We use that
647 ** to set the start time. Apart from that we also make sure that we remember the position of
648 ** the next record after the ABSTIME record. Inorder to report correct time values, all trace
649 ** records before the ABSTIME record are ignored.
651 gboolean nstrace_set_start_time(wtap *wth)
653 if (wth->file_type == WTAP_FILE_NETSCALER_1_0)
654 return nstrace_set_start_time_v10(wth);
655 else if (wth->file_type == WTAP_FILE_NETSCALER_2_0)
656 return nstrace_set_start_time_v20(wth);
661 #define __TNO(enumprefix,structprefix,structname,hdrname,structfieldname) \
662 wth->pseudo_header.nstr.hdrname##_offset = enumprefix##_##hdrname##_offset;
664 #define __TNL(enumprefix,structprefix,structname,hdrname,structfieldname) \
665 wth->pseudo_header.nstr.hdrname##_len = enumprefix##_##hdrname##_len;
667 #define __TNV1O(enumprefix,structprefix,structname,hdrname,structfieldname) \
668 __TNO(enumprefix,structprefix,structname,hdrname,structfieldname)
670 #define __TNV1L(enumprefix,structprefix,structname,hdrname,structfieldname) \
671 __TNL(enumprefix,structprefix,structname,hdrname,structfieldname)
676 ** Netscaler trace format read routines.
678 gboolean nstrace_read_v10(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
680 nstrace_t *nstrace = (nstrace_t *)wth->priv;
681 guint64 nsg_creltime = nstrace->nsg_creltime;
682 gchar *nstrace_buf = nstrace->pnstrace_buf;
683 gint32 nstrace_buf_offset = nstrace->nstrace_buf_offset;
684 gint32 nstrace_buflen = nstrace->nstrace_buflen;
685 nspr_pktracefull_v10_t *fp;
686 nspr_pktracepart_v10_t *pp;
693 while ((nstrace_buf_offset < nstrace_buflen) &&
694 ((nstrace_buflen - nstrace_buf_offset) >= ((gint32)sizeof(fp->nsprRecordType))))
697 fp = (nspr_pktracefull_v10_t *) &nstrace_buf[nstrace_buf_offset];
698 pp = (nspr_pktracepart_v10_t *) fp;
700 switch (pletohs(&fp->nsprRecordType))
702 case NSPR_PDPKTRACEFULLTX_V10:
703 case NSPR_PDPKTRACEFULLTXB_V10:
704 case NSPR_PDPKTRACEFULLRX_V10:
706 nsg_creltime += ns_hrtime2nsec(pletohl(&fp->fp_RelTimeHr));
707 wth->phdr.ts.secs = nstrace->nspm_curtime + (guint32) (nsg_creltime / 1000000000);
708 wth->phdr.ts.nsecs = (guint32) (nsg_creltime % 1000000000);
710 wth->phdr.len = pletohs(&fp->nsprRecordSize);
711 wth->phdr.caplen = wth->phdr.len;
714 TRACE_V10_REC_LEN_OFF(v10_full,fp,pktracefull_v10);
716 buffer_assure_space(wth->frame_buffer, wth->phdr.caplen);
717 memcpy(buffer_start_ptr(wth->frame_buffer), fp, wth->phdr.caplen);
718 *data_offset = wth->data_offset + nstrace_buf_offset;
720 nstrace->nstrace_buf_offset = nstrace_buf_offset + wth->phdr.len;
721 nstrace->nstrace_buflen = nstrace_buflen;
722 nstrace->nsg_creltime = nsg_creltime;
726 case NSPR_PDPKTRACEPARTTX_V10:
727 case NSPR_PDPKTRACEPARTTXB_V10:
728 case NSPR_PDPKTRACEPARTRX_V10:
730 nsg_creltime += ns_hrtime2nsec(pletohl(&pp->pp_RelTimeHr));
731 wth->phdr.ts.secs = nstrace->nspm_curtime + (guint32) (nsg_creltime / 1000000000);
732 wth->phdr.ts.nsecs = (guint32) (nsg_creltime % 1000000000);
734 wth->phdr.len = pletohs(&pp->pp_PktSizeOrg) + nspr_pktracepart_v10_s;
735 wth->phdr.caplen = pletohs(&pp->nsprRecordSize);
737 TRACE_V10_REC_LEN_OFF(v10_part,pp,pktracepart_v10);
739 buffer_assure_space(wth->frame_buffer, wth->phdr.caplen);
740 memcpy(buffer_start_ptr(wth->frame_buffer), pp, wth->phdr.caplen);
741 *data_offset = wth->data_offset + nstrace_buf_offset;
743 nstrace->nstrace_buf_offset = nstrace_buf_offset + wth->phdr.caplen;
744 nstrace->nsg_creltime = nsg_creltime;
745 nstrace->nstrace_buflen = nstrace_buflen;
749 case NSPR_ABSTIME_V10:
751 ns_setabstime(nstrace, pletohl(((nspr_abstime_v10_t *) fp)->abs_Time), pletohl(&((nspr_abstime_v10_t *) fp)->abs_RelTime));
752 nstrace_buf_offset += pletohs(&fp->nsprRecordSize);
755 case NSPR_RELTIME_V10:
757 ns_setrelativetime(nstrace, pletohl(((nspr_abstime_v10_t *) fp)->abs_RelTime));
758 nstrace_buf_offset += pletohs(&fp->nsprRecordSize);
761 case NSPR_UNUSEDSPACE_V10:
763 nstrace_buf_offset = nstrace_buflen;
768 nstrace_buf_offset += pletohs(&fp->nsprRecordSize);
773 nstrace_buf_offset = 0;
774 wth->data_offset += nstrace_buflen;
775 nstrace_buflen = GET_READ_PAGE_SIZE((nstrace->file_size - wth->data_offset));
776 }while((nstrace_buflen > 0) && (bytes_read = file_read(nstrace_buf, nstrace_buflen, wth->fh)) && (bytes_read == nstrace_buflen));
781 #define TIMEDEFV20(fp,type) \
783 nsg_creltime += ns_hrtime2nsec(pletohl(fp->type##_RelTimeHr));\
784 wth->phdr.ts.secs = nstrace->nspm_curtime + (guint32) (nsg_creltime / 1000000000);\
785 wth->phdr.ts.nsecs = (guint32) (nsg_creltime % 1000000000);\
788 #define TIMEDEFV23(fp,type) \
790 /* access _AbsTimeHr as a 64bit value */\
791 nsg_creltime = pletohll(fp->type##_AbsTimeHr);\
792 wth->phdr.ts.secs = (guint32) (nsg_creltime / 1000000000);\
793 wth->phdr.ts.nsecs = (guint32) (nsg_creltime % 1000000000);\
796 #define TIMEDEFV21(fp,type) TIMEDEFV20(fp,type)
797 #define TIMEDEFV22(fp,type) TIMEDEFV20(fp,type)
799 #define PPSIZEDEFV20(pp,ver) \
801 wth->phdr.len = pletohs(&pp->pp_PktSizeOrg) + nspr_pktracepart_v##ver##_s;\
802 wth->phdr.caplen = nspr_getv20recordsize((nspr_hd_v20_t *)pp);\
805 #define PPSIZEDEFV21(pp,ver) PPSIZEDEFV20(pp,ver)
806 #define PPSIZEDEFV22(pp,ver) PPSIZEDEFV20(pp,ver)
807 #define PPSIZEDEFV23(pp,ver) PPSIZEDEFV20(pp,ver)
809 #define FPSIZEDEFV20(fp,ver)\
811 wth->phdr.len = nspr_getv20recordsize((nspr_hd_v20_t *)fp);\
812 wth->phdr.caplen = wth->phdr.len;\
815 #define FPSIZEDEFV21(pp,ver) FPSIZEDEFV20(fp,ver)
816 #define FPSIZEDEFV22(pp,ver) FPSIZEDEFV20(fp,ver)
817 #define FPSIZEDEFV23(pp,ver) FPSIZEDEFV20(fp,ver)
819 #define PACKET_DESCRIBE(FPTIMEDEF,SIZEDEF,ver,enumprefix,type,structname,TYPE)\
821 nspr_##structname##_t *fp= (nspr_##structname##_t*)&nstrace_buf[nstrace_buf_offset];\
822 TIMEDEFV##ver(fp,type);\
823 SIZEDEF##ver(fp,ver);\
824 TRACE_V##ver##_REC_LEN_OFF(enumprefix,type,structname);\
825 buffer_assure_space(wth->frame_buffer, wth->phdr.caplen);\
826 memcpy(buffer_start_ptr(wth->frame_buffer), fp, wth->phdr.caplen);\
827 *data_offset = wth->data_offset + nstrace_buf_offset;\
828 nstrace->nstrace_buf_offset = nstrace_buf_offset + nspr_getv20recordsize((nspr_hd_v20_t *)fp);\
829 nstrace->nstrace_buflen = nstrace_buflen;\
830 nstrace->nsg_creltime = nsg_creltime;\
831 wth->pseudo_header.nstr.rec_type = NSPR_HEADER_VERSION##TYPE;\
835 gboolean nstrace_read_v20(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
837 nstrace_t *nstrace = (nstrace_t *)wth->priv;
838 guint64 nsg_creltime = nstrace->nsg_creltime;
839 gchar *nstrace_buf = nstrace->pnstrace_buf;
840 gint32 nstrace_buf_offset = nstrace->nstrace_buf_offset;
841 gint32 nstrace_buflen = nstrace->nstrace_buflen;
842 nspr_pktracefull_v20_t *fp20;
843 nspr_pktracefull_v21_t *fp21;
850 while ((nstrace_buf_offset < nstrace_buflen) &&
851 ((nstrace_buflen - nstrace_buf_offset) >= ((gint32)sizeof(fp21->fp_RecordType))))
853 fp21 = (nspr_pktracefull_v21_t *) &nstrace_buf[nstrace_buf_offset];
855 switch (fp21->fp_RecordType)
858 #define GENERATE_CASE(type,acttype) \
859 case NSPR_PDPKTRACEFULLTX_V##type:\
860 case NSPR_PDPKTRACEFULLTXB_V##type:\
861 case NSPR_PDPKTRACEFULLRX_V##type:\
862 PACKET_DESCRIBE(TIMEDEF,FPSIZEDEFV,type,v##type##_full,fp,pktracefull_v##type,acttype);
863 GENERATE_CASE(23,203);
864 GENERATE_CASE(22,202);
865 GENERATE_CASE(21,201);
866 GENERATE_CASE(20,200);
869 #define GENERATE_CASE(type,acttype) \
870 case NSPR_PDPKTRACEPARTTX_V##type:\
871 case NSPR_PDPKTRACEPARTTXB_V##type:\
872 case NSPR_PDPKTRACEPARTRX_V##type:\
873 PACKET_DESCRIBE(TIMEDEF,PPSIZEDEFV,type,v##type##_part,pp,pktracepart_v##type,acttype);
874 GENERATE_CASE(23,203);
875 GENERATE_CASE(22,202);
876 GENERATE_CASE(21,201);
877 GENERATE_CASE(20,200);
880 case NSPR_ABSTIME_V20:
882 fp20 = (nspr_pktracefull_v20_t *) &nstrace_buf[nstrace_buf_offset];
883 nstrace_buf_offset += nspr_getv20recordsize((nspr_hd_v20_t *)fp20);
884 ns_setabstime(nstrace, pletohl(&((nspr_abstime_v20_t *) fp20)->abs_Time), pletohs(&((nspr_abstime_v20_t *) fp20)->abs_RelTime));
888 case NSPR_RELTIME_V20:
890 fp20 = (nspr_pktracefull_v20_t *) &nstrace_buf[nstrace_buf_offset];
891 ns_setrelativetime(nstrace, pletohs(&((nspr_abstime_v20_t *) fp20)->abs_RelTime));
892 nstrace_buf_offset += nspr_getv20recordsize((nspr_hd_v20_t *)fp20);
896 case NSPR_UNUSEDSPACE_V20:
898 if (nstrace_buf_offset >= NSPR_PAGESIZE/2)
899 nstrace_buf_offset = nstrace_buflen;
901 nstrace_buf_offset = NSPR_PAGESIZE/2;
907 fp20 = (nspr_pktracefull_v20_t *) &nstrace_buf[nstrace_buf_offset];
908 nstrace_buf_offset += nspr_getv20recordsize((nspr_hd_v20_t *)fp20);
914 nstrace_buf_offset = 0;
915 wth->data_offset += nstrace_buflen;
916 nstrace_buflen = GET_READ_PAGE_SIZE((nstrace->file_size - wth->data_offset));
917 }while((nstrace_buflen > 0) && (bytes_read = file_read(nstrace_buf, nstrace_buflen, wth->fh)) && (bytes_read == nstrace_buflen));
929 gboolean nstrace_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
932 if (wth->file_type == WTAP_FILE_NETSCALER_1_0)
933 return nstrace_read_v10(wth, err, err_info, data_offset);
934 else if (wth->file_type == WTAP_FILE_NETSCALER_2_0)
935 return nstrace_read_v20(wth, err, err_info, data_offset);
941 #define __TNO(enumprefix,structprefix,structname,hdrname,structfieldname) \
942 pseudo_header->nstr.hdrname##_offset = (guint8) enumprefix##_##hdrname##_offset;
943 #define __TNL(enumprefix,structprefix,structname,hdrname,structfieldname) \
944 pseudo_header->nstr.hdrname##_len = (guint8) enumprefix##_##hdrname##_len;;
946 #define __TNV1O(enumprefix,structprefix,structname,hdrname,structfieldname) \
947 __TNO(enumprefix,structprefix,structname,hdrname,structfieldname)
948 #define __TNV1L(enumprefix,structprefix,structname,hdrname,structfieldname) \
949 __TNL(enumprefix,structprefix,structname,hdrname,structfieldname)
952 gboolean nstrace_seek_read(wtap *wth, gint64 seek_off,
953 union wtap_pseudo_header *pseudo_header, guint8 *pd, int length,
954 int *err, gchar **err_info)
960 if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
964 ** Read the packet data.
966 bytes_read = file_read(pd, length, wth->random_fh);
967 if (bytes_read != length) {
968 *err = file_error(wth->random_fh, err_info);
970 *err = WTAP_ERR_SHORT_READ;
974 if (wth->file_type == WTAP_FILE_NETSCALER_1_0)
977 #define GENERATE_CASE_FULL(type,acttype) \
978 case NSPR_PDPKTRACEFULLTX_V##type:\
979 case NSPR_PDPKTRACEFULLTXB_V##type:\
980 case NSPR_PDPKTRACEFULLRX_V##type:\
981 TRACE_V##type##_REC_LEN_OFF(v##type##_full,fp,pktracefull_v##type);\
982 pseudo_header->nstr.rec_type = NSPR_HEADER_VERSION##acttype;\
985 #define GENERATE_CASE_PART(type,acttype) \
986 case NSPR_PDPKTRACEPARTTX_V##type:\
987 case NSPR_PDPKTRACEPARTTXB_V##type:\
988 case NSPR_PDPKTRACEPARTRX_V##type:\
989 TRACE_V##type##_REC_LEN_OFF(v##type##_part,pp,pktracepart_v##type);\
990 pseudo_header->nstr.rec_type = NSPR_HEADER_VERSION##acttype;\
993 switch (pletohs(&(( nspr_header_v10_t*)pd)->ph_RecordType))
995 GENERATE_CASE_FULL(10,100)
996 GENERATE_CASE_PART(10,100)
998 } else if (wth->file_type == WTAP_FILE_NETSCALER_2_0)
1000 switch ((( nspr_hd_v20_t*)pd)->phd_RecordType)
1002 GENERATE_CASE_FULL(20,200)
1003 GENERATE_CASE_PART(20,200)
1004 GENERATE_CASE_FULL(21,201)
1005 GENERATE_CASE_PART(21,201)
1006 GENERATE_CASE_FULL(22,202)
1007 GENERATE_CASE_PART(22,202)
1008 GENERATE_CASE_FULL(23,203)
1009 GENERATE_CASE_PART(23,203)
1023 ** Netscaler trace format close routines.
1025 void nstrace_close(wtap *wth)
1027 nstrace_t *nstrace = (nstrace_t *)wth->priv;
1029 g_free(nstrace->pnstrace_buf);
1034 guint16 page_offset;
1036 guint32 absrec_time;
1039 /* Returns 0 if we could write the specified encapsulation type,
1040 ** an error indication otherwise. */
1041 int nstrace_10_dump_can_write_encap(int encap)
1043 if (encap == WTAP_ENCAP_NSTRACE_1_0)
1046 return WTAP_ERR_UNSUPPORTED_ENCAP;
1050 /* Returns 0 if we could write the specified encapsulation type,
1051 ** an error indication otherwise. */
1052 int nstrace_20_dump_can_write_encap(int encap)
1054 if (encap == WTAP_ENCAP_NSTRACE_2_0)
1057 return WTAP_ERR_UNSUPPORTED_ENCAP;
1061 /* Returns TRUE on success, FALSE on failure; sets "*err" to an error code on
1063 gboolean nstrace_dump_open(wtap_dumper *wdh, int *err _U_)
1065 nstrace_dump_t *nstrace;
1067 wdh->subtype_write = nstrace_dump;
1069 nstrace = (nstrace_dump_t *)g_malloc(sizeof(nstrace_dump_t));
1070 wdh->priv = (void *)nstrace;
1071 nstrace->page_offset = 0;
1072 nstrace->page_len = NSPR_PAGESIZE;
1073 nstrace->absrec_time = 0;
1079 static gboolean nstrace_add_signature(wtap_dumper *wdh, int *err)
1081 nstrace_dump_t *nstrace = (nstrace_dump_t *)wdh->priv;
1083 if (wdh->file_type == WTAP_FILE_NETSCALER_1_0)
1086 nspr_signature_v10_t sig10;
1088 /* populate the record */
1089 val16b = htoles(NSPR_SIGNATURE_V10);
1090 memcpy(sig10.phd.ph_RecordType, &val16b, sizeof sig10.phd.ph_RecordType);
1091 val16b = htoles(nspr_signature_v10_s);
1092 memcpy(sig10.phd.ph_RecordSize, &val16b, sizeof sig10.phd.ph_RecordSize);
1093 memset(sig10.sig_Signature, 0, NSPR_SIGSIZE_V10);
1094 g_strlcpy(sig10.sig_Signature, NSPR_SIGSTR_V10, NSPR_SIGSIZE_V10);
1096 /* Write the record into the file */
1097 if (!wtap_dump_file_write(wdh, &sig10, nspr_signature_v10_s,
1101 /* Move forward the page offset */
1102 nstrace->page_offset += (guint16) nspr_signature_v10_s;
1104 } else if (wdh->file_type == WTAP_FILE_NETSCALER_2_0)
1106 gchar sig[nspr_signature_v20_s + sizeof(NSPR_SIGSTR_V20)];
1107 nspr_signature_v20_t *sig20;
1109 sig20 = (nspr_signature_v20_t *)&sig;
1110 sig20->sig_RecordType = NSPR_SIGNATURE_V20;
1111 sig20->sig_RecordSize = nspr_signature_v20_s + sizeof(NSPR_SIGSTR_V20);
1112 memcpy(sig20->sig_Signature, NSPR_SIGSTR_V20, sizeof(NSPR_SIGSTR_V20));
1114 /* Write the record into the file */
1115 if (!wtap_dump_file_write(wdh, sig20, sig20->sig_RecordSize,
1119 /* Move forward the page offset */
1120 nstrace->page_offset += (guint16) sig20->sig_RecordSize;
1124 g_assert_not_reached();
1133 nstrace_add_abstime(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
1134 const guint8 *pd, int *err)
1136 nstrace_dump_t *nstrace = (nstrace_dump_t *)wdh->priv;
1137 guint64 nsg_creltime;
1139 if (wdh->file_type == WTAP_FILE_NETSCALER_1_0)
1144 nspr_abstime_v10_t abs10;
1146 /* populate the record */
1147 val16 = htoles(NSPR_ABSTIME_V10);
1148 memcpy(abs10.phd.ph_RecordType, &val16, sizeof abs10.phd.ph_RecordType);
1149 val16 = htoles(nspr_abstime_v10_s);
1150 memcpy(abs10.phd.ph_RecordSize, &val16, sizeof abs10.phd.ph_RecordSize);
1152 memcpy(&reltime, ((const nspr_pktracefull_v10_t *)pd)->fp_RelTimeHr, sizeof reltime);
1153 nsg_creltime = ns_hrtime2nsec(reltime);
1155 memset(abs10.abs_RelTime, 0, sizeof abs10.abs_RelTime);
1156 abstime = htolel((guint32)phdr->ts.secs - (guint32)(nsg_creltime/1000000000));
1157 memcpy(abs10.abs_Time, &abstime, sizeof abs10.abs_Time);
1159 /* Write the record into the file */
1160 if (!wtap_dump_file_write(wdh, &abs10, nspr_abstime_v10_s, err))
1163 /* Move forward the page offset */
1164 nstrace->page_offset += nspr_abstime_v10_s;
1166 } else if (wdh->file_type == WTAP_FILE_NETSCALER_2_0)
1170 nspr_abstime_v20_t abs20;
1172 abs20.abs_RecordType = NSPR_ABSTIME_V20;
1173 abs20.abs_RecordSize = nspr_abstime_v20_s;
1175 memcpy(&reltime, ((const nspr_pktracefull_v20_t *)pd)->fp_RelTimeHr, sizeof reltime);
1176 nsg_creltime = ns_hrtime2nsec(reltime);
1178 memset(abs20.abs_RelTime, 0, sizeof abs20.abs_RelTime);
1179 abstime = htolel((guint32)phdr->ts.secs - (guint32)(nsg_creltime/1000000000));
1180 memcpy(abs20.abs_RelTime, &abstime, sizeof abs20.abs_RelTime);
1182 /* Write the record into the file */
1183 if (!wtap_dump_file_write(wdh, &abs20, nspr_abstime_v20_s, err))
1186 /* Move forward the page offset */
1187 nstrace->page_offset += nspr_abstime_v20_s;
1191 g_assert_not_reached();
1199 /* Write a record for a packet to a dump file.
1200 Returns TRUE on success, FALSE on failure. */
1201 static gboolean nstrace_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
1202 const union wtap_pseudo_header *pseudo_header, const guint8 *pd, int *err)
1204 nstrace_dump_t *nstrace = (nstrace_dump_t *)wdh->priv;
1206 if (nstrace->page_offset == 0)
1208 /* Add the signature record and abs time record */
1209 if (wdh->file_type == WTAP_FILE_NETSCALER_1_0)
1211 if (!nstrace_add_signature(wdh, err) ||
1212 !nstrace_add_abstime(wdh, phdr, pd, err))
1214 } else if (wdh->file_type == WTAP_FILE_NETSCALER_2_0)
1216 if (!nstrace_add_signature(wdh, err) ||
1217 !nstrace_add_abstime(wdh, phdr, pd, err))
1221 g_assert_not_reached();
1226 switch (pseudo_header->nstr.rec_type)
1228 case NSPR_HEADER_VERSION100:
1230 if (wdh->file_type == WTAP_FILE_NETSCALER_1_0)
1232 if (nstrace->page_offset + phdr->caplen >= nstrace->page_len)
1234 /* Start on the next page */
1235 if (fseek(wdh->fh, (nstrace->page_len - nstrace->page_offset), SEEK_CUR) == -1)
1241 nstrace->page_offset = 0;
1243 /* Possibly add signature and abstime records and increment offset */
1244 if (!nstrace_add_signature(wdh, err))
1248 /* Write the actual record as is */
1249 if (!wtap_dump_file_write(wdh, pd, phdr->caplen, err))
1252 nstrace->page_offset += (guint16) phdr->caplen;
1253 } else if (wdh->file_type == WTAP_FILE_NETSCALER_2_0)
1255 *err = WTAP_ERR_UNSUPPORTED_FILE_TYPE;
1261 case NSPR_HEADER_VERSION200:
1262 case NSPR_HEADER_VERSION201:
1263 case NSPR_HEADER_VERSION202:
1264 case NSPR_HEADER_VERSION203:
1266 if (wdh->file_type == WTAP_FILE_NETSCALER_1_0)
1268 *err = WTAP_ERR_UNSUPPORTED_FILE_TYPE;
1270 } else if (wdh->file_type == WTAP_FILE_NETSCALER_2_0)
1272 if (nstrace->page_offset + phdr->caplen >= nstrace->page_len)
1274 /* Start on the next page */
1275 if (fseek(wdh->fh, (nstrace->page_len - nstrace->page_offset), SEEK_CUR) == -1)
1281 nstrace->page_offset = 0;
1283 /* Possibly add signature and abstime records and increment offset */
1284 if (!nstrace_add_signature(wdh, err))
1288 /* Write the actual record as is */
1289 if (!wtap_dump_file_write(wdh, pd, phdr->caplen, err))
1292 nstrace->page_offset += (guint16) phdr->caplen;
1298 g_assert_not_reached();