summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2018-04-20 09:45:27 +0300
committerSergey Poznyakoff <gray@gnu.org>2018-04-20 09:52:18 +0300
commite8caefcc1b1a19abfca6a1e0a7dfea4af2761b53 (patch)
treed406fc23d7ccfe18fafba72ea5233834edccec4f
parent2bc017183f7c923bba31a84b394f2208745a0aeb (diff)
downloadfileserv-e8caefcc1b1a19abfca6a1e0a7dfea4af2761b53.tar.gz
fileserv-e8caefcc1b1a19abfca6a1e0a7dfea4af2761b53.tar.bz2
Handle IPv4 mapped addresses
-rw-r--r--src/remoteip.c26
1 files changed, 21 insertions, 5 deletions
diff --git a/src/remoteip.c b/src/remoteip.c
index 9515df0..61bb015 100644
--- a/src/remoteip.c
+++ b/src/remoteip.c
@@ -27,6 +27,18 @@ str_is_ipv4(const char *addr)
27 return (dot_count == 3); 27 return (dot_count == 3);
28} 28}
29 29
30#define PFXSTR_IPV4_MAPPED "::ffff:"
31#define PFXLEN_IPV4_MAPPED (sizeof PFXSTR_IPV4_MAPPED - 1)
32
33static int
34str_is_ipv4mapped(const char *addr)
35{
36 return strlen(addr) > PFXLEN_IPV4_MAPPED
37 && strncasecmp(PFXSTR_IPV4_MAPPED, addr, PFXLEN_IPV4_MAPPED)
38 == 0
39 && str_is_ipv4(addr + PFXLEN_IPV4_MAPPED);
40}
41
30/* Returns 1 if ADDR is a valid IPv6 address */ 42/* Returns 1 if ADDR is a valid IPv6 address */
31static int 43static int
32str_is_ipv6(const char *addr) 44str_is_ipv6(const char *addr)
@@ -120,7 +132,7 @@ static int
120str_to_cidr(char const *str, struct cidr *cidr) 132str_to_cidr(char const *str, struct cidr *cidr)
121{ 133{
122 int rc; 134 int rc;
123 char *ipbuf; 135 char *ipbuf, *ipstart;
124 union { 136 union {
125 struct in_addr in; 137 struct in_addr in;
126 struct in6_addr in6; 138 struct in6_addr in6;
@@ -137,10 +149,14 @@ str_to_cidr(char const *str, struct cidr *cidr)
137 ipbuf = xmalloc(len+1); 149 ipbuf = xmalloc(len+1);
138 memcpy(ipbuf, str, len); 150 memcpy(ipbuf, str, len);
139 ipbuf[len] = 0; 151 ipbuf[len] = 0;
140 152 ipstart = ipbuf;
141 if (str_is_ipv4(ipbuf)) 153
154 if (str_is_ipv4(ipstart))
155 cidr->family = AF_INET;
156 else if (str_is_ipv4mapped(ipstart)) {
142 cidr->family = AF_INET; 157 cidr->family = AF_INET;
143 else if (str_is_ipv6(ipbuf)) 158 ipstart += PFXLEN_IPV4_MAPPED;
159 } else if (str_is_ipv6(ipbuf))
144 cidr->family = AF_INET6; 160 cidr->family = AF_INET6;
145 else { 161 else {
146 free(ipbuf); 162 free(ipbuf);
@@ -148,7 +164,7 @@ str_to_cidr(char const *str, struct cidr *cidr)
148 return -1; 164 return -1;
149 } 165 }
150 166
151 rc = inet_pton(cidr->family, ipbuf, &inaddr); 167 rc = inet_pton(cidr->family, ipstart, &inaddr);
152 free(ipbuf); 168 free(ipbuf);
153 169
154 if (rc != 1) { 170 if (rc != 1) {

Return to:

Send suggestions and report system problems to the System administrator.