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"
40 #define NSPR_PAGESIZE 8192
42 /* The different record types
43 ** NOTE: The Record Type is two byte fields and unused space is recognized by
44 ** either bytes being zero, therefore no record should any byte value as
47 ** New Performance Record Type is only one byte.
49 #define NSPR_UNUSEDSPACE_V10 0x0000 /* rest of the page is unused */
50 #define NSPR_UNUSEDSPACE_V20 0x00 /* rest of the page is unused */
51 #define NSPR_SIGNATURE_V10 0x0101 /* signature */
52 #define NSPR_SIGNATURE_V20 0x01 /* signature */
53 #define NSPR_ABSTIME_V10 0x0107 /* data capture time in secs from 1970*/
54 #define NSPR_ABSTIME_V20 0x07 /* data capture time in secs from 1970*/
55 #define NSPR_RELTIME_V10 0x0108 /* relative time in ms from last time */
56 #define NSPR_RELTIME_V20 0x08 /* relative time in ms from last time */
57 #define NSPR_RELTIMEHR_V10 0x0109 /* high resolution relative time */
58 #define NSPR_RELTIMEHR_V20 0x09 /* high resolution relative time */
59 #define NSPR_SYSTARTIME_V10 0x010A /* system start time */
60 #define NSPR_SYSTARTIME_V20 0x0A /* system start time */
61 #define NSPR_RELTIME2B_V10 0x010B /* relative time in ms from last time */
62 #define NSPR_RELTIME2B_V20 0x0B /* relative time in ms from last time */
65 /* The high resolution relative time format.
66 ** The MS 2 bits of the high resoltion time is defined as follows:
67 ** 00 : time value is in second
68 ** 01 : time value is in mili second
69 ** 10 : time value is in micro second
70 ** 11 : time value is in nano second
72 #define NSPR_HRTIME_MASKTM 0x3FFFFFFF /* mask to get time value */
73 #define NSPR_HRTIME_MASKFMT 0xC0000000 /* time value format mask */
74 #define NSPR_HRTIME_SEC 0x00000000 /* time value in second */
75 #define NSPR_HRTIME_MSEC 0x40000000 /* time value in mili second */
76 #define NSPR_HRTIME_USEC 0x80000000 /* time value in micro second */
77 #define NSPR_HRTIME_NSEC 0xC0000000 /* time value in nano second */
80 typedef struct nspr_header_v10
82 guint8 ph_RecordType[2]; /* Record Type */
83 guint8 ph_RecordSize[2]; /* Record Size including header */
85 #define nspr_header_v10_s ((guint32)sizeof(nspr_header_v10_t))
87 /* This is V20 short header (2 bytes long) to be included where needed */
88 #define NSPR_HEADER_V20(prefix) \
89 guint8 prefix##_RecordType; /* Record Type */ \
90 guint8 prefix##_RecordSize /* Record Size including header */ \
91 /* end of declaration */
93 /* This is new long header (3 bytes long) to be included where needed */
94 #define NSPR_HEADER3B_V20(prefix) \
95 guint8 prefix##_RecordType; /* Record Type */ \
96 guint8 prefix##_RecordSizeLow; /* Record Size including header */ \
97 guint8 prefix##_RecordSizeHigh /* Record Size including header */ \
98 /* end of declaration */
99 #define NSPR_HEADER3B_V21 NSPR_HEADER3B_V20
100 #define NSPR_HEADER3B_V22 NSPR_HEADER3B_V20
102 typedef struct nspr_hd_v20
104 NSPR_HEADER3B_V20(phd); /* long performance header */
107 #define nspr_hd_v20_s ((guint32)sizeof(nspr_hd_v20_t))
111 ** How to know if header size is short or long?
112 ** The short header size can be 0-127 bytes long. If MS Bit of ph_RecordSize
113 ** is set then record size has 2 bytes
115 #define NSPR_V20RECORDSIZE_2BYTES 0x80
117 /* Performance Data Header with device number */
118 typedef struct nspr_headerdev_v10
120 guint8 ph_RecordType[2]; /* Record Type */
121 guint8 ph_RecordSize[2]; /* Record Size including header */
122 guint8 ph_DevNo[4]; /* Network Device (NIC/CONN) number */
123 } nspr_headerdev_v10_t;
124 #define nspr_headerdev_v10_s ((guint32)sizeof(nspr_headerdev_v10_t))
126 typedef struct nspr_hd_v10
128 nspr_header_v10_t phd; /* performance header */
130 #define nspr_hd_v10_s ((guint32)sizeof(nspr_hd_v10_t))
132 typedef struct nspr_hdev_v10
134 nspr_headerdev_v10_t phd; /* performance header */
136 #define nspr_hdev_v10_s ((guint32)sizeof(nspr_hdev_v10_t))
138 /* if structure has defined phd as first field, it can use following names */
139 #define nsprRecordType phd.ph_RecordType
140 #define nsprRecordSize phd.ph_RecordSize
141 #define nsprReserved phd.ph_Reserved
142 #define nsprRecordTypeOrg phd.ph_Reserved
143 #define nsprDevNo phd.ph_DevNo
145 /* NSPR_SIGNATURE_V10 structure */
146 #define NSPR_SIGSIZE_V10 56 /* signature value size in bytes */
147 typedef struct nspr_signature_v10
149 nspr_header_v10_t phd; /* performance header */
150 guint8 sig_EndianType; /* Endian Type for the data */
151 guint8 sig_Reserved0;
152 guint8 sig_Reserved1[2];
153 gchar sig_Signature[NSPR_SIGSIZE_V10]; /* Signature value */
154 } nspr_signature_v10_t;
155 #define nspr_signature_v10_s ((guint32)sizeof(nspr_signature_v10_t))
157 /* NSPR_SIGNATURE_V20 structure */
158 #define NSPR_SIGSIZE_V20 sizeof(NSPR_SIGSTR_V20) /* signature value size in bytes */
159 typedef struct nspr_signature_v20
161 NSPR_HEADER_V20(sig); /* short performance header */
162 guint8 sig_EndianType; /* Endian Type for the data */
163 gchar sig_Signature[NSPR_SIGSIZE_V20]; /* Signature value */
164 } nspr_signature_v20_t;
165 #define nspr_signature_v20_s ((guint32)sizeof(nspr_signature_v20_t))
167 /* NSPR_ABSTIME_V10 and NSPR_SYSTARTIME_V10 structure */
168 typedef struct nspr_abstime_v10
170 nspr_header_v10_t phd; /* performance header */
171 guint8 abs_RelTime[4]; /* relative time is ms from last time */
172 guint8 abs_Time[4]; /* absolute time in seconds from 1970 */
173 } nspr_abstime_v10_t;
174 #define nspr_abstime_v10_s ((guint32)sizeof(nspr_abstime_v10_t))
177 /* NSPR_ABSTIME_V20 and NSPR_SYSTARTIME_V20 structure */
178 typedef struct nspr_abstime_v20
180 NSPR_HEADER_V20(abs); /* short performance header */
181 guint8 abs_RelTime[2]; /* relative time is ms from last time */
182 guint8 abs_Time[4]; /* absolute time in seconds from 1970 */
183 } nspr_abstime_v20_t;
184 #define nspr_abstime_v20_s ((guint32)sizeof(nspr_abstime_v20_t))
188 /* full packet trace structure */
189 typedef struct nspr_pktracefull_v10
191 nspr_headerdev_v10_t phd; /* performance header */
192 guint8 fp_RelTimeHr[4]; /* High resolution relative time */
193 guint8 fp_Data[1]; /* packet data starts here */
194 } nspr_pktracefull_v10_t;
195 #define nspr_pktracefull_v10_s (nspr_hdev_v10_s + 4)
197 /* new full packet trace structure v20 */
198 typedef struct nspr_pktracefull_v20
200 NSPR_HEADER3B_V20(fp); /* long performance header */
201 guint8 fp_DevNo; /* Network Device (NIC) number */
202 guint8 fp_RelTimeHr[4]; /* High resolution relative time */
203 guint8 fp_Data[4]; /* packet data starts here */
204 } nspr_pktracefull_v20_t;
205 #define nspr_pktracefull_v20_s ((guint32)(sizeof(nspr_pktracefull_v20_t) - 4))
207 /* new full packet trace structure v21 */
208 typedef struct nspr_pktracefull_v21
210 NSPR_HEADER3B_V21(fp); /* long performance header */
211 guint8 fp_DevNo; /* Network Device (NIC) number */
212 guint8 fp_RelTimeHr[4]; /* High resolution relative time */
213 guint8 fp_PcbDevNo[4]; /* PCB devno */
214 guint8 fp_lPcbDevNo[4]; /* link PCB devno */
215 guint8 fp_Data[4]; /* packet data starts here */
216 } nspr_pktracefull_v21_t;
217 #define nspr_pktracefull_v21_s ((guint32)(sizeof(nspr_pktracefull_v21_t) - 4))
219 /* new full packet trace structure v22 */
220 typedef struct nspr_pktracefull_v22
222 NSPR_HEADER3B_V22(fp); /* long performance header */
223 guint8 fp_DevNo; /* Network Device (NIC) number */
224 guint8 fp_RelTimeHr[4]; /* High resolution relative time */
225 guint8 fp_PcbDevNo[4]; /* PCB devno */
226 guint8 fp_lPcbDevNo[4]; /* link PCB devno */
227 guint8 fp_VlanTag[2]; /* vlan tag */
228 guint8 fp_Data[2]; /* packet data starts here */
229 } nspr_pktracefull_v22_t;
230 #define nspr_pktracefull_v22_s ((guint32)(sizeof(nspr_pktracefull_v22_t) - 2))
232 typedef struct nspr_pktracefull_v23
234 NSPR_HEADER3B_V22(fp); /* long performance header */
235 guint8 fp_DevNo; /* Network Device (NIC) number */
236 guint8 fp_AbsTimeHr[8]; /* High resolution absolute time */
237 guint8 fp_PcbDevNo[4]; /* PCB devno */
238 guint8 fp_lPcbDevNo[4]; /* link PCB devno */
239 guint8 fp_VlanTag[2]; /* vlan tag */
240 guint8 fp_Coreid[2]; /* coreid of the packet */
241 guint8 fp_Data[2]; /* packet data starts here */
242 } nspr_pktracefull_v23_t;
243 #define nspr_pktracefull_v23_s ((guint32)(sizeof(nspr_pktracefull_v23_t) - 2))
245 /* New full packet trace structure v24 for cluster tracing */
246 typedef struct nspr_pktracefull_v24
248 NSPR_HEADER3B_V22(fp); /* long performance header */
249 guint8 fp_DevNo; /* Network Device (NIC) number */
250 guint8 fp_AbsTimeHr[8]; /* High resolution absolute time in nanosec */
251 guint8 fp_PcbDevNo[4]; /* PCB devno */
252 guint8 fp_lPcbDevNo[4]; /* link PCB devno */
253 guint8 fp_VlanTag[2]; /* vlan tag */
254 guint8 fp_Coreid[2]; /* coreid of the packet */
255 guint8 fp_srcNodeId[2]; /* source node # */
256 guint8 fp_destNodeId[2]; /* destination node # */
257 guint8 fp_clFlags; /* cluster flags */
258 guint8 fp_Data[2]; /* packet data starts here */
259 } nspr_pktracefull_v24_t;
260 #define nspr_pktracefull_v24_s ((guint32)(sizeof(nspr_pktracefull_v24_t) - 4))
262 /* New full packet trace structure v25 for vm info tracing */
263 typedef struct nspr_pktracefull_v25
265 NSPR_HEADER3B_V22(fp); /* long performance header */
266 guint8 fp_DevNo; /* Network Device (NIC) number */
267 guint8 fp_AbsTimeHr[8]; /* High resolution absolute time in nanosec */
268 guint8 fp_PcbDevNo[4]; /* PCB devno */
269 guint8 fp_lPcbDevNo[4]; /* link PCB devno */
270 guint8 fp_VlanTag[2]; /* vlan tag */
271 guint8 fp_Coreid[2]; /* coreid of the packet */
272 guint8 fp_srcNodeId[2]; /* source node # */
273 guint8 fp_destNodeId[2]; /* destination node # */
274 guint8 fp_clFlags; /* cluster flags */
275 guint8 fp_src_vmname_len; /* vm src info */
276 guint8 fp_dst_vmname_len; /* vm src info */
277 guint8 fp_Data[4]; /* packet data starts here */
278 } nspr_pktracefull_v25_t;
279 #define nspr_pktracefull_v25_s ((guint32)(sizeof(nspr_pktracefull_v25_t) - 4))
280 #define fp_src_vmname fp_Data
281 #define fp_src_vmname fp_Data
284 /* partial packet trace structure */
285 typedef struct nspr_pktracepart_v10
287 nspr_headerdev_v10_t phd; /* performance header */
288 guint8 pp_RelTimeHr[4]; /* High resolution relative time */
289 guint8 pp_PktSizeOrg[2]; /* Original packet size */
290 guint8 pp_PktOffset[2]; /* starting offset in packet */
291 guint8 pp_Data[1]; /* packet data starts here */
292 } nspr_pktracepart_v10_t;
293 #define nspr_pktracepart_v10_s (nspr_pktracefull_v10_s + 4)
295 /* new partial packet trace structure */
296 typedef struct nspr_pktracepart_v20
298 NSPR_HEADER3B_V20(pp); /* long performance header */
299 guint8 pp_DevNo; /* Network Device (NIC) number */
300 guint8 pp_RelTimeHr[4]; /* High resolution relative time */
301 guint8 pp_PktSizeOrg[2]; /* Original packet size */
302 guint8 pp_PktOffset[2]; /* starting offset in packet */
303 guint8 pp_Data[4]; /* packet data starts here */
304 } nspr_pktracepart_v20_t;
305 #define nspr_pktracepart_v20_s ((guint32)(sizeof(nspr_pktracepart_v20_t) -4))
307 /* new partial packet trace structure */
308 typedef struct nspr_pktracepart_v21
310 NSPR_HEADER3B_V21(pp); /* long performance header */
311 guint8 pp_DevNo; /* Network Device (NIC) number */
312 guint8 pp_RelTimeHr[4]; /* High resolution relative time */
313 guint8 pp_PktSizeOrg[2]; /* Original packet size */
314 guint8 pp_PktOffset[2]; /* starting offset in packet */
315 guint8 pp_PcbDevNo[4]; /* PCB devno */
316 guint8 pp_lPcbDevNo[4]; /* link PCB devno */
317 guint8 pp_Data[4]; /* packet data starts here */
318 } nspr_pktracepart_v21_t;
319 #define nspr_pktracepart_v21_s ((guint32)(sizeof(nspr_pktracepart_v21_t) -4))
321 /* new partial packet trace structure v22 */
322 typedef struct nspr_pktracepart_v22
324 NSPR_HEADER3B_V22(pp); /* long performance header */
325 guint8 pp_DevNo; /* Network Device (NIC) number */
326 guint8 pp_RelTimeHr[4]; /* High resolution relative time */
327 guint8 pp_PktSizeOrg[2]; /* Original packet size */
328 guint8 pp_PktOffset[2]; /* starting offset in packet */
329 guint8 pp_PcbDevNo[4]; /* PCB devno */
330 guint8 pp_lPcbDevNo[4]; /* link PCB devno */
331 guint8 pp_VlanTag[2]; /* Vlan Tag */
332 guint8 pp_Data[2]; /* packet data starts here */
333 } nspr_pktracepart_v22_t;
334 #define nspr_pktracepart_v22_s ((guint32)(sizeof(nspr_pktracepart_v22_t) -2))
336 typedef struct nspr_pktracepart_v23
338 NSPR_HEADER3B_V22(pp); /* long performance header */
339 guint8 pp_DevNo; /* Network Device (NIC) number */
340 guint8 pp_AbsTimeHr[8]; /* High resolution absolute time */
341 guint8 pp_PktSizeOrg[2]; /* Original packet size */
342 guint8 pp_PktOffset[2]; /* starting offset in packet */
343 guint8 pp_PcbDevNo[4]; /* PCB devno */
344 guint8 pp_lPcbDevNo[4]; /* link PCB devno */
345 guint8 pp_VlanTag[2]; /* vlan tag */
346 guint8 pp_Coreid[2]; /* Coreid of the packet */
347 guint8 pp_Data[4]; /* packet data starts here */
348 } nspr_pktracepart_v23_t;
349 #define nspr_pktracepart_v23_s ((guint32)(sizeof(nspr_pktracepart_v23_t) -4))
351 /* New partial packet trace structure v24 for cluster tracing */
352 typedef struct nspr_pktracepart_v24
354 NSPR_HEADER3B_V22(pp); /* long performance header */
355 guint8 pp_DevNo; /* Network Device (NIC) number */
356 guint8 pp_AbsTimeHr[8]; /*High resolution absolute time in nanosec*/
357 guint8 pp_PktSizeOrg[2]; /* Original packet size */
358 guint8 pp_PktOffset[2]; /* starting offset in packet */
359 guint8 pp_PcbDevNo[4]; /* PCB devno */
360 guint8 pp_lPcbDevNo[4]; /* link PCB devno */
361 guint8 pp_VlanTag[2]; /* vlan tag */
362 guint8 pp_Coreid[2]; /* Coreid of the packet */
363 guint8 pp_srcNodeId[2]; /* source node # */
364 guint8 pp_destNodeId[2]; /* destination node # */
365 guint8 pp_clFlags; /* cluster flags */
366 guint8 pp_Data[4]; /* packet data starts here */
367 } nspr_pktracepart_v24_t;
368 #define nspr_pktracepart_v24_s ((guint32)(sizeof(nspr_pktracepart_v24_t) -4))
370 /* New partial packet trace structure v25 for vm info tracing */
371 typedef struct nspr_pktracepart_v25
373 NSPR_HEADER3B_V22(pp); /* long performance header */
374 guint8 pp_DevNo; /* Network Device (NIC) number */
375 guint8 pp_AbsTimeHr[8]; /*High resolution absolute time in nanosec*/
376 guint8 pp_PktSizeOrg[2]; /* Original packet size */
377 guint8 pp_PktOffset[2]; /* starting offset in packet */
378 guint8 pp_PcbDevNo[4]; /* PCB devno */
379 guint8 pp_lPcbDevNo[4]; /* link PCB devno */
380 guint8 pp_VlanTag[2]; /* vlan tag */
381 guint8 pp_Coreid[2]; /* Coreid of the packet */
382 guint8 pp_srcNodeId[2]; /* source node # */
383 guint8 pp_destNodeId[2]; /* destination node # */
384 guint8 pp_clFlags; /* cluster flags */
385 guint8 pp_src_vmname_len; /* vm info */
386 guint8 pp_dst_vmname_len; /* vm info */
387 guint8 pp_Data[4]; /* packet data starts here */
388 } nspr_pktracepart_v25_t;
389 #define nspr_pktracepart_v25_s ((guint32)(sizeof(nspr_pktracepart_v25_t) -4))
390 #define pp_src_vmname pp_Data
391 #define pp_dst_vmname pp_Data
393 #define myoffsetof(type,fieldname) (&(((type*)0)->fieldname))
395 #define __TNO(phdr,enumprefix,structprefix,structname,hdrname,structfieldname) \
396 guint8 enumprefix##_##hdrname##_offset = (guint8)GPOINTER_TO_INT(myoffsetof(nspr_##structname##_t,structprefix##_##structfieldname));
398 #define __TNL(phdr,enumprefix,structprefix,structname,hdrname,structfieldname) \
399 guint8 enumprefix##_##hdrname##_len = (guint8)sizeof(((nspr_##structname##_t*)0)->structprefix##_##structfieldname);
401 #define __TNV1O(phdr,enumprefix,structprefix,structname,hdrname,structfieldname) \
402 guint8 enumprefix##_##hdrname##_offset = (guint8)GPOINTER_TO_INT(myoffsetof(nspr_##structname##_t,structfieldname));
404 #define __TNV1L(phdr,enumprefix,structprefix,structname,hdrname,structfieldname) \
405 guint8 enumprefix##_##hdrname##_len = (guint8)sizeof(((nspr_##structname##_t*)0)->structfieldname);
407 #define TRACE_V10_REC_LEN_OFF(phdr,enumprefix,structprefix,structname) \
408 __TNV1O(phdr,enumprefix,structprefix,structname,dir,phd.ph_RecordType)\
409 __TNV1L(phdr,enumprefix,structprefix,structname,dir,phd.ph_RecordType)\
410 __TNV1O(phdr,enumprefix,structprefix,structname,nicno,phd.ph_DevNo)\
411 __TNV1L(phdr,enumprefix,structprefix,structname,nicno,phd.ph_DevNo)\
412 __TNO(phdr,enumprefix,structprefix,structname,eth,Data)
414 #define TRACE_FULL_V10_REC_LEN_OFF(phdr,enumprefix,structprefix,structname) \
415 (phdr)->len = pletohs(&(fp)->nsprRecordSize);\
416 (phdr)->caplen = (phdr)->len;\
417 TRACE_V10_REC_LEN_OFF(phdr,enumprefix,structprefix,structname)
419 #define TRACE_PART_V10_REC_LEN_OFF(phdr,enumprefix,structprefix,structname) \
420 (phdr)->presence_flags |= WTAP_HAS_CAP_LEN;\
421 (phdr)->len = pletohs(&pp->pp_PktSizeOrg) + nspr_pktracepart_v10_s;\
422 (phdr)->caplen = pletohs(&pp->nsprRecordSize);\
423 TRACE_V10_REC_LEN_OFF(phdr,enumprefix,structprefix,structname)
425 #define TRACE_V20_REC_LEN_OFF(phdr,enumprefix,structprefix,structname) \
426 __TNO(phdr,enumprefix,structprefix,structname,dir,RecordType)\
427 __TNL(phdr,enumprefix,structprefix,structname,dir,RecordType)\
428 __TNO(phdr,enumprefix,structprefix,structname,nicno,DevNo)\
429 __TNL(phdr,enumprefix,structprefix,structname,nicno,DevNo)\
430 __TNO(phdr,enumprefix,structprefix,structname,eth,Data)
432 #define TRACE_V21_REC_LEN_OFF(phdr,enumprefix,structprefix,structname) \
433 TRACE_V20_REC_LEN_OFF(phdr,enumprefix,structprefix,structname)\
434 __TNO(phdr,enumprefix,structprefix,structname,pcb,PcbDevNo)\
435 __TNO(phdr,enumprefix,structprefix,structname,l_pcb,lPcbDevNo)
437 #define TRACE_V22_REC_LEN_OFF(phdr,enumprefix,structprefix,structname) \
438 TRACE_V21_REC_LEN_OFF(phdr,enumprefix,structprefix,structname)\
439 __TNO(phdr,enumprefix,structprefix,structname,vlantag,VlanTag)
441 #define TRACE_V23_REC_LEN_OFF(phdr,enumprefix,structprefix,structname) \
442 TRACE_V22_REC_LEN_OFF(phdr,enumprefix,structprefix,structname)\
443 __TNO(phdr,enumprefix,structprefix,structname,coreid,Coreid)
445 #define TRACE_V24_REC_LEN_OFF(phdr,enumprefix,structprefix,structname) \
446 TRACE_V23_REC_LEN_OFF(phdr,enumprefix,structprefix,structname)\
447 __TNO(phdr,enumprefix,structprefix,structname,srcnodeid,srcNodeId)\
448 __TNO(phdr,enumprefix,structprefix,structname,destnodeid,destNodeId)\
449 __TNO(phdr,enumprefix,structprefix,structname,clflags,clFlags)
451 #define TRACE_V25_REC_LEN_OFF(phdr,enumprefix,structprefix,structname) \
452 TRACE_V24_REC_LEN_OFF(phdr,enumprefix,structprefix,structname)\
453 __TNO(phdr,enumprefix,structprefix,structname,src_vmname_len,src_vmname_len)\
454 __TNO(phdr,enumprefix,structprefix,structname,dst_vmname_len,dst_vmname_len)\
455 __TNO(phdr,enumprefix,structprefix,structname,data,Data)
457 TRACE_V10_REC_LEN_OFF(NULL,v10_part,pp,pktracepart_v10)
458 TRACE_V10_REC_LEN_OFF(NULL,v10_full,fp,pktracefull_v10)
459 TRACE_V20_REC_LEN_OFF(NULL,v20_part,pp,pktracepart_v20)
460 TRACE_V20_REC_LEN_OFF(NULL,v20_full,fp,pktracefull_v20)
461 TRACE_V21_REC_LEN_OFF(NULL,v21_part,pp,pktracepart_v21)
462 TRACE_V21_REC_LEN_OFF(NULL,v21_full,fp,pktracefull_v21)
463 TRACE_V22_REC_LEN_OFF(NULL,v22_part,pp,pktracepart_v22)
464 TRACE_V22_REC_LEN_OFF(NULL,v22_full,fp,pktracefull_v22)
465 TRACE_V23_REC_LEN_OFF(NULL,v23_part,pp,pktracepart_v23)
466 TRACE_V23_REC_LEN_OFF(NULL,v23_full,fp,pktracefull_v23)
467 TRACE_V24_REC_LEN_OFF(NULL,v24_part,pp,pktracepart_v24)
468 TRACE_V24_REC_LEN_OFF(NULL,v24_full,fp,pktracefull_v24)
469 TRACE_V25_REC_LEN_OFF(NULL,v25_part,pp,pktracepart_v25)
470 TRACE_V25_REC_LEN_OFF(NULL,v25_full,fp,pktracefull_v25)
478 #define ns_setabstime(nstrace, AbsoluteTime, RelativeTimems) \
480 (nstrace)->nspm_curtime = AbsoluteTime; \
481 (nstrace)->nspm_curtimemsec += RelativeTimems; \
482 (nstrace)->nspm_curtimelastmsec = nstrace->nspm_curtimemsec; \
486 #define ns_setrelativetime(nstrace, RelativeTimems) \
489 (nstrace)->nspm_curtimemsec += RelativeTimems; \
490 rsec = (guint32)((nstrace)->nspm_curtimemsec - (nstrace)->nspm_curtimelastmsec)/1000; \
491 (nstrace)->nspm_curtime += rsec; \
492 (nstrace)->nspm_curtimelastmsec += rsec * 1000; \
499 gint32 nstrace_buf_offset;
500 gint32 nstrace_buflen;
501 /* Performance Monitor Time variables */
502 guint32 nspm_curtime; /* current time since 1970 */
503 guint64 nspm_curtimemsec; /* current time in milliseconds */
504 guint64 nspm_curtimelastmsec; /* nspm_curtime last update time in milliseconds */
505 guint64 nsg_creltime;
509 static guint32 nspm_signature_version(wtap*, gchar*, gint32);
510 static gboolean nstrace_read_v10(wtap *wth, int *err, gchar **err_info,
511 gint64 *data_offset);
512 static gboolean nstrace_read_v20(wtap *wth, int *err, gchar **err_info,
513 gint64 *data_offset);
514 static gboolean nstrace_seek_read_v10(wtap *wth, gint64 seek_off,
515 struct wtap_pkthdr *phdr,
516 guint8 *pd, int length,
517 int *err, gchar **err_info);
518 static gboolean nstrace_seek_read_v20(wtap *wth, gint64 seek_off,
519 struct wtap_pkthdr *phdr,
520 guint8 *pd, int length,
521 int *err, gchar **err_info);
522 static void nstrace_close(wtap *wth);
524 static gboolean nstrace_set_start_time_v10(wtap *wth);
525 static gboolean nstrace_set_start_time_v20(wtap *wth);
526 static gboolean nstrace_set_start_time(wtap *wth);
527 static guint64 ns_hrtime2nsec(guint32 tm);
529 static gboolean nstrace_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
530 const guint8 *pd, int *err);
533 #define GET_READ_PAGE_SIZE(remaining_file_size) ((gint32)((remaining_file_size>NSPR_PAGESIZE)?NSPR_PAGESIZE:remaining_file_size))
536 static guint64 ns_hrtime2nsec(guint32 tm)
538 guint32 val = tm & NSPR_HRTIME_MASKTM;
539 switch(tm & NSPR_HRTIME_MASKFMT)
541 case NSPR_HRTIME_SEC: return (guint64)val*1000000000;
542 case NSPR_HRTIME_MSEC: return (guint64)val*1000000;
543 case NSPR_HRTIME_USEC: return (guint64)val*1000;
544 case NSPR_HRTIME_NSEC: return val;
551 ** Netscaler trace format open routines
553 int nstrace_open(wtap *wth, int *err, gchar **err_info)
561 errno = WTAP_ERR_CANT_READ;
563 if ((file_size = wtap_file_size(wth, err)) == -1)
566 nstrace_buf = (gchar *)g_malloc(NSPR_PAGESIZE);
567 page_size = GET_READ_PAGE_SIZE(file_size);
569 switch ((wth->file_type = nspm_signature_version(wth, nstrace_buf, page_size)))
571 case WTAP_FILE_NETSCALER_1_0:
572 wth->file_encap = WTAP_ENCAP_NSTRACE_1_0;
575 case WTAP_FILE_NETSCALER_2_0:
576 wth->file_encap = WTAP_ENCAP_NSTRACE_2_0;
580 *err = WTAP_ERR_UNSUPPORTED;
581 *err_info = g_strdup_printf("nstrace: file type %d unsupported", wth->file_type);
586 if ((file_seek(wth->fh, 0, SEEK_SET, err)) == -1)
588 *err = file_error(wth->fh, err_info);
593 bytes_read = file_read(nstrace_buf, page_size, wth->fh);
594 if (bytes_read != page_size)
596 *err = file_error(wth->fh, err_info);
598 if (*err != 0 && *err != WTAP_ERR_SHORT_READ)
603 switch (wth->file_type)
605 case WTAP_FILE_NETSCALER_1_0:
606 wth->subtype_read = nstrace_read_v10;
607 wth->subtype_seek_read = nstrace_seek_read_v10;
610 case WTAP_FILE_NETSCALER_2_0:
611 wth->subtype_read = nstrace_read_v20;
612 wth->subtype_seek_read = nstrace_seek_read_v20;
615 wth->subtype_close = nstrace_close;
617 nstrace = (nstrace_t *)g_malloc(sizeof(nstrace_t));
618 wth->priv = (void *)nstrace;
619 nstrace->pnstrace_buf = nstrace_buf;
620 nstrace->xxx_offset = 0;
621 nstrace->nstrace_buflen = page_size;
622 nstrace->nstrace_buf_offset = 0;
623 nstrace->nspm_curtime = 0;
624 nstrace->nspm_curtimemsec = 0;
625 nstrace->nspm_curtimelastmsec = 0;
626 nstrace->nsg_creltime = 0;
627 nstrace->file_size = file_size;
630 /* Set the start time by looking for the abstime record */
631 if ((nstrace_set_start_time(wth)) == FALSE)
633 /* Reset the read pointer to start of the file. */
634 if ((file_seek(wth->fh, 0, SEEK_SET, err)) == -1)
636 *err = file_error(wth->fh, err_info);
637 g_free(nstrace->pnstrace_buf);
642 /* Read the first page of data */
643 bytes_read = file_read(nstrace_buf, page_size, wth->fh);
644 if (bytes_read != page_size)
646 *err = file_error(wth->fh, err_info);
647 g_free(nstrace->pnstrace_buf);
652 /* reset the buffer offset */
653 nstrace->nstrace_buf_offset = 0;
656 wth->tsprecision = WTAP_FILE_TSPREC_NSEC;
657 wth->phdr.ts.secs = nstrace->nspm_curtime;
658 wth->phdr.ts.nsecs = 0;
665 #define nspm_signature_func(ver) \
666 static guint32 nspm_signature_isv##ver(gchar *sigp) {\
667 return strncmp(sigp,NSPR_SIGSTR_V##ver,(sizeof(NSPR_SIGSTR_V##ver)-1));\
670 nspm_signature_func(10)
671 nspm_signature_func(20)
674 ** Check signature and return the version number of the signature.
675 ** If not found, it returns 0. At the time of return from this function
676 ** we might not be at the first page. So after a call to this function, there
677 ** has to be a file seek to return to the start of the first page.
680 nspm_signature_version(wtap *wth, gchar *nstrace_buf, gint32 len)
682 gchar *dp = nstrace_buf;
685 bytes_read = file_read(dp, len, wth->fh);
686 if (bytes_read == len) {
688 for ( ; len > (gint32)(MIN(sizeof(NSPR_SIGSTR_V10), sizeof(NSPR_SIGSTR_V20))); dp++, len--)
690 #define sigv10p ((nspr_signature_v10_t*)dp)
691 if ((pletohs(&sigv10p->nsprRecordType) == NSPR_SIGNATURE_V10) &&
692 (pletohs(&sigv10p->nsprRecordSize) <= len) &&
693 ((gint32)sizeof(NSPR_SIGSTR_V10) <= len) &&
694 (!nspm_signature_isv10(sigv10p->sig_Signature)))
695 return WTAP_FILE_NETSCALER_1_0;
698 #define sigv20p ((nspr_signature_v20_t*)dp)
699 if ((sigv20p->sig_RecordType == NSPR_SIGNATURE_V20) &&
700 (sigv20p->sig_RecordSize <= len) &&
701 ((gint32)sizeof(NSPR_SIGSTR_V20) <= len) &&
702 (!nspm_signature_isv20(sigv20p->sig_Signature)))
703 return WTAP_FILE_NETSCALER_2_0;
708 return 0; /* no version found */
711 #define nspr_getv10recordtype(hdp) (pletohs(&hdp->nsprRecordType))
712 #define nspr_getv10recordsize(hdp) (pletohs(&hdp->nsprRecordSize))
713 #define nspr_getv20recordtype(hdp) (hdp->phd_RecordType)
714 #define nspr_getv20recordsize(hdp) \
715 (((hdp)->phd_RecordSizeLow & NSPR_V20RECORDSIZE_2BYTES)? \
716 (((hdp)->phd_RecordSizeHigh * NSPR_V20RECORDSIZE_2BYTES)+ \
717 ((hdp)->phd_RecordSizeLow & ~NSPR_V20RECORDSIZE_2BYTES)) : \
718 (hdp)->phd_RecordSizeLow)
721 #define nstrace_set_start_time_ver(ver) \
722 gboolean nstrace_set_start_time_v##ver(wtap *wth) \
724 nstrace_t *nstrace = (nstrace_t *)wth->priv;\
725 gchar* nstrace_buf = nstrace->pnstrace_buf;\
726 gint32 nstrace_buf_offset = nstrace->nstrace_buf_offset;\
727 gint32 nstrace_buflen = nstrace->nstrace_buflen;\
731 while (nstrace_buf_offset < nstrace_buflen)\
733 nspr_hd_v##ver##_t *fp = (nspr_hd_v##ver##_t *) &nstrace_buf[nstrace_buf_offset];\
734 switch (nspr_getv##ver##recordtype(fp))\
736 case NSPR_ABSTIME_V##ver:\
737 ns_setabstime(nstrace, pletohl(&((nspr_abstime_v##ver##_t *) fp)->abs_Time), pletohs(&((nspr_abstime_v##ver##_t *) fp)->abs_RelTime));\
738 nstrace->nstrace_buf_offset = nstrace_buf_offset + nspr_getv##ver##recordsize(fp);\
739 nstrace->nstrace_buflen = nstrace_buflen;\
741 case NSPR_UNUSEDSPACE_V10:\
742 nstrace_buf_offset = nstrace_buflen;\
745 nstrace_buf_offset += nspr_getv##ver##recordsize(fp);\
748 nstrace_buf_offset = 0;\
749 nstrace->xxx_offset += nstrace_buflen;\
750 nstrace_buflen = GET_READ_PAGE_SIZE((nstrace->file_size - nstrace->xxx_offset));\
751 }while((nstrace_buflen > 0) && (bytes_read = file_read(nstrace_buf, nstrace_buflen, wth->fh)) && bytes_read == nstrace_buflen); \
755 nstrace_set_start_time_ver(10)
756 nstrace_set_start_time_ver(20)
758 #undef nspr_getv10recordtype
759 #undef nspr_getv20recordtype
760 #undef nspr_getv10recordsize
763 ** Set the start time of the trace file. We look for the first ABSTIME record. We use that
764 ** to set the start time. Apart from that we also make sure that we remember the position of
765 ** the next record after the ABSTIME record. Inorder to report correct time values, all trace
766 ** records before the ABSTIME record are ignored.
768 static gboolean nstrace_set_start_time(wtap *wth)
770 if (wth->file_type == WTAP_FILE_NETSCALER_1_0)
771 return nstrace_set_start_time_v10(wth);
772 else if (wth->file_type == WTAP_FILE_NETSCALER_2_0)
773 return nstrace_set_start_time_v20(wth);
778 #define __TNO(phdr,enumprefix,structprefix,structname,hdrname,structfieldname) \
779 (phdr)->pseudo_header.nstr.hdrname##_offset = enumprefix##_##hdrname##_offset;
781 #define __TNL(phdr,enumprefix,structprefix,structname,hdrname,structfieldname) \
782 (phdr)->pseudo_header.nstr.hdrname##_len = enumprefix##_##hdrname##_len;
784 #define __TNV1O(phdr,enumprefix,structprefix,structname,hdrname,structfieldname) \
785 __TNO(phdr,enumprefix,structprefix,structname,hdrname,structfieldname)
787 #define __TNV1L(phdr,enumprefix,structprefix,structname,hdrname,structfieldname) \
788 __TNL(phdr,enumprefix,structprefix,structname,hdrname,structfieldname)
793 ** Netscaler trace format read routines.
795 static gboolean nstrace_read_v10(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
797 nstrace_t *nstrace = (nstrace_t *)wth->priv;
798 guint64 nsg_creltime = nstrace->nsg_creltime;
799 gchar *nstrace_buf = nstrace->pnstrace_buf;
800 gint32 nstrace_buf_offset = nstrace->nstrace_buf_offset;
801 gint32 nstrace_buflen = nstrace->nstrace_buflen;
802 nspr_pktracefull_v10_t *fp;
803 nspr_pktracepart_v10_t *pp;
810 while ((nstrace_buf_offset < nstrace_buflen) &&
811 ((nstrace_buflen - nstrace_buf_offset) >= ((gint32)sizeof(fp->nsprRecordType))))
814 #define GENERATE_CASE_FULL(phdr,type,acttype) \
815 case NSPR_PDPKTRACEFULLTX_V##type:\
816 case NSPR_PDPKTRACEFULLTXB_V##type:\
817 case NSPR_PDPKTRACEFULLRX_V##type:\
818 fp = (nspr_pktracefull_v10_t *) &nstrace_buf[nstrace_buf_offset];\
820 * XXX - we can't do this in the seek-read routine,\
821 * as the time stamps in the records are relative to\
822 * the previous packet.\
824 (phdr)->presence_flags = WTAP_HAS_TS;\
825 nsg_creltime += ns_hrtime2nsec(pletohl(&fp->fp_RelTimeHr));\
826 (phdr)->ts.secs = nstrace->nspm_curtime + (guint32) (nsg_creltime / 1000000000);\
827 (phdr)->ts.nsecs = (guint32) (nsg_creltime % 1000000000);\
828 TRACE_FULL_V##type##_REC_LEN_OFF(phdr,v##type##_full,fp,pktracefull_v##type);\
829 buffer_assure_space(wth->frame_buffer, (phdr)->caplen);\
830 memcpy(buffer_start_ptr(wth->frame_buffer), fp, (phdr)->caplen);\
831 *data_offset = nstrace->xxx_offset + nstrace_buf_offset;\
832 nstrace->nstrace_buf_offset = nstrace_buf_offset + (phdr)->len;\
833 nstrace->nstrace_buflen = nstrace_buflen;\
834 nstrace->nsg_creltime = nsg_creltime;\
837 #define GENERATE_CASE_PART(phdr,type,acttype) \
838 case NSPR_PDPKTRACEPARTTX_V##type:\
839 case NSPR_PDPKTRACEPARTTXB_V##type:\
840 case NSPR_PDPKTRACEPARTRX_V##type:\
841 pp = (nspr_pktracepart_v10_t *) &nstrace_buf[nstrace_buf_offset];\
843 * XXX - we can't do this in the seek-read routine,\
844 * as the time stamps in the records are relative to\
845 * the previous packet.\
847 (phdr)->presence_flags = WTAP_HAS_TS;\
848 nsg_creltime += ns_hrtime2nsec(pletohl(&pp->pp_RelTimeHr));\
849 (phdr)->ts.secs = nstrace->nspm_curtime + (guint32) (nsg_creltime / 1000000000);\
850 (phdr)->ts.nsecs = (guint32) (nsg_creltime % 1000000000);\
851 TRACE_PART_V##type##_REC_LEN_OFF(phdr,v##type##_part,pp,pktracepart_v##type);\
852 buffer_assure_space(wth->frame_buffer, (phdr)->caplen);\
853 memcpy(buffer_start_ptr(wth->frame_buffer), pp, (phdr)->caplen);\
854 *data_offset = nstrace->xxx_offset + nstrace_buf_offset;\
855 nstrace->nstrace_buf_offset = nstrace_buf_offset + (phdr)->caplen;\
856 nstrace->nsg_creltime = nsg_creltime;\
857 nstrace->nstrace_buflen = nstrace_buflen;\
860 switch (pletohs(&(( nspr_header_v10_t*)&nstrace_buf[nstrace_buf_offset])->ph_RecordType))
862 GENERATE_CASE_FULL(&wth->phdr,10,100)
863 GENERATE_CASE_PART(&wth->phdr,10,100)
865 #undef GENERATE_CASE_FULL
866 #undef GENERATE_CASE_PART
868 case NSPR_ABSTIME_V10:
870 fp = (nspr_pktracefull_v10_t *) &nstrace_buf[nstrace_buf_offset];
871 ns_setabstime(nstrace, pletohl(((nspr_abstime_v10_t *) fp)->abs_Time), pletohl(&((nspr_abstime_v10_t *) fp)->abs_RelTime));
872 nstrace_buf_offset += pletohs(&fp->nsprRecordSize);
875 case NSPR_RELTIME_V10:
877 fp = (nspr_pktracefull_v10_t *) &nstrace_buf[nstrace_buf_offset];
878 ns_setrelativetime(nstrace, pletohl(((nspr_abstime_v10_t *) fp)->abs_RelTime));
879 nstrace_buf_offset += pletohs(&fp->nsprRecordSize);
882 case NSPR_UNUSEDSPACE_V10:
884 nstrace_buf_offset = nstrace_buflen;
889 fp = (nspr_pktracefull_v10_t *) &nstrace_buf[nstrace_buf_offset];
890 nstrace_buf_offset += pletohs(&fp->nsprRecordSize);
895 nstrace_buf_offset = 0;
896 nstrace->xxx_offset += nstrace_buflen;
897 nstrace_buflen = GET_READ_PAGE_SIZE((nstrace->file_size - nstrace->xxx_offset));
898 }while((nstrace_buflen > 0) && (bytes_read = file_read(nstrace_buf, nstrace_buflen, wth->fh)) && (bytes_read == nstrace_buflen));
903 #define TIMEDEFV20(fp,type) \
905 wth->phdr.presence_flags |= WTAP_HAS_TS;\
906 nsg_creltime += ns_hrtime2nsec(pletohl(fp->type##_RelTimeHr));\
907 wth->phdr.ts.secs = nstrace->nspm_curtime + (guint32) (nsg_creltime / 1000000000);\
908 wth->phdr.ts.nsecs = (guint32) (nsg_creltime % 1000000000);\
911 #define TIMEDEFV23(fp,type) \
913 wth->phdr.presence_flags |= WTAP_HAS_TS;\
914 /* access _AbsTimeHr as a 64bit value */\
915 nsg_creltime = pletohll(fp->type##_AbsTimeHr);\
916 wth->phdr.ts.secs = (guint32) (nsg_creltime / 1000000000);\
917 wth->phdr.ts.nsecs = (guint32) (nsg_creltime % 1000000000);\
920 #define TIMEDEFV21(fp,type) TIMEDEFV20(fp,type)
921 #define TIMEDEFV22(fp,type) TIMEDEFV20(fp,type)
922 #define TIMEDEFV24(fp,type) TIMEDEFV23(fp,type)
923 #define TIMEDEFV25(fp,type) TIMEDEFV24(fp,type)
924 #define PPSIZEDEFV20(phdr,pp,ver) \
926 (phdr)->presence_flags |= WTAP_HAS_CAP_LEN;\
927 (phdr)->len = pletohs(&pp->pp_PktSizeOrg) + nspr_pktracepart_v##ver##_s;\
928 (phdr)->caplen = nspr_getv20recordsize((nspr_hd_v20_t *)pp);\
931 #define PPSIZEDEFV21(phdr,pp,ver) PPSIZEDEFV20(phdr,pp,ver)
932 #define PPSIZEDEFV22(phdr,pp,ver) PPSIZEDEFV20(phdr,pp,ver)
933 #define PPSIZEDEFV23(phdr,pp,ver) PPSIZEDEFV20(phdr,pp,ver)
934 #define PPSIZEDEFV24(phdr,pp,ver) PPSIZEDEFV20(phdr,pp,ver)
935 #define PPSIZEDEFV25(phdr,pp,ver) PPSIZEDEFV20(phdr,pp,ver)
937 #define FPSIZEDEFV20(phdr,fp,ver)\
939 (phdr)->len = nspr_getv20recordsize((nspr_hd_v20_t *)fp);\
940 (phdr)->caplen = (phdr)->len;\
943 #define FPSIZEDEFV21(phdr,fp,ver) FPSIZEDEFV20(phdr,fp,ver)
944 #define FPSIZEDEFV22(phdr,fp,ver) FPSIZEDEFV20(phdr,fp,ver)
945 #define FPSIZEDEFV23(phdr,fp,ver) FPSIZEDEFV20(phdr,fp,ver)
946 #define FPSIZEDEFV24(phdr,fp,ver) FPSIZEDEFV20(phdr,fp,ver)
947 #define FPSIZEDEFV25(phdr,fp,ver) FPSIZEDEFV20(phdr,fp,ver)
949 #define PACKET_DESCRIBE(phdr,FPTIMEDEF,SIZEDEF,ver,enumprefix,type,structname,TYPE)\
951 nspr_##structname##_t *fp= (nspr_##structname##_t*)&nstrace_buf[nstrace_buf_offset];\
952 TIMEDEFV##ver(fp,type);\
953 SIZEDEF##ver((phdr),fp,ver);\
954 TRACE_V##ver##_REC_LEN_OFF((phdr),enumprefix,type,structname);\
955 (phdr)->pseudo_header.nstr.rec_type = NSPR_HEADER_VERSION##TYPE;\
956 buffer_assure_space(wth->frame_buffer, (phdr)->caplen);\
957 memcpy(buffer_start_ptr(wth->frame_buffer), fp, (phdr)->caplen);\
958 *data_offset = nstrace->xxx_offset + nstrace_buf_offset;\
959 nstrace->nstrace_buf_offset = nstrace_buf_offset + nspr_getv20recordsize((nspr_hd_v20_t *)fp);\
960 nstrace->nstrace_buflen = nstrace_buflen;\
961 nstrace->nsg_creltime = nsg_creltime;\
965 static gboolean nstrace_read_v20(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
967 nstrace_t *nstrace = (nstrace_t *)wth->priv;
968 guint64 nsg_creltime = nstrace->nsg_creltime;
969 gchar *nstrace_buf = nstrace->pnstrace_buf;
970 gint32 nstrace_buf_offset = nstrace->nstrace_buf_offset;
971 gint32 nstrace_buflen = nstrace->nstrace_buflen;
978 while ((nstrace_buf_offset < nstrace_buflen) &&
979 ((nstrace_buflen - nstrace_buf_offset) >= ((gint32)sizeof((( nspr_hd_v20_t*)&nstrace_buf[nstrace_buf_offset])->phd_RecordType))))
981 switch ((( nspr_hd_v20_t*)&nstrace_buf[nstrace_buf_offset])->phd_RecordType)
984 #define GENERATE_CASE_FULL(phdr,type,acttype) \
985 case NSPR_PDPKTRACEFULLTX_V##type:\
986 case NSPR_PDPKTRACEFULLTXB_V##type:\
987 case NSPR_PDPKTRACEFULLRX_V##type:\
988 PACKET_DESCRIBE(phdr,TIMEDEF,FPSIZEDEFV,type,v##type##_full,fp,pktracefull_v##type,acttype);
990 #define GENERATE_CASE_FULL_V25(phdr,type,acttype) \
991 case NSPR_PDPKTRACEFULLTX_V##type:\
992 case NSPR_PDPKTRACEFULLTXB_V##type:\
993 case NSPR_PDPKTRACEFULLRX_V##type:\
994 case NSPR_PDPKTRACEFULLNEWRX_V##type:\
995 PACKET_DESCRIBE(phdr,TIMEDEF,FPSIZEDEFV,type,v##type##_full,fp,pktracefull_v##type,acttype);
997 #define GENERATE_CASE_PART(phdr,type,acttype) \
998 case NSPR_PDPKTRACEPARTTX_V##type:\
999 case NSPR_PDPKTRACEPARTTXB_V##type:\
1000 case NSPR_PDPKTRACEPARTRX_V##type:\
1001 PACKET_DESCRIBE(phdr,TIMEDEF,PPSIZEDEFV,type,v##type##_part,pp,pktracepart_v##type,acttype);
1003 #define GENERATE_CASE_PART_V25(phdr,type,acttype) \
1004 case NSPR_PDPKTRACEPARTTX_V##type:\
1005 case NSPR_PDPKTRACEPARTTXB_V##type:\
1006 case NSPR_PDPKTRACEPARTRX_V##type:\
1007 case NSPR_PDPKTRACEPARTNEWRX_V##type:\
1008 PACKET_DESCRIBE(phdr,TIMEDEF,PPSIZEDEFV,type,v##type##_part,pp,pktracepart_v##type,acttype);
1010 GENERATE_CASE_FULL(&wth->phdr,20,200);
1011 GENERATE_CASE_PART(&wth->phdr,20,200);
1012 GENERATE_CASE_FULL(&wth->phdr,21,201);
1013 GENERATE_CASE_PART(&wth->phdr,21,201);
1014 GENERATE_CASE_FULL(&wth->phdr,22,202);
1015 GENERATE_CASE_PART(&wth->phdr,22,202);
1016 GENERATE_CASE_FULL(&wth->phdr,23,203);
1017 GENERATE_CASE_PART(&wth->phdr,23,203);
1018 GENERATE_CASE_FULL_V25(&wth->phdr,24,204);
1019 GENERATE_CASE_PART_V25(&wth->phdr,24,204);
1020 GENERATE_CASE_FULL_V25(&wth->phdr,25,205);
1021 GENERATE_CASE_PART_V25(&wth->phdr,25,205);
1023 #undef GENERATE_CASE_FULL
1024 #undef GENERATE_CASE_FULL_V25
1025 #undef GENERATE_CASE_PART
1026 #undef GENERATE_CASE_PART_V25
1028 case NSPR_ABSTIME_V20:
1030 nspr_pktracefull_v20_t *fp20 = (nspr_pktracefull_v20_t *) &nstrace_buf[nstrace_buf_offset];
1031 nstrace_buf_offset += nspr_getv20recordsize((nspr_hd_v20_t *)fp20);
1032 ns_setabstime(nstrace, pletohl(&((nspr_abstime_v20_t *) fp20)->abs_Time), pletohs(&((nspr_abstime_v20_t *) fp20)->abs_RelTime));
1036 case NSPR_RELTIME_V20:
1038 nspr_pktracefull_v20_t *fp20 = (nspr_pktracefull_v20_t *) &nstrace_buf[nstrace_buf_offset];
1039 ns_setrelativetime(nstrace, pletohs(&((nspr_abstime_v20_t *) fp20)->abs_RelTime));
1040 nstrace_buf_offset += nspr_getv20recordsize((nspr_hd_v20_t *)fp20);
1044 case NSPR_UNUSEDSPACE_V20:
1046 if (nstrace_buf_offset >= NSPR_PAGESIZE/2)
1047 nstrace_buf_offset = nstrace_buflen;
1049 nstrace_buf_offset = NSPR_PAGESIZE/2;
1055 nspr_pktracefull_v20_t *fp20 = (nspr_pktracefull_v20_t *) &nstrace_buf[nstrace_buf_offset];
1056 nstrace_buf_offset += nspr_getv20recordsize((nspr_hd_v20_t *)fp20);
1062 nstrace_buf_offset = 0;
1063 nstrace->xxx_offset += nstrace_buflen;
1064 nstrace_buflen = GET_READ_PAGE_SIZE((nstrace->file_size - nstrace->xxx_offset));
1065 }while((nstrace_buflen > 0) && (bytes_read = file_read(nstrace_buf, nstrace_buflen, wth->fh)) && (bytes_read == nstrace_buflen));
1070 #undef PACKET_DESCRIBE
1072 static gboolean nstrace_seek_read_v10(wtap *wth, gint64 seek_off,
1073 struct wtap_pkthdr *phdr, guint8 *pd, int length,
1074 int *err, gchar **err_info)
1077 nspr_pktracefull_v10_t *fp;
1078 nspr_pktracepart_v10_t *pp;
1082 if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
1086 ** Read the packet data.
1088 bytes_read = file_read(pd, length, wth->random_fh);
1089 if (bytes_read != length) {
1090 *err = file_error(wth->random_fh, err_info);
1092 *err = WTAP_ERR_SHORT_READ;
1096 #define GENERATE_CASE_FULL(phdr,type,acttype) \
1097 case NSPR_PDPKTRACEFULLTX_V##type:\
1098 case NSPR_PDPKTRACEFULLTXB_V##type:\
1099 case NSPR_PDPKTRACEFULLRX_V##type:\
1100 fp = (nspr_pktracefull_v10_t *) pd;\
1101 TRACE_FULL_V##type##_REC_LEN_OFF(phdr,v##type##_full,fp,pktracefull_v##type);\
1102 (phdr)->pseudo_header.nstr.rec_type = NSPR_HEADER_VERSION##acttype;\
1105 #define GENERATE_CASE_PART(phdr,type,acttype) \
1106 case NSPR_PDPKTRACEPARTTX_V##type:\
1107 case NSPR_PDPKTRACEPARTTXB_V##type:\
1108 case NSPR_PDPKTRACEPARTRX_V##type:\
1109 pp = (nspr_pktracepart_v10_t *) pd;\
1110 TRACE_PART_V##type##_REC_LEN_OFF(phdr,v##type##_part,pp,pktracepart_v##type);\
1111 (phdr)->pseudo_header.nstr.rec_type = NSPR_HEADER_VERSION##acttype;\
1114 switch (pletohs(&(( nspr_header_v10_t*)pd)->ph_RecordType))
1116 GENERATE_CASE_FULL(phdr,10,100)
1117 GENERATE_CASE_PART(phdr,10,100)
1120 #undef GENERATE_CASE_FULL
1121 #undef GENERATE_CASE_PART
1126 #define PACKET_DESCRIBE(phdr,FPTIMEDEF,SIZEDEF,ver,enumprefix,type,structname,TYPE)\
1128 nspr_##structname##_t *fp= (nspr_##structname##_t*)pd;\
1129 SIZEDEF##ver((phdr),fp,ver);\
1130 TRACE_V##ver##_REC_LEN_OFF((phdr),enumprefix,type,structname);\
1131 (phdr)->pseudo_header.nstr.rec_type = NSPR_HEADER_VERSION##TYPE;\
1135 static gboolean nstrace_seek_read_v20(wtap *wth, gint64 seek_off,
1136 struct wtap_pkthdr *phdr, guint8 *pd, int length,
1137 int *err, gchar **err_info)
1143 if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
1147 ** Read the packet data.
1149 bytes_read = file_read(pd, length, wth->random_fh);
1150 if (bytes_read != length) {
1151 *err = file_error(wth->random_fh, err_info);
1153 *err = WTAP_ERR_SHORT_READ;
1157 #define GENERATE_CASE_FULL(phdr,type,acttype) \
1158 case NSPR_PDPKTRACEFULLTX_V##type:\
1159 case NSPR_PDPKTRACEFULLTXB_V##type:\
1160 case NSPR_PDPKTRACEFULLRX_V##type:\
1161 PACKET_DESCRIBE(phdr,TIMEDEF,FPSIZEDEFV,type,v##type##_full,fp,pktracefull_v##type,acttype);
1163 #define GENERATE_CASE_FULL_V25(phdr,type,acttype) \
1164 case NSPR_PDPKTRACEFULLTX_V##type:\
1165 case NSPR_PDPKTRACEFULLTXB_V##type:\
1166 case NSPR_PDPKTRACEFULLRX_V##type:\
1167 case NSPR_PDPKTRACEFULLNEWRX_V##type:\
1168 PACKET_DESCRIBE(phdr,TIMEDEF,FPSIZEDEFV,type,v##type##_full,fp,pktracefull_v##type,acttype);
1170 #define GENERATE_CASE_PART(phdr,type,acttype) \
1171 case NSPR_PDPKTRACEPARTTX_V##type:\
1172 case NSPR_PDPKTRACEPARTTXB_V##type:\
1173 case NSPR_PDPKTRACEPARTRX_V##type:\
1174 PACKET_DESCRIBE(phdr,TIMEDEF,PPSIZEDEFV,type,v##type##_part,pp,pktracepart_v##type,acttype);
1176 #define GENERATE_CASE_PART_V25(phdr,type,acttype) \
1177 case NSPR_PDPKTRACEPARTTX_V##type:\
1178 case NSPR_PDPKTRACEPARTTXB_V##type:\
1179 case NSPR_PDPKTRACEPARTRX_V##type:\
1180 case NSPR_PDPKTRACEPARTNEWRX_V##type:\
1181 PACKET_DESCRIBE(phdr,TIMEDEF,PPSIZEDEFV,type,v##type##_part,pp,pktracepart_v##type,acttype);
1183 switch ((( nspr_hd_v20_t*)pd)->phd_RecordType)
1185 GENERATE_CASE_FULL(phdr,20,200)
1186 GENERATE_CASE_PART(phdr,20,200)
1187 GENERATE_CASE_FULL(phdr,21,201)
1188 GENERATE_CASE_PART(phdr,21,201)
1189 GENERATE_CASE_FULL(phdr,22,202)
1190 GENERATE_CASE_PART(phdr,22,202)
1191 GENERATE_CASE_FULL(phdr,23,203)
1192 GENERATE_CASE_PART(phdr,23,203)
1193 GENERATE_CASE_FULL_V25(phdr,24,204)
1194 GENERATE_CASE_PART_V25(phdr,24,204)
1195 GENERATE_CASE_FULL_V25(phdr,25,205)
1196 GENERATE_CASE_PART_V25(phdr,25,205)
1199 #undef GENERATE_CASE_FULL
1200 #undef GENERATE_CASE_FULL_V25
1201 #undef GENERATE_CASE_PART
1202 #undef GENERATE_CASE_PART_V25
1208 ** Netscaler trace format close routines.
1210 static void nstrace_close(wtap *wth)
1212 nstrace_t *nstrace = (nstrace_t *)wth->priv;
1214 g_free(nstrace->pnstrace_buf);
1219 guint16 page_offset;
1221 guint32 absrec_time;
1224 /* Returns 0 if we could write the specified encapsulation type,
1225 ** an error indication otherwise. */
1226 int nstrace_10_dump_can_write_encap(int encap)
1228 if (encap == WTAP_ENCAP_NSTRACE_1_0)
1231 return WTAP_ERR_UNSUPPORTED_ENCAP;
1235 /* Returns 0 if we could write the specified encapsulation type,
1236 ** an error indication otherwise. */
1237 int nstrace_20_dump_can_write_encap(int encap)
1239 if (encap == WTAP_ENCAP_NSTRACE_2_0)
1242 return WTAP_ERR_UNSUPPORTED_ENCAP;
1246 /* Returns TRUE on success, FALSE on failure; sets "*err" to an error code on
1248 gboolean nstrace_dump_open(wtap_dumper *wdh, int *err _U_)
1250 nstrace_dump_t *nstrace;
1252 wdh->subtype_write = nstrace_dump;
1254 nstrace = (nstrace_dump_t *)g_malloc(sizeof(nstrace_dump_t));
1255 wdh->priv = (void *)nstrace;
1256 nstrace->page_offset = 0;
1257 nstrace->page_len = NSPR_PAGESIZE;
1258 nstrace->absrec_time = 0;
1264 static gboolean nstrace_add_signature(wtap_dumper *wdh, int *err)
1266 nstrace_dump_t *nstrace = (nstrace_dump_t *)wdh->priv;
1268 if (wdh->file_type == WTAP_FILE_NETSCALER_1_0)
1271 nspr_signature_v10_t sig10;
1273 /* populate the record */
1274 val16b = htoles(NSPR_SIGNATURE_V10);
1275 memcpy(sig10.phd.ph_RecordType, &val16b, sizeof sig10.phd.ph_RecordType);
1276 val16b = htoles(nspr_signature_v10_s);
1277 memcpy(sig10.phd.ph_RecordSize, &val16b, sizeof sig10.phd.ph_RecordSize);
1278 memset(sig10.sig_Signature, 0, NSPR_SIGSIZE_V10);
1279 g_strlcpy(sig10.sig_Signature, NSPR_SIGSTR_V10, NSPR_SIGSIZE_V10);
1281 /* Write the record into the file */
1282 if (!wtap_dump_file_write(wdh, &sig10, nspr_signature_v10_s,
1286 /* Move forward the page offset */
1287 nstrace->page_offset += (guint16) nspr_signature_v10_s;
1289 } else if (wdh->file_type == WTAP_FILE_NETSCALER_2_0)
1291 nspr_signature_v20_t sig20;
1293 sig20.sig_RecordType = NSPR_SIGNATURE_V20;
1294 sig20.sig_RecordSize = nspr_signature_v20_s;
1295 memcpy(sig20.sig_Signature, NSPR_SIGSTR_V20, sizeof(NSPR_SIGSTR_V20));
1297 /* Write the record into the file */
1298 if (!wtap_dump_file_write(wdh, &sig20, sig20.sig_RecordSize,
1302 /* Move forward the page offset */
1303 nstrace->page_offset += (guint16) sig20.sig_RecordSize;
1307 g_assert_not_reached();
1316 nstrace_add_abstime(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
1317 const guint8 *pd, int *err)
1319 nstrace_dump_t *nstrace = (nstrace_dump_t *)wdh->priv;
1320 guint64 nsg_creltime;
1322 if (wdh->file_type == WTAP_FILE_NETSCALER_1_0)
1327 nspr_abstime_v10_t abs10;
1329 /* populate the record */
1330 val16 = htoles(NSPR_ABSTIME_V10);
1331 memcpy(abs10.phd.ph_RecordType, &val16, sizeof abs10.phd.ph_RecordType);
1332 val16 = htoles(nspr_abstime_v10_s);
1333 memcpy(abs10.phd.ph_RecordSize, &val16, sizeof abs10.phd.ph_RecordSize);
1335 memcpy(&reltime, ((const nspr_pktracefull_v10_t *)pd)->fp_RelTimeHr, sizeof reltime);
1336 nsg_creltime = ns_hrtime2nsec(reltime);
1338 memset(abs10.abs_RelTime, 0, sizeof abs10.abs_RelTime);
1339 abstime = htolel((guint32)phdr->ts.secs - (guint32)(nsg_creltime/1000000000));
1340 memcpy(abs10.abs_Time, &abstime, sizeof abs10.abs_Time);
1342 /* Write the record into the file */
1343 if (!wtap_dump_file_write(wdh, &abs10, nspr_abstime_v10_s, err))
1346 /* Move forward the page offset */
1347 nstrace->page_offset += nspr_abstime_v10_s;
1349 } else if (wdh->file_type == WTAP_FILE_NETSCALER_2_0)
1353 nspr_abstime_v20_t abs20;
1355 abs20.abs_RecordType = NSPR_ABSTIME_V20;
1356 abs20.abs_RecordSize = nspr_abstime_v20_s;
1358 memcpy(&reltime, ((const nspr_pktracefull_v20_t *)pd)->fp_RelTimeHr, sizeof reltime);
1359 nsg_creltime = ns_hrtime2nsec(reltime);
1361 memset(abs20.abs_RelTime, 0, sizeof abs20.abs_RelTime);
1362 abstime = htolel((guint32)phdr->ts.secs - (guint32)(nsg_creltime/1000000000));
1363 memcpy(abs20.abs_RelTime, &abstime, sizeof abs20.abs_RelTime);
1365 /* Write the record into the file */
1366 if (!wtap_dump_file_write(wdh, &abs20, nspr_abstime_v20_s, err))
1369 /* Move forward the page offset */
1370 nstrace->page_offset += nspr_abstime_v20_s;
1374 g_assert_not_reached();
1382 /* Write a record for a packet to a dump file.
1383 Returns TRUE on success, FALSE on failure. */
1384 static gboolean nstrace_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
1385 const guint8 *pd, int *err)
1387 nstrace_dump_t *nstrace = (nstrace_dump_t *)wdh->priv;
1389 if (nstrace->page_offset == 0)
1391 /* Add the signature record and abs time record */
1392 if (wdh->file_type == WTAP_FILE_NETSCALER_1_0)
1394 if (!nstrace_add_signature(wdh, err) ||
1395 !nstrace_add_abstime(wdh, phdr, pd, err))
1397 } else if (wdh->file_type == WTAP_FILE_NETSCALER_2_0)
1399 if (!nstrace_add_signature(wdh, err) ||
1400 !nstrace_add_abstime(wdh, phdr, pd, err))
1404 g_assert_not_reached();
1409 switch (phdr->pseudo_header.nstr.rec_type)
1411 case NSPR_HEADER_VERSION100:
1413 if (wdh->file_type == WTAP_FILE_NETSCALER_1_0)
1415 if (nstrace->page_offset + phdr->caplen >= nstrace->page_len)
1417 /* Start on the next page */
1418 if (wtap_dump_file_seek(wdh, (nstrace->page_len - nstrace->page_offset), SEEK_CUR, err) == -1)
1421 nstrace->page_offset = 0;
1423 /* Possibly add signature and abstime records and increment offset */
1424 if (!nstrace_add_signature(wdh, err))
1428 /* Write the actual record as is */
1429 if (!wtap_dump_file_write(wdh, pd, phdr->caplen, err))
1432 nstrace->page_offset += (guint16) phdr->caplen;
1433 } else if (wdh->file_type == WTAP_FILE_NETSCALER_2_0)
1435 *err = WTAP_ERR_UNSUPPORTED_FILE_TYPE;
1441 case NSPR_HEADER_VERSION200:
1442 case NSPR_HEADER_VERSION201:
1443 case NSPR_HEADER_VERSION202:
1444 case NSPR_HEADER_VERSION203:
1445 case NSPR_HEADER_VERSION204:
1446 case NSPR_HEADER_VERSION205:
1447 if (wdh->file_type == WTAP_FILE_NETSCALER_1_0)
1449 *err = WTAP_ERR_UNSUPPORTED_FILE_TYPE;
1451 } else if (wdh->file_type == WTAP_FILE_NETSCALER_2_0)
1453 if (nstrace->page_offset + phdr->caplen >= nstrace->page_len)
1455 /* Start on the next page */
1456 if (wtap_dump_file_seek(wdh, (nstrace->page_len - nstrace->page_offset), SEEK_CUR, err) == -1)
1459 nstrace->page_offset = 0;
1461 /* Possibly add signature and abstime records and increment offset */
1462 if (!nstrace_add_signature(wdh, err))
1466 /* Write the actual record as is */
1467 if (!wtap_dump_file_write(wdh, pd, phdr->caplen, err))
1470 nstrace->page_offset += (guint16) phdr->caplen;
1476 g_assert_not_reached();