tcp jprobe 利用问题定位

来源:互联网 发布:公知日杂什么意思 编辑:程序博客网 时间:2024/06/15 23:38
/* * Here's a sample kernel module showing the use of jprobes to dump * the arguments of do_fork(). * * For more information on theory of operation of jprobes, see * Documentation/kprobes.txt * * Build and insert the kernel module as done in the kprobe example. * You will see the trace data in /var/log/messages and on the * console whenever do_fork() is invoked to create a new process. * (Some messages may be suppressed if syslogd is configured to * eliminate duplicate messages.) */#include <linux/kprobes.h>#include <linux/tcp.h>#include <linux/mm.h>#include <linux/slab.h>#include <linux/module.h>#include <linux/sysctl.h>#include <linux/kernel.h>#include <net/dst.h>#include <net/tcp.h>#include <net/inet_common.h>#include <linux/ipsec.h>#include <asm/unaligned.h>#include <net/netdma.h>#include <linux/skbtrace.h>#include <linux/skbuff.h>int all_enable1 = 0;module_param(all_enable1, int, 0644);int all_enable2 = 0;module_param(all_enable2, int, 0644);void jtcp_v4_send_check(struct sock *sk, struct sk_buff *skb){    struct tcp_sock *tp = tcp_sk(sk);    u32 saddr, daddr, seq, end_seq;    unsigned short  source, dest;    struct inet_sock *inet = inet_sk(sk);    if (sk == NULL || skb == NULL)goto drop;    saddr = inet->inet_saddr;    daddr = inet->inet_daddr;    source = ntohs(inet->inet_sport);    dest = ntohs(inet->inet_dport);    seq = TCP_SKB_CB(skb)->seq;    end_seq = TCP_SKB_CB(skb)->end_seq;if (all_enable1 && (source == 80 || dest == 80))printk("%s %s %pI4 %u -> %pI4 %u seq %u-%u lost %u sck %u paout %u\n", __func__, end_seq < tp->snd_nxt ? "R":"N", &saddr, source, &daddr, dest, seq, end_seq,tp->lost_out, tp->sacked_out, tp->packets_out);if (end_seq < tp->snd_nxt && all_enable2 && (source == 80 || dest == 80)) {printk("%s %s %pI4 %u -> %pI4 %u seq %u-%u lost %u sck %u paout %u\n", __func__, end_seq < tp->snd_nxt ? "R":"N", &saddr, source, &daddr, dest, seq, end_seq,tp->lost_out, tp->sacked_out, tp->packets_out);dump_stack();}drop:jprobe_return();return ;}int jtcp_ack(struct sock *sk, struct sk_buff *skb, int flag){    struct tcp_sock *tp = tcp_sk(sk);    u32 saddr, daddr, seq, end_seq, ack_seq;    unsigned short  source, dest;    struct inet_sock *inet = inet_sk(sk);    int i  = 0;    int len = 0;    char pf_buffer[1024] = {0};const unsigned char *ptr = NULL;struct tcp_sack_block_wire *sp_wire = NULL;    struct tcp_sack_block sp[TCP_NUM_SACKS] ={{0,0},{0,0},{0,0},{0,0}};int num_sacks;    if (sk == NULL || skb == NULL)        goto drop;    saddr = inet->inet_saddr;    daddr = inet->inet_daddr;    source = ntohs(inet->inet_sport);    dest = ntohs(inet->inet_dport);    seq = TCP_SKB_CB(skb)->seq;    end_seq = TCP_SKB_CB(skb)->end_seq;ack_seq = TCP_SKB_CB(skb)->ack_seq;    ptr = (skb_transport_header(skb) + TCP_SKB_CB(skb)->sacked);    sp_wire = (struct tcp_sack_block_wire *)(ptr+2);    num_sacks = min(TCP_NUM_SACKS, (ptr[1] - TCPOLEN_SACK_BASE) >> 3);if (TCP_SKB_CB(skb)->sacked) {for (i = 0; i < num_sacks; i++) {sp[i].start_seq = get_unaligned_be32(&sp_wire[i].start_seq);sp[i].end_seq = get_unaligned_be32(&sp_wire[i].end_seq);   if (len >= sizeof(pf_buffer) )break;sprintf(pf_buffer + len, "%u-%u,", sp[i].start_seq, sp[i].end_seq);len += strlen(pf_buffer);}}    if (all_enable1 && (source == 80 || dest == 80))        printk("%s %pI4 %u -> %pI4 %u %u seq %u lost %u sck %u paout %u sack %s\n",                 __func__, &saddr, source, &daddr, dest, ack_seq, seq,                tp->lost_out, tp->sacked_out, tp->packets_out, i ? pf_buffer : ""); drop:    jprobe_return();    return 0;}void jtcp_enter_loss(struct sock *sk, int how){printk("%s\n", __func__);jprobe_return();return;}static struct jprobe my_jprobe3 = {.entry = jtcp_enter_loss,.kp = {.symbol_name = "tcp_enter_loss",},};static struct jprobe my_jprobe1 = {.entry= jtcp_v4_send_check,.kp = {.symbol_name= "tcp_v4_send_check",},};static struct jprobe my_jprobe2 = {.entry   = jtcp_ack,.kp = {.symbol_name = "tcp_ack",},};struct jprobe *my_jprobes[3] = {NULL, NULL, NULL};static int __init jprobe_init(void){int ret;my_jprobes[0] = &my_jprobe1;my_jprobes[1] = &my_jprobe2;my_jprobes[2] = &my_jprobe3;ret = register_jprobes(my_jprobes, 3);if (ret < 0) {printk(KERN_INFO "1  register_jprobe failed, returned %d\n", ret);return -1;}printk(KERN_INFO "Planted jprobe at %p, handler addr %p\n",       my_jprobe1.kp.addr, my_jprobe1.entry);return 0;}static void __exit jprobe_exit(void){unregister_jprobes(my_jprobes, 3);printk(KERN_INFO "jprobe at %p unregistered\n", my_jprobe1.kp.addr);}module_init(jprobe_init)module_exit(jprobe_exit)MODULE_LICENSE("GPL");

0 0
原创粉丝点击