Esempio n. 1
0
wxString CslGeoIP::GetCountryNameByAddr(const char *host)
{
    CslGeoIP& self = GetInstance();

    if (!g_geoIP)
        return wxEmptyString;

    GeoIPRecord *r = NULL;
    const char *country = NULL;

    switch (self.m_type)
    {
        case GEOIP_COUNTRY:
            country = GeoIP_country_name_by_addr(g_geoIP, host);
            break;
        case GEOIP_CITY:
            if ((r = GeoIP_record_by_addr(g_geoIP, host)))
            {
                country = r->country_name;
                GeoIPRecord_delete(r);
            }
            break;
    }

    return country ? C2U(country) : wxString(wxEmptyString);
}
Esempio n. 2
0
const char* CslGeoIP::GetCountryCodeByAddr(const char *host)
{
    CslGeoIP& self = GetInstance();

    if (!g_geoIP)
        return NULL;

    GeoIPRecord *r = NULL;
    const char *code = NULL;

    switch (self.m_type)
    {
        case GEOIP_COUNTRY:
            code = GeoIP_country_code_by_addr(g_geoIP, host);
            break;
        case GEOIP_CITY:
            if ((r = GeoIP_record_by_addr(g_geoIP, host)))
            {
                code = r->country_code;
                GeoIPRecord_delete(r);
            }
            break;
    }

    return code;
}
Esempio n. 3
0
std::string city_code_by_addr(const std::string &ip)
{
    if (!GeoCity())
        return "";

    GeoIPRecord *record = GeoIP_record_by_addr(GeoCity(), ip.c_str());
    if (!record)
        return "";

    return record->city ? record->city : "";
}
Esempio n. 4
0
/* Pass this function an IP address as a string, it will return a hash
 * containing all the information that the database knows about the IP
 *    db.look_up('24.24.24.24')
 *    => {:city=>"Ithaca", :latitude=>42.4277992248535,
 *        :country_code=>"US", :longitude=>-76.4981994628906,
 *        :country_code3=>"USA", :dma_code=>555,
 *        :country_name=>"United States", :area_code=>607,
 *        :region=>"NY"}
 */
VALUE rb_geoip_city_look_up(VALUE self, VALUE addr) {
  GeoIP *gi;
  GeoIPRecord *record = NULL;
  VALUE hash = Qnil;

  Check_Type(addr, T_STRING);
  Data_Get_Struct(self, GeoIP, gi);
  if(record = GeoIP_record_by_addr(gi, StringValuePtr(addr))) {
    hash =  rb_city_record_to_hash(record);
    GeoIPRecord_delete(record);
  }
  return hash;
}
Esempio n. 5
0
/** Возвращает название области по ``ip``.
    Если по какой-либо причине область определить не удалось, возвращается
    пустая строка.
*/
std::string region_code_by_addr(const std::string &ip)
{
    if (!GeoCity())
        return "";

    GeoIPRecord *record = GeoIP_record_by_addr(GeoCity(), ip.c_str());
    if (!record)
        return "";

    const char *region_name =
        GeoIP_region_name_by_code(record->country_code, record->region);
    return region_name? region_name : "";
}
Esempio n. 6
0
static PyObject * GeoIP_record_by_addr_Py(PyObject *self, PyObject *args) {
  char * addr;
  GeoIPRecord * gir;
  GeoIP_GeoIPObject* GeoIP = (GeoIP_GeoIPObject*)self;
  if (!PyArg_ParseTuple(args, "s", &addr)) {
    return NULL;
  }
  gir = GeoIP_record_by_addr(GeoIP->gi, addr);
	if (gir == NULL) {
		Py_INCREF(Py_None);
		return Py_None;
	}
	return GeoIP_populate_dict(GeoIP->gi, gir);
}
Esempio n. 7
0
int resolve_ip(GeoIP* geoip, const char* ipaddr, char* out, int max_out)
{
  GeoIPRecord *r = GeoIP_record_by_addr(geoip, ipaddr);
  int chars_written = 0;
  if (r == NULL) {
    chars_written = snprintf(out, max_out, "NOT_FOUND");
  }
  else {
    chars_written  = snprintf(out, max_out, "%s\t%s\t%s\t%s\t%f\t%f\t%d\t%d", r->country_code, r->region, r->city, r->postal_code,
			      r->latitude, r->longitude, r->metro_code, r->area_code);

    GeoIPRecord_delete(r);
  }
  return chars_written;
}
Esempio n. 8
0
wxString CslGeoIP::GetCityNameByAddr(const char *host)
{
    CslGeoIP& self = GetInstance();

    wxString city;

    if (g_geoIP && self.m_type==GEOIP_CITY)
    {
        GeoIPRecord *r = GeoIP_record_by_addr(g_geoIP, host);

        if (r)
        {
            city = C2U(r->city);
            GeoIPRecord_delete(r);
        }
    }

    return city;
}
Esempio n. 9
0
void
ServerInfo::lookUp(const QHostInfo &host)
{
    qDebug() << __PRETTY_FUNCTION__ << " called ...";

    if (host.error() != QHostInfo::NoError) {
        qDebug() << "Lookup failed:" << host.errorString();
        return;
    }

    QString s;
    if(!host.addresses().isEmpty()) {

        s += QLatin1String("IP addresses: ");

        for(int i = 0;i < host.addresses().count();++i) {
            s += host.addresses().at(i).toString() + QLatin1String("\n");
        }

        GeoIPRecord* record = GeoIP_record_by_addr(gi,host.addresses().first().toString().toLatin1().constData());
        if(record) {

        const char* returnedCountry = record->country_name;

        s += QLatin1String("Country: ") + returnedCountry + QLatin1String("\n");
        s += QLatin1String("City: ") + QLatin1String(record->city)  + QLatin1String("\n");
        s += QLatin1String("Latitude: ") + QString::number(record->latitude)  + QLatin1String("\n");
        s += QLatin1String("Longitude: ") + QString::number(record->longitude)  + QLatin1String("\n");
        s += QLatin1String("Region: ") + QLatin1String(record->region) + QLatin1String("\n");
        s += QLatin1String("Postal code: ") + QLatin1String(record->postal_code) + QLatin1String("\n");

        }
        /* Save for later use */
        this->latitude = record->latitude;
        this->longitude = record->longitude;

        if(this->mainWindow->ui->googleMapsLookup_checkBox->isChecked()) {
            this->loadGoogleMaps();
        }

        this->ui->plainTextEdit->setPlainText(s);
    }
}
Esempio n. 10
0
int GeoIPLocAddr(char *addr, float *latitude, float *longitude)
{
    GeoIPRecord *gir;

    if (gi == NULL)
       return -1;

    if (city) {
        gir = GeoIP_record_by_addr(gi, (const char *)addr);
        if (gir != NULL) {
            *latitude = gir->latitude;
            *longitude = gir->longitude;
            GeoIPRecord_delete(gir);
            return 0;
        }
    }
    
    return -1;
}
Esempio n. 11
0
static int geoip_lookup_country(vcl_string *ip, vcl_string *resolved) {

    pthread_mutex_lock(&geoip_mutex);

    if (!gi) {
        geoip_init();
    }

    record = GeoIP_record_by_addr(gi, ip);

    snprintf(resolved, HEADER_MAXLEN, "country:%s", record
        ? record->country_code
        : FALLBACK_COUNTRY
    );

    pthread_mutex_unlock(&geoip_mutex);

    /* Assume always success: we have FALLBACK_COUNTRY */
    return 1;
}
Esempio n. 12
0
static int geoip_lookup(vcl_string *ip, vcl_string *resolved) {
    int lookup_success = 0;

    pthread_mutex_lock(&geoip_mutex);

    if (!gi) {
        geoip_init();
    }

    record = GeoIP_record_by_addr(gi, ip);

    /* Lookup succeeded */
    if (record) {
        lookup_success = 1;
        snprintf(resolved, HEADER_MAXLEN, HEADER_TMPL,
            record->city,
            record->country_code,
            record->latitude,
            record->longitude,
            ip
        );
    }

    /* Failed lookup */
    else {
        snprintf(resolved, HEADER_MAXLEN, HEADER_TMPL,
            "",      /* City */
            FALLBACK_COUNTRY,
            0.0f,    /* Latitude */
            0.0f,    /* Longitude */
            ip
        );
    }

    pthread_mutex_unlock(&geoip_mutex);

    return lookup_success;
}
Esempio n. 13
0
void testgeoipcity(int flags, const char *msg, int numlookups)
{
    GeoIP *i = NULL;
    GeoIPRecord *i3 = NULL;
    int i4 = 0;
    int i2 = 0;
    double t = 0;
    i = GeoIP_open("/usr/local/share/GeoIP/GeoIPCity.dat", flags);
    if (i == NULL) {
        printf("error: GeoLiteCity.dat does not exist\n");
        return;
    }
    timerstart();
    for (i2 = 0; i2 < numlookups; i2++) {
        i3 = GeoIP_record_by_addr(i, ipstring[i4]);
        GeoIPRecord_delete(i3);
        i4 = (i4 + 1) % numipstrings;
    }
    t = timerstop();
    printf("%s\n", msg);
    printf("%d lookups made in %f seconds \n", numlookups, t);
    GeoIP_delete(i);
}
    void info_getter_city::process_ip_info(ip_info& info) {
        if (GeoIPRecord *gir = GeoIP_record_by_addr(db, info.ip_string.c_str())) {
            if (!info.country_code2 && gir->country_code) {
                info.country_code2.reset(gir->country_code);
            }
            if (!info.country_code3 && gir->country_code3) {
                info.country_code3.reset(gir->country_code3);
            }
            if (!info.country_name_en && gir->country_name) {
                info.country_name_en.reset(gir->country_name);
            }
            if (!info.city_en && gir->city) {
                info.city_en.reset(gir->city);
            }
            if (!info.latitude) {
                info.latitude.reset(gir->latitude);
            }
            if (!info.longitude) {
                info.longitude.reset(gir->longitude);
            }

            GeoIPRecord_delete(gir);
        }
    }
Esempio n. 15
0
static int geoip_header_parser(request_rec * r)
{
    char *orgorisp;
    char *ipaddr;
    char *free_me = NULL;
    short int country_id;
    const char *continent_code;
    const char *country_code;
    const char *country_name;
    const char *region_name;

    geoip_server_config_rec *cfg;

    unsigned char databaseType;
    GeoIPRecord *gir;
    GeoIPRegion *giregion;
    int i;
    int netspeed;
    /* For splitting proxy headers */
    char *ipaddr_ptr = NULL;
    char *comma_ptr;
    cfg = ap_get_module_config(r->server->module_config, &geoip_module);

    if (!cfg)
        return DECLINED;

    if (!cfg->scanProxyHeaders) {
        ipaddr = _get_client_ip(r);
    } else {
        ap_add_common_vars(r);
        if (apr_table_get(r->subprocess_env, "HTTP_CLIENT_IP")) {
            ipaddr_ptr =
                (char *)apr_table_get(r->subprocess_env, "HTTP_CLIENT_IP");
        } else if (apr_table_get(r->subprocess_env, "HTTP_X_FORWARDED_FOR")) {
            ipaddr_ptr =
                (char *)apr_table_get(r->subprocess_env,
                                      "HTTP_X_FORWARDED_FOR");
        } else if (apr_table_get(r->headers_in, "X-Forwarded-For")) {
            ipaddr_ptr =
                (char *)apr_table_get(r->headers_in, "X-Forwarded-For");
        } else if (apr_table_get(r->subprocess_env, "HTTP_REMOTE_ADDR")) {
            ipaddr_ptr =
                (char *)apr_table_get(r->subprocess_env, "HTTP_REMOTE_ADDR");
        }
        if (!ipaddr_ptr) {
            ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0,
                         r->server,
                         "[mod_geoip]: Error while getting ipaddr from proxy headers. Using REMOTE_ADDR.");
            ipaddr = _get_client_ip(r);
        } else {
            /* Found XFF like header */
            ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0,
                         r->server, "[mod_geoip]: IPADDR_PTR: %s", ipaddr_ptr);

            if (cfg->proxyHeaderMode ==
                GEOIP_PROXY_HEADER_MODE_FIRST_NON_PRIVATE_IP) {
                ipaddr = free_me = _get_ip_from_xff(ipaddr_ptr);
                if (!ipaddr)
                    ipaddr = _get_client_ip(r);
            } else {
                ipaddr = free_me = (char *)calloc(8 * 4 + 7 + 1, sizeof(char));
                /* proxyHeaderMode is
                 * GEOIP_PROXY_HEADER_MODE_LAST_IP or GEOIP_PROXY_HEADER_MODE_FIRST_IP
                 */

                /*
                 * Check to ensure that the HTTP_CLIENT_IP or
                 * X-Forwarded-For header is not a comma separated
                 * list of addresses, which would cause mod_geoip to
                 * return no country code. If the header is a comma
                 * separated list, return the first IP address in the
                 * list, which is (hopefully!) the real client IP.
                 */

                if (cfg->proxyHeaderMode == GEOIP_PROXY_HEADER_MODE_LAST_IP) {
                    comma_ptr = strrchr(ipaddr_ptr, ',');
                    if (comma_ptr) {
                        /* skip over whitespace */
                        ipaddr_ptr = comma_ptr + strspn(comma_ptr, ", \t");
                    }
                }

                strncpy(ipaddr, ipaddr_ptr, 8 * 4 + 7);
                comma_ptr = strchr(ipaddr, ',');
                if (comma_ptr != 0)
                    *comma_ptr = '\0';
            }
        }
    }

/* this block should be removed! */
#if 1
    if (!cfg->gips) {
        if (cfg->GeoIPFilenames != NULL) {
            cfg->gips = malloc(sizeof(GeoIP *) * cfg->numGeoIPFiles);
            for (i = 0; i < cfg->numGeoIPFiles; i++) {
                cfg->gips[i] =
                    GeoIP_open(cfg->GeoIPFilenames[i],
                               (cfg->GeoIPFlags2[i] ==
                                GEOIP_UNKNOWN) ? cfg->GeoIPFlags
                               : cfg->GeoIPFlags2[i]);

                if (cfg->gips[i]) {
                    if (cfg->GeoIPEnableUTF8) {
                        GeoIP_set_charset(cfg->gips[i], GEOIP_CHARSET_UTF8);
                    }
                } else {
                    ap_log_error(APLOG_MARK, APLOG_ERR, 0,
                                 r->server,
                                 "[mod_geoip]: Error while opening data file %s",
                                 cfg->GeoIPFilenames[i]);
                    return DECLINED;
                }
            }
        } else {
            cfg->gips = malloc(sizeof(GeoIP *));
            cfg->gips[0] = GeoIP_new(GEOIP_STANDARD);
            if (!cfg->gips[0]) {
                ap_log_error(APLOG_MARK, APLOG_ERR, 0,
                             r->server,
                             "[mod_geoip]: Error while opening data file");
                return DECLINED;
            }
            cfg->numGeoIPFiles = 1;
        }
    }
#endif

    set_geoip_output(cfg, r, "GEOIP_ADDR", ipaddr);

    for (i = 0; i < cfg->numGeoIPFiles; i++) {

        /*
         * skip database handles that can not be opned for some
         * reason
         */
        if (cfg->gips[i] == NULL)
            continue;

        databaseType = cfg->gips[i] ? GeoIP_database_edition(cfg->gips[i]) : -1;        /* -1 is "magic value"
                                                                                         * in case file not
                                                                                         * found */
        switch (databaseType) {
        case GEOIP_NETSPEED_EDITION_REV1:
            orgorisp = GeoIP_name_by_addr(cfg->gips[i], ipaddr);
            setn_geoip_output(cfg, r, "GEOIP_NETSPEED", orgorisp);
            break;

        case GEOIP_NETSPEED_EDITION:
            netspeed = GeoIP_id_by_addr(cfg->gips[i], ipaddr);
            if (netspeed == GEOIP_UNKNOWN_SPEED) {
                netspeedstring = "unknown";
            } else if (netspeed == GEOIP_DIALUP_SPEED) {
                netspeedstring = "dialup";
            } else if (netspeed == GEOIP_CABLEDSL_SPEED) {
                netspeedstring = "cabledsl";
            } else if (netspeed == GEOIP_CORPORATE_SPEED) {
                netspeedstring = "corporate";
            }
            setn_geoip_output(cfg, r, "GEOIP_NETSPEED", netspeedstring);
            break;
        case GEOIP_COUNTRY_EDITION_V6:
            /* Get the Country ID */
            country_id = GeoIP_id_by_addr_v6(cfg->gips[i], ipaddr);

            if (country_id > 0) {
                /* Lookup the Code and the Name with the ID */
                continent_code = GeoIP_country_continent[country_id];
                country_code = GeoIP_country_code[country_id];
                country_name = GeoIP_country_name[country_id];

                if (cfg->numGeoIPFiles == 0) {
                    cfg->numGeoIPFiles = 0;
                }
                if (cfg->GeoIPFilenames == 0) {
                    cfg->GeoIPFilenames = 0;
                }
                /* Set it for our user */
                setn_geoip_output(cfg, r, "GEOIP_CONTINENT_CODE_V6",
                                  continent_code);
                setn_geoip_output(cfg, r, "GEOIP_COUNTRY_CODE_V6",
                                  country_code);
                setn_geoip_output(cfg, r, "GEOIP_COUNTRY_NAME_V6",
                                  country_name);
            }
            break;
        case GEOIP_COUNTRY_EDITION:
            /* Get the Country ID */
            country_id = GeoIP_country_id_by_addr(cfg->gips[i], ipaddr);

            if (country_id > 0) {
                /* Lookup the Code and the Name with the ID */
                continent_code = GeoIP_country_continent[country_id];
                country_code = GeoIP_country_code[country_id];
                country_name = GeoIP_country_name[country_id];

                if (cfg->numGeoIPFiles == 0) {
                    cfg->numGeoIPFiles = 0;
                }
                if (cfg->GeoIPFilenames == 0) {
                    cfg->GeoIPFilenames = 0;
                }
                /* Set it for our user */
                setn_geoip_output(cfg, r, "GEOIP_CONTINENT_CODE",
                                  continent_code);
                setn_geoip_output(cfg, r, "GEOIP_COUNTRY_CODE", country_code);
                setn_geoip_output(cfg, r, "GEOIP_COUNTRY_NAME", country_name);
            }

            break;
        case GEOIP_REGION_EDITION_REV0:
        case GEOIP_REGION_EDITION_REV1:
            giregion = GeoIP_region_by_name(cfg->gips[i], ipaddr);
            if (giregion != NULL) {
                region_name = NULL;
                if (giregion->country_code[0]) {
                    region_name =
                        GeoIP_region_name_by_code
                        (giregion->country_code, giregion->region);
                    set_geoip_output(cfg, r, "GEOIP_COUNTRY_CODE",
                                      giregion->country_code);
                    country_id = GeoIP_id_by_code(giregion->country_code);
                    setn_geoip_output(cfg, r, "GEOIP_COUNTRY_NAME",
                                      GeoIP_country_name[country_id]);
                    setn_geoip_output(cfg, r, "GEOIP_CONTINENT_CODE",
                                      GeoIP_country_continent[country_id]);
                }
                if (giregion->region[0]) {
                    set_geoip_output(cfg, r, "GEOIP_REGION", giregion->region);
                }
                if (region_name != NULL) {
                    set_geoip_output(cfg, r, "GEOIP_REGION_NAME", region_name);
                }
                GeoIPRegion_delete(giregion);
            }
            break;
        case GEOIP_CITY_EDITION_REV0_V6:
        case GEOIP_CITY_EDITION_REV1_V6:
            gir = GeoIP_record_by_addr_v6(cfg->gips[i], ipaddr);
            if (gir != NULL) {
                if (gir->country_code != NULL) {
                    region_name =
                        GeoIP_region_name_by_code(gir->country_code,
                                                  gir->region);
                }
                sprintf(metrocodestr, "%d", gir->dma_code);
                sprintf(areacodestr, "%d", gir->area_code);
                set_geoip_output(cfg, r, "GEOIP_CONTINENT_CODE_V6",
                                  gir->continent_code);
                set_geoip_output(cfg, r, "GEOIP_COUNTRY_CODE_V6",
                                  gir->country_code);
                set_geoip_output(cfg, r, "GEOIP_COUNTRY_NAME_V6",
                                  gir->country_name);
                set_geoip_output(cfg, r, "GEOIP_REGION_V6", gir->region);
                set_geoip_output(cfg, r, "GEOIP_REGION_NAME_V6", region_name);
                set_geoip_output(cfg, r, "GEOIP_CITY_V6", gir->city);
                set_geoip_output(cfg, r, "GEOIP_DMA_CODE_V6", metrocodestr);
                set_geoip_output(cfg, r, "GEOIP_METRO_CODE_V6", metrocodestr);
                set_geoip_output(cfg, r, "GEOIP_AREA_CODE_V6", areacodestr);
                sprintf(latstr, "%f", gir->latitude);
                sprintf(lonstr, "%f", gir->longitude);
                set_geoip_output(cfg, r, "GEOIP_LATITUDE_V6", latstr);
                set_geoip_output(cfg, r, "GEOIP_LONGITUDE_V6", lonstr);

                set_geoip_output(cfg, r, "GEOIP_POSTAL_CODE_V6",
                                  gir->postal_code);
                GeoIPRecord_delete(gir);
            }

            break;
        case GEOIP_CITY_EDITION_REV0:
        case GEOIP_CITY_EDITION_REV1:
            gir = GeoIP_record_by_addr(cfg->gips[i], ipaddr);
            if (gir != NULL) {
                if (gir->country_code != NULL) {
                    region_name =
                        GeoIP_region_name_by_code(gir->country_code,
                                                  gir->region);
                }
                sprintf(metrocodestr, "%d", gir->dma_code);
                sprintf(areacodestr, "%d", gir->area_code);
                set_geoip_output(cfg, r, "GEOIP_CONTINENT_CODE",
                                  gir->continent_code);
                set_geoip_output(cfg, r, "GEOIP_COUNTRY_CODE",
                                  gir->country_code);
                set_geoip_output(cfg, r, "GEOIP_COUNTRY_NAME",
                                  gir->country_name);
                set_geoip_output(cfg, r, "GEOIP_REGION", gir->region);
                set_geoip_output(cfg, r, "GEOIP_REGION_NAME", region_name);
                set_geoip_output(cfg, r, "GEOIP_CITY", gir->city);
                set_geoip_output(cfg, r, "GEOIP_DMA_CODE", metrocodestr);
                set_geoip_output(cfg, r, "GEOIP_METRO_CODE", metrocodestr);
                set_geoip_output(cfg, r, "GEOIP_AREA_CODE", areacodestr);
                sprintf(latstr, "%f", gir->latitude);
                sprintf(lonstr, "%f", gir->longitude);
                set_geoip_output(cfg, r, "GEOIP_LATITUDE", latstr);
                set_geoip_output(cfg, r, "GEOIP_LONGITUDE", lonstr);
                set_geoip_output(cfg, r, "GEOIP_POSTAL_CODE",
                                  gir->postal_code);
                GeoIPRecord_delete(gir);
            }

            break;
        case GEOIP_ORG_EDITION:
            orgorisp = GeoIP_name_by_addr(cfg->gips[i], ipaddr);
            setn_geoip_output(cfg, r, "GEOIP_ORGANIZATION", orgorisp);
            break;
        case GEOIP_ISP_EDITION:
            orgorisp = GeoIP_name_by_addr(cfg->gips[i], ipaddr);
            setn_geoip_output(cfg, r, "GEOIP_ISP", orgorisp);
            break;
        case GEOIP_DOMAIN_EDITION:
            orgorisp = GeoIP_name_by_addr(cfg->gips[i], ipaddr);
            setn_geoip_output(cfg, r, "GEOIP_DOMAIN", orgorisp);
            break;
        }
    }

    if (free_me)
        free(free_me);
    return OK;
}
Esempio n. 16
0
File: show.cpp Progetto: s12v/mtop
int main()
{
  // Инициализация глобальных переменных
  query = new char[65536];
	areaCodeNumber = 0;
	globalError = 0;

	// Инициализация генератора случайных чисел с помощью номера процесса
	init_genrand(getpid());

  // Подключение к MySQL
  connection = mysql_init(NULL);
  if(connection == NULL)
  {
    loading_error_exit(1);
  }
  if(mysql_real_connect(connection, NULL, MTOP_MYSQL_RO_USER, MTOP_MYSQL_RO_PASSWD, MTOP_MYSQL_DB, 0, NULL, 0) == NULL)
  {
    loading_error_exit(1);
  }

	// Загрузка регионов/городов
	// Загрузка данных геотаргетинга
	gi = GeoIP_open(MTOP_GEOIP_FILE, GEOIP_MEMORY_CACHE);
	if(gi == NULL)
	{
    loading_error_exit(3);
	}

	// Составляем массив соответствий areaCodeArr[AreaId] = AreaCode
	mysql_query_check(globalError, connection, "SELECT AreaId, AreaCode FROM Area;");
	result = mysql_store_result(connection);
	areaCodeNumber = mysql_num_rows(result);
	if(areaCodeNumber > 0) areaCodeArr = new int[areaCodeNumber];
	while((row = mysql_fetch_row(result)) != NULL)
	{
	  i = atoi(row[0]);
	  if(i > 0 && i < areaCodeNumber)	areaCodeArr[i] = atoi(row[1]);
	}
	mysql_free_result(result);

	// Открытие канала FIFO
	int fd = open(MTOP_FIFO_FILE, O_WRONLY | O_NONBLOCK);
	if(fd < 0)
	{
    loading_error_exit(133);
	}

  // Загрузка данных
	data_load();

	//// ПЕРЕМЕННЫЕ, необходимые для работы основного цикла

  #ifdef DEBUG
		struct timeval start_time, end_time;  // необходимо для определения времени работы основного цикла
	#endif
	struct timeval load_timeout, tmp_time;	// таймаут с предыдущей загрузки данных
	gettimeofday(&load_timeout, NULL);
	
  char *query_string = new char[1024];
  char *remote_addr = new char[50];
  char *p;
  int siteId;
  int accountId;
  int areaCodeId;
	time_t time_of_day;
	struct tm *tmbuf;

	PROFILE **profileCheckedArr;
	if(profileNum > 0) profileCheckedArr = new PROFILE*[profileNum];
	int	profileCheckedNum;

	BANNERCHECKED	*bannerCheckedArr;
	if(bannerNum) bannerCheckedArr = new BANNERCHECKED[bannerNum];
	int	bannerCheckedNum;
	int newPriority;
	int prioritySumm;

	unsigned long	rnd;
	unsigned long trafficKey;

	SITE *currentSite;
	BANNER *currentBanner;
	unsigned int bannerShowNum;

	TRAFFIC currentShow;

	int found;
	int error;

	int outputCodeType;

/////// ОСНОВНОЙ ЦИКЛ

	while(FCGI_Accept() >= 0)
	{
		#ifdef DEBUG
			printf("Content-type: text/plain\r\n\r\n");
			PrintEnv("Request environment", environ);
		#endif

    // Определение необходимости перезагрузки данных
		gettimeofday(&tmp_time, NULL);
		if(tmp_time.tv_sec - load_timeout.tv_sec > MTOP_DATA_TIMEOUT)
		{
			data_clear();										// Очистка памяти
			data_load();										// Перезагрузка данных
			gettimeofday(&load_timeout, NULL);
		}
		
		#ifdef DEBUG
			gettimeofday(&start_time, NULL);
		#endif

		// Инициализация переменных
		memset(query_string, 0, 1024);		// строка запроса
		memset(remote_addr, 0, 50);       // адрес

		p = NULL;                         // временная переменная

		siteId = 0;                       // ID сайта и аккаунта, полученные
		accountId = 0;                    // из строки запроса. Не доверять!
		areaCodeId = 0;                   // ID области (именно ID)

	  tmp_ui = 0;

		time_of_day = time(NULL);
		tmbuf = localtime(&time_of_day);  // структура с днём недели и т.п.

		for(i = 0; i < profileNum; i++)
		{ // обнуляем массив
			profileCheckedArr[i] = NULL;
		}
		profileCheckedNum = 0;

		for(i = 0; i < bannerNum; i++)
		{ // обнуляем массив
			bannerCheckedArr[i].banner = NULL;
			bannerCheckedArr[i].Priority = 0;
		}
		bannerCheckedNum = 0;

		newPriority = 0;									// временная переменная
		prioritySumm = 0;                 // сумма приоритетов подходящих баннеров

		currentSite = NULL;								// сайт, на котором происходит показ
		currentBanner = NULL;							// баннер, который показывается
		bannerShowNum = 1;								// количество баннеров, которые необходимо показать

		error = 0;                        // во время выполнения возникла какая-от ошибка
		found = 0;												// временная переменная
		outputCodeType = 0;               // тип выводимого кода (TEXT, WAP, картинка)

	  // Переносим переменную окружения QUERY_STRING в локальную переменную
	  p = getenv("QUERY_STRING");
		if(p != NULL)
		{
		  strncpy(query_string, p, 1024);
		}

		#ifdef DEBUG
		  printf("query_string = %s\n", query_string);
		#endif

	  // Выделяем тип вывода
	  // !!!!!! доработать
	  p = strtok(query_string, ";");
	  if(p != NULL) outputCodeType = atoi(p);
	  p = strtok(NULL, ";"); 									// ID аккаунта
	  if(p != NULL) siteId = atoi(p);
	  p = strtok(NULL, ";");									// ID сайта
	  if(p != NULL) accountId = atoi(p);

	  if(outputCodeType == CODE_TEXT_PHP)
	  {
		  p = strtok(NULL, ";");								// Количество баннеров для показа
		  if(p != NULL) bannerShowNum = atoi(p);
		  p = strtok(NULL, ";");								// IP-адрес, тип - int
		  if(p != NULL) tmp_ui= atoi(p);
	  }

	  // Проверка bannerShowNum in [1,MTOP_MAX_BANNER_NUM]
	  if( (bannerShowNum <= 0) || (bannerShowNum > MTOP_MAX_BANNER_NUM) )
	  {
			bannerShowNum = 1;
	  }

		#ifdef DEBUG
		  printf("outputCodeType = %d\n", outputCodeType);
		  printf("siteId         = %d\n", siteId);
		  printf("accountId      = %d\n", accountId);
		#endif

		// Определяем IP-адрес
		if(tmp_ui > 0)
		{
			ipntoa(tmp_ui, remote_addr);
		}
		else
		{
		  // Переносим переменную окружения REMOTE_ADDR в локальную переменную
		  p = getenv("REMOTE_ADDR");
			if(p != NULL)
			{
				strncpy(remote_addr, p, 49);
			}
			else
			{
				strncpy(remote_addr, MTOP_SERVER_IP, 49);
			}
		}

	  // Проверяем ID аккаунта и сайта на корректность (частично)
	  if(siteId <= 0 || accountId <= 0)
	  {
			error = 2;
	  }

		// Находим сайт, на котором происходит показ
		// Таким образом проверяем корректность siteId и accountID
		if(!error)
		{
		  // перебираем все сайты (обход списка)
			for(site = siteList; site != NULL; site = site->next)
			{
				if( (site->Id == siteId) && (site->AccountId == accountId) )
				{ // нашли сайт, устанавливаем указатель на него
					currentSite = site;
					#ifdef DEBUG
					  printf("Site found:\n");
					  currentSite->show();
					#endif
					break;
				}
			}
			if(currentSite == NULL)
			{ // не нашли сайт, ошибка
				error = 4;
			}
		}
		//

	  printf("IP (%s)\n", remote_addr);

		// Находим область (город или регион) по адресу
		if(!error)
		{
			#ifdef DEBUG
			  printf("IP (%s) ", remote_addr);
			#endif
			gir = GeoIP_record_by_addr(gi, remote_addr);
			if(gir != NULL)
			{ // нашли регион для IP
			  if(gir->region != NULL)
			  {
				  areaCodeId = atoi(gir->region);
					#ifdef DEBUG
					  printf(" FOUND. ", remote_addr);
					  printf("Country_code=%s, ", gir->country_code);
					  printf("region=%s, ", gir->region);
						printf("city=%s\n", gir->city);
					#endif
					GeoIPRecord_delete(gir);
				}
			}
		}

		// Перебираем профили (нерекурсивный обход списка)
		if(!error)
		{
			for(profile = profileList; profile != NULL; profile = profile->next)
			{ // отбор подходящего профиля
				#ifdef DEBUG
					printf("Profile:\n");
					profile->show();
				#endif

				// проверяем совпадение сайта
				if(profile->UserId == currentSite->UserId)
				{
					if(profile->OwnSites == MTOP_NET_OWNSITES_NO)
					{
						#ifdef DEBUG
							printf("MTOP_NET_OWNSITES_NO, rejecting profile:\n");
						#endif
						continue;
					}
				}

				// проверяем день недели
				if(!(dayOfWeekBitArr[tmbuf->tm_wday] & profile->DayOfWeek))
				{
					#ifdef DEBUG
						printf("DayOfWeek, rejecting profile:\n");
					#endif
					continue;
				}
	
				// проверяем время суток
				if(!(timeBitArr[tmbuf->tm_wday] & profile->Time))
				{
					#ifdef DEBUG
						printf("Time, rejecting profile:\n");
					#endif
					continue;
				}

				// Проверяем директ-таргетинг (белый список)
				if(profile->TargetingWhiteNumber > 0)
				{
				  found = 0;
				  for(i = 0; i < profile->TargetingWhiteNumber; i++)
				  {
				  	if(profile->TargetingWhite[i] == currentSite->Id)
				  	{
				  	  found = 1;
				  		break;
				  	}
				  }
				  // не найдено в белом списке - пропускаем профиль
				  if(!found) continue;
				}

				// Проверяем директ-таргетинг (черный список)
				if(profile->TargetingBlackNumber > 0)
				{
				  found = 0;
				  for(i = 0; i < profile->TargetingBlackNumber; i++)
				  {
				  	if(profile->TargetingBlack[i] == currentSite->Id)
				  	{
				  	  found = 1;
				  		break;
				  	}
				  }
				  // найдено в черном списке - пропускаем профиль
				  if(found) continue;
				}

				// Проверяем таргетинг по рубрикам
				if(profile->TargetingRubricNumber > 0)
				{
				  found = 0;
				  for(i = 0; i < profile->TargetingRubricNumber; i++)
				  {
				  	if(profile->TargetingRubric[i] == currentSite->RubricId)
				  	{
				  	  found = 1;
				  		break;
				  	}
				  }
				  // не найдено в рубриках - пропускаем профиль
				  if(!found) continue;
				}

				// Проверяем геотаргетинг
				if(profile->TargetingAreaNumber > 0)
				{
				  found = 0;
				  for(i = 0; i < profile->TargetingAreaNumber; i++)
				  {
				  	if(profile->TargetingArea[i] == areaCodeId)
				  	{
				  	  found = 1;
				  		break;
				  	}
				  }
				  // не найдено в рубриках - пропускаем профиль
				  if(!found) continue;
				}

				// добавляем в массив проверенных профилей
				profileCheckedArr[profileCheckedNum++] = profile;
			}
		}

		#ifdef DEBUG
	  printf("Selected profiles:\n");
		for(i = 0; i < profileCheckedNum; i++)
		{
		  profileCheckedArr[i]->show();
		}
		#endif

		// Перебираем баннеры и составляем массив сумм
		#ifdef DEBUG
		  printf("Total banners. bannerNum=%d\n", bannerNum);
		#endif
		if(!error)
		{
			for(banner = bannerList; banner != NULL; banner = banner->next)
			{
			  if( (banner->NetworkId == currentSite->NetworkId) && (banner->Priority > 0) )
			  {
					#ifdef DEBUG
					  printf("Banner:\n");
					  banner->show();
					#endif
			    found = 1;
			    // поиск в массиве подходящих профилей
					for(i = 0; i < profileCheckedNum; i++)
					{
					  profile = profileCheckedArr[i];
						if(banner->ProfileId == profile->Id)
						{
						  if(profile->OwnSites == MTOP_NET_OWNSITES_CHECK)
						  { // Требуется проверка URL сайта и баннера
							  if(strcmp(banner->HrefHash, currentSite->UrlHash) == 0)
							  { // URL совпадают, баннер не подходит
									found = 0;
									#ifdef DEBUG
									  printf("OwnSites == MTOP_NET_OWNSITES_CHECK, HrefHash = UrlHash, found = 0\n\n");
									#endif
							  	break;
							  }
							}
						  if( (profile->OwnSites == MTOP_NET_OWNSITES_NO) && (currentSite->UserId == profile->UserId))
						  { // Показ на своих сайтах запрещен
								#ifdef DEBUG
								  printf("MTOP_NET_OWNSITES_NO, Site->UserId = profile->UserId\n\n");
								#endif
						  	found = 0;
								break;
							}
						}
					}

					// баннер в профиле и подходит для показа
					if(found)
					{
					  // Добавляем баннер к массиву проверенных
					  newPriority = (int)(banner->Priority*200);
						bannerCheckedArr[bannerCheckedNum].banner = banner;
						bannerCheckedArr[bannerCheckedNum].Priority = prioritySumm + newPriority;
						prioritySumm += newPriority;

						#ifdef DEBUG
							printf("added banner to bannerCheckedArr[%d], ", bannerCheckedNum);
						  printf("Id: %d, ", banner->Id);
							printf("PrioritySumm: %d\n\n", prioritySumm);
						#endif

						bannerCheckedNum++;
						//
					}
				}
			}
		}

		// Цикл показов баннера
		for(j = 0; (j < bannerShowNum) && (j < MTOP_MAX_BANNER_NUM); j++)
		{
			// Если хотя бы один баннер можно показать
			if((bannerCheckedNum > 0) && (prioritySumm > 0))
			{
				rnd = genrand_int32();			// генерация случайного числа (скорость - ~10 млн. раз в сек)
				trafficKey = rnd;						// ключ для записи в базу трафика

				// Выбираем случайное целое число из интервала [0, prioritySumm-1]
				// можно попробовать заменить на (int)genrand_real2()*prioritySumm
				// т.е. rnd [0,1) * prioritySumm
				if(!error)
				{
					rnd = rnd % prioritySumm;
				}

				// определяем выпавший баннер
				if(!error)
				{
					for(i = 0; i < bannerCheckedNum; i++)
					{
						if(rnd < bannerCheckedArr[i].Priority)
						{
						  currentBanner = bannerCheckedArr[i].banner;
							break;
						}
					}
				}

				// Передача данных обработчику статистики
				if(!error)
				{
					currentShow.Type = mtop_signature_show;
					currentShow.SiteId = siteId;
					currentShow.AccountId = accountId;
					currentShow.NetworkId = currentSite->NetworkId;
					currentShow.BannerId = currentBanner->Id;
					currentShow.BannerAccountId = currentBanner->AccountId;
					currentShow.IP = ipaton(remote_addr);
					currentShow.Key = trafficKey;

				  p = getenv("HTTP_REFERER");
					if(p != NULL)
					{
					  strncpy(currentShow.Referer, p, 128);
					}

					// Находим и записываем AreaId
					for(i = 0; i < areaCodeNumber; i++)
					{
						if(areaCodeArr[i] == areaCodeId)
						{
							currentShow.AreaId = i;
							break;
						}
					}
				
					// Запись в канал
					if(write(fd, &currentShow, sizeof(TRAFFIC)) == -1)
					{
						#ifdef DEBUG
							printf("ERROR writing\n");
						#endif
					}
				}
			}
			//

			// Вывод отклика
			if((currentBanner != NULL) && !error)
			{ // баннер найден
				#ifdef DEBUG
					printf("\n-----------------\nSHOW BANNER:\n");
				  currentBanner->show();
				#endif

				switch(outputCodeType)
				{
					case CODE_IFRAME:
					{
					  if(j == 0)
					  {
							printf("Content-type: text/html\r\n\r\n");
						}
						printf("<html><head><title></title></head><body leftmargin=0 topmargin=0 marginwidth=0 marginheight=0><a href=\"http://nw.mtop.ru/go.cgi?%u;%u;%u\" target=\"_blank\"><img src=\"http://mtop.ru/i/%s\" width=%d height=%d border=0 alt=\"%s\"></a><br></body></html>\n", currentBanner->Id, siteId, trafficKey, currentBanner->File, currentSite->XSize, currentSite->YSize, currentBanner->String);
					 	break;
					}
					case CODE_TEXT:
					{
					  if(j == 0)
					  {
							printf("Content-type: application/x-javascript\r\n\r\n");
						}
						printf("document.write('<a href=\"http://nw.mtop.ru/go.cgi?%u;%u;%u\" target=\"_blank\">%s</a><br>');\r\n", currentBanner->Id, siteId, trafficKey, currentBanner->String);
					 	break;
					}
					case CODE_WAP:
					{
					  printf("Location: http://mtop.ru/i/%s\r\n\r\n", currentBanner->File);
					 	break;
					}
					case CODE_TEXT_PHP:
					{
					  if(j == 0)
					  {
							printf("Content-type: text/plain\r\n\r\n");
						}
						printf("<a href=\"http://nw.mtop.ru/go.cgi?%u;%u;%u\" target=\"_blank\">%s</a>\n", currentBanner->Id, siteId, trafficKey, currentBanner->String);
					 	break;
					}
				}
			}
			else
			{ // нет ни одного подходящего баннера или возникла ошибка
				// показываем загрушку для данной сети
			  if(j == 0)
			  {
					printf("Content-type: text/html\r\n\r\n");
				}
				if(currentSite != NULL)
				{
					#ifdef DEBUG
						printf("No banner found\n");
					#endif
					show_default_banner(currentSite->NetworkId, outputCodeType);
				}
				else
				{ // не найден даже сайт
					#ifdef DEBUG
						printf("No banner found, no site found\n");
					#endif
					show_default_banner();
				}
			}
		}
		//

		#ifdef DEBUG
			printf("Process ID: %d\n", getpid());
			gettimeofday(&end_time, NULL);
			double timediff = (end_time.tv_sec - start_time.tv_sec) + ((double)end_time.tv_usec - (double)start_time.tv_usec)/1000000;
			printf("main while{} time: %f seconds\n", timediff);
		#endif
	}

/////// ДЕИНИЦИАЛИЗАЦИЯ: закрываем соединение с MySQL, освобождаем память

  // Закываем соединение с MySQL
  mysql_close(connection);

  // Освобождаем память
	delete query;
	delete query_string;
	delete remote_addr;
	delete areaCodeArr;

	// Закрываем базу GeoIP
	GeoIP_delete(gi);

	return 0;
}
Esempio n. 17
0
const char *ip_to_city(const char *ip) {
    if(!geocity) return "Unknown";
    GeoIPRecord *r = GeoIP_record_by_addr(geocity, ip);
    const char *city = (r && r->city) ? r->city : "Unknown";
    return city;
}
Esempio n. 18
0
short int GeoIP_update_database_general (char * user_id,char * license_key,char *data_base_type, int verbose,char ** client_ipaddr, void (*f)( char *)) {
	struct hostent *hostlist;
	int sock;
	char * buf;
	struct sockaddr_in sa;
	int offset = 0, err;
	char * request_uri;
	char * compr;
	unsigned long comprLen;
	FILE *comp_fh, *cur_db_fh, *gi_fh;
	gzFile gz_fh;
	char * file_path_gz, * file_path_test;
	MD5_CONTEXT context;
	MD5_CONTEXT context2;
	unsigned char buffer[1024], digest[16] ,digest2[16];
	char hex_digest[33] = "0000000000000000000000000000000\0";
	char hex_digest2[33] = "0000000000000000000000000000000\0";
	unsigned int i;
	char *f_str;
	GeoIP * gi;
	char * db_info;
	char *ipaddress;
	char *geoipfilename;
	char *tmpstr;
	int dbtype;
	int lookupresult = 1;
	char block[BLOCK_SIZE];
	int block_size = BLOCK_SIZE;
	size_t len;
	size_t request_uri_len;
	size_t size;

	hostlist = GeoIP_get_host_or_proxy();

	if (hostlist == NULL)
		return GEOIP_DNS_ERR;

	if (hostlist->h_addrtype != AF_INET)
		return GEOIP_NON_IPV4_ERR;
	if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
		return GEOIP_SOCKET_OPEN_ERR;
	}

	memset(&sa, 0, sizeof(struct sockaddr_in));
	sa.sin_port = htons(GeoIPHTTPPort);
	memcpy(&sa.sin_addr, hostlist->h_addr_list[0], hostlist->h_length);
	sa.sin_family = AF_INET;
	
	if (verbose == 1) {
		GeoIP_printf(f,"Connecting to MaxMind GeoIP server\n");
		GeoIP_printf(f, "via Host or Proxy Server: %s:%d\n", hostlist->h_name, GeoIPHTTPPort);
	}
	
	if (connect(sock, (struct sockaddr *)&sa, sizeof(struct sockaddr))< 0)
		return GEOIP_CONNECTION_ERR;
	request_uri = malloc(sizeof(char) * (strlen(license_key) + strlen(GeoIPHTTPRequestMD5)+1036));
	if (request_uri == NULL)
		return GEOIP_OUT_OF_MEMORY_ERR;

	/* get the file name from a web page using the product id */
	sprintf(request_uri,GeoIPHTTPRequestFilename,GeoIPProxyHTTP,GeoIPProxiedHost,data_base_type,GeoIPUpdateHost);
	if (verbose == 1) {
		GeoIP_printf(f, "sending request %s \n",request_uri);
	}
	send(sock, request_uri, strlen(request_uri),0); /* send the request */
	free(request_uri);
	buf = malloc(sizeof(char) * (block_size+4));
	if (buf == NULL)
		return GEOIP_OUT_OF_MEMORY_ERR;
	offset = 0;
	for (;;){
		int amt;
		amt = recv(sock, &buf[offset], block_size,0); 
		if (amt == 0){
			break;
		} else if (amt == -1) {
			free(buf);
			return GEOIP_SOCKET_READ_ERR;
		}
		offset += amt;
		buf = realloc(buf, offset + block_size + 4);
	}
	buf[offset] = 0;
	offset = 0;
	tmpstr = strstr(buf, "\r\n\r\n") + 4;
	if (tmpstr[0] == '.' || strchr(tmpstr, '/') != NULL) {
		free(buf);
		return GEOIP_INVALID_SERVER_RESPONSE;
	}
	geoipfilename = _GeoIP_full_path_to(tmpstr);
	free(buf);

	/* print the database product id and the database filename */
	if (verbose == 1){
		GeoIP_printf(f, "database product id %s database file name %s \n",data_base_type,geoipfilename);
	}
	_GeoIP_setup_dbfilename();

	/* get MD5 of current GeoIP database file */
	if ((cur_db_fh = fopen (geoipfilename, "rb")) == NULL) {
    GeoIP_printf(f, NoCurrentDB, geoipfilename);
	} else {
		md5_init(&context);
		while ((len = fread (buffer, 1, 1024, cur_db_fh)) > 0)
			md5_write (&context, buffer, len);
		md5_final (&context);
		memcpy(digest,context.buf,16);
		fclose (cur_db_fh);
		for (i = 0; i < 16; i++)
			sprintf (&hex_digest[2*i], "%02x", digest[i]);
    GeoIP_printf(f, MD5Info, hex_digest );
	}
	if (verbose == 1) {
		GeoIP_printf(f,"MD5 sum of database %s is %s \n",geoipfilename,hex_digest);
	}
	if (client_ipaddr[0] == NULL) {
		/* We haven't gotten our IP address yet, so let's request it */
		if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
			free(geoipfilename);
			return GEOIP_SOCKET_OPEN_ERR;
		}

		memset(&sa, 0, sizeof(struct sockaddr_in));
		sa.sin_port = htons(GeoIPHTTPPort);
		memcpy(&sa.sin_addr, hostlist->h_addr_list[0], hostlist->h_length);
		sa.sin_family = AF_INET;

		if (verbose == 1)
			GeoIP_printf(f,"Connecting to MaxMind GeoIP Update server\n");

		/* Download gzip file */
		if (connect(sock, (struct sockaddr *)&sa, sizeof(struct sockaddr))< 0) {
			free(geoipfilename);
			return GEOIP_CONNECTION_ERR;
		}
		request_uri = malloc(sizeof(char) * (strlen(license_key) + strlen(GeoIPHTTPRequestMD5)+1036));
		if (request_uri == NULL) {
			free(geoipfilename);
			return GEOIP_OUT_OF_MEMORY_ERR;
		}

		/* get client ip address from MaxMind web page */
		sprintf(request_uri,GeoIPHTTPRequestClientIP,GeoIPProxyHTTP,GeoIPProxiedHost,GeoIPUpdateHost);
		send(sock, request_uri, strlen(request_uri),0); /* send the request */
		if (verbose == 1) {
			GeoIP_printf(f, "sending request %s", request_uri);
		}
		free(request_uri);
		buf = malloc(sizeof(char) * (block_size+1));
		if (buf == NULL) {
			free(geoipfilename);
			return GEOIP_OUT_OF_MEMORY_ERR;
		}
		offset = 0;

		for (;;){
			int amt;
			amt = recv(sock, &buf[offset], block_size,0); 
			if (amt == 0) {
				break;
			} else if (amt == -1) {
				free(buf);
				return GEOIP_SOCKET_READ_ERR;
			}
			offset += amt;
			buf = realloc(buf, offset+block_size+1);
		}

		buf[offset] = 0;
		offset = 0;
		ipaddress = strstr(buf, "\r\n\r\n") + 4; /* get the ip address */
		ipaddress = malloc(strlen(strstr(buf, "\r\n\r\n") + 4)+5);
		strcpy(ipaddress,strstr(buf, "\r\n\r\n") + 4);
		client_ipaddr[0] = ipaddress;
		if (verbose == 1) {
			GeoIP_printf(f, "client ip address: %s\n",ipaddress);
		}
		free(buf);
		close(sock);
	}

	ipaddress = client_ipaddr[0];

	/* make a md5 sum of ip address and license_key and store it in hex_digest2 */
	request_uri_len = sizeof(char) * 2036;
	request_uri = malloc(request_uri_len);
	md5_init(&context2);
	md5_write (&context2, (byte *)license_key, 12);//add license key to the md5 sum
	md5_write (&context2, (byte *)ipaddress, strlen(ipaddress));//add ip address to the md5 sum
	md5_final (&context2);
	memcpy(digest2,context2.buf,16);
	for (i = 0; i < 16; i++)
		snprintf (&hex_digest2[2*i], 3, "%02x", digest2[i]);// change the digest to a hex digest
	if (verbose == 1) {
		GeoIP_printf(f, "md5sum of ip address and license key is %s \n",hex_digest2);
	}

	/* send the request using the user id,product id, 
	 * md5 sum of the prev database and 
	 * the md5 sum of the license_key and ip address */
	if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
		return GEOIP_SOCKET_OPEN_ERR;
	}
	memset(&sa, 0, sizeof(struct sockaddr_in));
	sa.sin_port = htons(GeoIPHTTPPort);
	memcpy(&sa.sin_addr, hostlist->h_addr_list[0], hostlist->h_length);
	sa.sin_family = AF_INET;
	if (connect(sock, (struct sockaddr *)&sa, sizeof(struct sockaddr))< 0)
		return GEOIP_CONNECTION_ERR;
	snprintf(request_uri, request_uri_len, GeoIPHTTPRequestMD5,GeoIPProxyHTTP,GeoIPProxiedHost,hex_digest,hex_digest2,user_id,data_base_type);
	send(sock, request_uri, strlen(request_uri),0);
	if (verbose == 1) {
		GeoIP_printf(f, "sending request %s\n",request_uri);
	}

	free(request_uri);

	offset = 0;
	buf = malloc(sizeof(char) * block_size);
	if (buf == NULL)
		return GEOIP_OUT_OF_MEMORY_ERR;

	if (verbose == 1)
		GeoIP_printf(f,"Downloading gzipped GeoIP Database...\n");

	for (;;) {
		int amt;
		amt = recv(sock, &buf[offset], block_size,0);

		if (amt == 0) {
			break;
		} else if (amt == -1) {
			free(buf);
			return GEOIP_SOCKET_READ_ERR;
		}
		offset += amt;
		buf = realloc(buf, offset+block_size);
		if (buf == NULL)
			return GEOIP_OUT_OF_MEMORY_ERR;
	}

	compr = strstr(buf, "\r\n\r\n") + 4;
	comprLen = offset + buf - compr;

	if (strstr(compr, "License Key Invalid") != NULL) {
		if (verbose == 1)
			GeoIP_printf(f,"Failed\n");
		free(buf);
		return GEOIP_LICENSE_KEY_INVALID_ERR;
	} else if (strstr(compr, "No new updates available") != NULL) {
		free(buf);
		GeoIP_printf(f, "%s is up to date, no updates required\n", geoipfilename);
		return GEOIP_NO_NEW_UPDATES;
	} else if (strstr(compr, "Invalid UserId") != NULL){
		free(buf);
		return GEOIP_USER_ID_INVALID_ERR;
	} else if (strstr(compr, "Invalid product ID or subscription expired") != NULL){
		free(buf);
		return GEOIP_PRODUCT_ID_INVALID_ERR;
	}

	if (verbose == 1)
		GeoIP_printf(f,"Done\n");

	GeoIP_printf(f, "Updating %s\n", geoipfilename);

	/* save gzip file */
	file_path_gz = malloc(sizeof(char) * (strlen(geoipfilename) + 4));

	if (file_path_gz == NULL)
		return GEOIP_OUT_OF_MEMORY_ERR;
	strcpy(file_path_gz,geoipfilename);
	strcat(file_path_gz,".gz");
	if (verbose == 1) {
    GeoIP_printf(f, "%s%s", SavingGzip, file_path_gz );
	}
	comp_fh = fopen(file_path_gz, "wb");

	if(comp_fh == NULL) {
		free(file_path_gz);
		free(buf);
		return GEOIP_GZIP_IO_ERR;
	}

	size = fwrite(compr, 1, comprLen, comp_fh);
	fclose(comp_fh);
	free(buf);
        if ( size != comprLen ) {
		return GEOIP_GZIP_IO_ERR;
	}

	if (verbose == 1) {
		GeoIP_printf(f, "download data to a gz file named %s \n",file_path_gz);
		GeoIP_printf(f,"Done\n");
		GeoIP_printf(f,"Uncompressing gzip file ... ");
	}

	file_path_test = malloc(sizeof(char) * (strlen(GeoIPDBFileName[GEOIP_COUNTRY_EDITION]) + 6));
	if (file_path_test == NULL) {
		free(file_path_gz);
		return GEOIP_OUT_OF_MEMORY_ERR;
	}
	strcpy(file_path_test,GeoIPDBFileName[GEOIP_COUNTRY_EDITION]);
	strcat(file_path_test,".test");
	gi_fh = fopen(file_path_test, "wb");
	if(gi_fh == NULL) {
		free(file_path_test);
		free(file_path_gz);
		return GEOIP_TEST_IO_ERR;
	}
	/* uncompress gzip file */
	offset = 0;
	gz_fh = gzopen(file_path_gz, "rb");
	for (;;) {
		int amt;
		amt = gzread(gz_fh, block, block_size);
		if (amt == -1) {
			free(file_path_gz);
			free(file_path_test);
			gzclose(gz_fh);
			fclose(gi_fh);
			return GEOIP_GZIP_READ_ERR;
		}
		if (amt == 0) {
			break;
		}
		if ( amt != fwrite(block,1,amt,gi_fh) ){
			return GEOIP_GZIP_IO_ERR;
		}
	}
	gzclose(gz_fh);
	unlink(file_path_gz);
	free(file_path_gz);
	fclose(gi_fh);

	if (verbose == 1)
		GeoIP_printf(f,"Done\n");

	if (verbose == 1) {
		len = strlen(WritingFile) + strlen(geoipfilename) - 1;
		f_str = malloc(len);
		snprintf(f_str,len,WritingFile,geoipfilename);
		free(f_str);
	}

	/* sanity check */
	gi = GeoIP_open(file_path_test, GEOIP_STANDARD);

	if (verbose == 1)
		GeoIP_printf(f,"Performing santity checks ... ");

	if (gi == NULL) {
		GeoIP_printf(f,"Error opening sanity check database\n");
		return GEOIP_SANITY_OPEN_ERR;
	}


	/* get the database type */
	dbtype = GeoIP_database_edition(gi);
	if (verbose == 1) {
		GeoIP_printf(f, "Database type is %d\n",dbtype);
	}

	/* this checks to make sure the files is complete, since info is at the end
		 dependent on future databases having MaxMind in info (ISP and Organization databases currently don't have info string */

	if ((dbtype != GEOIP_ISP_EDITION)&&
			(dbtype != GEOIP_ORG_EDITION)) {
		if (verbose == 1)
			GeoIP_printf(f,"database_info  ");
		db_info = GeoIP_database_info(gi);
		if (db_info == NULL) {
			GeoIP_delete(gi);
			if (verbose == 1)
				GeoIP_printf(f,"FAIL null\n");
			return GEOIP_SANITY_INFO_FAIL;
		}
		if (strstr(db_info, "MaxMind") == NULL) {
			free(db_info);
			GeoIP_delete(gi);
			if (verbose == 1)
				GeoIP_printf(f,"FAIL maxmind\n");
			return GEOIP_SANITY_INFO_FAIL;
		}
		free(db_info);
		if (verbose == 1)
			GeoIP_printf(f,"PASS  ");
	}

	/* this performs an IP lookup test of a US IP address */
	if (verbose == 1)
		GeoIP_printf(f,"lookup  ");
	if (dbtype == GEOIP_NETSPEED_EDITION) {
		int netspeed = GeoIP_id_by_name(gi,"24.24.24.24");
		lookupresult = 0;
		if (netspeed == GEOIP_CABLEDSL_SPEED){
			lookupresult = 1;
		}
	}
	if (dbtype == GEOIP_COUNTRY_EDITION) {
		/* if data base type is country then call the function
		 * named GeoIP_country_code_by_addr */
		lookupresult = 1;
		if (strcmp(GeoIP_country_code_by_addr(gi,"24.24.24.24"), "US") != 0) {
			lookupresult = 0;
		}
		if (verbose == 1) {
			GeoIP_printf(f,"testing GEOIP_COUNTRY_EDITION\n");
		}
	}
	if (dbtype == GEOIP_REGION_EDITION_REV1) {
		/* if data base type is region then call the function
		 * named GeoIP_region_by_addr */
		GeoIPRegion *r = GeoIP_region_by_addr(gi,"24.24.24.24");
		lookupresult = 0;
		if (r != NULL) {
			lookupresult = 1;
			free(r);
		}
		if (verbose == 1) {
			GeoIP_printf(f,"testing GEOIP_REGION_EDITION\n");
		}
	}
	if (dbtype == GEOIP_CITY_EDITION_REV1) {
		/* if data base type is city then call the function
		 * named GeoIP_record_by_addr */
		GeoIPRecord *r = GeoIP_record_by_addr(gi,"24.24.24.24");
		lookupresult = 0;
		if (r != NULL) {
			lookupresult = 1;
			free(r);
		}
		if (verbose == 1) {
			GeoIP_printf(f,"testing GEOIP_CITY_EDITION\n");
		}
	}
	if ((dbtype == GEOIP_ISP_EDITION)||
			(dbtype == GEOIP_ORG_EDITION)) {
		/* if data base type is isp or org then call the function
		 * named GeoIP_org_by_addr */
		GeoIPRecord *r = (GeoIPRecord*)GeoIP_org_by_addr(gi,"24.24.24.24");
		lookupresult = 0;
		if (r != NULL) {
			lookupresult = 1;
			free(r);
		}
		if (verbose == 1) {
			if (dbtype == GEOIP_ISP_EDITION) {
				GeoIP_printf(f,"testing GEOIP_ISP_EDITION\n");
			}
			if (dbtype == GEOIP_ORG_EDITION) {
				GeoIP_printf(f,"testing GEOIP_ORG_EDITION\n");
			}
		}
	}
	if (lookupresult == 0) {
		GeoIP_delete(gi);
		if (verbose == 1)
			GeoIP_printf(f,"FAIL\n");
		return GEOIP_SANITY_LOOKUP_FAIL;
	}
	GeoIP_delete(gi);
	if (verbose == 1)
		GeoIP_printf(f,"PASS\n");

	/* install GeoIP.dat.test -> GeoIP.dat */
	err = rename(file_path_test, geoipfilename);
	if (err != 0) {
		GeoIP_printf(f,"GeoIP Install error while renaming file\n");
		return GEOIP_RENAME_ERR;
	}

	if (verbose == 1)
		GeoIP_printf(f,"Done\n");
	free(geoipfilename);
	return 0;
}
Esempio n. 19
0
static int 
geoip_header_parser(request_rec * r)
{
	char           *orgorisp;
	char           *ipaddr;
	short int       country_id;
	GeoIP          *gip;
	const char     *continent_code;
	const char     *country_code;
	const char     *country_name;
	const char     *region_name;

	geoip_server_config_rec *cfg;

	unsigned char   databaseType;
	GeoIPRecord    *gir;
	GeoIPRegion    *giregion;
	int             i;
	int             netspeed;
	/* For splitting proxy headers */
	char           *ipaddr_ptr = 0;
	char           *comma_ptr;
	char           *found_ip;
	apr_sockaddr_t *sa;
	char           *hostname = 0;

	cfg = ap_get_module_config(r->server->module_config, &geoip_module);

	if (!cfg)
		return DECLINED;

	if (!cfg->scanProxyHeaders) {
		ipaddr = r->connection->remote_ip;
	}
	else {
		ap_add_common_vars(r);
		if (apr_table_get(r->subprocess_env, "HTTP_CLIENT_IP")) {
			ipaddr_ptr = (char *) apr_table_get(r->subprocess_env, "HTTP_CLIENT_IP");
		}
		else if (apr_table_get(r->subprocess_env, "HTTP_X_FORWARDED_FOR")) {
			ipaddr_ptr = (char *) apr_table_get(r->subprocess_env, "HTTP_X_FORWARDED_FOR");
		}
		else if (apr_table_get(r->headers_in, "X-Forwarded-For")) {
			ipaddr_ptr = (char *) apr_table_get(r->headers_in, "X-Forwarded-For");
		}
		else if (apr_table_get(r->subprocess_env, "HTTP_REMOTE_ADDR")) {
			ipaddr_ptr = (char *) apr_table_get(r->subprocess_env, "HTTP_REMOTE_ADDR");
		}
		if (!ipaddr_ptr) {
			ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r->server, "[mod_geoip]: Error while getting ipaddr from proxy headers. Using REMOTE_ADDR.");
			ipaddr = r->connection->remote_ip;
		}
		else {
			ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r->server, "[mod_geoip]: IPADDR_PTR: %s", ipaddr_ptr);

			if (cfg->use_left_public_x_forwarded_for_ip) {
				// find the first public IP address in a potentially comma-separated list,
				// fall back to remote_ip if we can't find one
				ipaddr = first_public_ip_in_list(ipaddr_ptr, r->connection->remote_ip);
			} else {
				// leaving some of the following inconsistent indenting intact for easier diff to original maxmind src

                       /*
                        * Check to ensure that the HTTP_CLIENT_IP or
                        * X-Forwarded-For header is not a comma separated
                        * list of addresses, which would cause mod_geoip to
                        * return no country code. If the header is a comma
                        * separated list, return the first IP address in the
                        * list, which is (hopefully!) the real client IP.
                        */
                        ipaddr = (char *) calloc(8*4+7+1, sizeof(char));

                        if (cfg->use_last_x_forwarded_for_ip ){
                                comma_ptr = strrchr(ipaddr_ptr, ',');
                                if ( comma_ptr ) {
                                        /* skip over whitespace */
                                        ipaddr_ptr = comma_ptr + strspn(comma_ptr, ", \t");
                                }
                        }

                        strncpy(ipaddr, ipaddr_ptr, 8*4+7);
                        comma_ptr = strchr(ipaddr, ',');
                        if (comma_ptr != 0)
                                *comma_ptr = '\0';
			}
 		}
	}

/* this block should be removed! */
#if 1
	if (!cfg->gips) {
		if (cfg->GeoIPFilenames != NULL) {
			cfg->gips = malloc(sizeof(GeoIP *) * cfg->numGeoIPFiles);
			for (i = 0; i < cfg->numGeoIPFiles; i++) {
				cfg->gips[i] = GeoIP_open(cfg->GeoIPFilenames[i], (cfg->GeoIPFlags2[i] == GEOIP_UNKNOWN) ? cfg->GeoIPFlags : cfg->GeoIPFlags2[i]);

				if (cfg->gips[i]) {
					if (cfg->GeoIPEnableUTF8) {
						GeoIP_set_charset(cfg->gips[i], GEOIP_CHARSET_UTF8);
					}
				}
				else {
					ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, "[mod_geoip]: Error while opening data file %s", cfg->GeoIPFilenames[i]);
					return DECLINED;
				}
			}
		}
		else {
			cfg->gips = malloc(sizeof(GeoIP *));
			cfg->gips[0] = GeoIP_new(GEOIP_STANDARD);
			if (!cfg->gips[0]) {
				ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, "[mod_geoip]: Error while opening data file");
				return DECLINED;
			}
			cfg->numGeoIPFiles = 1;
		}
	}
#endif

	if (cfg->GeoIPEnableHostnameLookups
			&& apr_sockaddr_info_get(&sa, ipaddr, APR_INET, 0, 0, r->pool) == APR_SUCCESS
			&& apr_getnameinfo(&hostname, sa, 0) == APR_SUCCESS) {
		ap_str_tolower(hostname);
	}

	if (!hostname)
		hostname = ipaddr;

	if (cfg->GeoIPOutput & GEOIP_NOTES) {
		apr_table_setn(r->notes, "GEOIP_ADDR", ipaddr);
		apr_table_setn(r->notes, "GEOIP_HOST", hostname);
	}
	if (cfg->GeoIPOutput & GEOIP_ENV) {
		apr_table_setn(r->subprocess_env, "GEOIP_ADDR", ipaddr);
		apr_table_setn(r->subprocess_env, "GEOIP_HOST", hostname);
	}

	for (i = 0; i < cfg->numGeoIPFiles; i++) {

		/*
		 * skip database handles that can not be opned for some
		 * reason
		 */
		if (cfg->gips[i] == NULL)
			continue;

		databaseType = cfg->gips[i] ? GeoIP_database_edition(cfg->gips[i]) : -1;	/* -1 is "magic value"
												 * in case file not
												 * found */
		switch (databaseType) {
                case GEOIP_NETSPEED_EDITION_REV1:
                  orgorisp = GeoIP_name_by_addr(cfg->gips[i], ipaddr);
                  if (orgorisp != NULL) {
   	            if (cfg->GeoIPOutput & GEOIP_NOTES) {
	              apr_table_setn(r->notes, "GEOIP_NETSPEED", orgorisp);
	            }
	            if (cfg->GeoIPOutput & GEOIP_ENV) {
	              apr_table_setn(r->subprocess_env, "GEOIP_NETSPEED", orgorisp);
	            }
                  }
                break;
 
		case GEOIP_NETSPEED_EDITION:
			netspeed = GeoIP_id_by_addr(cfg->gips[i], ipaddr);
			if (netspeed == GEOIP_UNKNOWN_SPEED) {
				netspeedstring = "unknown";
			}
			else if (netspeed == GEOIP_DIALUP_SPEED) {
				netspeedstring = "dialup";
			}
			else if (netspeed == GEOIP_CABLEDSL_SPEED) {
				netspeedstring = "cabledsl";
			}
			else if (netspeed == GEOIP_CORPORATE_SPEED) {
				netspeedstring = "corporate";
			}
			if (cfg->GeoIPOutput & GEOIP_NOTES) {
				apr_table_setn(r->notes, "GEOIP_NETSPEED", netspeedstring);
			}
			if (cfg->GeoIPOutput & GEOIP_ENV) {
				apr_table_setn(r->subprocess_env, "GEOIP_NETSPEED", netspeedstring);
			}
			break;
		case GEOIP_COUNTRY_EDITION_V6:
			/* Get the Country ID */
			country_id = GeoIP_country_id_by_addr_v6(cfg->gips[i], ipaddr);

      if ( country_id > 0 ) {
			  /* Lookup the Code and the Name with the ID */
			  continent_code = GeoIP_country_continent[country_id];
			  country_code = GeoIP_country_code[country_id];
			  country_name = GeoIP_country_name[country_id];

			  if (cfg->numGeoIPFiles == 0) {
				  cfg->numGeoIPFiles = 0;
			  }
			  if (cfg->GeoIPFilenames == 0) {
				  cfg->GeoIPFilenames = 0;
			  }
			  /* Set it for our user */
			  if (cfg->GeoIPOutput & GEOIP_NOTES) {
				  apr_table_setn(r->notes, "GEOIP_CONTINENT_CODE_V6", continent_code);
		  		apr_table_setn(r->notes, "GEOIP_COUNTRY_CODE_V6", country_code);
			  	apr_table_setn(r->notes, "GEOIP_COUNTRY_NAME_V6", country_name);
			  }
			  if (cfg->GeoIPOutput & GEOIP_ENV) {
				  apr_table_setn(r->subprocess_env, "GEOIP_CONTINENT_CODE_V6", continent_code);
				  apr_table_setn(r->subprocess_env, "GEOIP_COUNTRY_CODE_V6", country_code);
				  apr_table_setn(r->subprocess_env, "GEOIP_COUNTRY_NAME_V6", country_name);
			  }
			}
			break;
		case GEOIP_COUNTRY_EDITION:
			/* Get the Country ID */
			country_id = GeoIP_country_id_by_addr(cfg->gips[i], ipaddr);

      if ( country_id > 0 ) {
			  /* Lookup the Code and the Name with the ID */
			  continent_code = GeoIP_country_continent[country_id];
			  country_code = GeoIP_country_code[country_id];
			  country_name = GeoIP_country_name[country_id];

			  if (cfg->numGeoIPFiles == 0) {
				  cfg->numGeoIPFiles = 0;
			  }
			  if (cfg->GeoIPFilenames == 0) {
				  cfg->GeoIPFilenames = 0;
			  }
			  /* Set it for our user */
			  if (cfg->GeoIPOutput & GEOIP_NOTES) {
				  apr_table_setn(r->notes, "GEOIP_CONTINENT_CODE", continent_code);
		  		apr_table_setn(r->notes, "GEOIP_COUNTRY_CODE", country_code);
			  	apr_table_setn(r->notes, "GEOIP_COUNTRY_NAME", country_name);
			  }
			  if (cfg->GeoIPOutput & GEOIP_ENV) {
				  apr_table_setn(r->subprocess_env, "GEOIP_CONTINENT_CODE", continent_code);
				  apr_table_setn(r->subprocess_env, "GEOIP_COUNTRY_CODE", country_code);
				  apr_table_setn(r->subprocess_env, "GEOIP_COUNTRY_NAME", country_name);
			  }
			}
			break;
		case GEOIP_REGION_EDITION_REV0:
		case GEOIP_REGION_EDITION_REV1:
			giregion = GeoIP_region_by_name(cfg->gips[i], ipaddr);
			if (giregion != NULL) {
			  if ( giregion->country_code[0] ) {
			    region_name = GeoIP_region_name_by_code(giregion->country_code, giregion->region);
			  }
				if (cfg->GeoIPOutput & GEOIP_NOTES) {
					if ( giregion->country_code[0] ){
						apr_table_set(r->notes, "GEOIP_COUNTRY_CODE", giregion->country_code);
					}
					if (giregion->region[0]) {
						apr_table_set(r->notes, "GEOIP_REGION", giregion->region);
					}
					if ( region_name != NULL ){
					  apr_table_set(r->notes, "GEOIP_REGION_NAME", region_name);
					}
				}
				if (cfg->GeoIPOutput & GEOIP_ENV) {
					if ( giregion->country_code[0] ){
						apr_table_set(r->subprocess_env, "GEOIP_COUNTRY_CODE", giregion->country_code);
					}
					if (giregion->region[0]) {
					      apr_table_set(r->subprocess_env, "GEOIP_REGION", giregion->region);
					}
					if ( region_name != NULL ){
					  apr_table_set(r->subprocess_env, "GEOIP_REGION_NAME", region_name);
					}
				}
				GeoIPRegion_delete(giregion);
			}
			break;
		case GEOIP_CITY_EDITION_REV0_V6:
		case GEOIP_CITY_EDITION_REV1_V6:
			gir = GeoIP_record_by_addr_v6(cfg->gips[i], ipaddr);
			if (gir != NULL) {
			        if ( gir->country_code != NULL ) {
				  region_name = GeoIP_region_name_by_code(gir->country_code, gir->region);
				}
				sprintf(metrocodestr, "%d", gir->dma_code);
				sprintf(areacodestr, "%d", gir->area_code);
				if (cfg->GeoIPOutput & GEOIP_NOTES) {
					apr_table_setn(r->notes, "GEOIP_CONTINENT_CODE_V6", gir->continent_code);
					apr_table_setn(r->notes, "GEOIP_COUNTRY_CODE_V6", gir->country_code);
					apr_table_setn(r->notes, "GEOIP_COUNTRY_NAME_V6", gir->country_name);
					if (gir->region != NULL) {
						apr_table_set(r->notes, "GEOIP_REGION_V6", gir->region);
						if ( region_name != NULL ){
						  apr_table_set(r->notes, "GEOIP_REGION_NAME_V6", region_name);
						}
					}
					if (gir->city != NULL) {
						apr_table_set(r->notes, "GEOIP_CITY_V6", gir->city);
					}
					apr_table_setn(r->notes, "GEOIP_DMA_CODE_V6", metrocodestr);
					apr_table_setn(r->notes, "GEOIP_METRO_CODE_V6", metrocodestr);
					apr_table_setn(r->notes, "GEOIP_AREA_CODE_V6", areacodestr);
				}
				if (cfg->GeoIPOutput & GEOIP_ENV) {
					apr_table_setn(r->subprocess_env, "GEOIP_CONTINENT_CODE_V6", gir->continent_code);
					apr_table_setn(r->subprocess_env, "GEOIP_COUNTRY_CODE_V6", gir->country_code);
					apr_table_setn(r->subprocess_env, "GEOIP_COUNTRY_NAME_V6", gir->country_name);
					if (gir->region != NULL) {
						apr_table_set(r->subprocess_env, "GEOIP_REGION_V6", gir->region);
						if ( region_name != NULL ){
						  apr_table_set(r->subprocess_env, "GEOIP_REGION_NAME_V6", region_name);
						}
					}
					if (gir->city != NULL) {
						apr_table_set(r->subprocess_env, "GEOIP_CITY_V6", gir->city);
					}
					apr_table_setn(r->subprocess_env, "GEOIP_DMA_CODE_V6", metrocodestr);
					apr_table_setn(r->subprocess_env, "GEOIP_METRO_CODE_V6", metrocodestr);
					apr_table_setn(r->subprocess_env, "GEOIP_AREA_CODE_V6", areacodestr);
				}
				sprintf(latstr, "%f", gir->latitude);
				sprintf(lonstr, "%f", gir->longitude);
				if (cfg->GeoIPOutput & GEOIP_NOTES) {
					apr_table_setn(r->notes, "GEOIP_LATITUDE_V6", latstr);
				}
				if (cfg->GeoIPOutput & GEOIP_ENV) {
					apr_table_setn(r->subprocess_env, "GEOIP_LATITUDE_V6", latstr);
				}
				if (cfg->GeoIPOutput & GEOIP_NOTES) {
					apr_table_setn(r->notes, "GEOIP_LONGITUDE_V6", lonstr);
				}
				if (cfg->GeoIPOutput & GEOIP_ENV) {
					apr_table_setn(r->subprocess_env, "GEOIP_LONGITUDE_V6", lonstr);
				}
				if (gir->postal_code != NULL) {
					if (cfg->GeoIPOutput & GEOIP_NOTES) {
						apr_table_set(r->notes, "GEOIP_POSTAL_CODE_V6", gir->postal_code);
					}
					if (cfg->GeoIPOutput & GEOIP_ENV) {
						apr_table_set(r->subprocess_env, "GEOIP_POSTAL_CODE_V6", gir->postal_code);
					}
				}
				GeoIPRecord_delete(gir);
			}
			break;
		case GEOIP_CITY_EDITION_REV0:
		case GEOIP_CITY_EDITION_REV1:
			gir = GeoIP_record_by_addr(cfg->gips[i], ipaddr);
			if (gir != NULL) {
			        if ( gir->country_code != NULL ) {
				  region_name = GeoIP_region_name_by_code(gir->country_code, gir->region);
				}
				sprintf(metrocodestr, "%d", gir->dma_code);
				sprintf(areacodestr, "%d", gir->area_code);
				if (cfg->GeoIPOutput & GEOIP_NOTES) {
					apr_table_setn(r->notes, "GEOIP_CONTINENT_CODE", gir->continent_code);
					apr_table_setn(r->notes, "GEOIP_COUNTRY_CODE", gir->country_code);
					apr_table_setn(r->notes, "GEOIP_COUNTRY_NAME", gir->country_name);
					if (gir->region != NULL) {
						apr_table_set(r->notes, "GEOIP_REGION", gir->region);
						if ( region_name != NULL ){
						  apr_table_set(r->notes, "GEOIP_REGION_NAME", region_name);
						}
					}
					if (gir->city != NULL) {
						apr_table_set(r->notes, "GEOIP_CITY", gir->city);
					}
					apr_table_setn(r->notes, "GEOIP_DMA_CODE", metrocodestr);
					apr_table_setn(r->notes, "GEOIP_METRO_CODE", metrocodestr);
					apr_table_setn(r->notes, "GEOIP_AREA_CODE", areacodestr);
				}
				if (cfg->GeoIPOutput & GEOIP_ENV) {
					apr_table_setn(r->subprocess_env, "GEOIP_CONTINENT_CODE", gir->continent_code);
					apr_table_setn(r->subprocess_env, "GEOIP_COUNTRY_CODE", gir->country_code);
					apr_table_setn(r->subprocess_env, "GEOIP_COUNTRY_NAME", gir->country_name);
					if (gir->region != NULL) {
						apr_table_set(r->subprocess_env, "GEOIP_REGION", gir->region);
						if ( region_name != NULL ){
						  apr_table_set(r->subprocess_env, "GEOIP_REGION_NAME", region_name);
						}
					}
					if (gir->city != NULL) {
						apr_table_set(r->subprocess_env, "GEOIP_CITY", gir->city);
					}
					apr_table_setn(r->subprocess_env, "GEOIP_DMA_CODE", metrocodestr);
					apr_table_setn(r->subprocess_env, "GEOIP_METRO_CODE", metrocodestr);
					apr_table_setn(r->subprocess_env, "GEOIP_AREA_CODE", areacodestr);
				}
				sprintf(latstr, "%f", gir->latitude);
				sprintf(lonstr, "%f", gir->longitude);
				if (cfg->GeoIPOutput & GEOIP_NOTES) {
					apr_table_setn(r->notes, "GEOIP_LATITUDE", latstr);
				}
				if (cfg->GeoIPOutput & GEOIP_ENV) {
					apr_table_setn(r->subprocess_env, "GEOIP_LATITUDE", latstr);
				}
				if (cfg->GeoIPOutput & GEOIP_NOTES) {
					apr_table_setn(r->notes, "GEOIP_LONGITUDE", lonstr);
				}
				if (cfg->GeoIPOutput & GEOIP_ENV) {
					apr_table_setn(r->subprocess_env, "GEOIP_LONGITUDE", lonstr);
				}
				if (gir->postal_code != NULL) {
					if (cfg->GeoIPOutput & GEOIP_NOTES) {
						apr_table_set(r->notes, "GEOIP_POSTAL_CODE", gir->postal_code);
					}
					if (cfg->GeoIPOutput & GEOIP_ENV) {
						apr_table_set(r->subprocess_env, "GEOIP_POSTAL_CODE", gir->postal_code);
					}
				}
				GeoIPRecord_delete(gir);
			}
			break;
		case GEOIP_ORG_EDITION:
			orgorisp = GeoIP_name_by_addr(cfg->gips[i], ipaddr);
			if (orgorisp != NULL) {
				if (cfg->GeoIPOutput & GEOIP_NOTES) {
					apr_table_setn(r->notes, "GEOIP_ORGANIZATION", orgorisp);
				}
				if (cfg->GeoIPOutput & GEOIP_ENV) {
					apr_table_setn(r->subprocess_env, "GEOIP_ORGANIZATION", orgorisp);
				}
			}
			break;
		case GEOIP_ISP_EDITION:
			orgorisp = GeoIP_name_by_addr(cfg->gips[i], ipaddr);
			if (orgorisp != NULL) {
				if (cfg->GeoIPOutput & GEOIP_NOTES) {
					apr_table_setn(r->notes, "GEOIP_ISP", orgorisp);
				}
				if (cfg->GeoIPOutput & GEOIP_ENV) {
					apr_table_setn(r->subprocess_env, "GEOIP_ISP", orgorisp);
				}
			}
			break;
		case GEOIP_DOMAIN_EDITION:
			orgorisp = GeoIP_name_by_addr(cfg->gips[i], ipaddr);
			if (orgorisp != NULL) {
				if (cfg->GeoIPOutput & GEOIP_NOTES) {
					apr_table_setn(r->notes, "GEOIP_DOMAIN", orgorisp);
				}
				if (cfg->GeoIPOutput & GEOIP_ENV) {
					apr_table_setn(r->subprocess_env, "GEOIP_DOMAIN", orgorisp);
				}
			}
			break;
		}
	}

	return OK;
}
Esempio n. 20
0
char *geo_lookup(GeoIP *gi, char *ipaddr, int bird) {
	/*
	 * Lookup the country_code by ip address, we can
	 * extend this in the future with more granular data
	 * such as region,city or even zipcode.
	 */
	static char area[MAX_BUF_LENGTH];

	// set the charset to UTF8
	GeoIP_set_charset(gi, GEOIP_CHARSET_UTF8);

	switch(bird){
		case COUNTRY: {
			const char *country= GeoIP_country_code_by_addr(gi, ipaddr);
			if (country==NULL){
				strncpy(area, unknown_geography, MAX_BUF_LENGTH);
			} else {
				strncpy(area, country, MAX_BUF_LENGTH);
			}

		}
		break;

		case REGION:{
			GeoIPRegion *gir;
			gir=GeoIP_region_by_addr(gi,ipaddr);
			if(gir == NULL || strlen(gir->region)==0){
				strncpy(area, unknown_geography, MAX_BUF_LENGTH);
			} else {
				strncpy(area, gir->region, MAX_BUF_LENGTH);
			}

			if(gir != NULL) {
				GeoIPRegion_delete(gir);
			}
			break;
		}

		case CITY:{
			GeoIPRecord *grecord;
			char *city;
			int mustFreeCity = 0;
			grecord = GeoIP_record_by_addr(gi, ipaddr);
			if (grecord !=NULL){
				if (grecord->city == NULL){
					strncpy(area, unknown_geography, MAX_BUF_LENGTH);
				} else {
					int len = strlen(grecord->city);
					city = strdup(grecord->city);
					mustFreeCity = 1;
					strncpy(area,city, MAX_BUF_LENGTH);
					replace_space_with_underscore(area, len);
				}
				if (mustFreeCity) {
					free(city);
				}
				GeoIPRecord_delete(grecord);
			} else {
				strncpy(area, unknown_geography, MAX_BUF_LENGTH);
			}
			break;
		}

		case LAT_LON: {
			GeoIPRecord *grecord;
			grecord = GeoIP_record_by_addr(gi, ipaddr);
			if (grecord!=NULL){
				snprintf(area, MAX_BUF_LENGTH, "%f,%f", grecord->latitude, grecord->longitude);
				GeoIPRecord_delete(grecord);
			} else {
				strncpy(area, unknown_geography, MAX_BUF_LENGTH);
			}
			break;
		}

		case EVERYTHING: {
			GeoIPRecord *grecord;
			char *country = unknown_geography, *region = unknown_geography, *city = unknown_geography;
			int mustFreeCity = 0;
			float lat = 0.0, lon = 0.0;
			grecord = GeoIP_record_by_addr(gi, ipaddr);
			if (grecord != NULL) {
				if (grecord->city != NULL) {
					city = strdup(grecord->city);
					mustFreeCity = 1;
				}
				replace_space_with_underscore(city, strlen(city));

				if (grecord->region != NULL) {
					region = grecord->region;
				}
				if (grecord->country_code != NULL) {
					country = grecord->country_code;
				}
				lat = grecord->latitude;
				lon = grecord->longitude;
			}
			snprintf(area, MAX_BUF_LENGTH, "%s|%s|%s|%f,%f", country, region, city, lat, lon);

			if (grecord != NULL) {
				GeoIPRecord_delete(grecord);
			}

			if (mustFreeCity) {
				free(city);
			}
			break;
		}

		default:
			break;
	}
	return area;
}