ip2cparser_v2.cpp
1 //------------------------------------------------------------------------------
2 // ip2cparser.cpp
3 //------------------------------------------------------------------------------
4 //
5 // This library is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU Lesser General Public
7 // License as published by the Free Software Foundation; either
8 // version 2.1 of the License, or (at your option) any later version.
9 //
10 // This library is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public
16 // License along with this library; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 // 02110-1301 USA
19 //
20 //------------------------------------------------------------------------------
21 // Copyright (C) 2022 "Zalewa" <zalewapl@gmail.com>
22 //------------------------------------------------------------------------------
23 #include "ip2cparser_v2.h"
24 
25 #include "ip2c/ip2cparser.h"
26 #include "ip2c/ip2crange.h"
27 
28 #include "datastreamoperatorwrapper.h"
29 #include "global.h"
30 #include <QMap>
31 
32 bool IP2CParserV2::parse(IP2CParser &self, QIODevice &dataBase)
33 {
34  // Hardcode the URL to the current DB source. This may be inaccurate,
35  // but version 2 didn't have the URL embedded.
36  self.url_ = "https://doomseeker.drdteam.org/ip2c/IpToCountry_v2.dat.php";
37  self.licences_[""] = "Please see the linked webpage for the licensing details of IP2C.\n" + self.url_;
38 
39  QDataStream dstream(&dataBase);
40  dstream.setByteOrder(QDataStream::LittleEndian);
41  DataStreamOperatorWrapper stream(&dstream);
42 
43  return readSectionIpv4(self, stream);
44 }
45 
46 bool IP2CParserV2::readSectionIpv4(IP2CParser &self, DataStreamOperatorWrapper &stream)
47 {
48  // We need to store the addresses in such hash table to make sure they
49  // are ordered in proper, ascending order. Otherwise the whole library
50  // will not work!
51  QMap<unsigned, IP2CRange> hashTable;
52 
53  while (stream.hasRemaining())
54  {
55  // Discard the first field as it is the country name. As of Doomseeker
56  // 1.3.3, the country names and their alpha-3 codes are hardcoded.
57  QString::fromUtf8(stream.readRawUntilByte('\0'));
58  QString countryCode = QString::fromUtf8(stream.readRawUntilByte('\0'));
59 
60  // Base entry for each IP read from the file
61  IP2CRange baseEntry;
62  baseEntry.country = countryCode;
63  if (!stream.hasRemaining())
64  return false;
65 
66  quint32 numOfIpBlocks = stream.readQUInt32();
67 
68  for (quint32 x = 0; x < numOfIpBlocks; ++x)
69  {
70  // Create new entry from the base.
71  IP2CRange entry = baseEntry;
72 
73  entry.ipStart = stream.readQUInt32();
74  if (!stream.hasRemaining())
75  return false;
76  entry.ipEnd = stream.readQUInt32();
77 
78  hashTable[entry.ipStart] = entry;
79  }
80  }
81 
82  self.ranges_ = hashTable.values();
83  return true;
84 }