These code snippets show how to use the Linux kernel module, list, and 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 address;
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 address;
Unsigned int port;
Unsigned short count;
If (copy_from_user (input, Buf, CNT )! = 0)
Return-efault;
R = CNT;
Sscanf (input, "% 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 address;
Unsigned int port;
Unsigned int count;
If (copy_from_user (input, Buf, CNT )! = 0)
Return-efault;
R = CNT;
Sscanf (input, "% 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 address;
Unsigned int port;
Unsigned int count;
If (copy_from_user (input, Buf, CNT )! = 0)
Return-efault;
R = CNT;
Sscanf (input, "% 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 Method ======================== ==== echo 8>/proc/sys/kernel/printkecho 1234234123 123>/proc/tccount/showecho 1234234123 123>/proc/tccount/addecho 1234234123 123>/proc/tccount /del