how to retrieve network sk_buff packets,thru a c code
i want to retrieve,that come in the form of struct sk_buff,so that i can store it at another place of my choice n i can process it later.wot do i need to do for that???
ideally just as ethernet card received the network packetsin the form of packts of sk_buff ,network driver gets the interrupt thru irq of eth0.which then calls the function netif_rx() and enqueuues the packets into the per-cpu queue. i want to store those packets at an alternate location,so that i can process it . i know that kernel also does the same thing but i want to do it thru my code.even if the kernel simultaneously does it if some more details r required kindly revert back ANY INPUT IS APPRECIATED. regards |
I'm working on a somehow similar project, and what I'm doing is adding a callback in the actual socket code with as parameters everything I need (in your case a pointer to the sk_buff structure).
You can then simply copy it to another location and do what you want with it... The modifications I made were: in net/socket.c, on the bottom: + EXPORT_SYMBOL(my_function_here); in net/ipv4/af_inet.c (note that of course will only handle IPv4 packets, but u'll get the idea): after the includes: + int (*my_function_here)(struct socket *sock, ...parameters); then (same file) in inet_stream_connect function (you should most probably change the reception functions rather than this one): + if (my_function_here) { + err = (*my_function_here)(parameters); Finally, in include/linux/net.h: + extern int (*my_function_here)(struct socket *sock, ...); And then you write a module which at initialization assigns a value to my_function_here so that it points to one of your functions that will handle the data. Don't forget on unload of module to reset the my_function_here pointer to NULL... Good luck acp |
thanx acp,i m looking into ur solution n will revert regarding the status,
but till this point wot ive done is i;ve written a kernel module thru which ive obtained pointer to the private (*priv) data structures of lan card in struct net_device. and ive shared interrupt of my code with irq 3 which is that of eth0. now whenever thre is an interrupt my module is called and interrupt handler is executed.in the handler i m working with priv pointer,but somehow i m not able to access the packets. now i want ur opinion whether this approach is correct or not?????? |
Well sorry to inform you that I'm in no way a kernel expert. What I know is what I proposed you above. Although I understand partially what you are doing, I'm in no way capable of helping you on that matter, sorry :).
Oh btw, you should take a look also at SELinux. It's part of the kernel (at least in the 2.6 series if I'm not mistaken), and provides with a set of hooks on several networking functions. For instance, if a connection is asked by an application in userspace (through the creation of a socket), you can activate a hook that will call a function and validate the creation of the socket or not. If you only need to access the data that might help. I wanted to be able to modify them therefore, this solution didn't apply. I don't know however if you can actually get the sk_buff structures from them... But you take a look. Good luck though ;) |
fine.
i m sorry but cud u elaborate a bit,wot all changes u did in the kernel code, as i m not clearly getting wot u did. |
Ok, I'll give you the necessary patches, that should make it clearer :
--- /usr/src/linux/include/linux/net.h 2006-09-20 05:42:06.000000000 +0200 +++ net.h 2007-03-01 11:15:56.000000000 +0100 @@ -306,3 +309,8 @@ extern int net_msg_burst; #endif /* __KERNEL__ */ #endif /* _LINUX_NET_H */ + +extern int (*autodiscovery_connection_callback)(struct socket *sock, + struct sockaddr *uaddr, int addr_len, int flags); --- /usr/src/linux/net/ipv4/af_inet.c 2006-09-20 05:42:06.000000000 +0200 +++ af_inet.c 2007-03-01 11:15:07.000000000 +0100 @@ -116,6 +116,11 @@ #include <linux/mroute.h> #endif +int (*autodiscovery_connection_callback)(struct socket *sock, + struct sockaddr *uaddr, int addr_len, int flags) = NULL;+ DEFINE_SNMP_STAT(struct linux_mib, net_statistics) __read_mostly; extern void ip_mc_drop_socket(struct sock *sk); @@ -522,6 +527,14 @@ int inet_stream_connect(struct socket *s int err; long timeo; + if (autodiscovery_connection_callback != NULL) { + err = (*autodiscovery_connection_callback)(sock, uaddr, addr_len, flags); + if (err) + goto out; + } + lock_sock(sk); if (uaddr->sa_family == AF_UNSPEC) { --- /usr/src/linux/net/socket.c 2006-09-20 05:42:06.000000000 +0200 +++ socket.c 2007-03-01 11:15:07.000000000 +0100 @@ -2177,3 +2177,6 @@ EXPORT_SYMBOL(sock_wake_async); EXPORT_SYMBOL(sockfd_lookup); EXPORT_SYMBOL(kernel_sendmsg); EXPORT_SYMBOL(kernel_recvmsg); +EXPORT_SYMBOL(autodiscovery_connection_callback); Now, the main part of my module consist of this file: #include <linux/init.h> #include <linux/module.h> #include <linux/socket.h> #include <linux/config.h> MODULE_LICENSE("GPL"); MODULE_AUTHOR("acp"); MODULE_DESCRIPTION("Autodiscovery module"); extern void *autodiscovery_connection_callback; static int _connection_callback(struct socket *sock, struct sockaddr *uaddr, int addr_len, int flags) { /* This is the function that will be called upon each attempt of connection using an AF_INET socket (IPv4 only) */ } static int autodiscovery_init(void) { printk(KERN_ALERT "Hello, this is autodiscovery module speaking.\n"); autodiscovery_connection_callback = _connection_callback; return 0; } static void autodiscovery_exit(void) { autodiscovery_connection_callback = NULL; printk(KERN_ALERT "Goodbye from autodiscovery module.\n"); } module_init(autodiscovery_init); module_exit(autodiscovery_exit); You should get the point by now I think. All I do in the kernel is to define a pointer to a function that I initialize to NULL. When my module loads it sets this pointer to one of its functions. Then whenever I want this function called, I just insert a block if (pointer != NULL) (*pointer)(parameters) BTW, the kernel used is 2.6.18.8 from www.kernel.org Hope that helped, acp |
All times are GMT -5. The time now is 05:22 AM. |