aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>2006-06-18 14:20:32 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2006-09-22 18:18:02 -0400
commit1884f78c7a8b456c654338e3eb2874a99688ea10 (patch)
tree1e4bb6d6a4355790e6d8a3fa36b4be7045b6dad3
parent1aaec67f9335a17856dfacdd3e5cc6f4c18faeec (diff)
[NETFILTER] NF_CONNTRACK_FTP: Use in6_pton() to convert address string.
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
-rw-r--r--net/netfilter/nf_conntrack_ftp.c96
1 files changed, 4 insertions, 92 deletions
diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c
index 960972d225f9..9dccb4039889 100644
--- a/net/netfilter/nf_conntrack_ftp.c
+++ b/net/netfilter/nf_conntrack_ftp.c
@@ -111,101 +111,13 @@ static struct ftp_search {
111 }, 111 },
112}; 112};
113 113
114/* This code is based on inet_pton() in glibc-2.2.4 */
115static int 114static int
116get_ipv6_addr(const char *src, size_t dlen, struct in6_addr *dst, u_int8_t term) 115get_ipv6_addr(const char *src, size_t dlen, struct in6_addr *dst, u_int8_t term)
117{ 116{
118 static const char xdigits[] = "0123456789abcdef"; 117 int ret = in6_pton(src, min_t(size_t, dlen, 0xffff), dst, term, &end);
119 u_int8_t tmp[16], *tp, *endp, *colonp; 118 if (ret > 0)
120 int ch, saw_xdigit; 119 return (int)(end - src);
121 u_int32_t val; 120 return 0;
122 size_t clen = 0;
123
124 tp = memset(tmp, '\0', sizeof(tmp));
125 endp = tp + sizeof(tmp);
126 colonp = NULL;
127
128 /* Leading :: requires some special handling. */
129 if (*src == ':'){
130 if (*++src != ':') {
131 DEBUGP("invalid \":\" at the head of addr\n");
132 return 0;
133 }
134 clen++;
135 }
136
137 saw_xdigit = 0;
138 val = 0;
139 while ((clen < dlen) && (*src != term)) {
140 const char *pch;
141
142 ch = tolower(*src++);
143 clen++;
144
145 pch = strchr(xdigits, ch);
146 if (pch != NULL) {
147 val <<= 4;
148 val |= (pch - xdigits);
149 if (val > 0xffff)
150 return 0;
151
152 saw_xdigit = 1;
153 continue;
154 }
155 if (ch != ':') {
156 DEBUGP("get_ipv6_addr: invalid char. \'%c\'\n", ch);
157 return 0;
158 }
159
160 if (!saw_xdigit) {
161 if (colonp) {
162 DEBUGP("invalid location of \"::\".\n");
163 return 0;
164 }
165 colonp = tp;
166 continue;
167 } else if (*src == term) {
168 DEBUGP("trancated IPv6 addr\n");
169 return 0;
170 }
171
172 if (tp + 2 > endp)
173 return 0;
174 *tp++ = (u_int8_t) (val >> 8) & 0xff;
175 *tp++ = (u_int8_t) val & 0xff;
176
177 saw_xdigit = 0;
178 val = 0;
179 continue;
180 }
181 if (saw_xdigit) {
182 if (tp + 2 > endp)
183 return 0;
184 *tp++ = (u_int8_t) (val >> 8) & 0xff;
185 *tp++ = (u_int8_t) val & 0xff;
186 }
187 if (colonp != NULL) {
188 /*
189 * Since some memmove()'s erroneously fail to handle
190 * overlapping regions, we'll do the shift by hand.
191 */
192 const int n = tp - colonp;
193 int i;
194
195 if (tp == endp)
196 return 0;
197
198 for (i = 1; i <= n; i++) {
199 endp[- i] = colonp[n - i];
200 colonp[n - i] = 0;
201 }
202 tp = endp;
203 }
204 if (tp != endp || (*src != term))
205 return 0;
206
207 memcpy(dst->s6_addr, tmp, sizeof(dst->s6_addr));
208 return clen;
209} 121}
210 122
211static int try_number(const char *data, size_t dlen, u_int32_t array[], 123static int try_number(const char *data, size_t dlen, u_int32_t array[],