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

📄 ip_fw.c

📁 基于组件方式开发操作系统的OSKIT源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		f_prt = f->fw_flg & IP_FW_F_KIND;				/* If wildcard, match */		if (f_prt == IP_FW_F_ALL)			goto got_match;		/* If different, dont match */		if (prt != f_prt) 			continue;		/* ICMP, done */		if (prt == IP_FW_F_ICMP) {			if (!icmptype_match(icmp, f))				continue;			goto got_match;		}		/* Check TCP flags and TCP/UDP ports only if packet is not fragment */		if (!(ip->ip_off & IP_OFFMASK)) {			/* TCP, a little more checking */			if (prt == IP_FW_F_TCP &&				(f->fw_tcpf != f->fw_tcpnf) &&				(!tcpflg_match(tcp, f)))				continue;			if (!port_match(&f->fw_pts[0], f->fw_nsp,							src_port, f->fw_flg & IP_FW_F_SRNG))				continue;			if (!port_match(&f->fw_pts[f->fw_nsp], f->fw_ndp,							dst_port, f->fw_flg & IP_FW_F_DRNG)) 				continue;		}got_match:		f->fw_pcnt++;		f->fw_bcnt+=ip->ip_len;		f->timestamp = time.tv_sec;		if (f->fw_flg & IP_FW_F_PRN) {			if (f->fw_flg & IP_FW_F_ACCEPT)				ipfw_report("Allow", f->fw_number, ip, f->fw_pcnt);			else if (f->fw_flg & IP_FW_F_COUNT)				ipfw_report("Count", f->fw_number, ip, f->fw_pcnt);			else				ipfw_report("Deny", f->fw_number, ip, f->fw_pcnt);		}		if (f->fw_flg & IP_FW_F_ACCEPT)			return 1;		if (f->fw_flg & IP_FW_F_COUNT)			continue;		break;	}	/*	 * Don't icmp outgoing packets at all	 */	if (f != NULL && !dir) {		/*		 * Do not ICMP reply to icmp packets....:) or to packets		 * rejected by entry without the special ICMP reply flag.		 */		if ((f_prt != IP_FW_F_ICMP) && (f->fw_flg & IP_FW_F_ICMPRPL)) {			if (f_prt == IP_FW_F_ALL)				icmp_error(m, ICMP_UNREACH, 					ICMP_UNREACH_HOST, 0L, 0);			else				icmp_error(m, ICMP_UNREACH, 					ICMP_UNREACH_PORT, 0L, 0);			return 0;		}	}	m_freem(m);	return 0;}static intadd_entry(chainptr, frwl)	struct ip_fw_head *chainptr;	struct ip_fw *frwl;{	struct ip_fw *ftmp = 0;	struct ip_fw_chain *fwc = 0, *fcp, *fcpl = 0;	u_short nbr = 0;	int s;	fwc = malloc(sizeof *fwc, M_IPFW, M_DONTWAIT);	ftmp = malloc(sizeof *ftmp, M_IPFW, M_DONTWAIT);	if (!fwc || !ftmp) {		dprintf(("ip_fw_ctl:  malloc said no\n"));		if (fwc)  free(fwc, M_IPFW);		if (ftmp) free(ftmp, M_IPFW);		return (ENOSPC);	}	bcopy(frwl, ftmp, sizeof(struct ip_fw));	ftmp->fw_pcnt = 0L;	ftmp->fw_bcnt = 0L;	fwc->rule = ftmp;		s = splnet();	if (!chainptr->lh_first) {		LIST_INSERT_HEAD(chainptr, fwc, chain);		splx(s);		return(0);	} else if (ftmp->fw_number == (u_short)-1) {		if (fwc)  free(fwc, M_IPFW);		if (ftmp) free(ftmp, M_IPFW);		splx(s);		return (EINVAL);	}	/* If entry number is 0, find highest numbered rule and add 100 */	if (ftmp->fw_number == 0) {		for (fcp = chainptr->lh_first; fcp; fcp = fcp->chain.le_next) {			if (fcp->rule->fw_number != (u_short)-1)				nbr = fcp->rule->fw_number;			else				break;		}		if (nbr < (u_short)-1 - 100)			nbr += 100;		ftmp->fw_number = nbr;	}	/* Got a valid number; now insert it, keeping the list ordered */	for (fcp = chainptr->lh_first; fcp; fcp = fcp->chain.le_next) {		if (fcp->rule->fw_number > ftmp->fw_number) {			if (fcpl) {				LIST_INSERT_AFTER(fcpl, fwc, chain);			} else {				LIST_INSERT_HEAD(chainptr, fwc, chain);			}			break;		} else {			fcpl = fcp;		}	}	splx(s);	return (0);}static intdel_entry(chainptr, frwl)	struct ip_fw_head *chainptr;	struct ip_fw *frwl;{	struct ip_fw_chain *fcp;	int s;	s = splnet();	fcp = chainptr->lh_first; 	if (frwl->fw_number != (u_short)-1) {		for (; fcp; fcp = fcp->chain.le_next) {			if (fcp->rule->fw_number == frwl->fw_number) {				LIST_REMOVE(fcp, chain);				splx(s);				free(fcp->rule, M_IPFW);				free(fcp, M_IPFW);				return 0;			}		}	}	splx(s);	return (EINVAL);}static intzero_entry(struct mbuf *m){	struct ip_fw *frwl;	struct ip_fw_chain *fcp;	int s;	if (m) {		frwl = check_ipfw_struct(m);		if (!frwl)			return(EINVAL);	}	else		frwl = NULL;	/*	 *	It's possible to insert multiple chain entries with the	 *	same number, so we don't stop after finding the first	 *	match if zeroing a specific entry.	 */	s = splnet();	for (fcp = ip_fw_chain.lh_first; fcp; fcp = fcp->chain.le_next)		if (!frwl || frwl->fw_number == fcp->rule->fw_number) {			fcp->rule->fw_bcnt = fcp->rule->fw_pcnt = 0;			fcp->rule->timestamp = 0;		}	splx(s);	return(0);}static struct ip_fw *check_ipfw_struct(m)	struct mbuf *m;{	struct ip_fw *frwl;	if (m->m_len != sizeof(struct ip_fw)) {		dprintf(("ip_fw_ctl: len=%d, want %d\n", m->m_len,		    sizeof(struct ip_fw)));		return (NULL);	}	frwl = mtod(m, struct ip_fw *);	if ((frwl->fw_flg & ~IP_FW_F_MASK) != 0) {		dprintf(("ip_fw_ctl: undefined flag bits set (flags=%x)\n",		    frwl->fw_flg));		return (NULL);	}	/* If neither In nor Out, then both */	if (!(frwl->fw_flg & (IP_FW_F_IN | IP_FW_F_OUT)))		frwl->fw_flg |= IP_FW_F_IN | IP_FW_F_OUT;	if ((frwl->fw_flg & IP_FW_F_SRNG) && frwl->fw_nsp < 2) {		dprintf(("ip_fw_ctl: src range set but n_src_p=%d\n",		    frwl->fw_nsp));		return (NULL);	}	if ((frwl->fw_flg & IP_FW_F_DRNG) && frwl->fw_ndp < 2) {		dprintf(("ip_fw_ctl: dst range set but n_dst_p=%d\n",		    frwl->fw_ndp));		return (NULL);	}	if (frwl->fw_nsp + frwl->fw_ndp > IP_FW_MAX_PORTS) {		dprintf(("ip_fw_ctl: too many ports (%d+%d)\n",		    frwl->fw_nsp, frwl->fw_ndp));		return (NULL);	}	return frwl;}intip_fw_ctl(stage, mm)	int stage;	struct mbuf **mm;{	int error;	struct mbuf *m;	if (stage == IP_FW_GET) {		struct ip_fw_chain *fcp = ip_fw_chain.lh_first;		*mm = m = m_get(M_WAIT, MT_SOOPTS);		for (; fcp; fcp = fcp->chain.le_next) {			memcpy(m->m_data, fcp->rule, sizeof *(fcp->rule));			m->m_len = sizeof *(fcp->rule);			m->m_next = m_get(M_WAIT, MT_SOOPTS);			m = m->m_next;			m->m_len = 0;		}		return (0);	}	m = *mm;	/* only allow get calls if secure mode > 2 */	if (securelevel > 2) {		if (m) (void)m_free(m);		return(EPERM);	}	if (stage == IP_FW_FLUSH) {		while (ip_fw_chain.lh_first != NULL && 		    ip_fw_chain.lh_first->rule->fw_number != (u_short)-1) {			struct ip_fw_chain *fcp = ip_fw_chain.lh_first;			int s = splnet();			LIST_REMOVE(ip_fw_chain.lh_first, chain);			splx(s);			free(fcp->rule, M_IPFW);			free(fcp, M_IPFW);		}		if (m) (void)m_free(m);		return (0);	}	if (stage == IP_FW_ZERO) {		error = zero_entry(m);		if (m) (void)m_free(m);		return (error);	}	if (m == NULL) {		printf("ip_fw_ctl:  NULL mbuf ptr\n");		return (EINVAL);	}	if (stage == IP_FW_ADD || stage == IP_FW_DEL) {		struct ip_fw *frwl = check_ipfw_struct(m);		if (!frwl) {			if (m) (void)m_free(m);			return (EINVAL);		}		if (stage == IP_FW_ADD)			error = add_entry(&ip_fw_chain, frwl);		else			error = del_entry(&ip_fw_chain, frwl);		if (m) (void)m_free(m);		return error;	}	dprintf(("ip_fw_ctl:  unknown request %d\n", stage));	if (m) (void)m_free(m);	return (EINVAL);}voidip_fw_init(void){	struct ip_fw deny;	ip_fw_chk_ptr = ip_fw_chk;	ip_fw_ctl_ptr = ip_fw_ctl;	LIST_INIT(&ip_fw_chain);	bzero(&deny, sizeof deny);	deny.fw_flg = IP_FW_F_ALL;	deny.fw_number = (u_short)-1;	add_entry(&ip_fw_chain, &deny);		printf("IP firewall initialized, ");#ifndef IPFIREWALL_VERBOSE	printf("logging disabled\n");#else	if (fw_verbose_limit == 0)		printf("unlimited logging\n");	else		printf("logging limited to %d packets/entry\n", fw_verbose_limit);#endif}#ifdef ACTUALLY_LKM_NOT_KERNEL#include <sys/conf.h>#include <sys/exec.h>#include <sys/sysent.h>#include <sys/lkm.h>static int (*old_chk_ptr)(struct mbuf *, struct ip *, struct ifnet *, int dir);static int (*old_ctl_ptr)(int, struct mbuf **);static intipfw_load(struct lkm_table *lkmtp, int cmd){	int s=splnet();	old_chk_ptr = ip_fw_chk_ptr;	old_ctl_ptr = ip_fw_ctl_ptr;	ip_fw_init();	splx(s);	return 0;}static intipfw_unload(struct lkm_table *lkmtp, int cmd){	int s=splnet();	ip_fw_chk_ptr =  old_chk_ptr;	ip_fw_ctl_ptr =  old_ctl_ptr;	while (ip_fw_chain.lh_first != NULL) {		struct ip_fw_chain *fcp = ip_fw_chain.lh_first;		LIST_REMOVE(ip_fw_chain.lh_first, chain);		free(fcp->rule, M_IPFW);		free(fcp, M_IPFW);	}		splx(s);	printf("IP firewall unloaded\n");	return 0;}MOD_MISC("ipfw_mod")intipfw_mod(struct lkm_table *lkmtp, int cmd, int ver){	DISPATCH(lkmtp, cmd, ver, ipfw_load, ipfw_unload, nosys);}#endif

⌨️ 快捷键说明

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