tcpfull-summarize.tcl
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:7k
源码类别:

通讯编程

开发平台:

Visual C++

  1. #
  2. # program to process a (full) tcp trace file and summarize
  3. # various things (dataful acks, pure acks, etc).
  4. #
  5. # invoke with "tclsh thisfile infile outprefix"
  6. #
  7. set seqmod 0 ; # seq number mod value (0: none)
  8. set seqscale 1 ; # amount to scale seq #s by
  9. set flowfactor 536; # amount to scale flow # by
  10. proc scaleseq { fid seqno } {
  11. global seqmod seqscale flowfactor
  12. if { $seqmod == 0 } {
  13. set val [expr $fid * $flowfactor + $seqno * $seqscale]
  14. } else {
  15. set val [expr $fid * $flowfactor + ($seqno % $seqmod) * $seqscale]
  16. }
  17. return $val
  18. }
  19. proc forward_segment { fid time seqno } {
  20. global segchan
  21. puts $segchan "$time [scaleseq $fid $seqno]"
  22. }
  23. proc forward_emptysegment { fid time seqno } {
  24. global emptysegchan
  25. puts $emptysegchan "$time [scaleseq $fid $seqno]"
  26. }
  27. proc backward_dataful_ack { fid time ackno } {
  28. global ackchan
  29. puts $ackchan "$time [scaleseq $fid $ackno]"
  30. }
  31. proc backward_pure_ack { fid time ackno } {
  32. global packchan
  33. puts $packchan "$time [scaleseq $fid $ackno]"
  34. }
  35. proc drop_pkt { fid time ackno } {
  36. global dropchan
  37. puts $dropchan "$time [scaleseq $fid $ackno]"
  38. }
  39. proc ctrl { fid time tflags seq } {
  40. global ctrlchan
  41. puts $ctrlchan "$time [scaleseq $fid $seq]"
  42. }
  43. proc ecnecho_pkt { fid time ackno } {
  44. global ecnchan
  45. puts $ecnchan "$time [scaleseq $fid $ackno]"
  46. }
  47. proc cong_act { fid time seqno } {
  48. global cactchan
  49. puts $cactchan "$time [scaleseq $fid $seqno]"
  50. }
  51. proc salen { fid time ackno } {
  52. global sachan
  53. puts $sachan "$time [scaleseq $fid $ackno]"
  54. }
  55. proc parse_line line {
  56. global synfound active_opener passive_opener seqmod
  57. set okrecs { - + d }
  58. if { [lsearch $okrecs [lindex $line 0]] < 0 } {
  59. return
  60. }
  61. set sline [split $line " "]
  62. if { [llength $sline] < 15 } {
  63. puts stderr "apparently not in extended full-tcp format!"
  64. exit 1
  65. }
  66. set field(op) [lindex $sline 0]
  67. set field(time) [lindex $sline 1]
  68. set field(tsrc) [lindex $sline 2]
  69. set field(tdst) [lindex $sline 3]
  70. set field(ptype) [lindex $sline 4]
  71. set field(len) [lindex $sline 5]
  72. set field(pflags) [lindex $sline 6]
  73. set field(fid) [lindex $sline 7]
  74. set field(src) [lindex $sline 8]
  75. set field(srcaddr) [lindex [split $field(src) "."] 0]
  76. set field(srcport) [lindex [split $field(src) "."] 1]
  77. set field(dst) [lindex $sline 9]
  78. set field(dstaddr) [lindex [split $field(dst) "."] 0]
  79. set field(dstaddr) [lindex [split $field(dst) "."] 1]
  80. set field(seqno) [lindex $sline 10]
  81. set field(uid) [lindex $sline 11]
  82. set field(tcpackno) [lindex $sline 12]
  83. set field(tcpflags) [lindex $sline 13]
  84. set field(tcphlen) [lindex $sline 14]
  85. set field(salen) [lindex $sline 15]
  86. set fid $field(fid)
  87. if { ![info exists synfound($fid)] && [expr $field(tcpflags) & 0x02] } {
  88. global reverse
  89. set synfound($fid) 1
  90. if { [info exists reverse] && $reverse } {
  91. set active_opener($fid) $field(dst)
  92. set passive_opener($fid) $field(src)
  93. } else {
  94. set active_opener($fid) $field(src)
  95. set passive_opener($fid) $field(dst)
  96. }
  97. }
  98. set interesting 0
  99. if { $field(op) == "+" && [lsearch "tcp ack" $field(ptype)] >= 0} {
  100. set interesting 1
  101. }
  102. if { $interesting && [expr $field(tcpflags) & 0x03] } {
  103. # either SYN or FIN is on
  104. if { $field(src) == $active_opener($fid) && 
  105.     $field(dst)  == $passive_opener($fid) } {
  106. ctrl $field(fid) $field(time) $field(tcpflags) 
  107. [expr $field(seqno) + $field(len) - $field(tcphlen)]
  108. } elseif { $field(src) == $passive_opener($fid) && 
  109.     $field(dst) == $active_opener($fid) } {
  110. ctrl $field(fid) $field(time) $field(tcpflags) 
  111. $field(tcpackno)
  112. }
  113. }
  114. if { $interesting && $field(src) == $active_opener($fid) && $field(dst) == $passive_opener($fid) } {
  115. set topseq [expr $field(seqno) + $field(len) - $field(tcphlen)]
  116. if { $field(len) > $field(tcphlen) } {
  117. forward_segment $field(fid) $field(time) $topseq
  118. } else {
  119. forward_emptysegment $field(fid) $field(time) $topseq
  120. }
  121. if { [string index $field(pflags) 3] == "A" } {
  122. cong_act $field(fid) $field(time) $topseq
  123. }
  124. return
  125. }
  126. if { $interesting && $field(len) > $field(tcphlen) &&
  127.     $field(src) == $passive_opener($fid) && $field(dst) == $active_opener($fid) } {
  128. # record acks for the forward direction that have data
  129. backward_dataful_ack $field(fid) $field(time) $field(tcpackno)
  130. if { [string index $field(pflags) 0] == "C"  &&
  131. [string last N $field(pflags)] >= 0 } {
  132. ecnecho_pkt $field(fid) $field(time) $field(tcpackno)
  133. }
  134. return
  135. }
  136. if { $interesting && $field(len) == $field(tcphlen) &&
  137.     $field(src) == $passive_opener($fid) && $field(dst) == $active_opener($fid) } {
  138. # record pure acks for the forward direction
  139. backward_pure_ack $field(fid) $field(time) $field(tcpackno)
  140. if { [string index $field(pflags) 0] == "C" &&
  141. [string last N $field(pflags)] >= 0 } {
  142. ecnecho_pkt $field(fid) $field(time) $field(tcpackno)
  143. }
  144. if { $field(salen) > 0 } {
  145. salen $field(fid) $field(time) $field(tcpackno)
  146. }
  147. return
  148. }
  149. if { $field(op) == "d" && $field(src) == $active_opener($fid) &&
  150.     $field(dst) == $passive_opener($fid) } {
  151. drop_pkt $field(fid) $field(time) 
  152. [expr $field(seqno) + $field(len) - $field(tcphlen)]
  153. return
  154. }
  155. }
  156. proc parse_file chan {
  157. while { [gets $chan line] >= 0 } {
  158. parse_line $line
  159. }
  160. }
  161. proc dofile { infile outfile } {
  162. global ackchan packchan segchan dropchan ctrlchan emptysegchan ecnchan cactchan sachan
  163.         set ackstmp $outfile.acks ; # data-full acks
  164.         set segstmp $outfile.p; # segments
  165. set esegstmp $outfile.es; # empty segments
  166.         set dropstmp $outfile.d; # drops
  167.         set packstmp $outfile.packs; # pure acks
  168. set ctltmp $outfile.ctrl ; # SYNs + FINs
  169. set ecntmp $outfile.ecn ; # ECN acks
  170. set cacttmp $outfile.cact; # cong action
  171. set satmp $outfile.sack; # sack info
  172.         exec rm -f $ackstmp $segstmp $esegstmp $dropstmp $packstmp $ctltmp $ecntmp $cacttmp $satmp
  173. set ackchan [open $ackstmp w]
  174. set segchan [open $segstmp w]
  175. set emptysegchan [open $esegstmp w]
  176. set dropchan [open $dropstmp w]
  177. set packchan [open $packstmp w]
  178. set ctrlchan [open $ctltmp w]
  179. set ecnchan [open $ecntmp w]
  180. set cactchan [open $cacttmp w]
  181. set sachan [open $satmp w]
  182. set inf [open $infile r]
  183. parse_file $inf
  184. close $ackchan
  185. close $segchan
  186. close $emptysegchan
  187. close $dropchan
  188. close $packchan
  189. close $ctrlchan
  190. close $ecnchan
  191. close $cactchan
  192. close $sachan
  193. }
  194. proc getopt {argc argv} { 
  195.         global opt
  196.         lappend optlist s n m r
  197.         for {set i 0} {$i < $argc} {incr i} {
  198.                 set arg [lindex $argv $i]
  199.                 if {[string range $arg 0 0] != "-"} continue
  200.                 set name [string range $arg 1 end]
  201.                 set opt($name) [lindex $argv [expr $i+1]]
  202.         }
  203. }
  204. getopt $argc $argv
  205. set base 0
  206. if { [info exists opt(s)] && $opt(s) != "" } {
  207. global seqscale base opt argc argv
  208. set seqscale $opt(s)
  209. incr argc -2
  210. incr base 2
  211. }
  212. if { [info exists opt(n)] && $opt(n) != "" } {
  213. global flowfactor base opt argc argv
  214. set flowfactor $opt(n)
  215. incr argc -2
  216. incr base 2
  217. }
  218. if { [info exists opt(m)] && $opt(m) != "" } {
  219. global seqmod base opt argc argv
  220. set seqmod $opt(m)
  221. incr argc -2
  222. incr base 2
  223. }
  224. if { [info exists opt(r)] && $opt(r) != "" } {
  225. global reverse base argc argv
  226. set reverse 1
  227. incr argc -1
  228. incr base
  229. }
  230. if { $argc < 2 || $argc > 3 } {
  231. puts stderr "usage: tclsh tcpfull-suumarize.tcl [-m wrapamt] [-r] [-n flowfactor] [-s seqscale] tracefile outprefix [reverse]"
  232. exit 1
  233. } elseif { $argc == 3 } {
  234. if { [lindex $argv [expr $base + 2]] == "reverse" } {
  235. global reverse
  236. set reverse 1
  237. }
  238. }
  239. dofile [lindex $argv [expr $base]] [lindex $argv [expr $base + 1]]
  240. exit 0