IP to Geo

IP to Geo Git Source Tree

Root/src/ip_to_geo.c

1#include <sys/socket.h>
2#include <netinet/in.h>
3#include <arpa/inet.h>
4#include <stdint.h>
5#include <stdio.h>
6#include <stdlib.h>
7#include <string.h>
8
9#include "ip_to_geo.h"
10
11#include "ip_data.c"
12
13static const uint8_t* ip_to_geo_rec(uint8_t* ip, unsigned level, const ip_level* root)
14{
15 unsigned cur_average;
16 const ip_level* cur_ip;
17 unsigned cur_addr;
18
19 while (1)
20 {
21 cur_ip = root;
22 cur_addr = ip[level];
23
24 // Optimistic search
25 if (cur_addr && level != 1)
26 {
27 cur_average = cur_addr >> root->average;
28
29 while (cur_average-- && cur_ip->next)
30 cur_ip = cur_ip->next;
31 }
32
33#define IP_TEST \
34 { \
35 if (cur_addr >= cur_ip->start && cur_addr <= cur_ip->end) \
36 { \
37 if (cur_ip->childs) \
38 { \
39 level++; \
40 root = cur_ip->childs; \
41 continue; \
42 } \
43 else \
44 return &cur_ip->code; \
45 } \
46 }
47
48 if (cur_addr < cur_ip->start)
49 {
50 for (cur_ip = cur_ip->prev; cur_ip; cur_ip = cur_ip->prev)
51 IP_TEST;
52 }
53 else if (cur_addr > cur_ip->end)
54 {
55 for (cur_ip = cur_ip->next; cur_ip; cur_ip = cur_ip->next)
56 IP_TEST;
57 }
58 else
59 IP_TEST;
60
61 break;
62 }
63 return NULL;
64}
65
66
67const uint8_t* ip_to_geo(uint8_t* ip, unsigned ip_size)
68{
69 const ip_level* first_level;
70
71 if (ip_size == 4)
72 first_level = s_root_ip[ip[0]];
73 else
74 return NULL;
75
76 if (!first_level) return NULL;
77
78 return ip_to_geo_rec(ip, 1, first_level);
79}
80
81const uint8_t* get_country_code(const uint8_t* idx)
82{
83 if (!idx || *idx >= sizeof(country_codes)/sizeof(country_codes[0]))
84 return NULL;
85
86 return country_codes[*idx];
87}
88
89/* int strip_to_int(char* strip_, uint32_t* ip) */
90/* { */
91/* char* saveptr = NULL; */
92/* char* cur; */
93/* int i; */
94/* char* strip = strdup(strip_); */
95
96/* *ip = 0; */
97
98/* for(i=3; i>=0; i--) */
99/* { */
100/* cur = strtok_r(strip, ".", &saveptr); */
101/* if (!cur) goto end; */
102/* *ip += atoi(cur) << (8*i); */
103/* strip = NULL; */
104/* } */
105
106/* cur = strtok_r(strip, ".", &saveptr); */
107/* end: */
108/* free(strip); */
109/* return (cur)?-1:0; */
110/* } */
111
112int interactive(struct gengetopt_args_info* params)
113{
114 const uint8_t* cc;
115 int ret;
116
117 ret = inet_addr(params->ip_arg);
118 if (ret == INADDR_NONE)
119 {
120 if (!params->quiet_flag)
121 fprintf(stderr, "Invalid IP %s\n", params->ip_arg);
122 return -1;
123 }
124
125 cc = ip_to_geo((uint8_t*)&ret, 4);
126
127 if (params->quiet_flag)
128 printf("%s\n", (cc)?(char*)get_country_code(cc):"<none>");
129 else
130 printf("IP %s : %s\n", params->ip_arg, (cc)?(char*)get_country_code(cc):"<none>");
131
132 return 0;
133}
134
135int main(int argc, char** argv)
136{
137 int ret;
138 struct gengetopt_args_info params;
139
140 ret = cmdline_parser (argc, argv, &params);
141
142 if (ret) return ret;
143
144 /* self_test(); */
145
146 if (params.ip_given)
147 return interactive(&params);
148 else if (params.daemon_flag)
149 return daemonize(&params);
150 else
151 cmdline_parser_print_help();
152
153 return 0;
154}

Archive Download this file

Branches

Tags