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 //-------------------------------------------------------------------------