📄 ipfwadm_core.c
字号:
if ( (frwl->fw_flg & IP_FW_F_DRNG) && frwl->fw_ndp < 2 ) {#ifdef DEBUG_IP_FIREWALL printk("ip_fw_ctl: dst range set but fw_ndp=%d\n", frwl->fw_ndp);#endif return(NULL); } if ( frwl->fw_nsp + frwl->fw_ndp > (frwl->fw_flg & IP_FW_F_REDIR ? IP_FW_MAX_PORTS - 1 : IP_FW_MAX_PORTS) ) {#ifdef DEBUG_IP_FIREWALL printk("ip_fw_ctl: too many ports (%d+%d)\n", frwl->fw_nsp,frwl->fw_ndp);#endif return(NULL); } return frwl;}#ifdef CONFIG_IP_ACCTint ip_acct_ctl(int stage, void *m, int len){ if ( stage == IP_ACCT_FLUSH ) { free_fw_chain(&ip_acct_chain); return(0); } if ( stage == IP_ACCT_ZERO ) { zero_fw_chain(ip_acct_chain); return(0); } if ( stage == IP_ACCT_INSERT || stage == IP_ACCT_APPEND || stage == IP_ACCT_DELETE ) { struct ip_fw *frwl; if (!(frwl=check_ipfw_struct(m,len))) return (EINVAL); switch (stage) { case IP_ACCT_INSERT: return( insert_in_chain(&ip_acct_chain,frwl,len)); case IP_ACCT_APPEND: return( append_to_chain(&ip_acct_chain,frwl,len)); case IP_ACCT_DELETE: return( del_from_chain(&ip_acct_chain,frwl)); default: /* * Should be panic but... (Why ??? - AC) */#ifdef DEBUG_IP_FIREWALL printk("ip_acct_ctl: unknown request %d\n",stage);#endif return(EINVAL); } }#ifdef DEBUG_IP_FIREWALL printk("ip_acct_ctl: unknown request %d\n",stage);#endif return(EINVAL);}#endif#ifdef CONFIG_IP_FIREWALLint ip_fw_ctl(int stage, void *m, int len){ int cmd, fwtype; cmd = stage & IP_FW_COMMAND; fwtype = (stage & IP_FW_TYPE) >> IP_FW_SHIFT; if ( cmd == IP_FW_FLUSH ) { free_fw_chain(chains[fwtype]); return(0); } if ( cmd == IP_FW_ZERO ) { zero_fw_chain(*chains[fwtype]); return(0); } if ( cmd == IP_FW_POLICY ) { int *tmp_policy_ptr; tmp_policy_ptr=(int *)m; *policies[fwtype] = *tmp_policy_ptr; return 0; } if ( cmd == IP_FW_CHECK ) { struct net_device *viadev; struct ip_fwpkt *ipfwp; struct iphdr *ip; if ( len != sizeof(struct ip_fwpkt) ) {#ifdef DEBUG_IP_FIREWALL printk("ip_fw_ctl: length=%d, expected %d\n", len, sizeof(struct ip_fwpkt));#endif return( EINVAL ); } ipfwp = (struct ip_fwpkt *)m; ip = &(ipfwp->fwp_iph); if ( !(viadev = dev_get_by_name(ipfwp->fwp_vianame)) ) {#ifdef DEBUG_IP_FIREWALL printk("ip_fw_ctl: invalid device \"%s\"\n", ipfwp->fwp_vianame);#endif return(EINVAL); } else if ( ip->ihl != sizeof(struct iphdr) / sizeof(int)) {#ifdef DEBUG_IP_FIREWALL printk("ip_fw_ctl: ip->ihl=%d, want %d\n",ip->ihl, sizeof(struct iphdr)/sizeof(int));#endif return(EINVAL); } switch (ip_fw_chk(ip, viadev, NULL, *chains[fwtype], *policies[fwtype], IP_FW_MODE_CHK)) { case FW_ACCEPT: return(0); case FW_REDIRECT: return(ECONNABORTED); case FW_MASQUERADE: return(ECONNRESET); case FW_REJECT: return(ECONNREFUSED); default: /* FW_BLOCK */ return(ETIMEDOUT); } } if ( cmd == IP_FW_MASQ_TIMEOUTS ) return ip_fw_masq_timeouts(m, len);/* * Here we really working hard-adding new elements * to blocking/forwarding chains or deleting 'em */ if ( cmd == IP_FW_INSERT || cmd == IP_FW_APPEND || cmd == IP_FW_DELETE ) { struct ip_fw *frwl; int fwtype; frwl=check_ipfw_struct(m,len); if (frwl==NULL) return (EINVAL); fwtype = (stage & IP_FW_TYPE) >> IP_FW_SHIFT; switch (cmd) { case IP_FW_INSERT: return(insert_in_chain(chains[fwtype],frwl,len)); case IP_FW_APPEND: return(append_to_chain(chains[fwtype],frwl,len)); case IP_FW_DELETE: return(del_from_chain(chains[fwtype],frwl)); default: /* * Should be panic but... (Why are BSD people panic obsessed ??) */#ifdef DEBUG_IP_FIREWALL printk("ip_fw_ctl: unknown request %d\n",stage);#endif return(EINVAL); } }#ifdef DEBUG_IP_FIREWALL printk("ip_fw_ctl: unknown request %d\n",stage);#endif return(ENOPROTOOPT);}#endif /* CONFIG_IP_FIREWALL */#if defined(CONFIG_IP_FIREWALL) || defined(CONFIG_IP_ACCT)static int ip_chain_procinfo(int stage, char *buffer, char **start, off_t offset, int length){ off_t pos=0, begin=0; struct ip_fw *i; unsigned long flags; int len, p; int last_len = 0; switch(stage) {#ifdef CONFIG_IP_FIREWALL case IP_FW_IN: i = ip_fw_in_chain; len=sprintf(buffer, "IP firewall input rules, default %d\n", ip_fw_in_policy); break; case IP_FW_OUT: i = ip_fw_out_chain; len=sprintf(buffer, "IP firewall output rules, default %d\n", ip_fw_out_policy); break; case IP_FW_FWD: i = ip_fw_fwd_chain; len=sprintf(buffer, "IP firewall forward rules, default %d\n", ip_fw_fwd_policy); break;#endif#ifdef CONFIG_IP_ACCT case IP_FW_ACCT: i = ip_acct_chain; len=sprintf(buffer,"IP accounting rules\n"); break;#endif default: /* this should never be reached, but safety first... */ i = NULL; len=0; break; } save_flags(flags); cli(); while(i!=NULL) { len+=sprintf(buffer+len,"%08X/%08X->%08X/%08X %.16s %08X %X ", ntohl(i->fw_src.s_addr),ntohl(i->fw_smsk.s_addr), ntohl(i->fw_dst.s_addr),ntohl(i->fw_dmsk.s_addr), (i->fw_vianame)[0] ? i->fw_vianame : "-", ntohl(i->fw_via.s_addr), i->fw_flg); /* 10 is enough for a 32 bit box but the counters are 64bit on the Alpha and Ultrapenguin */ len+=sprintf(buffer+len,"%u %u %-20lu %-20lu", i->fw_nsp,i->fw_ndp, i->fw_pcnt,i->fw_bcnt); for (p = 0; p < IP_FW_MAX_PORTS; p++) len+=sprintf(buffer+len, " %u", i->fw_pts[p]); len+=sprintf(buffer+len, " A%02X X%02X", i->fw_tosand, i->fw_tosxor); buffer[len++]='\n'; buffer[len]='\0'; pos=begin+len; if(pos<offset) { len=0; begin=pos; } else if(pos>offset+length) { len = last_len; break; } last_len = len; i=i->fw_next; } restore_flags(flags); *start=buffer+(offset-begin); len-=(offset-begin); if(len>length) len=length; return len;}#endif#ifdef CONFIG_IP_ACCTstatic int ip_acct_procinfo(char *buffer, char **start, off_t offset, int length){ return ip_chain_procinfo(IP_FW_ACCT, buffer,start, offset,length);}#endif#ifdef CONFIG_IP_FIREWALLstatic int ip_fw_in_procinfo(char *buffer, char **start, off_t offset, int length){ return ip_chain_procinfo(IP_FW_IN, buffer,start,offset,length);}static int ip_fw_out_procinfo(char *buffer, char **start, off_t offset, int length){ return ip_chain_procinfo(IP_FW_OUT, buffer,start,offset,length);}static int ip_fw_fwd_procinfo(char *buffer, char **start, off_t offset, int length){ return ip_chain_procinfo(IP_FW_FWD, buffer,start,offset,length);}#endif#ifdef CONFIG_IP_FIREWALL/* * Interface to the generic firewall chains. */int ipfw_input_check(struct firewall_ops *this, int pf, struct net_device *dev, void *phdr, void *arg, struct sk_buff **pskb){ return ip_fw_chk(phdr, dev, arg, ip_fw_in_chain, ip_fw_in_policy, IP_FW_MODE_FW);}int ipfw_output_check(struct firewall_ops *this, int pf, struct net_device *dev, void *phdr, void *arg, struct sk_buff **pskb){ return ip_fw_chk(phdr, dev, arg, ip_fw_out_chain, ip_fw_out_policy, IP_FW_MODE_FW);}int ipfw_forward_check(struct firewall_ops *this, int pf, struct net_device *dev, void *phdr, void *arg, struct sk_buff **pskb){ return ip_fw_chk(phdr, dev, arg, ip_fw_fwd_chain, ip_fw_fwd_policy, IP_FW_MODE_FW);}#ifdef CONFIG_IP_ACCTint ipfw_acct_in(struct firewall_ops *this, int pf, struct net_device *dev, void *phdr, void *arg, struct sk_buff **pskb){ return ip_fw_chk(phdr,dev,NULL,ip_acct_chain,0,IP_FW_MODE_ACCT_IN);}int ipfw_acct_out(struct firewall_ops *this, int pf, struct net_device *dev, void *phdr, void *arg, struct sk_buff **pskb){ return ip_fw_chk(phdr,dev,NULL,ip_acct_chain,0,IP_FW_MODE_ACCT_OUT);}#endifstruct firewall_ops ipfw_ops={ NULL, ipfw_forward_check, ipfw_input_check, ipfw_output_check,#ifdef CONFIG_IP_ACCT ipfw_acct_in, ipfw_acct_out#else NULL, NULL#endif};#endif#if defined(CONFIG_IP_ACCT) || defined(CONFIG_IP_FIREWALL)int ipfw_device_event(struct notifier_block *this, unsigned long event, void *ptr){ struct net_device *dev=ptr; char *devname = dev->name; unsigned long flags; struct ip_fw *fw; int chn; save_flags(flags); cli(); if (event == NETDEV_UP) { for (chn = 0; chn < IP_FW_CHAINS; chn++) for (fw = *chains[chn]; fw; fw = fw->fw_next) if ((fw->fw_vianame)[0] && !strncmp(devname, fw->fw_vianame, IFNAMSIZ)) fw->fw_viadev = dev; } else if (event == NETDEV_DOWN) { for (chn = 0; chn < IP_FW_CHAINS; chn++) for (fw = *chains[chn]; fw; fw = fw->fw_next) /* we could compare just the pointers ... */ if ((fw->fw_vianame)[0] && !strncmp(devname, fw->fw_vianame, IFNAMSIZ)) fw->fw_viadev = (struct net_device*)-1; } restore_flags(flags); return NOTIFY_DONE;}static struct notifier_block ipfw_dev_notifier={ ipfw_device_event, NULL, 0};#endifint ipfw_init_or_cleanup(int init){ int ret = 0; if (!init) goto cleanup; ret = register_firewall(PF_INET, &ipfw_ops); if (ret < 0) goto cleanup_nothing;#ifdef CONFIG_IP_ACCT proc_net_create("ip_acct", S_IFREG | S_IRUGO | S_IWUSR, ip_acct_procinfo);#endif proc_net_create("ip_input", S_IFREG | S_IRUGO | S_IWUSR, ip_fw_in_procinfo); proc_net_create("ip_output", S_IFREG | S_IRUGO | S_IWUSR, ip_fw_out_procinfo); proc_net_create("ip_forward", S_IFREG | S_IRUGO | S_IWUSR, ip_fw_fwd_procinfo); /* Register for device up/down reports */ register_netdevice_notifier(&ipfw_dev_notifier);#ifdef CONFIG_IP_FIREWALL_NETLINK ipfwsk = netlink_kernel_create(NETLINK_FIREWALL, NULL);#endif return ret; cleanup:#ifdef CONFIG_IP_FIREWALL_NETLINK sock_release(ipfwsk->socket);#endif unregister_netdevice_notifier(&ipfw_dev_notifier);#ifdef CONFIG_IP_ACCT proc_net_remove("ip_acct");#endif proc_net_remove("ip_input"); proc_net_remove("ip_output"); proc_net_remove("ip_forward"); free_fw_chain(chains[IP_FW_FWD]); free_fw_chain(chains[IP_FW_IN]); free_fw_chain(chains[IP_FW_OUT]); free_fw_chain(chains[IP_FW_ACCT]); unregister_firewall(PF_INET, &ipfw_ops); cleanup_nothing: return ret;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -