From 5e441c068f14c59bde307390da8646bcdf8aa4fb Mon Sep 17 00:00:00 2001 From: aixiao Date: Mon, 17 Feb 2025 12:59:02 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=EF=BC=9A=20=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E4=B8=BB=E8=A6=81=E5=A4=84=E7=90=86=E5=87=BD=E6=95=B0?= =?UTF-8?q?Processing=5FIP=5Faddresses(src=5Fip);=20=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=A4=84=E7=90=86=E6=94=BE=E5=88=B0cache.c=20=E6=9A=82?= =?UTF-8?q?=E6=97=B6=E6=9C=AA=E5=8F=91=E7=8E=B0Bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- a.out | Bin 0 -> 19336 bytes cache.c | 89 +++++++++++++++++++++++++++++ cache.h | 36 +++++++++++- cap.c | 163 ++++++++++++++---------------------------------------- common.c | 12 ++++ common.h | 2 + libcurl.c | 84 ++++++++++++++++++++++++++-- libcurl.h | 3 +- 8 files changed, 260 insertions(+), 129 deletions(-) create mode 100644 a.out diff --git a/a.out b/a.out new file mode 100644 index 0000000000000000000000000000000000000000..f6d47559104bd88ac226be39f2874e12fbb60b7d GIT binary patch literal 19336 zcmeHP4UkmDo$py#B?Q<-#Y6mH^cDdLvn(n>BVk}!cx$n+$AZzQ_n4h|yNvA4OlIC7 z7$`9d#&K&SF@EF}OU`&|?qY%;XMs^%l@m6xa*N~9>ywas(l}4keRxm zPG>)jT3;y7PtHhwc`V?eCu`XyT|Py4mJWk)FQuAi3O ze!8B`?6>_)71)gzQAZ(Z)aCsh{HQ(u+@y!c3NFv9|C+h|HFEK?O(+J9wI$0|iHgml zm+Iowp9GnjoAg_6zPmOyQ1hGlzZg9D$fOT$Sv2oJWo<{ab)9E1mZW8jhJoraF;@=LQt`m2< z0sMF|Nr(kXqvsuAHm+hFUu;VVdoo@tB#iLrL2-mFcjC z;dHXYv_h#3X1K!&#nK5;WKwq0N+#n;MYVUtTSFbgm_=hz+v#Q5@r08|Sjo0{vQwF) zI#5|Nlt@^yNJ(53<>Hp*%giN~-9Y6w+bCKx&7ow<;(TLjdFxeH7$r#6BCEr)i@Fv& z8I85G4uO`RQ$#_AA9<<{p*uNZ~^;ijkfa{RY)-30vqBwy{|`B6vm6CJ#MW*~*%!OQ1HB9W#AB?u~)+CryUL6sw({&bofR5{{w zTN4uu(oxx>!wSg=sw~-mv%unc$-$3t@RvGxeuS0U)ee4~!+wo}uX6AS2d|%jNWI>{ zk0*lD=Ag<@Jx^ec;D(?Qh(A$f<#Ah33B=R$k4`@isvPkXGzr`hR08oQtE@ae5L5#3 zf1|SUxHG5(;wP%CJnjlAf%sEYRvvqUN+5oc%F5&Zpc05bRb}O|FQ^3Koex+24&JX! zjvbG+z+X%Y7+vpT z4k1l>hGd$8^Lc%OjBlFNO=XxRU{7_0Wsxbl4**}XQjN5WSScDeNw)VWSSE5y;7b{GEIf~ol-uB zWSRo=JEVLT$u#xlw@G;t$u#BVH%s{hl4+{TC!{=@WSZjgtEF5)GEHsyW+{IjfJ{?b zJ}BjnNT#VQKTFEL!<&V+ZIETEd#^Eb;O~vhn?~26f##JBb-i`Z8$I(LK!XlVxF4n; zw*{&uZ;`gt|IqD5K%=MfVS)<=?Fkq@*Tay8&o_p$Rg*W9@w1Gu&q(|8e?&0-h>;mE zo_>G6@$}#b!}pwV;D~(^0<7WyqlU6=Rg)JL{r^;T#^;;oT?t>2p0Ud4nl~Dj!pOX3 zk1@LEoee%W9ler^;P71K`H+2AqU=KX`X4QTp z)6{EpH}n}*ziEKbFbJU+H~_?7Gp=TEzCNR;*{3M9)+Wd4x5_De)8DfSsDW@If; zo1(L??>Ur(sy#3Jz_{++)tEDk%##mbP#XKT_5!E|$nGy@`-<8AVm4dM=8D;YVs@~Y zrE8eujw)v9N@sRrF-!9Sv(t)Mnl+f6Tg(QFS)-V3E@m$+W>*)pYl_)KF}uEyZP=`e zYPf+>UZ}>thM%*%gYf~zos6>kjP6@ybN0yQG%^Q_o(V0O3ir?>GCEos<(~h7TD)P9 zJfEV8JNIp3GFx||+0g#Gxb>c*Njo>=b6j1AagbwdUqg=E3@)K(LJh+6`1 zC5reE*>>al=xH7S9OTpbZ*^LO`x;)JIu&K(66kJv83qH=O||K*FxuD9cY-qL?{4aI z8Q3s*r)FQnA!*WcE0x{dbjW43Oon-3#xfzgn_eI#dhjrM$5GTd(q{j7DyrvJ>a*^q z{jNC2Nt?ZA!KS-uFURS|P16zQ%|Us(19a+V!#>l{+qJ1z*fY8tdO@W?85y)@?ju2%V4?~7>85fn1e(sMG?0cLsQc{2Ph};vx*sD7^UOOm3HBqiZCjxx z{z6T;P=Rgs@hk>=VbuIsMMWj|ubzo2|H%3Rful^0E=uw%zc0~*GvbN)%4fo#*vVO^mUa8QpKtwseYgW{wa)W|LQn zCRvwB2b(-nH1Vqn6)LivO|}(H{k=_Z7?sLxU11IaFCt)=*N7^ zF5FM)(?jOTF%&%WuY#bb@_SrlMh{~4zV8!K-&(C|f`D>p{X0Z-{MJ6|ik_`fiyM7U z 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 I99*LKAAmcK@c;k- literal 0 HcmV?d00001 diff --git a/cache.c b/cache.c index 27d7ef4..77ea9dd 100644 --- a/cache.c +++ b/cache.c @@ -1,5 +1,94 @@ #include "cache.h" + +struct ip_cache_node *ip_cache_head = NULL; // 缓存链表的头节点 +int cache_size = 0; // 当前缓存中的 IP 数量 + +// 将新 IP 添加到缓存,若缓存过大则移除最早的 IP +void add_ip_to_cache(const char *ip) +{ + // 如果缓存大小超过限制,移除最早的 IP + if (cache_size >= MAX_CACHE_SIZE) { + struct ip_cache_node *current = ip_cache_head; + struct ip_cache_node *prev = NULL; + + // 找到链表的最后一个节点 + while (current->next != NULL) { + prev = current; + current = current->next; + } + + // 移除最后一个节点(最早的 IP) + if (prev != NULL) { + prev->next = NULL; + } else { + ip_cache_head = NULL; + } + free(current); + cache_size--; + } + + // 创建新的缓存节点并添加到链表头部 + struct ip_cache_node *new_node = (struct ip_cache_node *)malloc(sizeof(struct ip_cache_node)); + if (new_node == NULL) { + perror("malloc"); + return; + } + strncpy(new_node->ip, ip, INET_ADDRSTRLEN); + new_node->timestamp = time(NULL); // 记录当前时间 + new_node->next = ip_cache_head; + ip_cache_head = new_node; + cache_size++; +} + +// 检查 IP 是否已在缓存中并是否过期 +int is_ip_in_cache(const char *ip) +{ + time_t now = time(NULL); // 获取当前时间 + struct ip_cache_node *current = ip_cache_head; + struct ip_cache_node *prev = NULL; + + while (current != NULL) { + // 如果 IP 匹配并且未过期 + if (strcmp(current->ip, ip) == 0) { + if (now - current->timestamp <= CACHE_TTL) { + return 1; // IP 在缓存中,且未过期 + } else { + // 如果过期,从链表中移除这个节点 + if (prev == NULL) { + ip_cache_head = current->next; + } else { + prev->next = current->next; + } + + free(current); + cache_size--; + return 0; // IP 过期,不再缓存 + } + } + + prev = current; + current = current->next; + } + return 0; // IP 不在缓存中 +} + +// 清理缓存链表,释放所有节点的内存 +void free_ip_cache() +{ + struct ip_cache_node *current = ip_cache_head; + while (current != NULL) { + struct ip_cache_node *next = current->next; + free(current); + current = next; + } + + ip_cache_head = NULL; + cache_size = 0; +} + + + char cn_ip[MAXIPSET_][MAXIPLEN] = { 0 }; // 添加一个 IP 到集合(如果已存在则不添加) diff --git a/cache.h b/cache.h index 3b5ce90..514f128 100644 --- a/cache.h +++ b/cache.h @@ -6,12 +6,44 @@ #include #include #include +#include -#define MAXIPSET_ 256 +#include +#include +#include +#include +#include +#include // IP header +#include // TCP header +#include +#include + +#include +#include +#include +#include +#include +#include + +#define MAXIPSET_ 10240 #define MAXIPLEN 32 -extern char cn_ip[MAXIPSET_][MAXIPLEN]; +#define CACHE_TTL 180 // 设定缓存的存活时间为 600 秒 (10 分钟) +#define MAX_CACHE_SIZE 100 // 缓存最多存储 100 个 IP 地址 +extern int cache_size; // 当前缓存中的 IP 数量 +// 定义链表结构,用于缓存 IP 地址 +struct ip_cache_node { + char ip[INET_ADDRSTRLEN]; // 存储 IP 地址 + time_t timestamp; // 记录缓存时间 + struct ip_cache_node *next; // 指向下一个节点 +}; + +extern void add_ip_to_cache(const char *ip); +extern int is_ip_in_cache(const char *ip); +extern void free_ip_cache(); + +extern char cn_ip[MAXIPSET_][MAXIPLEN]; extern int add_cn_ip(char cn_ip[MAXIPSET_][MAXIPLEN], char *ip); extern int is_ip_in_set(char cn_ip[MAXIPSET_][MAXIPLEN], const char *ip); extern int cn_ip_len(char cn_ip[MAXIPSET_][MAXIPLEN]); diff --git a/cap.c b/cap.c index 106c57f..35c5988 100644 --- a/cap.c +++ b/cap.c @@ -10,131 +10,27 @@ pcap_t *handle; // 会话句柄 struct bpf_program fp; // 编译后的过滤器 pid_t pid = -1; // 子进程全局PID - #define SHM_SIZE 1024 // 共享内存大小 #define SHM_KEY 0124 // 共享内存键值 int shmid = -1; int RULE_NAME_NUMBER = 0; // ipset 集合集合数 char *RULE_NAME = NULL; // 共享内存 + + char *ip2region_area = NULL; // ip2region 解析结果 char *command_result = NULL; // 执行命令的结果 -#define CACHE_TTL 180 // 设定缓存的存活时间为 600 秒 (10 分钟) -#define MAX_CACHE_SIZE 100 // 缓存最多存储 100 个 IP 地址 -struct ip_cache_node *ip_cache_head = NULL; // 缓存链表的头节点 -int cache_size = 0; // 当前缓存中的 IP 数量 -// 定义链表结构,用于缓存 IP 地址 -struct ip_cache_node { - char ip[INET_ADDRSTRLEN]; // 存储 IP 地址 - time_t timestamp; // 记录缓存时间 - struct ip_cache_node *next; // 指向下一个节点 -}; - - -// 将新 IP 添加到缓存,若缓存过大则移除最早的 IP -void add_ip_to_cache(const char *ip) +void Processing_IP_addresses(char *src_ip) { - // 如果缓存大小超过限制,移除最早的 IP - if (cache_size >= MAX_CACHE_SIZE) { - struct ip_cache_node *current = ip_cache_head; - struct ip_cache_node *prev = NULL; - - // 找到链表的最后一个节点 - while (current->next != NULL) { - prev = current; - current = current->next; - } - - // 移除最后一个节点(最早的 IP) - if (prev != NULL) { - prev->next = NULL; - } else { - ip_cache_head = NULL; - } - free(current); - cache_size--; - } - - // 创建新的缓存节点并添加到链表头部 - struct ip_cache_node *new_node = (struct ip_cache_node *)malloc(sizeof(struct ip_cache_node)); - if (new_node == NULL) { - perror("malloc"); - return; - } - strncpy(new_node->ip, ip, INET_ADDRSTRLEN); - new_node->timestamp = time(NULL); // 记录当前时间 - new_node->next = ip_cache_head; - ip_cache_head = new_node; - cache_size++; -} - -// 检查 IP 是否已在缓存中并是否过期 -int is_ip_in_cache(const char *ip) -{ - time_t now = time(NULL); // 获取当前时间 - struct ip_cache_node *current = ip_cache_head; - struct ip_cache_node *prev = NULL; - - while (current != NULL) { - // 如果 IP 匹配并且未过期 - if (strcmp(current->ip, ip) == 0) { - if (now - current->timestamp <= CACHE_TTL) { - return 1; // IP 在缓存中,且未过期 - } else { - // 如果过期,从链表中移除这个节点 - if (prev == NULL) { - ip_cache_head = current->next; - } else { - prev->next = current->next; - } - - free(current); - cache_size--; - return 0; // IP 过期,不再缓存 - } - } - - prev = current; - current = current->next; - } - return 0; // IP 不在缓存中 -} - -// 清理缓存链表,释放所有节点的内存 -void free_ip_cache() -{ - struct ip_cache_node *current = ip_cache_head; - while (current != NULL) { - struct ip_cache_node *next = current->next; - free(current); - current = next; - } - - ip_cache_head = NULL; - cache_size = 0; -} - - -// 回调函数,在捕获到每个数据包时调用 -void packet_handler(u_char *args, const struct pcap_pkthdr *header, const u_char *packet) -{ - int ethernet_header_len = 14; - struct ip *ip_header = (struct ip *)(packet + ethernet_header_len); - char src_ip[INET_ADDRSTRLEN] = { 0 }; - // 地域白名单 char _region_list[WHITELIST_IP_NUM][WHITELIST_IP_NUM] = { { 0 }, { 0 } }; char _REGION_LIST[BUFFER] = { 0 }; const char *REGION_ENV = NULL; - char ipset_query_command[256] = { 0 }; - // 定义 Response 结构体 Response response; - inet_ntop(AF_INET, &(ip_header->ip_src), src_ip, INET_ADDRSTRLEN); - // 如果 IP 地址已在缓存中且未过期,则跳过查询 if (is_ip_in_cache(src_ip)) { _printf(RED "IP:%s 已在缓存中,跳过查询\n" REDEND, src_ip); @@ -156,14 +52,12 @@ void packet_handler(u_char *args, const struct pcap_pkthdr *header, const u_char printf("%s ", cn_ip[i]); } } - - if (cn_ip_len(cn_ip) >= 100) { // 清理集合 + if (cn_ip_len(cn_ip) >= 1024) { // 清理集合 clear_ip_set(cn_ip); } printf("cn_ip_len(cn_ip): %d\n", cn_ip_len(cn_ip)); - return; } @@ -196,34 +90,47 @@ void packet_handler(u_char *args, const struct pcap_pkthdr *header, const u_char add_ip_to_cache(src_ip); // 添加到缓存 - char *p = curl_get_area(src_ip); + char *p = CurlGetIpArea(src_ip); if (parse_json_to_struct(p, &response) == 0) { // 解析 JSON 到结构体 if (NULL == strstr(response.continent_country, "中国")) { // 这时是国外IP - _printf(RED "%s %s\n" REDEND, src_ip, response.continent_country); + _printf(RED "CurlGetIpArea(): %s %s\n" REDEND, src_ip, response.continent_country); add_ip_to_ipset(RULE_NAME, src_ip); - } else { // 这时是国内IP - add_cn_ip(cn_ip, src_ip); // 添加国内IP到缓存 + } else { // 这时是国内IP + add_cn_ip(cn_ip, src_ip); // 添加国内IP到缓存 _printf("IP: %s 离线库为国外, API 判断为国内, 标记为已处理!!!\n", src_ip); if (append_string_to_file("cn.txt", src_ip) != 0) { _printf("append_string_to_file() Error!!!\n"); } } - } else { fprintf(stderr, "Failed to parse JSON.\n"); } if (p != NULL) free(p); - } + if (ip2region_area != NULL) { free(ip2region_area); ip2region_area = NULL; } + + return ; +} + +// 回调函数,在捕获到每个数据包时调用 +void packet_handler(u_char *args, const struct pcap_pkthdr *header, const u_char *packet) +{ + int ethernet_header_len = 14; + struct ip *ip_header = (struct ip *)(packet + ethernet_header_len); + char src_ip[INET_ADDRSTRLEN] = { 0 }; + + inet_ntop(AF_INET, &(ip_header->ip_src), src_ip, INET_ADDRSTRLEN); + Processing_IP_addresses(src_ip); + return; } @@ -236,6 +143,7 @@ void usage() puts(" Usage: denyip [-d] [-i ] [-s ] [-h|-?]"); puts(" -d --daemon Daemon mode"); puts(" -i --interface interface (default eth0)"); + puts(" -f --protocol 过滤器 [\"tcp\" | \"udp\" | \"tcp or udp\"] (default \"tcp\")"); puts(" -l print iptables rule"); puts(" -s --signal regular signal (default start|stop) "); puts(" start Enable Iptables rule"); @@ -292,7 +200,7 @@ int main(int argc, char **argv) int opt; char errbuf[PCAP_ERRBUF_SIZE] = { 0 }; // 错误缓冲区 - char protocol[] = "tcp"; + char protocol[256] = "tcp"; char interface[256] = "{ 0 }"; char Ipset_Command[BUFFER] = { 0 }; @@ -302,9 +210,10 @@ int main(int argc, char **argv) memset(errbuf, 0, PCAP_ERRBUF_SIZE); int longindex = 0; - char optstring[] = "di:s:lh?"; + char optstring[] = "di:f:s:lh?"; static struct option longopts[] = { { "interface", required_argument, 0, 'i' }, + { "protocol", required_argument, 0, 'f' }, { "signal", required_argument, 0, 's' }, { "daemon", no_argument, 0, 'd' }, { "l", no_argument, 0, 'l' }, @@ -323,6 +232,9 @@ int main(int argc, char **argv) case 'i': strcpy(interface, optarg); break; + case 'f': + strcpy(protocol, optarg); + break; case 'l': system("iptables -L -v -n --line-numbers"); exit(0); @@ -381,16 +293,25 @@ int main(int argc, char **argv) return 1; } + char *local_addr = GetLocalAddr("https://inet-ip.aixiao.me/"); + if (local_addr == NULL) { + perror("GetLocalAddr()"); + return 1; + } + remove_char(local_addr, '\n'); + printf("Local Address: %s\n", local_addr); + printf("Read %d lines from file:\n", line_count); for (int i = 0; i < line_count; i++) { printf("Line %d: %s\n", i + 1, cn_ip[i]); } + + free(local_addr); } pid = fork(); // 创建子进程 if (pid == 0) // 子进程 { - int count = 0; snprintf(RULE_NAME, BUFFER, "root%d", RULE_NAME_NUMBER); @@ -400,7 +321,6 @@ int main(int argc, char **argv) while (1) { //_printf("子进程当前 Ipset Rule 名 %s\n", RULE_NAME); - count = get_ip_count_in_ipset(RULE_NAME); if (count >= 0) { _printf("子进程当前 Ipset Rule 名 %s, 数量: %d \n", RULE_NAME, count); @@ -417,7 +337,6 @@ int main(int argc, char **argv) sprintf(iptables_command, "iptables -I INPUT -m set --match-set %s src -j DROP", RULE_NAME); system(iptables_command); } - } if (RULE_NAME_NUMBER == MAXIPSET_RULT_NAME_NUM) { @@ -426,7 +345,7 @@ int main(int argc, char **argv) } } - sleep(9); // 每 3 秒检查一次 + sleep(3); // 每 3 秒检查一次 } } diff --git a/common.c b/common.c index f34972a..d17b26a 100644 --- a/common.c +++ b/common.c @@ -270,3 +270,15 @@ char *_execute_command(const char *command) { return output; } +void remove_char(char *str, char c) +{ + int i = 0, j = 0; + while (str[i]) { + if (str[i] != c) { + str[j++] = str[i]; + } + i++; + } + str[j] = '\0'; +} + diff --git a/common.h b/common.h index 338e5d2..5a05c4e 100644 --- a/common.h +++ b/common.h @@ -43,4 +43,6 @@ extern int is_valid_ip(const char *ip); extern int _command_exists(const char *command); extern char *_execute_command(const char *command); +extern void remove_char(char *str, char c); + #endif diff --git a/libcurl.c b/libcurl.c index 889b019..38bb650 100644 --- a/libcurl.c +++ b/libcurl.c @@ -27,8 +27,76 @@ static size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, voi return realsize; } +char *GetLocalAddr(char *url) +{ + CURL *curl_handle; + CURLcode res; + + struct curl_slist *headers = NULL; + struct MemoryStruct chunk; + + chunk.memory = malloc(1); /* 将根据上述再分配的需要增长 */ + chunk.size = 0; /* 此时没有数据 */ + + curl_global_init(CURL_GLOBAL_ALL); + + /* 初始化curl会话 */ + curl_handle = curl_easy_init(); + + char *p = NULL; + char *buff; + + p = strstr(url, "-H"); + if (p) { + + buff = (char *)alloca(p - url + 1); + if (buff == NULL) + perror("out of memory."); + + memset(buff, 0, p - url + 1); + memcpy(buff, url, (int)(p - url - 1)); + + // 赋值header值 + headers = curl_slist_append(headers, p + 3); + + // 设置header + curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, headers); + curl_easy_setopt(curl_handle, CURLOPT_URL, buff); + + } else { + /* 指定要获取的URL */ + curl_easy_setopt(curl_handle, CURLOPT_URL, url); + + } + + /* 将所有数据发送到此函数 */ + //对于同一次阻塞的curl_easy_perform而言,在写完获取的数据之前,会多次调用 WriteMemoryCallback + curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); + + /* 将"chunk"结构传递给回调函数 */ + curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk); + + curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0"); + + //对于同一次阻塞的curl_easy_perform而言,在写完获取的数据之前,会多次调用 WriteMemoryCallback + res = curl_easy_perform(curl_handle); + + if (res != CURLE_OK) { + fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); + } else { + //printf("%lu bytes retrieved\n", (unsigned long)chunk.size); + //printf("%s", chunk.memory); + ; + } + + curl_easy_cleanup(curl_handle); + curl_global_cleanup(); + + return chunk.memory; +} + // 获取公网IP -char *curl_get_area(char *ip) +char *CurlGetIpArea(char *ip) { char url[256] = { 0 }; snprintf(url, sizeof(url), "https://qifu.baidu.com/ip/geo/v1/district?ip=%s", ip); @@ -114,7 +182,10 @@ void parse_string_field(cJSON *parent, const char *field_name, char *output, siz // 函数用于从 JSON 字符串解析为结构体 int parse_json_to_struct(const char *json_string, Response *response) { - if (!response) return -1; + if (!json_string || !response) { + fprintf(stderr, "Invalid input parameters!\n"); + return -1; + } // 初始化结构体 memset(response, 0, sizeof(Response)); @@ -152,7 +223,12 @@ int parse_json_to_struct(const char *json_string, Response *response) parse_string_field(data_item, "region", response->data.region, sizeof(response->data.region)); } - snprintf(response->continent_country, 256, "%s%s", response->data.continent, response->data.country); + // ----------- 拼接 continent_country --------------- + if (snprintf(response->continent_country, sizeof(response->continent_country), "%s%s", response->data.continent, response->data.country) >= sizeof(response->continent_country)) { + fprintf(stderr, "continent_country truncated!\n"); + } + + //snprintf(response->continent_country, 256, "%s%s", response->data.continent, response->data.country); // 清理 JSON 对象 cJSON_Delete(root); @@ -186,4 +262,4 @@ int main(int argc, char *argv[]) free(p); } -*/ \ No newline at end of file +*/ diff --git a/libcurl.h b/libcurl.h index 220235e..5cf0f2e 100644 --- a/libcurl.h +++ b/libcurl.h @@ -43,7 +43,8 @@ typedef struct { } Response; -extern char *curl_get_area(char *URL); +extern char *CurlGetIpArea(char *ip); +extern char *GetLocalAddr(char *url); extern int parse_json_to_struct(const char *json_string, Response *response);