2006-09-22 06:28:01 +04:00
/*
* dccp_probe - Observe the DCCP flow with kprobes .
*
* The idea for this came from Werner Almesberger ' s umlsim
* Copyright ( C ) 2004 , Stephen Hemminger < shemminger @ osdl . org >
*
* Modified for DCCP from Stephen Hemminger ' s code
* Copyright ( C ) 2006 , Ian McDonald < ian . mcdonald @ jandi . co . nz >
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include <linux/kernel.h>
# include <linux/kprobes.h>
# include <linux/socket.h>
# include <linux/dccp.h>
# include <linux/proc_fs.h>
# include <linux/module.h>
# include <linux/kfifo.h>
# include <linux/vmalloc.h>
2007-09-12 14:01:34 +04:00
# include <net/net_namespace.h>
2006-09-22 06:28:01 +04:00
# include "dccp.h"
# include "ccid.h"
# include "ccids/ccid3.h"
static int port ;
static int bufsize = 64 * 1024 ;
static const char procname [ ] = " dccpprobe " ;
2008-06-11 14:19:09 +04:00
static struct {
kfifo: move struct kfifo in place
This is a new generic kernel FIFO implementation.
The current kernel fifo API is not very widely used, because it has to
many constrains. Only 17 files in the current 2.6.31-rc5 used it.
FIFO's are like list's a very basic thing and a kfifo API which handles
the most use case would save a lot of development time and memory
resources.
I think this are the reasons why kfifo is not in use:
- The API is to simple, important functions are missing
- A fifo can be only allocated dynamically
- There is a requirement of a spinlock whether you need it or not
- There is no support for data records inside a fifo
So I decided to extend the kfifo in a more generic way without blowing up
the API to much. The new API has the following benefits:
- Generic usage: For kernel internal use and/or device driver.
- Provide an API for the most use case.
- Slim API: The whole API provides 25 functions.
- Linux style habit.
- DECLARE_KFIFO, DEFINE_KFIFO and INIT_KFIFO Macros
- Direct copy_to_user from the fifo and copy_from_user into the fifo.
- The kfifo itself is an in place member of the using data structure, this save an
indirection access and does not waste the kernel allocator.
- Lockless access: if only one reader and one writer is active on the fifo,
which is the common use case, no additional locking is necessary.
- Remove spinlock - give the user the freedom of choice what kind of locking to use if
one is required.
- Ability to handle records. Three type of records are supported:
- Variable length records between 0-255 bytes, with a record size
field of 1 bytes.
- Variable length records between 0-65535 bytes, with a record size
field of 2 bytes.
- Fixed size records, which no record size field.
- Preserve memory resource.
- Performance!
- Easy to use!
This patch:
Since most users want to have the kfifo as part of another object,
reorganize the code to allow including struct kfifo in another data
structure. This requires changing the kfifo_alloc and kfifo_init
prototypes so that we pass an existing kfifo pointer into them. This
patch changes the implementation and all existing users.
[akpm@linux-foundation.org: fix warning]
Signed-off-by: Stefani Seibold <stefani@seibold.net>
Acked-by: Greg Kroah-Hartman <gregkh@suse.de>
Acked-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Acked-by: Andi Kleen <ak@linux.intel.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2009-12-22 01:37:26 +03:00
struct kfifo fifo ;
2006-09-22 06:28:01 +04:00
spinlock_t lock ;
wait_queue_head_t wait ;
2008-04-22 01:28:45 +04:00
struct timespec tstart ;
2006-09-22 06:28:01 +04:00
} dccpw ;
static void printl ( const char * fmt , . . . )
{
va_list args ;
int len ;
2008-04-22 01:28:45 +04:00
struct timespec now ;
2006-09-22 06:28:01 +04:00
char tbuf [ 256 ] ;
va_start ( args , fmt ) ;
2008-04-22 01:28:45 +04:00
getnstimeofday ( & now ) ;
2006-09-22 06:28:01 +04:00
2008-04-22 01:28:45 +04:00
now = timespec_sub ( now , dccpw . tstart ) ;
2006-09-22 06:28:01 +04:00
len = sprintf ( tbuf , " %lu.%06lu " ,
( unsigned long ) now . tv_sec ,
2008-04-22 01:28:45 +04:00
( unsigned long ) now . tv_nsec / NSEC_PER_USEC ) ;
2006-09-22 06:28:01 +04:00
len + = vscnprintf ( tbuf + len , sizeof ( tbuf ) - len , fmt , args ) ;
va_end ( args ) ;
2009-12-22 01:37:28 +03:00
kfifo_in_locked ( & dccpw . fifo , tbuf , len , & dccpw . lock ) ;
2006-09-22 06:28:01 +04:00
wake_up ( & dccpw . wait ) ;
}
static int jdccp_sendmsg ( struct kiocb * iocb , struct sock * sk ,
struct msghdr * msg , size_t size )
{
const struct inet_sock * inet = inet_sk ( sk ) ;
2009-10-05 04:53:13 +04:00
struct ccid3_hc_tx_sock * hc = NULL ;
2006-09-22 06:28:01 +04:00
2008-11-24 03:04:59 +03:00
if ( ccid_get_current_tx_ccid ( dccp_sk ( sk ) ) = = DCCPC_CCID3 )
2009-10-05 04:53:13 +04:00
hc = ccid3_hc_tx_sk ( sk ) ;
2006-09-22 06:28:01 +04:00
2009-10-15 10:30:45 +04:00
if ( port = = 0 | | ntohs ( inet - > inet_dport ) = = port | |
ntohs ( inet - > inet_sport ) = = port ) {
2009-10-05 04:53:13 +04:00
if ( hc )
2009-10-05 04:53:11 +04:00
printl ( " %pI4:%u %pI4:%u %d %d %d %d %u %llu %llu %d \n " ,
2009-10-15 10:30:45 +04:00
& inet - > inet_saddr , ntohs ( inet - > inet_sport ) ,
& inet - > inet_daddr , ntohs ( inet - > inet_dport ) , size ,
2009-10-05 04:53:13 +04:00
hc - > tx_s , hc - > tx_rtt , hc - > tx_p ,
hc - > tx_x_calc , hc - > tx_x_recv > > 6 ,
hc - > tx_x > > 6 , hc - > tx_t_ipi ) ;
2006-09-22 06:28:01 +04:00
else
2008-10-31 10:54:56 +03:00
printl ( " %pI4:%u %pI4:%u %d \n " ,
2009-10-15 10:30:45 +04:00
& inet - > inet_saddr , ntohs ( inet - > inet_sport ) ,
& inet - > inet_daddr , ntohs ( inet - > inet_dport ) ,
size ) ;
2006-09-22 06:28:01 +04:00
}
jprobe_return ( ) ;
return 0 ;
}
static struct jprobe dccp_send_probe = {
2006-11-20 23:41:37 +03:00
. kp = {
. symbol_name = " dccp_sendmsg " ,
} ,
2007-07-19 12:48:10 +04:00
. entry = jdccp_sendmsg ,
2006-09-22 06:28:01 +04:00
} ;
static int dccpprobe_open ( struct inode * inode , struct file * file )
{
kfifo: move struct kfifo in place
This is a new generic kernel FIFO implementation.
The current kernel fifo API is not very widely used, because it has to
many constrains. Only 17 files in the current 2.6.31-rc5 used it.
FIFO's are like list's a very basic thing and a kfifo API which handles
the most use case would save a lot of development time and memory
resources.
I think this are the reasons why kfifo is not in use:
- The API is to simple, important functions are missing
- A fifo can be only allocated dynamically
- There is a requirement of a spinlock whether you need it or not
- There is no support for data records inside a fifo
So I decided to extend the kfifo in a more generic way without blowing up
the API to much. The new API has the following benefits:
- Generic usage: For kernel internal use and/or device driver.
- Provide an API for the most use case.
- Slim API: The whole API provides 25 functions.
- Linux style habit.
- DECLARE_KFIFO, DEFINE_KFIFO and INIT_KFIFO Macros
- Direct copy_to_user from the fifo and copy_from_user into the fifo.
- The kfifo itself is an in place member of the using data structure, this save an
indirection access and does not waste the kernel allocator.
- Lockless access: if only one reader and one writer is active on the fifo,
which is the common use case, no additional locking is necessary.
- Remove spinlock - give the user the freedom of choice what kind of locking to use if
one is required.
- Ability to handle records. Three type of records are supported:
- Variable length records between 0-255 bytes, with a record size
field of 1 bytes.
- Variable length records between 0-65535 bytes, with a record size
field of 2 bytes.
- Fixed size records, which no record size field.
- Preserve memory resource.
- Performance!
- Easy to use!
This patch:
Since most users want to have the kfifo as part of another object,
reorganize the code to allow including struct kfifo in another data
structure. This requires changing the kfifo_alloc and kfifo_init
prototypes so that we pass an existing kfifo pointer into them. This
patch changes the implementation and all existing users.
[akpm@linux-foundation.org: fix warning]
Signed-off-by: Stefani Seibold <stefani@seibold.net>
Acked-by: Greg Kroah-Hartman <gregkh@suse.de>
Acked-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Acked-by: Andi Kleen <ak@linux.intel.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2009-12-22 01:37:26 +03:00
kfifo_reset ( & dccpw . fifo ) ;
2008-04-22 01:28:45 +04:00
getnstimeofday ( & dccpw . tstart ) ;
2006-09-22 06:28:01 +04:00
return 0 ;
}
static ssize_t dccpprobe_read ( struct file * file , char __user * buf ,
size_t len , loff_t * ppos )
{
int error = 0 , cnt = 0 ;
unsigned char * tbuf ;
2007-06-01 08:33:35 +04:00
if ( ! buf )
2006-09-22 06:28:01 +04:00
return - EINVAL ;
if ( len = = 0 )
return 0 ;
tbuf = vmalloc ( len ) ;
if ( ! tbuf )
return - ENOMEM ;
error = wait_event_interruptible ( dccpw . wait ,
2009-12-22 01:37:28 +03:00
kfifo_len ( & dccpw . fifo ) ! = 0 ) ;
2006-09-22 06:28:01 +04:00
if ( error )
goto out_free ;
2009-12-22 01:37:28 +03:00
cnt = kfifo_out_locked ( & dccpw . fifo , tbuf , len , & dccpw . lock ) ;
2008-04-25 12:49:48 +04:00
error = copy_to_user ( buf , tbuf , cnt ) ? - EFAULT : 0 ;
2006-09-22 06:28:01 +04:00
out_free :
vfree ( tbuf ) ;
return error ? error : cnt ;
}
2007-02-12 11:55:35 +03:00
static const struct file_operations dccpprobe_fops = {
2006-09-22 06:28:01 +04:00
. owner = THIS_MODULE ,
. open = dccpprobe_open ,
. read = dccpprobe_read ,
} ;
static __init int dccpprobe_init ( void )
{
int ret = - ENOMEM ;
init_waitqueue_head ( & dccpw . wait ) ;
spin_lock_init ( & dccpw . lock ) ;
2009-12-22 01:37:27 +03:00
if ( kfifo_alloc ( & dccpw . fifo , bufsize , GFP_KERNEL ) )
kfifo: move struct kfifo in place
This is a new generic kernel FIFO implementation.
The current kernel fifo API is not very widely used, because it has to
many constrains. Only 17 files in the current 2.6.31-rc5 used it.
FIFO's are like list's a very basic thing and a kfifo API which handles
the most use case would save a lot of development time and memory
resources.
I think this are the reasons why kfifo is not in use:
- The API is to simple, important functions are missing
- A fifo can be only allocated dynamically
- There is a requirement of a spinlock whether you need it or not
- There is no support for data records inside a fifo
So I decided to extend the kfifo in a more generic way without blowing up
the API to much. The new API has the following benefits:
- Generic usage: For kernel internal use and/or device driver.
- Provide an API for the most use case.
- Slim API: The whole API provides 25 functions.
- Linux style habit.
- DECLARE_KFIFO, DEFINE_KFIFO and INIT_KFIFO Macros
- Direct copy_to_user from the fifo and copy_from_user into the fifo.
- The kfifo itself is an in place member of the using data structure, this save an
indirection access and does not waste the kernel allocator.
- Lockless access: if only one reader and one writer is active on the fifo,
which is the common use case, no additional locking is necessary.
- Remove spinlock - give the user the freedom of choice what kind of locking to use if
one is required.
- Ability to handle records. Three type of records are supported:
- Variable length records between 0-255 bytes, with a record size
field of 1 bytes.
- Variable length records between 0-65535 bytes, with a record size
field of 2 bytes.
- Fixed size records, which no record size field.
- Preserve memory resource.
- Performance!
- Easy to use!
This patch:
Since most users want to have the kfifo as part of another object,
reorganize the code to allow including struct kfifo in another data
structure. This requires changing the kfifo_alloc and kfifo_init
prototypes so that we pass an existing kfifo pointer into them. This
patch changes the implementation and all existing users.
[akpm@linux-foundation.org: fix warning]
Signed-off-by: Stefani Seibold <stefani@seibold.net>
Acked-by: Greg Kroah-Hartman <gregkh@suse.de>
Acked-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Acked-by: Andi Kleen <ak@linux.intel.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2009-12-22 01:37:26 +03:00
return ret ;
2007-09-12 14:01:34 +04:00
if ( ! proc_net_fops_create ( & init_net , procname , S_IRUSR , & dccpprobe_fops ) )
2006-09-22 06:28:01 +04:00
goto err0 ;
2010-02-02 23:16:56 +03:00
try_then_request_module ( ( ret = register_jprobe ( & dccp_send_probe ) ) = = 0 ,
" dccp " ) ;
2006-09-22 06:28:01 +04:00
if ( ret )
goto err1 ;
pr_info ( " DCCP watch registered (port=%d) \n " , port ) ;
return 0 ;
err1 :
2007-09-12 14:01:34 +04:00
proc_net_remove ( & init_net , procname ) ;
2006-09-22 06:28:01 +04:00
err0 :
kfifo: move struct kfifo in place
This is a new generic kernel FIFO implementation.
The current kernel fifo API is not very widely used, because it has to
many constrains. Only 17 files in the current 2.6.31-rc5 used it.
FIFO's are like list's a very basic thing and a kfifo API which handles
the most use case would save a lot of development time and memory
resources.
I think this are the reasons why kfifo is not in use:
- The API is to simple, important functions are missing
- A fifo can be only allocated dynamically
- There is a requirement of a spinlock whether you need it or not
- There is no support for data records inside a fifo
So I decided to extend the kfifo in a more generic way without blowing up
the API to much. The new API has the following benefits:
- Generic usage: For kernel internal use and/or device driver.
- Provide an API for the most use case.
- Slim API: The whole API provides 25 functions.
- Linux style habit.
- DECLARE_KFIFO, DEFINE_KFIFO and INIT_KFIFO Macros
- Direct copy_to_user from the fifo and copy_from_user into the fifo.
- The kfifo itself is an in place member of the using data structure, this save an
indirection access and does not waste the kernel allocator.
- Lockless access: if only one reader and one writer is active on the fifo,
which is the common use case, no additional locking is necessary.
- Remove spinlock - give the user the freedom of choice what kind of locking to use if
one is required.
- Ability to handle records. Three type of records are supported:
- Variable length records between 0-255 bytes, with a record size
field of 1 bytes.
- Variable length records between 0-65535 bytes, with a record size
field of 2 bytes.
- Fixed size records, which no record size field.
- Preserve memory resource.
- Performance!
- Easy to use!
This patch:
Since most users want to have the kfifo as part of another object,
reorganize the code to allow including struct kfifo in another data
structure. This requires changing the kfifo_alloc and kfifo_init
prototypes so that we pass an existing kfifo pointer into them. This
patch changes the implementation and all existing users.
[akpm@linux-foundation.org: fix warning]
Signed-off-by: Stefani Seibold <stefani@seibold.net>
Acked-by: Greg Kroah-Hartman <gregkh@suse.de>
Acked-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Acked-by: Andi Kleen <ak@linux.intel.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2009-12-22 01:37:26 +03:00
kfifo_free ( & dccpw . fifo ) ;
2006-09-22 06:28:01 +04:00
return ret ;
}
module_init ( dccpprobe_init ) ;
static __exit void dccpprobe_exit ( void )
{
kfifo: move struct kfifo in place
This is a new generic kernel FIFO implementation.
The current kernel fifo API is not very widely used, because it has to
many constrains. Only 17 files in the current 2.6.31-rc5 used it.
FIFO's are like list's a very basic thing and a kfifo API which handles
the most use case would save a lot of development time and memory
resources.
I think this are the reasons why kfifo is not in use:
- The API is to simple, important functions are missing
- A fifo can be only allocated dynamically
- There is a requirement of a spinlock whether you need it or not
- There is no support for data records inside a fifo
So I decided to extend the kfifo in a more generic way without blowing up
the API to much. The new API has the following benefits:
- Generic usage: For kernel internal use and/or device driver.
- Provide an API for the most use case.
- Slim API: The whole API provides 25 functions.
- Linux style habit.
- DECLARE_KFIFO, DEFINE_KFIFO and INIT_KFIFO Macros
- Direct copy_to_user from the fifo and copy_from_user into the fifo.
- The kfifo itself is an in place member of the using data structure, this save an
indirection access and does not waste the kernel allocator.
- Lockless access: if only one reader and one writer is active on the fifo,
which is the common use case, no additional locking is necessary.
- Remove spinlock - give the user the freedom of choice what kind of locking to use if
one is required.
- Ability to handle records. Three type of records are supported:
- Variable length records between 0-255 bytes, with a record size
field of 1 bytes.
- Variable length records between 0-65535 bytes, with a record size
field of 2 bytes.
- Fixed size records, which no record size field.
- Preserve memory resource.
- Performance!
- Easy to use!
This patch:
Since most users want to have the kfifo as part of another object,
reorganize the code to allow including struct kfifo in another data
structure. This requires changing the kfifo_alloc and kfifo_init
prototypes so that we pass an existing kfifo pointer into them. This
patch changes the implementation and all existing users.
[akpm@linux-foundation.org: fix warning]
Signed-off-by: Stefani Seibold <stefani@seibold.net>
Acked-by: Greg Kroah-Hartman <gregkh@suse.de>
Acked-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Acked-by: Andi Kleen <ak@linux.intel.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2009-12-22 01:37:26 +03:00
kfifo_free ( & dccpw . fifo ) ;
2007-09-12 14:01:34 +04:00
proc_net_remove ( & init_net , procname ) ;
2006-09-22 06:28:01 +04:00
unregister_jprobe ( & dccp_send_probe ) ;
}
module_exit ( dccpprobe_exit ) ;
MODULE_PARM_DESC ( port , " Port to match (0=all) " ) ;
module_param ( port , int , 0 ) ;
MODULE_PARM_DESC ( bufsize , " Log buffer size (default 64k) " ) ;
module_param ( bufsize , int , 0 ) ;
MODULE_AUTHOR ( " Ian McDonald <ian.mcdonald@jandi.co.nz> " ) ;
MODULE_DESCRIPTION ( " DCCP snooper " ) ;
MODULE_LICENSE ( " GPL " ) ;