/* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* * Author : Boris Mikhailenko */ /* $Revision: 1.22 $ $Date: 2010/03/04 11:49:53 $ $Author: faust $ */ #ifndef USER_IPS_H #define USER_IPS_H #ifdef FREE_BSD #include #endif #include #include #include #include #include #include #include #include #include "common.h" #include "os_int.h" using namespace std; //------------------------------------------------------------------------- struct IP_MASK { IP_MASK() : ip(0), mask(0) {} IP_MASK(const IP_MASK & ipm) : ip(ipm.ip), mask(ipm.mask) {} uint32_t ip; uint32_t mask; }; //------------------------------------------------------------------------- class USER_IPS { friend std::ostream & operator<< (ostream & o, const USER_IPS & i); //friend stringstream & operator<< (stringstream & s, const USER_IPS & i); friend const USER_IPS StrToIPS(const string & ipsStr) throw(string); public: USER_IPS(); USER_IPS(const USER_IPS &); USER_IPS & operator=(const USER_IPS &); const IP_MASK & operator[](int idx) const; std::string GetIpStr() const; bool IsIPInIPS(uint32_t ip) const; bool OnlyOneIP() const; int Count() const; void Add(const IP_MASK &im); void Erase(); private: uint32_t CalcMask(unsigned int msk) const; std::vector ips; }; //------------------------------------------------------------------------- //----------------------------------------------------------------------------- inline USER_IPS::USER_IPS() : ips() {} //----------------------------------------------------------------------------- inline USER_IPS::USER_IPS(const USER_IPS & i) : ips(i.ips) {} //----------------------------------------------------------------------------- inline USER_IPS & USER_IPS::operator=(const USER_IPS & i) { ips = i.ips; return *this; } //----------------------------------------------------------------------------- inline const IP_MASK & USER_IPS::operator[](int idx) const { return ips[idx]; } //----------------------------------------------------------------------------- inline std::string USER_IPS::GetIpStr() const { if (ips.empty()) { return ""; } if (ips[0].ip == 0) { return "*"; } std::vector::const_iterator it(ips.begin()); std::stringstream s; s << inet_ntostring(it->ip); ++it; for (; it != ips.end(); ++it) { s << "," << inet_ntostring(it->ip); } return s.str(); } //----------------------------------------------------------------------------- inline int USER_IPS::Count() const { return ips.size(); } //----------------------------------------------------------------------------- inline bool USER_IPS::IsIPInIPS(uint32_t ip) const { if (ips.empty()) { return false; } if (ips.front().ip == 0) return true; for (std::vector::const_iterator it(ips.begin()); it != ips.end(); ++it) { uint32_t mask(CalcMask(it->mask)); if ((ip & mask) == (it->ip & mask)) return true; } return false; } //----------------------------------------------------------------------------- inline bool USER_IPS::OnlyOneIP() const { if (ips.size() == 1 && ips.front().mask == 32) return true; return false; } //----------------------------------------------------------------------------- inline uint32_t USER_IPS::CalcMask(unsigned int msk) const { if (msk > 32) return 0; return htonl(0xFFffFFff << (32 - msk)); } //----------------------------------------------------------------------------- inline void USER_IPS::Add(const IP_MASK &im) { ips.push_back(im); } //----------------------------------------------------------------------------- inline void USER_IPS::Erase() { ips.erase(ips.begin(), ips.end()); } //----------------------------------------------------------------------------- inline std::ostream & operator<<(std::ostream & o, const USER_IPS & i) { return o << i.GetIpStr(); } //----------------------------------------------------------------------------- /*inline stringstream & operator<<(std::stringstream & s, const USER_IPS & i) { s << i.GetIpStr(); return s; }*/ //----------------------------------------------------------------------------- inline const USER_IPS StrToIPS(const std::string & ipsStr) throw(std::string) { USER_IPS ips; char * paddr; IP_MASK im; std::vector ipMask; std::string err; if (ipsStr.empty()) { return ips; } if (ipsStr[0] == '*' && ipsStr.size() == 1) { im.ip = 0; im.mask = 0; ips.ips.push_back(im); return ips; } char * str = new char[ipsStr.size() + 1]; strcpy(str, ipsStr.c_str()); char * pstr = str; while ((paddr = strtok(pstr, ","))) { pstr = NULL; ipMask.push_back(paddr); } delete[] str; for (unsigned int i = 0; i < ipMask.size(); i++) { char str[128]; char * strIp; char * strMask; strcpy(str, ipMask[i].c_str()); strIp = strtok(str, "/"); if (strIp == NULL) { err = "Incorrect IP address " + ipsStr; return ips; } strMask = strtok(NULL, "/"); im.ip = inet_addr(strIp); if (im.ip == INADDR_NONE) { err = "Incorrect IP address: " + std::string(strIp); return ips; } im.mask = 32; if (strMask != NULL) { int m = 0; if (str2x(strMask, m) != 0) { err = "Incorrect mask: " + std::string(strMask); return ips; } im.mask = m; if (im.mask > 32) { err = "Incorrect mask: " + std::string(strMask); return ips; } if ((im.ip & ips.CalcMask(im.mask)) != im.ip) { err = "Address does'n match mask: " + std::string(strIp) + "/" + std::string(strMask); return ips; } } ips.ips.push_back(im); } return ips; } //------------------------------------------------------------------------- #endif //USER_IPS_H