nexmon – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | /* io_graph_item.h |
2 | * Definitions and functions for IO graph items |
||
3 | * |
||
4 | * Copied from gtk/io_stat.c, (c) 2002 Ronnie Sahlberg |
||
5 | * |
||
6 | * Wireshark - Network traffic analyzer |
||
7 | * By Gerald Combs <gerald@wireshark.org> |
||
8 | * Copyright 1998 Gerald Combs |
||
9 | * |
||
10 | * This program is free software; you can redistribute it and/or |
||
11 | * modify it under the terms of the GNU General Public License |
||
12 | * as published by the Free Software Foundation; either version 2 |
||
13 | * of the License, or (at your option) any later version. |
||
14 | * |
||
15 | * This program is distributed in the hope that it will be useful, |
||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
18 | * GNU General Public License for more details. |
||
19 | * |
||
20 | * You should have received a copy of the GNU General Public License |
||
21 | * along with this program; if not, write to the Free Software |
||
22 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
||
23 | */ |
||
24 | |||
25 | #ifndef __IO_GRAPH_ITEM_H__ |
||
26 | #define __IO_GRAPH_ITEM_H__ |
||
27 | |||
28 | #ifdef __cplusplus |
||
29 | extern "C" { |
||
30 | #endif /* __cplusplus */ |
||
31 | |||
32 | typedef enum { |
||
33 | IOG_ITEM_UNIT_FIRST, |
||
34 | IOG_ITEM_UNIT_PACKETS = IOG_ITEM_UNIT_FIRST, |
||
35 | IOG_ITEM_UNIT_BYTES, |
||
36 | IOG_ITEM_UNIT_BITS, |
||
37 | IOG_ITEM_UNIT_CALC_SUM, |
||
38 | IOG_ITEM_UNIT_CALC_FRAMES, |
||
39 | IOG_ITEM_UNIT_CALC_FIELDS, |
||
40 | IOG_ITEM_UNIT_CALC_MAX, |
||
41 | IOG_ITEM_UNIT_CALC_MIN, |
||
42 | IOG_ITEM_UNIT_CALC_AVERAGE, |
||
43 | IOG_ITEM_UNIT_CALC_LOAD, |
||
44 | IOG_ITEM_UNIT_LAST = IOG_ITEM_UNIT_CALC_LOAD, |
||
45 | NUM_IOG_ITEM_UNITS |
||
46 | } io_graph_item_unit_t; |
||
47 | |||
48 | typedef struct _io_graph_item_t { |
||
49 | guint32 frames; /* always calculated, will hold number of frames*/ |
||
50 | guint64 bytes; /* always calculated, will hold number of bytes*/ |
||
51 | guint64 fields; |
||
52 | gint64 int_max; |
||
53 | gint64 int_min; |
||
54 | gint64 int_tot; |
||
55 | /* XXX - Why do we always use 64-bit ints but split floats between |
||
56 | * gfloat and gdouble? |
||
57 | */ |
||
58 | gfloat float_max; |
||
59 | gfloat float_min; |
||
60 | gfloat float_tot; |
||
61 | gdouble double_max; |
||
62 | gdouble double_min; |
||
63 | gdouble double_tot; |
||
64 | nstime_t time_max; |
||
65 | nstime_t time_min; |
||
66 | nstime_t time_tot; |
||
67 | guint32 first_frame_in_invl; |
||
68 | guint32 last_frame_in_invl; |
||
69 | } io_graph_item_t; |
||
70 | |||
71 | /** Reset (zero) an io_graph_item_t. |
||
72 | * |
||
73 | * @param items [in,out] Array containing the items to reset. |
||
74 | * @param count [in] The number of items in the array. |
||
75 | */ |
||
76 | static inline void |
||
77 | reset_io_graph_items(io_graph_item_t *items, gsize count) { |
||
78 | io_graph_item_t *item; |
||
79 | gsize i; |
||
80 | |||
81 | for (i = 0; i < count; i++) { |
||
82 | item = &items[i]; |
||
83 | |||
84 | item->frames = 0; |
||
85 | item->bytes = 0; |
||
86 | item->fields = 0; |
||
87 | item->int_max = 0; |
||
88 | item->int_min = 0; |
||
89 | item->int_tot = 0; |
||
90 | item->float_max = 0; |
||
91 | item->float_min = 0; |
||
92 | item->float_tot = 0; |
||
93 | item->double_max = 0; |
||
94 | item->double_min = 0; |
||
95 | item->double_tot = 0; |
||
96 | nstime_set_zero(&item->time_max); |
||
97 | nstime_set_zero(&item->time_min); |
||
98 | nstime_set_zero(&item->time_tot); |
||
99 | item->first_frame_in_invl = 0; |
||
100 | item->last_frame_in_invl = 0; |
||
101 | } |
||
102 | } |
||
103 | |||
104 | /** Get the interval (array index) for a packet |
||
105 | * |
||
106 | * It is up to the caller to determine if the return value is valid. |
||
107 | * |
||
108 | * @param [in] pinfo Packet of interest. |
||
109 | * @param [in] interval Time interval in milliseconds. |
||
110 | * @return Array index on success, -1 on failure. |
||
111 | */ |
||
112 | int get_io_graph_index(packet_info *pinfo, int interval); |
||
113 | |||
114 | /** Check field and item unit compatibility |
||
115 | * |
||
116 | * @param field_name [in] Header field name to check |
||
117 | * @param hf_index [out] Assigned the header field index corresponding to field_name if valid. |
||
118 | * Can be NULL. |
||
119 | * @param item_unit [in] The type of unit to calculate. From IOG_ITEM_UNITS. |
||
120 | * @return NULL if compatible, otherwise an error string. The string must |
||
121 | * be freed by the caller. |
||
122 | */ |
||
123 | GString *check_field_unit(const char *field_name, int *hf_index, io_graph_item_unit_t item_unit); |
||
124 | |||
125 | /** Update the values of an io_graph_item_t. |
||
126 | * |
||
127 | * Frame and byte counts are always calculated. If edt is non-NULL advanced |
||
128 | * statistics are calculated using hfindex. |
||
129 | * |
||
130 | * @param items [in,out] Array containing the item to update. |
||
131 | * @param idx [in] Index of the item to update. |
||
132 | * @param pinfo [in] Packet containing update information. |
||
133 | * @param edt [in] Dissection information for advanced statistics. May be NULL. |
||
134 | * @param hf_index [in] Header field index for advanced statistics. |
||
135 | * @param item_unit [in] The type of unit to calculate. From IOG_ITEM_UNITS. |
||
136 | * @param interval [in] Timing interval in ms. |
||
137 | * @return TRUE if the update was successful, otherwise FALSE. |
||
138 | */ |
||
139 | static inline gboolean |
||
140 | update_io_graph_item(io_graph_item_t *items, int idx, packet_info *pinfo, epan_dissect_t *edt, int hf_index, int item_unit, guint32 interval) { |
||
141 | io_graph_item_t *item = &items[idx]; |
||
142 | |||
143 | /* Set the first and last frame num in current interval matching the target field+filter */ |
||
144 | if (item->first_frame_in_invl == 0) { |
||
145 | item->first_frame_in_invl = pinfo->num; |
||
146 | } |
||
147 | item->last_frame_in_invl = pinfo->num; |
||
148 | |||
149 | if (edt && hf_index >= 0) { |
||
150 | GPtrArray *gp; |
||
151 | guint i; |
||
152 | |||
153 | gp = proto_get_finfo_ptr_array(edt->tree, hf_index); |
||
154 | if (!gp) { |
||
155 | return FALSE; |
||
156 | } |
||
157 | |||
158 | /* Update the appropriate counters. If fields == 0, this is the first seen |
||
159 | * value so set any min/max values accordingly. */ |
||
160 | for (i=0; i < gp->len; i++) { |
||
161 | int new_int; |
||
162 | gint64 new_int64; |
||
163 | float new_float; |
||
164 | double new_double; |
||
165 | nstime_t *new_time; |
||
166 | |||
167 | switch (proto_registrar_get_ftype(hf_index)) { |
||
168 | case FT_UINT8: |
||
169 | case FT_UINT16: |
||
170 | case FT_UINT24: |
||
171 | case FT_UINT32: |
||
172 | new_int = fvalue_get_uinteger(&((field_info *)gp->pdata[i])->value); |
||
173 | |||
174 | if ((new_int > item->int_max) || (item->fields == 0)) { |
||
175 | item->int_max = new_int; |
||
176 | } |
||
177 | if ((new_int < item->int_min) || (item->fields == 0)) { |
||
178 | item->int_min = new_int; |
||
179 | } |
||
180 | item->int_tot += new_int; |
||
181 | item->fields++; |
||
182 | break; |
||
183 | case FT_INT8: |
||
184 | case FT_INT16: |
||
185 | case FT_INT24: |
||
186 | case FT_INT32: |
||
187 | new_int = fvalue_get_sinteger(&((field_info *)gp->pdata[i])->value); |
||
188 | if ((new_int > item->int_max) || (item->fields == 0)) { |
||
189 | item->int_max = new_int; |
||
190 | } |
||
191 | if ((new_int < item->int_min) || (item->fields == 0)) { |
||
192 | item->int_min = new_int; |
||
193 | } |
||
194 | item->int_tot += new_int; |
||
195 | item->fields++; |
||
196 | break; |
||
197 | case FT_UINT40: |
||
198 | case FT_UINT48: |
||
199 | case FT_UINT56: |
||
200 | case FT_UINT64: |
||
201 | new_int64 = fvalue_get_uinteger64(&((field_info *)gp->pdata[i])->value); |
||
202 | if ((new_int64 > item->int_max) || (item->fields == 0)) { |
||
203 | item->int_max = new_int64; |
||
204 | } |
||
205 | if ((new_int64 < item->int_min) || (item->fields == 0)) { |
||
206 | item->int_min = new_int64; |
||
207 | } |
||
208 | item->int_tot += new_int64; |
||
209 | item->fields++; |
||
210 | break; |
||
211 | case FT_INT40: |
||
212 | case FT_INT48: |
||
213 | case FT_INT56: |
||
214 | case FT_INT64: |
||
215 | new_int64 = fvalue_get_sinteger64(&((field_info *)gp->pdata[i])->value); |
||
216 | if ((new_int64 > item->int_max) || (item->fields == 0)) { |
||
217 | item->int_max = new_int64; |
||
218 | } |
||
219 | if ((new_int64 < item->int_min) || (item->fields == 0)) { |
||
220 | item->int_min = new_int64; |
||
221 | } |
||
222 | item->int_tot += new_int64; |
||
223 | item->fields++; |
||
224 | break; |
||
225 | case FT_FLOAT: |
||
226 | new_float = (gfloat)fvalue_get_floating(&((field_info *)gp->pdata[i])->value); |
||
227 | if ((new_float > item->float_max) || (item->fields == 0)) { |
||
228 | item->float_max = new_float; |
||
229 | } |
||
230 | if ((new_float < item->float_min) || (item->fields == 0)) { |
||
231 | item->float_min = new_float; |
||
232 | } |
||
233 | item->float_tot += new_float; |
||
234 | item->fields++; |
||
235 | break; |
||
236 | case FT_DOUBLE: |
||
237 | new_double = fvalue_get_floating(&((field_info *)gp->pdata[i])->value); |
||
238 | if ((new_double > item->double_max) || (item->fields == 0)) { |
||
239 | item->double_max = new_double; |
||
240 | } |
||
241 | if ((new_double < item->double_min) || (item->fields == 0)) { |
||
242 | item->double_min = new_double; |
||
243 | } |
||
244 | item->double_tot += new_double; |
||
245 | item->fields++; |
||
246 | break; |
||
247 | case FT_RELATIVE_TIME: |
||
248 | new_time = (nstime_t *)fvalue_get(&((field_info *)gp->pdata[i])->value); |
||
249 | |||
250 | switch (item_unit) { |
||
251 | guint64 t, pt; /* time in us */ |
||
252 | int j; |
||
253 | case IOG_ITEM_UNIT_CALC_LOAD: |
||
254 | /* |
||
255 | * Add the time this call spanned each interval according to its contribution |
||
256 | * to that interval. |
||
257 | */ |
||
258 | t = new_time->secs; |
||
259 | t = t * 1000000 + new_time->nsecs / 1000; |
||
260 | j = idx; |
||
261 | /* |
||
262 | * Handle current interval */ |
||
263 | pt = pinfo->rel_ts.secs * 1000000 + pinfo->rel_ts.nsecs / 1000; |
||
264 | pt = pt % (interval * 1000); |
||
265 | if (pt > t) { |
||
266 | pt = t; |
||
267 | } |
||
268 | while (t) { |
||
269 | io_graph_item_t *load_item; |
||
270 | |||
271 | load_item = &items[j]; |
||
272 | load_item->time_tot.nsecs += (int) (pt * 1000); |
||
273 | if (load_item->time_tot.nsecs > 1000000000) { |
||
274 | load_item->time_tot.secs++; |
||
275 | load_item->time_tot.nsecs -= 1000000000; |
||
276 | } |
||
277 | |||
278 | if (j == 0) { |
||
279 | break; |
||
280 | } |
||
281 | j--; |
||
282 | t -= pt; |
||
283 | if (t > (guint64) interval * 1000) { |
||
284 | pt = (guint64) interval * 1000; |
||
285 | } else { |
||
286 | pt = t; |
||
287 | } |
||
288 | } |
||
289 | break; |
||
290 | default: |
||
291 | if ( (new_time->secs > item->time_max.secs) |
||
292 | || ( (new_time->secs == item->time_max.secs) |
||
293 | && (new_time->nsecs > item->time_max.nsecs)) |
||
294 | || (item->fields == 0)) { |
||
295 | item->time_max = *new_time; |
||
296 | } |
||
297 | if ( (new_time->secs<item->time_min.secs) |
||
298 | || ( (new_time->secs == item->time_min.secs) |
||
299 | && (new_time->nsecs < item->time_min.nsecs)) |
||
300 | || (item->fields == 0)) { |
||
301 | item->time_min = *new_time; |
||
302 | } |
||
303 | nstime_add(&item->time_tot, new_time); |
||
304 | item->fields++; |
||
305 | } |
||
306 | break; |
||
307 | default: |
||
308 | if ((item_unit == IOG_ITEM_UNIT_CALC_FRAMES) || |
||
309 | (item_unit == IOG_ITEM_UNIT_CALC_FIELDS)) { |
||
310 | /* |
||
311 | * It's not an integeresque type, but |
||
312 | * all we want to do is count it, so |
||
313 | * that's all right. |
||
314 | */ |
||
315 | item->fields++; |
||
316 | } |
||
317 | else { |
||
318 | /* |
||
319 | * "Can't happen"; see the "check that the |
||
320 | * type is compatible" check in |
||
321 | * filter_callback(). |
||
322 | */ |
||
323 | g_assert_not_reached(); |
||
324 | } |
||
325 | break; |
||
326 | } |
||
327 | } |
||
328 | } |
||
329 | |||
330 | item->frames++; |
||
331 | item->bytes += pinfo->fd->pkt_len; |
||
332 | |||
333 | return TRUE; |
||
334 | } |
||
335 | |||
336 | |||
337 | #ifdef __cplusplus |
||
338 | } |
||
339 | #endif /* __cplusplus */ |
||
340 | |||
341 | #endif /* __IO_GRAPH_ITEM_H__ */ |
||
342 | |||
343 | /* |
||
344 | * Editor modelines |
||
345 | * |
||
346 | * Local Variables: |
||
347 | * c-basic-offset: 4 |
||
348 | * tab-width: 8 |
||
349 | * indent-tabs-mode: nil |
||
350 | * End: |
||
351 | * |
||
352 | * ex: set shiftwidth=4 tabstop=8 expandtab: |
||
353 | * :indentSize=4:tabSize=8:noTabs=true: |
||
354 | */ |