From: Tang Longjun <[email protected]> track the IP header information of packets through the kprobe ip_local_deliver function
Signed-off-by: Tang Longjun <[email protected]> --- tools/virtio/virtnet_mon/virtnet_mon.c | 42 +++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/tools/virtio/virtnet_mon/virtnet_mon.c b/tools/virtio/virtnet_mon/virtnet_mon.c index 9c0b5ebc3f03..69b4afcbeb56 100644 --- a/tools/virtio/virtnet_mon/virtnet_mon.c +++ b/tools/virtio/virtnet_mon/virtnet_mon.c @@ -440,6 +440,8 @@ enum event_type { START_XMIT_POST_EVENT = 2, GRO_RECEIVE_SKB_PRE_EVENT = 3, GRO_RECEIVE_SKB_POST_EVENT = 4, + IP_LOCAL_DELIVER_PRE_EVENT = 5, + IP_LOCAL_DELIVER_POST_EVENT = 6, }; struct iph_info { @@ -482,6 +484,7 @@ static char read_buf[READ_SIZE]; static struct kprobe start_xmit_kp; static struct kprobe gro_receive_skb_kp; +static struct kprobe ip_local_deliver_kp; /* convert pkt_dir to string */ static const char *pkt_dir_to_str(enum pkt_dir dir) @@ -522,7 +525,11 @@ static const char *event_type_to_str(enum event_type event_type) case GRO_RECEIVE_SKB_PRE_EVENT: return "GRO_RECEIVE_SKB_PRE_EVENT"; case GRO_RECEIVE_SKB_POST_EVENT: - return "GRO_RECEIVE_SKB_POST_EVENT"; + return "GRO_RECEIVE_SKB_POST_EVENT"; + case IP_LOCAL_DELIVER_PRE_EVENT: + return "IP_LOCAL_DELIVER_PRE_EVENT"; + case IP_LOCAL_DELIVER_POST_EVENT: + return "IP_LOCAL_DELIVER_POST_EVENT"; default: return "Unknown"; } @@ -757,6 +764,26 @@ static int gro_receive_skb_pre_handler(struct kprobe *p, struct pt_regs *regs) return 0; } +/* Kprobe pre-handler for ip_local_deliver */ +static int ip_local_deliver_pre_handler(struct kprobe *p, struct pt_regs *regs) +{ + struct sk_buff *skb; + struct virtnet_mon_pkt_info info; + + /* Get skb parameter (first parameter) */ + skb = (struct sk_buff *)KP_GET_ARG(regs, 0); + + memset(&info, 0, sizeof(struct virtnet_mon_pkt_info)); + get_common_info(PKT_DIR_RX, IP_LOCAL_DELIVER_PRE_EVENT, &info); + if (get_iph_info(skb, &info.iph_info) != 0) + return 0; + + kfifo_in(&virtnet_mon_kfifo, &info, 1); + wake_up_interruptible(&virtnet_mon_wq); + + return 0; +} + // open device static int virtnet_mon_open(struct inode *inode, struct file *file) { @@ -904,6 +931,18 @@ static int __init virtnet_mon_init(void) } pr_info("virtnet_mon: Registered kprobe for gro_receive_skb\n"); + /* Setup kprobe for ip_local_deliver */ + ip_local_deliver_kp.pre_handler = ip_local_deliver_pre_handler; + ip_local_deliver_kp.symbol_name = "ip_local_deliver"; + + ret = register_kprobe(&ip_local_deliver_kp); + if (ret < 0) { + pr_info("virtnet_mon: Failed to register kprobe for ip_local_deliver: %d\n", ret); + unregister_kprobe(&ip_local_deliver_kp); + return ret; + } + pr_info("virtnet_mon: Registered kprobe for ip_local_deliver\n"); + return 0; } @@ -916,6 +955,7 @@ static void __exit virtnet_mon_exit(void) /* Unregister kprobes */ unregister_kprobe(&start_xmit_kp); unregister_kprobe(&gro_receive_skb_kp); + unregister_kprobe(&ip_local_deliver_kp); pr_info("virtnet_mon: Unloading module\n"); } -- 2.43.0
