教你如何注册proc文件系统

分类: LINUX

有些时候编写的内核模块,为了具有更高的可调试性,通常会使用proc文件系统。例如netfilter的layer7模块。
下面是在2.6.24下的注册proc文件系统,并实现读写功能的代码。
在/proc/net下建立目录procdir,在该目录下注册procfile文件。

#include <linux/spinlock.h>
#include <linux/version.h>
#include <net/ip.h>
#include <net/tcp.h>
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/netfilter.h>
#include <net/netfilter/nf_conntrack.h>
#include <net/netfilter/nf_conntrack_core.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter/xt_layer7.h>
#include <linux/ctype.h>
#include <linux/proc_fs.h>


MODULE_LICENSE("GPL");
MODULE_AUTHOR("LTW");
MODULE_DESCRIPTION("make proc file");
static struct nf_hook_ops procfile;
static int procnum=20;

static struct proc_dir_entry* father;

unsigned int procfile_func(unsigned int hooknum,struct sk_buff *skb,const struct net_device *in,const struct net_device *out,int(*okfn)(struct sk_buff*))
{
    printk(KERN_ALERT "OK\n");
    return NF_ACCEPT;
}

static int my_atoi(const char *s)
{
    int val = 0;

    for (;; s++) {
        switch (*s) {
            case '0'...'9':
            val = 10*val+(*s-'0');
            break;
        default:
            return val;
        }
    }
}
/* write out num_packets to userland. */
static int procfile_read_proc(char* page, char ** start, off_t off, int count,int* eof, void * data)
{
    if(procnum>99)
        printk(KERN_ALERT "procnum is too big\n");
    page[0] = procnum/10 + '0';
    page[1] = procnum%10 + '0';
    page[2] = '\n';
    page[3] = '\0';

    *eof=1;

    return 3;
}

/* Read in num_packets from userland */
static int procfile_write_proc(struct file* file, const char* buffer,
                             unsigned long count, void *data)
{
    char * foo = kmalloc(count, GFP_ATOMIC);

    if(!foo){
        return count;
    }

    if(copy_from_user(foo, buffer, count)) {
        return -EFAULT;
    }


    procnum= my_atoi(foo);
    kfree (foo);

    /* This has an arbitrary limit to make the math easier. I'm lazy.
    But anyway, 99 is a LOT! If you want more, you're doing it wrong! */

    if(procnum > 99) {
        printk(KERN_ALERT "procnum can't be > 99.\n");
        procnum = 99;
    } else if(procnum < 1) {
        printk(KERN_ALERT "procnum can't be < 1.\n");
        procnum = 1;
    }

    return count;
}


static void procfile_cleanup_proc(void)
{
    remove_proc_entry("procfile",father);
    remove_proc_entry("procdir",init_net.proc_net);
}

static void procfile_init_proc(void)
{
    struct proc_dir_entry* entry;
    father=proc_mkdir("procdir",init_net.proc_net);
    entry = create_proc_entry("procfile", 0644,father);
    entry->read_proc = procfile_read_proc;
    entry->write_proc = procfile_write_proc;
}

static int __init procfile_init(void)
{
    printk(KERN_ALERT "procfile init\n");
    procfile_init_proc();
    memset(&procfile,0,sizeof(struct nf_hook_ops));
    procfile.hook=procfile_func;
    procfile.owner=THIS_MODULE;
    procfile.pf=PF_INET;
    procfile.hooknum=NF_IP_PRE_ROUTING;
    procfile.priority=NF_IP_PRI_NAT_DST-1;
    return nf_register_hook(&procfile);
}
static void __exit procfile_exit(void)
{
    procfile_cleanup_proc();
    nf_unregister_hook(&procfile);
}
module_init(procfile_init);
module_exit(procfile_exit);

 

转载时请注明出处(http://pengliang.cublog.cn),谢谢。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值