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 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 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 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 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 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 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 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 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 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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (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(enumprefix,structprefix,structname,hdrname,structfieldname) \
396 guint8 enumprefix##_##hdrname##_offset = (guint8)GPOINTER_TO_INT(myoffsetof(nspr_##structname##_t,structprefix##_##structfieldname));
398 #define __TNL(enumprefix,structprefix,structname,hdrname,structfieldname) \
399 guint8 enumprefix##_##hdrname##_len = (guint8)sizeof(((nspr_##structname##_t*)0)->structprefix##_##structfieldname);
401 #define __TNV1O(enumprefix,structprefix,structname,hdrname,structfieldname) \
402 guint8 enumprefix##_##hdrname##_offset = (guint8)GPOINTER_TO_INT(myoffsetof(nspr_##structname##_t,structfieldname));
404 #define __TNV1L(enumprefix,structprefix,structname,hdrname,structfieldname) \
405 guint8 enumprefix##_##hdrname##_len = (guint8)sizeof(((nspr_##structname##_t*)0)->structfieldname);
407 #define TRACE_V10_REC_LEN_OFF(enumprefix,structprefix,structname) \
408 __TNV1O(enumprefix,structprefix,structname,dir,phd.ph_RecordType)\
409 __TNV1L(enumprefix,structprefix,structname,dir,phd.ph_RecordType)\
410 __TNV1O(enumprefix,structprefix,structname,nicno,phd.ph_DevNo)\
411 __TNV1L(enumprefix,structprefix,structname,nicno,phd.ph_DevNo)\
412 __TNO(enumprefix,structprefix,structname,eth,Data)
414 #define TRACE_V20_REC_LEN_OFF(enumprefix,structprefix,structname) \
415 __TNO(enumprefix,structprefix,structname,dir,RecordType)\
416 __TNL(enumprefix,structprefix,structname,dir,RecordType)\
417 __TNO(enumprefix,structprefix,structname,nicno,DevNo)\
418 __TNL(enumprefix,structprefix,structname,nicno,DevNo)\
419 __TNO(enumprefix,structprefix,structname,eth,Data)
421 #define TRACE_V21_REC_LEN_OFF(enumprefix,structprefix,structname) \
422 TRACE_V20_REC_LEN_OFF(enumprefix,structprefix,structname)\
423 __TNO(enumprefix,structprefix,structname,pcb,PcbDevNo)\
424 __TNO(enumprefix,structprefix,structname,l_pcb,lPcbDevNo)
426 #define TRACE_V22_REC_LEN_OFF(enumprefix,structprefix,structname) \
427 TRACE_V21_REC_LEN_OFF(enumprefix,structprefix,structname)\
428 __TNO(enumprefix,structprefix,structname,vlantag,VlanTag)
430 #define TRACE_V23_REC_LEN_OFF(enumprefix,structprefix,structname) \
431 TRACE_V22_REC_LEN_OFF(enumprefix,structprefix,structname)\
432 __TNO(enumprefix,structprefix,structname,coreid,Coreid)
434 #define TRACE_V24_REC_LEN_OFF(enumprefix,structprefix,structname) \
435 TRACE_V23_REC_LEN_OFF(enumprefix,structprefix,structname)\
436 __TNO(enumprefix,structprefix,structname,srcnodeid,srcNodeId)\
437 __TNO(enumprefix,structprefix,structname,destnodeid,destNodeId)\
438 __TNO(enumprefix,structprefix,structname,clflags,clFlags)
440 #define TRACE_V25_REC_LEN_OFF(enumprefix,structprefix,structname) \
441 TRACE_V24_REC_LEN_OFF(enumprefix,structprefix,structname)\
442 __TNO(enumprefix,structprefix,structname,src_vmname_len,src_vmname_len)\
443 __TNO(enumprefix,structprefix,structname,dst_vmname_len,dst_vmname_len)\
444 __TNO(enumprefix,structprefix,structname,data,Data)
446 TRACE_V10_REC_LEN_OFF(v10_part,pp,pktracepart_v10)
447 TRACE_V10_REC_LEN_OFF(v10_full,fp,pktracefull_v10)
448 TRACE_V20_REC_LEN_OFF(v20_part,pp,pktracepart_v20)
449 TRACE_V20_REC_LEN_OFF(v20_full,fp,pktracefull_v20)
450 TRACE_V21_REC_LEN_OFF(v21_part,pp,pktracepart_v21)
451 TRACE_V21_REC_LEN_OFF(v21_full,fp,pktracefull_v21)
452 TRACE_V22_REC_LEN_OFF(v22_part,pp,pktracepart_v22)
453 TRACE_V22_REC_LEN_OFF(v22_full,fp,pktracefull_v22)
454 TRACE_V23_REC_LEN_OFF(v23_part,pp,pktracepart_v23)
455 TRACE_V23_REC_LEN_OFF(v23_full,fp,pktracefull_v23)
456 TRACE_V24_REC_LEN_OFF(v24_part,pp,pktracepart_v24)
457 TRACE_V24_REC_LEN_OFF(v24_full,fp,pktracefull_v24)
458 TRACE_V25_REC_LEN_OFF(v25_part,pp,pktracepart_v25)
459 TRACE_V25_REC_LEN_OFF(v25_full,fp,pktracefull_v25)
467 #define ns_setabstime(nstrace, AbsoluteTime, RelativeTimems) \
469 (nstrace)->nspm_curtime = AbsoluteTime; \
470 (nstrace)->nspm_curtimemsec += RelativeTimems; \
471 (nstrace)->nspm_curtimelastmsec = nstrace->nspm_curtimemsec; \
475 #define ns_setrelativetime(nstrace, RelativeTimems) \
478 (nstrace)->nspm_curtimemsec += RelativeTimems; \
479 rsec = (guint32)((nstrace)->nspm_curtimemsec - (nstrace)->nspm_curtimelastmsec)/1000; \
480 (nstrace)->nspm_curtime += rsec; \
481 (nstrace)->nspm_curtimelastmsec += rsec * 1000; \
488 gint32 nstrace_buf_offset;
489 gint32 nstrace_buflen;
490 /* Performance Monitor Time variables */
491 guint32 nspm_curtime; /* current time since 1970 */
492 guint64 nspm_curtimemsec; /* current time in milliseconds */
493 guint64 nspm_curtimelastmsec; /* nspm_curtime last update time in milliseconds */
494 guint64 nsg_creltime;
498 static guint32 nspm_signature_version(wtap*, gchar*, gint32);
499 static gboolean nstrace_read(wtap *wth, int *err, gchar **err_info,
500 gint64 *data_offset);
501 static gboolean nstrace_read_v10(wtap *wth, int *err, gchar **err_info,
502 gint64 *data_offset);
503 static gboolean nstrace_read_v20(wtap *wth, int *err, gchar **err_info,
504 gint64 *data_offset);
505 static gboolean nstrace_seek_read(wtap *wth, gint64 seek_off,
506 struct wtap_pkthdr *phdr,
507 guint8 *pd, int length,
508 int *err, gchar **err_info);
509 static void nstrace_close(wtap *wth);
511 static gboolean nstrace_set_start_time_v10(wtap *wth);
512 static gboolean nstrace_set_start_time_v20(wtap *wth);
513 static gboolean nstrace_set_start_time(wtap *wth);
514 static guint64 ns_hrtime2nsec(guint32 tm);
516 static gboolean nstrace_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
517 const guint8 *pd, int *err);
520 #define GET_READ_PAGE_SIZE(remaining_file_size) ((gint32)((remaining_file_size>NSPR_PAGESIZE)?NSPR_PAGESIZE:remaining_file_size))
523 static guint64 ns_hrtime2nsec(guint32 tm)
525 guint32 val = tm & NSPR_HRTIME_MASKTM;
526 switch(tm & NSPR_HRTIME_MASKFMT)
528 case NSPR_HRTIME_SEC: return (guint64)val*1000000000;
529 case NSPR_HRTIME_MSEC: return (guint64)val*1000000;
530 case NSPR_HRTIME_USEC: return (guint64)val*1000;
531 case NSPR_HRTIME_NSEC: return val;
538 ** Netscaler trace format open routines
540 int nstrace_open(wtap *wth, int *err, gchar **err_info)
548 errno = WTAP_ERR_CANT_READ;
550 if ((file_size = wtap_file_size(wth, err)) == -1)
553 nstrace_buf = (gchar *)g_malloc(NSPR_PAGESIZE);
554 page_size = GET_READ_PAGE_SIZE(file_size);
556 switch ((wth->file_type = nspm_signature_version(wth, nstrace_buf, page_size)))
558 case WTAP_FILE_NETSCALER_1_0:
559 wth->file_encap = WTAP_ENCAP_NSTRACE_1_0;
562 case WTAP_FILE_NETSCALER_2_0:
563 wth->file_encap = WTAP_ENCAP_NSTRACE_2_0;
567 *err = WTAP_ERR_UNSUPPORTED;
568 *err_info = g_strdup_printf("nstrace: file type %d unsupported", wth->file_type);
573 if ((file_seek(wth->fh, 0, SEEK_SET, err)) == -1)
575 *err = file_error(wth->fh, err_info);
580 bytes_read = file_read(nstrace_buf, page_size, wth->fh);
581 if (bytes_read != page_size)
583 *err = file_error(wth->fh, err_info);
588 wth->subtype_read = nstrace_read;
589 wth->subtype_seek_read = nstrace_seek_read;
590 wth->subtype_close = nstrace_close;
592 nstrace = (nstrace_t *)g_malloc(sizeof(nstrace_t));
593 wth->priv = (void *)nstrace;
594 nstrace->pnstrace_buf = nstrace_buf;
595 nstrace->xxx_offset = 0;
596 nstrace->nstrace_buflen = page_size;
597 nstrace->nstrace_buf_offset = 0;
598 nstrace->nspm_curtime = 0;
599 nstrace->nspm_curtimemsec = 0;
600 nstrace->nspm_curtimelastmsec = 0;
601 nstrace->nsg_creltime = 0;
602 nstrace->file_size = file_size;
605 /* Set the start time by looking for the abstime record */
606 if ((nstrace_set_start_time(wth)) == FALSE)
608 /* Reset the read pointer to start of the file. */
609 if ((file_seek(wth->fh, 0, SEEK_SET, err)) == -1)
611 *err = file_error(wth->fh, err_info);
612 g_free(nstrace->pnstrace_buf);
617 /* Read the first page of data */
618 bytes_read = file_read(nstrace_buf, page_size, wth->fh);
619 if (bytes_read != page_size)
621 *err = file_error(wth->fh, err_info);
622 g_free(nstrace->pnstrace_buf);
627 /* reset the buffer offset */
628 nstrace->nstrace_buf_offset = 0;
631 wth->tsprecision = WTAP_FILE_TSPREC_NSEC;
632 wth->phdr.ts.secs = nstrace->nspm_curtime;
633 wth->phdr.ts.nsecs = 0;
640 #define nspm_signature_func(ver) \
641 static guint32 nspm_signature_isv##ver(gchar *sigp) {\
642 return strncmp(sigp,NSPR_SIGSTR_V##ver,(sizeof(NSPR_SIGSTR_V##ver)-1));\
645 nspm_signature_func(10)
646 nspm_signature_func(20)
649 ** Check signature and return the version number of the signature.
650 ** If not found, it returns 0. At the time of return from this function
651 ** we might not be at the first page. So after a call to this function, there
652 ** has to be a file seek to return to the start of the first page.
655 nspm_signature_version(wtap *wth, gchar *nstrace_buf, gint32 len)
657 gchar *dp = nstrace_buf;
660 bytes_read = file_read(dp, len, wth->fh);
661 if (bytes_read == len) {
663 for ( ; len > (gint32)(MIN(sizeof(NSPR_SIGSTR_V10), sizeof(NSPR_SIGSTR_V20))); dp++, len--)
665 #define sigv10p ((nspr_signature_v10_t*)dp)
666 if ((pletohs(&sigv10p->nsprRecordType) == NSPR_SIGNATURE_V10) &&
667 (pletohs(&sigv10p->nsprRecordSize) <= len) &&
668 ((gint32)sizeof(NSPR_SIGSTR_V10) <= len) &&
669 (!nspm_signature_isv10(sigv10p->sig_Signature)))
670 return WTAP_FILE_NETSCALER_1_0;
673 #define sigv20p ((nspr_signature_v20_t*)dp)
674 if ((sigv20p->sig_RecordType == NSPR_SIGNATURE_V20) &&
675 (sigv20p->sig_RecordSize <= len) &&
676 ((gint32)sizeof(NSPR_SIGSTR_V20) <= len) &&
677 (!nspm_signature_isv20(sigv20p->sig_Signature)))
678 return WTAP_FILE_NETSCALER_2_0;
683 return 0; /* no version found */
686 #define nspr_getv10recordtype(hdp) (pletohs(&hdp->nsprRecordType))
687 #define nspr_getv10recordsize(hdp) (pletohs(&hdp->nsprRecordSize))
688 #define nspr_getv20recordtype(hdp) (hdp->phd_RecordType)
689 #define nspr_getv20recordsize(hdp) \
690 (((hdp)->phd_RecordSizeLow & NSPR_V20RECORDSIZE_2BYTES)? \
691 (((hdp)->phd_RecordSizeHigh * NSPR_V20RECORDSIZE_2BYTES)+ \
692 ((hdp)->phd_RecordSizeLow & ~NSPR_V20RECORDSIZE_2BYTES)) : \
693 (hdp)->phd_RecordSizeLow)
696 #define nstrace_set_start_time_ver(ver) \
697 gboolean nstrace_set_start_time_v##ver(wtap *wth) \
699 nstrace_t *nstrace = (nstrace_t *)wth->priv;\
700 gchar* nstrace_buf = nstrace->pnstrace_buf;\
701 gint32 nstrace_buf_offset = nstrace->nstrace_buf_offset;\
702 gint32 nstrace_buflen = nstrace->nstrace_buflen;\
706 while (nstrace_buf_offset < nstrace_buflen)\
708 nspr_hd_v##ver##_t *fp = (nspr_hd_v##ver##_t *) &nstrace_buf[nstrace_buf_offset];\
709 switch (nspr_getv##ver##recordtype(fp))\
711 case NSPR_ABSTIME_V##ver:\
712 ns_setabstime(nstrace, pletohl(&((nspr_abstime_v##ver##_t *) fp)->abs_Time), pletohs(&((nspr_abstime_v##ver##_t *) fp)->abs_RelTime));\
713 nstrace->nstrace_buf_offset = nstrace_buf_offset + nspr_getv##ver##recordsize(fp);\
714 nstrace->nstrace_buflen = nstrace_buflen;\
716 case NSPR_UNUSEDSPACE_V10:\
717 nstrace_buf_offset = nstrace_buflen;\
720 nstrace_buf_offset += nspr_getv##ver##recordsize(fp);\
723 nstrace_buf_offset = 0;\
724 nstrace->xxx_offset += nstrace_buflen;\
725 nstrace_buflen = GET_READ_PAGE_SIZE((nstrace->file_size - nstrace->xxx_offset));\
726 }while((nstrace_buflen > 0) && (bytes_read = file_read(nstrace_buf, nstrace_buflen, wth->fh)) && bytes_read == nstrace_buflen); \
730 nstrace_set_start_time_ver(10)
731 nstrace_set_start_time_ver(20)
733 #undef nspr_getv10recordtype
734 #undef nspr_getv20recordtype
735 #undef nspr_getv10recordsize
738 ** Set the start time of the trace file. We look for the first ABSTIME record. We use that
739 ** to set the start time. Apart from that we also make sure that we remember the position of
740 ** the next record after the ABSTIME record. Inorder to report correct time values, all trace
741 ** records before the ABSTIME record are ignored.
743 static gboolean nstrace_set_start_time(wtap *wth)
745 if (wth->file_type == WTAP_FILE_NETSCALER_1_0)
746 return nstrace_set_start_time_v10(wth);
747 else if (wth->file_type == WTAP_FILE_NETSCALER_2_0)
748 return nstrace_set_start_time_v20(wth);
753 #define __TNO(enumprefix,structprefix,structname,hdrname,structfieldname) \
754 wth->phdr.pseudo_header.nstr.hdrname##_offset = enumprefix##_##hdrname##_offset;
756 #define __TNL(enumprefix,structprefix,structname,hdrname,structfieldname) \
757 wth->phdr.pseudo_header.nstr.hdrname##_len = enumprefix##_##hdrname##_len;
759 #define __TNV1O(enumprefix,structprefix,structname,hdrname,structfieldname) \
760 __TNO(enumprefix,structprefix,structname,hdrname,structfieldname)
762 #define __TNV1L(enumprefix,structprefix,structname,hdrname,structfieldname) \
763 __TNL(enumprefix,structprefix,structname,hdrname,structfieldname)
768 ** Netscaler trace format read routines.
770 static gboolean nstrace_read_v10(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
772 nstrace_t *nstrace = (nstrace_t *)wth->priv;
773 guint64 nsg_creltime = nstrace->nsg_creltime;
774 gchar *nstrace_buf = nstrace->pnstrace_buf;
775 gint32 nstrace_buf_offset = nstrace->nstrace_buf_offset;
776 gint32 nstrace_buflen = nstrace->nstrace_buflen;
777 nspr_pktracefull_v10_t *fp;
778 nspr_pktracepart_v10_t *pp;
785 while ((nstrace_buf_offset < nstrace_buflen) &&
786 ((nstrace_buflen - nstrace_buf_offset) >= ((gint32)sizeof(fp->nsprRecordType))))
789 fp = (nspr_pktracefull_v10_t *) &nstrace_buf[nstrace_buf_offset];
790 pp = (nspr_pktracepart_v10_t *) fp;
792 switch (pletohs(&fp->nsprRecordType))
794 case NSPR_PDPKTRACEFULLTX_V10:
795 case NSPR_PDPKTRACEFULLTXB_V10:
796 case NSPR_PDPKTRACEFULLRX_V10:
798 wth->phdr.presence_flags = WTAP_HAS_TS;
800 nsg_creltime += ns_hrtime2nsec(pletohl(&fp->fp_RelTimeHr));
801 wth->phdr.ts.secs = nstrace->nspm_curtime + (guint32) (nsg_creltime / 1000000000);
802 wth->phdr.ts.nsecs = (guint32) (nsg_creltime % 1000000000);
804 wth->phdr.len = pletohs(&fp->nsprRecordSize);
805 wth->phdr.caplen = wth->phdr.len;
808 TRACE_V10_REC_LEN_OFF(v10_full,fp,pktracefull_v10);
810 buffer_assure_space(wth->frame_buffer, wth->phdr.caplen);
811 memcpy(buffer_start_ptr(wth->frame_buffer), fp, wth->phdr.caplen);
812 *data_offset = nstrace->xxx_offset + nstrace_buf_offset;
814 nstrace->nstrace_buf_offset = nstrace_buf_offset + wth->phdr.len;
815 nstrace->nstrace_buflen = nstrace_buflen;
816 nstrace->nsg_creltime = nsg_creltime;
820 case NSPR_PDPKTRACEPARTTX_V10:
821 case NSPR_PDPKTRACEPARTTXB_V10:
822 case NSPR_PDPKTRACEPARTRX_V10:
824 wth->phdr.presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN;
826 nsg_creltime += ns_hrtime2nsec(pletohl(&pp->pp_RelTimeHr));
827 wth->phdr.ts.secs = nstrace->nspm_curtime + (guint32) (nsg_creltime / 1000000000);
828 wth->phdr.ts.nsecs = (guint32) (nsg_creltime % 1000000000);
830 wth->phdr.len = pletohs(&pp->pp_PktSizeOrg) + nspr_pktracepart_v10_s;
831 wth->phdr.caplen = pletohs(&pp->nsprRecordSize);
833 TRACE_V10_REC_LEN_OFF(v10_part,pp,pktracepart_v10);
835 buffer_assure_space(wth->frame_buffer, wth->phdr.caplen);
836 memcpy(buffer_start_ptr(wth->frame_buffer), pp, wth->phdr.caplen);
837 *data_offset = nstrace->xxx_offset + nstrace_buf_offset;
839 nstrace->nstrace_buf_offset = nstrace_buf_offset + wth->phdr.caplen;
840 nstrace->nsg_creltime = nsg_creltime;
841 nstrace->nstrace_buflen = nstrace_buflen;
845 case NSPR_ABSTIME_V10:
847 ns_setabstime(nstrace, pletohl(((nspr_abstime_v10_t *) fp)->abs_Time), pletohl(&((nspr_abstime_v10_t *) fp)->abs_RelTime));
848 nstrace_buf_offset += pletohs(&fp->nsprRecordSize);
851 case NSPR_RELTIME_V10:
853 ns_setrelativetime(nstrace, pletohl(((nspr_abstime_v10_t *) fp)->abs_RelTime));
854 nstrace_buf_offset += pletohs(&fp->nsprRecordSize);
857 case NSPR_UNUSEDSPACE_V10:
859 nstrace_buf_offset = nstrace_buflen;
864 nstrace_buf_offset += pletohs(&fp->nsprRecordSize);
869 nstrace_buf_offset = 0;
870 nstrace->xxx_offset += nstrace_buflen;
871 nstrace_buflen = GET_READ_PAGE_SIZE((nstrace->file_size - nstrace->xxx_offset));
872 }while((nstrace_buflen > 0) && (bytes_read = file_read(nstrace_buf, nstrace_buflen, wth->fh)) && (bytes_read == nstrace_buflen));
877 #define TIMEDEFV20(fp,type) \
879 wth->phdr.presence_flags |= WTAP_HAS_TS;\
880 nsg_creltime += ns_hrtime2nsec(pletohl(fp->type##_RelTimeHr));\
881 wth->phdr.ts.secs = nstrace->nspm_curtime + (guint32) (nsg_creltime / 1000000000);\
882 wth->phdr.ts.nsecs = (guint32) (nsg_creltime % 1000000000);\
885 #define TIMEDEFV23(fp,type) \
887 wth->phdr.presence_flags |= WTAP_HAS_TS;\
888 /* access _AbsTimeHr as a 64bit value */\
889 nsg_creltime = pletohll(fp->type##_AbsTimeHr);\
890 wth->phdr.ts.secs = (guint32) (nsg_creltime / 1000000000);\
891 wth->phdr.ts.nsecs = (guint32) (nsg_creltime % 1000000000);\
894 #define TIMEDEFV21(fp,type) TIMEDEFV20(fp,type)
895 #define TIMEDEFV22(fp,type) TIMEDEFV20(fp,type)
896 #define TIMEDEFV24(fp,type) TIMEDEFV23(fp,type)
897 #define TIMEDEFV25(fp,type) TIMEDEFV24(fp,type)
898 #define PPSIZEDEFV20(pp,ver) \
900 wth->phdr.presence_flags |= WTAP_HAS_CAP_LEN;\
901 wth->phdr.len = pletohs(&pp->pp_PktSizeOrg) + nspr_pktracepart_v##ver##_s;\
902 wth->phdr.caplen = nspr_getv20recordsize((nspr_hd_v20_t *)pp);\
905 #define PPSIZEDEFV21(pp,ver) PPSIZEDEFV20(pp,ver)
906 #define PPSIZEDEFV22(pp,ver) PPSIZEDEFV20(pp,ver)
907 #define PPSIZEDEFV23(pp,ver) PPSIZEDEFV20(pp,ver)
908 #define PPSIZEDEFV24(pp,ver) PPSIZEDEFV20(pp,ver)
909 #define PPSIZEDEFV25(pp,ver) PPSIZEDEFV20(pp,ver)
911 #define FPSIZEDEFV20(fp,ver)\
913 wth->phdr.len = nspr_getv20recordsize((nspr_hd_v20_t *)fp);\
914 wth->phdr.caplen = wth->phdr.len;\
917 #define FPSIZEDEFV21(pp,ver) FPSIZEDEFV20(fp,ver)
918 #define FPSIZEDEFV22(pp,ver) FPSIZEDEFV20(fp,ver)
919 #define FPSIZEDEFV23(pp,ver) FPSIZEDEFV20(fp,ver)
920 #define FPSIZEDEFV24(pp,ver) FPSIZEDEFV20(fp,ver)
921 #define FPSIZEDEFV25(pp,ver) FPSIZEDEFV20(fp,ver)
923 #define PACKET_DESCRIBE(FPTIMEDEF,SIZEDEF,ver,enumprefix,type,structname,TYPE)\
925 nspr_##structname##_t *fp= (nspr_##structname##_t*)&nstrace_buf[nstrace_buf_offset];\
926 TIMEDEFV##ver(fp,type);\
927 SIZEDEF##ver(fp,ver);\
928 TRACE_V##ver##_REC_LEN_OFF(enumprefix,type,structname);\
929 buffer_assure_space(wth->frame_buffer, wth->phdr.caplen);\
930 memcpy(buffer_start_ptr(wth->frame_buffer), fp, wth->phdr.caplen);\
931 *data_offset = nstrace->xxx_offset + nstrace_buf_offset;\
932 nstrace->nstrace_buf_offset = nstrace_buf_offset + nspr_getv20recordsize((nspr_hd_v20_t *)fp);\
933 nstrace->nstrace_buflen = nstrace_buflen;\
934 nstrace->nsg_creltime = nsg_creltime;\
935 wth->phdr.pseudo_header.nstr.rec_type = NSPR_HEADER_VERSION##TYPE;\
939 static gboolean nstrace_read_v20(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
941 nstrace_t *nstrace = (nstrace_t *)wth->priv;
942 guint64 nsg_creltime = nstrace->nsg_creltime;
943 gchar *nstrace_buf = nstrace->pnstrace_buf;
944 gint32 nstrace_buf_offset = nstrace->nstrace_buf_offset;
945 gint32 nstrace_buflen = nstrace->nstrace_buflen;
946 nspr_pktracefull_v20_t *fp20;
947 nspr_pktracefull_v21_t *fp21;
954 while ((nstrace_buf_offset < nstrace_buflen) &&
955 ((nstrace_buflen - nstrace_buf_offset) >= ((gint32)sizeof(fp21->fp_RecordType))))
957 fp21 = (nspr_pktracefull_v21_t *) &nstrace_buf[nstrace_buf_offset];
959 switch (fp21->fp_RecordType)
962 #define GENERATE_CASE(type,acttype) \
963 case NSPR_PDPKTRACEFULLTX_V##type:\
964 case NSPR_PDPKTRACEFULLTXB_V##type:\
965 case NSPR_PDPKTRACEFULLRX_V##type:\
966 PACKET_DESCRIBE(TIMEDEF,FPSIZEDEFV,type,v##type##_full,fp,pktracefull_v##type,acttype);
967 #define GENERATE_CASE_V25(type,acttype) \
968 case NSPR_PDPKTRACEFULLTX_V##type:\
969 case NSPR_PDPKTRACEFULLTXB_V##type:\
970 case NSPR_PDPKTRACEFULLRX_V##type:\
971 case NSPR_PDPKTRACEFULLNEWRX_V##type:\
972 PACKET_DESCRIBE(TIMEDEF,FPSIZEDEFV,type,v##type##_full,fp,pktracefull_v##type,acttype);
973 GENERATE_CASE_V25(25,205);
974 GENERATE_CASE_V25(24,204);
975 GENERATE_CASE(23,203);
976 GENERATE_CASE(22,202);
977 GENERATE_CASE(21,201);
978 GENERATE_CASE(20,200);
980 #undef GENERATE_CASE_V25
982 #define GENERATE_CASE(type,acttype) \
983 case NSPR_PDPKTRACEPARTTX_V##type:\
984 case NSPR_PDPKTRACEPARTTXB_V##type:\
985 case NSPR_PDPKTRACEPARTRX_V##type:\
986 PACKET_DESCRIBE(TIMEDEF,PPSIZEDEFV,type,v##type##_part,pp,pktracepart_v##type,acttype);
987 #define GENERATE_CASE_V25(type,acttype) \
988 case NSPR_PDPKTRACEPARTTX_V##type:\
989 case NSPR_PDPKTRACEPARTTXB_V##type:\
990 case NSPR_PDPKTRACEPARTRX_V##type:\
991 case NSPR_PDPKTRACEPARTNEWRX_V##type:\
992 PACKET_DESCRIBE(TIMEDEF,PPSIZEDEFV,type,v##type##_part,pp,pktracepart_v##type,acttype);
993 GENERATE_CASE_V25(25,205);
994 GENERATE_CASE_V25(24,204);
995 GENERATE_CASE(23,203);
996 GENERATE_CASE(22,202);
997 GENERATE_CASE(21,201);
998 GENERATE_CASE(20,200);
1000 #undef GENERATE_CASE_V25
1002 case NSPR_ABSTIME_V20:
1004 fp20 = (nspr_pktracefull_v20_t *) &nstrace_buf[nstrace_buf_offset];
1005 nstrace_buf_offset += nspr_getv20recordsize((nspr_hd_v20_t *)fp20);
1006 ns_setabstime(nstrace, pletohl(&((nspr_abstime_v20_t *) fp20)->abs_Time), pletohs(&((nspr_abstime_v20_t *) fp20)->abs_RelTime));
1010 case NSPR_RELTIME_V20:
1012 fp20 = (nspr_pktracefull_v20_t *) &nstrace_buf[nstrace_buf_offset];
1013 ns_setrelativetime(nstrace, pletohs(&((nspr_abstime_v20_t *) fp20)->abs_RelTime));
1014 nstrace_buf_offset += nspr_getv20recordsize((nspr_hd_v20_t *)fp20);
1018 case NSPR_UNUSEDSPACE_V20:
1020 if (nstrace_buf_offset >= NSPR_PAGESIZE/2)
1021 nstrace_buf_offset = nstrace_buflen;
1023 nstrace_buf_offset = NSPR_PAGESIZE/2;
1029 fp20 = (nspr_pktracefull_v20_t *) &nstrace_buf[nstrace_buf_offset];
1030 nstrace_buf_offset += nspr_getv20recordsize((nspr_hd_v20_t *)fp20);
1036 nstrace_buf_offset = 0;
1037 nstrace->xxx_offset += nstrace_buflen;
1038 nstrace_buflen = GET_READ_PAGE_SIZE((nstrace->file_size - nstrace->xxx_offset));
1039 }while((nstrace_buflen > 0) && (bytes_read = file_read(nstrace_buf, nstrace_buflen, wth->fh)) && (bytes_read == nstrace_buflen));
1051 static gboolean nstrace_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
1054 if (wth->file_type == WTAP_FILE_NETSCALER_1_0)
1055 return nstrace_read_v10(wth, err, err_info, data_offset);
1056 else if (wth->file_type == WTAP_FILE_NETSCALER_2_0)
1057 return nstrace_read_v20(wth, err, err_info, data_offset);
1063 #define __TNO(enumprefix,structprefix,structname,hdrname,structfieldname) \
1064 phdr->pseudo_header.nstr.hdrname##_offset = (guint8) enumprefix##_##hdrname##_offset;
1065 #define __TNL(enumprefix,structprefix,structname,hdrname,structfieldname) \
1066 phdr->pseudo_header.nstr.hdrname##_len = (guint8) enumprefix##_##hdrname##_len;
1068 #define __TNV1O(enumprefix,structprefix,structname,hdrname,structfieldname) \
1069 __TNO(enumprefix,structprefix,structname,hdrname,structfieldname)
1070 #define __TNV1L(enumprefix,structprefix,structname,hdrname,structfieldname) \
1071 __TNL(enumprefix,structprefix,structname,hdrname,structfieldname)
1074 static gboolean nstrace_seek_read(wtap *wth, gint64 seek_off,
1075 struct wtap_pkthdr *phdr, guint8 *pd, int length,
1076 int *err, gchar **err_info)
1078 union wtap_pseudo_header *pseudo_header = &phdr->pseudo_header;
1083 if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
1087 ** Read the packet data.
1089 bytes_read = file_read(pd, length, wth->random_fh);
1090 if (bytes_read != length) {
1091 *err = file_error(wth->random_fh, err_info);
1093 *err = WTAP_ERR_SHORT_READ;
1097 if (wth->file_type == WTAP_FILE_NETSCALER_1_0)
1100 #define GENERATE_CASE_FULL(type,acttype) \
1101 case NSPR_PDPKTRACEFULLTX_V##type:\
1102 case NSPR_PDPKTRACEFULLTXB_V##type:\
1103 case NSPR_PDPKTRACEFULLRX_V##type:\
1104 TRACE_V##type##_REC_LEN_OFF(v##type##_full,fp,pktracefull_v##type);\
1105 pseudo_header->nstr.rec_type = NSPR_HEADER_VERSION##acttype;\
1108 #define GENERATE_CASE_PART(type,acttype) \
1109 case NSPR_PDPKTRACEPARTTX_V##type:\
1110 case NSPR_PDPKTRACEPARTTXB_V##type:\
1111 case NSPR_PDPKTRACEPARTRX_V##type:\
1112 TRACE_V##type##_REC_LEN_OFF(v##type##_part,pp,pktracepart_v##type);\
1113 pseudo_header->nstr.rec_type = NSPR_HEADER_VERSION##acttype;\
1116 switch (pletohs(&(( nspr_header_v10_t*)pd)->ph_RecordType))
1118 GENERATE_CASE_FULL(10,100)
1119 GENERATE_CASE_PART(10,100)
1121 } else if (wth->file_type == WTAP_FILE_NETSCALER_2_0)
1123 #define GENERATE_CASE_FULL_V25(type,acttype) \
1124 case NSPR_PDPKTRACEFULLTX_V##type:\
1125 case NSPR_PDPKTRACEFULLTXB_V##type:\
1126 case NSPR_PDPKTRACEFULLRX_V##type:\
1127 case NSPR_PDPKTRACEFULLNEWRX_V##type:\
1128 TRACE_V##type##_REC_LEN_OFF(v##type##_full,fp,pktracefull_v##type);\
1129 pseudo_header->nstr.rec_type = NSPR_HEADER_VERSION##acttype;\
1132 #define GENERATE_CASE_PART_V25(type,acttype) \
1133 case NSPR_PDPKTRACEPARTTX_V##type:\
1134 case NSPR_PDPKTRACEPARTTXB_V##type:\
1135 case NSPR_PDPKTRACEPARTRX_V##type:\
1136 case NSPR_PDPKTRACEPARTNEWRX_V##type:\
1137 TRACE_V##type##_REC_LEN_OFF(v##type##_part,pp,pktracepart_v##type);\
1138 pseudo_header->nstr.rec_type = NSPR_HEADER_VERSION##acttype;\
1141 switch ((( nspr_hd_v20_t*)pd)->phd_RecordType)
1143 GENERATE_CASE_FULL(20,200)
1144 GENERATE_CASE_PART(20,200)
1145 GENERATE_CASE_FULL(21,201)
1146 GENERATE_CASE_PART(21,201)
1147 GENERATE_CASE_FULL(22,202)
1148 GENERATE_CASE_PART(22,202)
1149 GENERATE_CASE_FULL(23,203)
1150 GENERATE_CASE_PART(23,203)
1151 GENERATE_CASE_FULL_V25(24,204)
1152 GENERATE_CASE_PART_V25(24,204)
1153 GENERATE_CASE_FULL_V25(25,205)
1154 GENERATE_CASE_PART_V25(25,205)
1168 ** Netscaler trace format close routines.
1170 static void nstrace_close(wtap *wth)
1172 nstrace_t *nstrace = (nstrace_t *)wth->priv;
1174 g_free(nstrace->pnstrace_buf);
1179 guint16 page_offset;
1181 guint32 absrec_time;
1184 /* Returns 0 if we could write the specified encapsulation type,
1185 ** an error indication otherwise. */
1186 int nstrace_10_dump_can_write_encap(int encap)
1188 if (encap == WTAP_ENCAP_NSTRACE_1_0)
1191 return WTAP_ERR_UNSUPPORTED_ENCAP;
1195 /* Returns 0 if we could write the specified encapsulation type,
1196 ** an error indication otherwise. */
1197 int nstrace_20_dump_can_write_encap(int encap)
1199 if (encap == WTAP_ENCAP_NSTRACE_2_0)
1202 return WTAP_ERR_UNSUPPORTED_ENCAP;
1206 /* Returns TRUE on success, FALSE on failure; sets "*err" to an error code on
1208 gboolean nstrace_dump_open(wtap_dumper *wdh, int *err _U_)
1210 nstrace_dump_t *nstrace;
1212 wdh->subtype_write = nstrace_dump;
1214 nstrace = (nstrace_dump_t *)g_malloc(sizeof(nstrace_dump_t));
1215 wdh->priv = (void *)nstrace;
1216 nstrace->page_offset = 0;
1217 nstrace->page_len = NSPR_PAGESIZE;
1218 nstrace->absrec_time = 0;
1224 static gboolean nstrace_add_signature(wtap_dumper *wdh, int *err)
1226 nstrace_dump_t *nstrace = (nstrace_dump_t *)wdh->priv;
1228 if (wdh->file_type == WTAP_FILE_NETSCALER_1_0)
1231 nspr_signature_v10_t sig10;
1233 /* populate the record */
1234 val16b = htoles(NSPR_SIGNATURE_V10);
1235 memcpy(sig10.phd.ph_RecordType, &val16b, sizeof sig10.phd.ph_RecordType);
1236 val16b = htoles(nspr_signature_v10_s);
1237 memcpy(sig10.phd.ph_RecordSize, &val16b, sizeof sig10.phd.ph_RecordSize);
1238 memset(sig10.sig_Signature, 0, NSPR_SIGSIZE_V10);
1239 g_strlcpy(sig10.sig_Signature, NSPR_SIGSTR_V10, NSPR_SIGSIZE_V10);
1241 /* Write the record into the file */
1242 if (!wtap_dump_file_write(wdh, &sig10, nspr_signature_v10_s,
1246 /* Move forward the page offset */
1247 nstrace->page_offset += (guint16) nspr_signature_v10_s;
1249 } else if (wdh->file_type == WTAP_FILE_NETSCALER_2_0)
1251 nspr_signature_v20_t sig20;
1253 sig20.sig_RecordType = NSPR_SIGNATURE_V20;
1254 sig20.sig_RecordSize = nspr_signature_v20_s;
1255 memcpy(sig20.sig_Signature, NSPR_SIGSTR_V20, sizeof(NSPR_SIGSTR_V20));
1257 /* Write the record into the file */
1258 if (!wtap_dump_file_write(wdh, &sig20, sig20.sig_RecordSize,
1262 /* Move forward the page offset */
1263 nstrace->page_offset += (guint16) sig20.sig_RecordSize;
1267 g_assert_not_reached();
1276 nstrace_add_abstime(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
1277 const guint8 *pd, int *err)
1279 nstrace_dump_t *nstrace = (nstrace_dump_t *)wdh->priv;
1280 guint64 nsg_creltime;
1282 if (wdh->file_type == WTAP_FILE_NETSCALER_1_0)
1287 nspr_abstime_v10_t abs10;
1289 /* populate the record */
1290 val16 = htoles(NSPR_ABSTIME_V10);
1291 memcpy(abs10.phd.ph_RecordType, &val16, sizeof abs10.phd.ph_RecordType);
1292 val16 = htoles(nspr_abstime_v10_s);
1293 memcpy(abs10.phd.ph_RecordSize, &val16, sizeof abs10.phd.ph_RecordSize);
1295 memcpy(&reltime, ((const nspr_pktracefull_v10_t *)pd)->fp_RelTimeHr, sizeof reltime);
1296 nsg_creltime = ns_hrtime2nsec(reltime);
1298 memset(abs10.abs_RelTime, 0, sizeof abs10.abs_RelTime);
1299 abstime = htolel((guint32)phdr->ts.secs - (guint32)(nsg_creltime/1000000000));
1300 memcpy(abs10.abs_Time, &abstime, sizeof abs10.abs_Time);
1302 /* Write the record into the file */
1303 if (!wtap_dump_file_write(wdh, &abs10, nspr_abstime_v10_s, err))
1306 /* Move forward the page offset */
1307 nstrace->page_offset += nspr_abstime_v10_s;
1309 } else if (wdh->file_type == WTAP_FILE_NETSCALER_2_0)
1313 nspr_abstime_v20_t abs20;
1315 abs20.abs_RecordType = NSPR_ABSTIME_V20;
1316 abs20.abs_RecordSize = nspr_abstime_v20_s;
1318 memcpy(&reltime, ((const nspr_pktracefull_v20_t *)pd)->fp_RelTimeHr, sizeof reltime);
1319 nsg_creltime = ns_hrtime2nsec(reltime);
1321 memset(abs20.abs_RelTime, 0, sizeof abs20.abs_RelTime);
1322 abstime = htolel((guint32)phdr->ts.secs - (guint32)(nsg_creltime/1000000000));
1323 memcpy(abs20.abs_RelTime, &abstime, sizeof abs20.abs_RelTime);
1325 /* Write the record into the file */
1326 if (!wtap_dump_file_write(wdh, &abs20, nspr_abstime_v20_s, err))
1329 /* Move forward the page offset */
1330 nstrace->page_offset += nspr_abstime_v20_s;
1334 g_assert_not_reached();
1342 /* Write a record for a packet to a dump file.
1343 Returns TRUE on success, FALSE on failure. */
1344 static gboolean nstrace_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
1345 const guint8 *pd, int *err)
1347 nstrace_dump_t *nstrace = (nstrace_dump_t *)wdh->priv;
1349 if (nstrace->page_offset == 0)
1351 /* Add the signature record and abs time record */
1352 if (wdh->file_type == WTAP_FILE_NETSCALER_1_0)
1354 if (!nstrace_add_signature(wdh, err) ||
1355 !nstrace_add_abstime(wdh, phdr, pd, err))
1357 } else if (wdh->file_type == WTAP_FILE_NETSCALER_2_0)
1359 if (!nstrace_add_signature(wdh, err) ||
1360 !nstrace_add_abstime(wdh, phdr, pd, err))
1364 g_assert_not_reached();
1369 switch (phdr->pseudo_header.nstr.rec_type)
1371 case NSPR_HEADER_VERSION100:
1373 if (wdh->file_type == WTAP_FILE_NETSCALER_1_0)
1375 if (nstrace->page_offset + phdr->caplen >= nstrace->page_len)
1377 /* Start on the next page */
1378 if (fseek(wdh->fh, (nstrace->page_len - nstrace->page_offset), SEEK_CUR) == -1)
1384 nstrace->page_offset = 0;
1386 /* Possibly add signature and abstime records and increment offset */
1387 if (!nstrace_add_signature(wdh, err))
1391 /* Write the actual record as is */
1392 if (!wtap_dump_file_write(wdh, pd, phdr->caplen, err))
1395 nstrace->page_offset += (guint16) phdr->caplen;
1396 } else if (wdh->file_type == WTAP_FILE_NETSCALER_2_0)
1398 *err = WTAP_ERR_UNSUPPORTED_FILE_TYPE;
1404 case NSPR_HEADER_VERSION200:
1405 case NSPR_HEADER_VERSION201:
1406 case NSPR_HEADER_VERSION202:
1407 case NSPR_HEADER_VERSION203:
1408 case NSPR_HEADER_VERSION204:
1409 case NSPR_HEADER_VERSION205:
1410 if (wdh->file_type == WTAP_FILE_NETSCALER_1_0)
1412 *err = WTAP_ERR_UNSUPPORTED_FILE_TYPE;
1414 } else if (wdh->file_type == WTAP_FILE_NETSCALER_2_0)
1416 if (nstrace->page_offset + phdr->caplen >= nstrace->page_len)
1418 /* Start on the next page */
1419 if (fseek(wdh->fh, (nstrace->page_len - nstrace->page_offset), SEEK_CUR) == -1)
1425 nstrace->page_offset = 0;
1427 /* Possibly add signature and abstime records and increment offset */
1428 if (!nstrace_add_signature(wdh, err))
1432 /* Write the actual record as is */
1433 if (!wtap_dump_file_write(wdh, pd, phdr->caplen, err))
1436 nstrace->page_offset += (guint16) phdr->caplen;
1442 g_assert_not_reached();