From Chris Hellberg via https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=8723 :
[metze/wireshark/wip.git] / tap-megaco-common.c
1 /* megaco_stat.c
2  * megaco-statistics for Wireshark
3  * Copyright 2003 Lars Roland
4  * Copyright 2008 Ericsson AB
5  * By Balint Reczey <balint.reczey@ericsson.com>
6  *
7  * $Id$
8  *
9  * Wireshark - Network traffic analyzer
10  * By Gerald Combs <gerald@wireshark.org>
11  * Copyright 1998 Gerald Combs
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26  */
27
28 #include "config.h"
29
30 #include <string.h>
31
32 #include <epan/packet_info.h>
33 #include <epan/epan.h>
34 #include <epan/value_string.h>
35 #include <epan/tap.h>
36 #include "epan/gcp.h"
37
38 #include "../timestats.h"
39 #include "../file.h"
40 #include "../globals.h"
41 #include "../stat_menu.h"
42
43 #include "tap-megaco-common.h"
44
45 static gboolean
46 megacostat_is_duplicate_reply(const gcp_cmd_t* cmd)
47 {
48         switch (cmd->type) {
49
50         GCP_CMD_REPLY_CASE
51                 {
52                         gcp_cmd_msg_t *cmd_msg;
53                         /* cycle through commands to find same command in the transaction */
54                         for (cmd_msg = cmd->trx->cmds;
55                              (cmd_msg != NULL) && (cmd_msg->cmd->msg->framenum != cmd->msg->framenum);
56                              cmd_msg = cmd_msg->next) {
57                                 if (cmd_msg->cmd->type == cmd->type)
58                                         return TRUE;
59                         }
60
61                         return FALSE;
62                 }
63                 break;
64         default:
65                 return FALSE;
66                 break;
67         }
68
69
70 }
71
72 static gboolean
73 megacostat_had_request(const gcp_cmd_t* cmd)
74 {
75         switch (cmd->type) {
76
77         GCP_CMD_REPLY_CASE
78                 {
79                         gcp_cmd_msg_t *cmd_msg;
80                         /* cycle through commands to find a request in the transaction */
81                         for (cmd_msg = cmd->trx->cmds;
82                              (cmd_msg != NULL) && (cmd_msg->cmd->msg->framenum != cmd->msg->framenum);
83                              cmd_msg = cmd_msg->next) {
84
85                                 switch (cmd_msg->cmd->type) {
86
87                                 GCP_CMD_REQ_CASE
88                                         return TRUE;
89                                         break;
90                                 default:
91                                         return FALSE;
92                                         break;
93                                 }
94                         }
95
96                         return FALSE;
97                 }
98                 break;
99         default:
100                 return FALSE;
101                 break;
102         }
103 }
104
105 int
106 megacostat_packet(void *pms, packet_info *pinfo, epan_dissect_t *edt _U_, const void *pmi)
107 {
108         megacostat_t *ms=(megacostat_t *)pms;
109         const gcp_cmd_t *mi=(const gcp_cmd_t*)pmi;
110         nstime_t delta;
111         int ret = 0;
112
113         switch (mi->type) {
114
115         GCP_CMD_REQ_CASE
116                 if(!mi->trx->initial) {
117                         /* Track Context is probably disabled, we cannot
118                          * measure service response time */
119                         return 0;
120                 }
121
122                 else if(mi->trx->initial->framenum != mi->msg->framenum){
123                         /* Duplicate is ignored */
124                         ms->req_dup_num++;
125                 }
126                 else {
127                         ms->open_req_num++;
128                 }
129                 break;
130
131         GCP_CMD_REPLY_CASE
132                 if(megacostat_is_duplicate_reply(mi)){
133                         /* Duplicate is ignored */
134                         ms->rsp_dup_num++;
135                 }
136                 else if (!megacostat_had_request(mi)) {
137                         /* no request was seen */
138                         ms->disc_rsp_num++;
139                 }
140                 else {
141                         ms->open_req_num--;
142                         /* calculate time delta between request and response */
143                         nstime_delta(&delta, &pinfo->fd->abs_ts, &mi->trx->initial->time);
144
145                         switch(mi->type) {
146
147                         case GCP_CMD_ADD_REPLY:
148                                 time_stat_update(&(ms->rtd[0]),&delta, pinfo);
149                                 break;
150                         case GCP_CMD_MOVE_REPLY:
151                                 time_stat_update(&(ms->rtd[1]),&delta, pinfo);
152                                 break;
153                         case GCP_CMD_MOD_REPLY:
154                                 time_stat_update(&(ms->rtd[2]),&delta, pinfo);
155                                 break;
156                         case GCP_CMD_SUB_REPLY:
157                                 time_stat_update(&(ms->rtd[3]),&delta, pinfo);
158                                 break;
159                         case GCP_CMD_AUDITCAP_REPLY:
160                                 time_stat_update(&(ms->rtd[4]),&delta, pinfo);
161                                 break;
162                         case GCP_CMD_AUDITVAL_REPLY:
163                                 time_stat_update(&(ms->rtd[5]),&delta, pinfo);
164                                 break;
165                         case GCP_CMD_NOTIFY_REPLY:
166                                 time_stat_update(&(ms->rtd[6]),&delta, pinfo);
167                                 break;
168                         case GCP_CMD_SVCCHG_REPLY:
169                                 time_stat_update(&(ms->rtd[7]),&delta, pinfo);
170                                 break;
171                         case GCP_CMD_TOPOLOGY_REPLY:
172                                 time_stat_update(&(ms->rtd[8]),&delta, pinfo);
173                                 break;
174                         case GCP_CMD_REPLY:
175                                 time_stat_update(&(ms->rtd[9]),&delta, pinfo);
176                                 break;
177                         default:
178                                 time_stat_update(&(ms->rtd[11]),&delta, pinfo);
179                         }
180                         time_stat_update(&(ms->rtd[10]),&delta, pinfo);
181
182                         ret = 1;
183                 }
184                 break;
185
186         default:
187                 break;
188         }
189
190         return ret;
191 }
192