|
Lines 275-362
passin:
Link Here
|
| 275 |
if (ip->ip_ttl <= IPTTLDEC) { |
275 |
if (ip->ip_ttl <= IPTTLDEC) { |
| 276 |
icmp_error(m, ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS, 0, 0); |
276 |
icmp_error(m, ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS, 0, 0); |
| 277 |
return NULL; /* mbuf already free'd */ |
277 |
return NULL; /* mbuf already free'd */ |
| 278 |
} |
278 |
} |
| 279 |
|
279 |
|
| 280 |
/* |
280 |
/* |
| 281 |
* Decrement the TTL and incrementally change the IP header checksum. |
281 |
* Decrement the TTL and incrementally change the IP header checksum. |
| 282 |
* Don't bother doing this with hw checksum offloading, it's faster |
282 |
* Don't bother doing this with hw checksum offloading, it's faster |
| 283 |
* doing it right here. |
283 |
* doing it right here. |
| 284 |
*/ |
284 |
*/ |
| 285 |
ip->ip_ttl -= IPTTLDEC; |
285 |
ip->ip_ttl -= IPTTLDEC; |
| 286 |
if (ip->ip_sum >= (u_int16_t) ~htons(IPTTLDEC << 8)) |
286 |
if (ip->ip_sum >= (u_int16_t) ~htons(IPTTLDEC << 8)) |
| 287 |
ip->ip_sum -= ~htons(IPTTLDEC << 8); |
287 |
ip->ip_sum -= ~htons(IPTTLDEC << 8); |
| 288 |
else |
288 |
else |
| 289 |
ip->ip_sum += htons(IPTTLDEC << 8); |
289 |
ip->ip_sum += htons(IPTTLDEC << 8); |
| 290 |
#ifdef IPSTEALTH |
290 |
#ifdef IPSTEALTH |
| 291 |
} |
291 |
} |
| 292 |
#endif |
292 |
#endif |
| 293 |
|
293 |
|
| 294 |
/* |
294 |
/* |
|
|
295 |
* Next hop forced by ipfilter hook? |
| 296 |
*/ |
| 297 |
if (m->m_flags & M_IP_NEXTHOP) { |
| 298 |
fwd_tag = m_tag_find(m, PACKET_TAG_IPFORWARD, NULL); |
| 299 |
/* |
| 300 |
* Skip outgoing filtering. |
| 301 |
*/ |
| 302 |
if (fwd_tag) |
| 303 |
goto reroute; |
| 304 |
} |
| 305 |
/* |
| 295 |
* Find route to destination. |
306 |
* Find route to destination. |
| 296 |
*/ |
307 |
*/ |
| 297 |
if (ip_findroute(&nh, dest, m) != 0) |
308 |
if (ip_findroute(&nh, dest, m) != 0) |
| 298 |
return (NULL); /* icmp unreach already sent */ |
309 |
return (NULL); /* icmp unreach already sent */ |
| 299 |
|
310 |
|
| 300 |
/* |
311 |
/* |
| 301 |
* Step 5: outgoing firewall packet processing |
312 |
* Step 5: outgoing firewall packet processing |
| 302 |
*/ |
313 |
*/ |
| 303 |
if (!PFIL_HOOKED(&V_inet_pfil_hook)) |
314 |
if (!PFIL_HOOKED(&V_inet_pfil_hook)) |
| 304 |
goto passout; |
315 |
goto passout; |
| 305 |
|
316 |
|
| 306 |
if (pfil_run_hooks(&V_inet_pfil_hook, &m, nh.nh_ifp, PFIL_OUT, PFIL_FWD, |
317 |
if (pfil_run_hooks(&V_inet_pfil_hook, &m, nh.nh_ifp, PFIL_OUT, PFIL_FWD, |
| 307 |
NULL) || m == NULL) { |
318 |
NULL) || m == NULL) { |
| 308 |
goto drop; |
319 |
goto drop; |
| 309 |
} |
320 |
} |
| 310 |
|
321 |
|
| 311 |
M_ASSERTVALID(m); |
322 |
M_ASSERTVALID(m); |
| 312 |
M_ASSERTPKTHDR(m); |
323 |
M_ASSERTPKTHDR(m); |
| 313 |
|
324 |
|
| 314 |
ip = mtod(m, struct ip *); |
325 |
ip = mtod(m, struct ip *); |
| 315 |
dest.s_addr = ip->ip_dst.s_addr; |
326 |
dest.s_addr = ip->ip_dst.s_addr; |
| 316 |
|
327 |
|
| 317 |
/* |
328 |
/* |
| 318 |
* Destination address changed? |
329 |
* Destination address changed? |
| 319 |
*/ |
330 |
*/ |
| 320 |
if (m->m_flags & M_IP_NEXTHOP) |
331 |
if (m->m_flags & M_IP_NEXTHOP) |
| 321 |
fwd_tag = m_tag_find(m, PACKET_TAG_IPFORWARD, NULL); |
332 |
fwd_tag = m_tag_find(m, PACKET_TAG_IPFORWARD, NULL); |
| 322 |
if (odest.s_addr != dest.s_addr || fwd_tag != NULL) { |
333 |
if (odest.s_addr != dest.s_addr || fwd_tag != NULL) { |
| 323 |
/* |
334 |
/* |
| 324 |
* Is it now for a local address on this host? |
335 |
* Is it now for a local address on this host? |
| 325 |
*/ |
336 |
*/ |
| 326 |
if (m->m_flags & M_FASTFWD_OURS || in_localip(dest)) { |
337 |
if (m->m_flags & M_FASTFWD_OURS || in_localip(dest)) { |
| 327 |
forwardlocal: |
338 |
forwardlocal: |
| 328 |
/* |
339 |
/* |
| 329 |
* Return packet for processing by ip_input(). |
340 |
* Return packet for processing by ip_input(). |
| 330 |
*/ |
341 |
*/ |
| 331 |
m->m_flags |= M_FASTFWD_OURS; |
342 |
m->m_flags |= M_FASTFWD_OURS; |
| 332 |
return (m); |
343 |
return (m); |
| 333 |
} |
344 |
} |
| 334 |
/* |
345 |
} |
| 335 |
* Redo route lookup with new destination address |
346 |
|
| 336 |
*/ |
347 |
reroute: |
| 337 |
if (fwd_tag) { |
348 |
if (fwd_tag != NULL) { |
| 338 |
dest.s_addr = ((struct sockaddr_in *) |
349 |
dest.s_addr = ((struct sockaddr_in *) |
| 339 |
(fwd_tag + 1))->sin_addr.s_addr; |
350 |
(fwd_tag + 1))->sin_addr.s_addr; |
| 340 |
m_tag_delete(m, fwd_tag); |
351 |
m_tag_delete(m, fwd_tag); |
| 341 |
m->m_flags &= ~M_IP_NEXTHOP; |
352 |
m->m_flags &= ~M_IP_NEXTHOP; |
| 342 |
} |
353 |
} |
|
|
354 |
/* |
| 355 |
* Redo route lookup with new destination address |
| 356 |
*/ |
| 357 |
if (odest.s_addr != dest.s_addr || fwd_tag != NULL) { |
| 343 |
if (ip_findroute(&nh, dest, m) != 0) |
358 |
if (ip_findroute(&nh, dest, m) != 0) |
| 344 |
return (NULL); /* icmp unreach already sent */ |
359 |
return (NULL); /* icmp unreach already sent */ |
| 345 |
} |
360 |
} |
| 346 |
|
361 |
|
| 347 |
passout: |
362 |
passout: |
| 348 |
/* |
363 |
/* |
| 349 |
* Step 6: send off the packet |
364 |
* Step 6: send off the packet |
| 350 |
*/ |
365 |
*/ |
| 351 |
ip_len = ntohs(ip->ip_len); |
366 |
ip_len = ntohs(ip->ip_len); |
| 352 |
ip_off = ntohs(ip->ip_off); |
367 |
ip_off = ntohs(ip->ip_off); |
| 353 |
|
368 |
|
| 354 |
bzero(&dst, sizeof(dst)); |
369 |
bzero(&dst, sizeof(dst)); |
| 355 |
dst.sin_family = AF_INET; |
370 |
dst.sin_family = AF_INET; |
| 356 |
dst.sin_len = sizeof(dst); |
371 |
dst.sin_len = sizeof(dst); |
| 357 |
dst.sin_addr = nh.nh_addr; |
372 |
dst.sin_addr = nh.nh_addr; |
| 358 |
|
373 |
|
| 359 |
/* |
374 |
/* |
| 360 |
* Check if packet fits MTU or if hardware will fragment for us |
375 |
* Check if packet fits MTU or if hardware will fragment for us |
| 361 |
*/ |
376 |
*/ |
| 362 |
if (ip_len <= nh.nh_mtu) { |
377 |
if (ip_len <= nh.nh_mtu) { |