Linux抓包命令集锦

相信抓包是程序员,运维工程师,架构师,都必不可少的一项技能。但是能够深入掌握好这门技艺的人,确实需要有开发,网络,运维,架构等"跨界”背景才能比较好的发挥抓包神技的威力。本文是纯干货,重点不在于理论,更注重实战技能,尤其注重对抓包数据的分析。本文中的命令追求的是使用最简单,最普及的Linux系统自带工具包实现各种抓包分析,具有尽可能广泛的移植性和可用性。文中给出的命令均在Centos 6.3,tcpdump 4.1版本下测试可用;其他平台及环境,可能需要你自己微调部分命令及脚本才可以运行。文中多数命令及脚本都严重依赖于tcpdump命令输出文本数据格式,微调代码时应格外注意这一点。注意,本文中的命令适用于一般的基于tcp连接的,请求响应模型的网络服务,但不适用于使用pipeline模式的网络服务。如果想理解本文命令思路的话,需要你熟悉tcp/ip协议,网络osi模型,常见网络通讯协议,socket编程,linux脚本编程,awk脚本编程,数据挖掘思维方式等知识,不足者请自行脑补。理解本文的思路后,还可以在这些命令基础上有许多种灵活搭配和变种,请自行研究。不想费脑细胞的,运气好的话,很多命令都可以直接使用。尽管这里讲的是Linux抓包,但如果使用流行的wireshark在Windows上抓包后保存成tcpdump格式文件,然后上传到Linux系统上照样可以使用本文中的命令进行分析。

 

1.盲抓

        盲抓就是瞎抓,尤其在你接触到一台陌生机器,感觉有点抓瞎的时候,应当使用本节中的方法,其目的是找出这台机器上的重点网络服务是哪些ip和端口。如果你明确的知道要抓的包是哪个ip,哪个端口,可以直接跳至下一小节。

在目标机器上抓取任意tcp数据(需要root权限):

[plain] view plain copy

  1. tcpdump -i any -nn tcp > 123.pkg.head.txt  

分析目标机器上热点ip:port(按数据包数量统计):[plain] view plain copy

  1. cat 123.pkg.head.txt | awk 'NF>5 && $2=="IP" {print $3,"[out]"; print substr($5,1,length($5)-1), "[in]"}' | sort | uniq -c | awk '{buf[NR]=$0;sum+=$1} END{for(i=1;i<=NR;i++) print buf[i], sum}' | awk '{printf("%s %s %s %.2f %%\n",$1, $2, $3, 100*$1/$4)}' | sort -nr -k 4 | less  
  2. 示例:  
  3. 2359 10.71.28.21.80 [in] 23.59 %  
  4. 2057 10.71.28.21.80 [out] 20.57 %  
  5. 331 10.71.28.20.8080 [in] 3.31 %  
  6. 253 10.71.28.20.8080 [out] 2.53 %  
  7. 190 218.92.220.60.39147 [out] 1.90 %  
  8. 154 218.92.220.60.39147 [in] 1.54 %  
  9. 106 218.92.220.56.60503 [out] 1.06 %  

分析目标机器上热点ip:port(按字节数,即带宽统计):[plain] view plain copy

  1. cat 123.pkg.head.txt | awk 'BEGIN{header_len=0x36;inp=0;inb=0;inbb=0;outp=0;outb=0;outbb=0;start="";end=""} function getBodyLen(){if("length"==$(NF-1)) return $NF;t_c=split($7,a,/[()]/);if(3==t_c)return a[2];else return 0;} NF>5 && $2=="IP" {len=header_len + getBodyLen();print $3,"[out]", len; print substr($5,1,length($5)-1), "[in]", len; }' | sort | awk 'BEGIN{ipport="";dir="";bc=0} {if($1!=ipport || $2!=dir){if(bc>0)print ipport,dir,bc;ipport=$1;dir=$2;bc=$3;}else{bc+=$3;}} END{if(bc>0)print ipport,dir,bc;}' | awk '{buf[NR]=$0;sum+=$3} END{for(i=1;i<=NR;i++) print buf[i], sum}' | awk '{printf("%s %s %s %.2f %%\n",$1, $2, $3, 100*$3/$4)}' | sort -nr -k 4 | less  
  2. 示例:  
  3. 10.71.28.21.80 [out] 2559403 42.46 %  
  4. 218.92.220.60.39147 [in] 417277 6.92 %  
  5. 10.71.28.21.80 [in] 306507 5.08 %  
  6. 101.26.37.38.39906 [in] 271432 4.50 %  
  7. 122.225.28.115.48239 [in] 170901 2.84 %  
  8. 218.92.220.56.60503 [in] 151630 2.52 %  
  9. 218.92.220.62.59711 [in] 151322 2.51 %  
  10. 218.92.220.56.25777 [in] 138038 2.29 %  
  11. 60.210.23.239.7490 [in] 131700 2.18 %  
  12. 10.71.28.20.8080 [out] 121366 2.01 %  

分析数据流量概要信息(调整ipportRegex的值来控制统计口径):[plain] view plain copy

  1. cat 123.pkg.head.txt | awk 'BEGIN{ipportRegex="10.71.28.21.80";header_len=0x36;inp=0;inb=0;inbb=0;outp=0;outb=0;outbb=0;start="";end=""} function getBodyLen(){if("length"==$(NF-1)) return $NF;t_c=split($7,a,/[()]/);if(3==t_c)return a[2];else return 0;} $3~ipportRegex{outp++;bl=getBodyLen();outb+=header_len+bl;outbb+=bl;if(""==start)start=$1;end=$1;} $5~ipportRegex{inp++;bl=getBodyLen();inb+=header_len+bl;inbb+=bl;if(""==start)start=$1;end=$1;} function timeSub(s,e){split(substr(s,1,8),sA1,":");s1=sA1[1]*3600+sA1[2]*60+sA1[3];us1=substr(s,10);split(substr(e,1,8),sA2,":");s2=sA2[1]*3600+sA2[2]*60+sA2[3];us2=substr(e,10);return s2*1000000+us2-s1*1000000-us1;} END{second=timeSub(start,end)/1000000;if(second<1) second=1; printf("total time: %.1f seconds\n", second);printf("[In]  pkg count: %s, pkg rate: %.2f pkg/s, bytes count: %s, bytes rate: %.2f KB/s, body bytes: %s, body bytes rate: %.2f KB/s, payload percent: %.1f%%\n", inp,inp/second,inb,inb/second/1024,inbb,inbb/second/1024,100*inbb/inb);printf("[Out] pkg count: %s, pkg rate: %.2f pkg/s, bytes count: %s, bytes rate: %.2f KB/s, body bytes: %s, body bytes rate: %.2f KB/s, payload percent: %.1f%%\n", outp,outp/second,outb,outb/second/1024,outbb,outbb/second/1024,100*outbb/outb);}'  
  2. cat 123.pkg.head.txt | awk 'BEGIN{ipportRegex="10.71.28.21.";header_len=0x36;inp=0;inb=0;inbb=0;outp=0;outb=0;outbb=0;start="";end=""} function getBodyLen(){if("length"==$(NF-1)) return $NF;t_c=split($7,a,/[()]/);if(3==t_c)return a[2];else return 0;} $3~ipportRegex{outp++;bl=getBodyLen();outb+=header_len+bl;outbb+=bl;if(""==start)start=$1;end=$1;} $5~ipportRegex{inp++;bl=getBodyLen();inb+=header_len+bl;inbb+=bl;if(""==start)start=$1;end=$1;} function timeSub(s,e){split(substr(s,1,8),sA1,":");s1=sA1[1]*3600+sA1[2]*60+sA1[3];us1=substr(s,10);split(substr(e,1,8),sA2,":");s2=sA2[1]*3600+sA2[2]*60+sA2[3];us2=substr(e,10);return s2*1000000+us2-s1*1000000-us1;} END{second=timeSub(start,end)/1000000;if(second<1) second=1; printf("total time: %.1f seconds\n", second);printf("[In]  pkg count: %s, pkg rate: %.2f pkg/s, bytes count: %s, bytes rate: %.2f KB/s, body bytes: %s, body bytes rate: %.2f KB/s, payload percent: %.1f%%\n", inp,inp/second,inb,inb/second/1024,inbb,inbb/second/1024,100*inbb/inb);printf("[Out] pkg count: %s, pkg rate: %.2f pkg/s, bytes count: %s, bytes rate: %.2f KB/s, body bytes: %s, body bytes rate: %.2f KB/s, payload percent: %.1f%%\n", outp,outp/second,outb,outb/second/1024,outbb,outbb/second/1024,100*outbb/outb);}'  
  3. cat 123.pkg.head.txt | awk 'BEGIN{ipportRegex="10.";header_len=0x36;inp=0;inb=0;inbb=0;outp=0;outb=0;outbb=0;start="";end=""} function getBodyLen(){if("length"==$(NF-1)) return $NF;t_c=split($7,a,/[()]/);if(3==t_c)return a[2];else return 0;} $3~ipportRegex{outp++;bl=getBodyLen();outb+=header_len+bl;outbb+=bl;if(""==start)start=$1;end=$1;} $5~ipportRegex{inp++;bl=getBodyLen();inb+=header_len+bl;inbb+=bl;if(""==start)start=$1;end=$1;} function timeSub(s,e){split(substr(s,1,8),sA1,":");s1=sA1[1]*3600+sA1[2]*60+sA1[3];us1=substr(s,10);split(substr(e,1,8),sA2,":");s2=sA2[1]*3600+sA2[2]*60+sA2[3];us2=substr(e,10);return s2*1000000+us2-s1*1000000-us1;} END{second=timeSub(start,end)/1000000;if(second<1) second=1; printf("total time: %.1f seconds\n", second);printf("[In]  pkg count: %s, pkg rate: %.2f pkg/s, bytes count: %s, bytes rate: %.2f KB/s, body bytes: %s, body bytes rate: %.2f KB/s, payload percent: %.1f%%\n", inp,inp/second,inb,inb/second/1024,inbb,inbb/second/1024,100*inbb/inb);printf("[Out] pkg count: %s, pkg rate: %.2f pkg/s, bytes count: %s, bytes rate: %.2f KB/s, body bytes: %s, body bytes rate: %.2f KB/s, payload percent: %.1f%%\n", outp,outp/second,outb,outb/second/1024,outbb,outbb/second/1024,100*outbb/outb);}'  
  4. 示例:  
  5. total time: 45.7 seconds  
  6. [In]  pkg count: 2359, pkg rate: 51.59 pkg/s, bytes count: 306507, bytes rate: 6.55 KB/s, body bytes: 179121, body bytes rate: 3.83 KB/s, payload percent: 58.4%  
  7. [Out] pkg count: 2057, pkg rate: 44.99 pkg/s, bytes count: 2559403, bytes rate: 54.66 KB/s, body bytes: 2448325, body bytes rate: 52.29 KB/s, payload percent: 95.7%  

 

2.抓取源数据

        明确了要抓取的目标服务的ip和端口后,就要开始正式抓包了,这些抓包数据是后续分析工作的基础。当然,你可能在抓包之前还要做一些其他工作,以保证抓包时的工作场景就是你想要分析的目标场景。抓包时你需要root权限。

抓取不含包体的包:

[plain] view plain copy

  1. tcpdump -nn port 80 > 123.pkg.txt  

抓取含有包体的包并进行初步解包:[plain] view plain copy

  1. tcpdump port 80 -w 123.pkg -s 120  
  2. tcpdump port 80 -w 123.pkg -s 0  
  3. tcpdump -r 123.pkg -XXnn > 123.pkg.txt  
  4. 示例:  
  5. 11:12:01.894222 IP 10.64.12.14.59493 > 10.70.60.56.1521: Flags [P.], seq 3862499245:3862499262, ack 627056474, win 501, options [nop,nop,TS val 2916000715 ecr 736856730], length 17  
  6.         0x0000:  0000 0c07 ace9 0022 195d 2445 0800 4500  .......".]$E..E.  
  7.         0x0010:  0045 cb3b 4000 4006 12ac 0a40 0c0e 0a46  .E.;@.@....@...F  
  8.         0x0020:  3c38 e865 05f1 e639 0fad 2560 1f5a 8018  <8.e...9..%`.Z..  
  9.         0x0030:  01f5 5d03 0000 0101 080a adce a3cb 2beb  ..]...........+.  
  10.         0x0040:  8a9a 0011 0000 0600 0000 0000 0305 0001  ................  
  11.         0x0050:  0301 0a                                  ...  
  12. 11:12:01.894226 IP 10.64.12.14.59514 > 10.70.60.56.1521: Flags [P.], seq 3903163064:3903163580, ack 4171729186, win 501, options [nop,nop,TS val 2916000715 ecr 736856729], length 516  
  13.         0x0000:  0000 0c07 ace9 0022 195d 2445 0800 4500  .......".]$E..E.  
  14.         0x0010:  0238 f2e9 4000 4006 e90a 0a40 0c0e 0a46  .8..@.@....@...F  
  15.         0x0020:  3c38 e87a 05f1 e8a5 8ab8 f8a7 8922 8018  <8.z........."..  
  16.         0x0030:  01f5 5ef6 0000 0101 080a adce a3cb 2beb  ..^...........+.  
  17.         0x0040:  8a99 0204 0000 0600 0000 0000 1169 0001  .............i..  

 

3.过滤

       有时候,需要分析的问题是包含在抓取目标服务的全部数据包中的一小部分,这个时候就要对包数据进行过滤。当然也可以在上一节进行抓取时直接进行过滤,但这里主要满足事后的过滤需求。

过滤掉含有包体的数据文件,只保留数据包头:

[plain] view plain copy

  1. cat 123.pkg.txt | awk 'substr($1,1,3)!="0x0"' > 123.pkg.head.txt  
  2. 示例:  
  3. 11:12:01.894222 IP 10.64.12.14.59493 > 10.70.60.56.1521: Flags [P.], seq 3862499245:3862499262, ack 627056474, win 501, options [nop,nop,TS val 2916000715 ecr 736856730], length 17  
  4. 11:12:01.894226 IP 10.64.12.14.59514 > 10.70.60.56.1521: Flags [P.], seq 3903163064:3903163580, ack 4171729186, win 501, options [nop,nop,TS val 2916000715 ecr 736856729], length 516  
  5. 11:12:01.894228 IP 10.64.12.14.59518 > 10.70.60.56.1521: Flags [P.], seq 3897659932:3897660175, ack 3171500152, win 501, options [nop,nop,TS val 2916000715 ecr 736856729], length 243  
  6. 11:12:01.894231 IP 10.64.12.14.59512 > 10.70.60.56.1521: Flags [P.], seq 3898476274:3898476788, ack 1748466768, win 501, options [nop,nop,TS val 2916000715 ecr 736856730], length 514  

按时间段过滤含有包体的数据文件(调整start和end的值以改变时间范围):[plain] view plain copy

  1. cat 123.pkg.txt | awk 'BEGIN {start="11:13:49.0";end="11:13:49.9";flag=0} {if(substr($1,1,3)=="0x0"){if(1==flag){print $0}}else{cur=substr($1,1,length(start));if(cur>=start && cur<=end){print $0;flag=1}else{flag=0}}}' > new123.pkg.txt  

按ip端口过滤含有包体的数据文件(调整ip和port的值):[plain] view plain copy

  1. cat new123.pkg.txt | awk 'BEGIN {ip="192.168.122.180";port="54365";flag=0} {if(substr($1,1,3)=="0x0"){if(1==flag){print $0}}else if($0~ip"."port){print $0;flag=1;}else{flag=0;}}' > newnew123.pkg.txt  

按文本关键字过滤含有包体的数据文件(调整keyword的值):[plain] view plain copy

  1. cat newnew123.pkg.txt | awk 'BEGIN{keyword="id_10bc3c9";buf="";found=0} {if(substr($1,1,2)=="0x"){if($0~keyword) found=1;buf=buf"\n"$0}else{if(1==found){print buf;found=0;}if($0~keyword) found=1;buf=$0}} END{if(1==found) print buf}' > tmp.pkg.txt  

按二进制串关键字从二进制数据包中过滤含有包体的数据文件(性能稍低,对于大文件耐心等待;例子中是过滤包含"test_dava_11968@163.com"字符串的数据包):[plain] view plain copy

  1. cat newnew123.pkg.txt | awk 'BEGIN{keyword="746573745f646176615f3131393638403136332e636f6d";bin="";buf=""} {if(substr($1,1,2)=="0x"){for(i=2;i<NF;i++) bin=bin""$i;buf=buf"\n"$0}else{if(length(bin)>0&&bin~keyword) print buf;buf=$0;bin=""}} END{if(length(bin)>0&&bin~keyword) print buf}' > tmp2.pkg.txt  

 

4.分类

       通过分类,将抓包文件中混杂在一起的多个客户端的数据包拆分成各自单独的文件,以利于人工查看以及后续分析。新生成的文件放在当前目录下的子目录中,例如10.64.12.14.443_detail。

按client端ip端口将混杂在一起的含有包体的包拆分的单独文件:

[plain] view plain copy

  1. cat 123.pkg.txt | awk 'BEGIN{server="10.70.60.56.1521";buf="";client="";dir=server"_detail";system("mkdir "dir" 2>/dev/null")} {if(substr($1,1,2)=="0x"){buf=buf"\n"$0}else{if(length(client)>0) print buf>>dir"/"client".txt";if($3==server){client=substr($5,1,length($5)-1);}else if($5~server){client=$3}else{client=""} buf=$0}}'  

按client端ip端口将混杂在一起的含有包体的包拆分的单独文件(超过1000个client后因受同时打开文件数限制awk性能非常低,可增加dd命令的bs缓冲区大小,并使用limit参数进行限制):
[plain] view plain copy

  1. dd if=123.pkg.txt bs=100M 2>/dev/null | awk 'BEGIN{server="10.70.60.56.1521";limit=1000;buf="";client="";count=0;dir=server"_detail";system("mkdir "dir" 2>/dev/null")} {if(substr($1,1,2)=="0x"){if(length(client)>0) buf=buf"\n"$0}else{if(length(client)>0) print buf>>dir"/"client".txt";if($3==server){client=substr($5,1,length($5)-1)}else if($5~server){client=$3}else{client=""}if(length(client)>0){if("ok"==all_clients[client]){buf=$0}else if(count<limit){count++;all_clients[client]="ok";buf=$0}else{client=""}}}}'  

 

5.交互分析

       前面的分析处理仅限于数据包本身的ip和port,而本节的交互分析则将数据包归类到一个个具体的tcp连接之中,提取有关的交互“成本”数据,并尝试分析数据包在请求响应模型中的交互语义。本节中的命令需要系列awk脚本支持,为不影响理解本节主要内容,相关脚本源码附录在文章末尾供参考,其中包含主脚本parseTcp.awk,以及若干插件脚本:fixLenParser.awk,lineParser.awk,oracleSqlParser.awk,httpParser.awk。

分析单个不含包体的数据文件的交互过程:

[plain] view plain copy

  1. cat 123.pkg.txt | /data/speng/tcpdump/parseTcp.awk 61.135.169.125.80 > interaction.txt  

分析单个不含包体的数据文件中只与某特定客户端有关的交互过程:[plain] view plain copy

  1. cat 123.pkg.txt | /data/speng/tcpdump/parseTcp.awk 61.135.169.125.80 1 172.20.154.45.3752 > interaction.txt  
  2. 示例:  
  3. 14:00:53.123517 client 172.20.154.45.3752_2455096098 connect take(us): 3291 slient_before(us): 72266270 result: ok  
  4. 14:00:53.132710 client 172.20.154.45.3752_2455096098 round-trip 1 slient_before(us): 5902 total take(us): 5927 req_time(us): 76 req_bytes: 1635 server_process(us): 5402 response_time(us): 449 response_bytes: 6587  
  5. 14:00:53.263446 client 172.20.154.45.3752_2455096098 round-trip 2 slient_before(us): 124809 total take(us): 17767 req_time(us): 88 req_bytes: 1620 server_process(us): 17679 response_time(us): 0 response_bytes: 946  
  6. 14:00:53.472286 client 172.20.154.45.3752_2455096098 round-trip 3 slient_before(us): 191073 total take(us): 9319 req_time(us): 53 req_bytes: 1620 server_process(us): 8517 response_time(us): 749 response_bytes: 10361  
  7. 14:00:54.587117 client 172.20.154.45.3752_2455096098 round-trip 4 slient_before(us): 1105512 total take(us): 13233 req_time(us): 92 req_bytes: 1618 server_process(us): 13113 response_time(us): 28 response_bytes: 2777  
  8. 14:01:14.598513 client 172.20.154.45.3752_2455096098 close take(us): 589 slient_before(us): 19998163 close_bytes: 0 direction: server->client result: full_close  

分析多个分类后含有包体的数据文件的交互过程(cd进入上一节分类后所生成的目录下执行命令):
[plain] view plain copy

  1. ls | xargs -n 10 awk 'BEGIN{f=""} {if(FILENAME!=f){print "newfile",FILENAME;f=FILENAME}if(substr($1,1,2)!="0x") print $0}' | ../parseTcp.awk 10.70.60.56.1521 > ../interaction.txt  

分析多个分类后含有包体的数据文件的交互过程(cd进入分类后文件所在目录下执行命令。支持识别包体中的特征数据,并打印出来便于后续业务分析。可编写类似oracleSqlParser.awk或httpParser.awk插件脚本进行新协议或业务扩展。源码附录在文章末尾):[plain] view plain copy

  1. ls | xargs -n 10 awk -f ../oracleSqlParser.awk --source 'function getLen(){if("length"==$(NF-1)) return $NF;t_c=split($7,a,/[()]/);if(3==t_c) return a[2];else return 0;} BEGIN{f="";h="";b=0;} {if(FILENAME!=f){if(1==b)parserEnd();if(""!=h)print h;print "newfile",FILENAME;f=FILENAME;h="";b=0;}if(substr($1,1,2)=="0x"){if(1==b)parserWork();}else{if(1==b)parserEnd();b=0;if(""!=h)print h;h=$0;bl=getLen();if(bl>0){parserInit(bl);b=1;}}} END{if(1==b)parserEnd();if(""!=h)print h;}' | ../parseTcp.awk 10.70.60.56.1521 > ../interaction.txt  
  2. ls | xargs -n 10 awk -f ../httpParser.awk --source 'function getLen(){if("length"==$(NF-1)) return $NF;t_c=split($7,a,/[()]/);if(3==t_c) return a[2];else return 0;} BEGIN{f="";h="";b=0;} {if(FILENAME!=f){if(1==b)parserEnd();if(""!=h)print h;print "newfile",FILENAME;f=FILENAME;h="";b=0;}if(substr($1,1,2)=="0x"){if(1==b)parserWork();}else{if(1==b)parserEnd();b=0;if(""!=h)print h;h=$0;bl=getLen();if(bl>0){parserInit(bl);b=1;}}} END{if(1==b)parserEnd();if(""!=h)print h;}' | ../parseTcp.awk 10.70.66.120.80 > ../interaction.txt  
  3. 示例:  
  4. sql:  
  5. 11:12:29.422380 client 10.64.12.14.59573_3961647293 connect take(us): 567 slient_before(us): 0 result: ok  
  6. 11:12:29.423124 client 10.64.12.14.59573_3961647293 round-trip 1 slient_before(us): 177 total take(us): 54042 req_time(us): 0 req_bytes: 211 server_process(us): 54042 response_time(us): 0 response_bytes: 8  
  7. 11:12:29.478165 client 10.64.12.14.59573_3961647293 round-trip 2 slient_before(us): 999 total take(us): 2021 req_time(us): 1409 req_bytes: 363 server_process(us): 612 response_time(us): 0 response_bytes: 127  
  8. 11:12:29.480257 client 10.64.12.14.59573_3961647293 round-trip 3 slient_before(us): 71 total take(us): 1420 req_time(us): 0 req_bytes: 33 server_process(us): 1420 response_time(us): 0 response_bytes: 188  
  9. 11:12:29.481825 client 10.64.12.14.59573_3961647293 round-trip 4 slient_before(us): 148 total take(us): 1036 req_time(us): 0 req_bytes: 779 server_process(us): 1036 response_time(us): 0 response_bytes: 834  
  10. 11:12:29.483414 client 10.64.12.14.59573_3961647293 round-trip 5 slient_before(us): 553 total take(us): 3983 req_time(us): 810 req_bytes: 184 server_process(us): 3173 response_time(us): 0 response_bytes: 73  
  11. 11:12:29.487836 client 10.64.12.14.59573_3961647293 round-trip 6 slient_before(us): 439 total take(us): 4891 req_time(us): 0 req_bytes: 574 server_process(us): 4891 response_time(us): 0 response_bytes: 1180  
  12. 11:12:29.492988 client 10.64.12.14.59573_3961647293 round-trip 7 slient_before(us): 261 total take(us): 3220 req_time(us): 0 req_bytes: 505 server_process(us): 3220 response_time(us): 0 response_bytes: 358  
  13. 11:12:29.496568 client 10.64.12.14.59573_3961647293 round-trip 8 slient_before(us): 360 total take(us): 2276 req_time(us): 0 req_bytes: 245 server_process(us): 2276 response_time(us): 0 response_bytes: 393 req_appflag: select.usrid,mailadd,mailflg,mobile,verifyflg,user_seq_id,is_oauth_type,lastlogin,pwd_strict.from.tab_users.where.mailadd.=:1--con_id_52d2c4  
  14. 11:12:29.499283 client 10.64.12.14.59573_3961647293 round-trip 9 slient_before(us): 439 total take(us): 704 req_time(us): 0 req_bytes: 17 server_process(us): 704 response_time(us): 0 response_bytes: 208  
  15. 11:12:29.500267 client 10.64.12.14.59573_3961647293 round-trip 10 slient_before(us): 280 total take(us): 766 req_time(us): 0 req_bytes: 245 server_process(us): 766 response_time(us): 0 response_bytes: 393 req_appflag: select.usrid,mailadd,mailflg,mobile,verifyflg,user_seq_id,is_oauth_type,lastlogin,pwd_strict.from.tab_users.where.mailadd.=:1--con_id_52d2c4  
  16. 11:12:29.501945 client 10.64.12.14.59573_3961647293 round-trip 11 slient_before(us): 912 total take(us): 681 req_time(us): 0 req_bytes: 17 server_process(us): 681 response_time(us): 0 response_bytes: 208  
  17. 11:12:29.503286 client 10.64.12.14.59573_3961647293 round-trip 12 slient_before(us): 660 total take(us): 4956 req_time(us): 0 req_bytes: 513 server_process(us): 4956 response_time(us): 0 response_bytes: 64 req_appflag: update.tab_users.tu.set.tu.lastlogin_third=tu.lastlogin,tu.lastlogin=to_date(:1,'yyyy-mm-dd.hh24:mi:ss'),tu.uct_time=to_date(:2,'yyyy-mm-dd.hh24:mi:ss'),tu.uct=:3,tu.auto_login_flag=:4,login_ip=:5.where.mailadd.=:6--con_id_52d2c4  
  18. 11:12:29.510362 client 10.64.12.14.59573_3961647293 round-trip 13 slient_before(us): 2120 total take(us): 3591 req_time(us): 0 req_bytes: 515 server_process(us): 3591 response_time(us): 0 response_bytes: 63 req_appflag: update.tab_users.tu.set.tu.lastlogin_third=tu.lastlogin,tu.lastlogin=to_date(:1,'yyyy-mm-dd.hh24:mi:ss'),tu.uct_time=to_date(:2,'yyyy-mm-dd.hh24:mi:ss'),tu.uct=:3,tu.auto_login_flag=:4,login_ip=:5.where.mailadd.=:6--con_id_52d2c4  
  19. 11:12:29.515085 client 10.64.12.14.59573_3961647293 round-trip 14 slient_before(us): 1132 total take(us): 3660 req_time(us): 0 req_bytes: 513 server_process(us): 3660 response_time(us): 0 response_bytes: 63 req_appflag: update.tab_users.tu.set.tu.lastlogin_third=tu.lastlogin,tu.lastlogin=to_date(:1,'yyyy-mm-dd.hh24:mi:ss'),tu.uct_time=to_date(:2,'yyyy-mm-dd.hh24:mi:ss'),tu.uct=:3,tu.auto_login_flag=:4,login_ip=:5.where.mailadd.=:6--con_id_52d2c4  
  20. 11:12:29.518969 client 10.64.12.14.59573_3961647293 round-trip 15 slient_before(us): 224 total take(us): 724 req_time(us): 0 req_bytes: 245 server_process(us): 724 response_time(us): 0 response_bytes: 392 req_appflag: select.usrid,mailadd,mailflg,mobile,verifyflg,user_seq_id,is_oauth_type,lastlogin,pwd_strict.from.tab_users.where.mailadd.=:1--con_id_52d2c4  
  21. 11:12:29.519737 client 10.64.12.14.59573_3961647293 round-trip 16 slient_before(us): 44 total take(us): 664 req_time(us): 0 req_bytes: 17 server_process(us): 664 response_time(us): 0 response_bytes: 208  
  22. 11:12:29.522030 client 10.64.12.14.59573_3961647293 round-trip 17 slient_before(us): 1629 total take(us): 4037 req_time(us): 0 req_bytes: 513 server_process(us): 4037 response_time(us): 0 response_bytes: 63 req_appflag: update.tab_users.tu.set.tu.lastlogin_third=tu.lastlogin,tu.lastlogin=to_date(:1,'yyyy-mm-dd.hh24:mi:ss'),tu.uct_time=to_date(:2,'yyyy-mm-dd.hh24:mi:ss'),tu.uct=:3,tu.auto_login_flag=:4,login_ip=:5.where.mailadd.=:6--con_id_52d2c4  
  23. 11:12:29.526610 client 10.64.12.14.59573_3961647293 round-trip 18 slient_before(us): 543 total take(us): 709 req_time(us): 0 req_bytes: 245 server_process(us): 709 response_time(us): 0 response_bytes: 392 req_appflag: select.usrid,mailadd,mailflg,mobile,verifyflg,user_seq_id,is_oauth_type,lastlogin,pwd_strict.from.tab_users.where.mailadd.=:1--con_id_52d2c4  
  24. 11:12:29.527617 client 10.64.12.14.59573_3961647293 round-trip 19 slient_before(us): 298 total take(us): 1490 req_time(us): 0 req_bytes: 17 server_process(us): 1490 response_time(us): 0 response_bytes: 208   
  25.   
  26. http:  
  27. 14:00:53.123517 client 172.20.154.45.3752_2455096098 connect take(us): 3291 slient_before(us): 72266270 result: ok  
  28. 14:00:53.132710 client 172.20.154.45.3752_2455096098 round-trip 1 slient_before(us): 5902 total take(us): 5927 req_time(us): 76 req_bytes: 1635 server_process(us): 5402 response_time(us): 449 response_bytes: 6587 req_appflag: GET./static/api/js/share.js?v=89860593.js?cdnversion=403517 response_appflag: 200.OK  
  29. 14:00:53.263446 client 172.20.154.45.3752_2455096098 round-trip 2 slient_before(us): 124809 total take(us): 17767 req_time(us): 88 req_bytes: 1620 server_process(us): 17679 response_time(us): 0 response_bytes: 946 req_appflag: GET./static/js/shell_v2.js?cdnversion=403519 response_appflag: 200.OK  
  30. 14:00:53.472286 client 172.20.154.45.3752_2455096098 round-trip 3 slient_before(us): 191073 total take(us): 9319 req_time(us): 53 req_bytes: 1620 server_process(us): 8517 response_time(us): 749 response_bytes: 10361 req_appflag: GET./static/js/bds_s_v2.js?cdnversion=403519 response_appflag: 200.OK  
  31. 14:00:54.587117 client 172.20.154.45.3752_2455096098 round-trip 4 slient_before(us): 1105512 total take(us): 13233 req_time(us): 92 req_bytes: 1618 server_process(us): 13113 response_time(us): 28 response_bytes: 2777 req_appflag: GET./static/js/logger.js?cdnversion=403519 response_appflag: 200.OK  
  32. 14:01:14.598513 client 172.20.154.45.3752_2455096098 close take(us): 589 slient_before(us): 19998163 close_bytes: 0 direction: server->client result: full_close  
  33.   
  34. https:  
  35. 16:53:29.658744 client 10.64.12.16.32769_169947140 connect take(us): 89 slient_before(us): 0 result: ok  
  36. 16:53:29.658857 client 10.64.12.16.32769_169947140 round-trip 1 slient_before(us): 24 total take(us): 6865 req_time(us): 0 req_bytes: 117 server_process(us): 1535 response_time(us): 5330 response_bytes: 5140  
  37. 16:53:29.670379 client 10.64.12.16.32769_169947140 round-trip 2 slient_before(us): 4657 total take(us): 6071 req_time(us): 0 req_bytes: 198 server_process(us): 6071 response_time(us): 0 response_bytes: 59  
  38. 16:53:29.676530 client 10.64.12.16.32769_169947140 round-trip 3 slient_before(us): 80 total take(us): 983303 req_time(us): 0 req_bytes: 133 server_process(us): 983303 response_time(us): 0 response_bytes: 842  
  39. 16:53:30.659883 client 10.64.12.16.32769_169947140 close take(us): 4412 slient_before(us): 50 close_bytes: 37 direction: server->client result: full_close  
  40. 16:54:39.540752 client 10.64.12.16.32769_239829149 connect take(us): 91 slient_before(us): 68876457 result: ok  
  41. 16:54:39.540866 client 10.64.12.16.32769_239829149 round-trip 1 slient_before(us): 23 total take(us): 7459 req_time(us): 0 req_bytes: 117 server_process(us): 2127 response_time(us): 5332 response_bytes: 5140  
  42. 16:54:39.552971 client 10.64.12.16.32769_239829149 round-trip 2 slient_before(us): 4646 total take(us): 5452 req_time(us): 0 req_bytes: 198 server_process(us): 5452 response_time(us): 0 response_bytes: 59  
  43. 16:54:39.558487 client 10.64.12.16.32769_239829149 round-trip 3 slient_before(us): 64 total take(us): 965470 req_time(us): 0 req_bytes: 133 server_process(us): 965470 response_time(us): 0 response_bytes: 842  
  44. 16:54:40.524004 client 10.64.12.16.32769_239829149 close take(us): 115 slient_before(us): 47 close_bytes: 37 direction: server->client result: full_close  


 

6.统计分析

        统计分析用于掌握一批数据包反映的整体交互规律和指标数据。配合使用上一节交互分析中获得的业务关键字过滤,还可以分析具有某些特定特征的交互指标数据。

分析多行模式输出的交互过程的请求响应对的平均响应时间(含请求响应的网络传输时间,但不含socket建立阶段):

[plain] view plain copy

  1. cat interaction.txt | grep round-trip | awk '{sum+=($10/1000000)} END {print "Lines = "NR", Sum = "sum"(seconds), Average = "sum/NR"(seconds)"}'   
  2. 示例:  
  3. Lines = 678796, Sum = 4234.81(seconds), Average = 0.00623871(seconds)  

分析多行模式输出的交互过程的请求响应对的服务器平均处理时间:[plain] view plain copy

  1. cat interaction.txt | grep round-trip | awk '{sum+=($16/1000000)} END {print "Lines = "NR", Sum = "sum"(seconds), Average = "sum/NR"(seconds)"}'  
  2. 示例:  
  3. Lines = 678796, Sum = 1612.32(seconds), Average = 0.00237526(seconds)  

分析多行模式输出的交互过程的请求响应对的平均请求大小:[plain] view plain copy

  1. cat interaction.txt | grep round-trip | awk '{sum+=$14} END {print "Lines = "NR", Sum = "sum"(bytes), Average = "sum/NR"(bytes)"}'  

分析多行模式输出的交互过程的请求响应对的平均响应大小:[plain] view plain copy

  1. cat interaction.txt | grep round-trip | awk '{sum+=$20} END {print "Lines = "NR", Sum = "sum"(bytes), Average = "sum/NR"(bytes)"}'  

分析某多行模式输出的https短连接交互过程的ssl握手阶段的平均处理时间:[plain] view plain copy

  1. cat interaction.txt | grep round-trip | awk '$5==1 {start=$1;r1_time=$10} $5==2 {slient=$7;r2_time=$10;print start, r1_time+slient+r2_time}' | awk '{sum+=($2/1000000)} END {print "Lines = "NR", Sum = "sum"(seconds), Average = "sum/NR"(seconds)"}'  
  2. 示例:  
  3. Lines = 284861, Sum = 12216.7(seconds), Average = 0.0428866(seconds)  

分析某多行模式输出的https短连接交互过程的ssl握手阶段的tps及每秒平均处理时间(可导入excel作图):[plain] view plain copy

  1. cat interaction.txt | grep round-trip | awk '$5==1 {start=$1;r1_time=$10} $5==2 {slient=$7;r2_time=$10;print start, r1_time+slient+r2_time}' | sort | awk '{print $2,$1}' | awk -F '.' '{print $1}' | awk 'BEGIN{sum=0;count=0;time=""} {if($2!=time){if(count>0) print time,count,sum/count/1000000;sum=$1;count=1;time=$2}else{sum+=$1;count++}} END{if(count>0) print time,count,sum/count/1000000}'  

上例做图如下:

分析某多行模式输出的https短连接交互过程的socket建立完成至服务器accept此连接经历的平均等待时间(可导入excel作图):

[plain] view plain copy

  1. cat interaction.txt | grep "round-trip 1 " | awk '{print $1,$7}' | sort | awk '{print $2,$1}' | awk -F '.' '{print $1}' | awk 'BEGIN{sum=0;count=0;time=""} {if($2!=time){if(count>0) printf("%s %s %.6f\n", time,count,sum/count/1000000);sum=$1;count=1;time=$2}else{sum+=$1;count++}} END{if(count>0) printf("%s %s %.6f\n", time,count,sum/count/1000000)}'  

分析某多行模式输出含有包体特征数据的oracle长连接交互过程中select语句及update语句的平均响应时间:[plain] view plain copy

  1. cat interaction.txt | grep select | awk '{sum+=($10/1000000)} END {print "Lines = "NR", Sum = "sum"(seconds), Average = "sum/NR"(seconds)"}'  
  2. cat interaction.txt | grep update | awk '{sum+=($10/1000000)} END {print "Lines = "NR", Sum = "sum"(seconds), Average = "sum/NR"(seconds)"}'  



 

附录:

parseTcp.awk源码(文件需有可执行权限):

[plain] view plain copy

  1. #!/bin/awk -f  
  2.   
  3. BEGIN \  
  4. {  
  5.   if(ARGC<2)  
  6.   {  
  7.     printf("Usage:\n");  
  8.     printf("      ./parseTcp.awk <server ip port> [<print in multi line, 0 or 1, default to 1> [client ip port]]\n");  
  9.     printf("Example:\n");  
  10.     printf("      cat ./pkg.txt | ./parseTcp.awk 10.64.12.14.443 1 10.64.12.16.60990\n");  
  11.     exit;  
  12.   }  
  13.   server=ARGV[1];  
  14.   multi_line=1;  
  15.   if(ARGC>2)  
  16.     multi_line=ARGV[2];  
  17.   default_client="";  
  18.   if(ARGC>3)  
  19.      default_client=ARGV[3];  
  20.   max_close_wait=240000000;  
  21.   max_connect_wait=max_close_wait;  
  22.   isn=0;  
  23.   need_newline=0;  
  24.   ARGC=1;  # don't delete this line!  
  25. }  
  26.   
  27. function checkflag(flag)  
  28. {  
  29.   pkgFlag=$6;  
  30.   if("Flags"==pkgFlag)  
  31.     pkgFlag=$7;  
  32.   if(pkgFlag~flag)  
  33.     return 1;  
  34.   else  
  35.     return 0  
  36. }  
  37.   
  38. function getBodyLen()  
  39. {  
  40.   if("length"==$(NF-1)) return $NF;  
  41.   count=split($7,a,/[()]/);  
  42.   if(3==count)  
  43.     return a[2];  
  44.   else  
  45.     return 0;  
  46. }  
  47.   
  48. function getTcpISN()  
  49. {  
  50.   if("seq"==$8)  
  51.     return substr($9,1,length($9)-1);  
  52.   count=split($7,a,":");  
  53.   if(2==count)  
  54.     return a[1];  
  55.   else  
  56.     return 0;  
  57. }  
  58.   
  59. function timeSub(start,end)  
  60. {  
  61.   split(substr(start,1,8),sA1,":");  
  62.   s1=sA1[1]*3600+sA1[2]*60+sA1[3];  
  63.   us1=substr(start,10);  
  64.   split(substr(end,1,8),sA2,":");  
  65.   s2=sA2[1]*3600+sA2[2]*60+sA2[3];  
  66.   us2=substr(end,10);  
  67.   return s2*1000000+us2-s1*1000000-us1;  
  68. }  
  69.   
  70. function printConnectInfo()  
  71. {  
  72.   if(1==connect_reset)  
  73.     connect_result="reset_by_server";  
  74.   else if(1==connect_timeout)  
  75.     connect_result="timeout";  
  76.   else  
  77.     connect_result="ok";  
  78.   printf("%s client %s_%s connect take(us): %s slient_before(us): %s result: %s",connect_start, client, isn, timeSub(connect_start,$1), slient_time, connect_result);  
  79.   need_newline=1;  
  80.   if("ok"!=connect_result)  
  81.   {  
  82.     printf("\n");  
  83.     need_newline=0;  
  84.   }  
  85. }  
  86.   
  87. function printRoundInfo()  
  88. {  
  89.   if(1==multi_line){printf("\n")}else{printf(" || ")}  
  90.   printf("%s client %s_%s round-trip %d slient_before(us): %s total take(us): %s req_time(us): %s req_bytes: %s server_process(us): %s response_time(us): %s response_bytes: %s",req_start, client, isn, round, slient_time, timeSub(req_start,response_end), timeSub(req_start,req_end), req_len, server_process, timeSub(response_start,response_end), response_len);  
  91.   if(""!=req_appflag)  
  92.     printf(" req_appflag: %s",req_appflag);  
  93.   if(""!=response_appflag)  
  94.     printf(" response_appflag: %s",response_appflag);  
  95.   need_newline=1;  
  96. }  
  97.   
  98. function printCloseInfo()  
  99. {  
  100.   if(1==server_close)  
  101.     direction="server->client";  
  102.   else  
  103.     direction="client->server";  
  104.   if(1==close_timeout)  
  105.     close_result="close_timeout";  
  106.   else if(2==client_close || 2==server_close)  
  107.     close_result="full_close";  
  108.   else  
  109.     close_result="half_close";  
  110.   if(1==multi_line){printf("\n")}else{printf(" || ")}  
  111.   printf("%s client %s_%s close take(us): %s slient_before(us): %s close_bytes: %s direction: %s result: %s\n", close_start, client, isn, timeSub(close_start,close_end), close_slient_time, close_bytes, direction, close_result);  
  112.   need_newline=0;  
  113. }  
  114.   
  115. function printResetInfo()  
  116. {  
  117.   if(1==multi_line){printf("\n")}else{printf(" || ")};  
  118.   if($3==server)  
  119.     resetPeer="server";  
  120.   else  
  121.     resetPeer="client";  
  122.   printf("%s client %s_%s reset connect by %s\n", $1, client, isn, resetPeer);  
  123.   need_newline=0;  
  124. }  
  125.   
  126. function onNewConnect()  
  127. {  
  128.   client=$3;  
  129.   isn=getTcpISN();  
  130.   slient_time=timeSub(slient_start,$1);  
  131.   connect_start=$1;  
  132.   connect_timeout=0;  
  133.   connect_reset=0;  
  134.   prepareClose();  
  135. }  
  136.   
  137. function onFirstRoundTrip()  
  138. {  
  139.   req_start="";  
  140.   round=0;  
  141. }  
  142.   
  143. function onNewRequest()  
  144. {  
  145.   req_start=$1;  
  146.   req_end=$1;  
  147.   req_len=bodyLen;  
  148.   round++;  
  149.   slient_time=timeSub(slient_start,$1);  
  150.   process_start=$1;  
  151.   req_appflag=last_appflag;  
  152. }  
  153.   
  154. function mergeRequest()  
  155. {  
  156.   req_end=$1;  
  157.   req_len+=bodyLen;  
  158.   process_start=$1;  
  159.   if(""!=last_appflag)  
  160.     req_appflag=last_appflag;  
  161. }  
  162.   
  163. function onNewResponse()  
  164. {  
  165.   response_start=$1;  
  166.   response_end=$1;  
  167.   response_len=bodyLen;  
  168.   server_process=timeSub(req_end,$1);  
  169.   slient_start=$1;  
  170.   response_appflag=last_appflag;  
  171. }  
  172.   
  173. function mergeResponse()  
  174. {  
  175.   response_end=$1;  
  176.   response_len+=bodyLen;  
  177.   slient_start=$1;  
  178.   if(""!=last_appflag)  
  179.     response_appflag=last_appflag;  
  180. }  
  181.   
  182. function prepareClose()  
  183. {  
  184.   close_start="";  
  185.   close_end="";  
  186.   close_bytes=0;  
  187.   close_timeout=0;  
  188.   client_close=0;  
  189.   server_close=0;  
  190.   close_slient_time=0;  
  191. }  
  192.   
  193. function checkCloseState()  
  194. {  
  195.   if(""==close_start)  
  196.   {  
  197.     if(1==checkflag("F") && ($3==client || $5==client":"))  
  198.     {  
  199.       close_start=$1;  
  200.       close_end=$1;  
  201.       if($3==server)  
  202.         server_close=1;  
  203.       else  
  204.         client_close=1;  
  205.       close_slient_time=timeSub(slient_start,$1);  
  206.       close_bytes+=bodyLen;  
  207.       return 1;  
  208.     }  
  209.     else  
  210.       return 0;  
  211.   }  
  212.   
  213.   if(timeSub(close_start,$1)>=max_close_wait)  
  214.   {  
  215.     close_end=$1;  
  216.     close_timeout=1;  
  217.     return 3;  
  218.   }  
  219.   
  220.   if($3==client || $5==client":")  
  221.   {  
  222.     close_bytes+=bodyLen;  
  223.     close_end=$1;  
  224.     if(1==checkflag("F"))  
  225.     {  
  226.       if($3==server && 1==client_close)  
  227.       {  
  228.         server_close=2;  
  229.         return 2;  
  230.       }  
  231.       else if($3==client && 1==server_close)  
  232.       {  
  233.         client_close=2;  
  234.         return 2;  
  235.       }  
  236.     }  
  237.   }  
  238.   
  239.   return 1;  
  240. }  
  241.   
  242. {  
  243.   last_appflag="";  
  244.   if("app_flag"==$1)  
  245.   {  
  246.     last_appflag=substr($0,length($1) + length(FS) + 1);  
  247.     getline;  
  248.   }  
  249.   
  250.   if("newfile"==$1)  
  251.   {  
  252.     if("response"==state)  
  253.       printRoundInfo();  
  254.     if(""!=close_start)  
  255.       printCloseInfo();  
  256.     if(1==need_newline)  
  257.       printf("\n");  
  258.     need_newline=0;  
  259.     isn=0;  
  260.     slient_start="";  
  261.     state="";  
  262.     next  
  263.   }  
  264.   
  265.   if(""==slient_start)  
  266.     slient_start=$1;  
  267.   
  268.   if($3!=server && $5!=server":")  
  269.     next;  
  270.   if(""!=default_client && $3!=default_client && $5!=default_client":")  
  271.     next;  
  272.   
  273.   bodyLen=getBodyLen();  
  274.     
  275.   if(""==state)  
  276.   {  
  277.     if($5!=server":")  
  278.       next;  
  279.     if(1==checkflag("S"))  
  280.       state="listen";  
  281.     else if(bodyLen>0)  
  282.     {  
  283.       client=$3;  
  284.       onFirstRoundTrip();  
  285.       prepareClose();  
  286.       state="request";  
  287.     }  
  288.     else  
  289.       next;  
  290.   }  
  291.   
  292.   if("listen"==state)  
  293.   {  
  294.     if($5==server":" && 1==checkflag("S"))  
  295.     {  
  296.       onNewConnect();  
  297.       slient_start=$1;  
  298.       state="syn_recv";  
  299.     }  
  300.   }  
  301.   else if("syn_recv"==state)  
  302.   {  
  303.     if(timeSub(connect_start,$1)>=max_connect_wait)  
  304.     {  
  305.       connect_timeout=1;  
  306.       printConnectInfo();  
  307.       slient_start=$1;  
  308.       state="listen";  
  309.     }  
  310.     else if($5==client":")  
  311.     {  
  312.       if(1==checkflag("S"))  
  313.         state="syn_ack";  
  314.       else if(1==checkflag("R"))  
  315.       {  
  316.         connect_reset=1;  
  317.         printConnectInfo();  
  318.         slient_start=$1;  
  319.         state="listen";  
  320.       }  
  321.     }  
  322.     else if($5==server":" && 1==checkflag("S"))  
  323.     {  
  324.       onNewConnect();  
  325.       slient_start=$1;  
  326.       state="syn_recv";  
  327.     }  
  328.   }  
  329.   else if("syn_ack"==state)  
  330.   {  
  331.     if(timeSub(connect_start,$1)>=max_connect_wait)  
  332.     {  
  333.       connect_timeout=1;  
  334.       printConnectInfo();  
  335.       slient_start=$1;  
  336.       state="";  
  337.     }  
  338.     else if(0==checkflag("R") && 0==checkflag("S") && $3==client)  
  339.     {  
  340.       printConnectInfo();  
  341.       onFirstRoundTrip();  
  342.       slient_start=$1;  
  343.       state="request";  
  344.     }  
  345.     else if(1==checkflag("R") && ($3==client || $5==client":"))  
  346.     {  
  347.       connect_reset=1;  
  348.       printConnectInfo();  
  349.       slient_start=$1;  
  350.       state="listen";  
  351.     }  
  352.   }  
  353.   else if("request"==state)  
  354.   {  
  355.     if(bodyLen>0)  
  356.     {  
  357.       if($3==client)  
  358.       {  
  359.         if(""==req_start)  
  360.           onNewRequest();  
  361.         else  
  362.           mergeRequest();  
  363.         if(checkCloseState()>1)  
  364.         {  
  365.           printCloseInfo();  
  366.           close_start="";            
  367.           state="listen";  
  368.         }  
  369.         slient_start=$1;  
  370.       }  
  371.       else if($5==client":")  
  372.       {  
  373.         onNewResponse();  
  374.         if(checkCloseState()>1)  
  375.         {  
  376.           printRoundInfo();  
  377.           printCloseInfo();  
  378.           close_start="";  
  379.           state="listen";  
  380.         }  
  381.         else  
  382.           state="response";  
  383.         slient_start=$1;  
  384.       }  
  385.     }  
  386.     else if(checkCloseState()>1)  
  387.     {  
  388.       printCloseInfo();  
  389.       close_start="";  
  390.       slient_start=$1;  
  391.       state="listen";  
  392.     }  
  393.     else if(1==checkflag("R") && ($3==client || $5==client":"))  
  394.     {  
  395.       printResetInfo();  
  396.       slient_start=$1;  
  397.       state="listen";  
  398.     }  
  399.   }  
  400.   else if("response"==state)  
  401.   {  
  402.     if(bodyLen>0)  
  403.     {  
  404.       if($5==client":")  
  405.       {  
  406.         mergeResponse();  
  407.         if(checkCloseState()>1)  
  408.         {  
  409.           printRoundInfo();  
  410.           printCloseInfo();  
  411.           close_start="";  
  412.           state="listen";  
  413.         }  
  414.         slient_start=$1;  
  415.       }  
  416.       else if($3==client)  
  417.       {  
  418.         printRoundInfo();  
  419.         if(checkCloseState()>1)  
  420.         {  
  421.           printCloseInfo();  
  422.           close_start="";  
  423.           state="listen";  
  424.         }  
  425.         else  
  426.         {  
  427.           onNewRequest();  
  428.           state="request";  
  429.         }  
  430.         slient_start=$1;  
  431.       }  
  432.     }  
  433.     else if(checkCloseState()>1)  
  434.     {  
  435.       printRoundInfo();  
  436.       printCloseInfo();  
  437.       close_start="";  
  438.       slient_start=$1;  
  439.       state="listen";  
  440.     }  
  441.     else if(1==checkflag("R") && ($3==client || $5==client":"))  
  442.     {  
  443.       printRoundInfo();  
  444.       printResetInfo();  
  445.       slient_start=$1;  
  446.       state="listen";  
  447.     }  
  448.   }  
  449. }  
  450.   
  451. END { \  
  452.   if("response"==state)  
  453.     printRoundInfo();  
  454.   if(""!=close_start)  
  455.     printCloseInfo();  
  456.   if(1==need_newline)  
  457.     printf("\n");  
  458. }  

 

fixLenParser.awk源码(这是一个插件,不可独立运行):

[plain] view plain copy

  1. function getHeaderBinLen()  
  2. {  
  3.   #check min length of (Ethernet + IP + TCP) packet header  
  4.   if(length(bin) < 108)  
  5.     return 0;  
  6.   if("08004" == substr(bin,25,5))  
  7.     ethernetHeaderLen=28;  
  8.   else if("08004" == substr(bin,29,5))  
  9.     ethernetHeaderLen=32;  
  10.   else  
  11.   {  
  12.     #unknown ethernet frame packet  
  13.     return -1;  
  14.   }  
  15.   ipHeaderLen = 8 * substr(bin,ethernetHeaderLen+2,1);  
  16.   tcpHeaderLen = 8 * substr(bin,ethernetHeaderLen+ipHeaderLen+25,1);  
  17.   return ethernetHeaderLen + ipHeaderLen + tcpHeaderLen;  
  18. }  
  19.   
  20. function parserInit(pkgBodyLen)  
  21. {  
  22.   maxLen=100;  
  23.   bin="";  
  24.   text="";  
  25.   pkgHeaderBinLen=0;  
  26.   ignore=0;  
  27. }  
  28.   
  29. function parserWork()  
  30. {  
  31.   if(1 == ignore)  
  32.     return;  
  33.   
  34.   for(field=2; field < NF; field++)  
  35.     bin=bin""$field;  
  36.   text=text""$NF;  
  37.     
  38.   if(pkgHeaderBinLen <= 0)  
  39.   {  
  40.     pkgHeaderBinLen=getHeaderBinLen();  
  41.     #print "pkgHeaderBinLen:", pkgHeaderBinLen  
  42.     if(-1 == pkgHeaderBinLen)  
  43.       ignore=1;  
  44.     if(pkgHeaderBinLen <= 0)  
  45.       return;  
  46.   }  
  47.   
  48.   if(length(text) >= pkgHeaderBinLen/2 + maxLen)  
  49.   {  
  50.     print "app_flag", substr(text,pkgHeaderBinLen/2+1, maxLen);  
  51.     ignore=1;  
  52.     return;  
  53.   }  
  54. }  
  55.   
  56. function parserEnd()  
  57. {  
  58.   if(1 == ignore)  
  59.     return;  
  60.   
  61.   print "app_flag", substr(text,pkgHeaderBinLen/2+1);  
  62. }  

 

lineParser.awk源码(这是一个插件,不可独立运行):

[plain] view plain copy

  1. function getHeaderBinLen()  
  2. {  
  3.   #check min length of (Ethernet + IP + TCP) packet header  
  4.   if(length(bin) < 108)  
  5.     return 0;  
  6.   if("08004" == substr(bin,25,5))  
  7.     ethernetHeaderLen=28;  
  8.   else if("08004" == substr(bin,29,5))  
  9.     ethernetHeaderLen=32;  
  10.   else  
  11.   {  
  12.     #unknown ethernet frame packet  
  13.     return -1;  
  14.   }  
  15.   ipHeaderLen = 8 * substr(bin,ethernetHeaderLen+2,1);  
  16.   tcpHeaderLen = 8 * substr(bin,ethernetHeaderLen+ipHeaderLen+25,1);  
  17.   return ethernetHeaderLen + ipHeaderLen + tcpHeaderLen;  
  18. }  
  19.   
  20. function parserInit(pkgBodyLen)  
  21. {  
  22.   maxline=1;  
  23.   bin="";  
  24.   text="";  
  25.   pkgHeaderBinLen=0;  
  26.   lineEndBin="0a";  
  27.   newLineStartInBodyBin0=0;  
  28.   lineCount=0;  
  29.   output="";  
  30.   if(pkgBodyLen < 2)  
  31.     ignore=1;  
  32.   else  
  33.     ignore=0;  
  34. }  
  35.   
  36. function parserWork()  
  37. {  
  38.   if(1 == ignore)  
  39.     return;  
  40.   
  41.   for(field=2; field < NF; field++)  
  42.     bin=bin""$field;  
  43.   text=text""$NF;  
  44.     
  45.   if(pkgHeaderBinLen <= 0)  
  46.   {  
  47.     pkgHeaderBinLen=getHeaderBinLen();  
  48.     #print "pkgHeaderBinLen:", pkgHeaderBinLen  
  49.     if(-1 == pkgHeaderBinLen)  
  50.       ignore=1;  
  51.     if(pkgHeaderBinLen <= 0)  
  52.       return;  
  53.   }  
  54.   
  55.   while(1)  
  56.   {  
  57.     pkgBodyBin=substr(bin,pkgHeaderBinLen+newLineStartInBodyBin0+1);  
  58.     #print "debug:pkgBodyBin", pkgBodyBin;  
  59.     lineEndPos=index(pkgBodyBin,lineEndBin);  
  60.     if(0 == lineEndPos)  
  61.       return;  
  62.     output=output""substr(text,(pkgHeaderBinLen+newLineStartInBodyBin0)/2+1,lineEndPos/2+1);  
  63.     #print "debug:output", output;  
  64.     lineCount++;  
  65.     if(lineCount >= maxline)  
  66.     {  
  67.       print "app_flag", output;  
  68.       ignore=1;  
  69.       return;  
  70.     }  
  71.     newLineStartInBodyBin0+=lineEndPos+1;  
  72.   }  
  73. }  
  74.   
  75. function parserEnd()  
  76. {  
  77.   if(1 == ignore)  
  78.     return;  
  79.   
  80.   output=output""substr(text,(pkgHeaderBinLen+newLineStartInBodyBin0)/2+1);  
  81.   print "app_flag", output;  
  82. }  

 

oracleSqlParser.awk源码(这是一个插件,不可独立运行):

[plain] view plain copy

  1. function getHeaderBinLen()  
  2. {  
  3.   #check min length of (Ethernet + IP + TCP) packet header  
  4.   if(length(bin) < 108)  
  5.     return 0;  
  6.   if("08004" == substr(bin,25,5))  
  7.     ethernetHeaderLen=28;  
  8.   else if("08004" == substr(bin,29,5))  
  9.     ethernetHeaderLen=32;  
  10.   else  
  11.   {  
  12.     #unknown ethernet frame packet  
  13.     return -1;  
  14.   }  
  15.   ipHeaderLen = 8 * substr(bin,ethernetHeaderLen+2,1);  
  16.   tcpHeaderLen = 8 * substr(bin,ethernetHeaderLen+ipHeaderLen+25,1);  
  17.   return ethernetHeaderLen + ipHeaderLen + tcpHeaderLen;  
  18. }  
  19.   
  20. function parserInit(pkgBodyLen)  
  21. {  
  22.   bin="";  
  23.   text="";  
  24.   pkgHeaderBinLen=0;  
  25.   sqlStartInBodyBin0=100;  
  26.   slqEndBin="01010";  
  27.   sql="";  
  28.   foundSqlStart=0;  
  29.   if(pkgBodyLen < sqlStartInBodyBin0/2 + 6)  
  30.     ignore=1;  
  31.   else  
  32.     ignore=0;  
  33. }  
  34.   
  35. function parserWork()  
  36. {  
  37.   if(1 == ignore)  
  38.     return;  
  39.   
  40.   for(field=2; field < NF; field++)  
  41.     bin=bin""$field;  
  42.   text=text""$NF;  
  43.   
  44.   if(pkgHeaderBinLen <= 0)  
  45.   {  
  46.     pkgHeaderBinLen=getHeaderBinLen();  
  47.     #print "pkgHeaderBinLen:", pkgHeaderBinLen  
  48.     if(-1 == pkgHeaderBinLen)  
  49.       ignore=1;  
  50.     if(pkgHeaderBinLen <= 0)  
  51.       return;  
  52.   }  
  53.   
  54.   if(0 == foundSqlStart)  
  55.   {  
  56.     if(length(text) >= (pkgHeaderBinLen+sqlStartInBodyBin0)/2 + 6)  
  57.     {  
  58.       sqlCmd=substr(text,(pkgHeaderBinLen+sqlStartInBodyBin0)/2 + 1,6);  
  59.       if("select" == sqlCmd || "update" == sqlCmd || "delete" == sqlCmd || "create" == sqlCmd)  
  60.         foundSqlStart=1;  
  61.       else  
  62.         ignore=1;  
  63.     }  
  64.   }  
  65.   else  
  66.   {  
  67.     tmpBin=substr(bin,pkgHeaderBinLen+sqlStartInBodyBin0);  
  68.     sqlEndPos=index(tmpBin,slqEndBin);  
  69.     if(sqlEndPos>0)  
  70.     {  
  71.       sql=substr(text,(pkgHeaderBinLen+sqlStartInBodyBin0)/2 + 1,(sqlEndPos - 1)/2);  
  72.       print "app_flag",sql;  
  73.       ignore=1;  
  74.     }  
  75.   }  
  76. }  
  77.   
  78. function parserEnd()  
  79. {  
  80.   if(1 == ignore)  
  81.     return;  
  82.   
  83.   if(1 == foundSqlStart)  
  84.   {  
  85.     sql=substr(text,(pkgHeaderBinLen+sqlStartInBodyBin0)/2 + 1);  
  86.     print "app_flag",sql;  
  87.   }  
  88. }  

httpParser.awk源码(这是一个插件,不可独立运行): 

[plain] view plain copy

  1. function getHeaderBinLen()  
  2. {  
  3.   #check min length of (Ethernet + IP + TCP) packet header  
  4.   if(length(bin) < 108)  
  5.     return 0;  
  6.   if("08004" == substr(bin,25,5))  
  7.     ethernetHeaderLen=28;  
  8.   else if("08004" == substr(bin,29,5))  
  9.     ethernetHeaderLen=32;  
  10.   else  
  11.   {  
  12.     #unknown ethernet frame packet  
  13.     return -1;  
  14.   }  
  15.   ipHeaderLen = 8 * substr(bin,ethernetHeaderLen+2,1);  
  16.   tcpHeaderLen = 8 * substr(bin,ethernetHeaderLen+ipHeaderLen+25,1);  
  17.   return ethernetHeaderLen + ipHeaderLen + tcpHeaderLen;  
  18. }  
  19.   
  20. function parserInit(pkgBodyLen)  
  21. {  
  22.   bin="";  
  23.   text="";  
  24.   pkgHeaderBinLen=0;  
  25.   lineEndBin="0d0a";  
  26.   spaceBin="20";  
  27.   maybeHttpReq="";  
  28.   maybeHttpResponse=0;  
  29.   if(pkgBodyLen < 16)  
  30.     ignore=1;  
  31.   else  
  32.     ignore=0;  
  33. }  
  34.   
  35. function parserWork()  
  36. {  
  37.   if(1 == ignore)  
  38.     return;  
  39.   
  40.   for(field=2; field < NF; field++)  
  41.     bin=bin""$field;  
  42.   text=text""$NF;  
  43.     
  44.   if(pkgHeaderBinLen <= 0)  
  45.   {  
  46.     pkgHeaderBinLen=getHeaderBinLen();  
  47.     #print "pkgHeaderBinLen:", pkgHeaderBinLen  
  48.     if(-1 == pkgHeaderBinLen)  
  49.       ignore=1;  
  50.     if(pkgHeaderBinLen <= 0)  
  51.       return;  
  52.   }  
  53.   
  54.   if("" == maybeHttpReq && 0 == maybeHttpResponse)  
  55.   {  
  56.     if(length(text) >= pkgHeaderBinLen/2 + 9)  
  57.     {  
  58.       tmp_count=split(substr(text,pkgHeaderBinLen/2+1,9),words,".");  
  59.       if(tmp_count <= 1)  
  60.       {  
  61.         ignore = 1;  
  62.         return;  
  63.       }  
  64.   
  65.       if("GET" == words[1] || "POST" == words[1] || "PUT" == words[1] || "DELETE" == words[1] || "OPTIONS" == words[1] || "HEAD" == words[1])  
  66.         maybeHttpReq = words[1];  
  67.       else if(words[1] ~ /^HTTP\//)  
  68.         maybeHttpResponse = 1;  
  69.       else  
  70.       {  
  71.         ignore = 1;  
  72.         return;  
  73.       }  
  74.     }  
  75.     else  
  76.       return;  
  77.   }  
  78.   
  79.   pkgBodyBin=substr(bin,pkgHeaderBinLen+1);  
  80.   lineEndPos=index(pkgBodyBin,lineEndBin);  
  81.   if(0 == lineEndPos)  
  82.     return;  
  83.     
  84.   firstLineBin=substr(pkgBodyBin,1,lineEndPos - 1);  
  85.   firstLineText=substr(text,pkgHeaderBinLen/2+1,lineEndPos/2);  
  86.   #print "debug:pkgBodyBin", pkgBodyBin;  
  87.   #print "debug:firstLineBin", firstLineBin;  
  88.   #print "debug:firstLineText", firstLineText;  
  89.   if("" != maybeHttpReq)  
  90.   {  
  91.     if(3 == split(firstLineBin, a1, spaceBin) && 2 == split(firstLineText, a2, ".HTTP/"))  
  92.       print "app_flag", a2[1];  
  93.     ignore = 1;  
  94.   }  
  95.   else if(1 == maybeHttpResponse)  
  96.   {  
  97.     if(split(firstLineBin, a1, spaceBin) >= 3 && split(firstLineText, a2, ".") >= 4 && a2[3] + 0 >= 100)  
  98.       print "app_flag", substr(firstLineText, length(a1[1])/2 + 2);  
  99.     ignore = 1;  
  100.   }  
  101. }  
  102.   
  103. function parserEnd()  
  104. {  
  105.   if(1 == ignore)  
  106.     return;  
  107.   
  108.   if("" != maybeHttpReq)  
  109.     print "app_flag", substr(text,pkgHeaderBinLen/2+1);  
  110. }  


   

版权声明:本文为博主原创文章,未经博主允许不得转载

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值