sockets - Linux protocol handler to get packets and processes associated to them -
hi linux networking experts, trying tool monitor sockets created each process, , bandwidth used each process. poll information /proc, miss short-lived sockets created , destroyed between poll cycles.
the idea create kernel module registers protocol handler networking subsystem, handler function called each packet received. in handler wanted socket associated sk_buff, , process opened socket. processes waiting socket, go through wait queue socket , check tasks in list. wrote this:
#include <linux/module.h> #include <linux/init.h> #include <linux/kernel.h> #include <linux/string.h> #include <linux/fs.h> #include <linux/types.h> #include <linux/kdev_t.h> #include <linux/netdevice.h> #include <linux/skbuff.h> #include <linux/slab.h> #include <net/datalink.h> #include <net/inet_hashtables.h> #include <net/tcp.h> #include <net/inet_common.h> #include <linux/list.h> #include <linux/ip.h> module_license("gpl"); module_description("xxx"); module_author("xxxx"); int prot_handler(struct sk_buff *, struct net_device *, struct packet_type *, struct net_device *); static struct packet_type handler_packet_type __read_mostly = { .type = cpu_to_be16(eth_p_ip), .func = prot_handler, }; int prot_handler(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev) { const struct iphdr *iph; const struct tcphdr *th; struct sock *sk; struct socket_wq *wq; wait_queue_head_t *q; struct task_struct * task; //printk(kern_alert "got sk_buff.\n"); iph = ip_hdr(skb); th = tcp_hdr(skb); sk = __inet_lookup_established(dev_net(skb->dev), &tcp_hashinfo, iph->saddr, th->source, iph->daddr, ntohs(th->dest), skb->skb_iif); /* __inet_lookup_skb crashing. might because skb_steal_sock? * * __inet_lookup_skb: * skb_steal_sock * __inet_lookup * __inet_lookup_established * __inet_lookup_listener */ if (!sk) return 0; //printk(kern_alert "found active sock.\n"); // code mimics sock_def_readable rcu_read_lock(); wq = rcu_dereference(sk->sk_wq); q = &wq->wait; if (wq_has_sleeper(wq)) { // code mimics __wake_up_common wait_queue_t *curr, *next; list_for_each_entry_safe(curr, next, &q->task_list, task_list) { task = curr->private; if (task && task->pid != 0) printk(kern_alert "got packet process id: %d\n", task->pid); } } } } rcu_read_unlock(); return 0; } static int __init dev_init(void) { printk(kern_alert "registering protocol handler network stack.\n"); dev_add_pack(&handler_packet_type); return 0; } static void __exit dev_exit(void) { printk(kern_alert "removing protocol handler.\n"); dev_remove_pack(&handler_packet_type); } module_init(dev_init); module_exit(dev_exit);
when load module, , started ssh session system test it. handler gets called when type on remote system, pid printed doesn't correlate expect. , handler doesn't called. think there might race condition ip_rcv.
apr 22 10:20:56 ol71node1 kernel: got packet process id: 13927307 apr 22 10:20:56 ol71node1 kernel: got packet process id: 13927307 apr 22 10:20:56 ol71node1 kernel: got packet process id: 13927307
can point how this, if use case doesn't make lot of sense?
thanks in advance.
Comments
Post a Comment