4 * Copyright (c) 2006 by Ravi Kondamuru <Ravi.Kondamuru@citrix.com>
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 #include "file_wrappers.h"
26 #include "netscaler.h"
28 /* Defines imported from netscaler code: nsperfrc.h */
30 #define NSPR_SIGSTR_V10 "NetScaler Performance Data"
31 #define NSPR_SIGSTR_V20 "NetScaler V20 Performance Data"
32 #define NSPR_SIGSTR NSPR_SIGSTR_V20
33 #define NSPR_SIGSTR_V30 "Netscaler V30 Performance Data"
34 #define NSPR_SIGSTR_V35 "Netscaler V35 Performance Data"
35 /* Defined but not used */
36 #define NSPR_SIGSTR_V21 "NetScaler V21 Performance Data"
37 #define NSPR_SIGSTR_V22 "NetScaler V22 Performance Data"
40 * NetScaler trace files are divided into 8K pages, with each page
41 * containing one or more records. The last page of the file
42 * might be less than 8K bytes.
44 * Records are not split across page boundaries; if a record doesn't
45 * fit in what remains in a page, the page is padded with null bytes
46 * and the next record is put at the beginning of the next page.
47 * A record type value of 0 means "unused space", so if there are
48 * enough null bytes to constitute a record type value, it will
49 * look as if there's an "unused space" record (which has no fields
50 * other than the type and zero or more additional padding bytes).
52 #define NSPR_PAGESIZE 8192
53 #define NSPR_PAGESIZE_TRACE (2*NSPR_PAGESIZE)
55 /* The different record types
56 ** NOTE: The Record Type is two byte fields and unused space is recognized by
57 ** either bytes being zero, therefore no record should any byte value as
60 ** New Performance Record Type is only one byte.
62 #define NSPR_UNUSEDSPACE_V10 0x0000 /* rest of the page is unused */
63 #define NSPR_UNUSEDSPACE_V20 0x00 /* rest of the page is unused */
64 #define NSPR_SIGNATURE_V10 0x0101 /* signature */
65 #define NSPR_SIGNATURE_V20 0x01 /* signature */
66 #define NSPR_SIGNATURE_V30 NSPR_SIGNATURE_V20
67 #define NSPR_SIGNATURE_V35 NSPR_SIGNATURE_V20
68 #define NSPR_ABSTIME_V10 0x0107 /* data capture time in secs from 1970*/
69 #define NSPR_ABSTIME_V20 0x07 /* data capture time in secs from 1970*/
70 #define NSPR_RELTIME_V10 0x0108 /* relative time in ms from last time */
71 #define NSPR_RELTIME_V20 0x08 /* relative time in ms from last time */
72 #define NSPR_RELTIMEHR_V10 0x0109 /* high resolution relative time */
73 #define NSPR_RELTIMEHR_V20 0x09 /* high resolution relative time */
74 #define NSPR_SYSTARTIME_V10 0x010A /* system start time */
75 #define NSPR_SYSTARTIME_V20 0x0A /* system start time */
76 #define NSPR_RELTIME2B_V10 0x010B /* relative time in ms from last time */
77 #define NSPR_RELTIME2B_V20 0x0B /* relative time in ms from last time */
80 /* The high resolution relative time format.
81 ** The MS 2 bits of the high resoltion time is defined as follows:
82 ** 00 : time value is in seconds
83 ** 01 : time value is in milliseconds
84 ** 10 : time value is in microseconds
85 ** 11 : time value is in nanoseconds
87 #define NSPR_HRTIME_MASKTM 0x3FFFFFFF /* mask to get time value */
88 #define NSPR_HRTIME_MASKFMT 0xC0000000 /* time value format mask */
89 #define NSPR_HRTIME_SEC 0x00000000 /* time value in second */
90 #define NSPR_HRTIME_MSEC 0x40000000 /* time value in mili second */
91 #define NSPR_HRTIME_USEC 0x80000000 /* time value in micro second */
92 #define NSPR_HRTIME_NSEC 0xC0000000 /* time value in nano second */
95 typedef struct nspr_header_v10
97 guint8 ph_RecordType[2]; /* Record Type */
98 guint8 ph_RecordSize[2]; /* Record Size including header */
100 #define nspr_header_v10_s ((guint32)sizeof(nspr_header_v10_t))
102 /* This is V20 short header (2 bytes long) to be included where needed */
103 #define NSPR_HEADER_V20(prefix) \
104 guint8 prefix##_RecordType; /* Record Type */ \
105 guint8 prefix##_RecordSize /* Record Size including header */ \
106 /* end of declaration */
108 /* This is new long header (3 bytes long) to be included where needed */
109 #define NSPR_HEADER3B_V20(prefix) \
110 guint8 prefix##_RecordType; /* Record Type */ \
111 guint8 prefix##_RecordSizeLow; /* Record Size including header */ \
112 guint8 prefix##_RecordSizeHigh /* Record Size including header */ \
113 /* end of declaration */
114 #define NSPR_HEADER3B_V21 NSPR_HEADER3B_V20
115 #define NSPR_HEADER3B_V22 NSPR_HEADER3B_V20
116 #define NSPR_HEADER3B_V30 NSPR_HEADER3B_V20
118 typedef struct nspr_hd_v20
120 NSPR_HEADER3B_V20(phd); /* long performance header */
123 #define nspr_hd_v20_s ((guint32)sizeof(nspr_hd_v20_t))
127 ** How to know if header size is short or long?
128 ** The short header size can be 0-127 bytes long. If MS Bit of ph_RecordSize
129 ** is set then record size has 2 bytes
131 #define NSPR_V20RECORDSIZE_2BYTES 0x80U
133 /* Performance Data Header with device number */
134 typedef struct nspr_headerdev_v10
136 guint8 ph_RecordType[2]; /* Record Type */
137 guint8 ph_RecordSize[2]; /* Record Size including header */
138 guint8 ph_DevNo[4]; /* Network Device (NIC/CONN) number */
139 } nspr_headerdev_v10_t;
140 #define nspr_headerdev_v10_s ((guint32)sizeof(nspr_headerdev_v10_t))
142 typedef struct nspr_hd_v10
144 nspr_header_v10_t phd; /* performance header */
146 #define nspr_hd_v10_s ((guint32)sizeof(nspr_hd_v10_t))
148 typedef struct nspr_hdev_v10
150 nspr_headerdev_v10_t phd; /* performance header */
152 #define nspr_hdev_v10_s ((guint32)sizeof(nspr_hdev_v10_t))
154 /* if structure has defined phd as first field, it can use following names */
155 #define nsprRecordType phd.ph_RecordType
156 #define nsprRecordSize phd.ph_RecordSize
157 #define nsprReserved phd.ph_Reserved
158 #define nsprRecordTypeOrg phd.ph_Reserved
159 #define nsprDevNo phd.ph_DevNo
161 /* NSPR_SIGNATURE_V10 structure */
162 #define NSPR_SIGSIZE_V10 56 /* signature value size in bytes */
163 typedef struct nspr_signature_v10
165 nspr_header_v10_t phd; /* performance header */
166 guint8 sig_EndianType; /* Endian Type for the data */
167 guint8 sig_Reserved0;
168 guint8 sig_Reserved1[2];
169 gchar sig_Signature[NSPR_SIGSIZE_V10]; /* Signature value */
170 } nspr_signature_v10_t;
171 #define nspr_signature_v10_s ((guint32)sizeof(nspr_signature_v10_t))
173 /* NSPR_SIGNATURE_V20 structure */
174 #define NSPR_SIGSIZE_V20 sizeof(NSPR_SIGSTR_V20) /* signature value size in bytes */
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[NSPR_SIGSIZE_V20]; /* Signature value */
180 } nspr_signature_v20_t;
181 #define nspr_signature_v20_s ((guint32)sizeof(nspr_signature_v20_t))
183 /* NSPR_SIGNATURE_V30 structure */
184 #define NSPR_SIGSIZE_V30 sizeof(NSPR_SIGSTR_V30) /* signature value size in bytes */
185 typedef struct nspr_signature_v30
187 NSPR_HEADER_V20(sig); /* short performance header */
188 guint8 sig_EndianType; /* Endian Type for the data */
189 gchar sig_Signature[NSPR_SIGSIZE_V30]; /* Signature value */
190 } nspr_signature_v30_t;
191 #define nspr_signature_v30_s ((guint32)sizeof(nspr_signature_v30_t))
193 #define NSPR_SIGSIZE_V35 sizeof(NSPR_SIGSTR_V35) /* signature value size in bytes */
194 typedef struct nspr_signature_v35
196 NSPR_HEADER_V20(sig); /* short performance header */
197 guint8 sig_EndianType; /* Endian Type for the data */
198 gchar sig_Signature[NSPR_SIGSIZE_V35]; /* Signature value */
199 } nspr_signature_v35_t;
200 #define nspr_signature_v35_s ((guint32)sizeof(nspr_signature_v35_t))
202 /* NSPR_ABSTIME_V10 and NSPR_SYSTARTIME_V10 structure */
203 typedef struct nspr_abstime_v10
205 nspr_header_v10_t phd; /* performance header */
206 guint8 abs_RelTime[4]; /* relative time is ms from last time */
207 guint8 abs_Time[4]; /* absolute time in seconds from 1970 */
208 } nspr_abstime_v10_t;
209 #define nspr_abstime_v10_s ((guint32)sizeof(nspr_abstime_v10_t))
212 /* NSPR_ABSTIME_V20 and NSPR_SYSTARTIME_V20 structure */
213 typedef struct nspr_abstime_v20
215 NSPR_HEADER_V20(abs); /* short performance header */
216 guint8 abs_RelTime[2]; /* relative time is ms from last time */
217 guint8 abs_Time[4]; /* absolute time in seconds from 1970 */
218 } nspr_abstime_v20_t;
219 #define nspr_abstime_v20_s ((guint32)sizeof(nspr_abstime_v20_t))
223 /* full packet trace structure */
224 typedef struct nspr_pktracefull_v10
226 nspr_headerdev_v10_t phd; /* performance header */
227 guint8 fp_RelTimeHr[4]; /* High resolution relative time */
228 } nspr_pktracefull_v10_t;
229 #define nspr_pktracefull_v10_s ((guint32)(sizeof(nspr_pktracefull_v10_t)))
231 /* new full packet trace structure v20 */
232 typedef struct nspr_pktracefull_v20
234 NSPR_HEADER3B_V20(fp); /* long performance header */
235 guint8 fp_DevNo; /* Network Device (NIC) number */
236 guint8 fp_RelTimeHr[4]; /* High resolution relative time */
237 } nspr_pktracefull_v20_t;
238 #define nspr_pktracefull_v20_s ((guint32)(sizeof(nspr_pktracefull_v20_t)))
240 /* new full packet trace structure v21 */
241 typedef struct nspr_pktracefull_v21
243 NSPR_HEADER3B_V21(fp); /* long performance header */
244 guint8 fp_DevNo; /* Network Device (NIC) number */
245 guint8 fp_RelTimeHr[4]; /* High resolution relative time */
246 guint8 fp_PcbDevNo[4]; /* PCB devno */
247 guint8 fp_lPcbDevNo[4]; /* link PCB devno */
248 } nspr_pktracefull_v21_t;
249 #define nspr_pktracefull_v21_s ((guint32)(sizeof(nspr_pktracefull_v21_t)))
251 /* new full packet trace structure v22 */
252 typedef struct nspr_pktracefull_v22
254 NSPR_HEADER3B_V22(fp); /* long performance header */
255 guint8 fp_DevNo; /* Network Device (NIC) number */
256 guint8 fp_RelTimeHr[4]; /* High resolution relative time */
257 guint8 fp_PcbDevNo[4]; /* PCB devno */
258 guint8 fp_lPcbDevNo[4]; /* link PCB devno */
259 guint8 fp_VlanTag[2]; /* vlan tag */
260 } nspr_pktracefull_v22_t;
261 #define nspr_pktracefull_v22_s ((guint32)(sizeof(nspr_pktracefull_v22_t)))
263 typedef struct nspr_pktracefull_v23
265 NSPR_HEADER3B_V22(fp); /* long performance header */
266 guint8 fp_DevNo; /* Network Device (NIC) number */
267 guint8 fp_AbsTimeHr[8]; /* High resolution absolute time */
268 guint8 fp_PcbDevNo[4]; /* PCB devno */
269 guint8 fp_lPcbDevNo[4]; /* link PCB devno */
270 guint8 fp_VlanTag[2]; /* vlan tag */
271 guint8 fp_Coreid[2]; /* coreid of the packet */
272 } nspr_pktracefull_v23_t;
273 #define nspr_pktracefull_v23_s ((guint32)(sizeof(nspr_pktracefull_v23_t)))
275 /* New full packet trace structure v24 for cluster tracing */
276 typedef struct nspr_pktracefull_v24
278 NSPR_HEADER3B_V22(fp); /* long performance header */
279 guint8 fp_DevNo; /* Network Device (NIC) number */
280 guint8 fp_AbsTimeHr[8]; /* High resolution absolute time in nanosec */
281 guint8 fp_PcbDevNo[4]; /* PCB devno */
282 guint8 fp_lPcbDevNo[4]; /* link PCB devno */
283 guint8 fp_VlanTag[2]; /* vlan tag */
284 guint8 fp_Coreid[2]; /* coreid of the packet */
285 guint8 fp_srcNodeId[2]; /* source node # */
286 guint8 fp_destNodeId[2]; /* destination node # */
287 guint8 fp_clFlags; /* cluster flags */
288 } nspr_pktracefull_v24_t;
289 #define nspr_pktracefull_v24_s ((guint32)(sizeof(nspr_pktracefull_v24_t)))
291 /* New full packet trace structure v25 for vm info tracing */
292 typedef struct nspr_pktracefull_v25
294 NSPR_HEADER3B_V22(fp); /* long performance header */
295 guint8 fp_DevNo; /* Network Device (NIC) number */
296 guint8 fp_AbsTimeHr[8]; /* High resolution absolute time in nanosec */
297 guint8 fp_PcbDevNo[4]; /* PCB devno */
298 guint8 fp_lPcbDevNo[4]; /* link PCB devno */
299 guint8 fp_VlanTag[2]; /* vlan tag */
300 guint8 fp_Coreid[2]; /* coreid of the packet */
301 guint8 fp_srcNodeId[2]; /* source node # */
302 guint8 fp_destNodeId[2]; /* destination node # */
303 guint8 fp_clFlags; /* cluster flags */
304 guint8 fp_src_vmname_len; /* vm src info */
305 guint8 fp_dst_vmname_len; /* vm src info */
306 } nspr_pktracefull_v25_t;
307 #define nspr_pktracefull_v25_s ((guint32)(sizeof(nspr_pktracefull_v25_t)))
309 /* New full packet trace structure v26 for vm info tracing */
310 typedef struct nspr_pktracefull_v26
312 NSPR_HEADER3B_V22(fp); /* long performance header */
313 guint8 fp_DevNo; /* Network Device (NIC) number */
314 guint8 fp_AbsTimeHr[8]; /* High resolution absolute time in nanosec */
315 guint8 fp_PcbDevNo[4]; /* PCB devno */
316 guint8 fp_lPcbDevNo[4]; /* link PCB devno */
317 guint8 fp_VlanTag[2]; /* vlan tag */
318 guint8 fp_Coreid[2]; /* coreid of the packet */
319 guint8 fp_srcNodeId[2]; /* source node # */
320 guint8 fp_destNodeId[2]; /* destination node # */
321 guint8 fp_clFlags; /* cluster flags */
322 guint8 fp_src_vmname_len; /* vm src info */
323 guint8 fp_dst_vmname_len; /* vm src info */
325 guint8 fp_ns_activity[4];
326 guint8 fp_reserved_32[12]; /* Adding more field to reduce wireshark changes every time */
327 } nspr_pktracefull_v26_t;
328 #define nspr_pktracefull_v26_s ((guint32)(sizeof(nspr_pktracefull_v26_t)))
330 /* partial packet trace structure */
331 typedef struct nspr_pktracepart_v10
333 nspr_headerdev_v10_t phd; /* performance header */
334 guint8 pp_RelTimeHr[4]; /* High resolution relative time */
335 guint8 pp_PktSizeOrg[2]; /* Original packet size */
336 guint8 pp_PktOffset[2]; /* starting offset in packet */
337 } nspr_pktracepart_v10_t;
338 #define nspr_pktracepart_v10_s ((guint32)(sizeof(nspr_pktracepart_v10_t)))
340 /* new partial packet trace structure */
341 typedef struct nspr_pktracepart_v20
343 NSPR_HEADER3B_V20(pp); /* long performance header */
344 guint8 pp_DevNo; /* Network Device (NIC) number */
345 guint8 pp_RelTimeHr[4]; /* High resolution relative time */
346 guint8 pp_PktSizeOrg[2]; /* Original packet size */
347 guint8 pp_PktOffset[2]; /* starting offset in packet */
348 } nspr_pktracepart_v20_t;
349 #define nspr_pktracepart_v20_s ((guint32)(sizeof(nspr_pktracepart_v20_t)))
351 /* new partial packet trace structure */
352 typedef struct nspr_pktracepart_v21
354 NSPR_HEADER3B_V21(pp); /* long performance header */
355 guint8 pp_DevNo; /* Network Device (NIC) number */
356 guint8 pp_RelTimeHr[4]; /* High resolution relative time */
357 guint8 pp_PktSizeOrg[2]; /* Original packet size */
358 guint8 pp_PktOffset[2]; /* starting offset in packet */
359 guint8 pp_PcbDevNo[4]; /* PCB devno */
360 guint8 pp_lPcbDevNo[4]; /* link PCB devno */
361 } nspr_pktracepart_v21_t;
362 #define nspr_pktracepart_v21_s ((guint32)(sizeof(nspr_pktracepart_v21_t)))
364 /* new partial packet trace structure v22 */
365 typedef struct nspr_pktracepart_v22
367 NSPR_HEADER3B_V22(pp); /* long performance header */
368 guint8 pp_DevNo; /* Network Device (NIC) number */
369 guint8 pp_RelTimeHr[4]; /* High resolution relative time */
370 guint8 pp_PktSizeOrg[2]; /* Original packet size */
371 guint8 pp_PktOffset[2]; /* starting offset in packet */
372 guint8 pp_PcbDevNo[4]; /* PCB devno */
373 guint8 pp_lPcbDevNo[4]; /* link PCB devno */
374 guint8 pp_VlanTag[2]; /* Vlan Tag */
375 } nspr_pktracepart_v22_t;
376 #define nspr_pktracepart_v22_s ((guint32)(sizeof(nspr_pktracepart_v22_t)))
378 typedef struct nspr_pktracepart_v23
380 NSPR_HEADER3B_V22(pp); /* long performance header */
381 guint8 pp_DevNo; /* Network Device (NIC) number */
382 guint8 pp_AbsTimeHr[8]; /* High resolution absolute time */
383 guint8 pp_PktSizeOrg[2]; /* Original packet size */
384 guint8 pp_PktOffset[2]; /* starting offset in packet */
385 guint8 pp_PcbDevNo[4]; /* PCB devno */
386 guint8 pp_lPcbDevNo[4]; /* link PCB devno */
387 guint8 pp_VlanTag[2]; /* vlan tag */
388 guint8 pp_Coreid[2]; /* Coreid of the packet */
389 } nspr_pktracepart_v23_t;
390 #define nspr_pktracepart_v23_s ((guint32)(sizeof(nspr_pktracepart_v23_t)))
392 /* New partial packet trace structure v24 for cluster tracing */
393 typedef struct nspr_pktracepart_v24
395 NSPR_HEADER3B_V22(pp); /* long performance header */
396 guint8 pp_DevNo; /* Network Device (NIC) number */
397 guint8 pp_AbsTimeHr[8]; /*High resolution absolute time in nanosec*/
398 guint8 pp_PktSizeOrg[2]; /* Original packet size */
399 guint8 pp_PktOffset[2]; /* starting offset in packet */
400 guint8 pp_PcbDevNo[4]; /* PCB devno */
401 guint8 pp_lPcbDevNo[4]; /* link PCB devno */
402 guint8 pp_VlanTag[2]; /* vlan tag */
403 guint8 pp_Coreid[2]; /* Coreid of the packet */
404 guint8 pp_srcNodeId[2]; /* source node # */
405 guint8 pp_destNodeId[2]; /* destination node # */
406 guint8 pp_clFlags; /* cluster flags */
407 } nspr_pktracepart_v24_t;
408 #define nspr_pktracepart_v24_s ((guint32)(sizeof(nspr_pktracepart_v24_t)))
410 /* New partial packet trace structure v25 for vm info tracing */
411 typedef struct nspr_pktracepart_v25
413 NSPR_HEADER3B_V22(pp); /* long performance header */
414 guint8 pp_DevNo; /* Network Device (NIC) number */
415 guint8 pp_AbsTimeHr[8]; /*High resolution absolute time in nanosec*/
416 guint8 pp_PktSizeOrg[2]; /* Original packet size */
417 guint8 pp_PktOffset[2]; /* starting offset in packet */
418 guint8 pp_PcbDevNo[4]; /* PCB devno */
419 guint8 pp_lPcbDevNo[4]; /* link PCB devno */
420 guint8 pp_VlanTag[2]; /* vlan tag */
421 guint8 pp_Coreid[2]; /* Coreid of the packet */
422 guint8 pp_srcNodeId[2]; /* source node # */
423 guint8 pp_destNodeId[2]; /* destination node # */
424 guint8 pp_clFlags; /* cluster flags */
425 guint8 pp_src_vmname_len; /* vm info */
426 guint8 pp_dst_vmname_len; /* vm info */
427 } nspr_pktracepart_v25_t;
428 #define nspr_pktracepart_v25_s ((guint32)(sizeof(nspr_pktracepart_v25_t)))
430 /* New full packet trace structure v30 for multipage spanning data */
431 typedef struct nspr_pktracefull_v30
433 NSPR_HEADER3B_V30(fp); /* long performance header */
434 guint8 fp_DevNo; /* Network Device (NIC) number */
435 guint8 fp_AbsTimeHr[8]; /*High resolution absolute time in nanosec*/
436 guint8 fp_PcbDevNo[4]; /* PCB devno */
437 guint8 fp_lPcbDevNo[4]; /* link PCB devno */
438 guint8 fp_PktSizeOrg[2]; /* Original packet size */
439 guint8 fp_VlanTag[2]; /* vlan tag */
440 guint8 fp_Coreid[2]; /* coreid of the packet */
441 guint8 fp_srcNodeId[2]; /* cluster nodeid of the packet */
442 guint8 fp_destNodeId[2];
444 guint8 fp_src_vmname_len;
445 guint8 fp_dst_vmname_len;
446 guint8 fp_reserved[3];
447 guint8 fp_ns_activity[4];
448 guint8 fp_reserved_32[12];
449 } nspr_pktracefull_v30_t;
450 #define nspr_pktracefull_v30_s ((guint32)(sizeof(nspr_pktracefull_v30_t)))
452 /* New full packet trace structure v35 for multipage spanning data */
453 typedef struct nspr_pktracefull_v35
455 NSPR_HEADER3B_V30(fp); /* long performance header */
456 guint8 fp_DevNo; /* Network Device (NIC) number */
457 guint8 fp_AbsTimeHr[8]; /*High resolution absolute time in nanosec*/
458 guint8 fp_PcbDevNo[4]; /* PCB devno */
459 guint8 fp_lPcbDevNo[4]; /* link PCB devno */
460 guint8 fp_PktSizeOrg[2]; /* Original packet size */
461 guint8 fp_VlanTag[2]; /* vlan tag */
462 guint8 fp_Coreid[2]; /* coreid of the packet */
463 guint8 fp_headerlen[2];
466 guint8 fp_ns_activity[4];
467 guint8 fp_nextrectype;
468 } nspr_pktracefull_v35_t;
469 #define nspr_pktracefull_v35_s ((guint32)(sizeof(nspr_pktracefull_v35_t)))
471 /* New partial packet trace structure v26 for vm info tracing */
472 typedef struct nspr_pktracepart_v26
474 NSPR_HEADER3B_V22(pp); /* long performance header */
475 guint8 pp_DevNo; /* Network Device (NIC) number */
476 guint8 pp_AbsTimeHr[8]; /*High resolution absolute time in nanosec*/
477 guint8 pp_PktSizeOrg[2]; /* Original packet size */
478 guint8 pp_PktOffset[2]; /* starting offset in packet */
479 guint8 pp_PcbDevNo[4]; /* PCB devno */
480 guint8 pp_lPcbDevNo[4]; /* link PCB devno */
481 guint8 pp_VlanTag[2]; /* vlan tag */
482 guint8 pp_Coreid[2]; /* Coreid of the packet */
483 guint8 pp_srcNodeId[2]; /* source node # */
484 guint8 pp_destNodeId[2]; /* destination node # */
485 guint8 pp_clFlags; /* cluster flags */
486 guint8 pp_src_vmname_len; /* vm info */
487 guint8 pp_dst_vmname_len; /* vm info */
489 guint8 pp_ns_activity[4];
490 guint8 pp_reserved_32[12]; /* Adding more field to reduce wireshark changes every time */
491 } nspr_pktracepart_v26_t;
492 #define nspr_pktracepart_v26_s ((guint32)(sizeof(nspr_pktracepart_v26_t)))
494 #define __TNDO(phdr,enumprefix,structname,hdrname)\
495 static const guint8 enumprefix##_##hdrname##_offset = (guint8)sizeof(nspr_##structname##_t);
497 #define __TNO(phdr,enumprefix,structprefix,structname,hdrname,structfieldname) \
498 static const guint8 enumprefix##_##hdrname##_offset = (guint8)GPOINTER_TO_INT(offsetof(nspr_##structname##_t,structprefix##_##structfieldname));
500 #define __TNL(phdr,enumprefix,structprefix,structname,hdrname,structfieldname) \
501 static const guint8 enumprefix##_##hdrname##_len = (guint8)sizeof(((nspr_##structname##_t*)0)->structprefix##_##structfieldname);
503 #define __TNV1O(phdr,enumprefix,structprefix,structname,hdrname,structfieldname) \
504 static const guint8 enumprefix##_##hdrname##_offset = (guint8)GPOINTER_TO_INT(offsetof(nspr_##structname##_t,structfieldname));
506 #define __TNV1L(phdr,enumprefix,structprefix,structname,hdrname,structfieldname) \
507 static const guint8 enumprefix##_##hdrname##_len = (guint8)sizeof(((nspr_##structname##_t*)0)->structfieldname);
509 #define TRACE_V10_REC_LEN_OFF(phdr,enumprefix,structprefix,structname) \
510 __TNV1O(phdr,enumprefix,structprefix,structname,dir,phd.ph_RecordType)\
511 __TNV1L(phdr,enumprefix,structprefix,structname,dir,phd.ph_RecordType)\
512 __TNV1O(phdr,enumprefix,structprefix,structname,nicno,phd.ph_DevNo)\
513 __TNV1L(phdr,enumprefix,structprefix,structname,nicno,phd.ph_DevNo)\
514 __TNDO(phdr,enumprefix,structname,eth)
516 #define TRACE_V20_REC_LEN_OFF(phdr,enumprefix,structprefix,structname) \
517 __TNO(phdr,enumprefix,structprefix,structname,dir,RecordType)\
518 __TNL(phdr,enumprefix,structprefix,structname,dir,RecordType)\
519 __TNO(phdr,enumprefix,structprefix,structname,nicno,DevNo)\
520 __TNL(phdr,enumprefix,structprefix,structname,nicno,DevNo)\
521 __TNDO(phdr,enumprefix,structname,eth)
523 #define TRACE_V21_REC_LEN_OFF(phdr,enumprefix,structprefix,structname) \
524 TRACE_V20_REC_LEN_OFF(phdr,enumprefix,structprefix,structname)\
525 __TNO(phdr,enumprefix,structprefix,structname,pcb,PcbDevNo)\
526 __TNO(phdr,enumprefix,structprefix,structname,l_pcb,lPcbDevNo)
528 #define TRACE_V22_REC_LEN_OFF(phdr,enumprefix,structprefix,structname) \
529 TRACE_V21_REC_LEN_OFF(phdr,enumprefix,structprefix,structname)\
530 __TNO(phdr,enumprefix,structprefix,structname,vlantag,VlanTag)
532 #define TRACE_V23_REC_LEN_OFF(phdr,enumprefix,structprefix,structname) \
533 TRACE_V22_REC_LEN_OFF(phdr,enumprefix,structprefix,structname)\
534 __TNO(phdr,enumprefix,structprefix,structname,coreid,Coreid)
536 #define TRACE_V24_REC_LEN_OFF(phdr,enumprefix,structprefix,structname) \
537 TRACE_V23_REC_LEN_OFF(phdr,enumprefix,structprefix,structname)\
538 __TNO(phdr,enumprefix,structprefix,structname,srcnodeid,srcNodeId)\
539 __TNO(phdr,enumprefix,structprefix,structname,destnodeid,destNodeId)\
540 __TNO(phdr,enumprefix,structprefix,structname,clflags,clFlags)
542 #define TRACE_V25_REC_LEN_OFF(phdr,enumprefix,structprefix,structname) \
543 TRACE_V24_REC_LEN_OFF(phdr,enumprefix,structprefix,structname)\
544 __TNO(phdr,enumprefix,structprefix,structname,src_vmname_len,src_vmname_len)\
545 __TNO(phdr,enumprefix,structprefix,structname,dst_vmname_len,dst_vmname_len)\
546 __TNDO(phdr,enumprefix,structname,data)
548 #define TRACE_V26_REC_LEN_OFF(phdr,enumprefix,structprefix,structname) \
549 TRACE_V25_REC_LEN_OFF(phdr,enumprefix,structprefix,structname)\
550 __TNO(phdr,enumprefix,structprefix,structname,ns_activity,ns_activity)\
552 #define TRACE_V30_REC_LEN_OFF(phdr, enumprefix, structprefix, structname) \
553 TRACE_V26_REC_LEN_OFF(phdr,enumprefix,structprefix,structname)\
555 #define TRACE_V35_REC_LEN_OFF(phdr, enumprefix, structprefix, structname) \
556 TRACE_V23_REC_LEN_OFF(phdr,enumprefix,structprefix,structname)\
557 __TNDO(phdr,enumprefix,structname,data)\
558 __TNO(phdr,enumprefix,structprefix,structname,ns_activity,ns_activity)
560 TRACE_V10_REC_LEN_OFF(NULL,v10_part,pp,pktracepart_v10)
561 TRACE_V10_REC_LEN_OFF(NULL,v10_full,fp,pktracefull_v10)
562 TRACE_V20_REC_LEN_OFF(NULL,v20_part,pp,pktracepart_v20)
563 TRACE_V20_REC_LEN_OFF(NULL,v20_full,fp,pktracefull_v20)
564 TRACE_V21_REC_LEN_OFF(NULL,v21_part,pp,pktracepart_v21)
565 TRACE_V21_REC_LEN_OFF(NULL,v21_full,fp,pktracefull_v21)
566 TRACE_V22_REC_LEN_OFF(NULL,v22_part,pp,pktracepart_v22)
567 TRACE_V22_REC_LEN_OFF(NULL,v22_full,fp,pktracefull_v22)
568 TRACE_V23_REC_LEN_OFF(NULL,v23_part,pp,pktracepart_v23)
569 TRACE_V23_REC_LEN_OFF(NULL,v23_full,fp,pktracefull_v23)
570 TRACE_V24_REC_LEN_OFF(NULL,v24_part,pp,pktracepart_v24)
571 TRACE_V24_REC_LEN_OFF(NULL,v24_full,fp,pktracefull_v24)
572 TRACE_V25_REC_LEN_OFF(NULL,v25_part,pp,pktracepart_v25)
573 TRACE_V25_REC_LEN_OFF(NULL,v25_full,fp,pktracefull_v25)
574 TRACE_V26_REC_LEN_OFF(NULL,v26_part,pp,pktracepart_v26)
575 TRACE_V26_REC_LEN_OFF(NULL,v26_full,fp,pktracefull_v26)
576 TRACE_V30_REC_LEN_OFF(NULL,v30_full,fp,pktracefull_v30)
577 TRACE_V35_REC_LEN_OFF(NULL,v35_full,fp,pktracefull_v35)
586 #define ns_setabstime(nstrace, AbsoluteTime, RelativeTimems) \
588 (nstrace)->nspm_curtime = AbsoluteTime; \
589 (nstrace)->nspm_curtimemsec += RelativeTimems; \
590 (nstrace)->nspm_curtimelastmsec = nstrace->nspm_curtimemsec; \
594 #define ns_setrelativetime(nstrace, RelativeTimems) \
597 (nstrace)->nspm_curtimemsec += RelativeTimems; \
598 rsec = (guint32)((nstrace)->nspm_curtimemsec - (nstrace)->nspm_curtimelastmsec)/1000; \
599 (nstrace)->nspm_curtime += rsec; \
600 (nstrace)->nspm_curtimelastmsec += rsec * 1000; \
607 guint32 nstrace_buf_offset;
608 guint32 nstrace_buflen;
609 /* Performance Monitor Time variables */
610 guint32 nspm_curtime; /* current time since 1970 */
611 guint64 nspm_curtimemsec; /* current time in milliseconds */
612 guint64 nspm_curtimelastmsec; /* nspm_curtime last update time in milliseconds */
613 guint64 nsg_creltime;
617 static guint32 nspm_signature_version(wtap*, gchar*, gint32);
618 static gboolean nstrace_read_v10(wtap *wth, int *err, gchar **err_info,
619 gint64 *data_offset);
620 static gboolean nstrace_read_v20(wtap *wth, int *err, gchar **err_info,
621 gint64 *data_offset);
622 static gboolean nstrace_read_v30(wtap *wth, int *err, gchar **err_info,
623 gint64 *data_offset);
624 static gboolean nstrace_seek_read_v10(wtap *wth, gint64 seek_off,
625 struct wtap_pkthdr *phdr,
627 int *err, gchar **err_info);
628 static gboolean nstrace_seek_read_v20(wtap *wth, gint64 seek_off,
629 struct wtap_pkthdr *phdr,
631 int *err, gchar **err_info);
632 static gboolean nstrace_seek_read_v30(wtap *wth, gint64 seek_off,
633 struct wtap_pkthdr *phdr,
635 int *err, gchar **err_info);
636 static void nstrace_close(wtap *wth);
638 static gboolean nstrace_set_start_time_v10(wtap *wth, int *err,
640 static gboolean nstrace_set_start_time_v20(wtap *wth, int *err,
642 static gboolean nstrace_set_start_time(wtap *wth, int *err, gchar **err_info);
643 static guint64 ns_hrtime2nsec(guint32 tm);
645 static gboolean nstrace_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
646 const guint8 *pd, int *err, gchar **err_info);
650 * Minimum of the page size and the amount of data left in the file;
651 * the last page of a file can be short.
653 #define GET_READ_PAGE_SIZE(remaining_file_size) ((gint32)((remaining_file_size>NSPR_PAGESIZE)?NSPR_PAGESIZE:remaining_file_size))
654 #define GET_READ_PAGE_SIZEV3(remaining_file_size) ((gint32)((remaining_file_size>NSPR_PAGESIZE_TRACE)?NSPR_PAGESIZE_TRACE:remaining_file_size))
656 static guint64 ns_hrtime2nsec(guint32 tm)
658 guint32 val = tm & NSPR_HRTIME_MASKTM;
659 switch(tm & NSPR_HRTIME_MASKFMT)
661 case NSPR_HRTIME_SEC: return (guint64)val*1000000000;
662 case NSPR_HRTIME_MSEC: return (guint64)val*1000000;
663 case NSPR_HRTIME_USEC: return (guint64)val*1000;
664 case NSPR_HRTIME_NSEC: return val;
670 nstrace_read_buf(FILE_T fh, void *buf, guint32 buflen, int *err,
675 bytes_read = file_read(buf, buflen, fh);
676 if (bytes_read < 0) {
677 *err = file_error(fh, err_info);
680 if ((guint32)bytes_read != buflen) {
682 * XXX - for which files can the last page be short?
691 ** Netscaler trace format open routines
693 wtap_open_return_val nstrace_open(wtap *wth, int *err, gchar **err_info)
701 if ((file_size = wtap_file_size(wth, err)) == -1)
702 return WTAP_OPEN_NOT_MINE;
704 nstrace_buf = (gchar *)g_malloc(NSPR_PAGESIZE);
705 page_size = GET_READ_PAGE_SIZE(file_size);
707 switch ((wth->file_type_subtype = nspm_signature_version(wth, nstrace_buf, page_size)))
709 case WTAP_FILE_TYPE_SUBTYPE_NETSCALER_1_0:
710 wth->file_encap = WTAP_ENCAP_NSTRACE_1_0;
713 case WTAP_FILE_TYPE_SUBTYPE_NETSCALER_2_0:
714 wth->file_encap = WTAP_ENCAP_NSTRACE_2_0;
717 case WTAP_FILE_TYPE_SUBTYPE_NETSCALER_3_0:
718 wth->file_encap = WTAP_ENCAP_NSTRACE_3_0;
720 nstrace_buf = (gchar *)g_malloc(NSPR_PAGESIZE_TRACE);
721 page_size = GET_READ_PAGE_SIZEV3(file_size);
724 case WTAP_FILE_TYPE_SUBTYPE_NETSCALER_3_5:
725 wth->file_encap = WTAP_ENCAP_NSTRACE_3_5;
727 nstrace_buf = (gchar *)g_malloc(NSPR_PAGESIZE_TRACE);
728 page_size = GET_READ_PAGE_SIZEV3(file_size);
732 /* No known signature found, assume it's not NetScaler */
734 return WTAP_OPEN_NOT_MINE;
737 if ((file_seek(wth->fh, 0, SEEK_SET, err)) == -1)
740 return WTAP_OPEN_ERROR;
743 if (!wtap_read_bytes(wth->fh, nstrace_buf, page_size, err, err_info))
746 if (*err != WTAP_ERR_SHORT_READ)
747 return WTAP_OPEN_ERROR;
748 return WTAP_OPEN_NOT_MINE;
751 switch (wth->file_type_subtype)
753 case WTAP_FILE_TYPE_SUBTYPE_NETSCALER_1_0:
754 wth->subtype_read = nstrace_read_v10;
755 wth->subtype_seek_read = nstrace_seek_read_v10;
758 case WTAP_FILE_TYPE_SUBTYPE_NETSCALER_2_0:
759 wth->subtype_read = nstrace_read_v20;
760 wth->subtype_seek_read = nstrace_seek_read_v20;
763 case WTAP_FILE_TYPE_SUBTYPE_NETSCALER_3_0:
764 wth->subtype_read = nstrace_read_v30;
765 wth->subtype_seek_read = nstrace_seek_read_v30;
768 case WTAP_FILE_TYPE_SUBTYPE_NETSCALER_3_5:
769 wth->subtype_read = nstrace_read_v30;
770 wth->subtype_seek_read = nstrace_seek_read_v30;
773 wth->subtype_close = nstrace_close;
775 nstrace = (nstrace_t *)g_malloc(sizeof(nstrace_t));
776 wth->priv = (void *)nstrace;
777 nstrace->pnstrace_buf = nstrace_buf;
778 nstrace->xxx_offset = 0;
779 nstrace->nstrace_buflen = page_size;
780 nstrace->nstrace_buf_offset = 0;
781 nstrace->nspm_curtime = 0;
782 nstrace->nspm_curtimemsec = 0;
783 nstrace->nspm_curtimelastmsec = 0;
784 nstrace->nsg_creltime = 0;
785 nstrace->file_size = file_size;
788 /* Set the start time by looking for the abstime record */
789 if ((nstrace_set_start_time(wth, err, err_info)) == FALSE)
792 * No absolute time record seen, so we just reset the read
793 * pointer to the start of the file, so we start reading
794 * at the first record, rather than skipping records up
795 * to and including an absolute time record.
799 /* We got an error reading the records. */
800 return WTAP_OPEN_ERROR;
802 if ((file_seek(wth->fh, 0, SEEK_SET, err)) == -1)
804 return WTAP_OPEN_ERROR;
807 /* Read the first page of data */
808 if (!wtap_read_bytes(wth->fh, nstrace_buf, page_size, err, err_info))
810 return WTAP_OPEN_ERROR;
813 /* reset the buffer offset */
814 nstrace->nstrace_buf_offset = 0;
817 wth->file_tsprec = WTAP_TSPREC_NSEC;
818 wth->phdr.ts.secs = nstrace->nspm_curtime;
819 wth->phdr.ts.nsecs = 0;
822 return WTAP_OPEN_MINE;
826 #define nspm_signature_func(ver) \
827 static guint32 nspm_signature_isv##ver(gchar *sigp) {\
828 return strncmp(sigp,NSPR_SIGSTR_V##ver,(sizeof(NSPR_SIGSTR_V##ver)-1));\
831 nspm_signature_func(10)
832 nspm_signature_func(20)
833 nspm_signature_func(30)
834 nspm_signature_func(35)
837 ** Check signature and return the file type and subtype for files with
838 ** that signature. If it finds no signature that it recognizes, it
839 ** returns WTAP_FILE_TYPE_SUBTYPE_UNKNOWN. At the time of return from
840 ** this function we might not be at the first page. So after a call to
841 ** this function, there has to be a file seek to return to the start
842 ** of the first page.
845 nspm_signature_version(wtap *wth, gchar *nstrace_buf, gint32 len)
847 gchar *dp = nstrace_buf;
850 bytes_read = file_read(dp, len, wth->fh);
851 if (bytes_read == len) {
853 for ( ; len > (gint32)(MIN(sizeof(NSPR_SIGSTR_V10), sizeof(NSPR_SIGSTR_V20))); dp++, len--)
855 #define sigv10p ((nspr_signature_v10_t*)dp)
856 if ((pletoh16(&sigv10p->nsprRecordType) == NSPR_SIGNATURE_V10) &&
857 (pletoh16(&sigv10p->nsprRecordSize) <= len) &&
858 ((gint32)sizeof(NSPR_SIGSTR_V10) <= len) &&
859 (!nspm_signature_isv10(sigv10p->sig_Signature)))
860 return WTAP_FILE_TYPE_SUBTYPE_NETSCALER_1_0;
863 #define sigv20p ((nspr_signature_v20_t*)dp)
864 if ((sigv20p->sig_RecordType == NSPR_SIGNATURE_V20) &&
865 (sigv20p->sig_RecordSize <= len) &&
866 ((gint32)sizeof(NSPR_SIGSTR_V20) <= len))
868 if (!nspm_signature_isv20(sigv20p->sig_Signature)){
869 return WTAP_FILE_TYPE_SUBTYPE_NETSCALER_2_0;
870 } else if (!nspm_signature_isv30(sigv20p->sig_Signature)){
871 return WTAP_FILE_TYPE_SUBTYPE_NETSCALER_3_0;
872 }else if (!nspm_signature_isv35(sigv20p->sig_Signature)){
873 return WTAP_FILE_TYPE_SUBTYPE_NETSCALER_3_5;
880 return WTAP_FILE_TYPE_SUBTYPE_UNKNOWN; /* no version found */
883 #define nspr_getv10recordtype(hdp) (pletoh16(&(hdp)->nsprRecordType))
884 #define nspr_getv10recordsize(hdp) (pletoh16(&(hdp)->nsprRecordSize))
885 #define nspr_getv20recordtype(hdp) ((hdp)->phd_RecordType)
886 #define nspr_getv20recordsize(hdp) \
887 (guint32)(((hdp)->phd_RecordSizeLow & NSPR_V20RECORDSIZE_2BYTES)? \
888 (((hdp)->phd_RecordSizeHigh * NSPR_V20RECORDSIZE_2BYTES)+ \
889 ((hdp)->phd_RecordSizeLow & ~NSPR_V20RECORDSIZE_2BYTES)) : \
890 (hdp)->phd_RecordSizeLow)
893 #define nstrace_set_start_time_ver(ver) \
894 gboolean nstrace_set_start_time_v##ver(wtap *wth, int *err, gchar **err_info) \
896 nstrace_t *nstrace = (nstrace_t *)wth->priv;\
897 gchar* nstrace_buf = nstrace->pnstrace_buf;\
898 guint32 nstrace_buf_offset = nstrace->nstrace_buf_offset;\
899 guint32 nstrace_buflen = nstrace->nstrace_buflen;\
900 guint32 record_size;\
903 while (nstrace_buf_offset < nstrace_buflen)\
905 nspr_hd_v##ver##_t *fp = (nspr_hd_v##ver##_t *) &nstrace_buf[nstrace_buf_offset];\
906 switch (nspr_getv##ver##recordtype(fp))\
908 case NSPR_ABSTIME_V##ver:\
909 ns_setabstime(nstrace, pletoh32(&((nspr_abstime_v##ver##_t *) fp)->abs_Time), pletoh16(&((nspr_abstime_v##ver##_t *) fp)->abs_RelTime));\
910 nstrace->nstrace_buf_offset = nstrace_buf_offset + nspr_getv##ver##recordsize(fp);\
911 nstrace->nstrace_buflen = nstrace_buflen;\
913 case NSPR_UNUSEDSPACE_V10:\
914 nstrace_buf_offset = nstrace_buflen;\
917 record_size = nspr_getv##ver##recordsize(fp);\
918 if (record_size == 0) {\
919 *err = WTAP_ERR_BAD_FILE;\
920 *err_info = g_strdup("nstrace: zero size record found");\
923 nstrace_buf_offset += record_size;\
926 nstrace_buf_offset = 0;\
927 nstrace->xxx_offset += nstrace_buflen;\
928 nstrace_buflen = GET_READ_PAGE_SIZE((nstrace->file_size - nstrace->xxx_offset));\
929 }while((nstrace_buflen > 0) && (nstrace_read_buf(wth->fh, nstrace_buf, nstrace_buflen, err, err_info)));\
933 nstrace_set_start_time_ver(10)
934 nstrace_set_start_time_ver(20)
936 #undef nspr_getv10recordtype
937 #undef nspr_getv20recordtype
940 ** Set the start time of the trace file. We look for the first ABSTIME record. We use that
941 ** to set the start time. Apart from that we also make sure that we remember the position of
942 ** the next record after the ABSTIME record. Inorder to report correct time values, all trace
943 ** records before the ABSTIME record are ignored.
945 static gboolean nstrace_set_start_time(wtap *wth, int *err, gchar **err_info)
947 if (wth->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_1_0)
948 return nstrace_set_start_time_v10(wth, err, err_info);
949 else if (wth->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_2_0)
950 return nstrace_set_start_time_v20(wth, err, err_info);
951 else if (wth->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_3_0)
952 return nstrace_set_start_time_v20(wth, err, err_info);
956 #define __TNDO(phdr,enumprefix,structname,hdrname)\
957 (phdr)->pseudo_header.nstr.hdrname##_offset = enumprefix##_##hdrname##_offset;
959 #define __TNO(phdr,enumprefix,structprefix,structname,hdrname,structfieldname) \
960 (phdr)->pseudo_header.nstr.hdrname##_offset = enumprefix##_##hdrname##_offset;
962 #define __TNL(phdr,enumprefix,structprefix,structname,hdrname,structfieldname) \
963 (phdr)->pseudo_header.nstr.hdrname##_len = enumprefix##_##hdrname##_len;
965 #define __TNV1O(phdr,enumprefix,structprefix,structname,hdrname,structfieldname) \
966 __TNO(phdr,enumprefix,structprefix,structname,hdrname,structfieldname)
968 #define __TNV1L(phdr,enumprefix,structprefix,structname,hdrname,structfieldname) \
969 __TNL(phdr,enumprefix,structprefix,structname,hdrname,structfieldname)
974 ** Netscaler trace format read routines.
976 ** The maximum value of the record data size is 65535, which is less than
977 ** WTAP_MAX_PACKET_SIZE_STANDARD will ever be, so we don't need to check it.
979 #define TIMEDEFV10(phdr,fp,type) \
981 (phdr)->presence_flags = WTAP_HAS_TS;\
982 nsg_creltime += ns_hrtime2nsec(pletoh32(&type->type##_RelTimeHr));\
983 (phdr)->ts.secs = nstrace->nspm_curtime + (guint32) (nsg_creltime / 1000000000);\
984 (phdr)->ts.nsecs = (guint32) (nsg_creltime % 1000000000);\
987 #define PARTSIZEDEFV10(phdr,pp,ver) \
989 (phdr)->presence_flags |= WTAP_HAS_CAP_LEN;\
990 (phdr)->len = pletoh16(&pp->pp_PktSizeOrg) + nspr_pktracepart_v##ver##_s;\
991 (phdr)->caplen = pletoh16(&pp->nsprRecordSize);\
994 #define FULLSIZEDEFV10(phdr,fp,ver) \
996 (phdr)->len = pletoh16(&(fp)->nsprRecordSize);\
997 (phdr)->caplen = (phdr)->len;\
1000 #define PACKET_DESCRIBE(phdr,FULLPART,fullpart,ver,type,HEADERVER) \
1002 nspr_pktrace##fullpart##_v##ver##_t *type = (nspr_pktrace##fullpart##_v##ver##_t *) &nstrace_buf[nstrace_buf_offset];\
1003 /* Make sure the record header is entirely contained in the page */\
1004 if ((nstrace_buflen - nstrace_buf_offset) < sizeof *type) {\
1005 *err = WTAP_ERR_BAD_FILE;\
1006 *err_info = g_strdup("nstrace: record header crosses page boundary");\
1009 /* Check sanity of record size */\
1010 if (pletoh16(&type->nsprRecordSize) < sizeof *type) {\
1011 *err = WTAP_ERR_BAD_FILE;\
1012 *err_info = g_strdup("nstrace: record size is less than record header size");\
1015 (phdr)->rec_type = REC_TYPE_PACKET;\
1016 TIMEDEFV##ver((phdr),fp,type);\
1017 FULLPART##SIZEDEFV##ver((phdr),type,ver);\
1018 TRACE_V##ver##_REC_LEN_OFF((phdr),v##ver##_##fullpart,type,pktrace##fullpart##_v##ver);\
1019 /* Make sure the record is entirely contained in the page */\
1020 if ((nstrace_buflen - nstrace_buf_offset) < (phdr)->caplen) {\
1021 *err = WTAP_ERR_BAD_FILE;\
1022 *err_info = g_strdup("nstrace: record crosses page boundary");\
1025 ws_buffer_assure_space(wth->frame_buffer, (phdr)->caplen);\
1026 memcpy(ws_buffer_start_ptr(wth->frame_buffer), type, (phdr)->caplen);\
1027 *data_offset = nstrace->xxx_offset + nstrace_buf_offset;\
1028 nstrace->nstrace_buf_offset = nstrace_buf_offset + (phdr)->caplen;\
1029 nstrace->nstrace_buflen = nstrace_buflen;\
1030 nstrace->nsg_creltime = nsg_creltime;\
1034 static gboolean nstrace_read_v10(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
1036 nstrace_t *nstrace = (nstrace_t *)wth->priv;
1037 guint64 nsg_creltime = nstrace->nsg_creltime;
1038 gchar *nstrace_buf = nstrace->pnstrace_buf;
1039 guint32 nstrace_buf_offset = nstrace->nstrace_buf_offset;
1040 guint32 nstrace_buflen = nstrace->nstrace_buflen;
1046 while ((nstrace_buf_offset < nstrace_buflen) &&
1047 ((nstrace_buflen - nstrace_buf_offset) >= ((gint32)sizeof((( nspr_header_v10_t*)&nstrace_buf[nstrace_buf_offset])->ph_RecordType))))
1050 #define GENERATE_CASE_FULL(phdr,ver,HEADERVER) \
1051 case NSPR_PDPKTRACEFULLTX_V##ver:\
1052 case NSPR_PDPKTRACEFULLTXB_V##ver:\
1053 case NSPR_PDPKTRACEFULLRX_V##ver:\
1054 PACKET_DESCRIBE(phdr,FULL,full,ver,fp,HEADERVER);
1056 #define GENERATE_CASE_PART(phdr,ver,HEADERVER) \
1057 case NSPR_PDPKTRACEPARTTX_V##ver:\
1058 case NSPR_PDPKTRACEPARTTXB_V##ver:\
1059 case NSPR_PDPKTRACEPARTRX_V##ver:\
1060 PACKET_DESCRIBE(phdr,PART,part,ver,pp,HEADERVER);
1062 switch (pletoh16(&(( nspr_header_v10_t*)&nstrace_buf[nstrace_buf_offset])->ph_RecordType))
1064 GENERATE_CASE_FULL(&wth->phdr,10,100)
1065 GENERATE_CASE_PART(&wth->phdr,10,100)
1067 #undef GENERATE_CASE_FULL
1068 #undef GENERATE_CASE_PART
1070 case NSPR_ABSTIME_V10:
1072 nspr_pktracefull_v10_t *fp = (nspr_pktracefull_v10_t *) &nstrace_buf[nstrace_buf_offset];
1073 if (pletoh16(&fp->nsprRecordSize) == 0) {
1074 *err = WTAP_ERR_BAD_FILE;
1075 *err_info = g_strdup("nstrace: zero size record found");
1078 ns_setabstime(nstrace, pletoh32(((nspr_abstime_v10_t *) fp)->abs_Time), pletoh32(&((nspr_abstime_v10_t *) fp)->abs_RelTime));
1079 nstrace_buf_offset += pletoh16(&fp->nsprRecordSize);
1083 case NSPR_RELTIME_V10:
1085 nspr_pktracefull_v10_t *fp = (nspr_pktracefull_v10_t *) &nstrace_buf[nstrace_buf_offset];
1086 if (pletoh16(&fp->nsprRecordSize) == 0) {
1087 *err = WTAP_ERR_BAD_FILE;
1088 *err_info = g_strdup("nstrace: zero size record found");
1091 ns_setrelativetime(nstrace, pletoh32(((nspr_abstime_v10_t *) fp)->abs_RelTime));
1092 nstrace_buf_offset += pletoh16(&fp->nsprRecordSize);
1096 case NSPR_UNUSEDSPACE_V10:
1097 nstrace_buf_offset = nstrace_buflen;
1102 nspr_pktracefull_v10_t *fp = (nspr_pktracefull_v10_t *) &nstrace_buf[nstrace_buf_offset];
1103 if (pletoh16(&fp->nsprRecordSize) == 0) {
1104 *err = WTAP_ERR_BAD_FILE;
1105 *err_info = g_strdup("nstrace: zero size record found");
1108 nstrace_buf_offset += pletoh16(&fp->nsprRecordSize);
1114 nstrace_buf_offset = 0;
1115 nstrace->xxx_offset += nstrace_buflen;
1116 nstrace_buflen = GET_READ_PAGE_SIZE((nstrace->file_size - nstrace->xxx_offset));
1117 }while((nstrace_buflen > 0) && (nstrace_read_buf(wth->fh, nstrace_buf, nstrace_buflen, err, err_info)));
1122 #undef PACKET_DESCRIBE
1124 #define TIMEDEFV20(phdr,fp,type) \
1126 (phdr)->presence_flags = WTAP_HAS_TS;\
1127 nsg_creltime += ns_hrtime2nsec(pletoh32(fp->type##_RelTimeHr));\
1128 (phdr)->ts.secs = nstrace->nspm_curtime + (guint32) (nsg_creltime / 1000000000);\
1129 (phdr)->ts.nsecs = (guint32) (nsg_creltime % 1000000000);\
1132 #define TIMEDEFV23(phdr,fp,type) \
1134 (phdr)->presence_flags = WTAP_HAS_TS;\
1135 /* access _AbsTimeHr as a 64bit value */\
1136 nsg_creltime = pletoh64(fp->type##_AbsTimeHr);\
1137 (phdr)->ts.secs = (guint32) (nsg_creltime / 1000000000);\
1138 (phdr)->ts.nsecs = (guint32) (nsg_creltime % 1000000000);\
1141 #define TIMEDEFV21(phdr,fp,type) TIMEDEFV20(phdr,fp,type)
1142 #define TIMEDEFV22(phdr,fp,type) TIMEDEFV20(phdr,fp,type)
1143 #define TIMEDEFV24(phdr,fp,type) TIMEDEFV23(phdr,fp,type)
1144 #define TIMEDEFV25(phdr,fp,type) TIMEDEFV24(phdr,fp,type)
1145 #define TIMEDEFV26(phdr,fp,type) TIMEDEFV24(phdr,fp,type)
1148 ** The maximum value of the record data size is 65535, which is less than
1149 ** WTAP_MAX_PACKET_SIZE_STANDARD will ever be, so we don't need to check it.
1151 #define PARTSIZEDEFV20(phdr,pp,ver) \
1153 (phdr)->presence_flags |= WTAP_HAS_CAP_LEN;\
1154 (phdr)->len = pletoh16(&pp->pp_PktSizeOrg) + nspr_pktracepart_v##ver##_s;\
1155 (phdr)->caplen = nspr_getv20recordsize((nspr_hd_v20_t *)pp);\
1158 #define PARTSIZEDEFV21(phdr,pp,ver) PARTSIZEDEFV20(phdr,pp,ver)
1159 #define PARTSIZEDEFV22(phdr,pp,ver) PARTSIZEDEFV20(phdr,pp,ver)
1160 #define PARTSIZEDEFV23(phdr,pp,ver) PARTSIZEDEFV20(phdr,pp,ver)
1161 #define PARTSIZEDEFV24(phdr,pp,ver) PARTSIZEDEFV20(phdr,pp,ver)
1162 #define PARTSIZEDEFV25(phdr,pp,ver) PARTSIZEDEFV20(phdr,pp,ver)
1163 #define PARTSIZEDEFV26(phdr,pp,ver) PARTSIZEDEFV20(phdr,pp,ver)
1165 #define FULLSIZEDEFV20(phdr,fp,ver)\
1167 (phdr)->len = nspr_getv20recordsize((nspr_hd_v20_t *)fp);\
1168 (phdr)->caplen = (phdr)->len;\
1171 #define FULLSIZEDEFV21(phdr,fp,ver) FULLSIZEDEFV20(phdr,fp,ver)
1172 #define FULLSIZEDEFV22(phdr,fp,ver) FULLSIZEDEFV20(phdr,fp,ver)
1173 #define FULLSIZEDEFV23(phdr,fp,ver) FULLSIZEDEFV20(phdr,fp,ver)
1174 #define FULLSIZEDEFV24(phdr,fp,ver) FULLSIZEDEFV20(phdr,fp,ver)
1175 #define FULLSIZEDEFV25(phdr,fp,ver) FULLSIZEDEFV20(phdr,fp,ver)
1176 #define FULLSIZEDEFV26(phdr,fp,ver) FULLSIZEDEFV20(phdr,fp,ver)
1178 #define PACKET_DESCRIBE(phdr,FULLPART,ver,enumprefix,type,structname,HEADERVER)\
1180 nspr_##structname##_t *fp= (nspr_##structname##_t*)&nstrace_buf[nstrace_buf_offset];\
1181 /* Make sure the record header is entirely contained in the page */\
1182 if ((nstrace_buflen - nstrace_buf_offset) < sizeof *fp) {\
1183 *err = WTAP_ERR_BAD_FILE;\
1184 *err_info = g_strdup("nstrace: record header crosses page boundary");\
1187 /* Check sanity of record size */\
1188 if (nspr_getv20recordsize((nspr_hd_v20_t *)fp) < sizeof *fp) {\
1189 *err = WTAP_ERR_BAD_FILE;\
1190 *err_info = g_strdup("nstrace: record size is less than record header size");\
1193 (phdr)->rec_type = REC_TYPE_PACKET;\
1194 TIMEDEFV##ver((phdr),fp,type);\
1195 FULLPART##SIZEDEFV##ver((phdr),fp,ver);\
1196 TRACE_V##ver##_REC_LEN_OFF((phdr),enumprefix,type,structname);\
1197 (phdr)->pseudo_header.nstr.rec_type = NSPR_HEADER_VERSION##HEADERVER;\
1198 /* Make sure the record is entirely contained in the page */\
1199 if ((nstrace_buflen - nstrace_buf_offset) < (phdr)->caplen) {\
1200 *err = WTAP_ERR_BAD_FILE;\
1201 *err_info = g_strdup("nstrace: record crosses page boundary");\
1204 ws_buffer_assure_space(wth->frame_buffer, (phdr)->caplen);\
1205 memcpy(ws_buffer_start_ptr(wth->frame_buffer), fp, (phdr)->caplen);\
1206 *data_offset = nstrace->xxx_offset + nstrace_buf_offset;\
1207 nstrace->nstrace_buf_offset = nstrace_buf_offset + nspr_getv20recordsize((nspr_hd_v20_t *)fp);\
1208 nstrace->nstrace_buflen = nstrace_buflen;\
1209 nstrace->nsg_creltime = nsg_creltime;\
1213 static gboolean nstrace_read_v20(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
1215 nstrace_t *nstrace = (nstrace_t *)wth->priv;
1216 guint64 nsg_creltime = nstrace->nsg_creltime;
1217 gchar *nstrace_buf = nstrace->pnstrace_buf;
1218 guint32 nstrace_buf_offset = nstrace->nstrace_buf_offset;
1219 guint32 nstrace_buflen = nstrace->nstrace_buflen;
1225 while ((nstrace_buf_offset < nstrace_buflen) &&
1226 ((nstrace_buflen - nstrace_buf_offset) >= ((gint32)sizeof((( nspr_hd_v20_t*)&nstrace_buf[nstrace_buf_offset])->phd_RecordType))))
1228 switch ((( nspr_hd_v20_t*)&nstrace_buf[nstrace_buf_offset])->phd_RecordType)
1231 #define GENERATE_CASE_FULL(phdr,ver,HEADERVER) \
1232 case NSPR_PDPKTRACEFULLTX_V##ver:\
1233 case NSPR_PDPKTRACEFULLTXB_V##ver:\
1234 case NSPR_PDPKTRACEFULLRX_V##ver:\
1235 PACKET_DESCRIBE(phdr,FULL,ver,v##ver##_full,fp,pktracefull_v##ver,HEADERVER);
1237 #define GENERATE_CASE_FULL_V25(phdr,ver,HEADERVER) \
1238 case NSPR_PDPKTRACEFULLTX_V##ver:\
1239 case NSPR_PDPKTRACEFULLTXB_V##ver:\
1240 case NSPR_PDPKTRACEFULLRX_V##ver:\
1241 case NSPR_PDPKTRACEFULLNEWRX_V##ver:\
1242 PACKET_DESCRIBE(phdr,FULL,ver,v##ver##_full,fp,pktracefull_v##ver,HEADERVER);
1244 #define GENERATE_CASE_PART(phdr,ver,HEADERVER) \
1245 case NSPR_PDPKTRACEPARTTX_V##ver:\
1246 case NSPR_PDPKTRACEPARTTXB_V##ver:\
1247 case NSPR_PDPKTRACEPARTRX_V##ver:\
1248 PACKET_DESCRIBE(phdr,PART,ver,v##ver##_part,pp,pktracepart_v##ver,HEADERVER);
1250 #define GENERATE_CASE_PART_V25(phdr,ver,HEADERVER) \
1251 case NSPR_PDPKTRACEPARTTX_V##ver:\
1252 case NSPR_PDPKTRACEPARTTXB_V##ver:\
1253 case NSPR_PDPKTRACEPARTRX_V##ver:\
1254 case NSPR_PDPKTRACEPARTNEWRX_V##ver:\
1255 PACKET_DESCRIBE(phdr,PART,ver,v##ver##_part,pp,pktracepart_v##ver,HEADERVER);
1257 GENERATE_CASE_FULL(&wth->phdr,20,200);
1258 GENERATE_CASE_PART(&wth->phdr,20,200);
1259 GENERATE_CASE_FULL(&wth->phdr,21,201);
1260 GENERATE_CASE_PART(&wth->phdr,21,201);
1261 GENERATE_CASE_FULL(&wth->phdr,22,202);
1262 GENERATE_CASE_PART(&wth->phdr,22,202);
1263 GENERATE_CASE_FULL(&wth->phdr,23,203);
1264 GENERATE_CASE_PART(&wth->phdr,23,203);
1265 GENERATE_CASE_FULL_V25(&wth->phdr,24,204);
1266 GENERATE_CASE_PART_V25(&wth->phdr,24,204);
1267 GENERATE_CASE_FULL_V25(&wth->phdr,25,205);
1268 GENERATE_CASE_PART_V25(&wth->phdr,25,205);
1269 GENERATE_CASE_FULL_V25(&wth->phdr,26,206);
1270 GENERATE_CASE_PART_V25(&wth->phdr,26,206);
1272 #undef GENERATE_CASE_FULL
1273 #undef GENERATE_CASE_FULL_V25
1274 #undef GENERATE_CASE_PART
1275 #undef GENERATE_CASE_PART_V25
1277 case NSPR_ABSTIME_V20:
1279 nspr_pktracefull_v20_t *fp20 = (nspr_pktracefull_v20_t *) &nstrace_buf[nstrace_buf_offset];
1280 if (nspr_getv20recordsize((nspr_hd_v20_t *)fp20) == 0) {
1281 *err = WTAP_ERR_BAD_FILE;
1282 *err_info = g_strdup("nstrace: zero size record found");
1285 nstrace_buf_offset += nspr_getv20recordsize((nspr_hd_v20_t *)fp20);
1286 ns_setabstime(nstrace, pletoh32(&((nspr_abstime_v20_t *) fp20)->abs_Time), pletoh16(&((nspr_abstime_v20_t *) fp20)->abs_RelTime));
1290 case NSPR_RELTIME_V20:
1292 nspr_pktracefull_v20_t *fp20 = (nspr_pktracefull_v20_t *) &nstrace_buf[nstrace_buf_offset];
1293 if (nspr_getv20recordsize((nspr_hd_v20_t *)fp20) == 0) {
1294 *err = WTAP_ERR_BAD_FILE;
1295 *err_info = g_strdup("nstrace: zero size record found");
1298 ns_setrelativetime(nstrace, pletoh16(&((nspr_abstime_v20_t *) fp20)->abs_RelTime));
1299 nstrace_buf_offset += nspr_getv20recordsize((nspr_hd_v20_t *)fp20);
1303 case NSPR_UNUSEDSPACE_V20:
1305 if (nstrace_buf_offset >= NSPR_PAGESIZE/2)
1306 nstrace_buf_offset = nstrace_buflen;
1308 nstrace_buf_offset = NSPR_PAGESIZE/2;
1314 nspr_pktracefull_v20_t *fp20 = (nspr_pktracefull_v20_t *) &nstrace_buf[nstrace_buf_offset];
1315 if (nspr_getv20recordsize((nspr_hd_v20_t *)fp20) == 0) {
1316 *err = WTAP_ERR_BAD_FILE;
1317 *err_info = g_strdup("nstrace: zero size record found");
1320 nstrace_buf_offset += nspr_getv20recordsize((nspr_hd_v20_t *)fp20);
1326 nstrace_buf_offset = 0;
1327 nstrace->xxx_offset += nstrace_buflen;
1328 nstrace_buflen = GET_READ_PAGE_SIZE((nstrace->file_size - nstrace->xxx_offset));
1329 }while((nstrace_buflen > 0) && (nstrace_read_buf(wth->fh, nstrace_buf, nstrace_buflen, err, err_info)));
1334 #undef PACKET_DESCRIBE
1336 #define SETETHOFFSET_35(phdr)\
1337 (phdr)->pseudo_header.nstr.eth_offset = pletoh16(&fp->fp_headerlen);\
1339 #define SETETHOFFSET_30(phdr) ;\
1341 #define TIMEDEFV30(phdr,fp,type) \
1343 (phdr)->presence_flags = WTAP_HAS_TS;\
1344 /* access _AbsTimeHr as a 64bit value */\
1345 nsg_creltime = pletoh64(fp->type##_AbsTimeHr);\
1346 (phdr)->ts.secs = (guint32) (nsg_creltime / 1000000000);\
1347 (phdr)->ts.nsecs = (guint32) (nsg_creltime % 1000000000);\
1350 #define TIMEDEFV35 TIMEDEFV30
1353 ** The maximum value of the record data size is 65535, which is less than
1354 ** WTAP_MAX_PACKET_SIZE_STANDARD will ever be, so we don't need to check it.
1356 #define FULLSIZEDEFV30(phdr,fp,ver)\
1358 (phdr)->presence_flags |= WTAP_HAS_CAP_LEN;\
1359 (phdr)->len = pletoh16(&fp->fp_PktSizeOrg) + nspr_pktracefull_v##ver##_s + fp->fp_src_vmname_len + fp->fp_dst_vmname_len;\
1360 (phdr)->caplen = nspr_getv20recordsize((nspr_hd_v20_t *)fp);\
1363 #define FULLSIZEDEFV35(phdr,fp,ver)\
1365 (phdr)->presence_flags |= WTAP_HAS_CAP_LEN;\
1366 (phdr)->len = pletoh16(&fp->fp_PktSizeOrg) + pletoh16(&fp->fp_headerlen);\
1367 (phdr)->caplen = nspr_getv20recordsize((nspr_hd_v20_t *)fp);\
1370 #define PACKET_DESCRIBE(phdr,FULLPART,ver,enumprefix,type,structname,HEADERVER)\
1372 nspr_##structname##_t *fp = (nspr_##structname##_t *) &nstrace_buf[nstrace_buf_offset];\
1373 /* Make sure the record header is entirely contained in the page */\
1374 if ((nstrace->nstrace_buflen - nstrace_buf_offset) < sizeof *fp) {\
1375 *err = WTAP_ERR_BAD_FILE;\
1376 *err_info = g_strdup("nstrace: record header crosses page boundary");\
1377 g_free(nstrace_tmpbuff);\
1380 (phdr)->rec_type = REC_TYPE_PACKET;\
1381 TIMEDEFV##ver((phdr),fp,type);\
1382 FULLPART##SIZEDEFV##ver((phdr),fp,ver);\
1383 TRACE_V##ver##_REC_LEN_OFF((phdr),enumprefix,type,structname);\
1384 SETETHOFFSET_##ver(phdr)\
1385 (phdr)->pseudo_header.nstr.rec_type = NSPR_HEADER_VERSION##HEADERVER;\
1386 /* Check sanity of record size */\
1387 if ((phdr)->caplen < sizeof *fp) {\
1388 *err = WTAP_ERR_BAD_FILE;\
1389 *err_info = g_strdup("nstrace: record size is less than record header size");\
1390 g_free(nstrace_tmpbuff);\
1393 ws_buffer_assure_space(wth->frame_buffer, (phdr)->caplen);\
1394 *data_offset = nstrace->xxx_offset + nstrace_buf_offset;\
1395 /* Copy record header */\
1396 while (nstrace_tmpbuff_off < nspr_##structname##_s) {\
1397 nstrace_tmpbuff[nstrace_tmpbuff_off++] = nstrace_buf[nstrace_buf_offset++];\
1399 nst_dataSize = nspr_getv20recordsize(hdp);\
1400 rec_size = nst_dataSize - nstrace_tmpbuff_off;\
1401 nsg_nextPageOffset = ((nstrace_buf_offset + rec_size) >= (guint)nstrace->nstrace_buflen) ?\
1402 ((nstrace_buf_offset + rec_size) - (NSPR_PAGESIZE_TRACE - 1)) : 0;\
1403 /* Copy record data */\
1404 while (nsg_nextPageOffset) {\
1405 /* Copy everything from this page */\
1406 while (nstrace_buf_offset < nstrace->nstrace_buflen) {\
1407 nstrace_tmpbuff[nstrace_tmpbuff_off++] = nstrace_buf[nstrace_buf_offset++];\
1409 nstrace->xxx_offset += nstrace_buflen;\
1410 nstrace_buflen = NSPR_PAGESIZE_TRACE;\
1411 /* Read the next page */\
1412 bytes_read = file_read(nstrace_buf, NSPR_PAGESIZE_TRACE, wth->fh);\
1413 if ( !file_eof(wth->fh) && bytes_read != NSPR_PAGESIZE_TRACE) {\
1414 g_free(nstrace_tmpbuff);\
1417 nstrace_buf_offset = 0;\
1419 nstrace_buflen = bytes_read;\
1420 rec_size = nst_dataSize - nstrace_tmpbuff_off;\
1421 nsg_nextPageOffset = ((nstrace_buf_offset + rec_size) >= (guint)nstrace->nstrace_buflen) ?\
1422 ((nstrace_buf_offset + rec_size) - (NSPR_PAGESIZE_TRACE- 1)): 0;\
1424 /* Copy the rest of the record */\
1425 while (nstrace_tmpbuff_off < nst_dataSize) {\
1426 nstrace_tmpbuff[nstrace_tmpbuff_off++] = nstrace_buf[nstrace_buf_offset++];\
1428 memcpy(ws_buffer_start_ptr(wth->frame_buffer), nstrace_tmpbuff, (phdr)->caplen);\
1429 nstrace->nstrace_buf_offset = nstrace_buf_offset;\
1430 nstrace->nstrace_buflen = nstrace_buflen;\
1431 nstrace->nsg_creltime = nsg_creltime;\
1432 g_free(nstrace_tmpbuff);\
1436 static gboolean nstrace_read_v30(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
1438 nstrace_t *nstrace = (nstrace_t *)wth->priv;
1439 guint64 nsg_creltime;
1440 gchar *nstrace_buf = nstrace->pnstrace_buf;
1441 guint32 nstrace_buf_offset = nstrace->nstrace_buf_offset;
1442 guint32 nstrace_buflen = nstrace->nstrace_buflen;
1443 guint8* nstrace_tmpbuff;
1444 guint32 nstrace_tmpbuff_off=0,nst_dataSize=0,rec_size=0,nsg_nextPageOffset=0;
1449 if(nstrace_buflen == 0){
1450 return FALSE; /* Reached End Of File */
1453 nstrace_tmpbuff = (guint8*)g_malloc(65536);
1457 if (!nstrace_buf[nstrace_buf_offset] && nstrace_buf_offset <= NSPR_PAGESIZE_TRACE){
1458 nstrace_buf_offset = NSPR_PAGESIZE_TRACE;
1460 if (file_eof(wth->fh) && bytes_read > 0 && bytes_read < NSPR_PAGESIZE_TRACE){
1461 memset(&nstrace_buf[bytes_read], 0, NSPR_PAGESIZE_TRACE-bytes_read);
1463 while ((nstrace_buf_offset < NSPR_PAGESIZE_TRACE) &&
1464 nstrace_buf[nstrace_buf_offset])
1466 hdp = (nspr_hd_v20_t *) &nstrace_buf[nstrace_buf_offset];
1467 if (nspr_getv20recordsize(hdp) == 0) {
1468 *err = WTAP_ERR_BAD_FILE;
1469 *err_info = g_strdup("nstrace: zero size record found");
1470 g_free(nstrace_tmpbuff);
1473 switch (hdp->phd_RecordType)
1476 #define GENERATE_CASE_FULL_V30(phdr,ver,HEADERVER) \
1477 case NSPR_PDPKTRACEFULLTX_V##ver:\
1478 case NSPR_PDPKTRACEFULLTXB_V##ver:\
1479 case NSPR_PDPKTRACEFULLRX_V##ver:\
1480 case NSPR_PDPKTRACEFULLNEWRX_V##ver:\
1481 PACKET_DESCRIBE(phdr,FULL,ver,v##ver##_full,fp,pktracefull_v##ver,HEADERVER);
1483 GENERATE_CASE_FULL_V30(&wth->phdr,30,300);
1485 #undef GENERATE_CASE_FULL_V30
1487 #define GENERATE_CASE_FULL_V35(phdr,ver,HEADERVER) \
1488 case NSPR_PDPKTRACEFULLTX_V##ver:\
1489 case NSPR_PDPKTRACEFULLTXB_V##ver:\
1490 case NSPR_PDPKTRACEFULLRX_V##ver:\
1491 case NSPR_PDPKTRACEFULLNEWRX_V##ver:\
1492 PACKET_DESCRIBE(phdr,FULL,ver,v##ver##_full,fp,pktracefull_v##ver,HEADERVER);
1493 GENERATE_CASE_FULL_V35(&wth->phdr,35,350);
1495 #undef GENERATE_CASE_FULL_V35
1497 case NSPR_ABSTIME_V20:
1499 nstrace_buf_offset += nspr_getv20recordsize(hdp);
1500 ns_setabstime(nstrace, pletoh32(&((nspr_abstime_v20_t *) &nstrace_buf[nstrace_buf_offset])->abs_Time), pletoh16(&((nspr_abstime_v20_t *) &nstrace_buf[nstrace_buf_offset])->abs_RelTime));
1504 case NSPR_RELTIME_V20:
1506 ns_setrelativetime(nstrace, pletoh16(&((nspr_abstime_v20_t *) &nstrace_buf[nstrace_buf_offset])->abs_RelTime));
1507 nstrace_buf_offset += nspr_getv20recordsize(hdp);
1513 nstrace_buf_offset += nspr_getv20recordsize(hdp);
1518 nstrace_buf_offset = 0;
1519 nstrace->xxx_offset += nstrace_buflen;
1520 nstrace_buflen = NSPR_PAGESIZE_TRACE;
1521 } while((nstrace_buflen > 0) && (bytes_read = file_read(nstrace_buf, nstrace_buflen, wth->fh)) > 0 && (file_eof(wth->fh) || (guint32)bytes_read == nstrace_buflen));
1524 *err = file_error(wth->fh, err_info);
1527 g_free(nstrace_tmpbuff);
1531 #undef PACKET_DESCRIBE
1534 * XXX - for these, we can't set the time stamp in the seek-read
1535 * routine, because the time stamps are relative.
1538 #define TIMEDEFV10(phdr,fp,type) \
1540 (phdr)->presence_flags = 0;\
1543 #define PACKET_DESCRIBE(phdr,FULLPART,fullpart,ver,type,HEADERVER) \
1545 nspr_pktrace##fullpart##_v##ver##_t *type = (nspr_pktrace##fullpart##_v##ver##_t *) pd;\
1546 (phdr)->rec_type = REC_TYPE_PACKET;\
1547 TIMEDEFV##ver((phdr),fp,type);\
1548 FULLPART##SIZEDEFV##ver((phdr),type,ver);\
1549 TRACE_V##ver##_REC_LEN_OFF(phdr,v##ver##_##fullpart,type,pktrace##fullpart##_v##ver);\
1550 (phdr)->pseudo_header.nstr.rec_type = NSPR_HEADER_VERSION##HEADERVER;\
1553 static gboolean nstrace_seek_read_v10(wtap *wth, gint64 seek_off,
1554 struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info)
1557 guint record_length;
1559 unsigned int bytes_to_read;
1563 if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
1567 ** Read the record header.
1569 if (!wtap_read_bytes(wth->random_fh, (void *)&hdr, sizeof hdr,
1574 ** Get the record length.
1576 record_length = nspr_getv10recordsize(&hdr);
1579 ** Copy the header to the buffer and read the rest of the record..
1581 ws_buffer_assure_space(buf, record_length);
1582 pd = ws_buffer_start_ptr(buf);
1583 memcpy(pd, (void *)&hdr, sizeof hdr);
1584 if (record_length > sizeof hdr) {
1585 bytes_to_read = (unsigned int)(record_length - sizeof hdr);
1586 if (!wtap_read_bytes(wth->random_fh, pd + sizeof hdr, bytes_to_read,
1592 ** Fill in what part of the struct wtap_pkthdr we can.
1594 #define GENERATE_CASE_FULL(phdr,type,HEADERVER) \
1595 case NSPR_PDPKTRACEFULLTX_V##type:\
1596 case NSPR_PDPKTRACEFULLTXB_V##type:\
1597 case NSPR_PDPKTRACEFULLRX_V##type:\
1598 PACKET_DESCRIBE(phdr,FULL,full,type,fp,HEADERVER);\
1601 #define GENERATE_CASE_PART(phdr,type,HEADERVER) \
1602 case NSPR_PDPKTRACEPARTTX_V##type:\
1603 case NSPR_PDPKTRACEPARTTXB_V##type:\
1604 case NSPR_PDPKTRACEPARTRX_V##type:\
1605 PACKET_DESCRIBE(phdr,PART,part,type,pp,HEADERVER);\
1608 switch (pletoh16(&(( nspr_header_v10_t*)pd)->ph_RecordType))
1610 GENERATE_CASE_FULL(phdr,10,100)
1611 GENERATE_CASE_PART(phdr,10,100)
1614 #undef GENERATE_CASE_FULL
1615 #undef GENERATE_CASE_PART
1620 #undef PACKET_DESCRIBE
1623 * XXX - for these, we can't set the time stamp in the seek-read
1624 * routine, because the time stamps are relative.
1627 #define TIMEDEFV20(phdr,fp,type) \
1629 (phdr)->presence_flags = 0;\
1634 #define TIMEDEFV21(phdr,fp,type) TIMEDEFV20(phdr,fp,type)
1635 #define TIMEDEFV22(phdr,fp,type) TIMEDEFV20(phdr,fp,type)
1637 #define PACKET_DESCRIBE(phdr,FULLPART,ver,enumprefix,type,structname,HEADERVER)\
1639 nspr_##structname##_t *fp= (nspr_##structname##_t*)pd;\
1640 (phdr)->rec_type = REC_TYPE_PACKET;\
1641 TIMEDEFV##ver((phdr),fp,type);\
1642 FULLPART##SIZEDEFV##ver((phdr),fp,ver);\
1643 TRACE_V##ver##_REC_LEN_OFF((phdr),enumprefix,type,structname);\
1644 (phdr)->pseudo_header.nstr.rec_type = NSPR_HEADER_VERSION##HEADERVER;\
1648 static gboolean nstrace_seek_read_v20(wtap *wth, gint64 seek_off,
1649 struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info)
1652 guint record_length;
1655 unsigned int bytes_to_read;
1656 guint64 nsg_creltime;
1660 if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
1664 ** Read the first 2 bytes of the record header.
1666 if (!wtap_read_bytes(wth->random_fh, (void *)&hdr, 2, err, err_info))
1671 ** Is there a third byte? If so, read it.
1673 if (hdr.phd_RecordSizeLow & NSPR_V20RECORDSIZE_2BYTES) {
1674 if (!wtap_read_bytes(wth->random_fh, (void *)&hdr.phd_RecordSizeHigh, 1,
1681 ** Get the record length.
1683 record_length = nspr_getv20recordsize(&hdr);
1686 ** Copy the header to the buffer and read the rest of the record..
1688 ws_buffer_assure_space(buf, record_length);
1689 pd = ws_buffer_start_ptr(buf);
1690 memcpy(pd, (void *)&hdr, hdrlen);
1691 if (record_length > hdrlen) {
1692 bytes_to_read = (unsigned int)(record_length - hdrlen);
1693 if (!wtap_read_bytes(wth->random_fh, pd + hdrlen, bytes_to_read,
1698 #define GENERATE_CASE_FULL(phdr,ver,HEADERVER) \
1699 case NSPR_PDPKTRACEFULLTX_V##ver:\
1700 case NSPR_PDPKTRACEFULLTXB_V##ver:\
1701 case NSPR_PDPKTRACEFULLRX_V##ver:\
1702 PACKET_DESCRIBE(phdr,FULL,ver,v##ver##_full,fp,pktracefull_v##ver,HEADERVER);
1704 #define GENERATE_CASE_FULL_V25(phdr,ver,HEADERVER) \
1705 case NSPR_PDPKTRACEFULLTX_V##ver:\
1706 case NSPR_PDPKTRACEFULLTXB_V##ver:\
1707 case NSPR_PDPKTRACEFULLRX_V##ver:\
1708 case NSPR_PDPKTRACEFULLNEWRX_V##ver:\
1709 PACKET_DESCRIBE(phdr,FULL,ver,v##ver##_full,fp,pktracefull_v##ver,HEADERVER);
1711 #define GENERATE_CASE_PART(phdr,ver,HEADERVER) \
1712 case NSPR_PDPKTRACEPARTTX_V##ver:\
1713 case NSPR_PDPKTRACEPARTTXB_V##ver:\
1714 case NSPR_PDPKTRACEPARTRX_V##ver:\
1715 PACKET_DESCRIBE(phdr,PART,ver,v##ver##_part,pp,pktracepart_v##ver,HEADERVER);
1717 #define GENERATE_CASE_PART_V25(phdr,ver,HEADERVER) \
1718 case NSPR_PDPKTRACEPARTTX_V##ver:\
1719 case NSPR_PDPKTRACEPARTTXB_V##ver:\
1720 case NSPR_PDPKTRACEPARTRX_V##ver:\
1721 case NSPR_PDPKTRACEPARTNEWRX_V##ver:\
1722 PACKET_DESCRIBE(phdr,PART,ver,v##ver##_part,pp,pktracepart_v##ver,HEADERVER);
1724 switch ((( nspr_hd_v20_t*)pd)->phd_RecordType)
1726 GENERATE_CASE_FULL(phdr,20,200)
1727 GENERATE_CASE_PART(phdr,20,200)
1728 GENERATE_CASE_FULL(phdr,21,201)
1729 GENERATE_CASE_PART(phdr,21,201)
1730 GENERATE_CASE_FULL(phdr,22,202)
1731 GENERATE_CASE_PART(phdr,22,202)
1732 GENERATE_CASE_FULL(phdr,23,203)
1733 GENERATE_CASE_PART(phdr,23,203)
1734 GENERATE_CASE_FULL_V25(phdr,24,204)
1735 GENERATE_CASE_PART_V25(phdr,24,204)
1736 GENERATE_CASE_FULL_V25(phdr,25,205)
1737 GENERATE_CASE_PART_V25(phdr,25,205)
1738 GENERATE_CASE_FULL_V25(phdr,26,206)
1739 GENERATE_CASE_PART_V25(phdr,26,206)
1742 #undef GENERATE_CASE_FULL
1743 #undef GENERATE_CASE_FULL_V25
1744 #undef GENERATE_CASE_PART
1745 #undef GENERATE_CASE_PART_V25
1750 #undef PACKET_DESCRIBE
1751 #undef SETETHOFFSET_35
1752 #undef SETETHOFFSET_30
1754 #define SETETHOFFSET_35(phdr)\
1756 (phdr)->pseudo_header.nstr.eth_offset = pletoh16(&fp->fp_headerlen);\
1759 #define SETETHOFFSET_30(phdr) ;\
1761 #define PACKET_DESCRIBE(phdr,FULLPART,ver,enumprefix,type,structname,HEADERVER)\
1763 nspr_##structname##_t *fp= (nspr_##structname##_t*)pd;\
1764 (phdr)->rec_type = REC_TYPE_PACKET;\
1765 TIMEDEFV##ver((phdr),fp,type);\
1766 SETETHOFFSET_##ver(phdr);\
1767 FULLPART##SIZEDEFV##ver((phdr),fp,ver);\
1768 TRACE_V##ver##_REC_LEN_OFF((phdr),enumprefix,type,structname);\
1769 (phdr)->pseudo_header.nstr.rec_type = NSPR_HEADER_VERSION##HEADERVER;\
1773 static gboolean nstrace_seek_read_v30(wtap *wth, gint64 seek_off,
1774 struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info)
1777 guint record_length;
1780 unsigned int bytes_to_read;
1781 guint64 nsg_creltime;
1785 if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
1788 ** Read the first 2 bytes of the record header.
1790 if (!wtap_read_bytes(wth->random_fh, (void *)&hdr, 2, err, err_info))
1795 ** Is there a third byte? If so, read it.
1797 if (hdr.phd_RecordSizeLow & NSPR_V20RECORDSIZE_2BYTES) {
1798 if (!wtap_read_bytes(wth->random_fh, (void *)&hdr.phd_RecordSizeHigh, 1,
1805 ** Get the record length.
1806 ** The maximum value of the record data size is 65535, which is less
1807 ** than WTAP_MAX_PACKET_SIZE_STANDARD will ever be, so we don't need to check it.
1809 record_length = nspr_getv20recordsize(&hdr);
1812 ** Copy the header to the buffer and read the rest of the record..
1814 ws_buffer_assure_space(buf, record_length);
1815 pd = ws_buffer_start_ptr(buf);
1816 memcpy(pd, (void *)&hdr, hdrlen);
1817 if (record_length > hdrlen) {
1818 bytes_to_read = (unsigned int)(record_length - hdrlen);
1819 if (!wtap_read_bytes(wth->random_fh, pd + hdrlen, bytes_to_read,
1824 (phdr)->caplen = (phdr)->len = record_length;
1826 #define GENERATE_CASE_V30(phdr,ver,HEADERVER) \
1827 case NSPR_PDPKTRACEFULLTX_V##ver:\
1828 case NSPR_PDPKTRACEFULLTXB_V##ver:\
1829 case NSPR_PDPKTRACEFULLRX_V##ver:\
1830 case NSPR_PDPKTRACEFULLNEWRX_V##ver:\
1831 PACKET_DESCRIBE(phdr,FULL,ver,v##ver##_full,fp,pktracefull_v##ver,HEADERVER);
1833 switch ((( nspr_hd_v20_t*)pd)->phd_RecordType)
1835 GENERATE_CASE_V30(phdr,30, 300);
1836 GENERATE_CASE_V30(phdr,35, 350);
1844 ** Netscaler trace format close routines.
1846 static void nstrace_close(wtap *wth)
1848 nstrace_t *nstrace = (nstrace_t *)wth->priv;
1850 g_free(nstrace->pnstrace_buf);
1855 guint16 page_offset;
1857 guint32 absrec_time;
1861 /* Returns 0 if we could write the specified encapsulation type,
1862 ** an error indication otherwise. */
1863 int nstrace_10_dump_can_write_encap(int encap)
1865 if (encap == WTAP_ENCAP_NSTRACE_1_0)
1868 return WTAP_ERR_UNWRITABLE_ENCAP;
1872 /* Returns 0 if we could write the specified encapsulation type,
1873 ** an error indication otherwise. */
1874 int nstrace_20_dump_can_write_encap(int encap)
1876 if (encap == WTAP_ENCAP_NSTRACE_2_0)
1879 return WTAP_ERR_UNWRITABLE_ENCAP;
1882 /* Returns 0 if we could write the specified encapsulation type,
1883 ** an error indication otherwise. */
1884 int nstrace_30_dump_can_write_encap(int encap)
1886 if (encap == WTAP_ENCAP_NSTRACE_3_0)
1889 return WTAP_ERR_UNWRITABLE_ENCAP;
1892 /* Returns 0 if we could write the specified encapsulation type,
1893 ** an error indication otherwise. */
1894 int nstrace_35_dump_can_write_encap(int encap)
1896 if (encap == WTAP_ENCAP_NSTRACE_3_5)
1899 return WTAP_ERR_UNWRITABLE_ENCAP;
1902 /* Returns TRUE on success, FALSE on failure; sets "*err" to an error code on
1904 gboolean nstrace_dump_open(wtap_dumper *wdh, int *err _U_)
1906 nstrace_dump_t *nstrace;
1908 wdh->subtype_write = nstrace_dump;
1910 nstrace = (nstrace_dump_t *)g_malloc(sizeof(nstrace_dump_t));
1911 wdh->priv = (void *)nstrace;
1912 nstrace->page_offset = 0;
1913 if ((wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_3_0) ||
1914 (wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_3_5))
1915 nstrace->page_len = NSPR_PAGESIZE_TRACE;
1917 nstrace->page_len = NSPR_PAGESIZE;
1919 nstrace->absrec_time = 0;
1920 nstrace->newfile = TRUE;
1926 static gboolean nstrace_add_signature(wtap_dumper *wdh, int *err)
1928 nstrace_dump_t *nstrace = (nstrace_dump_t *)wdh->priv;
1930 if (wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_1_0)
1933 nspr_signature_v10_t sig10;
1935 /* populate the record */
1936 val16b = GUINT16_TO_LE(NSPR_SIGNATURE_V10);
1937 memcpy(sig10.phd.ph_RecordType, &val16b, sizeof sig10.phd.ph_RecordType);
1938 val16b = GUINT16_TO_LE(nspr_signature_v10_s);
1939 memcpy(sig10.phd.ph_RecordSize, &val16b, sizeof sig10.phd.ph_RecordSize);
1940 memset(sig10.sig_Signature, 0, NSPR_SIGSIZE_V10);
1941 g_strlcpy(sig10.sig_Signature, NSPR_SIGSTR_V10, NSPR_SIGSIZE_V10);
1943 /* Write the record into the file */
1944 if (!wtap_dump_file_write(wdh, &sig10, nspr_signature_v10_s,
1948 /* Move forward the page offset */
1949 nstrace->page_offset += (guint16) nspr_signature_v10_s;
1951 } else if (wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_2_0)
1953 nspr_signature_v20_t sig20;
1955 sig20.sig_RecordType = NSPR_SIGNATURE_V20;
1956 sig20.sig_RecordSize = nspr_signature_v20_s;
1957 memcpy(sig20.sig_Signature, NSPR_SIGSTR_V20, sizeof(NSPR_SIGSTR_V20));
1959 /* Write the record into the file */
1960 if (!wtap_dump_file_write(wdh, &sig20, sig20.sig_RecordSize,
1964 /* Move forward the page offset */
1965 nstrace->page_offset += (guint16) sig20.sig_RecordSize;
1967 } else if (wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_3_0)
1969 nspr_signature_v30_t sig30;
1971 sig30.sig_RecordType = NSPR_SIGNATURE_V30;
1972 sig30.sig_RecordSize = nspr_signature_v30_s;
1973 memcpy(sig30.sig_Signature, NSPR_SIGSTR_V30, sizeof(NSPR_SIGSTR_V30));
1975 /* Write the record into the file */
1976 if (!wtap_dump_file_write(wdh, &sig30, sig30.sig_RecordSize,
1980 /* Move forward the page offset */
1981 nstrace->page_offset += (guint16) sig30.sig_RecordSize;
1982 } else if (wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_3_5)
1984 nspr_signature_v35_t sig35;
1986 sig35.sig_RecordType = NSPR_SIGNATURE_V35;
1987 sig35.sig_RecordSize = nspr_signature_v35_s;
1988 memcpy(sig35.sig_Signature, NSPR_SIGSTR_V35, sizeof(NSPR_SIGSTR_V35));
1990 /* Write the record into the file */
1991 if (!wtap_dump_file_write(wdh, &sig35, sig35.sig_RecordSize,
1995 /* Move forward the page offset */
1996 nstrace->page_offset += (guint16) sig35.sig_RecordSize;
1999 g_assert_not_reached();
2008 nstrace_add_abstime(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
2009 const guint8 *pd, int *err)
2011 nstrace_dump_t *nstrace = (nstrace_dump_t *)wdh->priv;
2012 guint64 nsg_creltime;
2014 if (wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_1_0)
2019 nspr_abstime_v10_t abs10;
2021 /* populate the record */
2022 val16 = GUINT16_TO_LE(NSPR_ABSTIME_V10);
2023 memcpy(abs10.phd.ph_RecordType, &val16, sizeof abs10.phd.ph_RecordType);
2024 val16 = GUINT16_TO_LE(nspr_abstime_v10_s);
2025 memcpy(abs10.phd.ph_RecordSize, &val16, sizeof abs10.phd.ph_RecordSize);
2027 memcpy(&reltime, ((const nspr_pktracefull_v10_t *)pd)->fp_RelTimeHr, sizeof reltime);
2028 nsg_creltime = ns_hrtime2nsec(reltime);
2030 memset(abs10.abs_RelTime, 0, sizeof abs10.abs_RelTime);
2031 abstime = GUINT32_TO_LE((guint32)phdr->ts.secs - (guint32)(nsg_creltime/1000000000));
2032 memcpy(abs10.abs_Time, &abstime, sizeof abs10.abs_Time);
2034 /* Write the record into the file */
2035 if (!wtap_dump_file_write(wdh, &abs10, nspr_abstime_v10_s, err))
2038 /* Move forward the page offset */
2039 nstrace->page_offset += nspr_abstime_v10_s;
2041 } else if ((wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_2_0) ||
2042 (wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_3_0) ||
2043 (wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_3_5)) {
2046 nspr_abstime_v20_t abs20;
2048 abs20.abs_RecordType = NSPR_ABSTIME_V20;
2049 abs20.abs_RecordSize = nspr_abstime_v20_s;
2051 memcpy(&reltime, ((const nspr_pktracefull_v20_t *)pd)->fp_RelTimeHr, sizeof reltime);
2052 nsg_creltime = ns_hrtime2nsec(reltime);
2054 memset(abs20.abs_RelTime, 0, sizeof abs20.abs_RelTime);
2055 abstime = GUINT32_TO_LE((guint32)phdr->ts.secs - (guint32)(nsg_creltime/1000000000));
2056 memcpy(abs20.abs_RelTime, &abstime, sizeof abs20.abs_RelTime);
2058 /* Write the record into the file */
2059 if (!wtap_dump_file_write(wdh, &abs20, nspr_abstime_v20_s, err))
2062 /* Move forward the page offset */
2063 nstrace->page_offset += nspr_abstime_v20_s;
2067 g_assert_not_reached();
2075 /* Write a record for a packet to a dump file.
2076 Returns TRUE on success, FALSE on failure. */
2077 static gboolean nstrace_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
2078 const guint8 *pd, int *err, gchar **err_info _U_)
2080 nstrace_dump_t *nstrace = (nstrace_dump_t *)wdh->priv;
2082 /* We can only write packet records. */
2083 if (phdr->rec_type != REC_TYPE_PACKET) {
2084 *err = WTAP_ERR_UNWRITABLE_REC_TYPE;
2088 if (nstrace->newfile == TRUE)
2090 nstrace->newfile = FALSE;
2091 /* Add the signature record and abs time record */
2092 if (wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_1_0)
2094 if (!nstrace_add_signature(wdh, err) ||
2095 !nstrace_add_abstime(wdh, phdr, pd, err))
2097 } else if (wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_2_0)
2099 if (!nstrace_add_signature(wdh, err) ||
2100 !nstrace_add_abstime(wdh, phdr, pd, err))
2102 } else if (wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_3_0 ||
2103 wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_3_5 )
2105 if (!nstrace_add_signature(wdh, err) ||
2106 !nstrace_add_abstime(wdh, phdr, pd, err))
2110 g_assert_not_reached();
2115 switch (phdr->pseudo_header.nstr.rec_type)
2117 case NSPR_HEADER_VERSION100:
2119 if (wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_1_0)
2121 if (nstrace->page_offset + phdr->caplen >= nstrace->page_len)
2123 /* Start on the next page */
2124 if (wtap_dump_file_seek(wdh, (nstrace->page_len - nstrace->page_offset), SEEK_CUR, err) == -1)
2127 nstrace->page_offset = 0;
2129 /* Possibly add signature and abstime records and increment offset */
2130 if (!nstrace_add_signature(wdh, err))
2134 /* Write the actual record as is */
2135 if (!wtap_dump_file_write(wdh, pd, phdr->caplen, err))
2138 nstrace->page_offset += (guint16) phdr->caplen;
2139 } else if (wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_2_0)
2141 *err = WTAP_ERR_UNWRITABLE_FILE_TYPE;
2147 case NSPR_HEADER_VERSION200:
2148 case NSPR_HEADER_VERSION201:
2149 case NSPR_HEADER_VERSION202:
2150 case NSPR_HEADER_VERSION203:
2151 case NSPR_HEADER_VERSION204:
2152 case NSPR_HEADER_VERSION205:
2153 case NSPR_HEADER_VERSION206:
2154 if (wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_1_0)
2156 *err = WTAP_ERR_UNWRITABLE_FILE_TYPE;
2158 } else if (wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_2_0)
2160 if (nstrace->page_offset + phdr->caplen >= nstrace->page_len)
2162 /* Start on the next page */
2163 if (wtap_dump_file_seek(wdh, (nstrace->page_len - nstrace->page_offset), SEEK_CUR, err) == -1)
2166 nstrace->page_offset = 0;
2168 /* Possibly add signature and abstime records and increment offset */
2169 if (!nstrace_add_signature(wdh, err))
2173 /* Write the actual record as is */
2174 if (!wtap_dump_file_write(wdh, pd, phdr->caplen, err))
2177 nstrace->page_offset += (guint16) phdr->caplen;
2182 case NSPR_HEADER_VERSION300:
2183 case NSPR_HEADER_VERSION350:
2184 if (wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_1_0)
2186 *err = WTAP_ERR_UNWRITABLE_FILE_TYPE;
2188 } else if (wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_2_0)
2190 *err = WTAP_ERR_UNWRITABLE_FILE_TYPE;
2192 } else if (wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_3_0 || wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_3_5)
2194 if (nstrace->page_offset + phdr->caplen >= nstrace->page_len)
2196 /* Start on the next page */
2197 if (wtap_dump_file_seek(wdh, (nstrace->page_len - nstrace->page_offset), SEEK_CUR, err) == -1)
2200 nstrace->page_offset = 0;
2202 /* Possibly add signature and abstime records and increment offset */
2203 if (!nstrace_add_signature(wdh, err))
2207 /* Write the actual record as is */
2208 if (!wtap_dump_file_write(wdh, pd, phdr->caplen, err))
2211 nstrace->page_offset += (guint16) phdr->caplen;
2214 g_assert_not_reached();
2220 g_assert_not_reached();
2228 * Editor modelines - http://www.wireshark.org/tools/modelines.html
2233 * indent-tabs-mode: nil
2236 * vi: set shiftwidth=4 tabstop=8 expandtab:
2237 * :indentSize=4:tabSize=8:noTabs=true: