diff options
author | Andre Detsch <adetsch@br.ibm.com> | 2009-04-14 14:23:59 -0300 |
---|---|---|
committer | Josh Stone <jistone@redhat.com> | 2009-04-14 10:42:53 -0700 |
commit | 5e868ddd8263d2f7b61a702891252cc2bacb1c07 (patch) | |
tree | 7482978638f8f41904d0f908715d8543ffec196d /tapset/tcp.stp | |
parent | 7175b49227fb1f71f3bdd6060ef9f6499e42f035 (diff) | |
download | systemtap-steved-5e868ddd8263d2f7b61a702891252cc2bacb1c07.tar.gz systemtap-steved-5e868ddd8263d2f7b61a702891252cc2bacb1c07.tar.xz systemtap-steved-5e868ddd8263d2f7b61a702891252cc2bacb1c07.zip |
Add new TCP and IP functions
This patch adds some basic functions to the IP and TCP tapsets.
Mainly, it's possible to get the iphdr and tcphdr from a sk_buff structure.
As a consequence, a TCP probe called tcp.receive() was created and
is probed every time a TCP packet is received, and a lot of
useful fields is available, as the TCP flags.
Also a small example that works like tcpdump for received TCP packets was
created.
This patch was tested on x86 and ppc machines, on 2.6.18 kernel and also on
mainline one.
Signed-off-by: Breno Leitao <leitao@linux.vnet.ibm.com>
Signed-off-by: Andre Detsch <adetsch@br.ibm.com>
Signed-off-by: Josh Stone <jistone@redhat.com>
Diffstat (limited to 'tapset/tcp.stp')
-rw-r--r-- | tapset/tcp.stp | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/tapset/tcp.stp b/tapset/tcp.stp index bb96b0cb..2c5dce7e 100644 --- a/tapset/tcp.stp +++ b/tapset/tcp.stp @@ -15,6 +15,7 @@ #include <net/sock.h> #include <net/tcp.h> #include <net/ip.h> +#include <linux/skbuff.h> %} // Get retransmission timeout in usecs. RTO is initialized from default @@ -78,6 +79,70 @@ function __tcp_sock_dport:long (sock:long){ return @cast(sock, "inet_sock")->dport } +/* returns the TCP header for recent (<2.6.21) kernel */ +function __get_skb_tcphdr_new:long(skb:long) +%{ /* pure */ + struct sk_buff *skb; + skb = (struct sk_buff *)(long)THIS->skb; + /* as done by skb_transport_header() */ + #ifdef NET_SKBUFF_DATA_USES_OFFSET + THIS->__retvalue = (long)(kread(&(skb->head)) + kread(&(skb->transport_header))); + #else + THIS->__retvalue = (long)kread(&(skb->transport_header)); + #endif + CATCH_DEREF_FAULT(); +%} + +/* returns the TCP header for a given sk_buff structure */ +function __get_skb_tcphdr:long(skb:long){ +%( kernel_v < "2.6.21" %? + tcphdr = @cast(skb, "sk_buff")->h->raw + return tcphdr +%: + return __get_skb_tcphdr_new(skb) +%) +} + +/* returns TCP URG flag for a given sk_buff structure */ +function __tcp_skb_urg:long (tcphdr){ + return @cast(tcphdr, "tcphdr")->urg +} + +/* returns TCP ACK flag for a given sk_buff structure */ +function __tcp_skb_ack:long (tcphdr){ + return @cast(tcphdr, "tcphdr")->ack +} + +/* returns TCP PSH flag for a given sk_buff structure */ +function __tcp_skb_psh:long (tcphdr){ + return @cast(tcphdr, "tcphdr")->psh +} + +/* returns TCP RST flag for a given sk_buff structure */ +function __tcp_skb_rst:long (tcphdr){ + return @cast(tcphdr, "tcphdr")->rst +} + +/* returns TCP SYN flag for a given sk_buff structure */ +function __tcp_skb_syn:long (tcphdr){ + return @cast(tcphdr, "tcphdr")->syn +} + +/* returns TCP FIN flag for a given sk_buff structure */ +function __tcp_skb_fin:long (tcphdr){ + return @cast(tcphdr, "tcphdr")->fin +} + +/* returns TCP source port for a given sk_buff structure */ +function __tcp_skb_sport:long (tcphdr){ + return ntohs(@cast(tcphdr, "tcphdr")->source) +} + +/* returns TCP destination port for a given sk_buff structure */ +function __tcp_skb_dport:long (tcphdr){ + return @cast(tcphdr, "tcphdr")->dest +} + /* return the TCP source port for a given sock */ function __tcp_sock_sport:long (sock:long){ return @cast(sock, "inet_sock")->sport @@ -300,3 +365,32 @@ probe tcp.setsockopt.return = kernel.function("tcp_setsockopt").return { ret = $return } +/** + * probe tcp.receive - Called when a TCP packet is received + * @saddr: A string representing the source IP address + * @daddr: A string representing the destination IP address + * @sport: TCP source port + * @dport: TCP destination port + * @urg: TCP URG flag + * @ack: TCP ACK flag + * @psh: TCP PSH flag + * @rst: TCP RST flag + * @syn: TCP SYN flag + * @fin: TCP FIN flag + */ +probe tcp.receive = kernel.function("tcp_v4_rcv") { + iphdr = __get_skb_iphdr($skb) + saddr = ip_ntop(__ip_skb_saddr(iphdr)) + daddr = ip_ntop(__ip_skb_daddr(iphdr)) + protocol = __ip_skb_proto(iphdr) + + tcphdr = __get_skb_tcphdr($skb) + dport = __tcp_skb_dport(tcphdr) + sport = __tcp_skb_sport(tcphdr) + urg = __tcp_skb_urg(tcphdr) + ack = __tcp_skb_ack(tcphdr) + psh = __tcp_skb_psh(tcphdr) + rst = __tcp_skb_rst(tcphdr) + syn = __tcp_skb_syn(tcphdr) + fin = __tcp_skb_fin(tcphdr) +} |