⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pfildrv.c

📁 pfil src. solaris, freebsd
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 2003 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */struct uio;#include <sys/conf.h>#include <sys/stream.h>#include <sys/errno.h>#include <sys/socket.h>#include <sys/stat.h>#include <sys/cmn_err.h>#include <sys/dlpi.h>#include <sys/io.h>#include <sys/moddefs.h>#include <net/if.h>#include <netinet/if_ether.h>#include <net/mtcp.h>#include <netinet/in_systm.h>#include <netinet/in.h>#undef IPOPT_EOL#undef IPOPT_NOP#undef IPOPT_RR#undef IPOPT_LSRR#undef IPOPT_SSRR#include <netinet/ip.h>#ifdef ETHERTYPE_IPV6# include <netinet/ip6.h>#endif#include <netinet/tcp.h>#include <netinet/udp.h>#include <netinet/ip_icmp.h>#include "compat.h"#include "qif.h"#include "pfil.h"#undef	USE_SERVICE_ROUTINE#define MINSDUSZ 1#define MAXSDUSZ INFPSZkrwlock_t	pfil_rw;/****************************************************************************//* pfil Streams Module Definition */#define PFIL_NAME   "pfil"static int pfilmodopen(queue_t *q, dev_t *devp, int flag, int sflag,			  cred_t *crp);static int pfilmodclose(queue_t *q, int flag, cred_t *crp);static struct module_info pfil_info =	{ 5051, "pfil driver module "/**/PFIL_RELEASE, 0, 65535, 65536, 1};static struct qinit pfilmod_rinit = {	(pfi_t)pfilmodrput, NULL, pfilmodopen, pfilmodclose,	NULL, &pfil_info, NULL};static struct qinit pfilmod_winit = {	(pfi_t)pfilmodwput, NULL, NULL, NULL, NULL, &pfil_info, NULL};struct streamtab pfilmodinfo = {	&pfilmod_rinit, &pfilmod_winit, NULL, NULL};static streams_info_t pfil_str_info = {	PFIL_NAME,				/* name */	-1,				/* major number */	{ NULL, NULL, NULL, NULL },	/* streamtab */	STR_IS_MODULE | MGR_IS_MP |	/* streams flags */	STR_SYSV4_OPEN | STR_MP_OPEN_CLOSE,	SQLVL_QUEUE,			/* sync level */	"",				/* elsewhere sync name */};/* End of pfil Streams Module initialization *//**********************************************************************//* DLKM specific structures for the pfil Streams Module */extern	struct	mod_operations	str_mod_ops;extern	struct	mod_conf_data	pfil_conf_data;static int pfil_load __P((void *));static int pfil_unload __P((void *));static struct mod_type_data     pfil_drv_link = {	"pfilm STREAMS module "/**/PFIL_RELEASE, &pfil_str_info };static  struct  modlink pfil_mod_link[] = {	{ &str_mod_ops, (void *)&pfil_drv_link },	{ NULL, (void *)NULL }};struct  modwrapper      pfil_wrapper = {	MODREV,	pfil_load,	pfil_unload,	(void (*)())NULL,	(void *)&pfil_conf_data,	(struct modlink*)&pfil_mod_link};/************************************************************************ * STREAMS module functions *//* ------------------------------------------------------------------------ *//* Function:    pfilmodopen                                                 *//* Returns:     int      - 0 == success, else error                         *//* Parameters:  q(I)     - pointer to read-side STREAMS queue               *//*              devp(I)  - pointer to a device number                       *//*              oflag(I) - file status open flags (always 0 for module open)*//*              sflag(I) - flag indicating how the open is being made       *//*              crp(I)   - pointer to message credentials from the user     *//*                                                                          *//* open() entry hook for the STREAMS module.                                *//* ------------------------------------------------------------------------ */static int pfilmodopen(queue_t *q, dev_t *devp, int flag, int sflag,			cred_t *crp){	PRINT(3,(CE_CONT, "pfilmodopen(%lx,%lx,%x,%x,%lx) [%s]\n",	      q, devp, flag, sflag, crp, QTONM(q)));	if (sflag != MODOPEN)		return ENXIO;	q->q_ptr = qif_new(q, KM_SLEEP);	WR(q)->q_ptr = q->q_ptr;	qprocson(q);	return 0;}/* ------------------------------------------------------------------------ *//* Function:    pfilmodclose                                                *//* Returns:     int     - always returns 0.                                 *//* Parameters:  q(I)    - pointer to read-side STREAMS queue                *//*              flag(I) - file status flag                                  *//*              crp(I)  - pointer to message credentials from the user      *//*                                                                          *//* close() entry hook for the STREAMS module. qif_delete() takes care of    *//* setting q_ptr back to NULL for both this and the write side queue.       *//* ------------------------------------------------------------------------ */static int pfilmodclose(queue_t *q, int flag, cred_t *crp){	PRINT(3,(CE_CONT, "pfilmodclose(%lx,%x,%lx) [%s]\n",	      q, flag, crp, QTONM(q)));	qprocsoff(q);	qif_delete(q->q_ptr, q);	return 0;}/* ------------------------------------------------------------------------ *//* Function:    pfil_precheck                                               *//* Returns:     int - < 0 pass packet because it's not a type subject to    *//*                    firewall rules (i.e. internal STREAMS messages),      *//*                    0 == pass packet, else > 0 indicates passing          *//*                    prohibited (possibly due to an error occuring in      *//*                    this function.)                                       *//* Parameters:  q(I)   - pointer to STREAMS queue                           *//*              mp(I)  - pointer to STREAMS message                         *//*              qif(I) - pointer to per-queue interface information         *//* Locks:       pfil_rw                                                     *//*                                                                          *//* In here we attempt to determine if there is an IP packet within an mblk  *//* that is being passed along and if there is, ensure that it falls on a 32 *//* bit aligned address and at least all of the layer 3 header is in one     *//* buffer, preferably all the layer 4 too if we recognise it.  Finally, if  *//* we can be sure that the buffer passes some sanity checks, pass it on to  *//* the registered callbacks for the particular protocol/direction.          *//* ------------------------------------------------------------------------ */int pfil_precheck(queue_t *q, mblk_t **mp, int flags, qif_t *qif){	register struct ip *ip;#ifdef ETHERTYPE_IPV6	register ip6_t *ip6;#endif	size_t hlen, len, off, mlen, iphlen, plen, p;	int err, out, sap, realigned = 0;	packet_filter_hook_t *pfh;	qpktinfo_t qpkt, *qpi;	struct pfil_head *ph;	mblk_t *m, *mt = *mp;	struct tcphdr *tcp;	u_char *bp, *s;	int cko = 0;	mblk_t *mi = *mp;	qpi = &qpkt;	qpi->qpi_q = q;	qpi->qpi_off = 0;	qpi->qpi_name = qif->qf_name;	qpi->qpi_real = qif;	qpi->qpi_ill = qif->qf_ill;	qpi->qpi_hl = qif->qf_hl;	qpi->qpi_ppa = qif->qf_ppa;	qpi->qpi_num = qif->qf_num;	qpi->qpi_flags = qif->qf_flags;	qpi->qpi_max_frag = qif->qf_max_frag;	if ((flags & PFIL_GROUP) != 0)		qpi->qpi_flags |= QF_GROUP;	/*	 * If there is only M_DATA for a packet going out, then any header	 * information (which would otherwise appear in an M_PROTO mblk before	 * the M_DATA) is prepended before the IP header.  We need to set the	 * offset to account for this. - see MMM	 */	out = (flags & PFIL_OUT) ? 1 : 0;	cko = (mt->b_flag & MSGCKO);	if (out != 0) {		/*		 * If outbound, set offset to qif->qf_hl as it will include		 * the cko length if cko is present.		 */		off = qpi->qpi_hl;	} else {		/*		 * unlike before,in the IN path,  we need to set the offset		 * as there maybe cko information we need to take care of.		 * If inbound, then the offset is:		 *      0 in nonfastpath/no cko		 *      8 in cko		 */		if (cko)			off = 8;		else			off = 0;	}tryagain:	ip = NULL;	m = NULL;	cko = (mt->b_flag & MSGCKO);	PRINT(9,(CE_CONT, "pfil_precheck(%lx,%lx,%x,%lx) sz %d %d hl %d\n",		 q, mp, flags, qif,		mt->b_wptr - mt->b_rptr, msgdsize(mt), qif->qf_hl));	/*	 * If the message protocol block indicates that there isn't a data	 * block following it, just return back.	 */	bp = (u_char *)ALIGN32(mt->b_rptr);	switch (MTYPE(mt))	{	case M_PROTO :	case M_PCPROTO :	    {		dl_unitdata_ind_t *dl = (dl_unitdata_ind_t *)bp;		if ((dl->dl_primitive != DL_UNITDATA_IND) &&		    (dl->dl_primitive != DL_UNITDATA_REQ)) {			ip = (struct ip *)dl;			if ((ip->ip_v == IPVERSION) &&			    (ip->ip_hl == (sizeof(*ip) >> 2)) &&			    (ntohs(ip->ip_len) == mt->b_wptr - mt->b_rptr)) {				off = 0;				m = mt;			} else {				qif->qf_notdata++;				return -1;			}		} else {			m = mt->b_cont;			if (m == NULL) {				qif->qf_notdata++;				return -3;	/* No data blocks */			}		}		break;	    }	case M_DATA :		m = mt;		break;	default :		qif->qf_notdata++;		return -2;	}	/*	 * Find the first data block, count the data blocks in this chain and	 * the total amount of data.	 */	if (ip == NULL)		for (m = mt; m && (MTYPE(m) != M_DATA); m = m->b_cont)			off = 0;	/* Any non-M_DATA cancels the offset */	if (m == NULL) {		qif->qf_nodata++;		return -3;	/* No data blocks */	}	/*	 * This is a complete kludge to try and work around some bizarre	 * packets which drop through into fr_donotip.	 */	if ((mt != m) && (MTYPE(mt) == M_PROTO || MTYPE(mt) == M_PCPROTO)) {		dl_unitdata_ind_t *dl = (dl_unitdata_ind_t *)bp;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -