wslua: fix nstime memory leak after passing unknown encoding to TvbRange_nstime()
[metze/wireshark/wip.git] / epan / geoip_db.c
1 /* geoip_db.c
2  * GeoIP database support
3  *
4  * Copyright 2008, Gerald Combs <gerald@wireshark.org>
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 /* To do:
26  * We currently return a single string for each database. Some databases,
27  * e.g. GeoIPCity, can return other info such as area codes.
28  */
29
30 #include "config.h"
31
32 #include <glib.h>
33
34 #include <epan/wmem/wmem.h>
35
36 #ifdef HAVE_GEOIP
37 #include <GeoIP.h>
38 #include <GeoIPCity.h>
39
40 #include <epan/geoip_db.h>
41 #include <epan/uat.h>
42 #include <epan/prefs.h>
43 #include <epan/value_string.h>
44
45 #include <wsutil/report_message.h>
46 #include <wsutil/file_util.h>
47
48 /* This needs to match NUM_GEOIP_COLS in hostlist_table.h */
49 #define MAX_GEOIP_DBS 13
50
51 /*
52  * GeoIP_free is patched into our GeoIP distribution on Windows.
53  * See bug 13598.
54  */
55 #ifndef HAVE_GEOIP_FREE
56 #define GeoIP_free  free
57 #endif
58
59 /* Column names for each database type */
60 value_string geoip_type_name_vals[] = {
61     { GEOIP_COUNTRY_EDITION,        "Country" },
62     { GEOIP_REGION_EDITION_REV0,    "Region" },
63     { GEOIP_CITY_EDITION_REV0,      "City"},
64     { GEOIP_ORG_EDITION,            "Organization" },
65     { GEOIP_ISP_EDITION,            "ISP" },
66     { GEOIP_CITY_EDITION_REV1,      "City" },
67     { GEOIP_REGION_EDITION_REV1,    "Region" },
68     { GEOIP_PROXY_EDITION,          "Proxy" },
69     { GEOIP_ASNUM_EDITION,          "AS Number" },
70     { GEOIP_NETSPEED_EDITION,       "Speed" },
71     { GEOIP_DOMAIN_EDITION,         "Domain" },
72 #ifdef HAVE_GEOIP_V6
73     { GEOIP_COUNTRY_EDITION_V6,     "Country" },
74 /* This is the closest thing to a version that GeoIP.h seems to provide. */
75 #if NUM_DB_TYPES > 31 /* 1.4.7 */
76     { GEOIP_CITY_EDITION_REV0_V6,   "City"},
77     { GEOIP_CITY_EDITION_REV1_V6,   "City"},
78     { GEOIP_ASNUM_EDITION_V6,       "AS Number" },
79     { GEOIP_ISP_EDITION_V6,         "ISP" },
80     { GEOIP_ORG_EDITION_V6,         "Organization" },
81     { GEOIP_DOMAIN_EDITION_V6,      "Domain" },
82 #endif /* NUM_DB_TYPES > 31 */
83 #if NUM_DB_TYPES > 32 /* 1.4.8 */
84     { GEOIP_NETSPEED_EDITION_REV1_V6, "Speed" },
85 #endif /* NUM_DB_TYPES > 32 */
86 #endif /* HAVE_GEOIP_V6 */
87     { WS_LAT_FAKE_EDITION,          "Latitude" },   /* fake database */
88     { WS_LON_FAKE_EDITION,          "Longitude" },  /* fake database */
89     { 0, NULL }
90 };
91
92 static GArray *geoip_dat_arr = NULL;
93
94 /* UAT definitions. Copied from oids.c */
95 typedef struct _geoip_db_path_t {
96     char* path;
97 } geoip_db_path_t;
98
99 static geoip_db_path_t *geoip_db_paths = NULL;
100 static guint num_geoip_db_paths = 0;
101 static const geoip_db_path_t geoip_db_system_paths[] = {
102 #ifdef G_OS_UNIX
103     { "/usr/share/GeoIP" },
104 #endif
105     { NULL }
106 };
107 static uat_t *geoip_db_paths_uat = NULL;
108 UAT_DIRECTORYNAME_CB_DEF(geoip_mod, path, geoip_db_path_t)
109
110
111 /**
112  * Scan a directory for GeoIP databases and load them
113  */
114 static void
115 geoip_dat_scan_dir(const char *dirname) {
116     WS_DIR *dir;
117     WS_DIRENT *file;
118     const char *name;
119     char *datname;
120     GeoIP *gi;
121
122     if ((dir = ws_dir_open(dirname, 0, NULL)) != NULL) {
123         while ((file = ws_dir_read_name(dir)) != NULL) {
124             name = ws_dir_get_name(file);
125             if (g_str_has_prefix(file, "Geo") && g_str_has_suffix(file, ".dat")) {
126                 datname = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", dirname, name);
127                 gi = GeoIP_open(datname, GEOIP_MEMORY_CACHE);
128                 if (gi) {
129                     g_array_append_val(geoip_dat_arr, gi);
130                 }
131                 g_free(datname);
132             }
133         }
134         ws_dir_close (dir);
135     }
136 }
137
138 /* UAT callbacks */
139 static void* geoip_db_path_copy_cb(void* dest, const void* orig, size_t len _U_) {
140     const geoip_db_path_t *m = (const geoip_db_path_t *)orig;
141     geoip_db_path_t *d = (geoip_db_path_t *)dest;
142
143     d->path = g_strdup(m->path);
144
145     return d;
146 }
147
148 static void geoip_db_path_free_cb(void* p) {
149     geoip_db_path_t *m = (geoip_db_path_t *)p;
150     g_free(m->path);
151 }
152
153 static void geoip_dat_cleanup(void) {
154     GeoIP *gi;
155     guint i;
156
157     /* If we have old data, clear out the whole thing
158      * and start again. TODO: Just update the ones that
159      * have changed for efficiency's sake. */
160     if (geoip_dat_arr) {
161         /* skip the last two, as they are fake */
162         for (i = 0; i < geoip_db_num_dbs() - 2; i++) {
163             gi = g_array_index(geoip_dat_arr, GeoIP *, i);
164             if (gi) {
165                 GeoIP_delete(gi);
166             }
167         }
168         /* don't use GeoIP_delete() on the two fake
169          * databases as they weren't created by GeoIP_new()
170          * or GeoIP_open() */
171         gi = g_array_index(geoip_dat_arr, GeoIP *, i);
172         g_free(gi);
173         gi = g_array_index(geoip_dat_arr, GeoIP *, i+1);
174         g_free(gi);
175         /* finally, free the array itself */
176         g_array_free(geoip_dat_arr, TRUE);
177         geoip_dat_arr = NULL;
178     }
179 }
180
181 /* called every time the user presses "Apply" or "OK in the list of
182  * GeoIP directories, and also once on startup */
183 static void geoip_db_post_update_cb(void) {
184     guint i;
185     GeoIP* gi;
186
187     geoip_dat_cleanup();
188
189     /* allocate the array */
190     geoip_dat_arr = g_array_new(FALSE, FALSE, sizeof(GeoIP *));
191
192     /* First try the system paths */
193     for (i = 0; geoip_db_system_paths[i].path != NULL; i++) {
194         geoip_dat_scan_dir(geoip_db_system_paths[i].path);
195     }
196
197     /* Walk all the directories */
198     for (i = 0; i < num_geoip_db_paths; i++) {
199         if (geoip_db_paths[i].path) {
200             geoip_dat_scan_dir(geoip_db_paths[i].path);
201         }
202     }
203
204     /* add fake databases for latitude and longitude
205      * (using "City" in reality) */
206
207     /* latitude */
208     gi = (GeoIP *)g_malloc(sizeof (GeoIP));
209     gi->databaseType = WS_LAT_FAKE_EDITION;
210     g_array_append_val(geoip_dat_arr, gi);
211
212     /* longitude */
213     gi = (GeoIP *)g_malloc(sizeof (GeoIP));
214     gi->databaseType = WS_LON_FAKE_EDITION;
215     g_array_append_val(geoip_dat_arr, gi);
216 }
217
218 static void geoip_db_cleanup(void)
219 {
220     geoip_dat_cleanup();
221 }
222
223 /**
224  * Initialize GeoIP lookups
225  */
226 void
227 geoip_db_pref_init(module_t *nameres)
228 {
229     static uat_field_t geoip_db_paths_fields[] = {
230         UAT_FLD_DIRECTORYNAME(geoip_mod, path, "GeoIP Database Directory", "The GeoIP database directory path"),
231         UAT_END_FIELDS
232     };
233
234     geoip_db_paths_uat = uat_new("GeoIP Database Paths",
235             sizeof(geoip_db_path_t),
236             "geoip_db_paths",
237             FALSE,
238             (void**)&geoip_db_paths,
239             &num_geoip_db_paths,
240             /* affects dissection of packets (as the GeoIP database is
241                used when dissecting), but not set of named fields */
242             UAT_AFFECTS_DISSECTION,
243             "ChGeoIPDbPaths",
244             geoip_db_path_copy_cb,
245             NULL,
246             geoip_db_path_free_cb,
247             geoip_db_post_update_cb,
248             geoip_db_cleanup,
249             geoip_db_paths_fields);
250
251     prefs_register_uat_preference(nameres,
252             "geoip_db_paths",
253             "GeoIP database directories",
254             "Search paths for GeoIP address mapping databases."
255             " Wireshark will look in each directory for files beginning"
256             " with \"Geo\" and ending with \".dat\".",
257             geoip_db_paths_uat);
258 }
259
260 guint
261 geoip_db_num_dbs(void) {
262     return (geoip_dat_arr == NULL) ? 0 : geoip_dat_arr->len;
263 }
264
265 const gchar *
266 geoip_db_name(guint dbnum) {
267     GeoIP *gi;
268
269     gi = g_array_index(geoip_dat_arr, GeoIP *, dbnum);
270     if (gi) {
271         return (val_to_str_const(gi->databaseType, geoip_type_name_vals, "Unknown database"));
272     }
273     return "Invalid database";
274 }
275
276 int
277 geoip_db_type(guint dbnum) {
278     GeoIP *gi;
279
280     gi = g_array_index(geoip_dat_arr, GeoIP *, dbnum);
281     if (gi) {
282         return (gi->databaseType);
283     }
284     return -1;
285 }
286
287 static int
288 geoip_db_lookup_latlon4(guint32 addr, float *lat, float *lon) {
289     GeoIP *gi;
290     GeoIPRecord *gir;
291     guint i;
292
293     for (i = 0; i < geoip_db_num_dbs(); i++) {
294         gi = g_array_index(geoip_dat_arr, GeoIP *, i);
295         if (gi) {
296             switch (gi->databaseType) {
297                 case GEOIP_CITY_EDITION_REV0:
298                 case GEOIP_CITY_EDITION_REV1:
299                     gir = GeoIP_record_by_ipnum(gi, addr);
300                     if (gir) {
301                         *lat = gir->latitude;
302                         *lon = gir->longitude;
303                         GeoIPRecord_delete(gir);
304                         return 0;
305                     }
306                     return -1;
307                     /*break;*/
308
309                 default:
310                     break;
311             }
312         }
313     }
314     return -1;
315 }
316
317 /*
318  * GeoIP 1.4.3 and later provide GeoIP_set_charset(), but in versions
319  * 1.4.3 to 1.4.6 that only applies to the City databases. I.e., it's
320  * possible to produce invalid UTF-8 sequences even if GeoIP_set_charset()
321  * is used.
322  */
323
324 /* Ensure that a given db value is UTF-8 */
325 static char *
326 db_val_to_utf_8(const char *val, GeoIP *gi) {
327
328     if (GeoIP_charset(gi) == GEOIP_CHARSET_ISO_8859_1) {
329         char *utf8_val;
330         utf8_val = g_convert(val, -1, "UTF-8", "ISO-8859-1", NULL, NULL, NULL);
331         if (utf8_val) {
332             char *ret_val = wmem_strdup(NULL, utf8_val);
333             g_free(utf8_val);
334             return ret_val;
335         }
336     }
337     return wmem_strdup(NULL, val);
338 }
339
340 char *
341 geoip_db_lookup_ipv4(guint dbnum, guint32 addr, const char *not_found) {
342     GeoIP *gi;
343     GeoIPRecord *gir;
344     char *name;
345     const char *country;
346     char *val, *ret = NULL;
347
348     if (dbnum > geoip_db_num_dbs()) {
349         if (not_found == NULL)
350             return NULL;
351
352         return wmem_strdup(NULL, not_found);
353     }
354     gi = g_array_index(geoip_dat_arr, GeoIP *, dbnum);
355     if (gi) {
356         switch (gi->databaseType) {
357             case GEOIP_COUNTRY_EDITION:
358                 country = GeoIP_country_name_by_ipnum(gi, addr);
359                 if (country) {
360                     ret = db_val_to_utf_8(country, gi);
361                 }
362                 break;
363
364             case GEOIP_CITY_EDITION_REV0:
365             case GEOIP_CITY_EDITION_REV1:
366                 gir = GeoIP_record_by_ipnum(gi, addr);
367                 if (gir && gir->city && gir->region) {
368                     val = wmem_strdup_printf(NULL, "%s, %s", gir->city, gir->region);
369                     ret = db_val_to_utf_8(val, gi);
370                     wmem_free(NULL, val);
371                 } else if (gir && gir->city) {
372                     ret = db_val_to_utf_8(gir->city, gi);
373                 }
374                 if (gir)
375                     GeoIPRecord_delete(gir);
376                 break;
377
378             case GEOIP_ORG_EDITION:
379             case GEOIP_ISP_EDITION:
380             case GEOIP_ASNUM_EDITION:
381                 name = GeoIP_name_by_ipnum(gi, addr);
382                 if (name) {
383                     ret = db_val_to_utf_8(name, gi);
384                     GeoIP_free(name);
385                 }
386                 break;
387
388             case WS_LAT_FAKE_EDITION:
389             {
390                 float lat;
391                 float lon;
392                 char *c;
393                 if(geoip_db_lookup_latlon4(addr, &lat, &lon) == 0) {
394                     val = wmem_strdup_printf(NULL, "%f", lat);
395                     c = strchr(val, ',');
396                     if (c != NULL) *c = '.';
397                     ret = val;
398                 }
399             }
400                 break;
401
402             case WS_LON_FAKE_EDITION:
403             {
404                 float lat;
405                 float lon;
406                 char *c;
407                 if(geoip_db_lookup_latlon4(addr, &lat, &lon) == 0) {
408                     val = wmem_strdup_printf(NULL, "%f", lon);
409                     c = strchr(val, ',');
410                     if (c != NULL) *c = '.';
411                     ret = val;
412                 }
413             }
414                 break;
415
416             default:
417                 break;
418         }
419     }
420
421     if (ret == NULL) {
422         if (not_found == NULL)
423             return NULL;
424
425         return wmem_strdup(NULL, not_found);
426     }
427
428     return ret;
429 }
430
431 #ifdef HAVE_GEOIP_V6
432
433 static int
434 #if NUM_DB_TYPES > 31 /* 1.4.7 */
435 geoip_db_lookup_latlon6(geoipv6_t addr, float *lat, float *lon) {
436     GeoIP *gi;
437     GeoIPRecord *gir;
438     guint i;
439
440     for (i = 0; i < geoip_db_num_dbs(); i++) {
441         gi = g_array_index(geoip_dat_arr, GeoIP *, i);
442         if (gi) {
443             switch (gi->databaseType) {
444                 case GEOIP_CITY_EDITION_REV0_V6:
445                 case GEOIP_CITY_EDITION_REV1_V6:
446                     gir = GeoIP_record_by_ipnum_v6(gi, addr);
447                     if(gir) {
448                         *lat = gir->latitude;
449                         *lon = gir->longitude;
450                         return 0;
451                     }
452                     return -1;
453                     /*break;*/
454
455                 default:
456                     break;
457             }
458         }
459     }
460     return -1;
461 }
462 #else /* NUM_DB_TYPES */
463 geoip_db_lookup_latlon6(geoipv6_t addr _U_, float *lat _U_, float *lon _U_) {
464     return -1;
465 }
466 #endif /* NUM_DB_TYPES */
467
468 char *
469 geoip_db_lookup_ipv6(guint dbnum, ws_in6_addr addr, const char *not_found) {
470     GeoIP *gi;
471     geoipv6_t gaddr;
472     char *name;
473     const char *country;
474     char *val, *ret = NULL;
475 #if NUM_DB_TYPES > 31
476     GeoIPRecord *gir;
477 #endif
478     if (dbnum > geoip_db_num_dbs()) {
479         if (not_found == NULL)
480             return NULL;
481
482         return wmem_strdup(NULL, not_found);
483     }
484
485     memcpy(&gaddr, &addr, sizeof(addr));
486
487     gi = g_array_index(geoip_dat_arr, GeoIP *, dbnum);
488     if (gi) {
489         switch (gi->databaseType) {
490             case GEOIP_COUNTRY_EDITION_V6:
491                 country = GeoIP_country_name_by_ipnum_v6(gi, gaddr);
492                 if (country) {
493                     ret = db_val_to_utf_8(country, gi);
494                 }
495                 break;
496
497 #if NUM_DB_TYPES > 31
498             case GEOIP_CITY_EDITION_REV0_V6:
499             case GEOIP_CITY_EDITION_REV1_V6:
500                 gir = GeoIP_record_by_ipnum_v6(gi, gaddr);
501                 if (gir && gir->city && gir->region) {
502                     val = wmem_strdup_printf(NULL, "%s, %s", gir->city, gir->region);
503                     ret = db_val_to_utf_8(val, gi);
504                     wmem_free(NULL, val);
505                 } else if (gir && gir->city) {
506                     ret = db_val_to_utf_8(gir->city, gi);
507                 }
508                 break;
509
510             case GEOIP_ORG_EDITION_V6:
511             case GEOIP_ISP_EDITION_V6:
512             case GEOIP_ASNUM_EDITION_V6:
513                 name = GeoIP_name_by_ipnum_v6(gi, gaddr);
514                 if (name) {
515                     ret = db_val_to_utf_8(name, gi);
516                     GeoIP_free(name);
517                 }
518                 break;
519 #endif /* NUM_DB_TYPES */
520
521             case WS_LAT_FAKE_EDITION:
522             {
523                 float lat;
524                 float lon;
525                 char *c;
526                 if(geoip_db_lookup_latlon6(gaddr, &lat, &lon) == 0) {
527                     val = wmem_strdup_printf(NULL, "%f", lat);
528                     c = strchr(val, ',');
529                     if (c != NULL) *c = '.';
530                     ret = val;
531                 }
532             }
533                 break;
534
535             case WS_LON_FAKE_EDITION:
536             {
537                 float lat;
538                 float lon;
539                 char *c;
540                 if(geoip_db_lookup_latlon6(gaddr, &lat, &lon) == 0) {
541                     val = wmem_strdup_printf(NULL, "%f", lon);
542                     c = strchr(val, ',');
543                     if (c != NULL) *c = '.';
544                     ret = val;
545                 }
546             }
547                 break;
548
549             default:
550                 break;
551         }
552     }
553
554     if (ret == NULL) {
555         if (not_found == NULL)
556             return NULL;
557
558         return wmem_strdup(NULL, not_found);
559     }
560
561     return ret;
562 }
563
564 #else /* HAVE_GEOIP_V6 */
565
566 char *
567 geoip_db_lookup_ipv6(guint dbnum _U_, ws_in6_addr addr _U_, const char *not_found) {
568     if (not_found == NULL)
569         return NULL;
570
571     return wmem_strdup(NULL, not_found);
572 }
573
574 #endif /* HAVE_GEOIP_V6 */
575
576 gchar *
577 geoip_db_get_paths(void) {
578     GString* path_str = NULL;
579     guint i;
580
581     path_str = g_string_new("");
582
583     for (i = 0; geoip_db_system_paths[i].path != NULL; i++) {
584         g_string_append_printf(path_str,
585                 "%s" G_SEARCHPATH_SEPARATOR_S, geoip_db_system_paths[i].path);
586     }
587
588     for (i = 0; i < num_geoip_db_paths; i++) {
589         if (geoip_db_paths[i].path) {
590             g_string_append_printf(path_str,
591                     "%s" G_SEARCHPATH_SEPARATOR_S, geoip_db_paths[i].path);
592         }
593     }
594
595     g_string_truncate(path_str, path_str->len-1);
596
597     return g_string_free(path_str, FALSE);
598 }
599
600 #else /* HAVE_GEOIP */
601 guint
602 geoip_db_num_dbs(void) {
603     return 0;
604 }
605
606 const gchar *
607 geoip_db_name(guint dbnum _U_) {
608     return "Unsupported";
609 }
610
611 int
612 geoip_db_type(guint dbnum _U_) {
613     return -1;
614 }
615
616 char *
617 geoip_db_lookup_ipv4(guint dbnum _U_, guint32 addr _U_, const char *not_found) {
618     if (not_found == NULL)
619         return NULL;
620
621     return (char *)wmem_strdup(NULL, not_found);
622 }
623
624 char *
625 geoip_db_lookup_ipv6(guint dbnum _U_, guint32 addr _U_, const char *not_found) {
626     if (not_found == NULL)
627         return NULL;
628
629     return (char *)wmem_strdup(NULL, not_found);
630 }
631
632 gchar *
633 geoip_db_get_paths(void) {
634     return g_strdup("");
635 }
636
637 #endif /* HAVE_GEOIP */
638
639 /*
640  * Editor modelines
641  *
642  * Local Variables:
643  * c-basic-offset: 4
644  * tab-width: 8
645  * indent-tabs-mode: nil
646  * End:
647  *
648  * ex: set shiftwidth=4 tabstop=8 expandtab:
649  * :indentSize=4:tabSize=8:noTabs=true:
650  */