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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 #include "file_wrappers.h"
29 #include "netscaler.h"
31 /* Defines imported from netscaler code: nsperfrc.h */
33 #define NSPR_SIGSTR_V10 "NetScaler Performance Data"
34 #define NSPR_SIGSTR_V20 "NetScaler V20 Performance Data"
35 #define NSPR_SIGSTR NSPR_SIGSTR_V20
36 /* Defined but not used */
37 #define NSPR_SIGSTR_V21 "NetScaler V21 Performance Data"
38 #define NSPR_SIGSTR_V22 "NetScaler V22 Performance Data"
39 #define NSPR_SIGSTR_V30 "Netscaler V30 Performance Data"
42 * NetScaler trace files are divided into 8K pages, with each page
43 * containing one or more records. The last page of the file
44 * might be less than 8K bytes.
46 * Records are not split across page boundaries; if a record doesn't
47 * fit in what remains in a page, the page is padded with null bytes
48 * and the next record is put at the beginning of the next page.
49 * A record type value of 0 means "unused space", so if there are
50 * enough null bytes to constitute a record type value, it will
51 * look as if there's an "unused space" record (which has no fields
52 * other than the type and zero or more additional padding bytes).
54 #define NSPR_PAGESIZE 8192
55 #define NSPR_PAGESIZE_TRACE (2*NSPR_PAGESIZE)
57 /* The different record types
58 ** NOTE: The Record Type is two byte fields and unused space is recognized by
59 ** either bytes being zero, therefore no record should any byte value as
62 ** New Performance Record Type is only one byte.
64 #define NSPR_UNUSEDSPACE_V10 0x0000 /* rest of the page is unused */
65 #define NSPR_UNUSEDSPACE_V20 0x00 /* rest of the page is unused */
66 #define NSPR_SIGNATURE_V10 0x0101 /* signature */
67 #define NSPR_SIGNATURE_V20 0x01 /* signature */
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 0x80
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_ABSTIME_V10 and NSPR_SYSTARTIME_V10 structure */
184 typedef struct nspr_abstime_v10
186 nspr_header_v10_t phd; /* performance header */
187 guint8 abs_RelTime[4]; /* relative time is ms from last time */
188 guint8 abs_Time[4]; /* absolute time in seconds from 1970 */
189 } nspr_abstime_v10_t;
190 #define nspr_abstime_v10_s ((guint32)sizeof(nspr_abstime_v10_t))
193 /* NSPR_ABSTIME_V20 and NSPR_SYSTARTIME_V20 structure */
194 typedef struct nspr_abstime_v20
196 NSPR_HEADER_V20(abs); /* short performance header */
197 guint8 abs_RelTime[2]; /* relative time is ms from last time */
198 guint8 abs_Time[4]; /* absolute time in seconds from 1970 */
199 } nspr_abstime_v20_t;
200 #define nspr_abstime_v20_s ((guint32)sizeof(nspr_abstime_v20_t))
204 /* full packet trace structure */
205 typedef struct nspr_pktracefull_v10
207 nspr_headerdev_v10_t phd; /* performance header */
208 guint8 fp_RelTimeHr[4]; /* High resolution relative time */
209 guint8 fp_Data[1]; /* packet data starts here */
210 } nspr_pktracefull_v10_t;
211 #define nspr_pktracefull_v10_s (nspr_hdev_v10_s + 4)
213 /* new full packet trace structure v20 */
214 typedef struct nspr_pktracefull_v20
216 NSPR_HEADER3B_V20(fp); /* long performance header */
217 guint8 fp_DevNo; /* Network Device (NIC) number */
218 guint8 fp_RelTimeHr[4]; /* High resolution relative time */
219 guint8 fp_Data[4]; /* packet data starts here */
220 } nspr_pktracefull_v20_t;
221 #define nspr_pktracefull_v20_s ((guint32)(sizeof(nspr_pktracefull_v20_t) - 4))
223 /* new full packet trace structure v21 */
224 typedef struct nspr_pktracefull_v21
226 NSPR_HEADER3B_V21(fp); /* long performance header */
227 guint8 fp_DevNo; /* Network Device (NIC) number */
228 guint8 fp_RelTimeHr[4]; /* High resolution relative time */
229 guint8 fp_PcbDevNo[4]; /* PCB devno */
230 guint8 fp_lPcbDevNo[4]; /* link PCB devno */
231 guint8 fp_Data[4]; /* packet data starts here */
232 } nspr_pktracefull_v21_t;
233 #define nspr_pktracefull_v21_s ((guint32)(sizeof(nspr_pktracefull_v21_t) - 4))
235 /* new full packet trace structure v22 */
236 typedef struct nspr_pktracefull_v22
238 NSPR_HEADER3B_V22(fp); /* long performance header */
239 guint8 fp_DevNo; /* Network Device (NIC) number */
240 guint8 fp_RelTimeHr[4]; /* High resolution relative time */
241 guint8 fp_PcbDevNo[4]; /* PCB devno */
242 guint8 fp_lPcbDevNo[4]; /* link PCB devno */
243 guint8 fp_VlanTag[2]; /* vlan tag */
244 guint8 fp_Data[2]; /* packet data starts here */
245 } nspr_pktracefull_v22_t;
246 #define nspr_pktracefull_v22_s ((guint32)(sizeof(nspr_pktracefull_v22_t) - 2))
248 typedef struct nspr_pktracefull_v23
250 NSPR_HEADER3B_V22(fp); /* long performance header */
251 guint8 fp_DevNo; /* Network Device (NIC) number */
252 guint8 fp_AbsTimeHr[8]; /* High resolution absolute time */
253 guint8 fp_PcbDevNo[4]; /* PCB devno */
254 guint8 fp_lPcbDevNo[4]; /* link PCB devno */
255 guint8 fp_VlanTag[2]; /* vlan tag */
256 guint8 fp_Coreid[2]; /* coreid of the packet */
257 guint8 fp_Data[2]; /* packet data starts here */
258 } nspr_pktracefull_v23_t;
259 #define nspr_pktracefull_v23_s ((guint32)(sizeof(nspr_pktracefull_v23_t) - 2))
261 /* New full packet trace structure v24 for cluster tracing */
262 typedef struct nspr_pktracefull_v24
264 NSPR_HEADER3B_V22(fp); /* long performance header */
265 guint8 fp_DevNo; /* Network Device (NIC) number */
266 guint8 fp_AbsTimeHr[8]; /* High resolution absolute time in nanosec */
267 guint8 fp_PcbDevNo[4]; /* PCB devno */
268 guint8 fp_lPcbDevNo[4]; /* link PCB devno */
269 guint8 fp_VlanTag[2]; /* vlan tag */
270 guint8 fp_Coreid[2]; /* coreid of the packet */
271 guint8 fp_srcNodeId[2]; /* source node # */
272 guint8 fp_destNodeId[2]; /* destination node # */
273 guint8 fp_clFlags; /* cluster flags */
274 guint8 fp_Data[2]; /* packet data starts here */
275 } nspr_pktracefull_v24_t;
276 #define nspr_pktracefull_v24_s ((guint32)(sizeof(nspr_pktracefull_v24_t) - 4))
278 /* New full packet trace structure v25 for vm info tracing */
279 typedef struct nspr_pktracefull_v25
281 NSPR_HEADER3B_V22(fp); /* long performance header */
282 guint8 fp_DevNo; /* Network Device (NIC) number */
283 guint8 fp_AbsTimeHr[8]; /* High resolution absolute time in nanosec */
284 guint8 fp_PcbDevNo[4]; /* PCB devno */
285 guint8 fp_lPcbDevNo[4]; /* link PCB devno */
286 guint8 fp_VlanTag[2]; /* vlan tag */
287 guint8 fp_Coreid[2]; /* coreid of the packet */
288 guint8 fp_srcNodeId[2]; /* source node # */
289 guint8 fp_destNodeId[2]; /* destination node # */
290 guint8 fp_clFlags; /* cluster flags */
291 guint8 fp_src_vmname_len; /* vm src info */
292 guint8 fp_dst_vmname_len; /* vm src info */
293 guint8 fp_Data[4]; /* packet data starts here */
294 } nspr_pktracefull_v25_t;
295 #define nspr_pktracefull_v25_s ((guint32)(sizeof(nspr_pktracefull_v25_t) - 4))
296 #define fp_src_vmname fp_Data
297 #define fp_src_vmname fp_Data
299 /* New full packet trace structure v26 for vm info tracing */
300 typedef struct nspr_pktracefull_v26
302 NSPR_HEADER3B_V22(fp); /* long performance header */
303 guint8 fp_DevNo; /* Network Device (NIC) number */
304 guint8 fp_AbsTimeHr[8]; /* High resolution absolute time in nanosec */
305 guint8 fp_PcbDevNo[4]; /* PCB devno */
306 guint8 fp_lPcbDevNo[4]; /* link PCB devno */
307 guint8 fp_VlanTag[2]; /* vlan tag */
308 guint8 fp_Coreid[2]; /* coreid of the packet */
309 guint8 fp_srcNodeId[2]; /* source node # */
310 guint8 fp_destNodeId[2]; /* destination node # */
311 guint8 fp_clFlags; /* cluster flags */
312 guint8 fp_src_vmname_len; /* vm src info */
313 guint8 fp_dst_vmname_len; /* vm src info */
315 guint8 fp_ns_activity[4];
316 guint8 fp_reserved_32[12]; /* Adding more field to reduce wireshark changes every time */
317 guint8 fp_Data[4]; /* packet data starts here */
318 } nspr_pktracefull_v26_t;
319 #define nspr_pktracefull_v26_s ((guint32)(sizeof(nspr_pktracefull_v26_t) - 4))
321 /* partial packet trace structure */
322 typedef struct nspr_pktracepart_v10
324 nspr_headerdev_v10_t phd; /* performance header */
325 guint8 pp_RelTimeHr[4]; /* High resolution relative time */
326 guint8 pp_PktSizeOrg[2]; /* Original packet size */
327 guint8 pp_PktOffset[2]; /* starting offset in packet */
328 guint8 pp_Data[1]; /* packet data starts here */
329 } nspr_pktracepart_v10_t;
330 #define nspr_pktracepart_v10_s (nspr_pktracefull_v10_s + 4)
332 /* new partial packet trace structure */
333 typedef struct nspr_pktracepart_v20
335 NSPR_HEADER3B_V20(pp); /* long performance header */
336 guint8 pp_DevNo; /* Network Device (NIC) number */
337 guint8 pp_RelTimeHr[4]; /* High resolution relative time */
338 guint8 pp_PktSizeOrg[2]; /* Original packet size */
339 guint8 pp_PktOffset[2]; /* starting offset in packet */
340 guint8 pp_Data[4]; /* packet data starts here */
341 } nspr_pktracepart_v20_t;
342 #define nspr_pktracepart_v20_s ((guint32)(sizeof(nspr_pktracepart_v20_t) -4))
344 /* new partial packet trace structure */
345 typedef struct nspr_pktracepart_v21
347 NSPR_HEADER3B_V21(pp); /* long performance header */
348 guint8 pp_DevNo; /* Network Device (NIC) number */
349 guint8 pp_RelTimeHr[4]; /* High resolution relative time */
350 guint8 pp_PktSizeOrg[2]; /* Original packet size */
351 guint8 pp_PktOffset[2]; /* starting offset in packet */
352 guint8 pp_PcbDevNo[4]; /* PCB devno */
353 guint8 pp_lPcbDevNo[4]; /* link PCB devno */
354 guint8 pp_Data[4]; /* packet data starts here */
355 } nspr_pktracepart_v21_t;
356 #define nspr_pktracepart_v21_s ((guint32)(sizeof(nspr_pktracepart_v21_t) -4))
358 /* new partial packet trace structure v22 */
359 typedef struct nspr_pktracepart_v22
361 NSPR_HEADER3B_V22(pp); /* long performance header */
362 guint8 pp_DevNo; /* Network Device (NIC) number */
363 guint8 pp_RelTimeHr[4]; /* High resolution relative time */
364 guint8 pp_PktSizeOrg[2]; /* Original packet size */
365 guint8 pp_PktOffset[2]; /* starting offset in packet */
366 guint8 pp_PcbDevNo[4]; /* PCB devno */
367 guint8 pp_lPcbDevNo[4]; /* link PCB devno */
368 guint8 pp_VlanTag[2]; /* Vlan Tag */
369 guint8 pp_Data[2]; /* packet data starts here */
370 } nspr_pktracepart_v22_t;
371 #define nspr_pktracepart_v22_s ((guint32)(sizeof(nspr_pktracepart_v22_t) -2))
373 typedef struct nspr_pktracepart_v23
375 NSPR_HEADER3B_V22(pp); /* long performance header */
376 guint8 pp_DevNo; /* Network Device (NIC) number */
377 guint8 pp_AbsTimeHr[8]; /* High resolution absolute time */
378 guint8 pp_PktSizeOrg[2]; /* Original packet size */
379 guint8 pp_PktOffset[2]; /* starting offset in packet */
380 guint8 pp_PcbDevNo[4]; /* PCB devno */
381 guint8 pp_lPcbDevNo[4]; /* link PCB devno */
382 guint8 pp_VlanTag[2]; /* vlan tag */
383 guint8 pp_Coreid[2]; /* Coreid of the packet */
384 guint8 pp_Data[4]; /* packet data starts here */
385 } nspr_pktracepart_v23_t;
386 #define nspr_pktracepart_v23_s ((guint32)(sizeof(nspr_pktracepart_v23_t) -4))
388 /* New partial packet trace structure v24 for cluster tracing */
389 typedef struct nspr_pktracepart_v24
391 NSPR_HEADER3B_V22(pp); /* long performance header */
392 guint8 pp_DevNo; /* Network Device (NIC) number */
393 guint8 pp_AbsTimeHr[8]; /*High resolution absolute time in nanosec*/
394 guint8 pp_PktSizeOrg[2]; /* Original packet size */
395 guint8 pp_PktOffset[2]; /* starting offset in packet */
396 guint8 pp_PcbDevNo[4]; /* PCB devno */
397 guint8 pp_lPcbDevNo[4]; /* link PCB devno */
398 guint8 pp_VlanTag[2]; /* vlan tag */
399 guint8 pp_Coreid[2]; /* Coreid of the packet */
400 guint8 pp_srcNodeId[2]; /* source node # */
401 guint8 pp_destNodeId[2]; /* destination node # */
402 guint8 pp_clFlags; /* cluster flags */
403 guint8 pp_Data[4]; /* packet data starts here */
404 } nspr_pktracepart_v24_t;
405 #define nspr_pktracepart_v24_s ((guint32)(sizeof(nspr_pktracepart_v24_t) -4))
407 /* New partial packet trace structure v25 for vm info tracing */
408 typedef struct nspr_pktracepart_v25
410 NSPR_HEADER3B_V22(pp); /* long performance header */
411 guint8 pp_DevNo; /* Network Device (NIC) number */
412 guint8 pp_AbsTimeHr[8]; /*High resolution absolute time in nanosec*/
413 guint8 pp_PktSizeOrg[2]; /* Original packet size */
414 guint8 pp_PktOffset[2]; /* starting offset in packet */
415 guint8 pp_PcbDevNo[4]; /* PCB devno */
416 guint8 pp_lPcbDevNo[4]; /* link PCB devno */
417 guint8 pp_VlanTag[2]; /* vlan tag */
418 guint8 pp_Coreid[2]; /* Coreid of the packet */
419 guint8 pp_srcNodeId[2]; /* source node # */
420 guint8 pp_destNodeId[2]; /* destination node # */
421 guint8 pp_clFlags; /* cluster flags */
422 guint8 pp_src_vmname_len; /* vm info */
423 guint8 pp_dst_vmname_len; /* vm info */
424 guint8 pp_Data[4]; /* packet data starts here */
425 } nspr_pktracepart_v25_t;
426 #define nspr_pktracepart_v25_s ((guint32)(sizeof(nspr_pktracepart_v25_t) -4))
427 #define pp_src_vmname pp_Data
428 #define pp_dst_vmname pp_Data
431 /* New full packet trace structure v30 for multipage spanning data */
432 typedef struct nspr_pktracefull_v30
434 NSPR_HEADER3B_V30(fp); /* long performance header */
435 guint8 fp_DevNo; /* Network Device (NIC) number */
436 guint8 fp_AbsTimeHr[8]; /*High resolution absolute time in nanosec*/
437 guint8 fp_PcbDevNo[4]; /* PCB devno */
438 guint8 fp_lPcbDevNo[4]; /* link PCB devno */
439 guint8 fp_PktSizeOrg[2]; /* Original packet size */
440 guint8 fp_VlanTag[2]; /* vlan tag */
441 guint8 fp_Coreid[2]; /* coreid of the packet */
442 guint8 fp_srcNodeId[2]; /* cluster nodeid of the packet */
443 guint8 fp_destNodeId[2];
445 guint8 fp_src_vmname_len;
446 guint8 fp_dst_vmname_len;
447 guint8 fp_reserved[3];
448 guint8 fp_ns_activity[4];
449 guint8 fp_reserved_32[12];
450 guint8 fp_Data[0]; /* packet data starts here */
451 } nspr_pktracefull_v30_t;
452 #define nspr_pktracefull_v30_s (sizeof(nspr_pktracefull_v30_t))
453 #define fp_src_vmname fp_Data
454 #define fp_dst_vmname fp_Data
456 /* New partial packet trace structure v26 for vm info tracing */
457 typedef struct nspr_pktracepart_v26
459 NSPR_HEADER3B_V22(pp); /* long performance header */
460 guint8 pp_DevNo; /* Network Device (NIC) number */
461 guint8 pp_AbsTimeHr[8]; /*High resolution absolute time in nanosec*/
462 guint8 pp_PktSizeOrg[2]; /* Original packet size */
463 guint8 pp_PktOffset[2]; /* starting offset in packet */
464 guint8 pp_PcbDevNo[4]; /* PCB devno */
465 guint8 pp_lPcbDevNo[4]; /* link PCB devno */
466 guint8 pp_VlanTag[2]; /* vlan tag */
467 guint8 pp_Coreid[2]; /* Coreid of the packet */
468 guint8 pp_srcNodeId[2]; /* source node # */
469 guint8 pp_destNodeId[2]; /* destination node # */
470 guint8 pp_clFlags; /* cluster flags */
471 guint8 pp_src_vmname_len; /* vm info */
472 guint8 pp_dst_vmname_len; /* vm info */
474 guint8 pp_ns_activity[4];
475 guint8 pp_reserved_32[12]; /* Adding more field to reduce wireshark changes every time */
476 guint8 pp_Data[4]; /* packet data starts here */
477 } nspr_pktracepart_v26_t;
478 #define nspr_pktracepart_v26_s ((guint32)(sizeof(nspr_pktracepart_v26_t) -4))
480 #define myoffsetof(type,fieldname) (&(((type*)0)->fieldname))
482 #define __TNO(phdr,enumprefix,structprefix,structname,hdrname,structfieldname) \
483 guint8 enumprefix##_##hdrname##_offset = (guint8)GPOINTER_TO_INT(myoffsetof(nspr_##structname##_t,structprefix##_##structfieldname));
485 #define __TNL(phdr,enumprefix,structprefix,structname,hdrname,structfieldname) \
486 guint8 enumprefix##_##hdrname##_len = (guint8)sizeof(((nspr_##structname##_t*)0)->structprefix##_##structfieldname);
488 #define __TNV1O(phdr,enumprefix,structprefix,structname,hdrname,structfieldname) \
489 guint8 enumprefix##_##hdrname##_offset = (guint8)GPOINTER_TO_INT(myoffsetof(nspr_##structname##_t,structfieldname));
491 #define __TNV1L(phdr,enumprefix,structprefix,structname,hdrname,structfieldname) \
492 guint8 enumprefix##_##hdrname##_len = (guint8)sizeof(((nspr_##structname##_t*)0)->structfieldname);
494 #define TRACE_V10_REC_LEN_OFF(phdr,enumprefix,structprefix,structname) \
495 __TNV1O(phdr,enumprefix,structprefix,structname,dir,phd.ph_RecordType)\
496 __TNV1L(phdr,enumprefix,structprefix,structname,dir,phd.ph_RecordType)\
497 __TNV1O(phdr,enumprefix,structprefix,structname,nicno,phd.ph_DevNo)\
498 __TNV1L(phdr,enumprefix,structprefix,structname,nicno,phd.ph_DevNo)\
499 __TNO(phdr,enumprefix,structprefix,structname,eth,Data)
501 #define TRACE_FULL_V10_REC_LEN_OFF(phdr,enumprefix,structprefix,structname) \
502 (phdr)->len = pletohs(&(fp)->nsprRecordSize);\
503 (phdr)->caplen = (phdr)->len;\
504 TRACE_V10_REC_LEN_OFF(phdr,enumprefix,structprefix,structname)
506 #define TRACE_PART_V10_REC_LEN_OFF(phdr,enumprefix,structprefix,structname) \
507 (phdr)->presence_flags |= WTAP_HAS_CAP_LEN;\
508 (phdr)->len = pletohs(&pp->pp_PktSizeOrg) + nspr_pktracepart_v10_s;\
509 (phdr)->caplen = pletohs(&pp->nsprRecordSize);\
510 TRACE_V10_REC_LEN_OFF(phdr,enumprefix,structprefix,structname)
512 #define TRACE_V20_REC_LEN_OFF(phdr,enumprefix,structprefix,structname) \
513 __TNO(phdr,enumprefix,structprefix,structname,dir,RecordType)\
514 __TNL(phdr,enumprefix,structprefix,structname,dir,RecordType)\
515 __TNO(phdr,enumprefix,structprefix,structname,nicno,DevNo)\
516 __TNL(phdr,enumprefix,structprefix,structname,nicno,DevNo)\
517 __TNO(phdr,enumprefix,structprefix,structname,eth,Data)
519 #define TRACE_V21_REC_LEN_OFF(phdr,enumprefix,structprefix,structname) \
520 TRACE_V20_REC_LEN_OFF(phdr,enumprefix,structprefix,structname)\
521 __TNO(phdr,enumprefix,structprefix,structname,pcb,PcbDevNo)\
522 __TNO(phdr,enumprefix,structprefix,structname,l_pcb,lPcbDevNo)
524 #define TRACE_V22_REC_LEN_OFF(phdr,enumprefix,structprefix,structname) \
525 TRACE_V21_REC_LEN_OFF(phdr,enumprefix,structprefix,structname)\
526 __TNO(phdr,enumprefix,structprefix,structname,vlantag,VlanTag)
528 #define TRACE_V23_REC_LEN_OFF(phdr,enumprefix,structprefix,structname) \
529 TRACE_V22_REC_LEN_OFF(phdr,enumprefix,structprefix,structname)\
530 __TNO(phdr,enumprefix,structprefix,structname,coreid,Coreid)
532 #define TRACE_V24_REC_LEN_OFF(phdr,enumprefix,structprefix,structname) \
533 TRACE_V23_REC_LEN_OFF(phdr,enumprefix,structprefix,structname)\
534 __TNO(phdr,enumprefix,structprefix,structname,srcnodeid,srcNodeId)\
535 __TNO(phdr,enumprefix,structprefix,structname,destnodeid,destNodeId)\
536 __TNO(phdr,enumprefix,structprefix,structname,clflags,clFlags)
538 #define TRACE_V25_REC_LEN_OFF(phdr,enumprefix,structprefix,structname) \
539 TRACE_V24_REC_LEN_OFF(phdr,enumprefix,structprefix,structname)\
540 __TNO(phdr,enumprefix,structprefix,structname,src_vmname_len,src_vmname_len)\
541 __TNO(phdr,enumprefix,structprefix,structname,dst_vmname_len,dst_vmname_len)\
542 __TNO(phdr,enumprefix,structprefix,structname,data,Data)
545 #define TRACE_V26_REC_LEN_OFF(phdr,enumprefix,structprefix,structname) \
546 TRACE_V25_REC_LEN_OFF(phdr,enumprefix,structprefix,structname)\
547 __TNO(phdr,enumprefix,structprefix,structname,ns_activity,ns_activity)\
549 #define TRACE_V30_REC_LEN_OFF(phdr, enumprefix, structprefix, structname) \
550 TRACE_V26_REC_LEN_OFF(phdr,enumprefix,structprefix,structname) \
552 TRACE_V10_REC_LEN_OFF(NULL,v10_part,pp,pktracepart_v10)
553 TRACE_V10_REC_LEN_OFF(NULL,v10_full,fp,pktracefull_v10)
554 TRACE_V20_REC_LEN_OFF(NULL,v20_part,pp,pktracepart_v20)
555 TRACE_V20_REC_LEN_OFF(NULL,v20_full,fp,pktracefull_v20)
556 TRACE_V21_REC_LEN_OFF(NULL,v21_part,pp,pktracepart_v21)
557 TRACE_V21_REC_LEN_OFF(NULL,v21_full,fp,pktracefull_v21)
558 TRACE_V22_REC_LEN_OFF(NULL,v22_part,pp,pktracepart_v22)
559 TRACE_V22_REC_LEN_OFF(NULL,v22_full,fp,pktracefull_v22)
560 TRACE_V23_REC_LEN_OFF(NULL,v23_part,pp,pktracepart_v23)
561 TRACE_V23_REC_LEN_OFF(NULL,v23_full,fp,pktracefull_v23)
562 TRACE_V24_REC_LEN_OFF(NULL,v24_part,pp,pktracepart_v24)
563 TRACE_V24_REC_LEN_OFF(NULL,v24_full,fp,pktracefull_v24)
564 TRACE_V25_REC_LEN_OFF(NULL,v25_part,pp,pktracepart_v25)
565 TRACE_V25_REC_LEN_OFF(NULL,v25_full,fp,pktracefull_v25)
566 TRACE_V26_REC_LEN_OFF(NULL,v26_part,pp,pktracepart_v26)
567 TRACE_V26_REC_LEN_OFF(NULL,v26_full,fp,pktracefull_v26)
568 TRACE_V30_REC_LEN_OFF(NULL,v30_full,fp,pktracefull_v30)
576 #define ns_setabstime(nstrace, AbsoluteTime, RelativeTimems) \
578 (nstrace)->nspm_curtime = AbsoluteTime; \
579 (nstrace)->nspm_curtimemsec += RelativeTimems; \
580 (nstrace)->nspm_curtimelastmsec = nstrace->nspm_curtimemsec; \
584 #define ns_setrelativetime(nstrace, RelativeTimems) \
587 (nstrace)->nspm_curtimemsec += RelativeTimems; \
588 rsec = (guint32)((nstrace)->nspm_curtimemsec - (nstrace)->nspm_curtimelastmsec)/1000; \
589 (nstrace)->nspm_curtime += rsec; \
590 (nstrace)->nspm_curtimelastmsec += rsec * 1000; \
597 gint32 nstrace_buf_offset;
598 gint32 nstrace_buflen;
599 /* Performance Monitor Time variables */
600 guint32 nspm_curtime; /* current time since 1970 */
601 guint64 nspm_curtimemsec; /* current time in milliseconds */
602 guint64 nspm_curtimelastmsec; /* nspm_curtime last update time in milliseconds */
603 guint64 nsg_creltime;
607 static guint32 nspm_signature_version(wtap*, gchar*, gint32);
608 static gboolean nstrace_read_v10(wtap *wth, int *err, gchar **err_info,
609 gint64 *data_offset);
610 static gboolean nstrace_read_v20(wtap *wth, int *err, gchar **err_info,
611 gint64 *data_offset);
612 static gboolean nstrace_read_v30(wtap *wth, int *err, gchar **err_info,
613 gint64 *data_offset);
614 static gboolean nstrace_seek_read_v10(wtap *wth, gint64 seek_off,
615 struct wtap_pkthdr *phdr,
616 Buffer *buf, int length,
617 int *err, gchar **err_info);
618 static gboolean nstrace_seek_read_v20(wtap *wth, gint64 seek_off,
619 struct wtap_pkthdr *phdr,
620 Buffer *buf, int length,
621 int *err, gchar **err_info);
622 static gboolean nstrace_seek_read_v30(wtap *wth, gint64 seek_off,
623 struct wtap_pkthdr *phdr,
624 Buffer *buf, int length,
625 int *err, gchar **err_info);
626 static void nstrace_close(wtap *wth);
628 static gboolean nstrace_set_start_time_v10(wtap *wth);
629 static gboolean nstrace_set_start_time_v20(wtap *wth);
630 static gboolean nstrace_set_start_time(wtap *wth);
631 static guint64 ns_hrtime2nsec(guint32 tm);
633 static gboolean nstrace_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
634 const guint8 *pd, int *err);
638 * Minimum of the page size and the amount of data left in the file;
639 * the last page of a file can be short.
641 #define GET_READ_PAGE_SIZE(remaining_file_size) ((gint32)((remaining_file_size>NSPR_PAGESIZE)?NSPR_PAGESIZE:remaining_file_size))
642 #define GET_READ_PAGE_SIZEV3(remaining_file_size) ((gint32)((remaining_file_size>NSPR_PAGESIZE_TRACE)?NSPR_PAGESIZE_TRACE:remaining_file_size))
644 static guint64 ns_hrtime2nsec(guint32 tm)
646 guint32 val = tm & NSPR_HRTIME_MASKTM;
647 switch(tm & NSPR_HRTIME_MASKFMT)
649 case NSPR_HRTIME_SEC: return (guint64)val*1000000000;
650 case NSPR_HRTIME_MSEC: return (guint64)val*1000000;
651 case NSPR_HRTIME_USEC: return (guint64)val*1000;
652 case NSPR_HRTIME_NSEC: return val;
659 ** Netscaler trace format open routines
661 int nstrace_open(wtap *wth, int *err, gchar **err_info)
669 errno = WTAP_ERR_CANT_READ;
671 if ((file_size = wtap_file_size(wth, err)) == -1)
674 nstrace_buf = (gchar *)g_malloc(NSPR_PAGESIZE);
675 page_size = GET_READ_PAGE_SIZE(file_size);
677 switch ((wth->file_type = nspm_signature_version(wth, nstrace_buf, page_size)))
679 case WTAP_FILE_NETSCALER_1_0:
680 wth->file_encap = WTAP_ENCAP_NSTRACE_1_0;
683 case WTAP_FILE_NETSCALER_2_0:
684 wth->file_encap = WTAP_ENCAP_NSTRACE_2_0;
687 case WTAP_FILE_NETSCALER_3_0:
688 wth->file_encap = WTAP_ENCAP_NSTRACE_3_0;
690 nstrace_buf = (gchar *)g_malloc(NSPR_PAGESIZE_TRACE);
691 page_size = GET_READ_PAGE_SIZEV3(file_size);
695 *err = WTAP_ERR_UNSUPPORTED;
696 *err_info = g_strdup_printf("nstrace: file type %d unsupported", wth->file_type);
701 if ((file_seek(wth->fh, 0, SEEK_SET, err)) == -1)
703 *err = file_error(wth->fh, err_info);
708 bytes_read = file_read(nstrace_buf, page_size, wth->fh);
709 if (bytes_read != page_size)
711 *err = file_error(wth->fh, err_info);
713 if (*err != 0 && *err != WTAP_ERR_SHORT_READ)
718 switch (wth->file_type)
720 case WTAP_FILE_NETSCALER_1_0:
721 wth->subtype_read = nstrace_read_v10;
722 wth->subtype_seek_read = nstrace_seek_read_v10;
725 case WTAP_FILE_NETSCALER_2_0:
726 wth->subtype_read = nstrace_read_v20;
727 wth->subtype_seek_read = nstrace_seek_read_v20;
730 case WTAP_FILE_NETSCALER_3_0:
731 wth->subtype_read = nstrace_read_v30;
732 wth->subtype_seek_read = nstrace_seek_read_v30;
735 wth->subtype_close = nstrace_close;
737 nstrace = (nstrace_t *)g_malloc(sizeof(nstrace_t));
738 wth->priv = (void *)nstrace;
739 nstrace->pnstrace_buf = nstrace_buf;
740 nstrace->xxx_offset = 0;
741 nstrace->nstrace_buflen = page_size;
742 nstrace->nstrace_buf_offset = 0;
743 nstrace->nspm_curtime = 0;
744 nstrace->nspm_curtimemsec = 0;
745 nstrace->nspm_curtimelastmsec = 0;
746 nstrace->nsg_creltime = 0;
747 nstrace->file_size = file_size;
750 /* Set the start time by looking for the abstime record */
751 if ((nstrace_set_start_time(wth)) == FALSE)
753 /* Reset the read pointer to start of the file. */
754 if ((file_seek(wth->fh, 0, SEEK_SET, err)) == -1)
756 *err = file_error(wth->fh, err_info);
757 g_free(nstrace->pnstrace_buf);
762 /* Read the first page of data */
763 bytes_read = file_read(nstrace_buf, page_size, wth->fh);
764 if (bytes_read != page_size)
766 *err = file_error(wth->fh, err_info);
767 g_free(nstrace->pnstrace_buf);
772 /* reset the buffer offset */
773 nstrace->nstrace_buf_offset = 0;
776 wth->tsprecision = WTAP_FILE_TSPREC_NSEC;
777 wth->phdr.ts.secs = nstrace->nspm_curtime;
778 wth->phdr.ts.nsecs = 0;
785 #define nspm_signature_func(ver) \
786 static guint32 nspm_signature_isv##ver(gchar *sigp) {\
787 return strncmp(sigp,NSPR_SIGSTR_V##ver,(sizeof(NSPR_SIGSTR_V##ver)-1));\
790 nspm_signature_func(10)
791 nspm_signature_func(20)
792 nspm_signature_func(30)
795 ** Check signature and return the version number of the signature.
796 ** If not found, it returns 0. At the time of return from this function
797 ** we might not be at the first page. So after a call to this function, there
798 ** has to be a file seek to return to the start of the first page.
801 nspm_signature_version(wtap *wth, gchar *nstrace_buf, gint32 len)
803 gchar *dp = nstrace_buf;
806 bytes_read = file_read(dp, len, wth->fh);
807 if (bytes_read == len) {
809 for ( ; len > (gint32)(MIN(sizeof(NSPR_SIGSTR_V10), sizeof(NSPR_SIGSTR_V20))); dp++, len--)
811 #define sigv10p ((nspr_signature_v10_t*)dp)
812 if ((pletohs(&sigv10p->nsprRecordType) == NSPR_SIGNATURE_V10) &&
813 (pletohs(&sigv10p->nsprRecordSize) <= len) &&
814 ((gint32)sizeof(NSPR_SIGSTR_V10) <= len) &&
815 (!nspm_signature_isv10(sigv10p->sig_Signature)))
816 return WTAP_FILE_NETSCALER_1_0;
819 #define sigv20p ((nspr_signature_v20_t*)dp)
820 if ((sigv20p->sig_RecordType == NSPR_SIGNATURE_V20) &&
821 (sigv20p->sig_RecordSize <= len) &&
822 ((gint32)sizeof(NSPR_SIGSTR_V20) <= len))
824 if (!nspm_signature_isv20(sigv20p->sig_Signature))
825 return WTAP_FILE_NETSCALER_2_0;
826 else if (!nspm_signature_isv30(sigv20p->sig_Signature))
827 return WTAP_FILE_NETSCALER_3_0;
833 return 0; /* no version found */
836 #define nspr_getv10recordtype(hdp) (pletohs(&hdp->nsprRecordType))
837 #define nspr_getv10recordsize(hdp) (pletohs(&hdp->nsprRecordSize))
838 #define nspr_getv20recordtype(hdp) (hdp->phd_RecordType)
839 #define nspr_getv20recordsize(hdp) \
840 (((hdp)->phd_RecordSizeLow & NSPR_V20RECORDSIZE_2BYTES)? \
841 (((hdp)->phd_RecordSizeHigh * NSPR_V20RECORDSIZE_2BYTES)+ \
842 ((hdp)->phd_RecordSizeLow & ~NSPR_V20RECORDSIZE_2BYTES)) : \
843 (hdp)->phd_RecordSizeLow)
846 #define nstrace_set_start_time_ver(ver) \
847 gboolean nstrace_set_start_time_v##ver(wtap *wth) \
849 nstrace_t *nstrace = (nstrace_t *)wth->priv;\
850 gchar* nstrace_buf = nstrace->pnstrace_buf;\
851 gint32 nstrace_buf_offset = nstrace->nstrace_buf_offset;\
852 gint32 nstrace_buflen = nstrace->nstrace_buflen;\
856 while (nstrace_buf_offset < nstrace_buflen)\
858 nspr_hd_v##ver##_t *fp = (nspr_hd_v##ver##_t *) &nstrace_buf[nstrace_buf_offset];\
859 switch (nspr_getv##ver##recordtype(fp))\
861 case NSPR_ABSTIME_V##ver:\
862 ns_setabstime(nstrace, pletohl(&((nspr_abstime_v##ver##_t *) fp)->abs_Time), pletohs(&((nspr_abstime_v##ver##_t *) fp)->abs_RelTime));\
863 nstrace->nstrace_buf_offset = nstrace_buf_offset + nspr_getv##ver##recordsize(fp);\
864 nstrace->nstrace_buflen = nstrace_buflen;\
866 case NSPR_UNUSEDSPACE_V10:\
867 nstrace_buf_offset = nstrace_buflen;\
870 nstrace_buf_offset += nspr_getv##ver##recordsize(fp);\
873 nstrace_buf_offset = 0;\
874 nstrace->xxx_offset += nstrace_buflen;\
875 nstrace_buflen = GET_READ_PAGE_SIZE((nstrace->file_size - nstrace->xxx_offset));\
876 }while((nstrace_buflen > 0) && (bytes_read = file_read(nstrace_buf, nstrace_buflen, wth->fh)) && bytes_read == nstrace_buflen); \
880 nstrace_set_start_time_ver(10)
881 nstrace_set_start_time_ver(20)
883 #undef nspr_getv10recordtype
884 #undef nspr_getv20recordtype
885 #undef nspr_getv10recordsize
888 ** Set the start time of the trace file. We look for the first ABSTIME record. We use that
889 ** to set the start time. Apart from that we also make sure that we remember the position of
890 ** the next record after the ABSTIME record. Inorder to report correct time values, all trace
891 ** records before the ABSTIME record are ignored.
893 static gboolean nstrace_set_start_time(wtap *wth)
895 if (wth->file_type == WTAP_FILE_NETSCALER_1_0)
896 return nstrace_set_start_time_v10(wth);
897 else if (wth->file_type == WTAP_FILE_NETSCALER_2_0)
898 return nstrace_set_start_time_v20(wth);
899 else if (wth->file_type == WTAP_FILE_NETSCALER_3_0)
900 return nstrace_set_start_time_v20(wth);
904 #define __TNO(phdr,enumprefix,structprefix,structname,hdrname,structfieldname) \
905 (phdr)->pseudo_header.nstr.hdrname##_offset = enumprefix##_##hdrname##_offset;
907 #define __TNL(phdr,enumprefix,structprefix,structname,hdrname,structfieldname) \
908 (phdr)->pseudo_header.nstr.hdrname##_len = enumprefix##_##hdrname##_len;
910 #define __TNV1O(phdr,enumprefix,structprefix,structname,hdrname,structfieldname) \
911 __TNO(phdr,enumprefix,structprefix,structname,hdrname,structfieldname)
913 #define __TNV1L(phdr,enumprefix,structprefix,structname,hdrname,structfieldname) \
914 __TNL(phdr,enumprefix,structprefix,structname,hdrname,structfieldname)
919 ** Netscaler trace format read routines.
921 static gboolean nstrace_read_v10(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
923 nstrace_t *nstrace = (nstrace_t *)wth->priv;
924 guint64 nsg_creltime = nstrace->nsg_creltime;
925 gchar *nstrace_buf = nstrace->pnstrace_buf;
926 gint32 nstrace_buf_offset = nstrace->nstrace_buf_offset;
927 gint32 nstrace_buflen = nstrace->nstrace_buflen;
928 nspr_pktracefull_v10_t *fp;
929 nspr_pktracepart_v10_t *pp;
936 while ((nstrace_buf_offset < nstrace_buflen) &&
937 ((nstrace_buflen - nstrace_buf_offset) >= ((gint32)sizeof(fp->nsprRecordType))))
940 #define GENERATE_CASE_FULL(phdr,type,acttype) \
941 case NSPR_PDPKTRACEFULLTX_V##type:\
942 case NSPR_PDPKTRACEFULLTXB_V##type:\
943 case NSPR_PDPKTRACEFULLRX_V##type:\
944 fp = (nspr_pktracefull_v10_t *) &nstrace_buf[nstrace_buf_offset];\
946 * XXX - we can't do this in the seek-read routine,\
947 * as the time stamps in the records are relative to\
948 * the previous packet.\
950 (phdr)->presence_flags = WTAP_HAS_TS;\
951 nsg_creltime += ns_hrtime2nsec(pletohl(&fp->fp_RelTimeHr));\
952 (phdr)->ts.secs = nstrace->nspm_curtime + (guint32) (nsg_creltime / 1000000000);\
953 (phdr)->ts.nsecs = (guint32) (nsg_creltime % 1000000000);\
954 TRACE_FULL_V##type##_REC_LEN_OFF(phdr,v##type##_full,fp,pktracefull_v##type);\
955 buffer_assure_space(wth->frame_buffer, (phdr)->caplen);\
956 memcpy(buffer_start_ptr(wth->frame_buffer), fp, (phdr)->caplen);\
957 *data_offset = nstrace->xxx_offset + nstrace_buf_offset;\
958 nstrace->nstrace_buf_offset = nstrace_buf_offset + (phdr)->len;\
959 nstrace->nstrace_buflen = nstrace_buflen;\
960 nstrace->nsg_creltime = nsg_creltime;\
963 #define GENERATE_CASE_PART(phdr,type,acttype) \
964 case NSPR_PDPKTRACEPARTTX_V##type:\
965 case NSPR_PDPKTRACEPARTTXB_V##type:\
966 case NSPR_PDPKTRACEPARTRX_V##type:\
967 pp = (nspr_pktracepart_v10_t *) &nstrace_buf[nstrace_buf_offset];\
969 * XXX - we can't do this in the seek-read routine,\
970 * as the time stamps in the records are relative to\
971 * the previous packet.\
973 (phdr)->presence_flags = WTAP_HAS_TS;\
974 nsg_creltime += ns_hrtime2nsec(pletohl(&pp->pp_RelTimeHr));\
975 (phdr)->ts.secs = nstrace->nspm_curtime + (guint32) (nsg_creltime / 1000000000);\
976 (phdr)->ts.nsecs = (guint32) (nsg_creltime % 1000000000);\
977 TRACE_PART_V##type##_REC_LEN_OFF(phdr,v##type##_part,pp,pktracepart_v##type);\
978 buffer_assure_space(wth->frame_buffer, (phdr)->caplen);\
979 memcpy(buffer_start_ptr(wth->frame_buffer), pp, (phdr)->caplen);\
980 *data_offset = nstrace->xxx_offset + nstrace_buf_offset;\
981 nstrace->nstrace_buf_offset = nstrace_buf_offset + (phdr)->caplen;\
982 nstrace->nsg_creltime = nsg_creltime;\
983 nstrace->nstrace_buflen = nstrace_buflen;\
986 switch (pletohs(&(( nspr_header_v10_t*)&nstrace_buf[nstrace_buf_offset])->ph_RecordType))
988 GENERATE_CASE_FULL(&wth->phdr,10,100)
989 GENERATE_CASE_PART(&wth->phdr,10,100)
991 #undef GENERATE_CASE_FULL
992 #undef GENERATE_CASE_PART
994 case NSPR_ABSTIME_V10:
996 fp = (nspr_pktracefull_v10_t *) &nstrace_buf[nstrace_buf_offset];
997 ns_setabstime(nstrace, pletohl(((nspr_abstime_v10_t *) fp)->abs_Time), pletohl(&((nspr_abstime_v10_t *) fp)->abs_RelTime));
998 nstrace_buf_offset += pletohs(&fp->nsprRecordSize);
1001 case NSPR_RELTIME_V10:
1003 fp = (nspr_pktracefull_v10_t *) &nstrace_buf[nstrace_buf_offset];
1004 ns_setrelativetime(nstrace, pletohl(((nspr_abstime_v10_t *) fp)->abs_RelTime));
1005 nstrace_buf_offset += pletohs(&fp->nsprRecordSize);
1008 case NSPR_UNUSEDSPACE_V10:
1010 nstrace_buf_offset = nstrace_buflen;
1015 fp = (nspr_pktracefull_v10_t *) &nstrace_buf[nstrace_buf_offset];
1016 nstrace_buf_offset += pletohs(&fp->nsprRecordSize);
1021 nstrace_buf_offset = 0;
1022 nstrace->xxx_offset += nstrace_buflen;
1023 nstrace_buflen = GET_READ_PAGE_SIZE((nstrace->file_size - nstrace->xxx_offset));
1024 }while((nstrace_buflen > 0) && (bytes_read = file_read(nstrace_buf, nstrace_buflen, wth->fh)) && (bytes_read == nstrace_buflen));
1029 #define TIMEDEFV20(fp,type) \
1031 wth->phdr.presence_flags |= WTAP_HAS_TS;\
1032 nsg_creltime += ns_hrtime2nsec(pletohl(fp->type##_RelTimeHr));\
1033 wth->phdr.ts.secs = nstrace->nspm_curtime + (guint32) (nsg_creltime / 1000000000);\
1034 wth->phdr.ts.nsecs = (guint32) (nsg_creltime % 1000000000);\
1037 #define TIMEDEFV23(fp,type) \
1039 wth->phdr.presence_flags |= WTAP_HAS_TS;\
1040 /* access _AbsTimeHr as a 64bit value */\
1041 nsg_creltime = pletohll(fp->type##_AbsTimeHr);\
1042 wth->phdr.ts.secs = (guint32) (nsg_creltime / 1000000000);\
1043 wth->phdr.ts.nsecs = (guint32) (nsg_creltime % 1000000000);\
1046 #define TIMEDEFV21(fp,type) TIMEDEFV20(fp,type)
1047 #define TIMEDEFV22(fp,type) TIMEDEFV20(fp,type)
1048 #define TIMEDEFV24(fp,type) TIMEDEFV23(fp,type)
1049 #define TIMEDEFV25(fp,type) TIMEDEFV24(fp,type)
1050 #define TIMEDEFV26(fp,type) TIMEDEFV24(fp,type)
1052 #define PPSIZEDEFV20(phdr,pp,ver) \
1054 (phdr)->presence_flags |= WTAP_HAS_CAP_LEN;\
1055 (phdr)->len = pletohs(&pp->pp_PktSizeOrg) + nspr_pktracepart_v##ver##_s;\
1056 (phdr)->caplen = nspr_getv20recordsize((nspr_hd_v20_t *)pp);\
1059 #define PPSIZEDEFV21(phdr,pp,ver) PPSIZEDEFV20(phdr,pp,ver)
1060 #define PPSIZEDEFV22(phdr,pp,ver) PPSIZEDEFV20(phdr,pp,ver)
1061 #define PPSIZEDEFV23(phdr,pp,ver) PPSIZEDEFV20(phdr,pp,ver)
1062 #define PPSIZEDEFV24(phdr,pp,ver) PPSIZEDEFV20(phdr,pp,ver)
1063 #define PPSIZEDEFV25(phdr,pp,ver) PPSIZEDEFV20(phdr,pp,ver)
1064 #define PPSIZEDEFV26(phdr,pp,ver) PPSIZEDEFV20(phdr,pp,ver)
1066 #define FPSIZEDEFV20(phdr,fp,ver)\
1068 (phdr)->len = nspr_getv20recordsize((nspr_hd_v20_t *)fp);\
1069 (phdr)->caplen = (phdr)->len;\
1072 #define FPSIZEDEFV21(phdr,fp,ver) FPSIZEDEFV20(phdr,fp,ver)
1073 #define FPSIZEDEFV22(phdr,fp,ver) FPSIZEDEFV20(phdr,fp,ver)
1074 #define FPSIZEDEFV23(phdr,fp,ver) FPSIZEDEFV20(phdr,fp,ver)
1075 #define FPSIZEDEFV24(phdr,fp,ver) FPSIZEDEFV20(phdr,fp,ver)
1076 #define FPSIZEDEFV25(phdr,fp,ver) FPSIZEDEFV20(phdr,fp,ver)
1077 #define FPSIZEDEFV26(phdr,fp,ver) FPSIZEDEFV20(phdr,fp,ver)
1079 #define PACKET_DESCRIBE(phdr,FPTIMEDEF,SIZEDEF,ver,enumprefix,type,structname,TYPE)\
1081 nspr_##structname##_t *fp= (nspr_##structname##_t*)&nstrace_buf[nstrace_buf_offset];\
1082 TIMEDEFV##ver(fp,type);\
1083 SIZEDEF##ver((phdr),fp,ver);\
1084 TRACE_V##ver##_REC_LEN_OFF((phdr),enumprefix,type,structname);\
1085 (phdr)->pseudo_header.nstr.rec_type = NSPR_HEADER_VERSION##TYPE;\
1086 buffer_assure_space(wth->frame_buffer, (phdr)->caplen);\
1087 memcpy(buffer_start_ptr(wth->frame_buffer), fp, (phdr)->caplen);\
1088 *data_offset = nstrace->xxx_offset + nstrace_buf_offset;\
1089 nstrace->nstrace_buf_offset = nstrace_buf_offset + nspr_getv20recordsize((nspr_hd_v20_t *)fp);\
1090 nstrace->nstrace_buflen = nstrace_buflen;\
1091 nstrace->nsg_creltime = nsg_creltime;\
1095 static gboolean nstrace_read_v20(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
1097 nstrace_t *nstrace = (nstrace_t *)wth->priv;
1098 guint64 nsg_creltime = nstrace->nsg_creltime;
1099 gchar *nstrace_buf = nstrace->pnstrace_buf;
1100 gint32 nstrace_buf_offset = nstrace->nstrace_buf_offset;
1101 gint32 nstrace_buflen = nstrace->nstrace_buflen;
1108 while ((nstrace_buf_offset < nstrace_buflen) &&
1109 ((nstrace_buflen - nstrace_buf_offset) >= ((gint32)sizeof((( nspr_hd_v20_t*)&nstrace_buf[nstrace_buf_offset])->phd_RecordType))))
1111 switch ((( nspr_hd_v20_t*)&nstrace_buf[nstrace_buf_offset])->phd_RecordType)
1114 #define GENERATE_CASE_FULL(phdr,type,acttype) \
1115 case NSPR_PDPKTRACEFULLTX_V##type:\
1116 case NSPR_PDPKTRACEFULLTXB_V##type:\
1117 case NSPR_PDPKTRACEFULLRX_V##type:\
1118 PACKET_DESCRIBE(phdr,TIMEDEF,FPSIZEDEFV,type,v##type##_full,fp,pktracefull_v##type,acttype);
1120 #define GENERATE_CASE_FULL_V25(phdr,type,acttype) \
1121 case NSPR_PDPKTRACEFULLTX_V##type:\
1122 case NSPR_PDPKTRACEFULLTXB_V##type:\
1123 case NSPR_PDPKTRACEFULLRX_V##type:\
1124 case NSPR_PDPKTRACEFULLNEWRX_V##type:\
1125 PACKET_DESCRIBE(phdr,TIMEDEF,FPSIZEDEFV,type,v##type##_full,fp,pktracefull_v##type,acttype);
1127 #define GENERATE_CASE_PART(phdr,type,acttype) \
1128 case NSPR_PDPKTRACEPARTTX_V##type:\
1129 case NSPR_PDPKTRACEPARTTXB_V##type:\
1130 case NSPR_PDPKTRACEPARTRX_V##type:\
1131 PACKET_DESCRIBE(phdr,TIMEDEF,PPSIZEDEFV,type,v##type##_part,pp,pktracepart_v##type,acttype);
1133 #define GENERATE_CASE_PART_V25(phdr,type,acttype) \
1134 case NSPR_PDPKTRACEPARTTX_V##type:\
1135 case NSPR_PDPKTRACEPARTTXB_V##type:\
1136 case NSPR_PDPKTRACEPARTRX_V##type:\
1137 case NSPR_PDPKTRACEPARTNEWRX_V##type:\
1138 PACKET_DESCRIBE(phdr,TIMEDEF,PPSIZEDEFV,type,v##type##_part,pp,pktracepart_v##type,acttype);
1140 GENERATE_CASE_FULL(&wth->phdr,20,200);
1141 GENERATE_CASE_PART(&wth->phdr,20,200);
1142 GENERATE_CASE_FULL(&wth->phdr,21,201);
1143 GENERATE_CASE_PART(&wth->phdr,21,201);
1144 GENERATE_CASE_FULL(&wth->phdr,22,202);
1145 GENERATE_CASE_PART(&wth->phdr,22,202);
1146 GENERATE_CASE_FULL(&wth->phdr,23,203);
1147 GENERATE_CASE_PART(&wth->phdr,23,203);
1148 GENERATE_CASE_FULL_V25(&wth->phdr,24,204);
1149 GENERATE_CASE_PART_V25(&wth->phdr,24,204);
1150 GENERATE_CASE_FULL_V25(&wth->phdr,25,205);
1151 GENERATE_CASE_PART_V25(&wth->phdr,25,205);
1152 GENERATE_CASE_FULL_V25(&wth->phdr,26,206);
1153 GENERATE_CASE_PART_V25(&wth->phdr,26,206);
1155 #undef GENERATE_CASE_FULL
1156 #undef GENERATE_CASE_FULL_V25
1157 #undef GENERATE_CASE_PART
1158 #undef GENERATE_CASE_PART_V25
1160 case NSPR_ABSTIME_V20:
1162 nspr_pktracefull_v20_t *fp20 = (nspr_pktracefull_v20_t *) &nstrace_buf[nstrace_buf_offset];
1163 nstrace_buf_offset += nspr_getv20recordsize((nspr_hd_v20_t *)fp20);
1164 ns_setabstime(nstrace, pletohl(&((nspr_abstime_v20_t *) fp20)->abs_Time), pletohs(&((nspr_abstime_v20_t *) fp20)->abs_RelTime));
1168 case NSPR_RELTIME_V20:
1170 nspr_pktracefull_v20_t *fp20 = (nspr_pktracefull_v20_t *) &nstrace_buf[nstrace_buf_offset];
1171 ns_setrelativetime(nstrace, pletohs(&((nspr_abstime_v20_t *) fp20)->abs_RelTime));
1172 nstrace_buf_offset += nspr_getv20recordsize((nspr_hd_v20_t *)fp20);
1176 case NSPR_UNUSEDSPACE_V20:
1178 if (nstrace_buf_offset >= NSPR_PAGESIZE/2)
1179 nstrace_buf_offset = nstrace_buflen;
1181 nstrace_buf_offset = NSPR_PAGESIZE/2;
1187 nspr_pktracefull_v20_t *fp20 = (nspr_pktracefull_v20_t *) &nstrace_buf[nstrace_buf_offset];
1188 nstrace_buf_offset += nspr_getv20recordsize((nspr_hd_v20_t *)fp20);
1194 nstrace_buf_offset = 0;
1195 nstrace->xxx_offset += nstrace_buflen;
1196 nstrace_buflen = GET_READ_PAGE_SIZE((nstrace->file_size - nstrace->xxx_offset));
1197 }while((nstrace_buflen > 0) && (bytes_read = file_read(nstrace_buf, nstrace_buflen, wth->fh)) && (bytes_read == nstrace_buflen));
1202 #undef PACKET_DESCRIBE
1204 static gboolean nstrace_read_v30(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
1206 nstrace_t *nstrace = (nstrace_t *)wth->priv;
1207 guint64 nsg_creltime = nstrace->nsg_creltime;
1208 gchar *nstrace_buf = nstrace->pnstrace_buf;
1209 gint32 nstrace_buf_offset = nstrace->nstrace_buf_offset;
1210 gint32 nstrace_buflen = nstrace->nstrace_buflen;
1211 guint8 nstrace_tmpbuff[65536];
1212 guint32 nstrace_tmpbuff_off=0,nst_dataSize=0,rec_size=0,nsg_nextPageOffset=0;
1220 while ((nstrace_buf_offset < NSPR_PAGESIZE_TRACE) &&
1221 nstrace_buf[nstrace_buf_offset])
1223 hdp = (nspr_hd_v20_t *) &nstrace_buf[nstrace_buf_offset];
1224 switch (hdp->phd_RecordType)
1226 case NSPR_PDPKTRACEFULLTX_V30:
1227 case NSPR_PDPKTRACEFULLTXB_V30:
1228 case NSPR_PDPKTRACEFULLRX_V30:
1229 case NSPR_PDPKTRACEFULLNEWRX_V30:
1231 nspr_pktracefull_v30_t *fp = (nspr_pktracefull_v30_t *) &nstrace_buf[nstrace_buf_offset];
1233 wth->phdr.presence_flags |= WTAP_HAS_TS;
1234 nsg_creltime = pletohll(fp->fp_AbsTimeHr);
1235 wth->phdr.ts.secs = (guint32) (nsg_creltime / 1000000000);
1236 wth->phdr.ts.nsecs = (guint32) (nsg_creltime % 1000000000);
1238 (&wth->phdr)->len = pletohs(&fp->fp_PktSizeOrg) + nspr_pktracefull_v30_s;
1239 (&wth->phdr)->caplen = nspr_getv20recordsize((nspr_hd_v20_t *)fp);
1240 (&wth->phdr)->presence_flags |= WTAP_HAS_CAP_LEN;
1242 TRACE_V30_REC_LEN_OFF((&wth->phdr),v30_full,30,pktracefull_v30);
1244 (&wth->phdr)->pseudo_header.nstr.rec_type = NSPR_HEADER_VERSION300;
1245 buffer_assure_space(wth->frame_buffer, (&wth->phdr)->caplen);
1246 *data_offset = nstrace->xxx_offset + nstrace_buf_offset;
1247 while (nstrace_tmpbuff_off < nspr_pktracefull_v30_s) {
1248 nstrace_tmpbuff[nstrace_tmpbuff_off++] = nstrace_buf[nstrace_buf_offset++];
1250 nst_dataSize = nspr_getv20recordsize(hdp);
1251 rec_size = nst_dataSize - nstrace_tmpbuff_off;
1252 nsg_nextPageOffset = ((nstrace_buf_offset + rec_size) >= NSPR_PAGESIZE_TRACE) ?
1253 ((nstrace_buf_offset + rec_size) - (NSPR_PAGESIZE_TRACE - 1)) : 0;
1254 while (nsg_nextPageOffset) {
1255 while (nstrace_buf_offset < NSPR_PAGESIZE_TRACE) {
1256 nstrace_tmpbuff[nstrace_tmpbuff_off++] = nstrace_buf[nstrace_buf_offset++];
1258 nstrace_buflen = NSPR_PAGESIZE_TRACE;
1259 nstrace->xxx_offset += nstrace_buflen;
1260 bytes_read = file_read(nstrace_buf, NSPR_PAGESIZE_TRACE, wth->fh);
1261 if (bytes_read != NSPR_PAGESIZE_TRACE) {
1264 nstrace_buf_offset = 0;
1266 rec_size = nst_dataSize - nstrace_tmpbuff_off;
1267 nsg_nextPageOffset = ((nstrace_buf_offset + rec_size) >= NSPR_PAGESIZE_TRACE) ?
1268 ((nstrace_buf_offset + rec_size) - (NSPR_PAGESIZE_TRACE- 1)): 0;
1270 while (nstrace_tmpbuff_off < nst_dataSize) {
1271 nstrace_tmpbuff[nstrace_tmpbuff_off++] = nstrace_buf[nstrace_buf_offset++];
1273 memcpy(buffer_start_ptr(wth->frame_buffer), nstrace_tmpbuff, (&wth->phdr)->caplen);
1274 nstrace->nstrace_buf_offset = nstrace_buf_offset;
1275 nstrace->nstrace_buflen = nstrace_buflen = NSPR_PAGESIZE_TRACE;
1276 nstrace->nsg_creltime = nsg_creltime;
1280 case NSPR_ABSTIME_V20:
1282 nstrace_buf_offset += nspr_getv20recordsize(hdp);
1283 ns_setabstime(nstrace, pletohl(&((nspr_abstime_v20_t *) &nstrace_buf[nstrace_buf_offset])->abs_Time), pletohs(&((nspr_abstime_v20_t *) &nstrace_buf[nstrace_buf_offset])->abs_RelTime));
1287 case NSPR_RELTIME_V20:
1289 ns_setrelativetime(nstrace, pletohs(&((nspr_abstime_v20_t *) &nstrace_buf[nstrace_buf_offset])->abs_RelTime));
1290 nstrace_buf_offset += nspr_getv20recordsize(hdp);
1296 nstrace_buf_offset += nspr_getv20recordsize(hdp);
1301 nstrace_buf_offset = 0;
1302 nstrace->xxx_offset += nstrace_buflen;
1303 nstrace_buflen = NSPR_PAGESIZE_TRACE;
1304 } while((nstrace_buflen > 0) && (bytes_read = file_read(nstrace_buf, nstrace_buflen, wth->fh)) && (bytes_read == nstrace_buflen));
1310 static gboolean nstrace_seek_read_v10(wtap *wth, gint64 seek_off,
1311 struct wtap_pkthdr *phdr, Buffer *buf, int length,
1312 int *err, gchar **err_info)
1316 nspr_pktracefull_v10_t *fp;
1317 nspr_pktracepart_v10_t *pp;
1321 if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
1325 ** Read the packet data.
1327 buffer_assure_space(buf, length);
1328 pd = buffer_start_ptr(buf);
1329 bytes_read = file_read(pd, length, wth->random_fh);
1330 if (bytes_read != length) {
1331 *err = file_error(wth->random_fh, err_info);
1333 *err = WTAP_ERR_SHORT_READ;
1337 #define GENERATE_CASE_FULL(phdr,type,acttype) \
1338 case NSPR_PDPKTRACEFULLTX_V##type:\
1339 case NSPR_PDPKTRACEFULLTXB_V##type:\
1340 case NSPR_PDPKTRACEFULLRX_V##type:\
1341 fp = (nspr_pktracefull_v10_t *) pd;\
1342 TRACE_FULL_V##type##_REC_LEN_OFF(phdr,v##type##_full,fp,pktracefull_v##type);\
1343 (phdr)->pseudo_header.nstr.rec_type = NSPR_HEADER_VERSION##acttype;\
1346 #define GENERATE_CASE_PART(phdr,type,acttype) \
1347 case NSPR_PDPKTRACEPARTTX_V##type:\
1348 case NSPR_PDPKTRACEPARTTXB_V##type:\
1349 case NSPR_PDPKTRACEPARTRX_V##type:\
1350 pp = (nspr_pktracepart_v10_t *) pd;\
1351 TRACE_PART_V##type##_REC_LEN_OFF(phdr,v##type##_part,pp,pktracepart_v##type);\
1352 (phdr)->pseudo_header.nstr.rec_type = NSPR_HEADER_VERSION##acttype;\
1355 switch (pletohs(&(( nspr_header_v10_t*)pd)->ph_RecordType))
1357 GENERATE_CASE_FULL(phdr,10,100)
1358 GENERATE_CASE_PART(phdr,10,100)
1361 #undef GENERATE_CASE_FULL
1362 #undef GENERATE_CASE_PART
1367 #define PACKET_DESCRIBE(phdr,FPTIMEDEF,SIZEDEF,ver,enumprefix,type,structname,TYPE)\
1369 nspr_##structname##_t *fp= (nspr_##structname##_t*)pd;\
1370 SIZEDEF##ver((phdr),fp,ver);\
1371 TRACE_V##ver##_REC_LEN_OFF((phdr),enumprefix,type,structname);\
1372 (phdr)->pseudo_header.nstr.rec_type = NSPR_HEADER_VERSION##TYPE;\
1376 static gboolean nstrace_seek_read_v20(wtap *wth, gint64 seek_off,
1377 struct wtap_pkthdr *phdr, Buffer *buf, int length,
1378 int *err, gchar **err_info)
1385 if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
1389 ** Read the packet data.
1391 buffer_assure_space(buf, length);
1392 pd = buffer_start_ptr(buf);
1393 bytes_read = file_read(pd, length, wth->random_fh);
1394 if (bytes_read != length) {
1395 *err = file_error(wth->random_fh, err_info);
1397 *err = WTAP_ERR_SHORT_READ;
1401 #define GENERATE_CASE_FULL(phdr,type,acttype) \
1402 case NSPR_PDPKTRACEFULLTX_V##type:\
1403 case NSPR_PDPKTRACEFULLTXB_V##type:\
1404 case NSPR_PDPKTRACEFULLRX_V##type:\
1405 PACKET_DESCRIBE(phdr,TIMEDEF,FPSIZEDEFV,type,v##type##_full,fp,pktracefull_v##type,acttype);
1407 #define GENERATE_CASE_FULL_V25(phdr,type,acttype) \
1408 case NSPR_PDPKTRACEFULLTX_V##type:\
1409 case NSPR_PDPKTRACEFULLTXB_V##type:\
1410 case NSPR_PDPKTRACEFULLRX_V##type:\
1411 case NSPR_PDPKTRACEFULLNEWRX_V##type:\
1412 PACKET_DESCRIBE(phdr,TIMEDEF,FPSIZEDEFV,type,v##type##_full,fp,pktracefull_v##type,acttype);
1414 #define GENERATE_CASE_PART(phdr,type,acttype) \
1415 case NSPR_PDPKTRACEPARTTX_V##type:\
1416 case NSPR_PDPKTRACEPARTTXB_V##type:\
1417 case NSPR_PDPKTRACEPARTRX_V##type:\
1418 PACKET_DESCRIBE(phdr,TIMEDEF,PPSIZEDEFV,type,v##type##_part,pp,pktracepart_v##type,acttype);
1420 #define GENERATE_CASE_PART_V25(phdr,type,acttype) \
1421 case NSPR_PDPKTRACEPARTTX_V##type:\
1422 case NSPR_PDPKTRACEPARTTXB_V##type:\
1423 case NSPR_PDPKTRACEPARTRX_V##type:\
1424 case NSPR_PDPKTRACEPARTNEWRX_V##type:\
1425 PACKET_DESCRIBE(phdr,TIMEDEF,PPSIZEDEFV,type,v##type##_part,pp,pktracepart_v##type,acttype);
1427 switch ((( nspr_hd_v20_t*)pd)->phd_RecordType)
1429 GENERATE_CASE_FULL(phdr,20,200)
1430 GENERATE_CASE_PART(phdr,20,200)
1431 GENERATE_CASE_FULL(phdr,21,201)
1432 GENERATE_CASE_PART(phdr,21,201)
1433 GENERATE_CASE_FULL(phdr,22,202)
1434 GENERATE_CASE_PART(phdr,22,202)
1435 GENERATE_CASE_FULL(phdr,23,203)
1436 GENERATE_CASE_PART(phdr,23,203)
1437 GENERATE_CASE_FULL_V25(phdr,24,204)
1438 GENERATE_CASE_PART_V25(phdr,24,204)
1439 GENERATE_CASE_FULL_V25(phdr,25,205)
1440 GENERATE_CASE_PART_V25(phdr,25,205)
1441 GENERATE_CASE_FULL_V25(phdr,26,206)
1442 GENERATE_CASE_PART_V25(phdr,26,206)
1445 #undef GENERATE_CASE_FULL
1446 #undef GENERATE_CASE_FULL_V25
1447 #undef GENERATE_CASE_PART
1448 #undef GENERATE_CASE_PART_V25
1454 static gboolean nstrace_seek_read_v30(wtap *wth, gint64 seek_off,
1455 struct wtap_pkthdr *phdr, Buffer *buf, int length,
1456 int *err, gchar **err_info)
1463 if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
1467 ** Read the packet data.
1469 buffer_assure_space(buf, length);
1470 pd = buffer_start_ptr(buf);
1471 bytes_read = file_read(pd, length, wth->random_fh);
1472 if (bytes_read != length) {
1473 *err = file_error(wth->random_fh, err_info);
1475 *err = WTAP_ERR_SHORT_READ;
1479 #define GENERATE_CASE_V30(phdr,type,acttype) \
1480 case NSPR_PDPKTRACEFULLTX_V##type:\
1481 case NSPR_PDPKTRACEFULLTXB_V##type:\
1482 case NSPR_PDPKTRACEFULLRX_V##type:\
1483 case NSPR_PDPKTRACEFULLNEWRX_V##type:\
1484 TRACE_V##type##_REC_LEN_OFF((phdr),v##type##_full,fp,pktracefull_v##type);\
1485 (phdr)->pseudo_header.nstr.rec_type = NSPR_HEADER_VERSION##acttype;\
1488 switch ((( nspr_hd_v20_t*)pd)->phd_RecordType)
1490 GENERATE_CASE_V30(phdr,30, 300);
1498 ** Netscaler trace format close routines.
1500 static void nstrace_close(wtap *wth)
1502 nstrace_t *nstrace = (nstrace_t *)wth->priv;
1504 g_free(nstrace->pnstrace_buf);
1509 guint16 page_offset;
1511 guint32 absrec_time;
1514 /* Returns 0 if we could write the specified encapsulation type,
1515 ** an error indication otherwise. */
1516 int nstrace_10_dump_can_write_encap(int encap)
1518 if (encap == WTAP_ENCAP_NSTRACE_1_0)
1521 return WTAP_ERR_UNSUPPORTED_ENCAP;
1525 /* Returns 0 if we could write the specified encapsulation type,
1526 ** an error indication otherwise. */
1527 int nstrace_20_dump_can_write_encap(int encap)
1529 if (encap == WTAP_ENCAP_NSTRACE_2_0)
1532 return WTAP_ERR_UNSUPPORTED_ENCAP;
1535 /* Returns 0 if we could write the specified encapsulation type,
1536 ** an error indication otherwise. */
1537 int nstrace_30_dump_can_write_encap(int encap)
1539 if (encap == WTAP_ENCAP_NSTRACE_3_0)
1542 return WTAP_ERR_UNSUPPORTED_ENCAP;
1545 /* Returns TRUE on success, FALSE on failure; sets "*err" to an error code on
1547 gboolean nstrace_dump_open(wtap_dumper *wdh, int *err _U_)
1549 nstrace_dump_t *nstrace;
1551 wdh->subtype_write = nstrace_dump;
1553 nstrace = (nstrace_dump_t *)g_malloc(sizeof(nstrace_dump_t));
1554 wdh->priv = (void *)nstrace;
1555 nstrace->page_offset = 0;
1556 nstrace->page_len = NSPR_PAGESIZE;
1557 nstrace->absrec_time = 0;
1563 static gboolean nstrace_add_signature(wtap_dumper *wdh, int *err)
1565 nstrace_dump_t *nstrace = (nstrace_dump_t *)wdh->priv;
1567 if (wdh->file_type == WTAP_FILE_NETSCALER_1_0)
1570 nspr_signature_v10_t sig10;
1572 /* populate the record */
1573 val16b = htoles(NSPR_SIGNATURE_V10);
1574 memcpy(sig10.phd.ph_RecordType, &val16b, sizeof sig10.phd.ph_RecordType);
1575 val16b = htoles(nspr_signature_v10_s);
1576 memcpy(sig10.phd.ph_RecordSize, &val16b, sizeof sig10.phd.ph_RecordSize);
1577 memset(sig10.sig_Signature, 0, NSPR_SIGSIZE_V10);
1578 g_strlcpy(sig10.sig_Signature, NSPR_SIGSTR_V10, NSPR_SIGSIZE_V10);
1580 /* Write the record into the file */
1581 if (!wtap_dump_file_write(wdh, &sig10, nspr_signature_v10_s,
1585 /* Move forward the page offset */
1586 nstrace->page_offset += (guint16) nspr_signature_v10_s;
1588 } else if (wdh->file_type == WTAP_FILE_NETSCALER_2_0)
1590 nspr_signature_v20_t sig20;
1592 sig20.sig_RecordType = NSPR_SIGNATURE_V20;
1593 sig20.sig_RecordSize = nspr_signature_v20_s;
1594 memcpy(sig20.sig_Signature, NSPR_SIGSTR_V20, sizeof(NSPR_SIGSTR_V20));
1596 /* Write the record into the file */
1597 if (!wtap_dump_file_write(wdh, &sig20, sig20.sig_RecordSize,
1601 /* Move forward the page offset */
1602 nstrace->page_offset += (guint16) sig20.sig_RecordSize;
1606 g_assert_not_reached();
1615 nstrace_add_abstime(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
1616 const guint8 *pd, int *err)
1618 nstrace_dump_t *nstrace = (nstrace_dump_t *)wdh->priv;
1619 guint64 nsg_creltime;
1621 if (wdh->file_type == WTAP_FILE_NETSCALER_1_0)
1626 nspr_abstime_v10_t abs10;
1628 /* populate the record */
1629 val16 = htoles(NSPR_ABSTIME_V10);
1630 memcpy(abs10.phd.ph_RecordType, &val16, sizeof abs10.phd.ph_RecordType);
1631 val16 = htoles(nspr_abstime_v10_s);
1632 memcpy(abs10.phd.ph_RecordSize, &val16, sizeof abs10.phd.ph_RecordSize);
1634 memcpy(&reltime, ((const nspr_pktracefull_v10_t *)pd)->fp_RelTimeHr, sizeof reltime);
1635 nsg_creltime = ns_hrtime2nsec(reltime);
1637 memset(abs10.abs_RelTime, 0, sizeof abs10.abs_RelTime);
1638 abstime = htolel((guint32)phdr->ts.secs - (guint32)(nsg_creltime/1000000000));
1639 memcpy(abs10.abs_Time, &abstime, sizeof abs10.abs_Time);
1641 /* Write the record into the file */
1642 if (!wtap_dump_file_write(wdh, &abs10, nspr_abstime_v10_s, err))
1645 /* Move forward the page offset */
1646 nstrace->page_offset += nspr_abstime_v10_s;
1648 } else if (wdh->file_type == WTAP_FILE_NETSCALER_2_0)
1652 nspr_abstime_v20_t abs20;
1654 abs20.abs_RecordType = NSPR_ABSTIME_V20;
1655 abs20.abs_RecordSize = nspr_abstime_v20_s;
1657 memcpy(&reltime, ((const nspr_pktracefull_v20_t *)pd)->fp_RelTimeHr, sizeof reltime);
1658 nsg_creltime = ns_hrtime2nsec(reltime);
1660 memset(abs20.abs_RelTime, 0, sizeof abs20.abs_RelTime);
1661 abstime = htolel((guint32)phdr->ts.secs - (guint32)(nsg_creltime/1000000000));
1662 memcpy(abs20.abs_RelTime, &abstime, sizeof abs20.abs_RelTime);
1664 /* Write the record into the file */
1665 if (!wtap_dump_file_write(wdh, &abs20, nspr_abstime_v20_s, err))
1668 /* Move forward the page offset */
1669 nstrace->page_offset += nspr_abstime_v20_s;
1673 g_assert_not_reached();
1681 /* Write a record for a packet to a dump file.
1682 Returns TRUE on success, FALSE on failure. */
1683 static gboolean nstrace_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
1684 const guint8 *pd, int *err)
1686 nstrace_dump_t *nstrace = (nstrace_dump_t *)wdh->priv;
1688 if (nstrace->page_offset == 0)
1690 /* Add the signature record and abs time record */
1691 if (wdh->file_type == WTAP_FILE_NETSCALER_1_0)
1693 if (!nstrace_add_signature(wdh, err) ||
1694 !nstrace_add_abstime(wdh, phdr, pd, err))
1696 } else if (wdh->file_type == WTAP_FILE_NETSCALER_2_0)
1698 if (!nstrace_add_signature(wdh, err) ||
1699 !nstrace_add_abstime(wdh, phdr, pd, err))
1703 g_assert_not_reached();
1708 switch (phdr->pseudo_header.nstr.rec_type)
1710 case NSPR_HEADER_VERSION100:
1712 if (wdh->file_type == WTAP_FILE_NETSCALER_1_0)
1714 if (nstrace->page_offset + phdr->caplen >= nstrace->page_len)
1716 /* Start on the next page */
1717 if (wtap_dump_file_seek(wdh, (nstrace->page_len - nstrace->page_offset), SEEK_CUR, err) == -1)
1720 nstrace->page_offset = 0;
1722 /* Possibly add signature and abstime records and increment offset */
1723 if (!nstrace_add_signature(wdh, err))
1727 /* Write the actual record as is */
1728 if (!wtap_dump_file_write(wdh, pd, phdr->caplen, err))
1731 nstrace->page_offset += (guint16) phdr->caplen;
1732 } else if (wdh->file_type == WTAP_FILE_NETSCALER_2_0)
1734 *err = WTAP_ERR_UNSUPPORTED_FILE_TYPE;
1740 case NSPR_HEADER_VERSION200:
1741 case NSPR_HEADER_VERSION201:
1742 case NSPR_HEADER_VERSION202:
1743 case NSPR_HEADER_VERSION203:
1744 case NSPR_HEADER_VERSION204:
1745 case NSPR_HEADER_VERSION205:
1746 case NSPR_HEADER_VERSION206:
1747 if (wdh->file_type == WTAP_FILE_NETSCALER_1_0)
1749 *err = WTAP_ERR_UNSUPPORTED_FILE_TYPE;
1751 } else if (wdh->file_type == WTAP_FILE_NETSCALER_2_0)
1753 if (nstrace->page_offset + phdr->caplen >= nstrace->page_len)
1755 /* Start on the next page */
1756 if (wtap_dump_file_seek(wdh, (nstrace->page_len - nstrace->page_offset), SEEK_CUR, err) == -1)
1759 nstrace->page_offset = 0;
1761 /* Possibly add signature and abstime records and increment offset */
1762 if (!nstrace_add_signature(wdh, err))
1766 /* Write the actual record as is */
1767 if (!wtap_dump_file_write(wdh, pd, phdr->caplen, err))
1770 nstrace->page_offset += (guint16) phdr->caplen;
1776 g_assert_not_reached();