LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Kernel (https://www.linuxquestions.org/questions/linux-kernel-70/)
-   -   how to retrieve network sk_buff packets,thru a c code (https://www.linuxquestions.org/questions/linux-kernel-70/how-to-retrieve-network-sk_buff-packets-thru-a-c-code-530625/)

raklo 02-20-2007 12:57 AM

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

acp 02-28-2007 05:35 AM

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

raklo 02-28-2007 10:08 PM

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??????

acp 03-01-2007 03:37 AM

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 ;)

raklo 03-01-2007 03:50 AM

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.

acp 03-01-2007 04:29 AM

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.