summaryrefslogtreecommitdiff
path: root/src/qcommon/IpToCountryResolver.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/qcommon/IpToCountryResolver.c')
-rw-r--r--src/qcommon/IpToCountryResolver.c152
1 files changed, 152 insertions, 0 deletions
diff --git a/src/qcommon/IpToCountryResolver.c b/src/qcommon/IpToCountryResolver.c
new file mode 100644
index 0000000..f2fd97e
--- /dev/null
+++ b/src/qcommon/IpToCountryResolver.c
@@ -0,0 +1,152 @@
+#include "IpToCountryResolver.h"
+#include "q_shared.h"
+
+void convertToCamelCase(char *str)
+{
+ int upper = 1;
+ char *pos = str;
+ while (*pos != '\0') {
+ if (*pos != ' ') {
+ if (upper) {
+ (*pos) = toupper(*pos);
+ upper = 0;
+ }
+ else
+ (*pos) = tolower(*pos);
+ } else {
+ upper = 1;
+ }
+ pos++;
+ }
+}
+
+IpToCountryInfo *FindCountryInfoUI(unsigned int ip, IpToCountryList *infoList)
+{
+ int abound = 0;
+ int zbound = infoList->size-1;
+ int tbound = 0;
+ IpToCountryInfo *telement;
+
+ if (infoList->size == 0)
+ return NULL;
+
+ while (abound <= zbound)
+ {
+ tbound = (abound+zbound)/2;
+ telement = &infoList->infoArray[tbound];
+
+ if (ip < telement->ipFrom)
+ zbound = tbound-1;
+ else if (ip > telement->ipTo)
+ abound = tbound+1;
+ else
+ return telement;
+ }
+ return NULL;
+}
+
+IpToCountryInfo *FindCountryInfoB(unsigned int parts[4], unsigned int length, IpToCountryList *infoList)
+{
+ return FindCountryInfoUI(ipbyte_to_int(parts, length),infoList);
+}
+
+IpToCountryInfo *FindCountryInfoS(const char *ip_addr, IpToCountryList *infoList)
+{
+ return FindCountryInfoUI(ipstr_to_int(ip_addr),infoList);
+}
+
+unsigned int ipbyte_to_int(unsigned int parts[4], unsigned int length)
+{
+ unsigned int val = parts[length-1];
+
+ switch (length) {
+
+ case 1: /* a -- 32 bits */
+ break;
+
+ case 2: /* a.b -- 8.24 bits */
+ if (val > 0xffffff)
+ return (0);
+ val |= parts[0] << 24;
+ break;
+
+ case 3: /* a.b.c -- 8.8.16 bits */
+ if (val > 0xffff)
+ return (0);
+ val |= (parts[0] << 24) | (parts[1] << 16);
+ break;
+
+ case 4: /* a.b.c.d -- 8.8.8.8 bits */
+ if (val > 0xff)
+ return (0);
+ val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
+ break;
+ }
+
+ return val;
+}
+
+unsigned int ipstr_to_int(const char *cp_arg)
+{
+ register unsigned long val;
+ register int base, n;
+ register unsigned char c;
+ register unsigned const char *cp = (unsigned const char *) cp_arg;
+ unsigned int parts[4];
+ register unsigned int *pp = parts;
+
+ for (;;) {
+ /*
+ * Collect number up to ``.''.
+ * Values are specified as for C:
+ * 0x=hex, 0=octal, other=decimal.
+ */
+ val = 0; base = 10;
+ if (*cp == '0') {
+ if (*++cp == 'x' || *cp == 'X')
+ base = 16, cp++;
+ else
+ base = 8;
+ }
+ while ((c = *cp) != '\0') {
+ if (isascii(c) && isdigit(c)) {
+ val = (val * base) + (c - '0');
+ cp++;
+ continue;
+ }
+ if (base == 16 && isascii(c) && isxdigit(c)) {
+ val = (val << 4) +
+ (c + 10 - (islower(c) ? 'a' : 'A'));
+ cp++;
+ continue;
+ }
+ break;
+ }
+ if (*cp == '.') {
+ /*
+ * Internet format:
+ * a.b.c.d
+ * a.b.c (with c treated as 16-bits)
+ * a.b (with b treated as 24 bits)
+ */
+ if (pp >= parts + 3 || val > 0xff)
+ return (0);
+ *pp++ = val, cp++;
+ } else {
+ *pp = val;
+ break;
+ }
+ }
+ /*
+ * Check for trailing characters.
+ */
+ if (*cp && (!isascii(*cp) || !isspace(*cp)))
+ return (0);
+ /*
+ * Concoct the address according to
+ * the number of parts specified.
+ */
+ n = pp - parts + 1;
+
+ return ipbyte_to_int(parts,n);
+}