http://blog.163.com/digoal@126/blog/static/16387704020131014104256627/
 
例子来自tcpdumplike.stp脚本, 当tcp.receive事件触发后, 取出类似tcpdump输出的源ip, 目的ip, 源端口, 目的端口, 以及6个tcp包的控制比特位信息.
tcp.receive alias实际上包含2个内核函数, 分别代表ipv4和ipv6. 
kernel.function("tcp_v4_rcv")
kernel.function("tcp_v6_rcv")!, module("ipv6").function("tcp_v6_rcv")
// !表示有限匹配kernel.function("tcp_v6_rcv"), 匹配后下面的module就不触发了.
 
脚本内容以及注解
[root@db-172-16-3-150 network]# cd /usr/share/systemtap/testsuite/systemtap.examples/network
[root@db-172-16-3-150 network]# cat tcpdumplike.stp
#!/usr/bin/stap
 
// A TCP dump like example
 
probe begin, timer.s(1) {
  printf("-----------------------------------------------------------------\n")
  printf("       Source IP         Dest IP  SPort  DPort  U  A  P  R  S  F \n")
  printf("-----------------------------------------------------------------\n")
}
// stap脚本开始, 并且以后每秒输出一次头信息. 方便阅读.
 
probe tcp.receive {
  printf(" %15s %15s  %5d  %5d  %d  %d  %d  %d  %d  %d\n",
         saddr, daddr, sport, dport, urg, ack, psh, rst, syn, fin)
}
// 跟踪tcp.receive事件, 事件出发时, 输出
// saddr 源IP
// daddr 目的IP
// sport 源端口
// dport 目的端口
// urg, ack, psh, rst syn, fin 6个tcp包的控制比特位信息
 
执行输出举例
[root@db-172-16-3-150 network]# stap ./tcpdumplike.stp 
-----------------------------------------------------------------
       Source IP         Dest IP  SPort  DPort  U  A  P  R  S  F 
-----------------------------------------------------------------
     172.16.8.31    172.16.3.150  51167     22  0  1  0  0  0  0
     172.16.8.31    172.16.3.150  54223     22  0  1  1  0  0  0
     172.16.8.31    172.16.3.150  54223     22  0  1  1  0  0  0
     172.16.8.31    172.16.3.150  54223     22  0  1  0  0  0  0
     172.16.8.31    172.16.3.150  51167     22  0  1  1  0  0  0
     172.16.3.40    172.16.3.150  51927   9000  0  0  0  0  1  0
最后一行的A=0, S=1, 表示这个包是从172.16.3.40发过来的建立三次握手的第一个包.
U=1的话, 表示重要的包, 接收到后不要放到缓冲区, 直接处理.
 
本文用到的tcp.receive probe alias原型.
/usr/share/systemtap/tapset/tcp.stp
/**
 * probe tcp.receive - Called when a TCP packet is received
 * @name: Name of the probe point
 * @iphdr: IP header address
 * @protocol: Packet protocol from driver
 * @family: IP address family
 * @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 = tcp.ipv4.receive, tcp.ipv6.receive
{
}
// tcp.receive包含ipv4和ipv6的alias.
 
probe tcp.ipv4.receive = kernel.function("tcp_v4_rcv")
{
        name = "tcp.ipv4.receive"
        iphdr = __get_skb_iphdr($skb)
        # If we're here, by definition we're doing AF_INET, not AF_INET6.
        family = %{ /* pure */ AF_INET %}
        saddr = format_ipaddr(__ip_skb_saddr(iphdr), %{ /* pure */ AF_INET %})
        daddr = format_ipaddr(__ip_skb_daddr(iphdr), %{ /* pure */ AF_INET %})
        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)
}
 
probe tcp.ipv6.receive = kernel.function("tcp_v6_rcv")!,
        module("ipv6").function("tcp_v6_rcv")
{
        name = "tcp.ipv6.receive"
        iphdr = __get_skb_iphdr(@defined($skb) ? $skb : kernel_pointer($pskb))
        # If we're here, by definition we're doing AF_INET6, not AF_INET.
        family = %{ /* pure */ AF_INET6 %}
        saddr = format_ipaddr(&@cast(iphdr, "ipv6hdr")->saddr,
                              %{ /* pure */ AF_INET6 %})
        daddr = format_ipaddr(&@cast(iphdr, "ipv6hdr")->daddr,
                              %{ /* pure */ AF_INET6 %})
        # If we're here, by definition we're doing IPPROTO_TCP.  There
        # isn't a protocol field in 'struct ipv6hdr'.  There is one in
        # 'struct sk_buff', but that protocol field is an Ethernet
        # Procol ID (ETH_P_*), not an IP protocol ID (IPPROTO_*).
        protocol = %{ /* pure */ IPPROTO_TCP %}
 
        tcphdr = __get_skb_tcphdr(@defined($skb) ? $skb : kernel_pointer($pskb))
        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)
}
// 一些tcp常用的函数
//
//Definitions of the TCP protocol sk_state field listed below.
//
//     TCP_ESTABLISHED = 1,   Normal data transfer
//     TCP_SYN_SENT   = 2,   App. has started to open a connection
//     TCP_SYN_RECV   = 3,   A connection request has arrived; wait for ACK
//     TCP_FIN_WAIT1  = 4,   App. has said it is finished
//     TCP_FIN_WAIT2  = 5,   The other side has agreed to close
//     TCP_TIME_WAIT  = 6,   Wait for all packets to die off
//     TCP_CLOSE      = 7,   No connection is active or pending 
//     TCP_CLOSE_WAIT = 8,   The other side has initiated a release
//     TCP_LAST_ACK   = 9,   Last ACK, wait for all packets to die off
//     TCP_LISTEN     = 10,  Waiting for incoming call
//     TCP_CLOSING    = 11,  Both sides have tried to close simultaneously
//     TCP_MAX_STATES = 12   Max states number
// 
function tcp_ts_get_info_state:long(sock:long)
%{ /* pure */
        struct sock *sk = (struct sock *)(long) STAP_ARG_sock;
        STAP_RETVALUE = (int64_t) kread(&(sk->sk_state));
        CATCH_DEREF_FAULT();
%}
 
/* return the TCP destination port for a given sock */
function __tcp_sock_dport:long (sock:long)
{
    return (@defined(@cast(sock, "inet_sock")->inet_dport)
            ? @cast(sock, "inet_sock")->inet_dport # kernel >= 2.6.33
            : (@defined(@cast(sock, "inet_sock")->dport)
               ? @cast(sock, "inet_sock", "kernel")->dport # kernel >= 2.6.11
               : @cast(sock, "inet_sock", "kernel<net/ip.h>")->inet->dport))
}
// 内嵌了C代码, 为了取出sock的值.
 
TCP 包头信息

TCP Header Format

    0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source Port | Destination Port |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Sequence Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Acknowledgment Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Data | |U|A|P|R|S|F| |
| Offset| Reserved |R|C|S|S|Y|I| Window |
| | |G|K|H|T|N|N| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Checksum | Urgent Pointer |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options | Padding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| data |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ TCP Header Format Note that one tick mark represents one bit position. Figure 3.
控制比特信息 : 

Control Bits: 6 bits (from left to right):

    URG:  Urgent Pointer field significant
ACK: Acknowledgment field significant
PSH: Push Function
RST: Reset the connection
SYN: Synchronize sequence numbers
FIN: No more data from sender
 
[参考]
1. /usr/share/systemtap/testsuite/systemtap.examples
3. systemtap-testsuite
5. /usr/share/systemtap/testsuite/systemtap.examples/index.txt
6. /usr/share/systemtap/testsuite/systemtap.examples/keyword-index.txt
7. /usr/share/systemtap/tapset

Systemtap examples, Network - 4 Monitoring TCP Packets的更多相关文章

  1. computer network layers architecture (TCP/IP)

    computer network layers architecture (TCP/IP) 计算机网络分层架构 TCP/IP 协议簇 OSI 模型(7 层) TCP/IP (4 层) Applicat ...

  2. Top 10 Free Wireless Network hacking/monitoring tools for ethical hackers and businesses

    There are lots of free tools available online to get easy access to the WiFi networks intended to he ...

  3. Language-Directed Hardware Design for Network Performance Monitoring——Marple

    网络监控困难 1.仅仅通过去增加特定的监控功能到交换机是不能满足运营商不断变化的需求的.(交换机需要支持网络性能问题的表达语言) 2.他们缺乏对网络深处的性能问题进行本地化的可见性,间接推断网络问题的 ...

  4. SystemTap Beginners Guide

    SystemTap 3.0 SystemTap Beginners Guide Introduction to SystemTap Edition 3.0   Red Hat, Inc. Don Do ...

  5. Network Load Balancing Technical Overview--reference

    http://technet.microsoft.com/en-us/library/bb742455.aspx Abstract Network Load Balancing, a clusteri ...

  6. TCP/UDP端口列表

    http://zh.wikipedia.org/wiki/TCP/UDP%E7%AB%AF%E5%8F%A3%E5%88%97%E8%A1%A8 TCP/UDP端口列表     本条目可通过翻译外语维 ...

  7. Monitoring and Tuning the Linux Networking Stack: Receiving Data

    http://blog.packagecloud.io/eng/2016/06/22/monitoring-tuning-linux-networking-stack-receiving-data/ ...

  8. How Network Load Balancing Technology Works--reference

    http://technet.microsoft.com/en-us/library/cc756878(v=ws.10).aspx In this section Network Load Balan ...

  9. 内核调试神器SystemTap — 简介与使用(一)

    a linux trace/probe tool. 官网:https://sourceware.org/systemtap/ 简介 SystemTap是我目前所知的最强大的内核调试工具,有些家伙甚至说 ...

随机推荐

  1. bzoj5138 [Usaco2017 Dec]Push a Box

    题目描述: bz luogu 题解: 暴力可以记录$AB$位置转移,这个时候状态是$n^4$的,无法接受. 考虑只记录$A$在$B$旁边时的状态,这个时候状态时$n^2$的. 所以说转移有两种,一种是 ...

  2. 离线功能对比:service worker和applicationCache

    SW 复杂,事件驱动,可以拦截请求,和缓存这些请求的响应数据,实现的效果更加灵活 AppCache 简单易用,声明式的将要缓存的文件清单声明在一个文件中.由于设计上的原因,它存在一些问题,导致难以运用 ...

  3. FIFO设计思考之一

    不管同步FIFO还是异步FIFO,设计难点是full/empty状态flag的正确性. 要保证任何情况 FULL时NO WRITE,EMPTY时NO READ.overflow / underflow ...

  4. PAT Basic 1044

    1044 火星数字 火星人是以 13 进制计数的: 地球人的 0 被火星人称为 tret. 地球人数字 1 到 12 的火星文分别为:jan, feb, mar, apr, may, jun, jly ...

  5. Python 输出命令行进度条

    在使用 pip 安装时,你会发现有下载进度条,我们也可以借助开源的第三方库来实现这个功能,在项目输出时增加一些可视化效果. 一个简单易用的第三方库是:progress 作者提供了动图很直观地展现了实现 ...

  6. vue 的 scroller 使用

    一 安装 使用npm 安装npm install vue-scroller -d 二 引入 import VueScroller from "vue-scroller" Vue.u ...

  7. 交换机VLAN的定义、意义以及划分方式

    什么是VLAN 虚拟网技术(VLAN,Virtual Local Area Network)的诞生主要源于广播.广播在网络中起着非常重要的作用,如发现新设备.调整网络路径.IP地址租赁等等,许多网络协 ...

  8. loj2141 「SHOI2017」期末考试

    我们枚举每一个时间点,使得所有科目的时间都小于等于这个时间点,计算安排老师的代价和学生们的不满意度更新答案. 但是枚举太慢了,可以发现,时间点越早,学生们不满意度越小,安排老师的代价越高.即安排老师的 ...

  9. HTTP/1.1协议支持的8种请求方法

    方法 说明 GET 获取资源 POST 传输实体主体 PUT 传输文件 DELETE 删除文件 HEAD 获得报文首部 OPTIONS 询问支持的方法 TRACE 追踪路径 CONNECT 要求用隧道 ...

  10. Leetcode 332.重新安排行程

    重新安排行程 给定一个机票的字符串二维数组[from, to],子数组中的两个成员分别表示飞机出发和降落的机场地点,对该行程进行重新规划排序.所有这些机票都属于一个从JFK(肯尼迪国际机场)出发的先生 ...