This is the mail archive of the
systemtap@sourceware.org
mailing list for the systemtap project.
Tapset for TCP
- From: Breno Leitao <leitao at linux dot vnet dot ibm dot com>
- To: systemtap at sources dot redhat dot com
- Date: Fri, 13 Mar 2009 15:48:21 -0300
- Subject: Tapset for TCP
Guys,
I created a tapset for TCP incoming packets, and I hope it's helpful to the
project. Until now, it probes when the kernel receives a TCP packets,
and expose the following values:
IP SRC address
IP DST address
IP TTL
IP CHECKSUM
TCP SRC PORT
TCP DST PORT
TCP SEQ NUMBER
TCP SEQ ACK NUMBER
TCP CHECKSUM
An example is also attached.
I have plan to create another probe for TCP output packets and integrate
in the same file. As soon as I finish the output part, I'll also send
it you.
So, I am sharing these files now, in order to receive some feedback and
improve the code quality.
Thanks
Breno
// An example for TCP tapset
probe TCP.receivepkt {
printf("IP header\n")
printf("Source Address %d\n", ipsrc);
printf("Destination Address %d\n", ipdst);
printf("TTL %d\n", ttl);
printf("IP checksum %d\n", ipcksum);
printf("-------------\n");
printf("TCP HEADER\n");
printf("Source port %d\n", sport);
printf("Dest port %d\n", dport);
printf("Seq # %u\n", seq);
printf("ACK Seq %u\n", ackseq);
printf("TCP Checksum %d\n", tcpcksum);
printf("\n\n");
}
// TCP tapset
// Copyright (C) 2009 IBM Corp.
//
// This file is part of systemtap, and is free software. You can
// redistribute it and/or modify it under the terms of the GNU General
// Public License (GPL); either version 2, or (at your option) any
// later version.
//
// Author: Breno Leitao <leitao@linux.vnet.ibm.com>
%{
#include<linux/byteorder/generic.h>
#include<linux/if_ether.h>
#include<linux/skbuff.h>
#include<linux/ip.h>
#include<linux/in.h>
#include<linux/tcp.h>
%}
/* Check if the skb is using TCP/IP */
function istcp:long (data:long)
%{
struct iphdr *ip;
struct sk_buff *skb;
int tmp = 0;
skb = (struct sk_buff *) THIS->data;
if (skb->protocol == htons(ETH_P_IP)){
ip = (struct iphdr *) skb->data;
tmp = (ip->protocol == htons(IPPROTO_TCP));
}
THIS->__retvalue = tmp;
%}
/* Return TCP source port */
function tcpsport:long (data:long)
%{
struct iphdr *ip;
struct sk_buff *skb;
struct tcphdr *tcp;
int tmp = 0;
skb = (struct sk_buff *) THIS->data;
if (skb->protocol == htons(ETH_P_IP)){
ip = (struct iphdr *) skb->data;
if (ip->protocol == htons(IPPROTO_TCP)){
tcp = (struct tcphdr *)(skb->data + ip->ihl * 4);
tmp = tcp->source;
}
}
THIS->__retvalue = tmp;
%}
/* Return TCP checksum */
function tcpcksum:long (data:long)
%{
struct iphdr *ip;
struct sk_buff *skb;
struct tcphdr *tcp;
int tmp = 0;
skb = (struct sk_buff *) THIS->data;
if (skb->protocol == htons(ETH_P_IP)){
ip = (struct iphdr *) skb->data;
if (ip->protocol == htons(IPPROTO_TCP)){
tcp = (struct tcphdr *)(skb->data + ip->ihl * 4);
tmp = tcp->check;
}
}
THIS->__retvalue = tmp;
%}
/* return TCP ack sequence number */
function tcpackseq:long (data:long)
%{
struct iphdr *ip;
struct sk_buff *skb;
struct tcphdr *tcp;
int tmp = 0;
skb = (struct sk_buff *) THIS->data;
if (skb->protocol == htons(ETH_P_IP)){
ip = (struct iphdr *) skb->data;
if (ip->protocol == htons(IPPROTO_TCP)){
tcp = (struct tcphdr *)(skb->data + ip->ihl * 4);
tmp = tcp->ack_seq;
}
}
THIS->__retvalue = tmp;
%}
/* return TCP sequence number */
function tcpseq:long (data:long)
%{
struct iphdr *ip;
struct sk_buff *skb;
struct tcphdr *tcp;
int tmp = 0;
skb = (struct sk_buff *) THIS->data;
if (skb->protocol == htons(ETH_P_IP)){
ip = (struct iphdr *) skb->data;
if (ip->protocol == htons(IPPROTO_TCP)){
tcp = (struct tcphdr *)(skb->data + ip->ihl * 4);
tmp = tcp->seq;
}
}
THIS->__retvalue = tmp;
%}
/* return TCP destination port */
function tcpdport:long (data:long)
%{
struct iphdr *ip;
struct sk_buff *skb;
struct tcphdr *tcp;
int tmp = 0;
skb = (struct sk_buff *) THIS->data;
if (skb->protocol == htons(ETH_P_IP)){
ip = (struct iphdr *) skb->data;
if (ip->protocol == htons(IPPROTO_TCP)){
tcp = (struct tcphdr *)(skb->data + ip->ihl * 4);
tmp = tcp->dest;
}
}
THIS->__retvalue = tmp;
%}
/* return IP time to live */
function ipttl:long (data:long)
%{
struct sk_buff *skb;
struct iphdr *ip;
__be32 ttl;
skb = (struct sk_buff *) THIS->data;
ip = (struct iphdr *) skb->data;
ttl = (__be32) ip->ttl;
THIS->__retvalue = ttl;
%}
/* return IP source */
function ipsource:long (data:long)
%{
struct sk_buff *skb;
struct iphdr *ip;
__be32 src;
skb = (struct sk_buff *) THIS->data;
ip = (struct iphdr *) skb->data;
src = (__be32) ip->saddr;
THIS->__retvalue = src;
%}
/* Return ip destination address */
function ipdst:long (data:long)
%{
struct sk_buff *skb;
struct iphdr *ip;
__be32 dst;
skb = (struct sk_buff *) THIS->data;
ip = (struct iphdr *) skb->data;
dst = (__be32) ip->daddr;
THIS->__retvalue = dst;
%}
/* Return ip checksum */
function ipcksum:long (data:long)
%{
struct sk_buff *skb;
struct iphdr *ip;
__be32 cksum;
skb = (struct sk_buff *) THIS->data;
ip = (struct iphdr *) skb->data;
cksum = (__be32) ip->check;
THIS->__retvalue = cksum;
%}
/* A probe point intercepting any incoming packet */
probe TCP.receivepkt = kernel.function("netif_receive_skb")
{
if (istcp($skb)) {
/* TCP */
seq = tcpseq($skb)
ackseq = tcpackseq($skb)
tcpcksum = tcpcksum($skb)
sport = tcpsport($skb)
dport = tcpdport($skb)
/* IP */
ipdst = ipdst($skb)
ipsrc = ipsource($skb)
ipcksum = ipcksum($skb)
ttl = ipttl($skb)
} else {
next
}
}