This is the mail archive of the systemtap@sourceware.org mailing list for the systemtap project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Tapset for TCP


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
> 	}
> }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]