| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: ipf.c,v 1.3 2011/02/02 02:20:26 rmind Exp $ */ | | 1 | /* $NetBSD: ipf.c,v 1.4 2012/01/30 16:14:27 darrenr Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 2004, 2008 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 2004, 2008 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
| @@ -141,50 +141,50 @@ static struct ftp_proxy_entry * | | | @@ -141,50 +141,50 @@ static struct ftp_proxy_entry * |
141 | ftp_proxy_entry_find(u_int32_t id) | | 141 | ftp_proxy_entry_find(u_int32_t id) |
142 | { | | 142 | { |
143 | struct ftp_proxy_entry *fpe; | | 143 | struct ftp_proxy_entry *fpe; |
144 | | | 144 | |
145 | LIST_FOREACH(fpe, &ftp_proxy_entries, link) { | | 145 | LIST_FOREACH(fpe, &ftp_proxy_entries, link) { |
146 | if (fpe->id == id) { | | 146 | if (fpe->id == id) { |
147 | return fpe; | | 147 | return fpe; |
148 | } | | 148 | } |
149 | } | | 149 | } |
150 | return NULL; | | 150 | return NULL; |
151 | } | | 151 | } |
152 | | | 152 | |
153 | static int | | 153 | static int |
154 | ftp_proxy_entry_add_nat(struct ftp_proxy_entry *fpe, ipnat_t ipn) | | 154 | ftp_proxy_entry_add_nat(struct ftp_proxy_entry *fpe, ipnat_t *ipn) |
155 | { | | 155 | { |
156 | struct ftp_proxy_nat *fpn; | | 156 | struct ftp_proxy_nat *fpn; |
157 | | | 157 | |
158 | fpn = malloc(sizeof(*fpn)); | | 158 | fpn = malloc(sizeof(*fpn)); |
159 | if (fpn == NULL) | | 159 | if (fpn == NULL) |
160 | return (-1); | | 160 | return (-1); |
161 | | | 161 | |
162 | memcpy(&fpn->ipn, &ipn, sizeof(fpn->ipn)); | | 162 | memcpy(&fpn->ipn, ipn, sizeof(fpn->ipn)); |
163 | LIST_INSERT_HEAD(&fpe->nat_entries, fpn, link); | | 163 | LIST_INSERT_HEAD(&fpe->nat_entries, fpn, link); |
164 | | | 164 | |
165 | return (0); | | 165 | return (0); |
166 | } | | 166 | } |
167 | | | 167 | |
168 | static int | | 168 | static int |
169 | ipfilter_add_nat(ipnat_t ipn) | | 169 | ipfilter_add_nat(ipnat_t *ipn) |
170 | { | | 170 | { |
171 | ipfobj_t obj; | | 171 | ipfobj_t obj; |
172 | | | 172 | |
173 | memset(&obj, 0, sizeof(obj)); | | 173 | memset(&obj, 0, sizeof(obj)); |
174 | obj.ipfo_rev = IPFILTER_VERSION; | | 174 | obj.ipfo_rev = IPFILTER_VERSION; |
175 | obj.ipfo_size = sizeof(ipn); | | 175 | obj.ipfo_size = ipn->in_size; |
176 | obj.ipfo_type = IPFOBJ_IPNAT; | | 176 | obj.ipfo_type = IPFOBJ_IPNAT; |
177 | obj.ipfo_ptr = &ipn; | | 177 | obj.ipfo_ptr = ipn; |
178 | | | 178 | |
179 | return ioctl(natfd, SIOCADNAT, &obj); | | 179 | return ioctl(natfd, SIOCADNAT, &obj); |
180 | } | | 180 | } |
181 | | | 181 | |
182 | static int | | 182 | static int |
183 | ipfilter_remove_nat(ipnat_t ipn) | | 183 | ipfilter_remove_nat(ipnat_t ipn) |
184 | { | | 184 | { |
185 | ipfobj_t obj; | | 185 | ipfobj_t obj; |
186 | | | 186 | |
187 | memset(&obj, 0, sizeof(obj)); | | 187 | memset(&obj, 0, sizeof(obj)); |
188 | obj.ipfo_rev = IPFILTER_VERSION; | | 188 | obj.ipfo_rev = IPFILTER_VERSION; |
189 | obj.ipfo_size = sizeof(ipn); | | 189 | obj.ipfo_size = sizeof(ipn); |
190 | obj.ipfo_type = IPFOBJ_IPNAT; | | 190 | obj.ipfo_type = IPFOBJ_IPNAT; |
| @@ -214,131 +214,81 @@ ipf_add_nat(u_int32_t id, struct sockadd | | | @@ -214,131 +214,81 @@ ipf_add_nat(u_int32_t id, struct sockadd |
214 | u_int16_t nat_range_high) | | 214 | u_int16_t nat_range_high) |
215 | { | | 215 | { |
216 | | | 216 | |
217 | /* TODO */ | | 217 | /* TODO */ |
218 | | | 218 | |
219 | return (0); | | 219 | return (0); |
220 | } | | 220 | } |
221 | | | 221 | |
222 | int | | 222 | int |
223 | ipf_add_rdr(u_int32_t id, struct sockaddr *src, struct sockaddr *dst, | | 223 | ipf_add_rdr(u_int32_t id, struct sockaddr *src, struct sockaddr *dst, |
224 | u_int16_t d_port, struct sockaddr *rdr, u_int16_t rdr_port) | | 224 | u_int16_t d_port, struct sockaddr *rdr, u_int16_t rdr_port) |
225 | { | | 225 | { |
226 | struct ftp_proxy_entry *fpe = ftp_proxy_entry_find(id); | | 226 | struct ftp_proxy_entry *fpe = ftp_proxy_entry_find(id); |
227 | ipnat_t ipn; | | 227 | ipnat_t *ipn; |
228 | | | 228 | |
229 | if (fpe == NULL) { | | 229 | if (fpe == NULL) { |
230 | errno = ENOENT; | | 230 | errno = ENOENT; |
231 | return (-1); | | 231 | return (-1); |
232 | } | | 232 | } |
233 | | | 233 | |
234 | if (!src || !dst || !d_port || !rdr || !rdr_port || | | 234 | if (!src || !dst || !d_port || !rdr || !rdr_port || |
235 | (src->sa_family != rdr->sa_family)) { | | 235 | (src->sa_family != rdr->sa_family)) { |
236 | errno = EINVAL; | | 236 | errno = EINVAL; |
237 | return (-1); | | 237 | return (-1); |
238 | } | | 238 | } |
239 | | | 239 | |
240 | memset(&ipn, 0, sizeof(ipn)); | | 240 | ipn = calloc(1, sizeof(*ipn) + 2 * IF_NAMESIZE + 2); |
241 | ipn.in_redir = NAT_REDIRECT; | | 241 | if (ipn == NULL) { |
242 | ipn.in_v = 4; | | 242 | errno = ENOMEM; |
243 | ipn.in_outip = satosin(dst)->sin_addr.s_addr; | | | |
244 | ipn.in_outmsk = 0xffffffff; | | | |
245 | strlcpy(ipn.in_ifnames[0], netif, sizeof(ipn.in_ifnames[0])); | | | |
246 | strlcpy(ipn.in_ifnames[1], netif, sizeof(ipn.in_ifnames[1])); | | | |
247 | ipn.in_pmin = htons(d_port); | | | |
248 | ipn.in_pmax = htons(d_port); | | | |
249 | ipn.in_inip = satosin(rdr)->sin_addr.s_addr; | | | |
250 | ipn.in_inmsk = 0xffffffff; | | | |
251 | ipn.in_pnext = htons(rdr_port); | | | |
252 | ipn.in_flags = IPN_FIXEDDPORT | IPN_TCP; | | | |
253 | strlcpy(ipn.in_tag.ipt_tag, fpe->proxy_tag, sizeof(ipn.in_tag.ipt_tag)); | | | |
254 | | | | |
255 | if (ipfilter_add_nat(ipn) == -1) | | | |
256 | return (-1); | | 243 | return (-1); |
| | | 244 | } |
| | | 245 | ipn->in_redir = NAT_REDIRECT; |
| | | 246 | ipn->in_v[0] = 4; |
| | | 247 | ipn->in_v[1] = 4; |
| | | 248 | ipn->in_odstaddr = satosin(dst)->sin_addr.s_addr; |
| | | 249 | ipn->in_odstmsk = 0xffffffff; |
| | | 250 | ipn->in_odport = htons(d_port); |
| | | 251 | ipn->in_dtop = htons(d_port); |
| | | 252 | ipn->in_ndstaddr = satosin(rdr)->sin_addr.s_addr; |
| | | 253 | ipn->in_ndstmsk = 0xffffffff; |
| | | 254 | ipn->in_dpnext = htons(rdr_port); |
| | | 255 | ipn->in_flags = IPN_FIXEDDPORT | IPN_TCP; |
| | | 256 | strlcpy(ipn->in_tag.ipt_tag, fpe->proxy_tag, |
| | | 257 | sizeof(ipn->in_tag.ipt_tag)); |
| | | 258 | |
| | | 259 | ipn->in_ifnames[0] = 0; |
| | | 260 | (void) strlcpy(ipn->in_names, netif, IF_NAMESIZE); |
| | | 261 | ipn->in_namelen = strlen(ipn->in_names) + 1; |
| | | 262 | ipn->in_ifnames[1] = ipn->in_namelen; |
| | | 263 | (void) strlcpy(ipn->in_names + ipn->in_namelen, netif, IF_NAMESIZE); |
| | | 264 | ipn->in_namelen += strlen(ipn->in_names + ipn->in_ifnames[1]) + 1; |
| | | 265 | ipn->in_size = sizeof(*ipn) + ipn->in_namelen; |
257 | | | 266 | |
258 | if (ftp_proxy_entry_add_nat(fpe, ipn) == -1) | | 267 | if (ipfilter_add_nat(ipn) == -1) { |
| | | 268 | free(ipn); |
259 | return (-1); | | 269 | return (-1); |
| | | 270 | } |
260 | | | 271 | |
261 | fpe->status = 1; | | 272 | if (ftp_proxy_entry_add_nat(fpe, ipn) == -1) { |
262 | | | 273 | free(ipn); |
263 | return (0); | | | |
264 | } | | | |
265 | | | | |
266 | #if 0 | | | |
267 | int | | | |
268 | ipf_add_rdr(u_int32_t id, struct sockaddr *src, struct sockaddr *dst, | | | |
269 | u_int16_t d_port, struct sockaddr *rdr, u_int16_t rdr_port) | | | |
270 | { | | | |
271 | u_32_t sum1, sum2, sumd; | | | |
272 | int onoff, error; | | | |
273 | nat_save_t ns; | | | |
274 | ipfobj_t obj; | | | |
275 | nat_t *nat; | | | |
276 | | | | |
277 | if (!src || !dst || !d_port || !rdr || !rdr_port || | | | |
278 | (src->sa_family != rdr->sa_family)) { | | | |
279 | errno = EINVAL; | | | |
280 | return (-1); | | 274 | return (-1); |
281 | } | | 275 | } |
282 | | | 276 | |
283 | memset(&ns, 0, sizeof(ns)); | | 277 | fpe->status = 1; |
284 | | | 278 | free(ipn); |
285 | nat = &ns.ipn_nat; | | | |
286 | nat->nat_p = IPPROTO_TCP; | | | |
287 | nat->nat_dir = NAT_OUTBOUND; | | | |
288 | nat->nat_redir = NAT_REDIRECT; | | | |
289 | strlcpy(nat->nat_ifnames[0], netif, sizeof(nat->nat_ifnames[0])); | | | |
290 | strlcpy(nat->nat_ifnames[1], netif, sizeof(nat->nat_ifnames[1])); | | | |
291 | | | | |
292 | nat->nat_inip = satosin(rdr)->sin_addr; | | | |
293 | nat->nat_outip = satosin(dst)->sin_addr; | | | |
294 | nat->nat_oip = satosin(src)->sin_addr; | | | |
295 | | | | |
296 | sum1 = LONG_SUM(ntohl(nat->nat_inip.s_addr)) + rdr_port; | | | |
297 | sum2 = LONG_SUM(ntohl(nat->nat_outip.s_addr)) + d_port; | | | |
298 | CALC_SUMD(sum1, sum2, sumd); | | | |
299 | nat->nat_sumd[0] = (sumd & 0xffff) + (sumd >> 16); | | | |
300 | nat->nat_sumd[1] = nat->nat_sumd[0]; | | | |
301 | | | | |
302 | sum1 = LONG_SUM(ntohl(nat->nat_inip.s_addr)); | | | |
303 | sum2 = LONG_SUM(ntohl(nat->nat_outip.s_addr)); | | | |
304 | CALC_SUMD(sum1, sum2, sumd); | | | |
305 | nat->nat_ipsumd = (sumd & 0xffff) + (sumd >> 16); | | | |
306 | | | | |
307 | nat->nat_inport = htons(rdr_port); | | | |
308 | nat->nat_outport = htons(d_port); | | | |
309 | nat->nat_oport = satosin(src)->sin_port; | | | |
310 | | | | |
311 | nat->nat_flags = IPN_TCPUDP; | | | |
312 | | | | |
313 | memset(&obj, 0, sizeof(obj)); | | | |
314 | obj.ipfo_rev = IPFILTER_VERSION; | | | |
315 | obj.ipfo_size = sizeof(ns); | | | |
316 | obj.ipfo_ptr = &ns; | | | |
317 | obj.ipfo_type = IPFOBJ_NATSAVE; | | | |
318 | | | | |
319 | error = 0; | | | |
320 | onoff = 1; | | | |
321 | if (ioctl(natfd, SIOCSTLCK, &onoff) == -1) | | | |
322 | return (-1); | | | |
323 | if (ioctl(natfd, SIOCSTPUT, &obj) == -1) | | | |
324 | error = -1; | | | |
325 | onoff = 0; | | | |
326 | if (ioctl(natfd, SIOCSTLCK, &onoff) == -1) | | | |
327 | error = -1; | | | |
328 | | | 279 | |
329 | return (error); | | 280 | return (0); |
330 | } | | 281 | } |
331 | #endif | | | |
332 | | | 282 | |
333 | int | | 283 | int |
334 | ipf_do_commit(void) | | 284 | ipf_do_commit(void) |
335 | { | | 285 | { |
336 | struct ftp_proxy_entry *fpe, *n; | | 286 | struct ftp_proxy_entry *fpe, *n; |
337 | struct ftp_proxy_nat *fpn; | | 287 | struct ftp_proxy_nat *fpn; |
338 | | | 288 | |
339 | for (fpe = LIST_FIRST(&ftp_proxy_entries); fpe != NULL; fpe = n) { | | 289 | for (fpe = LIST_FIRST(&ftp_proxy_entries); fpe != NULL; fpe = n) { |
340 | n = LIST_NEXT(fpe, link); | | 290 | n = LIST_NEXT(fpe, link); |
341 | | | 291 | |
342 | /* | | 292 | /* |
343 | * If status is nul, then the session is going to be ended. | | 293 | * If status is nul, then the session is going to be ended. |
344 | * Remove all nat mappings that were added. | | 294 | * Remove all nat mappings that were added. |