Deleted Added
full compact
ip_divert.c (169462) ip_divert.c (171746)
1/*-
2 * Copyright (c) 1982, 1986, 1988, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 12 unchanged lines hidden (view full) ---

21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
1/*-
2 * Copyright (c) 1982, 1986, 1988, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 12 unchanged lines hidden (view full) ---

21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * $FreeBSD: head/sys/netinet/ip_divert.c 169462 2007-05-11 10:20:51Z rwatson $
29 * $FreeBSD: head/sys/netinet/ip_divert.c 171746 2007-08-06 22:06:36Z csjp $
30 */
31
32#if !defined(KLD_MODULE)
33#include "opt_inet.h"
34#include "opt_ipfw.h"
35#include "opt_mac.h"
36#ifndef INET
37#error "IPDIVERT requires INET."

--- 18 unchanged lines hidden (view full) ---

56#include <sys/socketvar.h>
57#include <sys/sx.h>
58#include <sys/sysctl.h>
59#include <sys/systm.h>
60
61#include <vm/uma.h>
62
63#include <net/if.h>
30 */
31
32#if !defined(KLD_MODULE)
33#include "opt_inet.h"
34#include "opt_ipfw.h"
35#include "opt_mac.h"
36#ifndef INET
37#error "IPDIVERT requires INET."

--- 18 unchanged lines hidden (view full) ---

56#include <sys/socketvar.h>
57#include <sys/sx.h>
58#include <sys/sysctl.h>
59#include <sys/systm.h>
60
61#include <vm/uma.h>
62
63#include <net/if.h>
64#include <net/netisr.h>
64#include <net/route.h>
65
66#include <netinet/in.h>
67#include <netinet/in_pcb.h>
68#include <netinet/in_systm.h>
69#include <netinet/in_var.h>
70#include <netinet/ip.h>
71#include <netinet/ip_divert.h>

--- 228 unchanged lines hidden (view full) ---

300 */
301static int
302div_output(struct socket *so, struct mbuf *m, struct sockaddr_in *sin,
303 struct mbuf *control)
304{
305 struct m_tag *mtag;
306 struct divert_tag *dt;
307 int error = 0;
65#include <net/route.h>
66
67#include <netinet/in.h>
68#include <netinet/in_pcb.h>
69#include <netinet/in_systm.h>
70#include <netinet/in_var.h>
71#include <netinet/ip.h>
72#include <netinet/ip_divert.h>

--- 228 unchanged lines hidden (view full) ---

301 */
302static int
303div_output(struct socket *so, struct mbuf *m, struct sockaddr_in *sin,
304 struct mbuf *control)
305{
306 struct m_tag *mtag;
307 struct divert_tag *dt;
308 int error = 0;
309 struct mbuf *options;
308
309 /*
310 * An mbuf may hasn't come from userland, but we pretend
311 * that it has.
312 */
313 m->m_pkthdr.rcvif = NULL;
314 m->m_nextpkt = NULL;
315

--- 40 unchanged lines hidden (view full) ---

356 INP_LOCK(inp);
357 /*
358 * Don't allow both user specified and setsockopt options,
359 * and don't allow packet length sizes that will crash
360 */
361 if (((ip->ip_hl != (sizeof (*ip) >> 2)) && inp->inp_options) ||
362 ((u_short)ntohs(ip->ip_len) > m->m_pkthdr.len)) {
363 error = EINVAL;
310
311 /*
312 * An mbuf may hasn't come from userland, but we pretend
313 * that it has.
314 */
315 m->m_pkthdr.rcvif = NULL;
316 m->m_nextpkt = NULL;
317

--- 40 unchanged lines hidden (view full) ---

358 INP_LOCK(inp);
359 /*
360 * Don't allow both user specified and setsockopt options,
361 * and don't allow packet length sizes that will crash
362 */
363 if (((ip->ip_hl != (sizeof (*ip) >> 2)) && inp->inp_options) ||
364 ((u_short)ntohs(ip->ip_len) > m->m_pkthdr.len)) {
365 error = EINVAL;
366 INP_UNLOCK(inp);
367 INP_INFO_WUNLOCK(&divcbinfo);
364 m_freem(m);
365 } else {
366 /* Convert fields to host order for ip_output() */
367 ip->ip_len = ntohs(ip->ip_len);
368 ip->ip_off = ntohs(ip->ip_off);
369
370 /* Send packet to output processing */
371 ipstat.ips_rawout++; /* XXX */
372
373#ifdef MAC
374 mac_create_mbuf_from_inpcb(inp, m);
375#endif
368 m_freem(m);
369 } else {
370 /* Convert fields to host order for ip_output() */
371 ip->ip_len = ntohs(ip->ip_len);
372 ip->ip_off = ntohs(ip->ip_off);
373
374 /* Send packet to output processing */
375 ipstat.ips_rawout++; /* XXX */
376
377#ifdef MAC
378 mac_create_mbuf_from_inpcb(inp, m);
379#endif
376 error = ip_output(m,
377 inp->inp_options, NULL,
378 ((so->so_options & SO_DONTROUTE) ?
379 IP_ROUTETOIF : 0) |
380 IP_ALLOWBROADCAST | IP_RAWOUTPUT,
381 inp->inp_moptions, NULL);
380 /*
381 * Get ready to inject the packet into ip_output().
382 * Just in case socket options were specified on the
383 * divert socket, we duplicate them. This is done
384 * to avoid having to hold the PCB locks over the call
385 * to ip_output(), as doing this results in a number of
386 * lock ordering complexities.
387 *
388 * Note that we set the multicast options argument for
389 * ip_output() to NULL since it should be invariant that
390 * they are not present.
391 */
392 KASSERT(inp->inp_moptions == NULL,
393 ("multicast options set on a divert socket"));
394 options = NULL;
395 /*
396 * XXXCSJP: It is unclear to me whether or not it makes
397 * sense for divert sockets to have options. However,
398 * for now we will duplicate them with the INP locks
399 * held so we can use them in ip_output() without
400 * requring a reference to the pcb.
401 */
402 if (inp->inp_options != NULL) {
403 options = m_dup(inp->inp_options, M_DONTWAIT);
404 if (options == NULL)
405 error = ENOBUFS;
406 }
407 INP_UNLOCK(inp);
408 INP_INFO_WUNLOCK(&divcbinfo);
409 if (error == ENOBUFS) {
410 m_freem(m);
411 return (error);
412 }
413 error = ip_output(m, options, NULL,
414 ((so->so_options & SO_DONTROUTE) ?
415 IP_ROUTETOIF : 0) | IP_ALLOWBROADCAST |
416 IP_RAWOUTPUT, NULL, NULL);
417 if (options != NULL)
418 m_freem(options);
382 }
419 }
383 INP_UNLOCK(inp);
384 INP_INFO_WUNLOCK(&divcbinfo);
385 } else {
386 dt->info |= IP_FW_DIVERT_LOOPBACK_FLAG;
387 if (m->m_pkthdr.rcvif == NULL) {
388 /*
389 * No luck with the name, check by IP address.
390 * Clear the port and the ifname to make sure
391 * there are no distractions for ifa_ifwithaddr.
392 */

--- 8 unchanged lines hidden (view full) ---

401 }
402 m->m_pkthdr.rcvif = ifa->ifa_ifp;
403 }
404#ifdef MAC
405 SOCK_LOCK(so);
406 mac_create_mbuf_from_socket(so, m);
407 SOCK_UNLOCK(so);
408#endif
420 } else {
421 dt->info |= IP_FW_DIVERT_LOOPBACK_FLAG;
422 if (m->m_pkthdr.rcvif == NULL) {
423 /*
424 * No luck with the name, check by IP address.
425 * Clear the port and the ifname to make sure
426 * there are no distractions for ifa_ifwithaddr.
427 */

--- 8 unchanged lines hidden (view full) ---

436 }
437 m->m_pkthdr.rcvif = ifa->ifa_ifp;
438 }
439#ifdef MAC
440 SOCK_LOCK(so);
441 mac_create_mbuf_from_socket(so, m);
442 SOCK_UNLOCK(so);
443#endif
409 /* Send packet to input processing */
410 ip_input(m);
444 /* Send packet to input processing via netisr */
445 netisr_queue(NETISR_IP, m);
411 }
412
413 return error;
414
415cantsend:
416 m_freem(m);
417 return error;
418}

--- 302 unchanged lines hidden ---
446 }
447
448 return error;
449
450cantsend:
451 m_freem(m);
452 return error;
453}

--- 302 unchanged lines hidden ---