kprobe is the implementation of systemTap probing function for kernel functions in the kernel. Since the kernel provides a formal API to use kprobe, it may be more convenient for many kernel programmers to use kprobe directly than to use SystemTap. Three types of kprobe handlers are provided in the kernel, namely jprobe, kprobe, kretprobe. The following code uses these three probes to observe the return result of the ip_route_input() call in the TCP/IP arp_process function execution. This code also Shows the method of sharing parameters between the Entry handler and the Ret handler of the same function probe. The code is as follows:
arp_probe.c /* * arp_probe.c, by Qianfeng Zhang ([email protected]) * /
#include #include #include #include #include #include #include #include#br>
MODULE_AUTHOR("[email protected]"); MODULE_DESCRIPTION("A module to track the Call results of ip_route_input() inside arp_process using jprobe and kretprobe"); MODULE_LICENSE("GPL");
static int j_arp_process(struct sk_buff *skb) { struct net_d Evice *dev = skb->dev; struct in_device *in_dev; int no_addr, rpf;
in_dev = in_dev_get(dev); no_addr = ( in_dev->ifa_list == NULL ); rpf = IN_DEV_RPFILTER( in_dev); in_dev_put (in_dev); printk (" \\ narp_process () is called with interface device% s, in_dev (no_addr =% d, rpf =% d) \\ n ", dev- & gt; name, no_addr, rpf) Jprobe_return(); return(0); };
static int j_fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif, struct net_device *dev, __be32 *spec_dst, u32 *itag, u32 mark)
{ printk("fib_validate_source() is called with dst=0x%x, oif=%d \ ", dst, oif); jprobe_return(); return(0); };
static struct jprobe my_jp1 = { .entry = j_arp_process, .kp.symbol_name = "arp_process" };
static struct jprobe my_jp2 = { .entry = j_fib_validate_source, .kp .symbol_name = "fib_validate_source" };
static int entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs) { printk("Calling: %s()\ ", ri-> ;rp->kp.symbol_name); return(0); };
static int return_handler(struct kretprobe_instance *ri, struct pt_regs *regs) { int eax;
eax = regs ->ax & 0xffff ; printk("Returning: %s() with a return value: 0x%lx(64bit) 0x%x(32bit)\ ", ri->rp->kp.symbol_name , regs->ax, eax);
return(0); };
static int fib_lookup_entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs) { struct fib_result *resp;< Br>
resp = (struct fib_result *) regs->dx; printk("Calling: %s()\ ", ri->rp->kp.symbol_name); *((struct fib_result **)ri->data) = resp;
return(0); };
static int fib_lookup_return_handler(struct kretprobe_instance *ri, struct pt_regs *regs { struct fib_result *resp; int eax;
eax = regs->ax & 0xffff ; resp = *((struct fib_result **) ri->data); printk("Returning: ;: fib_lookup () with a return value type 0x% 0x% lx (64bit) (32bit), result- & gt x:% d \\ n ", regs- & gt; ax, eax, resp- & gt; type);
return (0);}
static struct kretprobe my_rp1 = {.handler = return_handler, .entry_handler = entry_handler, .kp.symbol_name = " ip_route_input_slow "};
static struct kretprobe my_rp2 = {.handler = return_handler, .entry_handler = entry_handler, .kp.symbol_name = " fib_validate_source "};
static struct kretprobe my_rp3 = { .handler = fib_lookup_return_handler, .entry_handler = fib_lookup_entry_handler, .kp.symbol_name = "fib_lookup", .data_size = sizeof(struct fib_result *) };
static int __init init_myprobe(void { int ret;
printk("RTN_UNICAST is %d\ ", RTN_UNICAST); if ( (ret = register_jprobe(&my_jp1)) < 0) { printk("register_jprobe %s failed, returned% d \\ n ", my_jp1.kp.symbol_name, ret); return (-1);}
if ((ret = register_jprobe (& my_jp2)) & lt; 0) {printk ( "register_jprobe %s failed, returned %d\ ", my_jp2.kp.symbol_name, ret); return(-1); }< Br>
if ( (ret = register_kretprobe(&my_rp1)) < 0 ) { printk("register_kretprobe %s failed, returned %d\ ", my_rp1.kp.symbol_name, ret); unregister_jprobe(& ; my_jp1); unregister_jprobe (& my_jp2); return (-1);}
if ((ret = register_kretprobe (& my_rp2)) & lt; 0) {printk (" register_kretprobe% s failed, Return %d\ ", my_rp2.kp.symbol_name, ret); unregister_jprobe(&my_jp1); unregister_jprobe(&my_jp2); unregister_kretprobe(&my_rp1); return(-1); }
If ( (ret = register_kretprobe(&my_rp3)) < 0 ) { printk("register_kretprobe %s failed, returned %d\ ", my_rp3.kp.symbol_name, ret); unregister_jprobe(&my_jp1); unregister_jprobe (&my_jp2); unregister_kretprobe(&my_rp1); unregister_kretprobe(&my_rp2); return(-1); }
return 0; }
1. In STM32, there are five clock sources, HSI, HSE, LSI, LSE, PLL. 1, HSI is a high-speed internal
Linux support for NICs is better than other hardware. XteamLinux 4.0
Data is the most important part of a Unix/Linux system, but backing up and synchro
Bill · Gates attitude towards software is: If you want good software, you have to pay for it.
Familiar with Linux virus to do system protection engineering
Quartz Time Configuration Basic Tutorial
Xshell configuration file backup tutorial
Exynos 4412 startup process analysis
Kingate proxy server setup steps
Realize linux and windows file transfer
Linux system /etc/fstab loss, mount LVM repair
Linux security mechanism detailed
Tiny4412 assembly water light code, Tiny4412 bare metal LED operation
Linux often crashes, stuck, what should I do?
How to use the capability feature to enhance the security of Linux systems
Tips for Win10 System to Hide Local Disks to Protect Important Files
How to solve the problem of Win10 version of "Xbox" login error 0x800488AB?
Win10 RS2 preview version 14905 Insider setting problem how to solve
The difference between Windows8 system and Win7
How does Win8.1 run the command prompt? Open the command prompt six ways
How does Windows XP configure IPv4 as IPv6
WIN10 removes and restores 6 folders (video, images, documents, downloads, music, desktop)