]> git.stg.codes - stg.git/blobdiff - include/stg/user_ips.h
Headers moved to subdir stg
[stg.git] / include / stg / user_ips.h
diff --git a/include/stg/user_ips.h b/include/stg/user_ips.h
new file mode 100644 (file)
index 0000000..250520b
--- /dev/null
@@ -0,0 +1,280 @@
+/*
+ *    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 <stg34@stargazer.dp.ua>
+ */
+
+ /*
+ $Revision: 1.22 $
+ $Date: 2010/03/04 11:49:53 $
+ $Author: faust $
+ */
+
+#ifndef USER_IPS_H
+#define USER_IPS_H
+
+#ifdef FREE_BSD
+#include <sys/types.h>
+#endif
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <cstring>
+#include <vector>
+#include <string>
+#include <iostream>
+#include <sstream>
+
+#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<IP_MASK> 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<IP_MASK>::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<IP_MASK>::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<std::string> 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