Line data Source code
1 : /* Copyright (c) 2001-2004, Roger Dingledine. 2 : * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. 3 : * Copyright (c) 2007-2021, The Tor Project, Inc. */ 4 : /* See LICENSE for licensing information */ 5 : 6 : /** 7 : * @file getinfo_geoip.c 8 : * @brief GEOIP-related controller GETINFO commands. 9 : **/ 10 : 11 : #include "core/or/or.h" 12 : #include "core/mainloop/connection.h" 13 : #include "feature/control/control.h" 14 : #include "feature/control/getinfo_geoip.h" 15 : #include "lib/geoip/geoip.h" 16 : 17 : /** Helper used to implement GETINFO ip-to-country/... controller command. */ 18 : int 19 0 : getinfo_helper_geoip(control_connection_t *control_conn, 20 : const char *question, char **answer, 21 : const char **errmsg) 22 : { 23 0 : (void)control_conn; 24 0 : if (!strcmpstart(question, "ip-to-country/")) { 25 0 : int c; 26 0 : sa_family_t family; 27 0 : tor_addr_t addr; 28 0 : question += strlen("ip-to-country/"); 29 : 30 0 : if (!strcmp(question, "ipv4-available") || 31 0 : !strcmp(question, "ipv6-available")) { 32 0 : family = !strcmp(question, "ipv4-available") ? AF_INET : AF_INET6; 33 0 : const int available = geoip_is_loaded(family); 34 0 : tor_asprintf(answer, "%d", !! available); 35 0 : return 0; 36 : } 37 : 38 0 : family = tor_addr_parse(&addr, question); 39 0 : if (family != AF_INET && family != AF_INET6) { 40 0 : *errmsg = "Invalid address family"; 41 0 : return -1; 42 : } 43 0 : if (!geoip_is_loaded(family)) { 44 0 : *errmsg = "GeoIP data not loaded"; 45 0 : return -1; 46 : } 47 0 : if (family == AF_INET) 48 0 : c = geoip_get_country_by_ipv4(tor_addr_to_ipv4h(&addr)); 49 : else /* AF_INET6 */ 50 0 : c = geoip_get_country_by_ipv6(tor_addr_to_in6(&addr)); 51 0 : *answer = tor_strdup(geoip_get_country_name(c)); 52 : } 53 : return 0; 54 : }