Deleted Added
full compact
ip_divert.c (136073) ip_divert.c (136714)
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 136073 2004-10-03 00:26:35Z green $
29 * $FreeBSD: head/sys/netinet/ip_divert.c 136714 2004-10-19 21:14:57Z andre $
30 */
31
30 */
31
32#if !defined(KLD_MODULE)
32#include "opt_inet.h"
33#include "opt_inet.h"
33#include "opt_ipfw.h"
34#include "opt_ipdivert.h"
35#include "opt_ipsec.h"
36#include "opt_mac.h"
34#include "opt_mac.h"
37
38#ifndef INET
39#error "IPDIVERT requires INET."
40#endif
35#ifndef INET
36#error "IPDIVERT requires INET."
37#endif
38#endif
41
42#include <sys/param.h>
43#include <sys/kernel.h>
44#include <sys/lock.h>
45#include <sys/malloc.h>
46#include <sys/mac.h>
47#include <sys/mbuf.h>
39
40#include <sys/param.h>
41#include <sys/kernel.h>
42#include <sys/lock.h>
43#include <sys/malloc.h>
44#include <sys/mac.h>
45#include <sys/mbuf.h>
46#include <sys/module.h>
47#include <sys/kernel.h>
48#include <sys/proc.h>
49#include <sys/protosw.h>
50#include <sys/signalvar.h>
51#include <sys/socket.h>
52#include <sys/socketvar.h>
53#include <sys/sx.h>
54#include <sys/sysctl.h>
55#include <sys/systm.h>

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

97 *
98 * On reinjection, processing in ip_input() and ip_output()
99 * will be exactly the same as for the original packet, except that
100 * ipfw processing will start at the rule number after the one
101 * written in the cookie (so, tagging a packet with a cookie of 0
102 * will cause it to be effectively considered as a standard packet).
103 */
104
48#include <sys/proc.h>
49#include <sys/protosw.h>
50#include <sys/signalvar.h>
51#include <sys/socket.h>
52#include <sys/socketvar.h>
53#include <sys/sx.h>
54#include <sys/sysctl.h>
55#include <sys/systm.h>

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

97 *
98 * On reinjection, processing in ip_input() and ip_output()
99 * will be exactly the same as for the original packet, except that
100 * ipfw processing will start at the rule number after the one
101 * written in the cookie (so, tagging a packet with a cookie of 0
102 * will cause it to be effectively considered as a standard packet).
103 */
104
105/* Internal variables */
105/* Internal variables. */
106static struct inpcbhead divcb;
107static struct inpcbinfo divcbinfo;
108
109static u_long div_sendspace = DIVSNDQ; /* XXX sysctl ? */
110static u_long div_recvspace = DIVRCVQ; /* XXX sysctl ? */
111
112/*
113 * Initialize divert connection block queue.

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

142}
143
144/*
145 * Divert a packet by passing it up to the divert socket at port 'port'.
146 *
147 * Setup generic address and protocol structures for div_input routine,
148 * then pass them along with mbuf chain.
149 */
106static struct inpcbhead divcb;
107static struct inpcbinfo divcbinfo;
108
109static u_long div_sendspace = DIVSNDQ; /* XXX sysctl ? */
110static u_long div_recvspace = DIVRCVQ; /* XXX sysctl ? */
111
112/*
113 * Initialize divert connection block queue.

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

142}
143
144/*
145 * Divert a packet by passing it up to the divert socket at port 'port'.
146 *
147 * Setup generic address and protocol structures for div_input routine,
148 * then pass them along with mbuf chain.
149 */
150void
150static void
151divert_packet(struct mbuf *m, int incoming)
152{
153 struct ip *ip;
154 struct inpcb *inp;
155 struct socket *sa;
156 u_int16_t nport;
157 struct sockaddr_in divsrc;
158 struct m_tag *mtag;

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

645 * the pcbinfo for in_setpeeraddr to lock.
646 */
647static int
648div_peeraddr(struct socket *so, struct sockaddr **nam)
649{
650 return (in_setpeeraddr(so, nam, &divcbinfo));
651}
652
151divert_packet(struct mbuf *m, int incoming)
152{
153 struct ip *ip;
154 struct inpcb *inp;
155 struct socket *sa;
156 u_int16_t nport;
157 struct sockaddr_in divsrc;
158 struct m_tag *mtag;

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

645 * the pcbinfo for in_setpeeraddr to lock.
646 */
647static int
648div_peeraddr(struct socket *so, struct sockaddr **nam)
649{
650 return (in_setpeeraddr(so, nam, &divcbinfo));
651}
652
653
654SYSCTL_DECL(_net_inet_divert);
653#ifdef SYSCTL_NODE
654SYSCTL_NODE(_net_inet, IPPROTO_DIVERT, divert, CTLFLAG_RW, 0, "IPDIVERT");
655SYSCTL_PROC(_net_inet_divert, OID_AUTO, pcblist, CTLFLAG_RD, 0, 0,
656 div_pcblist, "S,xinpcb", "List of active divert sockets");
655SYSCTL_PROC(_net_inet_divert, OID_AUTO, pcblist, CTLFLAG_RD, 0, 0,
656 div_pcblist, "S,xinpcb", "List of active divert sockets");
657#endif
657
658struct pr_usrreqs div_usrreqs = {
659 div_abort, pru_accept_notsupp, div_attach, div_bind,
660 pru_connect_notsupp, pru_connect2_notsupp, in_control, div_detach,
661 div_disconnect, pru_listen_notsupp, div_peeraddr, pru_rcvd_notsupp,
662 pru_rcvoob_notsupp, div_send, pru_sense_null, div_shutdown,
663 div_sockaddr, sosend, soreceive, sopoll, in_pcbsosetlabel
664};
658
659struct pr_usrreqs div_usrreqs = {
660 div_abort, pru_accept_notsupp, div_attach, div_bind,
661 pru_connect_notsupp, pru_connect2_notsupp, in_control, div_detach,
662 div_disconnect, pru_listen_notsupp, div_peeraddr, pru_rcvd_notsupp,
663 pru_rcvoob_notsupp, div_send, pru_sense_null, div_shutdown,
664 div_sockaddr, sosend, soreceive, sopoll, in_pcbsosetlabel
665};
666
667struct protosw div_protosw = {
668 SOCK_RAW, NULL, IPPROTO_DIVERT, PR_ATOMIC|PR_ADDR,
669 div_input, NULL, div_ctlinput, ip_ctloutput,
670 NULL,
671 div_init, NULL, NULL, NULL,
672 &div_usrreqs
673};
674
675static int
676div_modevent(module_t mod, int type, void *unused)
677{
678 int err = 0;
679 int n;
680
681 switch (type) {
682 case MOD_LOAD:
683 /*
684 * Protocol will be initialized by pf_proto_register().
685 * We don't have to register ip_protox because we are not
686 * a true IP protocol that goes over the wire.
687 */
688 err = pf_proto_register(PF_INET, &div_protosw);
689 ip_divert_ptr = divert_packet;
690 break;
691 case MOD_UNLOAD:
692 /*
693 * Module ipdivert can only be unloaded if no sockets are
694 * connected. Maybe this can be changed later to forcefully
695 * disconnect any open sockets.
696 */
697 INP_INFO_RLOCK(&divcbinfo);
698 n = divcbinfo.ipi_count;
699 INP_INFO_RUNLOCK(&divcbinfo);
700 if (n != 0) {
701 err = EBUSY;
702 break;
703 }
704 ip_divert_ptr = NULL;
705 err = pf_proto_unregister(PF_INET, IPPROTO_DIVERT, SOCK_RAW);
706 INP_INFO_LOCK_DESTROY(&divcbinfo);
707 break;
708 default:
709 return EINVAL;
710 break;
711 }
712 return err;
713}
714
715static moduledata_t ipdivertmod = {
716 "ipdivert",
717 div_modevent,
718 0
719};
720
721DECLARE_MODULE(ipdivert, ipdivertmod, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY);
722MODULE_DEPEND(dummynet, ipfw, 2, 2, 2);
723MODULE_VERSION(ipdivert, 1);