-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathipipqx.c
90 lines (76 loc) · 2.4 KB
/
ipipqx.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
//
// Created by yue on 16-5-27.
//
#include "ipip.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef unsigned char byte;
typedef unsigned int uint;
#define B2IL(b) (((b)[0] & 0xFF) | (((b)[1] << 8) & 0xFF00) | (((b)[2] << 16) & 0xFF0000) | (((b)[3] << 24) & 0xFF000000))
#define B2IU(b) (((b)[3] & 0xFF) | (((b)[2] << 8) & 0xFF00) | (((b)[1] << 16) & 0xFF0000) | (((b)[0] << 24) & 0xFF000000))
struct {
byte *data;
byte *index;
uint *flag;
uint offset;
} ipip;
int destroy() {
if (!ipip.offset) {
return 0;
}
free(ipip.flag);
free(ipip.index);
free(ipip.data);
ipip.offset = 0;
return 0;
}
int init(const char *ipdb) {
if (ipip.offset) {
return 0;
}
FILE *file = fopen(ipdb, "rb");
fseek(file, 0, SEEK_END);
long size = ftell(file);
fseek(file, 0, SEEK_SET);
ipip.data = (byte *) malloc(size * sizeof(byte));
fread(ipip.data, sizeof(byte), (size_t) size, file);
fclose(file);
uint indexLength = B2IU(ipip.data);
ipip.index = (byte *) malloc(indexLength * sizeof(byte));
memcpy(ipip.index, ipip.data + 4, indexLength);
ipip.offset = indexLength;
ipip.flag = (uint *) malloc(65536 * sizeof(uint));
memcpy(ipip.flag, ipip.index, 65536 * sizeof(uint));
return 0;
}
int find(const char *ip, char *result) {
uint ips[4];
int num = sscanf(ip, "%d.%d.%d.%d", &ips[0], &ips[1], &ips[2], &ips[3]);
if (num == 4) {
uint ip_prefix_value = ips[0] * 256 + ips[1];
uint ip2long_value = B2IU(ips);
uint start = ipip.flag[ip_prefix_value];
uint max_comp_len = ipip.offset - 262148;
int index_offset = -1;
int index_length = -1;
for (start = start * 13 + 262144; start < max_comp_len; start += 13) {
if (B2IU(ipip.index + start) <= ip2long_value) {
if (B2IU(ipip.index + start + 4) >= ip2long_value) {
index_offset = B2IL(ipip.index + start + 8) & 0x00FFFFFF;
index_length = 0xff & ipip.index[start + 12];
break;
}
} else {
break;
}
}
if (index_offset == -1 && index_length == -1) {
return 0;
}
memcpy(result, ipip.data + ipip.offset + index_offset - 262144, (size_t) index_length);
result[index_length] = '\0';
return 1;
}
return 0;
}