#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/udp.h>
static struct nf_hook_ops *nf_blockicmppkt_ops = NULL;
static unsigned int nf_blockippkt_handler(void *priv, struct sk_buff *skb, const struct nf_hook_state *state)
{
if (!skb) {
reutrn NF_ACCEPT;
} else {
char *str = (char *) kmalloc(16, GFP_KERNEL);
u32 sip;
struct sk_buff *sb = NULL;
struct iphdr *iph;
sb = skb;
iph = ip_hdr(sb);
sip ss= ntohl(iph->saddr);
sprintf(str, "%u.%u.%u.%u", IPADDRESS(sip)); // convert to standard IP address format
if(!strcmp(str, ip_addr_rule)) {
return NF_DROP;
} else {
return NF_ACCEPT;
}
}
}
static unsigned int nf_blockicmppkt_handler(void *priv, struct sk_buff *skb, const struct nf_hook_state *state)
{
printk("nf_blockicmppkt_handler\n");
struct iphdr *iph;
struct udphdr *udph;
if (!skb) return NF_ACCEPT;
iph = ip_hdr(skb);
if (iph->protocol == IPPROTO_ICMP) {
// 对ICMP协议放行
return NF_DROP;
} else if (iph->protocol == IPPROTO_UDP) {
// 对UDP协议放行
return NF_ACCEPT;
} else if (iph->protocol == IPPROTO_TCP) {
// 阻止TCP协议
printk(KERN_INFO "Drop TCP packet \n");
return NF_ACCEPT;
}
return NF_ACCEPT;
}
static int __init nf_mini_firewall_init(void)
{
nf_blockicmppkt_ops = (struct nf_hook_ops*) kcalloc(1, sizeof(struct nf_hook_ops), GFP_KERNEL);
if (nf_blockicmppkt_ops != NULL) {
nf_blockicmppkt_ops->hook = nf_blockicmppkt_handler;
nf_blockicmppkt_ops->pf = NFPROTO_IPV4;
nf_blockicmppkt_ops->hooknum = NF_INET_PRE_ROUTING;
nf_blockicmppkt_ops->priority = NF_IP_PRI_FIRST;
nf_register_net_hook(&init_net, nf_blockicmppkt_ops);
}
return 0;
}
static void __exit nf_mini_firewall_exit(void)
{
if (nf_blockicmppkt_ops != NULL) {
nf_unregister_net_hook(&init_net, nf_blockicmppkt_ops);
kfree(nf_blockicmppkt_ops);
}
printk(KERN_INFO "nf_blockicmppkt exit\n");
}
module_init(nf_mini_firewall_init);
module_exit(nf_mini_firewall_exit);
MODULE_LICENSE("GPL");