d4c7b8b855540926e677b029a3fca83aacb305d0
[metze/wireshark/wip.git] / ui / cli / tap-protocolinfo.c
1 /* tap-protocolinfo.c
2  * protohierstat   2002 Ronnie Sahlberg
3  *
4  * Wireshark - Network traffic analyzer
5  * By Gerald Combs <gerald@wireshark.org>
6  * Copyright 1998 Gerald Combs
7  *
8  * SPDX-License-Identifier: GPL-2.0+*/
9
10 /* This module provides Protocol Column Info tap for tshark */
11
12 #include "config.h"
13
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17
18 #include "epan/epan_dissect.h"
19 #include "epan/column-utils.h"
20 #include <epan/tap.h>
21 #include <epan/stat_tap_ui.h>
22
23 void register_tap_listener_protocolinfo(void);
24
25 typedef struct _pci_t {
26         char *filter;
27         int hf_index;
28 } pci_t;
29
30
31 static int
32 protocolinfo_packet(void *prs, packet_info *pinfo, epan_dissect_t *edt, const void *dummy _U_)
33 {
34         pci_t *rs = (pci_t *)prs;
35         GPtrArray *gp;
36         guint i;
37         char *str;
38
39         /*
40          * XXX - there needs to be a way for "protocolinfo_init()" to
41          * find out whether the columns are being generated and, if not,
42          * to report an error and exit, as the whole point of this tap
43          * is to modify the columns, and if the columns aren't being
44          * displayed, that makes this tap somewhat pointless.
45          *
46          * To prevent a crash, we check whether INFO column is writable
47          * and, if not, we report that error and exit.
48          */
49         if (!col_get_writable(pinfo->cinfo, COL_INFO)) {
50                 fprintf(stderr, "tshark: the proto,colinfo tap doesn't work if the INFO column isn't being printed.\n");
51                 exit(1);
52         }
53         gp = proto_get_finfo_ptr_array(edt->tree, rs->hf_index);
54         if (!gp) {
55                 return 0;
56         }
57
58         for (i=0; i<gp->len; i++) {
59                 str = (char *)proto_construct_match_selected_string((field_info *)gp->pdata[i], NULL);
60                 if (str) {
61                         col_append_fstr(pinfo->cinfo, COL_INFO, "  %s", str);
62                         wmem_free(NULL, str);
63                 }
64         }
65         return 0;
66 }
67
68
69
70 static void
71 protocolinfo_init(const char *opt_arg, void *userdata _U_)
72 {
73         pci_t *rs;
74         const char *field = NULL;
75         const char *filter = NULL;
76         header_field_info *hfi;
77         GString *error_string;
78
79         if (!strncmp("proto,colinfo,", opt_arg, 14)) {
80                 filter = opt_arg+14;
81                 field = strchr(filter, ',');
82                 if (field) {
83                         field += 1;  /* skip the ',' */
84                 }
85         }
86         if (!field) {
87                 fprintf(stderr, "tshark: invalid \"-z proto,colinfo,<filter>,<field>\" argument\n");
88                 exit(1);
89         }
90
91         hfi = proto_registrar_get_byname(field);
92         if (!hfi) {
93                 fprintf(stderr, "tshark: Field \"%s\" doesn't exist.\n", field);
94                 exit(1);
95         }
96
97         rs = g_new(pci_t, 1);
98         rs->hf_index = hfi->id;
99         if ((field-filter) > 1) {
100                 rs->filter = (char *)g_malloc(field-filter);
101                 g_strlcpy(rs->filter, filter, (field-filter));
102         } else {
103                 rs->filter = NULL;
104         }
105
106         error_string = register_tap_listener("frame", rs, rs->filter, TL_REQUIRES_PROTO_TREE, NULL, protocolinfo_packet, NULL);
107         if (error_string) {
108                 /* error, we failed to attach to the tap. complain and clean up */
109                 fprintf(stderr, "tshark: Couldn't register proto,colinfo tap: %s\n",
110                     error_string->str);
111                 g_string_free(error_string, TRUE);
112                 g_free(rs->filter);
113                 g_free(rs);
114
115                 exit(1);
116         }
117 }
118
119 static stat_tap_ui protocolinfo_ui = {
120         REGISTER_STAT_GROUP_GENERIC,
121         NULL,
122         "proto,colinfo",
123         protocolinfo_init,
124         0,
125         NULL
126 };
127
128 void
129 register_tap_listener_protocolinfo(void)
130 {
131         register_stat_tap_ui(&protocolinfo_ui, NULL);
132 }
133
134 /*
135  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
136  *
137  * Local variables:
138  * c-basic-offset: 8
139  * tab-width: 8
140  * indent-tabs-mode: t
141  * End:
142  *
143  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
144  * :indentSize=8:tabSize=8:noTabs=false:
145  */