public Dictionary <string, object> GetIPInfo(string IP) { Dictionary <string, object> buf = new Dictionary <string, object>(); string NormalForm = string.Empty; string InputIP = string.Empty; if (!IPConverter.IsIP(IP)) { buf.Add("ip", IP); buf.Add("status", "ERROR: Not valid IP address"); return(buf); } NormalForm = IPConverter.ToStandForm(IP); if (NormalForm != IP) { InputIP = IP; IP = NormalForm; } string spec = CheckSpecDiaps(IP); if (spec != string.Empty) { buf.Add("ip", IP); if (InputIP != string.Empty) { buf.Add("input_ip", InputIP); } buf.Add("status", "WARNING: " + spec); return(buf); } buf = db.GetIPInfo(IP, InfoType); if (buf == null) { buf = new Dictionary <string, object>(); buf.Add("ip", IP); if (InputIP != string.Empty) { buf.Add("input_ip", InputIP); } buf.Add("status", db.ErrorMessage); return(buf); } if (InputIP != string.Empty) { buf.Add("input_ip", InputIP); } buf.Add("status", "OK"); return(buf); }
public static string CheckSpecDiaps(string IP) { int uip = IPConverter.IPToInt32(IP); for (int i = 0; i < SpecList.GetLength(0); i++) { int start = IPConverter.IPToInt32(SpecList[i, 0]); int end = IPConverter.IPToInt32(SpecList[i, 1]); string desr = SpecList[i, 2]; if (uip >= start && uip <= end) { return(desr); } } return(string.Empty); }
//Поиск ID для IP private uint SearchID(string IP) { //преобразуем IP-адрес в беззнаковый UInt32 uint ipn = IPConverter.IPToUInt32(IP); //получаем 1-й байт IP-адреса byte ip1n = (byte)(ipn / 0x1000000); //небольшая проверка if (ip1n == 0 || ip1n == 10 || ip1n == 127 || ip1n >= Header.fbIndexLen) { return(0); } //достаем 3 младших байта uint ipn3b = (uint)(ipn - ip1n * 0x1000000); //находим блок данных в индексе первых байт uint blocks_min = fb_idx_arr[ip1n - 1]; uint blocks_max = fb_idx_arr[ip1n]; uint min = 0; uint max = 0; //если длина блока > кол-ва эл-тов в основном индексе if (blocks_max - blocks_min > Header.Range) { //ищем блок данных в основном индексе //При целочисленном делении результат //всегда округляется по направлению к нулю //Floor из оригинального исходника не нужен uint part = SearchIdx(ipn, blocks_min / Header.Range, (blocks_max / Header.Range) - 1); // Нашли номер блока в котором нужно искать IP, // теперь находим нужный блок в БД min = part > 0 ? part * Header.Range : 0; max = part > Header.mIndexLen ? Header.DiapCount : (part + 1) * Header.Range; // Нужно проверить чтобы блок не выходил за // пределы блока первого байта if (min < blocks_min) { min = blocks_min; } if (max > blocks_max) { max = blocks_max; } } else { min = blocks_min; max = blocks_max; } uint len = max - min; uint ID = 0; //поиск в БД диапазонов if (DatabaseMode != SxGeoMode.FileMode) //БД диапазонов в памяти { ID = SearchDB(db_b, ipn3b, min, max); } else //БД диапазонов на диске { byte[] db_part = LoadDBPart(min, len); ID = SearchDB(db_part, ipn3b, 0, len); } return(ID); }
public Dictionary <string, object> GetIPInfo(string IP, SxGeoInfoType InfoType) { Dictionary <string, object> data_city = new Dictionary <string, object>(); Dictionary <string, object> data_country = new Dictionary <string, object>(); Dictionary <string, object> data_region = new Dictionary <string, object>(); if (!IsOpen) { ErrorMessage = "Database not open."; return(null); } if (!IPConverter.IsIP(IP)) //проверяем IP ли это) { ErrorMessage = IP + " is not valid IP address."; return(null); } //получаем ID IP-адреса uint ID = SearchID(IP); if (ID == 0) //не нашли { ErrorMessage = "Not found."; return(null); } //создаем переменные для хранения ответа IPInfo = new Dictionary <string, object>(); IPInfoTypes = new Dictionary <string, Type>(); //добавляем сам адрес IPInfo.Add("ip", IP); IPInfoTypes.Add("ip", typeof(string)); if (Header.IdLen == 1) //БД SxGeo, ничего кроме ISO-кода вывести не сможем { IPInfo.Add("country_iso", IdToIso(ID)); IPInfoTypes.Add("country_iso", typeof(string)); return(IPInfo); } //БД SxGeoCountry, можем вывести много чего SxGeoUnpack Unpacker = null; byte[] buf = null; //если найденный 'ID' < размера справочника городов //город не найден - только страна if (ID < Header.CountrySize) { Unpacker = new SxGeoUnpack(Header.pack_country, Header.DBEncoding); buf = ReadDBDirs(Header.countries_begin, ID, Header.MaxCountry, cities_db); data_country = Unpacker.Unpack(buf); AddData(data_country, Unpacker.GetRecordTypes(), "country_"); return(IPInfo); } //город найден, находим и распаковываем информацию о городе Unpacker = new SxGeoUnpack(Header.pack_city, Header.DBEncoding); buf = ReadDBDirs(Header.countries_begin, ID, Header.MaxCity, cities_db); data_city = Unpacker.Unpack(buf); //о стране по ID страны data_country = GetCountry((byte)data_city["country_id"]); switch (InfoType) { case SxGeoInfoType.OnlyCountry: //только информация о стране { AddData(data_country, SxGeoUnpack.GetRecordTypes(Header.pack_country), "country_"); }; break; case SxGeoInfoType.CountryCity: //страна+город { AddData(data_country, SxGeoUnpack.GetRecordTypes(Header.pack_country), "country_"); AddData(data_city, Unpacker.GetRecordTypes(), "city_"); }; break; default: //полная информация с регионом (если есть) { Unpacker = new SxGeoUnpack(Header.pack_region, Header.DBEncoding); buf = ReadDBDirs(Header.regions_begin, (uint)data_city["region_seek"], Header.MaxRegion, regions_db); data_region = Unpacker.Unpack(buf); AddData(data_country, SxGeoUnpack.GetRecordTypes(Header.pack_country), "country_"); AddData(data_city, SxGeoUnpack.GetRecordTypes(Header.pack_city), "city_"); AddData(data_region, Unpacker.GetRecordTypes(), "region_"); }; break; } return(IPInfo); }