nexmon – Blame information for rev 1

Subversion Repositories:
Rev:
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 */