]> git.stg.codes - stg.git/blob - include/stg/user_ips.h
Another code cleanup
[stg.git] / include / stg / user_ips.h
1 /*
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.
6  *
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.
11  *
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
15  */
16
17 /*
18  *    Author : Boris Mikhailenko <stg34@stargazer.dp.ua>
19  */
20
21  /*
22  $Revision: 1.22 $
23  $Date: 2010/03/04 11:49:53 $
24  $Author: faust $
25  */
26
27 #ifndef USER_IPS_H
28 #define USER_IPS_H
29
30 #ifdef FREE_BSD
31 #include <sys/types.h>
32 #endif
33
34 #include <sys/socket.h>
35 #include <netinet/in.h>
36 #include <arpa/inet.h>
37
38 #include <cstring>
39 #include <vector>
40 #include <string>
41 #include <iostream>
42 #include <sstream>
43
44 #include "common.h"
45 #include "os_int.h"
46
47 using namespace std;
48
49 //-------------------------------------------------------------------------
50 struct IP_MASK
51 {
52 IP_MASK() : ip(0), mask(0) {}
53 IP_MASK(const IP_MASK & ipm) : ip(ipm.ip), mask(ipm.mask)  {}
54 uint32_t ip;
55 uint32_t mask;
56 };
57 //-------------------------------------------------------------------------
58 class USER_IPS
59 {
60     friend std::ostream & operator<< (ostream & o, const USER_IPS & i);
61     //friend stringstream & operator<< (stringstream & s, const USER_IPS & i);
62     friend const USER_IPS StrToIPS(const string & ipsStr) throw(string);
63
64 public:
65     USER_IPS();
66     USER_IPS(const USER_IPS &);
67     USER_IPS & operator=(const USER_IPS &);
68     const IP_MASK & operator[](int idx) const;
69     std::string GetIpStr() const;
70     bool IsIPInIPS(uint32_t ip) const;
71     bool OnlyOneIP() const;
72     int  Count() const;
73     void Add(const IP_MASK &im);
74     void Erase();
75
76 private:
77     uint32_t CalcMask(unsigned int msk) const;
78     std::vector<IP_MASK> ips;
79 };
80 //-------------------------------------------------------------------------
81
82 //-----------------------------------------------------------------------------
83 inline
84 USER_IPS::USER_IPS()
85     : ips()
86 {}
87 //-----------------------------------------------------------------------------
88 inline
89 USER_IPS::USER_IPS(const USER_IPS & i)
90     : ips(i.ips)
91 {}
92 //-----------------------------------------------------------------------------
93 inline
94 USER_IPS & USER_IPS::operator=(const USER_IPS & i)
95 {
96 ips = i.ips;
97 return *this;
98 }
99 //-----------------------------------------------------------------------------
100 inline
101 const IP_MASK & USER_IPS::operator[](int idx) const
102 {
103 return ips[idx];
104 }
105 //-----------------------------------------------------------------------------
106 inline
107 std::string USER_IPS::GetIpStr() const
108 {
109 if (ips.empty())
110     {
111     return "";
112     }
113
114 if (ips[0].ip == 0)
115     {
116     return "*";
117     }
118
119 std::vector<IP_MASK>::const_iterator it(ips.begin());
120 std::stringstream s;
121 s << inet_ntostring(it->ip);
122 ++it;
123 for (; it != ips.end(); ++it)
124     {
125     s << "," << inet_ntostring(it->ip);
126     }
127 return s.str();
128 }
129 //-----------------------------------------------------------------------------
130 inline
131 int USER_IPS::Count() const
132 {
133 return ips.size();
134 }
135 //-----------------------------------------------------------------------------
136 inline
137 bool USER_IPS::IsIPInIPS(uint32_t ip) const
138 {
139 if (ips.empty())
140     {
141     return false;
142     }
143
144 if (ips.front().ip == 0)
145     return true;
146
147 for (std::vector<IP_MASK>::const_iterator it(ips.begin()); it != ips.end(); ++it)
148     {
149     uint32_t mask(CalcMask(it->mask));
150     if ((ip & mask) == (it->ip & mask))
151         return true;
152     }
153 return false;
154 }
155 //-----------------------------------------------------------------------------
156 inline
157 bool USER_IPS::OnlyOneIP() const
158 {
159 if (ips.size() == 1 && ips.front().mask == 32)
160     return true;
161
162 return false;
163 }
164 //-----------------------------------------------------------------------------
165 inline
166 uint32_t USER_IPS::CalcMask(unsigned int msk) const
167 {
168 if (msk > 32)
169     return 0;
170 return htonl(0xFFffFFff << (32 - msk));
171 }
172 //-----------------------------------------------------------------------------
173 inline
174 void USER_IPS::Add(const IP_MASK &im)
175 {
176 ips.push_back(im);
177 }
178 //-----------------------------------------------------------------------------
179 inline
180 void USER_IPS::Erase()
181 {
182 ips.erase(ips.begin(), ips.end());
183 }
184 //-----------------------------------------------------------------------------
185 inline
186 std::ostream & operator<<(std::ostream & o, const USER_IPS & i)
187 {
188 return o << i.GetIpStr();
189 }
190 //-----------------------------------------------------------------------------
191 /*inline
192 stringstream & operator<<(std::stringstream & s, const USER_IPS & i)
193 {
194 s << i.GetIpStr();
195 return s;
196 }*/
197 //-----------------------------------------------------------------------------
198 inline
199 const USER_IPS StrToIPS(const std::string & ipsStr) throw(std::string)
200 {
201 USER_IPS ips;
202 char * paddr;
203 IP_MASK im;
204 std::vector<std::string> ipMask;
205 std::string err;
206 if (ipsStr.empty())
207     {
208     return ips;
209     }
210
211 if (ipsStr[0] == '*' && ipsStr.size() == 1)
212     {
213     im.ip = 0;
214     im.mask = 0;
215     ips.ips.push_back(im);
216     return ips;
217     }
218
219 char * str = new char[ipsStr.size() + 1];
220 strcpy(str, ipsStr.c_str());
221 char * pstr = str;
222 while ((paddr = strtok(pstr, ",")))
223     {
224     pstr = NULL;
225     ipMask.push_back(paddr);
226     }
227
228 delete[] str;
229
230 for (unsigned int i = 0; i < ipMask.size(); i++)
231     {
232     char str[128];
233     char * strIp;
234     char * strMask;
235     strcpy(str, ipMask[i].c_str());
236     strIp = strtok(str, "/");
237     if (strIp == NULL)
238         {
239         err = "Incorrect IP address " + ipsStr;
240         return ips;
241         }
242     strMask = strtok(NULL, "/");
243
244     im.ip = inet_addr(strIp);
245     if (im.ip == INADDR_NONE)
246         {
247         err = "Incorrect IP address: " + std::string(strIp);
248         return ips;
249         }
250
251     im.mask = 32;
252     if (strMask != NULL)
253         {
254         int m = 0;
255         if (str2x(strMask, m) != 0)
256             {
257             err = "Incorrect mask: " + std::string(strMask);
258             return ips;
259             }
260         im.mask = m;
261
262         if (im.mask > 32)
263             {
264             err = "Incorrect mask: " + std::string(strMask);
265             return ips;
266             }
267
268         if ((im.ip & ips.CalcMask(im.mask)) != im.ip)
269             {
270             err = "Address does'n match mask: " + std::string(strIp) + "/" + std::string(strMask);
271             return ips;
272             }
273         }
274     ips.ips.push_back(im);
275     }
276
277 return ips;
278 }
279 //-------------------------------------------------------------------------
280 #endif //USER_IPS_H