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 <wsutil/buffer.h>
27 #include "netscaler.h"
29 /* Defines imported from netscaler code: nsperfrc.h */
31 #define NSPR_SIGSTR_V10 "NetScaler Performance Data"
32 #define NSPR_SIGSTR_V20 "NetScaler V20 Performance Data"
33 #define NSPR_SIGSTR NSPR_SIGSTR_V20
34 #define NSPR_SIGSTR_V30 "Netscaler V30 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_ABSTIME_V10 0x0107 /* data capture time in secs from 1970*/
68 #define NSPR_ABSTIME_V20 0x07 /* data capture time in secs from 1970*/
69 #define NSPR_RELTIME_V10 0x0108 /* relative time in ms from last time */
70 #define NSPR_RELTIME_V20 0x08 /* relative time in ms from last time */
71 #define NSPR_RELTIMEHR_V10 0x0109 /* high resolution relative time */
72 #define NSPR_RELTIMEHR_V20 0x09 /* high resolution relative time */
73 #define NSPR_SYSTARTIME_V10 0x010A /* system start time */
74 #define NSPR_SYSTARTIME_V20 0x0A /* system start time */
75 #define NSPR_RELTIME2B_V10 0x010B /* relative time in ms from last time */
76 #define NSPR_RELTIME2B_V20 0x0B /* relative time in ms from last time */
79 /* The high resolution relative time format.
80 ** The MS 2 bits of the high resoltion time is defined as follows:
81 ** 00 : time value is in seconds
82 ** 01 : time value is in milliseconds
83 ** 10 : time value is in microseconds
84 ** 11 : time value is in nanoseconds
86 #define NSPR_HRTIME_MASKTM 0x3FFFFFFF /* mask to get time value */
87 #define NSPR_HRTIME_MASKFMT 0xC0000000 /* time value format mask */
88 #define NSPR_HRTIME_SEC 0x00000000 /* time value in second */
89 #define NSPR_HRTIME_MSEC 0x40000000 /* time value in mili second */
90 #define NSPR_HRTIME_USEC 0x80000000 /* time value in micro second */
91 #define NSPR_HRTIME_NSEC 0xC0000000 /* time value in nano second */
94 typedef struct nspr_header_v10
96 guint8 ph_RecordType[2]; /* Record Type */
97 guint8 ph_RecordSize[2]; /* Record Size including header */
99 #define nspr_header_v10_s ((guint32)sizeof(nspr_header_v10_t))
101 /* This is V20 short header (2 bytes long) to be included where needed */
102 #define NSPR_HEADER_V20(prefix) \
103 guint8 prefix##_RecordType; /* Record Type */ \
104 guint8 prefix##_RecordSize /* Record Size including header */ \
105 /* end of declaration */
107 /* This is new long header (3 bytes long) to be included where needed */
108 #define NSPR_HEADER3B_V20(prefix) \
109 guint8 prefix##_RecordType; /* Record Type */ \
110 guint8 prefix##_RecordSizeLow; /* Record Size including header */ \
111 guint8 prefix##_RecordSizeHigh /* Record Size including header */ \
112 /* end of declaration */
113 #define NSPR_HEADER3B_V21 NSPR_HEADER3B_V20
114 #define NSPR_HEADER3B_V22 NSPR_HEADER3B_V20
115 #define NSPR_HEADER3B_V30 NSPR_HEADER3B_V20
117 typedef struct nspr_hd_v20
119 NSPR_HEADER3B_V20(phd); /* long performance header */
122 #define nspr_hd_v20_s ((guint32)sizeof(nspr_hd_v20_t))
126 ** How to know if header size is short or long?
127 ** The short header size can be 0-127 bytes long. If MS Bit of ph_RecordSize
128 ** is set then record size has 2 bytes
130 #define NSPR_V20RECORDSIZE_2BYTES 0x80
132 /* Performance Data Header with device number */
133 typedef struct nspr_headerdev_v10
135 guint8 ph_RecordType[2]; /* Record Type */
136 guint8 ph_RecordSize[2]; /* Record Size including header */
137 guint8 ph_DevNo[4]; /* Network Device (NIC/CONN) number */
138 } nspr_headerdev_v10_t;
139 #define nspr_headerdev_v10_s ((guint32)sizeof(nspr_headerdev_v10_t))
141 typedef struct nspr_hd_v10
143 nspr_header_v10_t phd; /* performance header */
145 #define nspr_hd_v10_s ((guint32)sizeof(nspr_hd_v10_t))
147 typedef struct nspr_hdev_v10
149 nspr_headerdev_v10_t phd; /* performance header */
151 #define nspr_hdev_v10_s ((guint32)sizeof(nspr_hdev_v10_t))
153 /* if structure has defined phd as first field, it can use following names */
154 #define nsprRecordType phd.ph_RecordType
155 #define nsprRecordSize phd.ph_RecordSize
156 #define nsprReserved phd.ph_Reserved
157 #define nsprRecordTypeOrg phd.ph_Reserved
158 #define nsprDevNo phd.ph_DevNo
160 /* NSPR_SIGNATURE_V10 structure */
161 #define NSPR_SIGSIZE_V10 56 /* signature value size in bytes */
162 typedef struct nspr_signature_v10
164 nspr_header_v10_t phd; /* performance header */
165 guint8 sig_EndianType; /* Endian Type for the data */
166 guint8 sig_Reserved0;
167 guint8 sig_Reserved1[2];
168 gchar sig_Signature[NSPR_SIGSIZE_V10]; /* Signature value */
169 } nspr_signature_v10_t;
170 #define nspr_signature_v10_s ((guint32)sizeof(nspr_signature_v10_t))
172 /* NSPR_SIGNATURE_V20 structure */
173 #define NSPR_SIGSIZE_V20 sizeof(NSPR_SIGSTR_V20) /* signature value size in bytes */
174 typedef struct nspr_signature_v20
176 NSPR_HEADER_V20(sig); /* short performance header */
177 guint8 sig_EndianType; /* Endian Type for the data */
178 gchar sig_Signature[NSPR_SIGSIZE_V20]; /* Signature value */
179 } nspr_signature_v20_t;
180 #define nspr_signature_v20_s ((guint32)sizeof(nspr_signature_v20_t))
182 /* NSPR_SIGNATURE_V30 structure */
183 #define NSPR_SIGSIZE_V30 sizeof(NSPR_SIGSTR_V30) /* signature value size in bytes */
184 typedef struct nspr_signature_v30
186 NSPR_HEADER_V20(sig); /* short performance header */
187 guint8 sig_EndianType; /* Endian Type for the data */
188 gchar sig_Signature[NSPR_SIGSIZE_V30]; /* Signature value */
189 } nspr_signature_v30_t;
190 #define nspr_signature_v30_s ((guint32)sizeof(nspr_signature_v30_t))
192 /* NSPR_ABSTIME_V10 and NSPR_SYSTARTIME_V10 structure */
193 typedef struct nspr_abstime_v10
195 nspr_header_v10_t phd; /* performance header */
196 guint8 abs_RelTime[4]; /* relative time is ms from last time */
197 guint8 abs_Time[4]; /* absolute time in seconds from 1970 */
198 } nspr_abstime_v10_t;
199 #define nspr_abstime_v10_s ((guint32)sizeof(nspr_abstime_v10_t))
202 /* NSPR_ABSTIME_V20 and NSPR_SYSTARTIME_V20 structure */
203 typedef struct nspr_abstime_v20
205 NSPR_HEADER_V20(abs); /* short performance header */
206 guint8 abs_RelTime[2]; /* relative time is ms from last time */
207 guint8 abs_Time[4]; /* absolute time in seconds from 1970 */
208 } nspr_abstime_v20_t;
209 #define nspr_abstime_v20_s ((guint32)sizeof(nspr_abstime_v20_t))
213 /* full packet trace structure */
214 typedef struct nspr_pktracefull_v10
216 nspr_headerdev_v10_t phd; /* performance header */
217 guint8 fp_RelTimeHr[4]; /* High resolution relative time */
218 guint8 fp_Data[1]; /* packet data starts here */
219 } nspr_pktracefull_v10_t;
220 #define nspr_pktracefull_v10_s (nspr_hdev_v10_s + 4)
222 /* new full packet trace structure v20 */
223 typedef struct nspr_pktracefull_v20
225 NSPR_HEADER3B_V20(fp); /* long performance header */
226 guint8 fp_DevNo; /* Network Device (NIC) number */
227 guint8 fp_RelTimeHr[4]; /* High resolution relative time */
228 guint8 fp_Data[4]; /* packet data starts here */
229 } nspr_pktracefull_v20_t;
230 #define nspr_pktracefull_v20_s ((guint32)(sizeof(nspr_pktracefull_v20_t) - 4))
232 /* new full packet trace structure v21 */
233 typedef struct nspr_pktracefull_v21
235 NSPR_HEADER3B_V21(fp); /* long performance header */
236 guint8 fp_DevNo; /* Network Device (NIC) number */
237 guint8 fp_RelTimeHr[4]; /* High resolution relative time */
238 guint8 fp_PcbDevNo[4]; /* PCB devno */
239 guint8 fp_lPcbDevNo[4]; /* link PCB devno */
240 guint8 fp_Data[4]; /* packet data starts here */
241 } nspr_pktracefull_v21_t;
242 #define nspr_pktracefull_v21_s ((guint32)(sizeof(nspr_pktracefull_v21_t) - 4))
244 /* new full packet trace structure v22 */
245 typedef struct nspr_pktracefull_v22
247 NSPR_HEADER3B_V22(fp); /* long performance header */
248 guint8 fp_DevNo; /* Network Device (NIC) number */
249 guint8 fp_RelTimeHr[4]; /* High resolution relative time */
250 guint8 fp_PcbDevNo[4]; /* PCB devno */
251 guint8 fp_lPcbDevNo[4]; /* link PCB devno */
252 guint8 fp_VlanTag[2]; /* vlan tag */
253 guint8 fp_Data[2]; /* packet data starts here */
254 } nspr_pktracefull_v22_t;
255 #define nspr_pktracefull_v22_s ((guint32)(sizeof(nspr_pktracefull_v22_t) - 2))
257 typedef struct nspr_pktracefull_v23
259 NSPR_HEADER3B_V22(fp); /* long performance header */
260 guint8 fp_DevNo; /* Network Device (NIC) number */
261 guint8 fp_AbsTimeHr[8]; /* High resolution absolute time */
262 guint8 fp_PcbDevNo[4]; /* PCB devno */
263 guint8 fp_lPcbDevNo[4]; /* link PCB devno */
264 guint8 fp_VlanTag[2]; /* vlan tag */
265 guint8 fp_Coreid[2]; /* coreid of the packet */
266 guint8 fp_Data[2]; /* packet data starts here */
267 } nspr_pktracefull_v23_t;
268 #define nspr_pktracefull_v23_s ((guint32)(sizeof(nspr_pktracefull_v23_t) - 2))
270 /* New full packet trace structure v24 for cluster tracing */
271 typedef struct nspr_pktracefull_v24
273 NSPR_HEADER3B_V22(fp); /* long performance header */
274 guint8 fp_DevNo; /* Network Device (NIC) number */
275 guint8 fp_AbsTimeHr[8]; /* High resolution absolute time in nanosec */
276 guint8 fp_PcbDevNo[4]; /* PCB devno */
277 guint8 fp_lPcbDevNo[4]; /* link PCB devno */
278 guint8 fp_VlanTag[2]; /* vlan tag */
279 guint8 fp_Coreid[2]; /* coreid of the packet */
280 guint8 fp_srcNodeId[2]; /* source node # */
281 guint8 fp_destNodeId[2]; /* destination node # */
282 guint8 fp_clFlags; /* cluster flags */
283 guint8 fp_Data[2]; /* packet data starts here */
284 } nspr_pktracefull_v24_t;
285 #define nspr_pktracefull_v24_s ((guint32)(sizeof(nspr_pktracefull_v24_t) - 4))
287 /* New full packet trace structure v25 for vm info tracing */
288 typedef struct nspr_pktracefull_v25
290 NSPR_HEADER3B_V22(fp); /* long performance header */
291 guint8 fp_DevNo; /* Network Device (NIC) number */
292 guint8 fp_AbsTimeHr[8]; /* High resolution absolute time in nanosec */
293 guint8 fp_PcbDevNo[4]; /* PCB devno */
294 guint8 fp_lPcbDevNo[4]; /* link PCB devno */
295 guint8 fp_VlanTag[2]; /* vlan tag */
296 guint8 fp_Coreid[2]; /* coreid of the packet */
297 guint8 fp_srcNodeId[2]; /* source node # */
298 guint8 fp_destNodeId[2]; /* destination node # */
299 guint8 fp_clFlags; /* cluster flags */
300 guint8 fp_src_vmname_len; /* vm src info */
301 guint8 fp_dst_vmname_len; /* vm src info */
302 guint8 fp_Data[4]; /* packet data starts here */
303 } nspr_pktracefull_v25_t;
304 #define nspr_pktracefull_v25_s ((guint32)(sizeof(nspr_pktracefull_v25_t) - 4))
305 #define fp_src_vmname fp_Data
306 #define fp_src_vmname fp_Data
308 /* New full packet trace structure v26 for vm info tracing */
309 typedef struct nspr_pktracefull_v26
311 NSPR_HEADER3B_V22(fp); /* long performance header */
312 guint8 fp_DevNo; /* Network Device (NIC) number */
313 guint8 fp_AbsTimeHr[8]; /* High resolution absolute time in nanosec */
314 guint8 fp_PcbDevNo[4]; /* PCB devno */
315 guint8 fp_lPcbDevNo[4]; /* link PCB devno */
316 guint8 fp_VlanTag[2]; /* vlan tag */
317 guint8 fp_Coreid[2]; /* coreid of the packet */
318 guint8 fp_srcNodeId[2]; /* source node # */
319 guint8 fp_destNodeId[2]; /* destination node # */
320 guint8 fp_clFlags; /* cluster flags */
321 guint8 fp_src_vmname_len; /* vm src info */
322 guint8 fp_dst_vmname_len; /* vm src info */
324 guint8 fp_ns_activity[4];
325 guint8 fp_reserved_32[12]; /* Adding more field to reduce wireshark changes every time */
326 guint8 fp_Data[4]; /* packet data starts here */
327 } nspr_pktracefull_v26_t;
328 #define nspr_pktracefull_v26_s ((guint32)(sizeof(nspr_pktracefull_v26_t) - 4))
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 guint8 pp_Data[1]; /* packet data starts here */
338 } nspr_pktracepart_v10_t;
339 #define nspr_pktracepart_v10_s (nspr_pktracefull_v10_s + 4)
341 /* new partial packet trace structure */
342 typedef struct nspr_pktracepart_v20
344 NSPR_HEADER3B_V20(pp); /* long performance header */
345 guint8 pp_DevNo; /* Network Device (NIC) number */
346 guint8 pp_RelTimeHr[4]; /* High resolution relative time */
347 guint8 pp_PktSizeOrg[2]; /* Original packet size */
348 guint8 pp_PktOffset[2]; /* starting offset in packet */
349 guint8 pp_Data[4]; /* packet data starts here */
350 } nspr_pktracepart_v20_t;
351 #define nspr_pktracepart_v20_s ((guint32)(sizeof(nspr_pktracepart_v20_t) -4))
353 /* new partial packet trace structure */
354 typedef struct nspr_pktracepart_v21
356 NSPR_HEADER3B_V21(pp); /* long performance header */
357 guint8 pp_DevNo; /* Network Device (NIC) number */
358 guint8 pp_RelTimeHr[4]; /* High resolution relative time */
359 guint8 pp_PktSizeOrg[2]; /* Original packet size */
360 guint8 pp_PktOffset[2]; /* starting offset in packet */
361 guint8 pp_PcbDevNo[4]; /* PCB devno */
362 guint8 pp_lPcbDevNo[4]; /* link PCB devno */
363 guint8 pp_Data[4]; /* packet data starts here */
364 } nspr_pktracepart_v21_t;
365 #define nspr_pktracepart_v21_s ((guint32)(sizeof(nspr_pktracepart_v21_t) -4))
367 /* new partial packet trace structure v22 */
368 typedef struct nspr_pktracepart_v22
370 NSPR_HEADER3B_V22(pp); /* long performance header */
371 guint8 pp_DevNo; /* Network Device (NIC) number */
372 guint8 pp_RelTimeHr[4]; /* High resolution relative time */
373 guint8 pp_PktSizeOrg[2]; /* Original packet size */
374 guint8 pp_PktOffset[2]; /* starting offset in packet */
375 guint8 pp_PcbDevNo[4]; /* PCB devno */
376 guint8 pp_lPcbDevNo[4]; /* link PCB devno */
377 guint8 pp_VlanTag[2]; /* Vlan Tag */
378 guint8 pp_Data[2]; /* packet data starts here */
379 } nspr_pktracepart_v22_t;
380 #define nspr_pktracepart_v22_s ((guint32)(sizeof(nspr_pktracepart_v22_t) -2))
382 typedef struct nspr_pktracepart_v23
384 NSPR_HEADER3B_V22(pp); /* long performance header */
385 guint8 pp_DevNo; /* Network Device (NIC) number */
386 guint8 pp_AbsTimeHr[8]; /* High resolution absolute time */
387 guint8 pp_PktSizeOrg[2]; /* Original packet size */
388 guint8 pp_PktOffset[2]; /* starting offset in packet */
389 guint8 pp_PcbDevNo[4]; /* PCB devno */
390 guint8 pp_lPcbDevNo[4]; /* link PCB devno */
391 guint8 pp_VlanTag[2]; /* vlan tag */
392 guint8 pp_Coreid[2]; /* Coreid of the packet */
393 guint8 pp_Data[4]; /* packet data starts here */
394 } nspr_pktracepart_v23_t;
395 #define nspr_pktracepart_v23_s ((guint32)(sizeof(nspr_pktracepart_v23_t) -4))
397 /* New partial packet trace structure v24 for cluster tracing */
398 typedef struct nspr_pktracepart_v24
400 NSPR_HEADER3B_V22(pp); /* long performance header */
401 guint8 pp_DevNo; /* Network Device (NIC) number */
402 guint8 pp_AbsTimeHr[8]; /*High resolution absolute time in nanosec*/
403 guint8 pp_PktSizeOrg[2]; /* Original packet size */
404 guint8 pp_PktOffset[2]; /* starting offset in packet */
405 guint8 pp_PcbDevNo[4]; /* PCB devno */
406 guint8 pp_lPcbDevNo[4]; /* link PCB devno */
407 guint8 pp_VlanTag[2]; /* vlan tag */
408 guint8 pp_Coreid[2]; /* Coreid of the packet */
409 guint8 pp_srcNodeId[2]; /* source node # */
410 guint8 pp_destNodeId[2]; /* destination node # */
411 guint8 pp_clFlags; /* cluster flags */
412 guint8 pp_Data[4]; /* packet data starts here */
413 } nspr_pktracepart_v24_t;
414 #define nspr_pktracepart_v24_s ((guint32)(sizeof(nspr_pktracepart_v24_t) -4))
416 /* New partial packet trace structure v25 for vm info tracing */
417 typedef struct nspr_pktracepart_v25
419 NSPR_HEADER3B_V22(pp); /* long performance header */
420 guint8 pp_DevNo; /* Network Device (NIC) number */
421 guint8 pp_AbsTimeHr[8]; /*High resolution absolute time in nanosec*/
422 guint8 pp_PktSizeOrg[2]; /* Original packet size */
423 guint8 pp_PktOffset[2]; /* starting offset in packet */
424 guint8 pp_PcbDevNo[4]; /* PCB devno */
425 guint8 pp_lPcbDevNo[4]; /* link PCB devno */
426 guint8 pp_VlanTag[2]; /* vlan tag */
427 guint8 pp_Coreid[2]; /* Coreid of the packet */
428 guint8 pp_srcNodeId[2]; /* source node # */
429 guint8 pp_destNodeId[2]; /* destination node # */
430 guint8 pp_clFlags; /* cluster flags */
431 guint8 pp_src_vmname_len; /* vm info */
432 guint8 pp_dst_vmname_len; /* vm info */
433 guint8 pp_Data[4]; /* packet data starts here */
434 } nspr_pktracepart_v25_t;
435 #define nspr_pktracepart_v25_s ((guint32)(sizeof(nspr_pktracepart_v25_t) -4))
436 #define pp_src_vmname pp_Data
437 #define pp_dst_vmname pp_Data
440 /* New full packet trace structure v30 for multipage spanning data */
441 typedef struct nspr_pktracefull_v30
443 NSPR_HEADER3B_V30(fp); /* long performance header */
444 guint8 fp_DevNo; /* Network Device (NIC) number */
445 guint8 fp_AbsTimeHr[8]; /*High resolution absolute time in nanosec*/
446 guint8 fp_PcbDevNo[4]; /* PCB devno */
447 guint8 fp_lPcbDevNo[4]; /* link PCB devno */
448 guint8 fp_PktSizeOrg[2]; /* Original packet size */
449 guint8 fp_VlanTag[2]; /* vlan tag */
450 guint8 fp_Coreid[2]; /* coreid of the packet */
451 guint8 fp_srcNodeId[2]; /* cluster nodeid of the packet */
452 guint8 fp_destNodeId[2];
454 guint8 fp_src_vmname_len;
455 guint8 fp_dst_vmname_len;
456 guint8 fp_reserved[3];
457 guint8 fp_ns_activity[4];
458 guint8 fp_reserved_32[12];
459 guint8 fp_Data[0]; /* packet data starts here */
460 } nspr_pktracefull_v30_t;
461 #define nspr_pktracefull_v30_s ((guint32)(sizeof(nspr_pktracefull_v30_t)))
462 #define fp_src_vmname fp_Data
463 #define fp_dst_vmname fp_Data
465 /* New partial packet trace structure v26 for vm info tracing */
466 typedef struct nspr_pktracepart_v26
468 NSPR_HEADER3B_V22(pp); /* long performance header */
469 guint8 pp_DevNo; /* Network Device (NIC) number */
470 guint8 pp_AbsTimeHr[8]; /*High resolution absolute time in nanosec*/
471 guint8 pp_PktSizeOrg[2]; /* Original packet size */
472 guint8 pp_PktOffset[2]; /* starting offset in packet */
473 guint8 pp_PcbDevNo[4]; /* PCB devno */
474 guint8 pp_lPcbDevNo[4]; /* link PCB devno */
475 guint8 pp_VlanTag[2]; /* vlan tag */
476 guint8 pp_Coreid[2]; /* Coreid of the packet */
477 guint8 pp_srcNodeId[2]; /* source node # */
478 guint8 pp_destNodeId[2]; /* destination node # */
479 guint8 pp_clFlags; /* cluster flags */
480 guint8 pp_src_vmname_len; /* vm info */
481 guint8 pp_dst_vmname_len; /* vm info */
483 guint8 pp_ns_activity[4];
484 guint8 pp_reserved_32[12]; /* Adding more field to reduce wireshark changes every time */
485 guint8 pp_Data[4]; /* packet data starts here */
486 } nspr_pktracepart_v26_t;
487 #define nspr_pktracepart_v26_s ((guint32)(sizeof(nspr_pktracepart_v26_t) -4))
489 #define myoffsetof(type,fieldname) (&(((type*)0)->fieldname))
491 #define __TNO(phdr,enumprefix,structprefix,structname,hdrname,structfieldname) \
492 guint8 enumprefix##_##hdrname##_offset = (guint8)GPOINTER_TO_INT(myoffsetof(nspr_##structname##_t,structprefix##_##structfieldname));
494 #define __TNL(phdr,enumprefix,structprefix,structname,hdrname,structfieldname) \
495 guint8 enumprefix##_##hdrname##_len = (guint8)sizeof(((nspr_##structname##_t*)0)->structprefix##_##structfieldname);
497 #define __TNV1O(phdr,enumprefix,structprefix,structname,hdrname,structfieldname) \
498 guint8 enumprefix##_##hdrname##_offset = (guint8)GPOINTER_TO_INT(myoffsetof(nspr_##structname##_t,structfieldname));
500 #define __TNV1L(phdr,enumprefix,structprefix,structname,hdrname,structfieldname) \
501 guint8 enumprefix##_##hdrname##_len = (guint8)sizeof(((nspr_##structname##_t*)0)->structfieldname);
503 #define TRACE_V10_REC_LEN_OFF(phdr,enumprefix,structprefix,structname) \
504 __TNV1O(phdr,enumprefix,structprefix,structname,dir,phd.ph_RecordType)\
505 __TNV1L(phdr,enumprefix,structprefix,structname,dir,phd.ph_RecordType)\
506 __TNV1O(phdr,enumprefix,structprefix,structname,nicno,phd.ph_DevNo)\
507 __TNV1L(phdr,enumprefix,structprefix,structname,nicno,phd.ph_DevNo)\
508 __TNO(phdr,enumprefix,structprefix,structname,eth,Data)
510 #define TRACE_FULL_V10_REC_LEN_OFF(phdr,enumprefix,structprefix,structname) \
511 (phdr)->len = pletoh16(&(fp)->nsprRecordSize);\
512 (phdr)->caplen = (phdr)->len;\
513 TRACE_V10_REC_LEN_OFF(phdr,enumprefix,structprefix,structname)
515 #define TRACE_PART_V10_REC_LEN_OFF(phdr,enumprefix,structprefix,structname) \
516 (phdr)->rec_type = REC_TYPE_PACKET;\
517 (phdr)->presence_flags |= WTAP_HAS_CAP_LEN;\
518 (phdr)->len = pletoh16(&pp->pp_PktSizeOrg) + nspr_pktracepart_v10_s;\
519 (phdr)->caplen = pletoh16(&pp->nsprRecordSize);\
520 TRACE_V10_REC_LEN_OFF(phdr,enumprefix,structprefix,structname)
522 #define TRACE_V20_REC_LEN_OFF(phdr,enumprefix,structprefix,structname) \
523 __TNO(phdr,enumprefix,structprefix,structname,dir,RecordType)\
524 __TNL(phdr,enumprefix,structprefix,structname,dir,RecordType)\
525 __TNO(phdr,enumprefix,structprefix,structname,nicno,DevNo)\
526 __TNL(phdr,enumprefix,structprefix,structname,nicno,DevNo)\
527 __TNO(phdr,enumprefix,structprefix,structname,eth,Data)
529 #define TRACE_V21_REC_LEN_OFF(phdr,enumprefix,structprefix,structname) \
530 TRACE_V20_REC_LEN_OFF(phdr,enumprefix,structprefix,structname)\
531 __TNO(phdr,enumprefix,structprefix,structname,pcb,PcbDevNo)\
532 __TNO(phdr,enumprefix,structprefix,structname,l_pcb,lPcbDevNo)
534 #define TRACE_V22_REC_LEN_OFF(phdr,enumprefix,structprefix,structname) \
535 TRACE_V21_REC_LEN_OFF(phdr,enumprefix,structprefix,structname)\
536 __TNO(phdr,enumprefix,structprefix,structname,vlantag,VlanTag)
538 #define TRACE_V23_REC_LEN_OFF(phdr,enumprefix,structprefix,structname) \
539 TRACE_V22_REC_LEN_OFF(phdr,enumprefix,structprefix,structname)\
540 __TNO(phdr,enumprefix,structprefix,structname,coreid,Coreid)
542 #define TRACE_V24_REC_LEN_OFF(phdr,enumprefix,structprefix,structname) \
543 TRACE_V23_REC_LEN_OFF(phdr,enumprefix,structprefix,structname)\
544 __TNO(phdr,enumprefix,structprefix,structname,srcnodeid,srcNodeId)\
545 __TNO(phdr,enumprefix,structprefix,structname,destnodeid,destNodeId)\
546 __TNO(phdr,enumprefix,structprefix,structname,clflags,clFlags)
548 #define TRACE_V25_REC_LEN_OFF(phdr,enumprefix,structprefix,structname) \
549 TRACE_V24_REC_LEN_OFF(phdr,enumprefix,structprefix,structname)\
550 __TNO(phdr,enumprefix,structprefix,structname,src_vmname_len,src_vmname_len)\
551 __TNO(phdr,enumprefix,structprefix,structname,dst_vmname_len,dst_vmname_len)\
552 __TNO(phdr,enumprefix,structprefix,structname,data,Data)
554 #define TRACE_V26_REC_LEN_OFF(phdr,enumprefix,structprefix,structname) \
555 TRACE_V25_REC_LEN_OFF(phdr,enumprefix,structprefix,structname)\
556 __TNO(phdr,enumprefix,structprefix,structname,ns_activity,ns_activity)\
558 #define TRACE_V30_REC_LEN_OFF(phdr, enumprefix, structprefix, structname) \
559 TRACE_V26_REC_LEN_OFF(phdr,enumprefix,structprefix,structname)\
561 TRACE_V10_REC_LEN_OFF(NULL,v10_part,pp,pktracepart_v10)
562 TRACE_V10_REC_LEN_OFF(NULL,v10_full,fp,pktracefull_v10)
563 TRACE_V20_REC_LEN_OFF(NULL,v20_part,pp,pktracepart_v20)
564 TRACE_V20_REC_LEN_OFF(NULL,v20_full,fp,pktracefull_v20)
565 TRACE_V21_REC_LEN_OFF(NULL,v21_part,pp,pktracepart_v21)
566 TRACE_V21_REC_LEN_OFF(NULL,v21_full,fp,pktracefull_v21)
567 TRACE_V22_REC_LEN_OFF(NULL,v22_part,pp,pktracepart_v22)
568 TRACE_V22_REC_LEN_OFF(NULL,v22_full,fp,pktracefull_v22)
569 TRACE_V23_REC_LEN_OFF(NULL,v23_part,pp,pktracepart_v23)
570 TRACE_V23_REC_LEN_OFF(NULL,v23_full,fp,pktracefull_v23)
571 TRACE_V24_REC_LEN_OFF(NULL,v24_part,pp,pktracepart_v24)
572 TRACE_V24_REC_LEN_OFF(NULL,v24_full,fp,pktracefull_v24)
573 TRACE_V25_REC_LEN_OFF(NULL,v25_part,pp,pktracepart_v25)
574 TRACE_V25_REC_LEN_OFF(NULL,v25_full,fp,pktracefull_v25)
575 TRACE_V26_REC_LEN_OFF(NULL,v26_part,pp,pktracepart_v26)
576 TRACE_V26_REC_LEN_OFF(NULL,v26_full,fp,pktracefull_v26)
577 TRACE_V30_REC_LEN_OFF(NULL,v30_full,fp,pktracefull_v30)
585 #define ns_setabstime(nstrace, AbsoluteTime, RelativeTimems) \
587 (nstrace)->nspm_curtime = AbsoluteTime; \
588 (nstrace)->nspm_curtimemsec += RelativeTimems; \
589 (nstrace)->nspm_curtimelastmsec = nstrace->nspm_curtimemsec; \
593 #define ns_setrelativetime(nstrace, RelativeTimems) \
596 (nstrace)->nspm_curtimemsec += RelativeTimems; \
597 rsec = (guint32)((nstrace)->nspm_curtimemsec - (nstrace)->nspm_curtimelastmsec)/1000; \
598 (nstrace)->nspm_curtime += rsec; \
599 (nstrace)->nspm_curtimelastmsec += rsec * 1000; \
606 gint32 nstrace_buf_offset;
607 gint32 nstrace_buflen;
608 /* Performance Monitor Time variables */
609 guint32 nspm_curtime; /* current time since 1970 */
610 guint64 nspm_curtimemsec; /* current time in milliseconds */
611 guint64 nspm_curtimelastmsec; /* nspm_curtime last update time in milliseconds */
612 guint64 nsg_creltime;
616 static guint32 nspm_signature_version(wtap*, gchar*, gint32);
617 static gboolean nstrace_read_v10(wtap *wth, int *err, gchar **err_info,
618 gint64 *data_offset);
619 static gboolean nstrace_read_v20(wtap *wth, int *err, gchar **err_info,
620 gint64 *data_offset);
621 static gboolean nstrace_read_v30(wtap *wth, int *err, gchar **err_info,
622 gint64 *data_offset);
623 static gboolean nstrace_seek_read_v10(wtap *wth, gint64 seek_off,
624 struct wtap_pkthdr *phdr,
626 int *err, gchar **err_info);
627 static gboolean nstrace_seek_read_v20(wtap *wth, gint64 seek_off,
628 struct wtap_pkthdr *phdr,
630 int *err, gchar **err_info);
631 static gboolean nstrace_seek_read_v30(wtap *wth, gint64 seek_off,
632 struct wtap_pkthdr *phdr,
634 int *err, gchar **err_info);
635 static void nstrace_close(wtap *wth);
637 static gboolean nstrace_set_start_time_v10(wtap *wth);
638 static gboolean nstrace_set_start_time_v20(wtap *wth);
639 static gboolean nstrace_set_start_time(wtap *wth);
640 static guint64 ns_hrtime2nsec(guint32 tm);
642 static gboolean nstrace_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
643 const guint8 *pd, int *err);
647 * Minimum of the page size and the amount of data left in the file;
648 * the last page of a file can be short.
650 #define GET_READ_PAGE_SIZE(remaining_file_size) ((gint32)((remaining_file_size>NSPR_PAGESIZE)?NSPR_PAGESIZE:remaining_file_size))
651 #define GET_READ_PAGE_SIZEV3(remaining_file_size) ((gint32)((remaining_file_size>NSPR_PAGESIZE_TRACE)?NSPR_PAGESIZE_TRACE:remaining_file_size))
653 static guint64 ns_hrtime2nsec(guint32 tm)
655 guint32 val = tm & NSPR_HRTIME_MASKTM;
656 switch(tm & NSPR_HRTIME_MASKFMT)
658 case NSPR_HRTIME_SEC: return (guint64)val*1000000000;
659 case NSPR_HRTIME_MSEC: return (guint64)val*1000000;
660 case NSPR_HRTIME_USEC: return (guint64)val*1000;
661 case NSPR_HRTIME_NSEC: return val;
668 ** Netscaler trace format open routines
670 int nstrace_open(wtap *wth, int *err, gchar **err_info)
678 if ((file_size = wtap_file_size(wth, err)) == -1)
681 nstrace_buf = (gchar *)g_malloc(NSPR_PAGESIZE);
682 page_size = GET_READ_PAGE_SIZE(file_size);
684 switch ((wth->file_type_subtype = nspm_signature_version(wth, nstrace_buf, page_size)))
686 case WTAP_FILE_TYPE_SUBTYPE_NETSCALER_1_0:
687 wth->file_encap = WTAP_ENCAP_NSTRACE_1_0;
690 case WTAP_FILE_TYPE_SUBTYPE_NETSCALER_2_0:
691 wth->file_encap = WTAP_ENCAP_NSTRACE_2_0;
694 case WTAP_FILE_TYPE_SUBTYPE_NETSCALER_3_0:
695 wth->file_encap = WTAP_ENCAP_NSTRACE_3_0;
697 nstrace_buf = (gchar *)g_malloc(NSPR_PAGESIZE_TRACE);
698 page_size = GET_READ_PAGE_SIZEV3(file_size);
702 /* No known signature found, assume it's not NetScaler */
707 if ((file_seek(wth->fh, 0, SEEK_SET, err)) == -1)
709 *err = file_error(wth->fh, err_info);
714 if (!wtap_read_bytes(wth->fh, nstrace_buf, page_size, err, err_info))
717 if (*err != WTAP_ERR_SHORT_READ)
722 switch (wth->file_type_subtype)
724 case WTAP_FILE_TYPE_SUBTYPE_NETSCALER_1_0:
725 wth->subtype_read = nstrace_read_v10;
726 wth->subtype_seek_read = nstrace_seek_read_v10;
729 case WTAP_FILE_TYPE_SUBTYPE_NETSCALER_2_0:
730 wth->subtype_read = nstrace_read_v20;
731 wth->subtype_seek_read = nstrace_seek_read_v20;
734 case WTAP_FILE_TYPE_SUBTYPE_NETSCALER_3_0:
735 wth->subtype_read = nstrace_read_v30;
736 wth->subtype_seek_read = nstrace_seek_read_v30;
739 wth->subtype_close = nstrace_close;
741 nstrace = (nstrace_t *)g_malloc(sizeof(nstrace_t));
742 wth->priv = (void *)nstrace;
743 nstrace->pnstrace_buf = nstrace_buf;
744 nstrace->xxx_offset = 0;
745 nstrace->nstrace_buflen = page_size;
746 nstrace->nstrace_buf_offset = 0;
747 nstrace->nspm_curtime = 0;
748 nstrace->nspm_curtimemsec = 0;
749 nstrace->nspm_curtimelastmsec = 0;
750 nstrace->nsg_creltime = 0;
751 nstrace->file_size = file_size;
754 /* Set the start time by looking for the abstime record */
755 if ((nstrace_set_start_time(wth)) == FALSE)
757 /* Reset the read pointer to start of the file. */
758 if ((file_seek(wth->fh, 0, SEEK_SET, err)) == -1)
760 g_free(nstrace->pnstrace_buf);
765 /* Read the first page of data */
766 if (!wtap_read_bytes(wth->fh, nstrace_buf, page_size, err, err_info))
768 g_free(nstrace->pnstrace_buf);
773 /* reset the buffer offset */
774 nstrace->nstrace_buf_offset = 0;
777 wth->file_tsprec = WTAP_TSPREC_NSEC;
778 wth->phdr.ts.secs = nstrace->nspm_curtime;
779 wth->phdr.ts.nsecs = 0;
786 #define nspm_signature_func(ver) \
787 static guint32 nspm_signature_isv##ver(gchar *sigp) {\
788 return strncmp(sigp,NSPR_SIGSTR_V##ver,(sizeof(NSPR_SIGSTR_V##ver)-1));\
791 nspm_signature_func(10)
792 nspm_signature_func(20)
793 nspm_signature_func(30)
796 ** Check signature and return the file type and subtype for files with
797 ** that signature. If it finds no signature that it recognizes, it
798 ** returns WTAP_FILE_TYPE_SUBTYPE_UNKNOWN. At the time of return from
799 ** this function we might not be at the first page. So after a call to
800 ** this function, there has to be a file seek to return to the start
801 ** of the first page.
804 nspm_signature_version(wtap *wth, gchar *nstrace_buf, gint32 len)
806 gchar *dp = nstrace_buf;
809 bytes_read = file_read(dp, len, wth->fh);
810 if (bytes_read == len) {
812 for ( ; len > (gint32)(MIN(sizeof(NSPR_SIGSTR_V10), sizeof(NSPR_SIGSTR_V20))); dp++, len--)
814 #define sigv10p ((nspr_signature_v10_t*)dp)
815 if ((pletoh16(&sigv10p->nsprRecordType) == NSPR_SIGNATURE_V10) &&
816 (pletoh16(&sigv10p->nsprRecordSize) <= len) &&
817 ((gint32)sizeof(NSPR_SIGSTR_V10) <= len) &&
818 (!nspm_signature_isv10(sigv10p->sig_Signature)))
819 return WTAP_FILE_TYPE_SUBTYPE_NETSCALER_1_0;
822 #define sigv20p ((nspr_signature_v20_t*)dp)
823 if ((sigv20p->sig_RecordType == NSPR_SIGNATURE_V20) &&
824 (sigv20p->sig_RecordSize <= len) &&
825 ((gint32)sizeof(NSPR_SIGSTR_V20) <= len))
827 if (!nspm_signature_isv20(sigv20p->sig_Signature))
828 return WTAP_FILE_TYPE_SUBTYPE_NETSCALER_2_0;
829 else if (!nspm_signature_isv30(sigv20p->sig_Signature))
830 return WTAP_FILE_TYPE_SUBTYPE_NETSCALER_3_0;
836 return WTAP_FILE_TYPE_SUBTYPE_UNKNOWN; /* no version found */
839 #define nspr_getv10recordtype(hdp) (pletoh16(&(hdp)->nsprRecordType))
840 #define nspr_getv10recordsize(hdp) (pletoh16(&(hdp)->nsprRecordSize))
841 #define nspr_getv20recordtype(hdp) ((hdp)->phd_RecordType)
842 #define nspr_getv20recordsize(hdp) \
843 (((hdp)->phd_RecordSizeLow & NSPR_V20RECORDSIZE_2BYTES)? \
844 (((hdp)->phd_RecordSizeHigh * NSPR_V20RECORDSIZE_2BYTES)+ \
845 ((hdp)->phd_RecordSizeLow & ~NSPR_V20RECORDSIZE_2BYTES)) : \
846 (hdp)->phd_RecordSizeLow)
849 #define nstrace_set_start_time_ver(ver) \
850 gboolean nstrace_set_start_time_v##ver(wtap *wth) \
852 nstrace_t *nstrace = (nstrace_t *)wth->priv;\
853 gchar* nstrace_buf = nstrace->pnstrace_buf;\
854 gint32 nstrace_buf_offset = nstrace->nstrace_buf_offset;\
855 gint32 nstrace_buflen = nstrace->nstrace_buflen;\
859 while (nstrace_buf_offset < nstrace_buflen)\
861 nspr_hd_v##ver##_t *fp = (nspr_hd_v##ver##_t *) &nstrace_buf[nstrace_buf_offset];\
862 switch (nspr_getv##ver##recordtype(fp))\
864 case NSPR_ABSTIME_V##ver:\
865 ns_setabstime(nstrace, pletoh32(&((nspr_abstime_v##ver##_t *) fp)->abs_Time), pletoh16(&((nspr_abstime_v##ver##_t *) fp)->abs_RelTime));\
866 nstrace->nstrace_buf_offset = nstrace_buf_offset + nspr_getv##ver##recordsize(fp);\
867 nstrace->nstrace_buflen = nstrace_buflen;\
869 case NSPR_UNUSEDSPACE_V10:\
870 nstrace_buf_offset = nstrace_buflen;\
873 nstrace_buf_offset += nspr_getv##ver##recordsize(fp);\
876 nstrace_buf_offset = 0;\
877 nstrace->xxx_offset += nstrace_buflen;\
878 nstrace_buflen = GET_READ_PAGE_SIZE((nstrace->file_size - nstrace->xxx_offset));\
879 }while((nstrace_buflen > 0) && (bytes_read = file_read(nstrace_buf, nstrace_buflen, wth->fh)) && bytes_read == nstrace_buflen); \
883 nstrace_set_start_time_ver(10)
884 nstrace_set_start_time_ver(20)
886 #undef nspr_getv10recordtype
887 #undef nspr_getv20recordtype
890 ** Set the start time of the trace file. We look for the first ABSTIME record. We use that
891 ** to set the start time. Apart from that we also make sure that we remember the position of
892 ** the next record after the ABSTIME record. Inorder to report correct time values, all trace
893 ** records before the ABSTIME record are ignored.
895 static gboolean nstrace_set_start_time(wtap *wth)
897 if (wth->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_1_0)
898 return nstrace_set_start_time_v10(wth);
899 else if (wth->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_2_0)
900 return nstrace_set_start_time_v20(wth);
901 else if (wth->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_3_0)
902 return nstrace_set_start_time_v20(wth);
906 #define __TNO(phdr,enumprefix,structprefix,structname,hdrname,structfieldname) \
907 (phdr)->pseudo_header.nstr.hdrname##_offset = enumprefix##_##hdrname##_offset;
909 #define __TNL(phdr,enumprefix,structprefix,structname,hdrname,structfieldname) \
910 (phdr)->pseudo_header.nstr.hdrname##_len = enumprefix##_##hdrname##_len;
912 #define __TNV1O(phdr,enumprefix,structprefix,structname,hdrname,structfieldname) \
913 __TNO(phdr,enumprefix,structprefix,structname,hdrname,structfieldname)
915 #define __TNV1L(phdr,enumprefix,structprefix,structname,hdrname,structfieldname) \
916 __TNL(phdr,enumprefix,structprefix,structname,hdrname,structfieldname)
921 ** Netscaler trace format read routines.
923 static gboolean nstrace_read_v10(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
925 nstrace_t *nstrace = (nstrace_t *)wth->priv;
926 guint64 nsg_creltime = nstrace->nsg_creltime;
927 gchar *nstrace_buf = nstrace->pnstrace_buf;
928 gint32 nstrace_buf_offset = nstrace->nstrace_buf_offset;
929 gint32 nstrace_buflen = nstrace->nstrace_buflen;
930 nspr_pktracefull_v10_t *fp;
931 nspr_pktracepart_v10_t *pp;
938 while ((nstrace_buf_offset < nstrace_buflen) &&
939 ((nstrace_buflen - nstrace_buf_offset) >= ((gint32)sizeof(fp->nsprRecordType))))
942 #define GENERATE_CASE_FULL(phdr,type,acttype) \
943 case NSPR_PDPKTRACEFULLTX_V##type:\
944 case NSPR_PDPKTRACEFULLTXB_V##type:\
945 case NSPR_PDPKTRACEFULLRX_V##type:\
946 fp = (nspr_pktracefull_v10_t *) &nstrace_buf[nstrace_buf_offset];\
948 * XXX - we can't do this in the seek-read routine,\
949 * as the time stamps in the records are relative to\
950 * the previous packet.\
952 (phdr)->rec_type = REC_TYPE_PACKET;\
953 (phdr)->presence_flags = WTAP_HAS_TS;\
954 nsg_creltime += ns_hrtime2nsec(pletoh32(&fp->fp_RelTimeHr));\
955 (phdr)->ts.secs = nstrace->nspm_curtime + (guint32) (nsg_creltime / 1000000000);\
956 (phdr)->ts.nsecs = (guint32) (nsg_creltime % 1000000000);\
957 TRACE_FULL_V##type##_REC_LEN_OFF(phdr,v##type##_full,fp,pktracefull_v##type);\
958 ws_buffer_assure_space(wth->frame_buffer, (phdr)->caplen);\
959 memcpy(ws_buffer_start_ptr(wth->frame_buffer), fp, (phdr)->caplen);\
960 *data_offset = nstrace->xxx_offset + nstrace_buf_offset;\
961 nstrace->nstrace_buf_offset = nstrace_buf_offset + (phdr)->len;\
962 nstrace->nstrace_buflen = nstrace_buflen;\
963 nstrace->nsg_creltime = nsg_creltime;\
966 #define GENERATE_CASE_PART(phdr,type,acttype) \
967 case NSPR_PDPKTRACEPARTTX_V##type:\
968 case NSPR_PDPKTRACEPARTTXB_V##type:\
969 case NSPR_PDPKTRACEPARTRX_V##type:\
970 pp = (nspr_pktracepart_v10_t *) &nstrace_buf[nstrace_buf_offset];\
972 * XXX - we can't do this in the seek-read routine,\
973 * as the time stamps in the records are relative to\
974 * the previous packet.\
976 (phdr)->rec_type = REC_TYPE_PACKET;\
977 (phdr)->presence_flags = WTAP_HAS_TS;\
978 nsg_creltime += ns_hrtime2nsec(pletoh32(&pp->pp_RelTimeHr));\
979 (phdr)->ts.secs = nstrace->nspm_curtime + (guint32) (nsg_creltime / 1000000000);\
980 (phdr)->ts.nsecs = (guint32) (nsg_creltime % 1000000000);\
981 TRACE_PART_V##type##_REC_LEN_OFF(phdr,v##type##_part,pp,pktracepart_v##type);\
982 ws_buffer_assure_space(wth->frame_buffer, (phdr)->caplen);\
983 memcpy(ws_buffer_start_ptr(wth->frame_buffer), pp, (phdr)->caplen);\
984 *data_offset = nstrace->xxx_offset + nstrace_buf_offset;\
985 nstrace->nstrace_buf_offset = nstrace_buf_offset + (phdr)->caplen;\
986 nstrace->nsg_creltime = nsg_creltime;\
987 nstrace->nstrace_buflen = nstrace_buflen;\
990 switch (pletoh16(&(( nspr_header_v10_t*)&nstrace_buf[nstrace_buf_offset])->ph_RecordType))
992 GENERATE_CASE_FULL(&wth->phdr,10,100)
993 GENERATE_CASE_PART(&wth->phdr,10,100)
995 #undef GENERATE_CASE_FULL
996 #undef GENERATE_CASE_PART
998 case NSPR_ABSTIME_V10:
1000 fp = (nspr_pktracefull_v10_t *) &nstrace_buf[nstrace_buf_offset];
1001 ns_setabstime(nstrace, pletoh32(((nspr_abstime_v10_t *) fp)->abs_Time), pletoh32(&((nspr_abstime_v10_t *) fp)->abs_RelTime));
1002 nstrace_buf_offset += pletoh16(&fp->nsprRecordSize);
1005 case NSPR_RELTIME_V10:
1007 fp = (nspr_pktracefull_v10_t *) &nstrace_buf[nstrace_buf_offset];
1008 ns_setrelativetime(nstrace, pletoh32(((nspr_abstime_v10_t *) fp)->abs_RelTime));
1009 nstrace_buf_offset += pletoh16(&fp->nsprRecordSize);
1012 case NSPR_UNUSEDSPACE_V10:
1014 nstrace_buf_offset = nstrace_buflen;
1019 fp = (nspr_pktracefull_v10_t *) &nstrace_buf[nstrace_buf_offset];
1020 nstrace_buf_offset += pletoh16(&fp->nsprRecordSize);
1025 nstrace_buf_offset = 0;
1026 nstrace->xxx_offset += nstrace_buflen;
1027 nstrace_buflen = GET_READ_PAGE_SIZE((nstrace->file_size - nstrace->xxx_offset));
1028 }while((nstrace_buflen > 0) && (bytes_read = file_read(nstrace_buf, nstrace_buflen, wth->fh)) && (bytes_read == nstrace_buflen));
1033 #define TIMEDEFV20(fp,type) \
1035 wth->phdr.rec_type = REC_TYPE_PACKET;\
1036 wth->phdr.presence_flags |= WTAP_HAS_TS;\
1037 nsg_creltime += ns_hrtime2nsec(pletoh32(fp->type##_RelTimeHr));\
1038 wth->phdr.ts.secs = nstrace->nspm_curtime + (guint32) (nsg_creltime / 1000000000);\
1039 wth->phdr.ts.nsecs = (guint32) (nsg_creltime % 1000000000);\
1042 #define TIMEDEFV23(fp,type) \
1044 wth->phdr.rec_type = REC_TYPE_PACKET;\
1045 wth->phdr.presence_flags |= WTAP_HAS_TS;\
1046 /* access _AbsTimeHr as a 64bit value */\
1047 nsg_creltime = pletoh64(fp->type##_AbsTimeHr);\
1048 wth->phdr.ts.secs = (guint32) (nsg_creltime / 1000000000);\
1049 wth->phdr.ts.nsecs = (guint32) (nsg_creltime % 1000000000);\
1052 #define TIMEDEFV30(fp,type) \
1054 wth->phdr.rec_type = REC_TYPE_PACKET;\
1055 wth->phdr.presence_flags |= WTAP_HAS_TS;\
1056 /* access _AbsTimeHr as a 64bit value */\
1057 nsg_creltime = pletoh64(fp->type##_AbsTimeHr);\
1058 wth->phdr.ts.secs = (guint32) (nsg_creltime / 1000000000);\
1059 wth->phdr.ts.nsecs = (guint32) (nsg_creltime % 1000000000);\
1062 #define TIMEDEFV21(fp,type) TIMEDEFV20(fp,type)
1063 #define TIMEDEFV22(fp,type) TIMEDEFV20(fp,type)
1064 #define TIMEDEFV24(fp,type) TIMEDEFV23(fp,type)
1065 #define TIMEDEFV25(fp,type) TIMEDEFV24(fp,type)
1066 #define TIMEDEFV26(fp,type) TIMEDEFV24(fp,type)
1068 #define PPSIZEDEFV20(phdr,pp,ver) \
1070 (phdr)->rec_type = REC_TYPE_PACKET;\
1071 (phdr)->presence_flags |= WTAP_HAS_CAP_LEN;\
1072 (phdr)->len = pletoh16(&pp->pp_PktSizeOrg) + nspr_pktracepart_v##ver##_s;\
1073 (phdr)->caplen = nspr_getv20recordsize((nspr_hd_v20_t *)pp);\
1076 #define PPSIZEDEFV21(phdr,pp,ver) PPSIZEDEFV20(phdr,pp,ver)
1077 #define PPSIZEDEFV22(phdr,pp,ver) PPSIZEDEFV20(phdr,pp,ver)
1078 #define PPSIZEDEFV23(phdr,pp,ver) PPSIZEDEFV20(phdr,pp,ver)
1079 #define PPSIZEDEFV24(phdr,pp,ver) PPSIZEDEFV20(phdr,pp,ver)
1080 #define PPSIZEDEFV25(phdr,pp,ver) PPSIZEDEFV20(phdr,pp,ver)
1081 #define PPSIZEDEFV26(phdr,pp,ver) PPSIZEDEFV20(phdr,pp,ver)
1083 #define FPSIZEDEFV20(phdr,fp,ver)\
1085 (phdr)->len = nspr_getv20recordsize((nspr_hd_v20_t *)fp);\
1086 (phdr)->caplen = (phdr)->len;\
1089 #define FPSIZEDEFV21(phdr,fp,ver) FPSIZEDEFV20(phdr,fp,ver)
1090 #define FPSIZEDEFV22(phdr,fp,ver) FPSIZEDEFV20(phdr,fp,ver)
1091 #define FPSIZEDEFV23(phdr,fp,ver) FPSIZEDEFV20(phdr,fp,ver)
1092 #define FPSIZEDEFV24(phdr,fp,ver) FPSIZEDEFV20(phdr,fp,ver)
1093 #define FPSIZEDEFV25(phdr,fp,ver) FPSIZEDEFV20(phdr,fp,ver)
1094 #define FPSIZEDEFV26(phdr,fp,ver) FPSIZEDEFV20(phdr,fp,ver)
1096 #define FPSIZEDEFV30(phdr,fp,ver)\
1098 (phdr)->rec_type = REC_TYPE_PACKET;\
1099 (phdr)->presence_flags |= WTAP_HAS_CAP_LEN;\
1100 (phdr)->len = pletoh16(&fp->fp_PktSizeOrg) + nspr_pktracefull_v##ver##_s;\
1101 (phdr)->caplen = nspr_getv20recordsize((nspr_hd_v20_t *)fp);\
1104 #define PACKET_DESCRIBE(phdr,FPTIMEDEF,SIZEDEF,ver,enumprefix,type,structname,TYPE)\
1106 nspr_##structname##_t *fp= (nspr_##structname##_t*)&nstrace_buf[nstrace_buf_offset];\
1107 TIMEDEFV##ver(fp,type);\
1108 SIZEDEF##ver((phdr),fp,ver);\
1109 TRACE_V##ver##_REC_LEN_OFF((phdr),enumprefix,type,structname);\
1110 (phdr)->pseudo_header.nstr.rec_type = NSPR_HEADER_VERSION##TYPE;\
1111 ws_buffer_assure_space(wth->frame_buffer, (phdr)->caplen);\
1112 memcpy(ws_buffer_start_ptr(wth->frame_buffer), fp, (phdr)->caplen);\
1113 *data_offset = nstrace->xxx_offset + nstrace_buf_offset;\
1114 nstrace->nstrace_buf_offset = nstrace_buf_offset + nspr_getv20recordsize((nspr_hd_v20_t *)fp);\
1115 nstrace->nstrace_buflen = nstrace_buflen;\
1116 nstrace->nsg_creltime = nsg_creltime;\
1120 static gboolean nstrace_read_v20(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
1122 nstrace_t *nstrace = (nstrace_t *)wth->priv;
1123 guint64 nsg_creltime = nstrace->nsg_creltime;
1124 gchar *nstrace_buf = nstrace->pnstrace_buf;
1125 gint32 nstrace_buf_offset = nstrace->nstrace_buf_offset;
1126 gint32 nstrace_buflen = nstrace->nstrace_buflen;
1133 while ((nstrace_buf_offset < nstrace_buflen) &&
1134 ((nstrace_buflen - nstrace_buf_offset) >= ((gint32)sizeof((( nspr_hd_v20_t*)&nstrace_buf[nstrace_buf_offset])->phd_RecordType))))
1136 switch ((( nspr_hd_v20_t*)&nstrace_buf[nstrace_buf_offset])->phd_RecordType)
1139 #define GENERATE_CASE_FULL(phdr,type,acttype) \
1140 case NSPR_PDPKTRACEFULLTX_V##type:\
1141 case NSPR_PDPKTRACEFULLTXB_V##type:\
1142 case NSPR_PDPKTRACEFULLRX_V##type:\
1143 PACKET_DESCRIBE(phdr,TIMEDEF,FPSIZEDEFV,type,v##type##_full,fp,pktracefull_v##type,acttype);
1145 #define GENERATE_CASE_FULL_V25(phdr,type,acttype) \
1146 case NSPR_PDPKTRACEFULLTX_V##type:\
1147 case NSPR_PDPKTRACEFULLTXB_V##type:\
1148 case NSPR_PDPKTRACEFULLRX_V##type:\
1149 case NSPR_PDPKTRACEFULLNEWRX_V##type:\
1150 PACKET_DESCRIBE(phdr,TIMEDEF,FPSIZEDEFV,type,v##type##_full,fp,pktracefull_v##type,acttype);
1152 #define GENERATE_CASE_PART(phdr,type,acttype) \
1153 case NSPR_PDPKTRACEPARTTX_V##type:\
1154 case NSPR_PDPKTRACEPARTTXB_V##type:\
1155 case NSPR_PDPKTRACEPARTRX_V##type:\
1156 PACKET_DESCRIBE(phdr,TIMEDEF,PPSIZEDEFV,type,v##type##_part,pp,pktracepart_v##type,acttype);
1158 #define GENERATE_CASE_PART_V25(phdr,type,acttype) \
1159 case NSPR_PDPKTRACEPARTTX_V##type:\
1160 case NSPR_PDPKTRACEPARTTXB_V##type:\
1161 case NSPR_PDPKTRACEPARTRX_V##type:\
1162 case NSPR_PDPKTRACEPARTNEWRX_V##type:\
1163 PACKET_DESCRIBE(phdr,TIMEDEF,PPSIZEDEFV,type,v##type##_part,pp,pktracepart_v##type,acttype);
1165 GENERATE_CASE_FULL(&wth->phdr,20,200);
1166 GENERATE_CASE_PART(&wth->phdr,20,200);
1167 GENERATE_CASE_FULL(&wth->phdr,21,201);
1168 GENERATE_CASE_PART(&wth->phdr,21,201);
1169 GENERATE_CASE_FULL(&wth->phdr,22,202);
1170 GENERATE_CASE_PART(&wth->phdr,22,202);
1171 GENERATE_CASE_FULL(&wth->phdr,23,203);
1172 GENERATE_CASE_PART(&wth->phdr,23,203);
1173 GENERATE_CASE_FULL_V25(&wth->phdr,24,204);
1174 GENERATE_CASE_PART_V25(&wth->phdr,24,204);
1175 GENERATE_CASE_FULL_V25(&wth->phdr,25,205);
1176 GENERATE_CASE_PART_V25(&wth->phdr,25,205);
1177 GENERATE_CASE_FULL_V25(&wth->phdr,26,206);
1178 GENERATE_CASE_PART_V25(&wth->phdr,26,206);
1180 #undef GENERATE_CASE_FULL
1181 #undef GENERATE_CASE_FULL_V25
1182 #undef GENERATE_CASE_PART
1183 #undef GENERATE_CASE_PART_V25
1185 case NSPR_ABSTIME_V20:
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);
1189 ns_setabstime(nstrace, pletoh32(&((nspr_abstime_v20_t *) fp20)->abs_Time), pletoh16(&((nspr_abstime_v20_t *) fp20)->abs_RelTime));
1193 case NSPR_RELTIME_V20:
1195 nspr_pktracefull_v20_t *fp20 = (nspr_pktracefull_v20_t *) &nstrace_buf[nstrace_buf_offset];
1196 ns_setrelativetime(nstrace, pletoh16(&((nspr_abstime_v20_t *) fp20)->abs_RelTime));
1197 nstrace_buf_offset += nspr_getv20recordsize((nspr_hd_v20_t *)fp20);
1201 case NSPR_UNUSEDSPACE_V20:
1203 if (nstrace_buf_offset >= NSPR_PAGESIZE/2)
1204 nstrace_buf_offset = nstrace_buflen;
1206 nstrace_buf_offset = NSPR_PAGESIZE/2;
1212 nspr_pktracefull_v20_t *fp20 = (nspr_pktracefull_v20_t *) &nstrace_buf[nstrace_buf_offset];
1213 nstrace_buf_offset += nspr_getv20recordsize((nspr_hd_v20_t *)fp20);
1219 nstrace_buf_offset = 0;
1220 nstrace->xxx_offset += nstrace_buflen;
1221 nstrace_buflen = GET_READ_PAGE_SIZE((nstrace->file_size - nstrace->xxx_offset));
1222 }while((nstrace_buflen > 0) && (bytes_read = file_read(nstrace_buf, nstrace_buflen, wth->fh)) && (bytes_read == nstrace_buflen));
1227 #undef PACKET_DESCRIBE
1229 #define PACKET_DESCRIBE(phdr,FPTIMEDEF,SIZEDEF,ver,enumprefix,type,structname,TYPE)\
1231 nspr_##structname##_t *fp = (nspr_##structname##_t *) &nstrace_buf[nstrace_buf_offset];\
1232 TIMEDEFV##ver(fp,type);\
1233 SIZEDEF##ver((phdr),fp,ver);\
1234 TRACE_V##ver##_REC_LEN_OFF((phdr),enumprefix,type,structname);\
1235 (phdr)->pseudo_header.nstr.rec_type = NSPR_HEADER_VERSION##TYPE;\
1236 ws_buffer_assure_space(wth->frame_buffer, (phdr)->caplen);\
1237 *data_offset = nstrace->xxx_offset + nstrace_buf_offset;\
1238 while (nstrace_tmpbuff_off < nspr_##structname##_s) {\
1239 nstrace_tmpbuff[nstrace_tmpbuff_off++] = nstrace_buf[nstrace_buf_offset++];\
1241 nst_dataSize = nspr_getv20recordsize(hdp);\
1242 rec_size = nst_dataSize - nstrace_tmpbuff_off;\
1243 nsg_nextPageOffset = ((nstrace_buf_offset + rec_size) >= NSPR_PAGESIZE_TRACE) ?\
1244 ((nstrace_buf_offset + rec_size) - (NSPR_PAGESIZE_TRACE - 1)) : 0;\
1245 while (nsg_nextPageOffset) {\
1246 while (nstrace_buf_offset < NSPR_PAGESIZE_TRACE) {\
1247 nstrace_tmpbuff[nstrace_tmpbuff_off++] = nstrace_buf[nstrace_buf_offset++];\
1249 nstrace_buflen = NSPR_PAGESIZE_TRACE;\
1250 nstrace->xxx_offset += nstrace_buflen;\
1251 bytes_read = file_read(nstrace_buf, NSPR_PAGESIZE_TRACE, wth->fh);\
1252 if (bytes_read != NSPR_PAGESIZE_TRACE) {\
1255 nstrace_buf_offset = 0;\
1257 rec_size = nst_dataSize - nstrace_tmpbuff_off;\
1258 nsg_nextPageOffset = ((nstrace_buf_offset + rec_size) >= NSPR_PAGESIZE_TRACE) ?\
1259 ((nstrace_buf_offset + rec_size) - (NSPR_PAGESIZE_TRACE- 1)): 0;\
1261 while (nstrace_tmpbuff_off < nst_dataSize) {\
1262 nstrace_tmpbuff[nstrace_tmpbuff_off++] = nstrace_buf[nstrace_buf_offset++];\
1264 memcpy(ws_buffer_start_ptr(wth->frame_buffer), nstrace_tmpbuff, (phdr)->caplen);\
1265 nstrace->nstrace_buf_offset = nstrace_buf_offset;\
1266 nstrace->nstrace_buflen = nstrace_buflen = ((gint32)NSPR_PAGESIZE_TRACE);\
1267 nstrace->nsg_creltime = nsg_creltime;\
1271 static gboolean nstrace_read_v30(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
1273 nstrace_t *nstrace = (nstrace_t *)wth->priv;
1274 guint64 nsg_creltime = nstrace->nsg_creltime;
1275 gchar *nstrace_buf = nstrace->pnstrace_buf;
1276 gint32 nstrace_buf_offset = nstrace->nstrace_buf_offset;
1277 gint32 nstrace_buflen = nstrace->nstrace_buflen;
1278 guint8 nstrace_tmpbuff[65536];
1279 guint32 nstrace_tmpbuff_off=0,nst_dataSize=0,rec_size=0,nsg_nextPageOffset=0;
1287 while ((nstrace_buf_offset < NSPR_PAGESIZE_TRACE) &&
1288 nstrace_buf[nstrace_buf_offset])
1290 hdp = (nspr_hd_v20_t *) &nstrace_buf[nstrace_buf_offset];
1291 switch (hdp->phd_RecordType)
1294 #define GENERATE_CASE_V30(phdr,type,acttype) \
1295 case NSPR_PDPKTRACEFULLTX_V##type:\
1296 case NSPR_PDPKTRACEFULLTXB_V##type:\
1297 case NSPR_PDPKTRACEFULLRX_V##type:\
1298 case NSPR_PDPKTRACEFULLNEWRX_V##type:\
1299 PACKET_DESCRIBE(phdr, TIMEDEF, FPSIZEDEFV,type,v##type##_full,fp,pktracefull_v##type,acttype);
1300 GENERATE_CASE_V30(&wth->phdr,30, 300);
1301 #undef GENERATE_CASE_V30
1303 case NSPR_ABSTIME_V20:
1305 nstrace_buf_offset += nspr_getv20recordsize(hdp);
1306 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));
1310 case NSPR_RELTIME_V20:
1312 ns_setrelativetime(nstrace, pletoh16(&((nspr_abstime_v20_t *) &nstrace_buf[nstrace_buf_offset])->abs_RelTime));
1313 nstrace_buf_offset += nspr_getv20recordsize(hdp);
1319 nstrace_buf_offset += nspr_getv20recordsize(hdp);
1324 nstrace_buf_offset = 0;
1325 nstrace->xxx_offset += nstrace_buflen;
1326 nstrace_buflen = NSPR_PAGESIZE_TRACE;
1327 } while((nstrace_buflen > 0) && (bytes_read = file_read(nstrace_buf, nstrace_buflen, wth->fh)) && (bytes_read == nstrace_buflen));
1332 #undef PACKET_DESCRIBE
1334 static gboolean nstrace_seek_read_v10(wtap *wth, gint64 seek_off,
1335 struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info)
1338 guint record_length;
1340 unsigned int bytes_to_read;
1341 nspr_pktracefull_v10_t *fp;
1342 nspr_pktracepart_v10_t *pp;
1346 if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
1350 ** Read the record header.
1352 if (!wtap_read_bytes(wth->random_fh, (void *)&hdr, sizeof hdr,
1357 ** Get the record length.
1359 record_length = nspr_getv10recordsize(&hdr);
1362 ** Copy the header to the buffer and read the rest of the record..
1364 ws_buffer_assure_space(buf, record_length);
1365 pd = ws_buffer_start_ptr(buf);
1366 memcpy(pd, (void *)&hdr, sizeof hdr);
1367 if (record_length > sizeof hdr) {
1368 bytes_to_read = (unsigned int)(record_length - sizeof hdr);
1369 if (!wtap_read_bytes(wth->random_fh, pd + sizeof hdr, bytes_to_read,
1375 ** Fill in what part of the struct wtap_pkthdr we can.
1377 #define GENERATE_CASE_FULL(phdr,type,acttype) \
1378 case NSPR_PDPKTRACEFULLTX_V##type:\
1379 case NSPR_PDPKTRACEFULLTXB_V##type:\
1380 case NSPR_PDPKTRACEFULLRX_V##type:\
1381 fp = (nspr_pktracefull_v10_t *) pd;\
1382 TRACE_FULL_V##type##_REC_LEN_OFF(phdr,v##type##_full,fp,pktracefull_v##type);\
1383 (phdr)->pseudo_header.nstr.rec_type = NSPR_HEADER_VERSION##acttype;\
1386 #define GENERATE_CASE_PART(phdr,type,acttype) \
1387 case NSPR_PDPKTRACEPARTTX_V##type:\
1388 case NSPR_PDPKTRACEPARTTXB_V##type:\
1389 case NSPR_PDPKTRACEPARTRX_V##type:\
1390 pp = (nspr_pktracepart_v10_t *) pd;\
1391 TRACE_PART_V##type##_REC_LEN_OFF(phdr,v##type##_part,pp,pktracepart_v##type);\
1392 (phdr)->pseudo_header.nstr.rec_type = NSPR_HEADER_VERSION##acttype;\
1395 switch (pletoh16(&(( nspr_header_v10_t*)pd)->ph_RecordType))
1397 GENERATE_CASE_FULL(phdr,10,100)
1398 GENERATE_CASE_PART(phdr,10,100)
1401 #undef GENERATE_CASE_FULL
1402 #undef GENERATE_CASE_PART
1407 #define PACKET_DESCRIBE(phdr,FPTIMEDEF,SIZEDEF,ver,enumprefix,type,structname,TYPE)\
1409 nspr_##structname##_t *fp= (nspr_##structname##_t*)pd;\
1410 SIZEDEF##ver((phdr),fp,ver);\
1411 TRACE_V##ver##_REC_LEN_OFF((phdr),enumprefix,type,structname);\
1412 (phdr)->pseudo_header.nstr.rec_type = NSPR_HEADER_VERSION##TYPE;\
1416 static gboolean nstrace_seek_read_v20(wtap *wth, gint64 seek_off,
1417 struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info)
1420 guint record_length;
1423 unsigned int bytes_to_read;
1427 if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
1431 ** Read the first 2 bytes of the record header.
1433 if (!wtap_read_bytes(wth->random_fh, (void *)&hdr, 2, err, err_info))
1438 ** Is there a third byte? If so, read it.
1440 if (hdr.phd_RecordSizeLow & NSPR_V20RECORDSIZE_2BYTES) {
1441 if (!wtap_read_bytes(wth->random_fh, (void *)&hdr.phd_RecordSizeHigh, 1,
1448 ** Get the record length.
1450 record_length = nspr_getv20recordsize(&hdr);
1453 ** Copy the header to the buffer and read the rest of the record..
1455 ws_buffer_assure_space(buf, record_length);
1456 pd = ws_buffer_start_ptr(buf);
1457 memcpy(pd, (void *)&hdr, hdrlen);
1458 if (record_length > hdrlen) {
1459 bytes_to_read = (unsigned int)(record_length - hdrlen);
1460 if (!wtap_read_bytes(wth->random_fh, pd + hdrlen, bytes_to_read,
1465 #define GENERATE_CASE_FULL(phdr,type,acttype) \
1466 case NSPR_PDPKTRACEFULLTX_V##type:\
1467 case NSPR_PDPKTRACEFULLTXB_V##type:\
1468 case NSPR_PDPKTRACEFULLRX_V##type:\
1469 PACKET_DESCRIBE(phdr,TIMEDEF,FPSIZEDEFV,type,v##type##_full,fp,pktracefull_v##type,acttype);
1471 #define GENERATE_CASE_FULL_V25(phdr,type,acttype) \
1472 case NSPR_PDPKTRACEFULLTX_V##type:\
1473 case NSPR_PDPKTRACEFULLTXB_V##type:\
1474 case NSPR_PDPKTRACEFULLRX_V##type:\
1475 case NSPR_PDPKTRACEFULLNEWRX_V##type:\
1476 PACKET_DESCRIBE(phdr,TIMEDEF,FPSIZEDEFV,type,v##type##_full,fp,pktracefull_v##type,acttype);
1478 #define GENERATE_CASE_PART(phdr,type,acttype) \
1479 case NSPR_PDPKTRACEPARTTX_V##type:\
1480 case NSPR_PDPKTRACEPARTTXB_V##type:\
1481 case NSPR_PDPKTRACEPARTRX_V##type:\
1482 PACKET_DESCRIBE(phdr,TIMEDEF,PPSIZEDEFV,type,v##type##_part,pp,pktracepart_v##type,acttype);
1484 #define GENERATE_CASE_PART_V25(phdr,type,acttype) \
1485 case NSPR_PDPKTRACEPARTTX_V##type:\
1486 case NSPR_PDPKTRACEPARTTXB_V##type:\
1487 case NSPR_PDPKTRACEPARTRX_V##type:\
1488 case NSPR_PDPKTRACEPARTNEWRX_V##type:\
1489 PACKET_DESCRIBE(phdr,TIMEDEF,PPSIZEDEFV,type,v##type##_part,pp,pktracepart_v##type,acttype);
1491 switch ((( nspr_hd_v20_t*)pd)->phd_RecordType)
1493 GENERATE_CASE_FULL(phdr,20,200)
1494 GENERATE_CASE_PART(phdr,20,200)
1495 GENERATE_CASE_FULL(phdr,21,201)
1496 GENERATE_CASE_PART(phdr,21,201)
1497 GENERATE_CASE_FULL(phdr,22,202)
1498 GENERATE_CASE_PART(phdr,22,202)
1499 GENERATE_CASE_FULL(phdr,23,203)
1500 GENERATE_CASE_PART(phdr,23,203)
1501 GENERATE_CASE_FULL_V25(phdr,24,204)
1502 GENERATE_CASE_PART_V25(phdr,24,204)
1503 GENERATE_CASE_FULL_V25(phdr,25,205)
1504 GENERATE_CASE_PART_V25(phdr,25,205)
1505 GENERATE_CASE_FULL_V25(phdr,26,206)
1506 GENERATE_CASE_PART_V25(phdr,26,206)
1509 #undef GENERATE_CASE_FULL
1510 #undef GENERATE_CASE_FULL_V25
1511 #undef GENERATE_CASE_PART
1512 #undef GENERATE_CASE_PART_V25
1518 static gboolean nstrace_seek_read_v30(wtap *wth, gint64 seek_off,
1519 struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info)
1522 guint record_length;
1525 unsigned int bytes_to_read;
1529 if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
1532 ** Read the first 2 bytes of the record header.
1534 if (!wtap_read_bytes(wth->random_fh, (void *)&hdr, 2, err, err_info))
1539 ** Is there a third byte? If so, read it.
1541 if (hdr.phd_RecordSizeLow & NSPR_V20RECORDSIZE_2BYTES) {
1542 if (!wtap_read_bytes(wth->random_fh, (void *)&hdr.phd_RecordSizeHigh, 1,
1549 ** Get the record length.
1551 record_length = nspr_getv20recordsize(&hdr);
1554 ** Copy the header to the buffer and read the rest of the record..
1556 ws_buffer_assure_space(buf, record_length);
1557 pd = ws_buffer_start_ptr(buf);
1558 memcpy(pd, (void *)&hdr, hdrlen);
1559 if (record_length > hdrlen) {
1560 bytes_to_read = (unsigned int)(record_length - hdrlen);
1561 if (!wtap_read_bytes(wth->random_fh, pd + hdrlen, bytes_to_read,
1566 #define GENERATE_CASE_V30(phdr,type,acttype) \
1567 case NSPR_PDPKTRACEFULLTX_V##type:\
1568 case NSPR_PDPKTRACEFULLTXB_V##type:\
1569 case NSPR_PDPKTRACEFULLRX_V##type:\
1570 case NSPR_PDPKTRACEFULLNEWRX_V##type:\
1571 TRACE_V##type##_REC_LEN_OFF((phdr),v##type##_full,fp,pktracefull_v##type);\
1572 (phdr)->pseudo_header.nstr.rec_type = NSPR_HEADER_VERSION##acttype;\
1575 switch ((( nspr_hd_v20_t*)pd)->phd_RecordType)
1577 GENERATE_CASE_V30(phdr,30, 300);
1585 ** Netscaler trace format close routines.
1587 static void nstrace_close(wtap *wth)
1589 nstrace_t *nstrace = (nstrace_t *)wth->priv;
1591 g_free(nstrace->pnstrace_buf);
1596 guint16 page_offset;
1598 guint32 absrec_time;
1601 /* Returns 0 if we could write the specified encapsulation type,
1602 ** an error indication otherwise. */
1603 int nstrace_10_dump_can_write_encap(int encap)
1605 if (encap == WTAP_ENCAP_NSTRACE_1_0)
1608 return WTAP_ERR_UNSUPPORTED_ENCAP;
1612 /* Returns 0 if we could write the specified encapsulation type,
1613 ** an error indication otherwise. */
1614 int nstrace_20_dump_can_write_encap(int encap)
1616 if (encap == WTAP_ENCAP_NSTRACE_2_0)
1619 return WTAP_ERR_UNSUPPORTED_ENCAP;
1622 /* Returns 0 if we could write the specified encapsulation type,
1623 ** an error indication otherwise. */
1624 int nstrace_30_dump_can_write_encap(int encap)
1626 if (encap == WTAP_ENCAP_NSTRACE_3_0)
1629 return WTAP_ERR_UNSUPPORTED_ENCAP;
1632 /* Returns TRUE on success, FALSE on failure; sets "*err" to an error code on
1634 gboolean nstrace_dump_open(wtap_dumper *wdh, int *err _U_)
1636 nstrace_dump_t *nstrace;
1638 wdh->subtype_write = nstrace_dump;
1640 nstrace = (nstrace_dump_t *)g_malloc(sizeof(nstrace_dump_t));
1641 wdh->priv = (void *)nstrace;
1642 nstrace->page_offset = 0;
1643 nstrace->page_len = NSPR_PAGESIZE;
1644 nstrace->absrec_time = 0;
1650 static gboolean nstrace_add_signature(wtap_dumper *wdh, int *err)
1652 nstrace_dump_t *nstrace = (nstrace_dump_t *)wdh->priv;
1654 if (wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_1_0)
1657 nspr_signature_v10_t sig10;
1659 /* populate the record */
1660 val16b = GUINT16_TO_LE(NSPR_SIGNATURE_V10);
1661 memcpy(sig10.phd.ph_RecordType, &val16b, sizeof sig10.phd.ph_RecordType);
1662 val16b = GUINT16_TO_LE(nspr_signature_v10_s);
1663 memcpy(sig10.phd.ph_RecordSize, &val16b, sizeof sig10.phd.ph_RecordSize);
1664 memset(sig10.sig_Signature, 0, NSPR_SIGSIZE_V10);
1665 g_strlcpy(sig10.sig_Signature, NSPR_SIGSTR_V10, NSPR_SIGSIZE_V10);
1667 /* Write the record into the file */
1668 if (!wtap_dump_file_write(wdh, &sig10, nspr_signature_v10_s,
1672 /* Move forward the page offset */
1673 nstrace->page_offset += (guint16) nspr_signature_v10_s;
1675 } else if (wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_2_0)
1677 nspr_signature_v20_t sig20;
1679 sig20.sig_RecordType = NSPR_SIGNATURE_V20;
1680 sig20.sig_RecordSize = nspr_signature_v20_s;
1681 memcpy(sig20.sig_Signature, NSPR_SIGSTR_V20, sizeof(NSPR_SIGSTR_V20));
1683 /* Write the record into the file */
1684 if (!wtap_dump_file_write(wdh, &sig20, sig20.sig_RecordSize,
1688 /* Move forward the page offset */
1689 nstrace->page_offset += (guint16) sig20.sig_RecordSize;
1691 } else if (wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_3_0)
1693 nspr_signature_v30_t sig30;
1695 sig30.sig_RecordType = NSPR_SIGNATURE_V30;
1696 sig30.sig_RecordSize = nspr_signature_v30_s;
1697 memcpy(sig30.sig_Signature, NSPR_SIGSTR_V30, sizeof(NSPR_SIGSTR_V30));
1699 /* Write the record into the file */
1700 if (!wtap_dump_file_write(wdh, &sig30, sig30.sig_RecordSize,
1704 /* Move forward the page offset */
1705 nstrace->page_offset += (guint16) sig30.sig_RecordSize;
1708 g_assert_not_reached();
1717 nstrace_add_abstime(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
1718 const guint8 *pd, int *err)
1720 nstrace_dump_t *nstrace = (nstrace_dump_t *)wdh->priv;
1721 guint64 nsg_creltime;
1723 if (wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_1_0)
1728 nspr_abstime_v10_t abs10;
1730 /* populate the record */
1731 val16 = GUINT16_TO_LE(NSPR_ABSTIME_V10);
1732 memcpy(abs10.phd.ph_RecordType, &val16, sizeof abs10.phd.ph_RecordType);
1733 val16 = GUINT16_TO_LE(nspr_abstime_v10_s);
1734 memcpy(abs10.phd.ph_RecordSize, &val16, sizeof abs10.phd.ph_RecordSize);
1736 memcpy(&reltime, ((const nspr_pktracefull_v10_t *)pd)->fp_RelTimeHr, sizeof reltime);
1737 nsg_creltime = ns_hrtime2nsec(reltime);
1739 memset(abs10.abs_RelTime, 0, sizeof abs10.abs_RelTime);
1740 abstime = GUINT32_TO_LE((guint32)phdr->ts.secs - (guint32)(nsg_creltime/1000000000));
1741 memcpy(abs10.abs_Time, &abstime, sizeof abs10.abs_Time);
1743 /* Write the record into the file */
1744 if (!wtap_dump_file_write(wdh, &abs10, nspr_abstime_v10_s, err))
1747 /* Move forward the page offset */
1748 nstrace->page_offset += nspr_abstime_v10_s;
1750 } else if ((wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_2_0) ||
1751 (wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_3_0)) {
1754 nspr_abstime_v20_t abs20;
1756 abs20.abs_RecordType = NSPR_ABSTIME_V20;
1757 abs20.abs_RecordSize = nspr_abstime_v20_s;
1759 memcpy(&reltime, ((const nspr_pktracefull_v20_t *)pd)->fp_RelTimeHr, sizeof reltime);
1760 nsg_creltime = ns_hrtime2nsec(reltime);
1762 memset(abs20.abs_RelTime, 0, sizeof abs20.abs_RelTime);
1763 abstime = GUINT32_TO_LE((guint32)phdr->ts.secs - (guint32)(nsg_creltime/1000000000));
1764 memcpy(abs20.abs_RelTime, &abstime, sizeof abs20.abs_RelTime);
1766 /* Write the record into the file */
1767 if (!wtap_dump_file_write(wdh, &abs20, nspr_abstime_v20_s, err))
1770 /* Move forward the page offset */
1771 nstrace->page_offset += nspr_abstime_v20_s;
1775 g_assert_not_reached();
1783 /* Write a record for a packet to a dump file.
1784 Returns TRUE on success, FALSE on failure. */
1785 static gboolean nstrace_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
1786 const guint8 *pd, int *err)
1788 nstrace_dump_t *nstrace = (nstrace_dump_t *)wdh->priv;
1790 /* We can only write packet records. */
1791 if (phdr->rec_type != REC_TYPE_PACKET) {
1792 *err = WTAP_ERR_REC_TYPE_UNSUPPORTED;
1796 if (nstrace->page_offset == 0)
1798 /* Add the signature record and abs time record */
1799 if (wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_1_0)
1801 if (!nstrace_add_signature(wdh, err) ||
1802 !nstrace_add_abstime(wdh, phdr, pd, err))
1804 } else if (wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_2_0)
1806 if (!nstrace_add_signature(wdh, err) ||
1807 !nstrace_add_abstime(wdh, phdr, pd, err))
1809 } else if (wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_3_0)
1811 if (!nstrace_add_signature(wdh, err) ||
1812 !nstrace_add_abstime(wdh, phdr, pd, err))
1816 g_assert_not_reached();
1821 switch (phdr->pseudo_header.nstr.rec_type)
1823 case NSPR_HEADER_VERSION100:
1825 if (wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_1_0)
1827 if (nstrace->page_offset + phdr->caplen >= nstrace->page_len)
1829 /* Start on the next page */
1830 if (wtap_dump_file_seek(wdh, (nstrace->page_len - nstrace->page_offset), SEEK_CUR, err) == -1)
1833 nstrace->page_offset = 0;
1835 /* Possibly add signature and abstime records and increment offset */
1836 if (!nstrace_add_signature(wdh, err))
1840 /* Write the actual record as is */
1841 if (!wtap_dump_file_write(wdh, pd, phdr->caplen, err))
1844 nstrace->page_offset += (guint16) phdr->caplen;
1845 } else if (wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_2_0)
1847 *err = WTAP_ERR_UNSUPPORTED_FILE_TYPE;
1853 case NSPR_HEADER_VERSION200:
1854 case NSPR_HEADER_VERSION201:
1855 case NSPR_HEADER_VERSION202:
1856 case NSPR_HEADER_VERSION203:
1857 case NSPR_HEADER_VERSION204:
1858 case NSPR_HEADER_VERSION205:
1859 case NSPR_HEADER_VERSION206:
1860 if (wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_1_0)
1862 *err = WTAP_ERR_UNSUPPORTED_FILE_TYPE;
1864 } else if (wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_2_0)
1866 if (nstrace->page_offset + phdr->caplen >= nstrace->page_len)
1868 /* Start on the next page */
1869 if (wtap_dump_file_seek(wdh, (nstrace->page_len - nstrace->page_offset), SEEK_CUR, err) == -1)
1872 nstrace->page_offset = 0;
1874 /* Possibly add signature and abstime records and increment offset */
1875 if (!nstrace_add_signature(wdh, err))
1879 /* Write the actual record as is */
1880 if (!wtap_dump_file_write(wdh, pd, phdr->caplen, err))
1883 nstrace->page_offset += (guint16) phdr->caplen;
1888 case NSPR_HEADER_VERSION300:
1889 if (wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_1_0)
1891 *err = WTAP_ERR_UNSUPPORTED_FILE_TYPE;
1893 } else if (wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_2_0)
1895 *err = WTAP_ERR_UNSUPPORTED_FILE_TYPE;
1897 } else if (wdh->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NETSCALER_3_0)
1899 if (nstrace->page_offset + phdr->caplen >= nstrace->page_len)
1901 /* Start on the next page */
1902 if (wtap_dump_file_seek(wdh, (nstrace->page_len - nstrace->page_offset), SEEK_CUR, err) == -1)
1905 nstrace->page_offset = 0;
1907 /* Possibly add signature and abstime records and increment offset */
1908 if (!nstrace_add_signature(wdh, err))
1912 /* Write the actual record as is */
1913 if (!wtap_dump_file_write(wdh, pd, phdr->caplen, err))
1916 nstrace->page_offset += (guint16) phdr->caplen;
1919 g_assert_not_reached();
1925 g_assert_not_reached();