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