- 论坛徽章:
- 0
|
本人想写一个关于Netfilter 的内核模块,这个模块主要用来检查所以进入本机的数据包,如果是发给本机的(192.68.4.103)tcp包,就修改包头的源IP地址为100.100.100.100 然后通过。小弟初学内核编程,一个人鼓捣了好久。对源文件编译通过后无法正常加载该模块。每次一加载,键盘后两个灯就会不停闪烁,电脑死机,没有任何反映(屏幕不变黑)。
本人使用的是ubuntu 16.04 操作系统。
下面是本人写的模块文件。
跪求各位大神给予小弟指点迷津。
- #include <linux/init.h>
- #include <linux/module.h>
- #include <linux/netfilter.h>
- #include <linux/netfilter_ipv4.h>
- #include<linux/inet.h>
- #include<net/ip.h>
- #include<net/tcp.h>
- #include <linux/netdevice.h>
- #include <linux/inet.h>
- #include <linux/socket.h>
- #include <linux/skbuff.h>
- MODULE_LICENSE("GPL");
- MODULE_AUTHOR("LINHOS");
- #define IF_NAME "eno1" //本机网卡名称
- struct nf_hook_ops nfho;
- static unsigned int checkIP(
- unsigned int hooknum, //钩子点
- struct sk_buff *__skb,
- const struct net_device *in,
- const struct net_device *out,
- int(*okfn)(struct sk_buff *)//?
- ) {
- struct sk_buff *skb; //数据包
- struct net_device *dev; // 驱动设备
- //struct ethhdr *eth_out; //输出接口 在修改mac地址的时候启用
- struct iphdr *iph; //ip头
- struct tcphdr *tcph; //tcp头
- int tot_len; //总长度
- unsigned int iph_len; //ip头长度
- int tcph_len; //tcp头长度
- int ret;
- skb = __skb;
- if (skb == NULL)
- return NF_ACCEPT;
- iph = ip_hdr(skb); //获得ip头
- if (iph == NULL)
- return NF_ACCEPT;
- tot_len = ntohs(iph->tot_len);
- if (iph->daddr =="192.68.4.103") { //本机ip地址
- iph_len = ip_hdrlen(skb);//获取ip首部长度
- skb_pull(skb, iph_len);//指针跳转ip头长度
- skb_reset_transport_header(skb);//重置IP头?
- if (iph->protocol ==IPPROTO_TCP) {// 判断协议类型(TCP)
- tcph = tcp_hdr(skb);
- tcph_len = tcp_hdrlen(skb);
- iph->saddr = in_aton("100.100.100.100"); //修改源IP地址
- dev = dev_get_by_name(&init_net, IF_NAME); //获取驱动
- tcph->check = 0; //校验码置0
- skb->csum = csum_partial((unsigned char *) tcph,
- tot_len - iph_len,
- 0);
- //重置校验和
- tcph->check = csum_tcpudp_magic(iph->saddr,
- iph->daddr,
- ntohs(iph->tot_len) - iph_len,
- iph->protocol,
- skb->csum);
- //tcp校验
- iph->check = 0;
- iph->check = ip_fast_csum(iph, iph->ihl);
- //ip头校验,需要先置0
- skb->ip_summed = CHECKSUM_NONE; //设定不需要进行硬件校验
- skb->pkt_type = PACKET_HOST;
- skb->dev = dev;
- skb_push(skb, iph_len); //退入第三层
- skb_push(skb, ETH_ALEN); //退入第二层
- ret = dev_queue_xmit(skb); //发送数据包
- if (ret < 0) { //发送失败
- printk(KERN_ERR "dev_queue_xmit() error!\n");
- return NF_DROP; //丢弃
- }
- return NF_STOLEN;
- }
- skb_push(skb, iph_len);
- skb_reset_transport_header(skb);
- }
- return NF_ACCEPT;
- }
- static int __initfilter_init(void){
- printk("------------------------------------checkIP is OK!-------------------------------------");
- nfho.hook = checkIP;
- nfho.pf = AF_INET; //设置协议类型,与PF_INEF相同
- nfho.hooknum = NF_INET_PRE_ROUTING;
- nfho.priority = NF_IP_PRI_FIRST; //设置钩子的优先级
- int ret = nf_register_hook(&nfho); //注册钩子
- if (ret < 0) {
- printk(KERN_ERR "can't modify skb hook!");
- return ret;
- }
- return 0;
- }
- static void filter_exit(void) {
- nf_unregister_hook(&nfho);
- }
- module_init(filter_init);
- module_exit(filter_exit);
复制代码 求大神指导我写的哪里错了,该怎么改。
|
|