fix doxygen generation
[obnox/wireshark/wip.git] / tap-h225counter.c
1 /* tap_h225counter.c
2  * h225 message counter for ethereal
3  * Copyright 2003 Lars Roland
4  *
5  * $Id$
6  *
7  * Ethereal - Network traffic analyzer
8  * By Gerald Combs <gerald@ethereal.com>
9  * Copyright 1998 Gerald Combs
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24  */
25
26 /* With MSVC and a libethereal.dll this file needs to import some variables 
27    in a special way. Therefore _NEED_VAR_IMPORT_ is defined. */  
28 #define _NEED_VAR_IMPORT_
29
30 #ifdef HAVE_CONFIG_H
31 # include "config.h"
32 #endif
33
34 #include <stdio.h>
35
36 #ifdef HAVE_SYS_TYPES_H
37 # include <sys/types.h>
38 #endif
39
40 #include <string.h>
41 #include "epan/packet_info.h"
42 #include <epan/tap.h>
43 #include "epan/value_string.h"
44 #include "register.h"
45 #include <epan/dissectors/packet-h225.h>
46
47 /* following values represent the size of their valuestring arrays */
48
49 #define RAS_MSG_TYPES 33
50 #define CS_MSG_TYPES 13
51
52 #define GRJ_REASONS 8
53 #define RRJ_REASONS 18
54 #define URQ_REASONS 6
55 #define URJ_REASONS 6
56 #define ARJ_REASONS 22
57 #define BRJ_REASONS 8
58 #define DRQ_REASONS 3
59 #define DRJ_REASONS 4
60 #define LRJ_REASONS 16
61 #define IRQNAK_REASONS 4
62 #define REL_CMP_REASONS 26
63 #define FACILITY_REASONS 11
64
65
66 /* used to keep track of the statistics for an entire program interface */
67 typedef struct _h225counter_t {
68         char *filter;
69         guint32 ras_msg[RAS_MSG_TYPES + 1];
70         guint32 cs_msg[CS_MSG_TYPES + 1];
71         guint32 grj_reason[GRJ_REASONS + 1];
72         guint32 rrj_reason[RRJ_REASONS + 1];
73         guint32 urq_reason[URQ_REASONS + 1];
74         guint32 urj_reason[URJ_REASONS + 1];
75         guint32 arj_reason[ARJ_REASONS + 1];
76         guint32 brj_reason[BRJ_REASONS + 1];
77         guint32 drq_reason[DRQ_REASONS + 1];
78         guint32 drj_reason[DRJ_REASONS + 1];
79         guint32 lrj_reason[LRJ_REASONS + 1];
80         guint32 irqnak_reason[IRQNAK_REASONS + 1];
81         guint32 rel_cmp_reason[REL_CMP_REASONS + 1];
82         guint32 facility_reason[FACILITY_REASONS + 1];
83 } h225counter_t;
84
85
86 static void
87 h225counter_reset(void *phs)
88 {
89         h225counter_t *hs=(h225counter_t *)phs;
90         int i;
91
92         for(i=0;i<=RAS_MSG_TYPES;i++) {
93                 hs->ras_msg[i] = 0;
94         }
95         for(i=0;i<=CS_MSG_TYPES;i++) {
96                 hs->cs_msg[i] = 0;
97         }
98         for(i=0;i<=GRJ_REASONS;i++) {
99                 hs->grj_reason[i] = 0;
100         }
101         for(i=0;i<=RRJ_REASONS;i++) {
102                 hs->rrj_reason[i] = 0;
103         }
104         for(i=0;i<=URQ_REASONS;i++) {
105                 hs->urq_reason[i] = 0;
106         }
107         for(i=0;i<=URJ_REASONS;i++) {
108                 hs->urj_reason[i] = 0;
109         }
110         for(i=0;i<=ARJ_REASONS;i++) {
111                 hs->arj_reason[i] = 0;
112         }
113         for(i=0;i<=BRJ_REASONS;i++) {
114                 hs->brj_reason[i] = 0;
115         }
116         for(i=0;i<=DRQ_REASONS;i++) {
117                 hs->drq_reason[i] = 0;
118         }
119         for(i=0;i<=DRJ_REASONS;i++) {
120                 hs->drj_reason[i] = 0;
121         }
122         for(i=0;i<=LRJ_REASONS;i++) {
123                 hs->lrj_reason[i] = 0;
124         }
125         for(i=0;i<=IRQNAK_REASONS;i++) {
126                 hs->irqnak_reason[i] = 0;
127         }
128         for(i=0;i<=REL_CMP_REASONS;i++) {
129                 hs->rel_cmp_reason[i] = 0;
130         }
131         for(i=0;i<=FACILITY_REASONS;i++) {
132                 hs->facility_reason[i] = 0;
133         }
134 }
135
136 static int
137 h225counter_packet(void *phs, packet_info *pinfo _U_, epan_dissect_t *edt _U_, void *phi)
138 {
139         h225counter_t *hs=(h225counter_t *)phs;
140         h225_packet_info *pi=phi;
141
142         switch (pi->msg_type) {
143
144         case H225_RAS:
145                 if(pi->msg_tag==-1) { /* uninitialized */
146                         return 0;
147                 }
148                 else if (pi->msg_tag >= RAS_MSG_TYPES) { /* unknown */
149                         hs->ras_msg[RAS_MSG_TYPES]++;
150                 }
151                 else {
152                         hs->ras_msg[pi->msg_tag]++;
153                 }
154
155                 /* Look for reason tag */
156                 if(pi->reason==-1) { /* uninitialized */
157                         break;
158                 }
159
160                 switch(pi->msg_tag) {
161
162                 case 2: /* GRJ */
163                         if(pi->reason < GRJ_REASONS)
164                                 hs->grj_reason[pi->reason]++;
165                         else
166                                 hs->grj_reason[GRJ_REASONS]++;
167                         break;
168                 case 5: /* RRJ */
169                         if(pi->reason < RRJ_REASONS)
170                                 hs->rrj_reason[pi->reason]++;
171                         else
172                                 hs->rrj_reason[RRJ_REASONS]++;
173                         break;
174                 case 6: /* URQ */
175                         if(pi->reason < URQ_REASONS)
176                                 hs->urq_reason[pi->reason]++;
177                         else
178                                 hs->urq_reason[URQ_REASONS]++;
179                         break;
180                 case 8: /* URJ */
181                         if(pi->reason < URJ_REASONS)
182                                 hs->urj_reason[pi->reason]++;
183                         else
184                                 hs->urj_reason[URJ_REASONS]++;
185                         break;
186                 case 11: /* ARJ */
187                         if(pi->reason < ARJ_REASONS)
188                                 hs->arj_reason[pi->reason]++;
189                         else
190                                 hs->arj_reason[ARJ_REASONS]++;
191                         break;
192                 case 14: /* BRJ */
193                         if(pi->reason < BRJ_REASONS)
194                                 hs->brj_reason[pi->reason]++;
195                         else
196                                 hs->brj_reason[BRJ_REASONS]++;
197                         break;
198                 case 15: /* DRQ */
199                         if(pi->reason < DRQ_REASONS)
200                                 hs->drq_reason[pi->reason]++;
201                         else
202                                 hs->drq_reason[DRQ_REASONS]++;
203                         break;
204                 case 17: /* DRJ */
205                         if(pi->reason < DRJ_REASONS)
206                                 hs->drj_reason[pi->reason]++;
207                         else
208                                 hs->drj_reason[DRJ_REASONS]++;
209                         break;
210                 case 20: /* LRJ */
211                         if(pi->reason < LRJ_REASONS)
212                                 hs->lrj_reason[pi->reason]++;
213                         else
214                                 hs->lrj_reason[LRJ_REASONS]++;
215                         break;
216                 case 29: /* IRQ Nak */
217                         if(pi->reason < IRQNAK_REASONS)
218                                 hs->irqnak_reason[pi->reason]++;
219                         else
220                                 hs->irqnak_reason[IRQNAK_REASONS]++;
221                         break;
222
223                 default:
224                         /* do nothing */
225                         break;
226                 }
227
228                 break;
229
230         case H225_CS:
231                 if(pi->msg_tag==-1) { /* uninitialized */
232                         return 0;
233                 }
234                 else if (pi->msg_tag >= CS_MSG_TYPES) { /* unknown */
235                         hs->cs_msg[CS_MSG_TYPES]++;
236                 }
237                 else {
238                         hs->cs_msg[pi->msg_tag]++;
239                 }
240
241                 /* Look for reason tag */
242                 if(pi->reason==-1) { /* uninitialized */
243                         break;
244                 }
245
246                 switch(pi->msg_tag) {
247
248                 case 5: /* ReleaseComplete */
249                         if(pi->reason < REL_CMP_REASONS)
250                                 hs->rel_cmp_reason[pi->reason]++;
251                         else
252                                 hs->rel_cmp_reason[REL_CMP_REASONS]++;
253                         break;
254                 case 6: /* Facility */
255                         if(pi->reason < FACILITY_REASONS)
256                                 hs->facility_reason[pi->reason]++;
257                         else
258                                 hs->facility_reason[FACILITY_REASONS]++;
259                         break;
260                 default:
261                         /* do nothing */
262                         break;
263                 }
264
265                 break;
266
267         default:
268                 return 0;
269                 break;
270         }
271
272         return 1;
273 }
274
275
276 static void
277 h225counter_draw(void *phs)
278 {
279         h225counter_t *hs=(h225counter_t *)phs;
280         int i,j;
281
282         printf("================== H225 Message and Reason Counter ==================\n");
283         printf("RAS-Messages:\n");
284         for(i=0;i<=RAS_MSG_TYPES;i++) {
285                 if(hs->ras_msg[i]!=0) {
286                         printf("  %s : %u\n", val_to_str(i,RasMessage_vals,"unknown ras-messages  "), hs->ras_msg[i]);
287                         /* reason counter */
288                         switch(i) {
289                         case 2: /* GRJ */
290                                 for(j=0;j<=GRJ_REASONS;j++) {
291                                         if(hs->grj_reason[j]!=0) {
292                                                 printf("    %s : %u\n", val_to_str(j,GatekeeperRejectReason_vals,"unknown reason   "), hs->grj_reason[j]);
293                                         }
294                                 }
295                                 break;
296                         case 5: /* RRJ */
297                                 for(j=0;j<=RRJ_REASONS;j++) {
298                                         if(hs->rrj_reason[j]!=0) {
299                                                 printf("    %s : %u\n", val_to_str(j,RegistrationRejectReason_vals,"unknown reason   "), hs->rrj_reason[j]);
300                                         }
301                                 }
302                                 break;
303                         case 6: /* URQ */
304                                 for(j=0;j<=URQ_REASONS;j++) {
305                                         if(hs->urq_reason[j]!=0) {
306                                                 printf("    %s : %u\n", val_to_str(j,UnregRequestReason_vals,"unknown reason   "), hs->urq_reason[j]);
307                                         }
308                                 }
309                                 break;
310                         case 8: /* URJ */
311                                 for(j=0;j<=URJ_REASONS;j++) {
312                                         if(hs->urj_reason[j]!=0) {
313                                                 printf("    %s : %u\n", val_to_str(j,UnregRejectReason_vals,"unknown reason   "), hs->urj_reason[j]);
314                                         }
315                                 }
316                                 break;
317                         case 11: /* ARJ */
318                                 for(j=0;j<=ARJ_REASONS;j++) {
319                                         if(hs->arj_reason[j]!=0) {
320                                                 printf("    %s : %u\n", val_to_str(j,AdmissionRejectReason_vals,"unknown reason   "), hs->arj_reason[j]);
321                                         }
322                                 }
323                                 break;
324                         case 14: /* BRJ */
325                                 for(j=0;j<=BRJ_REASONS;j++) {
326                                         if(hs->brj_reason[j]!=0) {
327                                                 printf("    %s : %u\n", val_to_str(j,BandRejectReason_vals,"unknown reason   "), hs->brj_reason[j]);
328                                         }
329                                 }
330                                 break;
331                         case 15: /* DRQ */
332                                 for(j=0;j<=DRQ_REASONS;j++) {
333                                         if(hs->drq_reason[j]!=0) {
334                                                 printf("    %s : %u\n", val_to_str(j,DisengageReason_vals,"unknown reason   "), hs->drq_reason[j]);
335                                         }
336                                 }
337                                 break;
338                         case 17: /* DRJ */
339                                 for(j=0;j<=DRJ_REASONS;j++) {
340                                         if(hs->drj_reason[j]!=0) {
341                                                 printf("    %s : %u\n", val_to_str(j,DisengageRejectReason_vals,"unknown reason   "), hs->drj_reason[j]);
342                                         }
343                                 }
344                                 break;
345                         case 20: /* LRJ */
346                                 for(j=0;j<=LRJ_REASONS;j++) {
347                                         if(hs->lrj_reason[j]!=0) {
348                                                 printf("    %s : %u\n", val_to_str(j,LocationRejectReason_vals,"unknown reason   "), hs->lrj_reason[j]);
349                                         }
350                                 }
351                         case 29: /* IRQNak */
352                                 for(j=0;j<=IRQNAK_REASONS;j++) {
353                                         if(hs->irqnak_reason[j]!=0) {
354                                                 printf("    %s : %u\n", val_to_str(j,InfoRequestNakReason_vals,"unknown reason   "), hs->irqnak_reason[j]);
355                                         }
356                                 }
357                                 break;
358                         default:
359                                 break;
360                         }
361                         /* end of reason counter*/
362                 }
363         }
364         printf("Call Signalling:\n");
365         for(i=0;i<=CS_MSG_TYPES;i++) {
366                 if(hs->cs_msg[i]!=0) {
367                         printf("  %s : %u\n", val_to_str(i,h323_message_body_vals,"unknown cs-messages   "), hs->cs_msg[i]);
368                         /* reason counter */
369                         switch(i) {
370                         case 5: /* ReleaseComplete */
371                                 for(j=0;j<=REL_CMP_REASONS;j++) {
372                                         if(hs->rel_cmp_reason[j]!=0) {
373                                                 printf("    %s : %u\n", val_to_str(j,ReleaseCompleteReason_vals,"unknown reason   "), hs->rel_cmp_reason[j]);
374                                         }
375                                 }
376                                 break;
377                         case 6: /* Facility */
378                                 for(j=0;j<=FACILITY_REASONS;j++) {
379                                         if(hs->facility_reason[j]!=0) {
380                                                 printf("    %s : %u\n", val_to_str(j,FacilityReason_vals,"unknown reason   "), hs->facility_reason[j]);
381                                         }
382                                 }
383                                 break;
384                         default:
385                                 break;
386                         }
387                 }
388         }
389         printf("=====================================================================\n");
390 }
391
392
393 static void
394 h225counter_init(char *optarg)
395 {
396         h225counter_t *hs;
397         char *filter=NULL;
398         GString *error_string;
399
400         if(!strncmp(optarg,"h225,counter,",13)){
401                 filter=optarg+13;
402         } else {
403                 filter=g_malloc(1);
404                 *filter='\0';
405         }
406
407         hs = g_malloc(sizeof(h225counter_t));
408         hs->filter=g_malloc(strlen(filter)+1);
409         strcpy(hs->filter, filter);
410
411         h225counter_reset(hs);
412
413         error_string=register_tap_listener("h225", hs, filter, NULL, h225counter_packet, h225counter_draw);
414         if(error_string){
415                 /* error, we failed to attach to the tap. clean up */
416                 g_free(hs->filter);
417                 g_free(hs);
418
419                 fprintf(stderr, "tethereal: Couldn't register h225,counter tap: %s\n",
420                     error_string->str);
421                 g_string_free(error_string, TRUE);
422                 exit(1);
423         }
424 }
425
426
427 void
428 register_tap_listener_h225counter(void)
429 {
430         register_ethereal_tap("h225,counter", h225counter_init);
431 }