2 * Copied from gtk/conversations_table.c 2003 Ronnie Sahlberg
3 * Helper routines common to all conversations taps.
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later*/
14 #include "traffic_table_ui.h"
15 #include <wsutil/utf8_entities.h>
19 #include "epan/address.h"
20 #include "epan/addr_resolv.h"
21 #include "epan/geoip_db.h"
22 #include "epan/strutil.h"
23 #include "wsutil/pint.h"
24 #include "wsutil/str_util.h"
26 #include "epan/packet_info.h"
27 #include "epan/conversation_table.h"
31 #include "wsutil/filesystem.h"
32 #include "wsutil/file_util.h"
33 #include "wsutil/tempfile.h"
36 const char *conv_column_titles[CONV_NUM_COLUMNS] = {
43 "Packets A " UTF8_RIGHTWARDS_ARROW " B",
44 "Bytes A " UTF8_RIGHTWARDS_ARROW " B",
45 "Packets B " UTF8_RIGHTWARDS_ARROW " A",
46 "Bytes B " UTF8_RIGHTWARDS_ARROW " A",
49 "Bits/s A " UTF8_RIGHTWARDS_ARROW " B",
50 "Bits/s B " UTF8_RIGHTWARDS_ARROW " A"
53 const char *conv_conn_a_title = "Connection A";
54 const char *conv_conn_b_title = "Connection B";
55 const char *conv_abs_start_title = "Abs Start";
57 const char *endp_column_titles[ENDP_NUM_COLUMNS] = {
68 const char *endp_conn_title = "Connection";
71 #define MAX_TPL_LINE_LEN 4096
73 create_endpoint_geoip_map(const GArray *endp_array, gchar **err_str) {
74 char *tpl_filename, *tpl_line;
75 FILE *tpl_file, *out_file;
77 gchar *map_filename = NULL;
81 int db_lon, db_lat, db_country4, db_country6, db_city4, db_city6, db_asn4, db_asn6;
83 const char *map_endpoint_opener = "{\n";
85 db_lon = db_lat = db_country4 = db_country6 = db_city4 = db_city6 = db_asn4 = db_asn6 = -1;
87 /* Create a location map HTML file from a template */
88 /* XXX - add error handling */
89 tpl_filename = get_datafile_path("ipmap.html");
90 tpl_file = ws_fopen(tpl_filename, "r");
91 if(tpl_file == NULL) {
93 GString *err_descr = g_string_new("");
94 g_string_printf(err_descr, file_open_error_message(errno, FALSE), tpl_filename);
95 *err_str = g_string_free(err_descr, FALSE);
100 g_free(tpl_filename);
103 /* We should probably create a file with a temporary name and a .html extension instead */
104 if (! create_tempdir(&map_path, "Wireshark IP Map ")) {
106 GString *err_descr = g_string_new("");
107 g_string_printf(err_descr, "Could not create temporary directory\n%s",
109 *err_str = g_string_free(err_descr, FALSE);
119 map_filename = g_strdup_printf("%s%cipmap.html", map_path, G_DIR_SEPARATOR);
120 out_file = ws_fopen(map_filename, "w");
121 if(out_file == NULL) {
123 GString *err_descr = g_string_new("");
124 g_string_printf(err_descr, file_open_error_message(errno, FALSE), map_filename);
125 *err_str = g_string_free(err_descr, FALSE);
127 g_free(map_filename);
132 tpl_line = (char *)g_malloc(MAX_TPL_LINE_LEN);
134 while (fgets(tpl_line, MAX_TPL_LINE_LEN, tpl_file) != NULL) {
135 fputs(tpl_line, out_file);
136 /* MUST match ipmap.html */
137 if (strstr(tpl_line, "// Start endpoint list")) {
142 for (cur_db = 0; cur_db < geoip_db_num_dbs(); cur_db++) {
143 switch (geoip_db_type(cur_db)) {
144 case WS_LON_FAKE_EDITION:
147 case WS_LAT_FAKE_EDITION:
150 case GEOIP_COUNTRY_EDITION:
151 db_country4 = cur_db;
153 case GEOIP_COUNTRY_EDITION_V6:
154 db_country6 = cur_db;
156 case GEOIP_CITY_EDITION_REV0:
157 case GEOIP_CITY_EDITION_REV1:
160 case GEOIP_CITY_EDITION_REV0_V6:
161 case GEOIP_CITY_EDITION_REV1_V6:
167 if(db_lon < 0 || db_lat < 0) {
169 *err_str = g_strdup("Unable to open GeoIP database");
171 /* We can't write the map file, so close it and get rid of it */
173 ws_unlink(map_filename);
174 g_free(map_filename);
180 /* Fill in our map data */
181 tpl_entry = g_string_new("");
183 for (i = 0; i < endp_array->len; i++) {
184 char *lat = NULL, *lon = NULL, *country = NULL, *city = NULL, *asn = NULL;
185 hostlist_talker_t *endp_item = &g_array_index(endp_array, hostlist_talker_t, i);
187 if (endp_item->myaddress.type == AT_IPv4) {
188 lon = geoip_db_lookup_ipv4(db_lon, pntoh32(endp_item->myaddress.data), NULL);
189 lat = geoip_db_lookup_ipv4(db_lat, pntoh32(endp_item->myaddress.data), NULL);
190 country = geoip_db_lookup_ipv4(db_country4, pntoh32(endp_item->myaddress.data), "-");
191 city = geoip_db_lookup_ipv4(db_city4, pntoh32(endp_item->myaddress.data), "-");
192 asn = geoip_db_lookup_ipv4(db_asn4, pntoh32(endp_item->myaddress.data), "-");
193 } else if (endp_item->myaddress.type == AT_IPv6) {
194 const ws_in6_addr *addr = (const ws_in6_addr *) endp_item->myaddress.data;
195 lon = geoip_db_lookup_ipv6(db_lon, *addr, NULL);
196 lat = geoip_db_lookup_ipv6(db_lat, *addr, NULL);
197 country = geoip_db_lookup_ipv6(db_country6, *addr, "-");
198 city = geoip_db_lookup_ipv6(db_city6, *addr, "-");
199 asn = geoip_db_lookup_ipv6(db_asn6, *addr, "-");
206 'type': 'Feature', 'geometry': { 'type': 'Point', 'coordinates': [-122.583889, 37.898889] },
207 'properties': { 'title': 'host.example.com', 'description': 'AS: AS12345 Ewok Holdings, Inc.<br/>Country: US<br/>City: Muir Woods, CA<br/>Packets: 6<br/>Bytes: 980' }
214 g_string_printf(tpl_entry, "%s", map_endpoint_opener);
216 /* Longitude + latitude */
217 g_string_append_printf(tpl_entry, " 'type': 'Feature', 'geometry': { 'type': 'Point', 'coordinates': [%s, %s] },\n", lon, lat);
220 addr_str = address_to_display(NULL, &endp_item->myaddress);
221 g_string_append_printf(tpl_entry, " 'properties': { 'title': '%s', ", addr_str);
222 wmem_free(NULL, addr_str);
227 esc_entry = string_replace(city, "'", "'");
228 g_string_append_printf(tpl_entry, "'description': '<div class=\"geoip_property\">City: %s</div>", esc_entry);
232 esc_entry = string_replace(country, "'", "'");
233 g_string_append_printf(tpl_entry, "<div class=\"geoip_property\">Country: %s</div>", esc_entry);
237 esc_entry = format_size(endp_item->tx_frames + endp_item->rx_frames,
238 (format_size_flags_e)(format_size_unit_none|format_size_prefix_si));
239 g_string_append_printf(tpl_entry, "<div class=\"geoip_property\">Packets: %s</div>", esc_entry);
243 esc_entry = format_size(endp_item->tx_bytes + endp_item->rx_bytes,
244 (format_size_flags_e)(format_size_unit_none|format_size_prefix_si));
245 g_string_append_printf(tpl_entry, "<div class=\"geoip_property\">Bytes: %s</div>", esc_entry);
249 esc_entry = string_replace(asn, "'", "'");
250 g_string_append_printf(tpl_entry, "<div class=\"geoip_property\">AS Number: %s</div>", esc_entry);
253 /* XXX - We could add specific icons, e.g. depending on the amount of packets or bytes */
254 g_string_append(tpl_entry, "' }\n");
255 g_string_append(tpl_entry, "}");
257 fputs(tpl_entry->str, out_file);
258 map_endpoint_opener = ",\n{\n";
261 wmem_free(NULL, lat);
262 wmem_free(NULL, lon);
263 wmem_free(NULL, country);
264 wmem_free(NULL, city);
265 wmem_free(NULL, asn);
267 /* XXX Display an error if we we have no entries */
270 while (fgets(tpl_line, MAX_TPL_LINE_LEN, tpl_file) != NULL) {
271 fputs(tpl_line, out_file);
290 * indent-tabs-mode: nil
293 * ex: set shiftwidth=4 tabstop=8 expandtab:
294 * :indentSize=4:tabSize=8:noTabs=true: