Minor changes.
[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 #include "stg/common.h"
31 #include "os_int.h"
32
33 #include <cstring>
34 #include <vector>
35 #include <string>
36 #include <iostream>
37
38 #ifdef FREE_BSD
39 #include <sys/types.h>
40 #endif
41
42 #include <sys/socket.h>
43 #include <netinet/in.h>
44 #include <arpa/inet.h>
45
46 //-------------------------------------------------------------------------
47 struct IP_MASK
48 {
49 IP_MASK() : ip(0), mask(0) {}
50 uint32_t ip;
51 uint32_t mask;
52 };
53 //-------------------------------------------------------------------------
54 class USER_IPS
55 {
56     friend std::ostream & operator<< (std::ostream & o, const USER_IPS & i);
57     friend const USER_IPS StrToIPS(const std::string & ipsStr);
58
59 public:
60     typedef std::vector<IP_MASK> ContainerType;
61     typedef ContainerType::size_type IndexType;
62
63     const IP_MASK & operator[](IndexType idx) const { return ips[idx]; }
64     std::string GetIpStr() const;
65     bool IsIPInIPS(uint32_t ip) const;
66     bool OnlyOneIP() const;
67     bool IsAnyIP() const;
68     size_t Count() const { return ips.size(); }
69     void Add(const IP_MASK &im) { ips.push_back(im); }
70
71 private:
72     uint32_t CalcMask(unsigned int msk) const;
73     ContainerType ips;
74 };
75 //-------------------------------------------------------------------------
76
77 inline
78 std::string USER_IPS::GetIpStr() const
79 {
80 if (ips.empty())
81     return "";
82
83 if (ips[0].ip == 0)
84     return "*";
85
86 ContainerType::const_iterator it(ips.begin());
87 std::string res = inet_ntostring(it->ip);
88 ++it;
89 for (; it != ips.end(); ++it)
90     res += "," + inet_ntostring(it->ip);
91 return res;
92 }
93 //-----------------------------------------------------------------------------
94 inline
95 uint32_t USER_IPS::CalcMask(unsigned int msk) const
96 {
97 if (msk > 32)
98     return 0;
99 return htonl(0xFFffFFff << (32 - msk));
100 }
101 //-----------------------------------------------------------------------------
102 inline
103 bool USER_IPS::IsIPInIPS(uint32_t ip) const
104 {
105 if (ips.empty())
106     return false;
107
108 if (ips.front().ip == 0)
109     return true;
110
111 for (ContainerType::const_iterator it(ips.begin()); it != ips.end(); ++it)
112     {
113     uint32_t mask(CalcMask(it->mask));
114     if ((ip & mask) == (it->ip & mask))
115         return true;
116     }
117 return false;
118 }
119 //-----------------------------------------------------------------------------
120 inline
121 bool USER_IPS::OnlyOneIP() const
122 {
123 if (ips.size() == 1 && ips.front().mask == 32 && ips.front().ip != 0)
124     return true;
125
126 return false;
127 }
128 //-----------------------------------------------------------------------------
129 inline
130 bool USER_IPS::IsAnyIP() const
131 {
132     return !ips.empty() && ips.front().ip == 0;
133 }
134 //-----------------------------------------------------------------------------
135 inline
136 std::ostream & operator<<(std::ostream & o, const USER_IPS & i)
137 {
138 return o << i.GetIpStr();
139 }
140 //-----------------------------------------------------------------------------
141 inline
142 const USER_IPS StrToIPS(const std::string & ipsStr)
143 {
144 USER_IPS ips;
145 std::vector<std::string> ipMask;
146 if (ipsStr.empty())
147     return ips;
148
149 if (ipsStr[0] == '*' && ipsStr.size() == 1)
150     {
151     ips.ips.push_back(IP_MASK());
152     return ips;
153     }
154
155 char * tmp = new char[ipsStr.size() + 1];
156 strcpy(tmp, ipsStr.c_str());
157 char * pstr = tmp;
158 char * paddr = NULL;
159 while ((paddr = strtok(pstr, ",")))
160     {
161     pstr = NULL;
162     ipMask.push_back(paddr);
163     }
164
165 delete[] tmp;
166
167 for (USER_IPS::IndexType i = 0; i < ipMask.size(); i++)
168     {
169     char str[128];
170     char * strIp;
171     char * strMask;
172     strcpy(str, ipMask[i].c_str());
173     strIp = strtok(str, "/");
174     if (strIp == NULL)
175         return ips;
176     strMask = strtok(NULL, "/");
177
178     IP_MASK im;
179
180     im.ip = inet_addr(strIp);
181     if (im.ip == INADDR_NONE)
182         return ips;
183
184     im.mask = 32;
185     if (strMask != NULL)
186         {
187         int m = 0;
188         if (str2x(strMask, m) != 0)
189             return ips;
190         im.mask = m;
191
192         if (im.mask > 32)
193             return ips;
194
195         if ((im.ip & ips.CalcMask(im.mask)) != im.ip)
196             return ips;
197         }
198     ips.ips.push_back(im);
199     }
200
201 return ips;
202 }
203 //-------------------------------------------------------------------------
204 #endif //USER_IPS_H