This is the mail archive of the
systemtap@sourceware.org
mailing list for the systemtap project.
Re: Tapset for TCP
- From: Arnaldo Carvalho de Melo <acme at redhat dot com>
- To: Breno Leitao <leitao at linux dot vnet dot ibm dot com>
- Cc: systemtap at sources dot redhat dot com
- Date: Fri, 13 Mar 2009 20:12:53 -0300
- Subject: Re: Tapset for TCP
- References: <49BAAA75.50706@linux.vnet.ibm.com>
Em Fri, Mar 13, 2009 at 03:48:21PM -0300, Breno Leitao escreveu:
> 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:
You may want to take a look at:
http://git.kernel.org/?p=linux/kernel/git/acme/nettaps.git;a=tree;f=tapset
- Arnaldo
> 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
> }
> }