2  *    This program is free software; you can redistribute it and/or modify
 
   3  *    it under the terms of the GNU General Public License as published by
 
   4  *    the Free Software Foundation; either version 2 of the License, or
 
   5  *    (at your option) any later version.
 
   7  *    This program is distributed in the hope that it will be useful,
 
   8  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
   9  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
  10  *    GNU General Public License for more details.
 
  12  *    You should have received a copy of the GNU General Public License
 
  13  *    along with this program; if not, write to the Free Software
 
  14  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
  18  *    Author : Boris Mikhailenko <stg34@stargazer.dp.ua>
 
  23 #include "stg/common.h"
 
  32 #include <sys/types.h>
 
  35 #include <sys/socket.h>
 
  36 #include <netinet/in.h>
 
  37 #include <arpa/inet.h>
 
  42 //-------------------------------------------------------------------------
 
  45     IPMask() noexcept : ip(0), mask(0) {}
 
  46     IPMask(uint32_t i, uint32_t m) noexcept : ip(i), mask(m) {}
 
  48     IPMask(const IPMask&) = default;
 
  49     IPMask& operator=(const IPMask&) = default;
 
  50     IPMask(IPMask&&) = default;
 
  51     IPMask& operator=(IPMask&&) = default;
 
  56 //-------------------------------------------------------------------------
 
  59     friend std::ostream & operator<< (std::ostream & o, const UserIPs & i);
 
  62         using ContainerType = std::vector<IPMask>;
 
  63         using IndexType = ContainerType::size_type;
 
  67         UserIPs(const UserIPs&) = default;
 
  68         UserIPs& operator=(const UserIPs&) = default;
 
  69         UserIPs(UserIPs&&) = default;
 
  70         UserIPs& operator=(UserIPs&&) = default;
 
  72         static UserIPs parse(const std::string& source);
 
  74         const IPMask& operator[](IndexType idx) const noexcept { return ips[idx]; }
 
  75         std::string toString() const noexcept;
 
  76         bool find(uint32_t ip) const noexcept;
 
  77         bool onlyOneIP() const noexcept;
 
  78         bool isAnyIP() const noexcept;
 
  79         size_t count() const noexcept { return ips.size(); }
 
  80         void add(const IPMask& im)  noexcept{ ips.push_back(im); }
 
  83         uint32_t calcMask(unsigned int msk) const noexcept;
 
  86 //-------------------------------------------------------------------------
 
  89 std::string UserIPs::toString() const noexcept
 
  97     auto it = ips.begin();
 
  98     std::string res = inet_ntostring(it->ip);
 
 100     for (; it != ips.end(); ++it)
 
 101         res += "," + inet_ntostring(it->ip);
 
 104 //-----------------------------------------------------------------------------
 
 106 uint32_t UserIPs::calcMask(unsigned int msk) const noexcept
 
 110     return htonl(0xFFffFFff << (32 - msk));
 
 112 //-----------------------------------------------------------------------------
 
 114 bool UserIPs::find(uint32_t ip) const noexcept
 
 119     if (ips.front().ip == 0)
 
 122     for (auto it = ips.begin(); it != ips.end(); ++it)
 
 124         const auto mask = calcMask(it->mask);
 
 125         if ((ip & mask) == (it->ip & mask))
 
 130 //-----------------------------------------------------------------------------
 
 132 bool UserIPs::onlyOneIP() const noexcept
 
 134     if (ips.size() == 1 && ips.front().mask == 32 && ips.front().ip != 0)
 
 139 //-----------------------------------------------------------------------------
 
 141 bool UserIPs::isAnyIP() const noexcept
 
 143     return !ips.empty() && ips.front().ip == 0;
 
 145 //-----------------------------------------------------------------------------
 
 147 std::ostream & operator<<(std::ostream& o, const UserIPs& i)
 
 149     return o << i.toString();
 
 151 //-----------------------------------------------------------------------------
 
 153 UserIPs UserIPs::parse(const std::string& source)
 
 159     if (source[0] == '*' && source.size() == 1)
 
 161         ips.ips.push_back(IPMask());
 
 165     std::vector<std::string> ipMask;
 
 166     char * tmp = new char[source.size() + 1];
 
 167     strcpy(tmp, source.c_str());
 
 170     while ((paddr = strtok(pstr, ",")))
 
 173         ipMask.push_back(paddr);
 
 178     for (UserIPs::IndexType i = 0; i < ipMask.size(); i++)
 
 183         strcpy(str, ipMask[i].c_str());
 
 184         strIp = strtok(str, "/");
 
 187         strMask = strtok(NULL, "/");
 
 191         im.ip = inet_addr(strIp);
 
 192         if (im.ip == INADDR_NONE)
 
 199             if (str2x(strMask, m) != 0)
 
 206             if ((im.ip & ips.calcMask(im.mask)) != im.ip)
 
 209         ips.ips.push_back(im);
 
 214 //-------------------------------------------------------------------------