Skip to content

Commit 436d951

Browse files
committed
Move ip matching functionality into net_util.c.
1 parent 00ead44 commit 436d951

File tree

5 files changed

+133
-134
lines changed

5 files changed

+133
-134
lines changed

CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ list(APPEND PROXYRES_SRCS
3030
event.h
3131
log.h
3232
mutex.h
33+
net_util.h
34+
net_util.c
3335
proxyres.c
3436
resolver_i.h
3537
resolver.c
@@ -44,8 +46,6 @@ if(PROXYRES_EXECUTE)
4446
mozilla_js.h
4547
net_adapter.h
4648
net_adapter.c
47-
net_util.h
48-
net_util.c
4949
resolver_posix.h
5050
resolver_posix.c
5151
wpad_dhcp.h

net_util.c

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
# include <winsock2.h>
1010
# include <ws2tcpip.h>
1111
#else
12+
# include <arpa/inet.h>
1213
# include <sys/types.h>
1314
# include <sys/socket.h>
1415
# include <netdb.h>
@@ -132,3 +133,126 @@ char *dns_resolve(const char *host, int32_t *error) {
132133
char *dns_resolve_ex(const char *host, int32_t *error) {
133134
return dns_resolve_filter(host, AF_UNSPEC, UINT8_MAX, error);
134135
}
136+
137+
#if _WIN32_WINNT < _WIN32_WINNT_VISTA
138+
// Backwards compatible inet_pton for Windows XP
139+
int32_t inet_pton(int32_t af, const char *src, void *dst) {
140+
struct sockaddr_storage sock_storage;
141+
int32_t size = sizeof(sockaddr_storage);
142+
char src_copy[INET6_ADDRSTRLEN + 1];
143+
144+
memset(&sock_storage, 0, sizeof(sock_storage));
145+
strncpy(src_copy, src, INET6_ADDRSTRLEN + 1);
146+
src_copy[INET6_ADDRSTRLEN] = 0;
147+
148+
if (WSAStringToAddress(src_copy, af, NULL, (struct sockaddr *)&sock_storage, &size) == 0) {
149+
switch (af) {
150+
case AF_INET:
151+
*(struct in_addr *)dst = ((struct sockaddr_in *)&ss)->sin_addr;
152+
return 1;
153+
case AF_INET6:
154+
*(struct in6_addr *)dst = ((struct sockaddr_in6 *)&ss)->sin6_addr;
155+
return 1;
156+
}
157+
}
158+
return 0;
159+
}
160+
#endif
161+
162+
// Check if the ipv4 address matches the cidr notation range
163+
bool is_ipv4_in_cidr_range(const char *ip, const char *cidr) {
164+
if (!ip || !cidr)
165+
return false;
166+
167+
// Convert ip from text to binary
168+
struct in_addr ip_addr;
169+
if (!inet_pton(AF_INET, ip, &ip_addr))
170+
return false;
171+
172+
// Parse cidr notation
173+
char *cidr_ip = strdup(cidr);
174+
char *cidr_prefix = strchr(cidr_ip, '/');
175+
if (!cidr_prefix) {
176+
free(cidr_ip);
177+
return false;
178+
}
179+
*cidr_prefix = 0;
180+
cidr_prefix++;
181+
182+
// Parse cidr prefix
183+
int32_t prefix = atoi(cidr_prefix);
184+
if (prefix < 0 || prefix > 32) {
185+
free(cidr_ip);
186+
return false;
187+
}
188+
189+
// Convert cidr ip from text to binary
190+
struct in_addr cidr_addr;
191+
if (!inet_pton(AF_INET, cidr_ip, &cidr_addr)) {
192+
free(cidr_ip);
193+
return false;
194+
}
195+
free(cidr_ip);
196+
197+
// Check if ip address is in cidr range
198+
uint32_t ip_int = ntohl(ip_addr.s_addr);
199+
uint32_t cidr_int = ntohl(cidr_addr.s_addr);
200+
uint32_t mask = prefix >= 32 ? 0xFFFFFFFFu : ~(0xFFFFFFFFu >> prefix);
201+
202+
return (ip_int & mask) == (cidr_int & mask);
203+
}
204+
205+
// Check if the ipv6 address matches the cidr notation range
206+
bool is_ipv6_in_cidr_range(const char *ip, const char *cidr) {
207+
if (!ip || !cidr)
208+
return false;
209+
210+
// Convert ip from text to binary
211+
struct in6_addr ip_addr;
212+
if (!inet_pton(AF_INET6, ip, &ip_addr))
213+
return false;
214+
215+
// Parse cidr notation
216+
char *cidr_ip = strdup(cidr);
217+
char *cidr_prefix = strchr(cidr_ip, '/');
218+
if (!cidr_prefix) {
219+
free(cidr_ip);
220+
return false;
221+
}
222+
*cidr_prefix = 0;
223+
cidr_prefix++;
224+
225+
// Parse cidr prefix
226+
int32_t prefix = atoi(cidr_prefix);
227+
if (prefix < 0 || prefix > 128) {
228+
free(cidr_ip);
229+
return false;
230+
}
231+
232+
// Convert cidr ip from text to binary
233+
struct in6_addr cidr_addr;
234+
if (!inet_pton(AF_INET6, cidr_ip, &cidr_addr)) {
235+
free(cidr_ip);
236+
return false;
237+
}
238+
free(cidr_ip);
239+
240+
// Check if ip address is in cidr range
241+
uint8_t *ip_data = (uint8_t *)&ip_addr.s6_addr;
242+
uint8_t *cidr_data = (uint8_t *)&cidr_addr.s6_addr;
243+
244+
// Compare leading bytes of address
245+
int32_t check_bytes = prefix / 8;
246+
if (check_bytes) {
247+
if (memcmp(ip_data, cidr_data, check_bytes))
248+
return false;
249+
}
250+
251+
// Check remaining bits of address
252+
int32_t check_bits = prefix & 0x07;
253+
if (!check_bits)
254+
return true;
255+
256+
uint8_t mask = (0xff << (8 - check_bits));
257+
return ((ip_data[check_bytes] ^ cidr_data[check_bytes]) & mask) == 0;
258+
}

net_util.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ char *dns_resolve(const char *host, int32_t *error);
1010
// Resolve a host name to its addresses
1111
char *dns_resolve_ex(const char *host, int32_t *error);
1212

13+
// Check if the ipv4 address matches the cidr notation range
14+
bool is_ipv4_in_cidr_range(const char *ip, const char *cidr);
15+
16+
// Check if the ipv6 address matches the cidr notation range
17+
bool is_ipv6_in_cidr_range(const char *ip, const char *cidr);
18+
1319
#ifdef __cplusplus
1420
}
1521
#endif

util.c

Lines changed: 1 addition & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,13 @@
66
#include <string.h>
77
#include <ctype.h>
88

9-
#ifdef _WIN32
10-
# include <ws2tcpip.h>
11-
#else
12-
# include <arpa/inet.h>
13-
#endif
14-
159
#ifdef _WIN32
1610
# define strcasecmp _stricmp
1711
# define strncasecmp _strnicmp
1812
#endif
1913

14+
#include "net_util.h"
2015
#include "util.h"
21-
#ifdef _WIN32
22-
# include "util_win.h"
23-
#endif
2416

2517
// Replace one character in the string with another
2618
int32_t str_change_chr(char *str, char from, char to) {
@@ -474,104 +466,6 @@ char *convert_proxy_list_to_uri_list(const char *proxy_list, const char *default
474466
return uri_list;
475467
}
476468

477-
// Check if the ipv4 address matches the cidr notation range
478-
static bool is_ipv4_in_cidr_range(const char *ip, const char *cidr) {
479-
if (!ip || !cidr)
480-
return false;
481-
482-
// Convert ip from text to binary
483-
struct in_addr ip_addr;
484-
if (!inet_pton(AF_INET, ip, &ip_addr))
485-
return false;
486-
487-
// Parse cidr notation
488-
char *cidr_ip = strdup(cidr);
489-
char *cidr_prefix = strchr(cidr_ip, '/');
490-
if (!cidr_prefix) {
491-
free(cidr_ip);
492-
return false;
493-
}
494-
*cidr_prefix = 0;
495-
cidr_prefix++;
496-
497-
// Parse cidr prefix
498-
int32_t prefix = atoi(cidr_prefix);
499-
if (prefix < 0 || prefix > 32) {
500-
free(cidr_ip);
501-
return false;
502-
}
503-
504-
// Convert cidr ip from text to binary
505-
struct in_addr cidr_addr;
506-
if (!inet_pton(AF_INET, cidr_ip, &cidr_addr)) {
507-
free(cidr_ip);
508-
return false;
509-
}
510-
free(cidr_ip);
511-
512-
// Check if ip address is in cidr range
513-
uint32_t ip_int = ntohl(ip_addr.s_addr);
514-
uint32_t cidr_int = ntohl(cidr_addr.s_addr);
515-
uint32_t mask = prefix >= 32 ? 0xFFFFFFFFu : ~(0xFFFFFFFFu >> prefix);
516-
517-
return (ip_int & mask) == (cidr_int & mask);
518-
}
519-
520-
// Check if the ipv6 address matches the cidr notation range
521-
static bool is_ipv6_in_cidr_range(const char *ip, const char *cidr) {
522-
if (!ip || !cidr)
523-
return false;
524-
525-
// Convert ip from text to binary
526-
struct in6_addr ip_addr;
527-
if (!inet_pton(AF_INET6, ip, &ip_addr))
528-
return false;
529-
530-
// Parse cidr notation
531-
char *cidr_ip = strdup(cidr);
532-
char *cidr_prefix = strchr(cidr_ip, '/');
533-
if (!cidr_prefix) {
534-
free(cidr_ip);
535-
return false;
536-
}
537-
*cidr_prefix = 0;
538-
cidr_prefix++;
539-
540-
// Parse cidr prefix
541-
int32_t prefix = atoi(cidr_prefix);
542-
if (prefix < 0 || prefix > 128) {
543-
free(cidr_ip);
544-
return false;
545-
}
546-
547-
// Convert cidr ip from text to binary
548-
struct in6_addr cidr_addr;
549-
if (!inet_pton(AF_INET6, cidr_ip, &cidr_addr)) {
550-
free(cidr_ip);
551-
return false;
552-
}
553-
free(cidr_ip);
554-
555-
// Check if ip address is in cidr range
556-
uint8_t *ip_data = (uint8_t *)&ip_addr.s6_addr;
557-
uint8_t *cidr_data = (uint8_t *)&cidr_addr.s6_addr;
558-
559-
// Compare leading bytes of address
560-
int32_t check_bytes = prefix / 8;
561-
if (check_bytes) {
562-
if (memcmp(ip_data, cidr_data, check_bytes))
563-
return false;
564-
}
565-
566-
// Check remaining bits of address
567-
int32_t check_bits = prefix & 0x07;
568-
if (!check_bits)
569-
return true;
570-
571-
uint8_t mask = (0xff << (8 - check_bits));
572-
return ((ip_data[check_bytes] ^ cidr_data[check_bytes]) & mask) == 0;
573-
}
574-
575469
// Evaluates whether or not the proxy should be bypassed for a given url
576470
bool should_bypass_proxy(const char *url, const char *bypass_list) {
577471
char bypass_rule[HOST_MAX] = {0};

util_win.c

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -182,28 +182,3 @@ char *convert_winhttp_proxy_list_to_uri_list(const char *proxy_list) {
182182

183183
return uri_list;
184184
}
185-
186-
#if _WIN32_WINNT < _WIN32_WINNT_VISTA
187-
// Backwards compatible inet_pton for Windows XP
188-
int32_t inet_pton(int32_t af, const char *src, void *dst) {
189-
struct sockaddr_storage sock_storage;
190-
int32_t size = sizeof(sockaddr_storage);
191-
char src_copy[INET6_ADDRSTRLEN + 1];
192-
193-
memset(&sock_storage, 0, sizeof(sock_storage));
194-
strncpy(src_copy, src, INET6_ADDRSTRLEN + 1);
195-
src_copy[INET6_ADDRSTRLEN] = 0;
196-
197-
if (WSAStringToAddress(src_copy, af, NULL, (struct sockaddr *)&sock_storage, &size) == 0) {
198-
switch (af) {
199-
case AF_INET:
200-
*(struct in_addr *)dst = ((struct sockaddr_in *)&ss)->sin_addr;
201-
return 1;
202-
case AF_INET6:
203-
*(struct in6_addr *)dst = ((struct sockaddr_in6 *)&ss)->sin6_addr;
204-
return 1;
205-
}
206-
}
207-
return 0;
208-
}
209-
#endif

0 commit comments

Comments
 (0)