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); |
|