]> git.stg.codes - stg.git/blob - include/stg/user_ips.h
Better handling of errors from server. Refactoring.
[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 "stg/common.h"
45 #include "os_int.h"
46
47 //-------------------------------------------------------------------------
48 struct IP_MASK
49 {
50 IP_MASK() : ip(0), mask(0) {}
51 IP_MASK(const IP_MASK & ipm) : ip(ipm.ip), mask(ipm.mask)  {}
52 uint32_t ip;
53 uint32_t mask;
54 };
55 //-------------------------------------------------------------------------
56 class USER_IPS
57 {
58     friend std::ostream & operator<< (std::ostream & o, const USER_IPS & i);
59     //friend stringstream & operator<< (stringstream & s, const USER_IPS & i);
60     friend const USER_IPS StrToIPS(const std::string & ipsStr);
61
62 public:
63     typedef std::vector<IP_MASK> ContainerType;
64     typedef ContainerType::size_type IndexType;
65
66     USER_IPS();
67     USER_IPS(const USER_IPS &);
68     USER_IPS & operator=(const USER_IPS &);
69     const IP_MASK & operator[](IndexType idx) const;
70     std::string GetIpStr() const;
71     bool IsIPInIPS(uint32_t ip) const;
72     bool OnlyOneIP() const;
73     bool IsAnyIP() const;
74     size_t  Count() const;
75     void Add(const IP_MASK &im);
76     void Erase();
77
78 private:
79     uint32_t CalcMask(unsigned int msk) const;
80     ContainerType ips;
81 };
82 //-------------------------------------------------------------------------
83
84 //-----------------------------------------------------------------------------
85 inline
86 USER_IPS::USER_IPS()
87     : ips()
88 {}
89 //-----------------------------------------------------------------------------
90 inline
91 USER_IPS::USER_IPS(const USER_IPS & i)
92     : ips(i.ips)
93 {}
94 //-----------------------------------------------------------------------------
95 inline
96 USER_IPS & USER_IPS::operator=(const USER_IPS & i)
97 {
98 ips = i.ips;
99 return *this;
100 }
101 //-----------------------------------------------------------------------------
102 inline
103 const IP_MASK & USER_IPS::operator[](IndexType idx) const
104 {
105 return ips[idx];
106 }
107 //-----------------------------------------------------------------------------
108 inline
109 std::string USER_IPS::GetIpStr() const
110 {
111 if (ips.empty())
112     {
113     return "";
114     }
115
116 if (ips[0].ip == 0)
117     {
118     return "*";
119     }
120
121 ContainerType::const_iterator it(ips.begin());
122 std::ostringstream s;
123 s << inet_ntostring(it->ip);
124 ++it;
125 for (; it != ips.end(); ++it)
126     {
127     s << "," << inet_ntostring(it->ip);
128     }
129 return s.str();
130 }
131 //-----------------------------------------------------------------------------
132 inline
133 size_t USER_IPS::Count() const
134 {
135 return ips.size();
136 }
137 //-----------------------------------------------------------------------------
138 inline
139 uint32_t USER_IPS::CalcMask(unsigned int msk) const
140 {
141 if (msk > 32)
142     return 0;
143 return htonl(0xFFffFFff << (32 - msk));
144 }
145 //-----------------------------------------------------------------------------
146 inline
147 bool USER_IPS::IsIPInIPS(uint32_t ip) const
148 {
149 if (ips.empty())
150     {
151     return false;
152     }
153
154 if (ips.front().ip == 0)
155     return true;
156
157 for (ContainerType::const_iterator it(ips.begin()); it != ips.end(); ++it)
158     {
159     uint32_t mask(CalcMask(it->mask));
160     if ((ip & mask) == (it->ip & mask))
161         return true;
162     }
163 return false;
164 }
165 //-----------------------------------------------------------------------------
166 inline
167 bool USER_IPS::OnlyOneIP() const
168 {
169 if (ips.size() == 1 && ips.front().mask == 32)
170     return true;
171
172 return false;
173 }
174 //-----------------------------------------------------------------------------
175 inline
176 bool USER_IPS::IsAnyIP() const
177 {
178     return !ips.empty() && ips.front().ip == 0;
179 }
180 //-----------------------------------------------------------------------------
181 inline
182 void USER_IPS::Add(const IP_MASK &im)
183 {
184 ips.push_back(im);
185 }
186 //-----------------------------------------------------------------------------
187 inline
188 void USER_IPS::Erase()
189 {
190 ips.erase(ips.begin(), ips.end());
191 }
192 //-----------------------------------------------------------------------------
193 inline
194 std::ostream & operator<<(std::ostream & o, const USER_IPS & i)
195 {
196 return o << i.GetIpStr();
197 }
198 //-----------------------------------------------------------------------------
199 /*inline
200 stringstream & operator<<(std::stringstream & s, const USER_IPS & i)
201 {
202 s << i.GetIpStr();
203 return s;
204 }*/
205 //-----------------------------------------------------------------------------
206 inline
207 const USER_IPS StrToIPS(const std::string & ipsStr)
208 {
209 USER_IPS ips;
210 char * paddr;
211 IP_MASK im;
212 std::vector<std::string> ipMask;
213 if (ipsStr.empty())
214     {
215     return ips;
216     }
217
218 if (ipsStr[0] == '*' && ipsStr.size() == 1)
219     {
220     im.ip = 0;
221     im.mask = 0;
222     ips.ips.push_back(im);
223     return ips;
224     }
225
226 char * tmp = new char[ipsStr.size() + 1];
227 strcpy(tmp, ipsStr.c_str());
228 char * pstr = tmp;
229 while ((paddr = strtok(pstr, ",")))
230     {
231     pstr = NULL;
232     ipMask.push_back(paddr);
233     }
234
235 delete[] tmp;
236
237 for (USER_IPS::IndexType i = 0; i < ipMask.size(); i++)
238     {
239     char str[128];
240     char * strIp;
241     char * strMask;
242     strcpy(str, ipMask[i].c_str());
243     strIp = strtok(str, "/");
244     if (strIp == NULL)
245         {
246         return ips;
247         }
248     strMask = strtok(NULL, "/");
249
250     im.ip = inet_addr(strIp);
251     if (im.ip == INADDR_NONE)
252         {
253         return ips;
254         }
255
256     im.mask = 32;
257     if (strMask != NULL)
258         {
259         int m = 0;
260         if (str2x(strMask, m) != 0)
261             {
262             return ips;
263             }
264         im.mask = m;
265
266         if (im.mask > 32)
267             {
268             return ips;
269             }
270
271         if ((im.ip & ips.CalcMask(im.mask)) != im.ip)
272             {
273             return ips;
274             }
275         }
276     ips.ips.push_back(im);
277     }
278
279 return ips;
280 }
281 //-------------------------------------------------------------------------
282 #endif //USER_IPS_H