注册 登录  
 加关注

网易博客网站关停、迁移的公告:

将从2018年11月30日00:00起正式停止网易博客运营
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

ideality

@linux c 编程@

 
 
 

日志

 
 
关于我

喜欢开源,愿意结识青岛使用开源的朋友,一起学习,工作。

网易考拉推荐
 
 

Linux中list.h中函数,jhash应用实例(转)  

2013-09-26 10:55:39|  分类: netfilter |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

这些代码片段展示如何使用Linux内核模块,list,以及hash

===================tccounter.c=====================

#include <linux/init.h>

#include <linux/module.h>

#include <linux/moduleparam.h>

#include <linux/list.h>

#include <linux/jhash.h>

#include <linux/ctype.h>

#include <linux/proc_fs.h>

#include <asm/uaccess.h>

MODULE_LICENSE("GPL");

static unsigned int ip = 123456789;

module_param(ip, uint, 0);

static unsigned int port = 1;

module_param(port, uint, 0);

#define TCCOUNT_SIZE 255

struct tccount

{

    struct list_head list;

    unsigned int ip;

    unsigned short port;

    unsigned short counter;

};

struct tccount tclist[TCCOUNT_SIZE];

unsigned int gethash(unsigned int ip, unsigned int port)

{

     return jhash_2words(ip, port, 4)%TCCOUNT_SIZE;

}

int tccount_init(void)

{

    int i;

    for(i = 0; i < TCCOUNT_SIZE; i++ )

    {

       INIT_LIST_HEAD(&(tclist[i].list));

       tclist[i].ip = 0;

       tclist[i].port = 0;

       tclist[i].counter = 0;

    }

    return 0;

}

int addNewStream(unsigned int sip, unsigned int sport)

{

    unsigned int hash;

    struct tccount *stream;

    hash = gethash(sip, sport);

    list_for_each_entry(stream, &(tclist[hash].list), list)

    {

        if(stream && stream->ip == sip && stream->port == sport)

        {

            stream->counter++;

            return 0;

        }

    }

    stream = kmalloc(sizeof(struct tccount), GFP_KERNEL);

    stream->ip = sip;

    stream->port = sport;

    stream->counter = 1;

    list_add_rcu(&(stream->list), &(tclist[hash].list));

    return 0;

}

int delStream(unsigned int sip, unsigned int sport)

{

    unsigned int hash;

    struct tccount *stream;

    hash = gethash(sip, sport);

    list_for_each_entry(stream, &(tclist[hash].list), list)

    {

        if(stream->ip == sip && stream->port == sport)

        {

            stream->counter--;

            if(stream->counter == 0 && stream != &tclist[hash])

            {

                list_del_rcu(&(stream->list));

                kfree(&stream);

            }

        }

    }

    return 0;

}

unsigned short getStreamCount(unsigned int sip, unsigned int sport)

{

    unsigned int hash;

    struct tccount *stream;

    hash = gethash(sip, sport);

    list_for_each_entry(stream, &(tclist[hash].list), list)

    {

        if(stream->ip == sip && stream->port == sport)

            return stream->counter;

    }

    return 0;

}

/*debug proc*/

static int proc_show_tccount(struct file *f, const char *buf, unsigned long cnt, void *data)

{

    char input[32];

    int r;

    unsigned int ip;

    unsigned int port;

    unsigned short count;

    if (copy_from_user(input, buf, cnt) != 0)

        return -EFAULT;

    r = cnt;


    sscanf(input, "%u %u", &ip, &port) ;

    count = getStreamCount(ip, port);

    printk(KERN_ALERT "(%d, %d) counter:%u/n",ip, port, count);

    return cnt;

}

static int proc_set_tccount(struct file *f, const char *buf, unsigned long cnt, void *data)

{

    char input[32];

    int r;

    unsigned int ip;

    unsigned int port;

    unsigned int count;

    if (copy_from_user(input, buf, cnt) != 0)

        return -EFAULT;

    r = cnt;

    sscanf(input, "%u %u", &ip, &port) ;

    count = addNewStream(ip, port);

    printk(KERN_ALERT "(%d, %d) has been added/n", ip, port);

    return cnt;

}

static int proc_del_tccount(struct file *f, const char *buf, unsigned long cnt, void *data)

{

    char input[32];

    int r;

    unsigned int ip;

    unsigned int port;

    unsigned int count;

    if (copy_from_user(input, buf, cnt) != 0)

        return -EFAULT;

    r = cnt;

    sscanf(input, "%u %u", &ip, &port) ;

    count = delStream(ip, port);

    printk(KERN_ALERT "a stream of (%d, %d) has been deleted/n", ip, port);

    return cnt;

}

static int proc_add(void)

{

    char tmp[32];

    struct proc_dir_entry *proc_tcctl, *pentry;

    sprintf(tmp, "tccount");

    proc_tcctl = proc_mkdir(tmp, NULL);

    sprintf(tmp, "show");

    pentry = create_proc_entry(tmp, 0644, proc_tcctl);

    pentry->data        = NULL;

    pentry->read_proc   = NULL;

    pentry->write_proc  = proc_show_tccount;

    pentry->owner       = THIS_MODULE;

    sprintf(tmp, "del");

    pentry = create_proc_entry(tmp, 0644, proc_tcctl);

    pentry->data        = NULL;

    pentry->read_proc   = NULL;

    pentry->write_proc  = proc_del_tccount;

    pentry->owner       = THIS_MODULE;

    sprintf(tmp, "add");

    pentry = create_proc_entry(tmp, 0644, proc_tcctl);

    pentry->data        = NULL;

    pentry->read_proc   = NULL;

    pentry->write_proc  = proc_set_tccount;

    pentry->owner       = THIS_MODULE;

    return 0;

}

static int hello_init(void)

{

    tccount_init();

    proc_add();

    return 0;

}

static void hello_exit(void)

{

    printk("Goodbye!/n");

}

module_init(hello_init);

module_exit(hello_exit);


====================Makefile========================

 

obj-m += tccounter.o

all:

make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:

make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

====================debug方法======================
echo 8 > /proc/sys/kernel/printk
echo 1234234123 123 > /proc/tccount/show
echo 1234234123 123 > /proc/tccount/add
echo 1234234123 123 > /proc/tccount/del

  评论这张
 
阅读(1831)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018