有些时候编写的内核模块,为了具有更高的可调试性,通常会使用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 ),谢谢。