Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

First incarnation of HTTPProtocolParser.

git-svn-id: http://maatkit.googlecode.com/svn/trunk@5079 dfb901c2-3250-0410-b216-0b33211c9131
  • Loading branch information...
commit 74a067b28a06350c50175f139b9b25a37dd4e95d 1 parent 09b9ac1
authored November 09, 2009
317  common/HTTPProtocolParser.pm
... ...
@@ -0,0 +1,317 @@
  1
+# This program is copyright 2009 Percona Inc.
  2
+# Feedback and improvements are welcome.
  3
+#
  4
+# THIS PROGRAM IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
  5
+# WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  6
+# MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  7
+#
  8
+# This program is free software; you can redistribute it and/or modify it under
  9
+# the terms of the GNU General Public License as published by the Free Software
  10
+# Foundation, version 2; OR the Perl Artistic License.  On UNIX and similar
  11
+# systems, you can issue `man perlgpl' or `man perlartistic' to read these
  12
+# licenses.
  13
+#
  14
+# You should have received a copy of the GNU General Public License along with
  15
+# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
  16
+# Place, Suite 330, Boston, MA  02111-1307  USA.
  17
+# ###########################################################################
  18
+# HTTPProtocolParser package $Revision$
  19
+# ###########################################################################
  20
+package HTTPProtocolParser;
  21
+
  22
+use strict;
  23
+use warnings FATAL => 'all';
  24
+use English qw(-no_match_vars);
  25
+
  26
+use Data::Dumper;
  27
+$Data::Dumper::Indent    = 1;
  28
+$Data::Dumper::Sortkeys  = 1;
  29
+$Data::Dumper::Quotekeys = 0;
  30
+
  31
+use constant MKDEBUG => $ENV{MKDEBUG};
  32
+
  33
+# server is the "host:port" of the sever being watched.  It's auto-guessed if
  34
+# not specified.
  35
+sub new {
  36
+   my ( $class, %args ) = @_;
  37
+
  38
+   my ( $server_port )
  39
+      = $args{server} ? $args{server} =~ m/:(\w+)/ : ('80');
  40
+   $server_port ||= '80';  # In case $args{server} doesn't have a port.
  41
+
  42
+   my $self = {
  43
+      server      => $args{server},
  44
+      server_port => $server_port,
  45
+      sessions    => {},
  46
+      o           => $args{o},
  47
+   };
  48
+   return bless $self, $class;
  49
+}
  50
+
  51
+# The packet arg should be a hashref from TcpdumpParser::parse_event().
  52
+# misc is a placeholder for future features.
  53
+sub parse_packet {
  54
+   my ( $self, $packet, $misc ) = @_;
  55
+
  56
+   my $src_host = "$packet->{src_host}:$packet->{src_port}";
  57
+   my $dst_host = "$packet->{dst_host}:$packet->{dst_port}";
  58
+
  59
+   if ( my $server = $self->{server} ) {  # Watch only the given server.
  60
+      if ( $src_host ne $server && $dst_host ne $server ) {
  61
+         MKDEBUG && _d('Packet is not to or from', $server);
  62
+         return;
  63
+      }
  64
+   }
  65
+
  66
+   # Auto-detect the server by looking for port 80.
  67
+   my $packet_from;
  68
+   my $client;
  69
+   if ( $src_host =~ m/:$self->{server_port}$/ ) {
  70
+      $packet_from = 'server';
  71
+      $client      = $dst_host;
  72
+   }
  73
+   elsif ( $dst_host =~ m/:$self->{server_port}$/ ) {
  74
+      $packet_from = 'client';
  75
+      $client      = $src_host;
  76
+   }
  77
+   else {
  78
+      warn 'Packet is not to or from web server: ', Dumper($packet);
  79
+      return;
  80
+   }
  81
+   MKDEBUG && _d('Client:', $client);
  82
+
  83
+   # Get the client's session info or create a new session if the
  84
+   # client hasn't been seen before.
  85
+   if ( !exists $self->{sessions}->{$client} ) {
  86
+      MKDEBUG && _d('New session');
  87
+      $self->{sessions}->{$client} = {
  88
+         client      => $client,
  89
+         state       => undef,
  90
+         raw_packets => [],
  91
+         # ts -- wait for ts later.
  92
+      };
  93
+   };
  94
+   my $session = $self->{sessions}->{$client};
  95
+
  96
+   # Return early if there's no TCP data.  These are usually ACK packets, but
  97
+   # they could also be FINs in which case, we should close and delete the
  98
+   # client's session.
  99
+   if ( $packet->{data_len} == 0 ) {
  100
+      MKDEBUG && _d('No TCP data');
  101
+      return;
  102
+   }
  103
+
  104
+   # Save raw packets to dump later in case something fails.
  105
+   push @{$session->{raw_packets}}, $packet->{raw_packet};
  106
+
  107
+   # Finally, parse the packet and maybe create an event.
  108
+   $packet->{data} = pack('H*', $packet->{data});
  109
+   my $event;
  110
+   if ( $packet_from eq 'server' ) {
  111
+      $event = $self->_packet_from_server($packet, $session, $misc);
  112
+   }
  113
+   elsif ( $packet_from eq 'client' ) {
  114
+      $event = $self->_packet_from_client($packet, $session, $misc);
  115
+   }
  116
+   else {
  117
+      # Should not get here.
  118
+      die 'Packet origin unknown';
  119
+   }
  120
+
  121
+   MKDEBUG && _d('Done with packet; event:', Dumper($event));
  122
+   return $event;
  123
+}
  124
+
  125
+# Handles a packet from the server given the state of the session.  Returns an
  126
+# event if one was ready to be created, otherwise returns nothing.
  127
+sub _packet_from_server {
  128
+   my ( $self, $packet, $session, $misc ) = @_;
  129
+   die "I need a packet"  unless $packet;
  130
+   die "I need a session" unless $session;
  131
+
  132
+   MKDEBUG && _d('Packet is from server; client state:', $session->{state}); 
  133
+
  134
+   my $data = $packet->{data};
  135
+
  136
+   # If there's no session state, then we're catching a server response
  137
+   # mid-stream.
  138
+   if ( !$session->{state} ) {
  139
+      MKDEBUG && _d('Ignoring mid-stream server response');
  140
+      return;
  141
+   }
  142
+
  143
+   # Assume that the server is returning only one value. 
  144
+   # TODO: make it handle multiple.
  145
+   if ( $session->{state} eq 'awaiting headers' ) {
  146
+      MKDEBUG && _d('State:', $session->{state});
  147
+
  148
+      my ($line1, $header) = $packet->{data} =~ m/\A(.*?)\r\n(.+)?/s;
  149
+      # First header val should be: version  code phrase
  150
+      # E.g.:                       HTTP/1.1  200 OK
  151
+      my ($version, $code, $phrase) = $line1 =~ m/(\S+)/g;
  152
+
  153
+      $session->{response} = $code;
  154
+      MKDEBUG && _d('Reponse code for last', 
  155
+         $session->{request}, $session->{page},
  156
+         'request:', $session->{response});
  157
+
  158
+      MKDEBUG && _d('HTTP header:', $header);
  159
+      my @headers;
  160
+      foreach my $val ( split(/\r\n/, $header) ) {
  161
+         last unless $val;
  162
+         # Capture and save any useful header values.
  163
+         if ( $val =~ m/^Content-Length/i ) {
  164
+            ($session->{bytes}) = $val =~ /: (\d+)/;
  165
+         }
  166
+      }
  167
+   }
  168
+   else {
  169
+         return; # Prevent firing event.
  170
+   }
  171
+
  172
+   MKDEBUG && _d('Creating event, deleting session');
  173
+   my $event = make_event($session, $packet);
  174
+   delete $self->{sessions}->{$session->{client}}; # http is stateless!
  175
+   $session->{raw_packets} = []; # Avoid keeping forever
  176
+   return $event;
  177
+}
  178
+
  179
+# Handles a packet from the client given the state of the session.
  180
+sub _packet_from_client {
  181
+   my ( $self, $packet, $session, $misc ) = @_;
  182
+   die "I need a packet"  unless $packet;
  183
+   die "I need a session" unless $session;
  184
+
  185
+   MKDEBUG && _d('Packet is from client; state:', $session->{state});
  186
+
  187
+   my $event;
  188
+   if ( ($session->{state} || '') =~ m/awaiting / ) {
  189
+      # Whoa, we expected something from the server, not the client.  Fire an
  190
+      # INTERRUPTED with what we've got, and create a new session.
  191
+      MKDEBUG && _d("Expected data from the client, looks like interrupted");
  192
+      $session->{res} = 'INTERRUPTED';
  193
+      $event = make_event($session, $packet);
  194
+      my $client = $session->{client};
  195
+      delete @{$session}{keys %$session};
  196
+      $session->{client} = $client;
  197
+   }
  198
+
  199
+   my ($line1, $val);
  200
+   my ($request, $page);
  201
+   if ( !$session->{state} ) {
  202
+      MKDEBUG && _d('Session state: ', $session->{state});
  203
+      $session->{state} = 'awaiting headers';
  204
+
  205
+      # Split up the first line into its parts.
  206
+      ($line1, $val) = $packet->{data} =~ m/\A(.*?)\r\n(.+)?/s;
  207
+      my @vals = $line1 =~ m/(\S+)/g;
  208
+      $request = lc shift @vals;
  209
+      MKDEBUG && _d('Request:', $request);
  210
+      if ( $request eq 'get' ) {
  211
+         ($page) = shift @vals;
  212
+         MKDEBUG && _d('Page:', $page);
  213
+      }
  214
+      else {
  215
+         MKDEBUG && _d("Don't know how to handle", $request);
  216
+      }
  217
+
  218
+      @{$session}{qw(request page)} = ($request, $page);
  219
+      $session->{host}       = $packet->{src_host};
  220
+      $session->{pos_in_log} = $packet->{pos_in_log};
  221
+      $session->{ts}         = $packet->{ts};
  222
+   }
  223
+   else {
  224
+      MKDEBUG && _d('Session state: ', $session->{state});
  225
+      $val = $packet->{data};
  226
+   }
  227
+
  228
+   return $event;
  229
+}
  230
+
  231
+# The event is not yet suitable for mk-query-digest.  It lacks, for example,
  232
+# an arg and fingerprint attribute.  The event should be passed to
  233
+# HTTPEvent::make_event() to transform it.
  234
+sub make_event {
  235
+   my ( $session, $packet ) = @_;
  236
+   my $event = {
  237
+      request      => $session->{request},
  238
+      page         => $session->{page},
  239
+      response     => $session->{response},
  240
+      ts           => $session->{ts},
  241
+      host         => $session->{host},
  242
+      bytes        => $session->{bytes} || 0,
  243
+      reponse_time => timestamp_diff($session->{ts}, $packet->{ts}),
  244
+      pos_in_log   => $session->{pos_in_log},
  245
+   };
  246
+   return $event;
  247
+}
  248
+
  249
+sub _get_errors_fh {
  250
+   my ( $self ) = @_;
  251
+   my $errors_fh = $self->{errors_fh};
  252
+   return $errors_fh if $errors_fh;
  253
+
  254
+   # Errors file isn't open yet; try to open it.
  255
+   my $o = $self->{o};
  256
+   if ( $o && $o->has('tcpdump-errors') && $o->got('tcpdump-errors') ) {
  257
+      my $errors_file = $o->get('tcpdump-errors');
  258
+      MKDEBUG && _d('tcpdump-errors file:', $errors_file);
  259
+      open $errors_fh, '>>', $errors_file
  260
+         or die "Cannot open tcpdump-errors file $errors_file: $OS_ERROR";
  261
+   }
  262
+
  263
+   $self->{errors_fh} = $errors_fh;
  264
+   return $errors_fh;
  265
+}
  266
+
  267
+sub fail_session {
  268
+   my ( $self, $session, $reason ) = @_;
  269
+   my $errors_fh = $self->_get_errors_fh();
  270
+   if ( $errors_fh ) {
  271
+      $session->{reason_for_failure} = $reason;
  272
+      my $session_dump = '# ' . Dumper($session);
  273
+      chomp $session_dump;
  274
+      $session_dump =~ s/\n/\n# /g;
  275
+      print $errors_fh "$session_dump\n";
  276
+      {
  277
+         local $LIST_SEPARATOR = "\n";
  278
+         print $errors_fh "@{$session->{raw_packets}}";
  279
+         print $errors_fh "\n";
  280
+      }
  281
+   }
  282
+   MKDEBUG && _d('Failed session', $session->{client}, 'because', $reason);
  283
+   delete $self->{sessions}->{$session->{client}};
  284
+   return;
  285
+}
  286
+
  287
+sub _d {
  288
+   my ($package, undef, $line) = caller 0;
  289
+   @_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }
  290
+        map { defined $_ ? $_ : 'undef' }
  291
+        @_;
  292
+   print STDERR "# $package:$line $PID ", join(' ', @_), "\n";
  293
+}
  294
+
  295
+# Returns the difference between two tcpdump timestamps.  TODO: this is in
  296
+# MySQLProtocolParser too, best to factor it out somewhere common.
  297
+sub timestamp_diff {
  298
+   my ( $start, $end ) = @_;
  299
+   my $sd = substr($start, 0, 11, '');
  300
+   my $ed = substr($end,   0, 11, '');
  301
+   my ( $sh, $sm, $ss ) = split(/:/, $start);
  302
+   my ( $eh, $em, $es ) = split(/:/, $end);
  303
+   my $esecs = ($eh * 3600 + $em * 60 + $es);
  304
+   my $ssecs = ($sh * 3600 + $sm * 60 + $ss);
  305
+   if ( $sd eq $ed ) {
  306
+      return sprintf '%.6f', $esecs - $ssecs;
  307
+   }
  308
+   else { # Assume only one day boundary has been crossed, no DST, etc
  309
+      return sprintf '%.6f', ( 86_400 - $ssecs ) + $esecs;
  310
+   }
  311
+}
  312
+
  313
+1;
  314
+
  315
+# ###########################################################################
  316
+# End HTTPProtocolParser package
  317
+# ###########################################################################
89  common/t/HTTPProtocolParser.t
... ...
@@ -0,0 +1,89 @@
  1
+#!/usr/bin/perl
  2
+
  3
+use strict;
  4
+use warnings FATAL => 'all';
  5
+use English qw(-no_match_vars);
  6
+use Test::More tests => 2;
  7
+
  8
+require "../HTTPProtocolParser.pm";
  9
+require "../TcpdumpParser.pm";
  10
+
  11
+use Data::Dumper;
  12
+$Data::Dumper::Quotekeys = 0;
  13
+$Data::Dumper::Sortkeys  = 1;
  14
+$Data::Dumper::Indent    = 1;
  15
+
  16
+my $tcpdump  = new TcpdumpParser();
  17
+my $protocol; # Create a new HTTPProtocolParser for each test.
  18
+
  19
+sub load_data {
  20
+   my ( $file ) = @_;
  21
+   open my $fh, '<', $file or BAIL_OUT("Cannot open $file: $OS_ERROR");
  22
+   my $contents = do { local $/ = undef; <$fh> };
  23
+   close $fh;
  24
+   (my $data = join('', $contents =~ m/(.*)/g)) =~ s/\s+//g;
  25
+   return $data;
  26
+}
  27
+
  28
+sub run_test {
  29
+   my ( $def ) = @_;
  30
+   map     { die "What is $_ for?" }
  31
+      grep { $_ !~ m/^(?:misc|file|result|num_events|desc)$/ }
  32
+      keys %$def;
  33
+   my @e;
  34
+   my $num_events = 0;
  35
+
  36
+   my @callbacks;
  37
+   push @callbacks, sub {
  38
+      my ( $packet ) = @_;
  39
+      return $protocol->parse_packet($packet, undef);
  40
+   };
  41
+   push @callbacks, sub {
  42
+      push @e, @_;
  43
+   };
  44
+
  45
+   eval {
  46
+      open my $fh, "<", $def->{file}
  47
+         or BAIL_OUT("Cannot open $def->{file}: $OS_ERROR");
  48
+      $num_events++ while $tcpdump->parse_event($fh, undef, @callbacks);
  49
+      close $fh;
  50
+   };
  51
+   is($EVAL_ERROR, '', "No error on $def->{file}");
  52
+   if ( defined $def->{result} ) {
  53
+      is_deeply(
  54
+         \@e,
  55
+         $def->{result},
  56
+         $def->{file} . ($def->{desc} ? ": $def->{desc}" : '')
  57
+      ) or print "Got: ", Dumper(\@e);
  58
+   }
  59
+   if ( defined $def->{num_events} ) {
  60
+      is($num_events, $def->{num_events}, "$def->{file} num_events");
  61
+   }
  62
+
  63
+   # Uncomment this if you're hacking the unknown.
  64
+   # print "Events for $def->{file}: ", Dumper(\@e);
  65
+
  66
+   return;
  67
+}
  68
+
  69
+# GET a very simple page.
  70
+$protocol = new HTTPProtocolParser();
  71
+run_test({
  72
+   file   => 'samples/http_tcpdump001.txt',
  73
+   result => [
  74
+      { ts           => '2009-11-09 11:31:52.341907',
  75
+        bytes        => '715',
  76
+        host         => '10.112.2.144',
  77
+        pos_in_log   => 0,
  78
+        request      => 'get',
  79
+        page         => '/contact',
  80
+        response     => '200',
  81
+        reponse_time => '0.651419',
  82
+      },
  83
+   ],
  84
+});
  85
+
  86
+# #############################################################################
  87
+# Done.
  88
+# #############################################################################
  89
+exit;
107  common/t/samples/http_tcpdump001.txt
... ...
@@ -0,0 +1,107 @@
  1
+2009-11-09 11:31:52.341907 IP 10.112.2.144.58680 > 64.13.232.157.80: tcp 428
  2
+	0x0000:  4500 01e0 9928 4000 4006 6a45 0a70 0290
  3
+	0x0010:  400d e89d e538 0050 ff78 7c13 9c69 ff04
  4
+	0x0020:  8018 006a 0f76 0000 0101 080a 0032 fa31
  5
+	0x0030:  0cea bf27 4745 5420 2f63 6f6e 7461 6374
  6
+	0x0040:  2048 5454 502f 312e 310d 0a48 6f73 743a
  7
+	0x0050:  2068 6163 6b6d 7973 716c 2e63 6f6d 0d0a
  8
+	0x0060:  5573 6572 2d41 6765 6e74 3a20 4d6f 7a69
  9
+	0x0070:  6c6c 612f 352e 3020 2858 3131 3b20 553b
  10
+	0x0080:  204c 696e 7578 2078 3836 5f36 343b 2065
  11
+	0x0090:  6e2d 5553 3b20 7276 3a31 2e39 2e30 2e31
  12
+	0x00a0:  3529 2047 6563 6b6f 2f32 3030 3931 3032
  13
+	0x00b0:  3831 3520 5562 756e 7475 2f39 2e30 3420
  14
+	0x00c0:  286a 6175 6e74 7929 2046 6972 6566 6f78
  15
+	0x00d0:  2f33 2e30 2e31 350d 0a41 6363 6570 743a
  16
+	0x00e0:  2074 6578 742f 6874 6d6c 2c61 7070 6c69
  17
+	0x00f0:  6361 7469 6f6e 2f78 6874 6d6c 2b78 6d6c
  18
+	0x0100:  2c61 7070 6c69 6361 7469 6f6e 2f78 6d6c
  19
+	0x0110:  3b71 3d30 2e39 2c2a 2f2a 3b71 3d30 2e38
  20
+	0x0120:  0d0a 4163 6365 7074 2d4c 616e 6775 6167
  21
+	0x0130:  653a 2065 6e2d 7573 2c65 6e3b 713d 302e
  22
+	0x0140:  350d 0a41 6363 6570 742d 456e 636f 6469
  23
+	0x0150:  6e67 3a20 677a 6970 2c64 6566 6c61 7465
  24
+	0x0160:  0d0a 4163 6365 7074 2d43 6861 7273 6574
  25
+	0x0170:  3a20 4953 4f2d 3838 3539 2d31 2c75 7466
  26
+	0x0180:  2d38 3b71 3d30 2e37 2c2a 3b71 3d30 2e37
  27
+	0x0190:  0d0a 4b65 6570 2d41 6c69 7665 3a20 3330
  28
+	0x01a0:  300d 0a43 6f6e 6e65 6374 696f 6e3a 206b
  29
+	0x01b0:  6565 702d 616c 6976 650d 0a52 6566 6572
  30
+	0x01c0:  6572 3a20 6874 7470 3a2f 2f68 6163 6b6d
  31
+	0x01d0:  7973 716c 2e63 6f6d 2f66 6171 0d0a 0d0a
  32
+2009-11-09 11:31:52.406461 IP 64.13.232.157.80 > 10.112.2.144.58680: tcp 0
  33
+	0x0000:  4500 0034 4ae8 4000 3306 c731 400d e89d
  34
+	0x0010:  0a70 0290 0050 e538 9c69 ff04 ff78 7dbf
  35
+	0x0020:  8010 0014 7b14 0000 0101 080a 0cea c06c
  36
+	0x0030:  0032 fa31
  37
+2009-11-09 11:31:52.993326 IP 64.13.232.157.80 > 10.112.2.144.58680: tcp 967
  38
+	0x0000:  4500 03fb 4ae9 4000 3306 c369 400d e89d
  39
+	0x0010:  0a70 0290 0050 e538 9c69 ff04 ff78 7dbf
  40
+	0x0020:  8018 0014 bcb2 0000 0101 080a 0cea c0a6
  41
+	0x0030:  0032 fa31 4854 5450 2f31 2e31 2032 3030
  42
+	0x0040:  204f 4b0d 0a44 6174 653a 204d 6f6e 2c20
  43
+	0x0050:  3039 204e 6f76 2032 3030 3920 3138 3a33
  44
+	0x0060:  303a 3536 2047 4d54 0d0a 5365 7276 6572
  45
+	0x0070:  3a20 4170 6163 6865 2f32 2e30 2e35 340d
  46
+	0x0080:  0a58 2d50 6f77 6572 6564 2d42 793a 2050
  47
+	0x0090:  4850 2f34 2e34 2e38 0d0a 5661 7279 3a20
  48
+	0x00a0:  4163 6365 7074 2d45 6e63 6f64 696e 670d
  49
+	0x00b0:  0a43 6f6e 7465 6e74 2d45 6e63 6f64 696e
  50
+	0x00c0:  673a 2067 7a69 700d 0a43 6f6e 7465 6e74
  51
+	0x00d0:  2d4c 656e 6774 683a 2037 3135 0d0a 4b65
  52
+	0x00e0:  6570 2d41 6c69 7665 3a20 7469 6d65 6f75
  53
+	0x00f0:  743d 352c 206d 6178 3d39 370d 0a43 6f6e
  54
+	0x0100:  6e65 6374 696f 6e3a 204b 6565 702d 416c
  55
+	0x0110:  6976 650d 0a43 6f6e 7465 6e74 2d54 7970
  56
+	0x0120:  653a 2074 6578 742f 6874 6d6c 0d0a 0d0a
  57
+	0x0130:  1f8b 0800 0000 0000 0003 9d54 5b6f d330
  58
+	0x0140:  147e cfaf 3818 8981 b4c6 eb26 04db 9208
  59
+	0x0150:  e83a 31a9 63b0 96db d3e4 3a27 8b35 c74e
  60
+	0x0160:  6da7 1710 ff1d 3b69 7763 6288 97d8 3997
  61
+	0x0170:  ef3b f677 8e93 2747 6783 c9f7 8f43 285d
  62
+	0x0180:  25e1 e3e7 77a3 9301 901e a55f f706 941e
  63
+	0x0190:  4d8e e0db fbc9 e908 faf1 0e8c 9d11 dc51
  64
+	0x01a0:  3afc 4080 94ce d507 942e 168b 78b1 176b
  65
+	0x01b0:  7349 27e7 7419 50fa 216d bded d936 27ce
  66
+	0x01c0:  5d4e b228 6949 9695 5436 7d00 a0bf bfbf
  67
+	0x01d0:  dfe5 9110 7420 99ba 4c09 2a02 d7bb 8081
  68
+	0x01e0:  2cf7 8b13 4e62 36d0 ca31 eee0 3de3 5770
  69
+	0x01f0:  ba1a 7f1a 25b4 f344 4985 8e81 6215 a6c4
  70
+	0x0200:  e8a9 7696 00f7 e1a8 5c4a 9416 2ac7 e536
  71
+	0x0210:  285d 6829 f582 00dd a484 c27a 386b c43c
  72
+	0x0220:  2583 2ea1 3759 d578 2bdd e1d2 d150 e821
  73
+	0x0230:  f092 198b 2e3d 199f f55e bf7e b9df eb77
  74
+	0x0240:  5052 a82b 3028 5362 dd4a a22d 111d 81d2
  75
+	0x0250:  6071 7df4 d217 5dad ec4c c65c 57b4 0b8b
  76
+	0x0260:  b9f5 753a 4fb7 6669 ff03 60eb bfef c9a2
  77
+	0x0270:  b814 15fc 9c6a 93a3 e9f9 533a 5d1d ecd6
  78
+	0x0280:  4bb0 5a8a 1c9e 163b af8a 9d9d c35f 51d2
  79
+	0x0290:  1164 91df 7557 1825 539d af3c 722e e620
  80
+	0x02a0:  f294 9ca2 6a3c 2200 5c9b a66e 6d60 c025
  81
+	0x02b0:  b341 3651 1168 a152 c2b5 d4e6 60c3 f1b7
  82
+	0x02c0:  d391 ecb6 422c 0b90 d493 dc65 13aa d01d
  83
+	0x02d0:  df1d 4aa5 dd45 4bdb e14f a5be a424 7be7
  84
+	0x02e0:  9700 f54c 4d6d 7d78 fbfb 1840 c166 243b
  85
+	0x02f0:  7efb e91f b31f 3f31 efba 906c daf1 ffca
  86
+	0x0300:  0a1d e315 1d85 2520 dcc4 774d 7c71 e174
  87
+	0x0310:  4db2 8d6b 7d7f eb25 ba91 71dd b3e4 96b2
  88
+	0x0320:  bcbf 96b1 dc7d 7064 bcb9 75d7 1bd2 9302
  89
+	0x0330:  56ba 8192 cdd1 8f88 ea39 e4a5 129c 4998
  90
+	0x0340:  3568 9dd0 6a1b 6a89 cc22 60c5 8404 e620
  91
+	0x0350:  e13a c76c 3c1c 0d07 1338 1f7e 199e 8f87
  92
+	0x0360:  cfb7 2acd 6339 b3ab ea8a b3f2 0d17 72da
  93
+	0x0370:  d45b 2f12 da06 c7c9 d484 e6ee 488f b581
  94
+	0x0380:  1b22 61ad a7ba a671 6605 aec4 701d 7faa
  95
+	0x0390:  084c e5ad 77ce 8cd0 8d85 5c73 db1a 2f1b
  96
+	0x03a0:  91a3 8542 18eb eeb2 9d29 a8b1 7150 3323
  97
+	0x03b0:  d100 2a28 0c53 cf9e eeee f50f 99b0 6005
  98
+	0x03c0:  cc03 94ff 48fc 01cf ab60 f413 7837 4a6d
  99
+	0x03d0:  f9eb f018 162a d63e 530d fa9d 43a3 504a
  100
+	0x03e0:  7c11 774a d519 44f7 f44a e87a fada 7724
  101
+	0x03f0:  8b7e 035a 975d 6f8a 0500 00
  102
+2009-11-09 11:31:52.993366 IP 10.112.2.144.58680 > 64.13.232.157.80: tcp 0
  103
+	0x0000:  4500 0034 9929 4000 4006 6bf0 0a70 0290
  104
+	0x0010:  400d e89d e538 0050 ff78 7dbf 9c6a 02cb
  105
+	0x0020:  8010 007e 7606 0000 0101 080a 0032 fad4
  106
+	0x0030:  0cea c0a6
  107
+

0 notes on commit 74a067b

Please sign in to comment.
Something went wrong with that request. Please try again.