USB: add binary API to usbmon
This patch adds a new, "binary" API in addition to the old, text API usbmon had before. The new API allows for less CPU use, and it allows to capture all data from a packet where old API only captured 32 bytes at most. There are some limitations and conditions to this, e.g. in case someone constructs a URB with 1GB of data, it's not likely to be captured, because even the huge buffers of the new reader are finite. Nonetheless, I expect this new capability to capture all data for all real life scenarios. The downside is, a special user mode application is required where cat(1) worked before. I have sample code at http://people.redhat.com/zaitcev/linux/ and Paolo Abeni is working on patching libpcap. This patch was initially written by Paolo and later I tweaked it, and we had a little back-and-forth. So this is a jointly authored patch, but I am submitting this I am responsible for the bugs. Signed-off-by: Paolo Abeni <paolo.abeni@email.it> Signed-off-by: Pete Zaitcev <zaitcev@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
a8ef36bc0a
commit
6f23ee1fef
@@ -9,6 +9,7 @@
|
||||
#include <linux/usb.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
#include "usb_mon.h"
|
||||
@@ -63,6 +64,8 @@ struct mon_reader_text {
|
||||
char slab_name[SLAB_NAME_SZ];
|
||||
};
|
||||
|
||||
static struct dentry *mon_dir; /* Usually /sys/kernel/debug/usbmon */
|
||||
|
||||
static void mon_text_ctor(void *, struct kmem_cache *, unsigned long);
|
||||
|
||||
/*
|
||||
@@ -436,7 +439,7 @@ static int mon_text_release(struct inode *inode, struct file *file)
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct file_operations mon_fops_text = {
|
||||
static const struct file_operations mon_fops_text = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = mon_text_open,
|
||||
.llseek = no_llseek,
|
||||
@@ -447,6 +450,47 @@ const struct file_operations mon_fops_text = {
|
||||
.release = mon_text_release,
|
||||
};
|
||||
|
||||
int mon_text_add(struct mon_bus *mbus, const struct usb_bus *ubus)
|
||||
{
|
||||
struct dentry *d;
|
||||
enum { NAMESZ = 10 };
|
||||
char name[NAMESZ];
|
||||
int rc;
|
||||
|
||||
rc = snprintf(name, NAMESZ, "%dt", ubus->busnum);
|
||||
if (rc <= 0 || rc >= NAMESZ)
|
||||
goto err_print_t;
|
||||
d = debugfs_create_file(name, 0600, mon_dir, mbus, &mon_fops_text);
|
||||
if (d == NULL)
|
||||
goto err_create_t;
|
||||
mbus->dent_t = d;
|
||||
|
||||
/* XXX The stats do not belong to here (text API), but oh well... */
|
||||
rc = snprintf(name, NAMESZ, "%ds", ubus->busnum);
|
||||
if (rc <= 0 || rc >= NAMESZ)
|
||||
goto err_print_s;
|
||||
d = debugfs_create_file(name, 0600, mon_dir, mbus, &mon_fops_stat);
|
||||
if (d == NULL)
|
||||
goto err_create_s;
|
||||
mbus->dent_s = d;
|
||||
|
||||
return 1;
|
||||
|
||||
err_create_s:
|
||||
err_print_s:
|
||||
debugfs_remove(mbus->dent_t);
|
||||
mbus->dent_t = NULL;
|
||||
err_create_t:
|
||||
err_print_t:
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mon_text_del(struct mon_bus *mbus)
|
||||
{
|
||||
debugfs_remove(mbus->dent_t);
|
||||
debugfs_remove(mbus->dent_s);
|
||||
}
|
||||
|
||||
/*
|
||||
* Slab interface: constructor.
|
||||
*/
|
||||
@@ -459,3 +503,24 @@ static void mon_text_ctor(void *mem, struct kmem_cache *slab, unsigned long sfla
|
||||
memset(mem, 0xe5, sizeof(struct mon_event_text));
|
||||
}
|
||||
|
||||
int __init mon_text_init(void)
|
||||
{
|
||||
struct dentry *mondir;
|
||||
|
||||
mondir = debugfs_create_dir("usbmon", NULL);
|
||||
if (IS_ERR(mondir)) {
|
||||
printk(KERN_NOTICE TAG ": debugfs is not available\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
if (mondir == NULL) {
|
||||
printk(KERN_NOTICE TAG ": unable to create usbmon directory\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
mon_dir = mondir;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __exit mon_text_exit(void)
|
||||
{
|
||||
debugfs_remove(mon_dir);
|
||||
}
|
||||
|
Reference in New Issue
Block a user