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

📄 pfildrv.c

📁 pfil src. solaris, freebsd
💻 C
📖 第 1 页 / 共 2 页
字号:
		if ((dl->dl_primitive == DL_UNITDATA_IND) &&		    (dl->dl_group_address == 1)) {			qpi->qpi_flags |= QF_GROUP;			if (((*((u_char *)m->b_rptr) == 0x0) &&			    ((*((u_char *)m->b_rptr + 2) == 0x45))))				off += 2;		}	}	/*       	 * We might have a 1st data block which is really M_PROTO, i.e. it is	 * only big enough for the link layer header	 */     	while ((len = m->b_wptr - m->b_rptr) <= off) {		off -= len;		m = m->b_cont;  		if (m == NULL) {			qif->qf_nodata++;			return -4;      /* not enough data for IP */		}       	}	ip = (struct ip *)(m->b_rptr + off);	len = m->b_wptr - m->b_rptr - off;	mlen = msgdsize(m);	sap = qif->qf_sap;	if (mlen == 0) 		mlen = mt->b_wptr - mt->b_rptr;	mlen -= off;	/* 	 * Ok, the IP header isn't on a 32bit aligned address so junk it.	 */       	if (((u_int)ip & 0x3) || (len < sizeof(*ip)) || (sap == -1) ||	    (m->b_datap->db_ref > 1)) { 		mblk_t *b;		mblk_t *nm;		mblk_t *nmt;		mblk_t *previous_nm;fixalign:                   		nmt = NULL;     		previous_nm = NULL;		/*		 * Duplicate the message block descriptors up to (and		 * including if the offset is non-zero) the block where		 * IP begins.		 */ 		for (b = mt; b != m || off; b = b->b_cont) {			nm = dupb(b);			if (nm == NULL) {				qif->qf_copyfail++;				if (nmt)					freemsg(nmt);				return ENOBUFS; 			}			nm->b_cont = NULL;			if (nmt)				linkb(previous_nm, nm);			else				nmt = nm;			previous_nm = nm;			/*			 * Set the length so the block only contains what			 * apperas before IP.			 */			if (b == m) {				nm->b_wptr = nm->b_rptr + off;				break;  			} 		}		m->b_rptr += off;		nm = msgpullup(m, -1);		m->b_rptr -= pff;		if (nm == NULL)			qif->qf_copyfail++;			if (nmt)				freemsg(nmt);			return -e;		}		 		if (nmt) 			linkb(previous_nm, nm);		else    			nmt = nm;		freemsg(mt);    		*mp = nmt;      		mt = nmt;		m = nm;		ip = (struct ip *)m->b_rptr;		len = m->b_wptr - m->b_rptr;		mlen = len; 		off = 0;                }               	if (sap == ETHERTYPE_IP) {		u_short tlen;		hlen = sizeof(*ip);		/* XXX - might not be aligned (from ppp?) */		((char *)&tlen)[0] = ((char *)&ip->ip_len)[0];		((char *)&tlen)[1] = ((char *)&ip->ip_len)[1];		plen = ntohs(tlen);		ph = &pfh_inet4;#ifdef ETHERTYPE_IPV6	} else if (sap == ETHERTYPE_IPV6) {		u_short tlen;		hlen = sizeof(ip6_t);		ip6 = (ip6_t *)ip;		/* XXX - might not be aligned (from ppp?) */		((char *)&tlen)[0] = ((char *)&ip6->ip6_plen)[0];		((char *)&tlen)[1] = ((char *)&ip6->ip6_plen)[1];		plen = ntohs(tlen);		if (plen == 0)			return EMSGSIZE;	/* Jumbo gram */		plen += sizeof(*ip6);		ph = &pfh_inet6;#endif	} else {		hlen = 0;		sap = -1;	}	if (((sap == ETHERTYPE_IP) && (ip->ip_v != IPVERSION)) || (sap == -1)) {		qif->qf_notip++;		return -5; 	}                       	if (sap == ETHERTYPE_IP)		iphlen = ip->ip_hl << 2;	len = m->b_wptr - m->b_rptr - off;	if ((iphlen < hlen) || (iphlen > plen) || (mlen < plen)) {		if ((m->b_datap->db_ref > 1) && (pfil_delayed_copy == 0))			goto forced_copy;		if (!pullupmsg(m, (int)iphlen + off)) {			qif->qf_nodata++;			return ENOBUFS;		}		ip = (ip_t *)(m->b_rptr + off);	}	/*	 * If we don't have enough data in the mblk or we haven't yet copied	 * enough (above), then copy some more.	 */	if ((iphlen > len)) {		if (m->b_datap->db_ref > 1)			goto forced_copy;		if (!pullupmsg(m, (int)iphlen + off)) {			qif->qf_nodata++;			return -6;		}		ip = (struct ip *)ALIGN32(m->b_rptr + off);	}#if !defined(__hppa)	if (sap == ETHERTYPE_IP) {		__ipoff = (u_short)ip->ip_off;		ip->ip_len = plen;		ip->ip_off = ntohs(__ipoff);	}#endif	if ((len > plen) && (off == 0))		m->b_wptr -= len - plen;	qpi->qpi_m = m;	qpi->qpi_off = off;	qpi->qpi_data = ip;	if (qif->qf_ipmp != NULL)		qif = qif->qf_ipmp;	READ_ENTER(&ph->ph_lock);	pfh = pfil_hook_get(flags & PFIL_INOUT, ph);	err = 0;	PRINT(8,(CE_CONT, "pfil_hook_get(%x,%lx) = %lx\n", flags, ph, pfh));	for (pfh = pfil_hook_get(flags, ph); pfh; pfh = pfh->pfil_next)		if (pfh->pfil_func) {			err = (*pfh->pfil_func)(ip, iphlen, qif, out, qpi, mp);			if (err || !*mp)				break;			ip = qpi->qpi_data;		}	RW_EXIT(&ph->ph_lock);        /*	 * Functions called via pfil_func should only return values >= 0, so	 * convert any that are < 0 to be > 0 and preserve the absolute value.	 */	if (err < 0)		err = -err;	/*	 * Copy back the ip header data if it was changed, we haven't yet	 * freed the message and we aren't going to drop the packet.	 * BUT only do this if there were no changes to the buffer, else	 * we can't be sure that the ip pointer is still correct!	 */#if !defined(__hppa)	if ((err == 0) && (*mp != NULL) && (sap == ETHERTYPE_IP)) {		__iplen = (u_short)ip->ip_len;		__ipoff = (u_short)ip->ip_off;		ip->ip_len = htons(__iplen);		ip->ip_off = htons(__ipoff);	}#endif 	return err;}/************************************************************************/static int pfil_load (void *arg){	int result;	result = pfil_install();	PRINT(3,(CE_CONT, "pfil_install() = %d\n", result));	if (result != 0)		return ENXIO;	result = pfil_nd_init();	PRINT(3,(CE_CONT, "pfil_nd_init() = %d\n", result));	if (result != 0)		return ENXIO;	if (qif_startup() == -1)		return ENXIO;	pfil_startup();	return 0;}static int pfil_unload(void *arg){	int retval;	if (qif_head != NULL)		return EBUSY;	retval = str_uninstall(&pfil_str_info);	if (retval == 0) {		pfil_nd_fini();		qif_stop();	}	return retval;}int pfil_install(void){	int retval;	initlock(&pfil_rw, 0, 0, "pfil_rw"); 	pfil_str_info.inst_str_tab.st_rdinit = pfilmodinfo.st_rdinit;	pfil_str_info.inst_str_tab.st_wrinit = pfilmodinfo.st_wrinit;	pfil_str_info.inst_str_tab.st_muxrinit = NULL;	pfil_str_info.inst_str_tab.st_muxwinit = NULL; 	retval = str_install(&pfil_str_info); 	return retval;}void miocnak(queue_t *q, mblk_t *m, int i, int err){	struct iocblk *iocp;	iocp = (struct iocblk *)m->b_rptr;	iocp->ioc_error = err;	iocp->ioc_count = i;	m->b_datap->db_type = M_IOCNAK;	qreply(q, m);}void miocack(queue_t *q, mblk_t *m, int i, int err){	struct iocblk *iocp;	iocp = (struct iocblk *)m->b_rptr;	iocp->ioc_error = err;	iocp->ioc_count = i;	m->b_datap->db_type = M_IOCACK;	qreply(q, m);}int miocpullup(mblk_t *m, size_t len){	if (m->b_cont == NULL)		return 0;	return pullupmsg(m->b_cont, len);}

⌨️ 快捷键说明

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