diff options
author | YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> | 2006-06-18 14:20:32 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-09-22 18:18:02 -0400 |
commit | 1884f78c7a8b456c654338e3eb2874a99688ea10 (patch) | |
tree | 1e4bb6d6a4355790e6d8a3fa36b4be7045b6dad3 | |
parent | 1aaec67f9335a17856dfacdd3e5cc6f4c18faeec (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.c | 96 |
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 */ | ||
115 | static int | 114 | static int |
116 | get_ipv6_addr(const char *src, size_t dlen, struct in6_addr *dst, u_int8_t term) | 115 | get_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 | ||
211 | static int try_number(const char *data, size_t dlen, u_int32_t array[], | 123 | static int try_number(const char *data, size_t dlen, u_int32_t array[], |