Changeset 1652

Show
Ignore:
Timestamp:
11/12/06 12:54:00 (2 years ago)
Author:
mbr
Message:

- Interim commit for major refactoring of Snort signature interaface and matching capability.
- Adding support for ttl, IP ID, dsize, tcp seq/ack, window, psad_dsize, psad_derived_sids,

and various ICMP header tests.

- Refactored check_scan() to break-out parsing of Netfilter logs into a dedicated function.
- Added variables from snort.conf such as EXTERNAL_NET and HTTP_SERVERS, etc.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • psad/branches/sigdevel/psad

    r1648 r1652  
    8282# 
    8383#  Sample tcp packet (rejected by Netfilter... --log-prefix = "DROP ") 
     84# 
    8485#  Mar 11 13:15:52 orthanc kernel: DROP IN=lo OUT= MAC=00:00:00:00:00:00:00:00: 
    8586#  00:00:00:00:08:00 SRC=127.0.0.1 DST=127.0.0.1 LEN=60 TOS=0x00 PREC=0x00 
     
    8788# 
    8889#  Sample icmp packet rejected by Netfilter INPUT chain: 
     90# 
    8991#  Nov 27 15:45:51 orthanc kernel: DROP IN=eth1 OUT= MAC=00:a0:cc:e2:1f:f2:00: 
    9092#  20:78:10:70:e7:08:00 SRC=192.168.10.20 DST=192.168.10.1 LEN=84 TOS=0x00 
     
    9294# 
    9395#  Sample icmp packet logged through FORWARD chain: 
     96# 
    9497#  Aug 20 21:23:32 orthanc kernel: SID365 IN=eth2 OUT=eth1 SRC=192.168.20.25 
    9598#  DST=192.168.10.15 LEN=84 TOS=0x00 PREC=0x00 TTL=63 ID=0 DF PROTO=ICMP TYPE=8 
     
    238241my %snort_ref_baseurl = (); 
    239242 
    240 ### cache all scan signatures (initialized by default) 
     243### cache all scan signatures from /etc/psad/signatures file 
    241244my %sigs = (); 
    242  
    243 ### cache signature messages, danger levels, etc.  All of these 
    244 ### signatures come from the /etc/psad/signatures file. 
    245 my %sigs_attr = (); 
    246  
    247 ### cache all signatures that have been derived from Snort rules 
    248 ### (these signatures also come from /etc/psad/signatures, but conform 
    249 ### to the new signature format in psad-1.5.0 
    250 my %derived_sigs = (); 
    251 my %derived_sigs_attr = (); 
     245my %sig_search = (); 
    252246 
    253247### cache Netfilter prefixes 
     
    426420    'T' => $tcp_timestamp_type 
    427421); 
     422 
     423### These are not directly support by psad because they 
     424### do not appear in Netfilter logs; however, several of 
     425### these options are supported if fwsnort is also running. 
     426my @unsupported_snort_opts = qw( 
     427    pcre 
     428    fragbits 
     429    content-list 
     430    rpc 
     431    byte_test 
     432    byte_jump 
     433    distance 
     434    within 
     435    flowbits 
     436    rawbytes 
     437    regex 
     438    isdataat 
     439    uricontent 
     440    content 
     441    offset 
     442    replace 
     443    resp 
     444    flowbits 
     445); 
     446 
     447### for Snort signature sp/dp matching 
     448my @port_types = ( 
     449    {'sp' => 'norm', 'dp' => 'norm'}, 
     450    {'sp' => 'norm', 'dp' => 'neg'}, 
     451    {'sp' => 'neg',  'dp' => 'norm'}, 
     452    {'sp' => 'neg',  'dp' => 'neg'}, 
     453); 
     454 
     455### packet parsing return values 
     456my $PKT_ERROR   = 0; 
     457my $PKT_SUCCESS = 1; 
     458my $PKT_IGNORE  = 2; 
     459 
     460### header lengths 
     461my $TCP_HEADER_LEN  = 20;  ### excludes options 
     462my $UDP_HEADER_LEN  = 8; 
     463my $ICMP_HEADER_LEN = 4; 
     464my $IP_HEADER_LEN   = 20;  ### excludes options 
    428465 
    429466### save a copy of the command line arguments 
     
    962999 
    9631000    my $pkt_ctr = 0; 
    964     my $print_scale_factor = 0; 
    965  
    966     if ($analyze_msgs) { 
    967         if ($#$fw_packets_aref < 100) { 
    968             $print_scale_factor = $#$fw_packets_aref; 
    969         } else { 
    970             $print_scale_factor = int($#$fw_packets_aref/10); 
    971             if ($print_scale_factor < 100) { 
    972                 $print_scale_factor -= $print_scale_factor % 10; 
    973             } elsif ($print_scale_factor < 1000) { 
    974                 $print_scale_factor -= $print_scale_factor % 100; 
    975             } elsif ($print_scale_factor < 10000) { 
    976                 $print_scale_factor -= $print_scale_factor % 1000; 
    977             } elsif ($print_scale_factor < 100000) { 
    978                 $print_scale_factor -= $print_scale_factor % 10000; 
    979             } elsif ($print_scale_factor < 1000000) { 
    980                 $print_scale_factor -= $print_scale_factor % 100000; 
    981             } else { 
    982                 $print_scale_factor = 50000; 
    983             } 
    984         } 
    985         $print_scale_factor++ if $print_scale_factor == 0; 
    986     } 
    987  
    988     #  Mar 11 13:15:52 orthanc kernel: DROP IN=lo OUT= MAC=00:00:00:00:00:00:00:00: 
    989     #  00:00:00:00:08:00 SRC=127.0.0.1 DST=127.0.0.1 LEN=60 TOS=0x00 PREC=0x00 
    990     #  TTL=64 ID=0 DF PROTO=TCP SPT=44847 DPT=35 WINDOW=32304 RES=0x00 SYN URGP=0 
    991  
    992     PKT: for my $pkt (@$fw_packets_aref) { 
    993         my $src = ''; 
    994         my $dst = ''; 
    995         my $len = -1; 
    996         my $tos = ''; 
    997         my $ttl = -1; 
    998         my $id  = -1; 
    999         my $proto = ''; 
    1000         my $sp    = -1; 
    1001         my $dp    = -1; 
    1002         my $win   = -1; 
    1003         my $type  = -1; 
    1004         my $code  = -1; 
    1005         my $seq   = -1; 
    1006         my $flags = ''; 
    1007         my $frag_bit = 0; 
    1008         my $sid   = 0; 
    1009         my $chain    = ''; 
    1010         my $intf     = ''; 
    1011         my $src_mac  = ''; 
    1012         my $dst_mac  = ''; 
    1013         my $tcp_options = ''; 
    1014         my $dshield_str = ''; 
    1015         my $syslog_host = ''; 
    1016         my $log_prefix  = ''; 
    1017  
    1018         print STDERR $pkt, "\n" if $debug; 
     1001 
     1002    my $print_scale_factor = &get_scale_factor($#$fw_packets_aref); 
     1003 
     1004    ### loop through all of the packet log messages we have just acquired 
     1005    ### from Netfilter/iptables 
     1006 
     1007    PKT: for my $pkt_str (@$fw_packets_aref) { 
     1008 
     1009        ### main packet data structure 
     1010        my %pkt = ( 
     1011 
     1012            ### data link layer 
     1013            'src_mac' => '', 
     1014            'dst_mac' => '', 
     1015            'intf'    => '',   ### FIXME in and out interfaces? 
     1016 
     1017            ### network layer 
     1018            'src'    => '', 
     1019            'dst'    => '', 
     1020            'proto'  => '', 
     1021            'ip_id'  => -1, 
     1022            'ttl'    => -1, 
     1023            'tos'    => '', 
     1024            'ip_len' => -1, 
     1025            'itype'  => -1, 
     1026            'icode'  => -1, 
     1027            'icmp_seq' => -1, 
     1028            'icmp_id'  => -1, 
     1029            'frag_bit' => 0, 
     1030 
     1031            ### transport layer 
     1032            'sp'  => -1, 
     1033            'dp'  => -1, 
     1034            'win' => -1, 
     1035            'flags' => -1, 
     1036            'tcp_seq' => -1, 
     1037            'tcp_ack' => -1, 
     1038            'tcp_opt' => '', 
     1039            'udp_len' => -1, 
     1040 
     1041            ### extra fields for psad internals (DShield reporting, fwsnort 
     1042            ### sid matching, Netfilter logging prefixes and chains, etc.) 
     1043            'fwsnort_sid' => 0, 
     1044            'nf_chain'=> '', 
     1045            'nf_log_prefix' => '', 
     1046            'dshield_str' => '', 
     1047            'syslog_host' => '', 
     1048        ); 
     1049 
    10191050 
    10201051        if ($analyze_msgs) { 
     
    10251056        } 
    10261057 
    1027         ### see if we need to ignore this packet based on the 
    1028         ### IGNORE_PROTOCOLS config keyword. 
    1029         if (%ignore_protocols) { 
    1030             for my $proto (keys %ignore_protocols) { 
    1031                 next PKT if $pkt =~ /\sPROTO=$proto\s/; 
    1032             } 
    1033         } 
    1034  
    1035         ### get the in/out interface and Netfilter chain 
    1036         if ($pkt =~ /IN=(\S+)\s+OUT=\s/) { 
    1037             $intf = $1; 
    1038             $chain = 'INPUT'; 
    1039         } elsif ($pkt =~ /IN=(\S+)\s+OUT=\S/) { 
    1040             $intf = $1; 
    1041             $chain = 'FORWARD'; 
    1042         } elsif ($pkt =~ /IN=\s+OUT=(\S+)/) { 
    1043             $intf = $1; 
    1044             $chain = 'OUTPUT'; 
    1045         } 
    1046  
    1047         if ($pkt =~ /\sMAC=(\S+)/) { 
    1048             my $mac_str = $1; 
    1049             if ($mac_str =~ /^((?:\w{2}\:){6})((?:\w{2}\:){6})/) { 
    1050                 $dst_mac = $1; 
    1051                 $src_mac = $2; 
    1052             } 
    1053         } 
    1054         if ($src_mac) { 
    1055             $src_mac =~ s/:$//; 
    1056             print STDERR "[+] src mac addr: $src_mac\n" if $debug; 
    1057         } 
    1058         if ($dst_mac) { 
    1059             $dst_mac =~ s/:$//; 
    1060             print STDERR "[+] dst mac addr: $dst_mac\n" if $debug; 
    1061         } 
    1062  
    1063         unless ($intf and $chain) { 
    1064             print STDERR "[-] err packet: could not determine ", 
    1065                 "interface and chain.\n" if $debug; 
    1066             push @err_pkts, $pkt; 
     1058        ### main parsing routine for the Netfilter packet logging message 
     1059        my $pkt_parse_rv = &parse_NF_pkt_str(\%pkt, $pkt_str); 
     1060        if ($pkt_parse_rv == $PKT_ERROR) { 
     1061            push @err_pkts, $pkt_str; 
    10671062            next PKT; 
    1068         } 
    1069  
    1070         if (%ignore_interfaces) { 
    1071             for my $ignore_intf (keys %ignore_interfaces) { 
    1072                 next PKT if $intf eq $ignore_intf; 
    1073             } 
    1074         } 
    1075  
    1076         ### get the syslog logging host for this packet 
    1077         if ($pkt =~ /(\S+)\s+kernel:/) { 
    1078             $syslog_host = $1; 
    1079         } elsif ($pkt =~ /^\s*\S+\s+\S+\s+\S+\s+(\S+)/) { 
    1080             ### parsed packet from the beginning where the time portion 
    1081             ### of the syslog message is 
    1082             $syslog_host = $1; 
    1083         } 
    1084  
    1085         ### try to extract a snort sid (generated by fwsnort) from 
    1086         ### the packet 
    1087         unless ($no_snort_sids) { 
    1088             if ($pkt =~ /$config{'SNORT_SID_STR'}(\d+)/) { 
    1089                 $sid = $1; 
    1090             } 
    1091         } 
    1092  
    1093         unless ($sid or $config{'FW_SEARCH_ALL'} eq 'Y') { 
    1094             ### note that this is not _too_ strict since people 
    1095             ### have different ways of writing --log-prefix strings 
    1096             my $matched = 0; 
    1097             for my $fw_search_str (@fw_search) { 
    1098                 $matched = 1 if $pkt =~ /$fw_search_str/; 
    1099             } 
    1100             next PKT unless $matched; 
    1101         } 
    1102  
    1103         ### see if there is a logging prefix (used for scan email alert even 
    1104         ### if we are running with FW_SEARCH_ALL = Y).  Note that sometimes 
    1105         ### there is a buffering issue in the kernel ring buffer that is used 
    1106         ### to hold the Netfilter log message, so we want to get only the 
    1107         ### very last possible candidate for the log prefix (this is why the 
    1108         ### "kernel:" string is preceded by .*). 
    1109         if ($pkt =~ /.*kernel:\s+(.*?)\s*IN=/) { 
    1110             $log_prefix = $1; 
    1111             if ($log_prefix =~ /\S/) { 
    1112                 if ($config{'IGNORE_LOG_PREFIXES'} ne 'NONE') { 
    1113                     next PKT if $log_prefix 
    1114                             =~ m|$config{'IGNORE_LOG_PREFIXES'}|; 
    1115                 } 
    1116                 $ipt_prefixes{$log_prefix}++; 
    1117             } 
    1118         } 
    1119  
    1120         ### May 18 22:21:26 orthanc kernel: DROP IN=eth2 OUT= 
    1121         ### MAC=00:60:1d:23:d0:01:00:60:1d:23:d3:0e:08:00 SRC=192.168.20.25 
    1122         ### DST=192.168.20.1 LEN=60 TOS=0x10 PREC=0x00 TTL=64 ID=47300 DF 
    1123         ### PROTO=TCP SPT=34111 DPT=6345 WINDOW=5840 RES=0x00 SYN URGP=0 
    1124         if ($pkt =~ /SRC=(\S+)\s+DST=(\S+)\s+LEN=(\d+)\s+TOS=(\S+) 
    1125                     \s*.*\s+TTL=(\d+)\s+ID=(\d+)\s*.*\s+PROTO=TCP\s+ 
    1126                     SPT=(\d+)\s+DPT=(\d+)\s.*\s*WINDOW=(\d+)\s+ 
    1127                     (.*)\s+URGP=/x) { 
    1128             ($src, $dst, $len, $tos, $ttl, $id, $sp, $dp, $win, $flags) = 
    1129                 ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10); 
    1130  
    1131             ### the reserve bits are not reported by ulogd, but normal 
    1132             ### Netfilter syslog messages contain them. 
    1133             $flags =~ s/\s*RES=\S+\s*//; 
    1134  
    1135             $proto = 'tcp'; 
    1136  
    1137             $flags = 'NULL' unless $flags;  ### default to NULL 
    1138             if (!$sid && $config{'IGNORE_CONNTRACK_BUG_PKTS'} eq 'Y' && 
    1139                     ($flags =~ /ACK/ || $flags =~ /RST/)) { 
    1140 #                    $dp > 1024 && ($flags =~ /ACK/ || 
    1141                 ### FIXME: ignore TCP packets that have the ACK or RST 
    1142                 ### bits set (unless we matched a snort sid) since 
    1143                 ### _usually_ we see these packets as a result of the 
    1144                 ### Netfilter connection tracking bug.  Also, note that 
    1145                 ### no signatures make use of the RST flag. 
    1146                 print STDERR "[-] err packet: matched ACK or RST flag.\n" 
    1147                     if $debug; 
    1148                 next PKT; 
    1149             } 
    1150             ### per page 595 of the Camel book, "if /blah1|blah2/" 
    1151             ### can be slower than "if /blah1/ || /blah2/ 
    1152             unless ($flags !~ /WIN/ && 
    1153                     $flags =~ /ACK/ || 
    1154                     $flags =~ /SYN/ || 
    1155                     $flags =~ /RST/ || 
    1156                     $flags =~ /URG/ || 
    1157                     $flags =~ /PSH/ || 
    1158                     $flags =~ /FIN/ || 
    1159                     $flags eq 'NULL') { 
    1160                 print STDERR "[-] err packet: bad tcp flags.\n" if $debug; 
    1161                 push @err_pkts, $pkt; 
    1162                 next PKT; 
    1163             } 
    1164             $frag_bit = 1 if $pkt =~ /\sDF\s+PROTO/; 
    1165             ### don't pickup IP options if --log-ip-options is used 
    1166             ### (they appear before the PROTO= field). 
    1167             if ($pkt =~ /URGP=\S+\s+OPT\s+\((\S+)\)/) { 
    1168                 $tcp_options = $1; 
    1169             } 
    1170  
    1171             ### make sure we have a "reasonable" packet (note that nmap 
    1172             ### can scan port 0 and Netfilter can report this fact) 
    1173             unless ($src and $dst and $len >= 0 and $tos and $ttl >= 0 
    1174                     and $id >= 0 and $proto and $sp >= 0 and $dp >= 0 
    1175                     and $win >= 0 and $flags) { 
    1176                 push @err_pkts, $pkt; 
    1177                 next PKT; 
    1178             } 
    1179  
    1180             ### see if we need to ignore this packet based on the 
    1181             ### IGNORE_PORTS config keyword 
    1182             if (%ignore_ports) { 
    1183                 next PKT if &ignore_port($dp, $proto); 
    1184             } 
    1185  
     1063        } elsif ($pkt_parse_rv == $PKT_IGNORE) { 
     1064            next PKT; 
     1065        } 
     1066 
     1067        if ($pkt{'proto'} eq 'tcp') { 
    11861068            $tcp_ctr++; 
    1187  
    1188             if ($config{'ENABLE_DSHIELD_ALERTS'} eq 'Y' 
    1189                     and not $benchmark 
    1190                     and not $analyze_msgs) { 
    1191                 my $dflags = $flags; 
    1192                 $dflags =~ s/\s/,/g; 
    1193                 $dshield_str = "$src\t$sp\t$dst\t$dp\t$proto\t$dflags"; 
    1194             } 
    1195         ### May 18 22:21:26 orthanc kernel: DROP IN=eth2 OUT= 
    1196         ### MAC=00:60:1d:23:d0:01:00:60:1d:23:d3:0e:08:00 
    1197         ### SRC=192.168.20.25 DST=192.168.20.1 LEN=28 TOS=0x00 PREC=0x00 
    1198         ### TTL=40 ID=47523 PROTO=UDP SPT=57339 DPT=305 LEN=8 
    1199         } elsif ($pkt =~ /SRC=(\S+)\s+DST=(\S+)\s+LEN=(\d+)\s+TOS=(\S+) 
    1200                           \s.*TTL=(\d+)\s+ID=(\d+)\s*.*\s+PROTO=UDP\s+ 
    1201                           SPT=(\d+)\s+DPT=(\d+)/x) { 
    1202             ($src, $dst, $len, $tos, $ttl, $id, $sp, $dp) = 
    1203                 ($1,$2,$3,$4,$5,$6,$7,$8); 
    1204             $proto = 'udp'; 
    1205  
    1206             ### make sure we have a "reasonable" packet (note that nmap 
    1207             ### can scan port 0 and Netfilter can report this fact) 
    1208             unless ($src and $dst and $len >= 0 and $tos and $ttl >= 0 
    1209                     and $id >= 0 and $proto and $sp >= 0 and $dp >= 0) { 
    1210                 push @err_pkts, $pkt; 
    1211                 next PKT; 
    1212             } 
    1213  
    1214             ### see if we need to ignore this packet based on the 
    1215             ### IGNORE_PORTS config keyword 
    1216             if (%ignore_ports) { 
    1217                 next PKT if &ignore_port($dp, $proto); 
    1218             } 
    1219  
     1069        } elsif ($pkt{'proto'} eq 'udp') { 
    12201070            $udp_ctr++; 
    1221  
    1222             if ($config{'ENABLE_DSHIELD_ALERTS'} eq 'Y' 
    1223                     and not $benchmark 
    1224                     and not $analyze_msgs) { 
    1225                 $dshield_str = "$src\t$sp\t$dst\t$dp\t$proto"; 
    1226             } 
    1227         } elsif ($pkt =~ /SRC=(\S+)\s+DST=(\S+)\s+LEN=(\d+).* 
    1228                           TTL=(\d+).*PROTO=ICMP\s+TYPE=(\d+)\s+ 
    1229                           CODE=(\d+)\s+ID=(\d+)\s+SEQ=(\d+)/x) { 
    1230             ($src, $dst, $len, $ttl, $type, $code, $id, $seq) = 
    1231                 ($1,$2,$3,$4,$5,$6,$7,$8); 
    1232             $proto = 'icmp'; 
    1233             unless ($src and $dst and $len >= 0 and $ttl >= 0 and $proto 
    1234                     and $type >= 0 and $code >= 0 and $id >= 0 
    1235                     and $seq >= 0) { 
    1236                 push @err_pkts, $pkt; 
    1237                 next PKT; 
    1238             } 
     1071        } elsif ($pkt{'proto'} eq 'icmp') { 
    12391072            $icmp_ctr++; 
    1240  
    1241             if ($config{'ENABLE_DSHIELD_ALERTS'} eq 'Y' 
    1242                     and not $benchmark 
    1243                     and not $analyze_msgs) { 
    1244                 $dshield_str = "$src\t$type\t$dst\t$code\t$proto"; 
    1245             } 
    1246         } else { 
    1247             ### Sometimes the Netfilter log entry gets messed up due to 
    1248             ### buffering issues so we write it to the error log. 
    1249             print STDERR "[-] err packet: no regex match.\n" if $debug; 
    1250             push @err_pkts, $pkt; 
    1251             next PKT; 
    12521073        } 
    12531074 
    12541075        ### If we made it here then we correctly matched packets 
    12551076        ### that the firewall logged. 
    1256         print STDERR "[+] valid packet: $src -> $dst $proto\n" if $debug; 
     1077        print STDERR "[+] valid packet: $pkt{'src'} -> $pkt{'dst'} ", 
     1078            "$pkt{'proto'}\n" if $debug; 
    12571079 
    12581080        ### initialize the danger level to 0 if it is not already defined 
     
    12601082        ### different destination IP, so the danger level represents the 
    12611083        ### aggregate danger level). 
    1262         unless (defined $scan_dl{$src}) { 
    1263             $scan_dl{$src} = 0; 
    1264             $scan{$src}{$dst}{'alerted'} = 0 
     1084        unless (defined $scan_dl{$pkt{'src'}}) { 
     1085            $scan_dl{$pkt{'src'}} = 0; 
     1086            $scan{$pkt{'src'}}{$pkt{'dst'}}{'alerted'} = 0 
    12651087                if $config{'ALERT_ALL'} eq 'N'; 
    12661088        } 
     
    12701092        ### -1 if there is no auto-assigned danger level. 
    12711093        unless ($no_auto_dl) { 
    1272             my $rv = &assign_auto_danger_level($src, $proto, $dp); 
    1273             if ($debug) { 
    1274                 print STDERR "[+] assign_auto_danger_level() returned: $rv\n"; 
    1275             } 
     1094            my $rv = &assign_auto_danger_level($pkt{'src'}, $pkt{'proto'}, 
     1095                        $pkt{'dp'}); 
     1096 
     1097            print STDERR "[+] assign_auto_danger_level() returned: $rv\n" 
     1098                if $debug; 
    12761099            if ($rv == 0) { 
    1277                 print STDERR "[+] ignoring $src $proto $dp scan.\n" if $debug; 
     1100                print STDERR "[+] ignoring $pkt{'src'} $pkt{'proto'} ", 
     1101                    "$pkt{'dp'} scan.\n" if $debug; 
    12781102                next PKT; 
    12791103            } 
     
    12861110                and not $benchmark 
    12871111                and not $analyze_msgs 
    1288                 and $dshield_str) { 
    1289             if ($pkt =~ /^\s*(\w+)\s+(\d+)\s+(\S+)/) { 
     1112                and $pkt{'dshield_str'}) { 
     1113            if ($pkt_str =~ /^\s*(\w+)\s+(\d+)\s+(\S+)/) { 
    12901114                my $month   = Decode_Month($1); 
    12911115                my $day     = sprintf("%.2d", $2); 
     
    12931117                push @dshield_data, "$year-$month-$day $time_24 " . 
    12941118                    "$timezone\t$config{'DSHIELD_USER_ID'}\t1" . 
    1295                     "\t$dshield_str\n"; 
     1119                    "\t$pkt{'dshield_str'}\n"; 
    12961120            } 
    12971121        } 
     
    12991123        ### see if we need to timeout any old scans 
    13001124        if ($config{'ENABLE_PERSISTENCE'} eq 'N') { 
    1301             if (defined $scan{$src}{$dst}{'s_time'}) { 
    1302                 if ((time() - $scan{$src}{$dst}{'s_time'}) 
     1125            if (defined $scan{$pkt{'src'}}{$pkt{'dst'}}{'s_time'}) { 
     1126                if ((time() - $scan{$pkt{'src'}}{$pkt{'dst'}}{'s_time'}) 
    13031127                        >= $config{'SCAN_TIMEOUT'}) { 
    1304                     delete $scan{$src}{$dst}; 
     1128                    delete $scan{$pkt{'src'}}{$pkt{'dst'}}; 
    13051129                } 
    13061130            } 
     
    13081132 
    13091133        ### record the absolute starting time of the scan 
    1310         unless (defined $scan{$src}{$dst}{'s_time'}) { 
     1134        unless (defined $scan{$pkt{'src'}}{$pkt{'dst'}}{'s_time'}) { 
    13111135            if ($analyze_msgs) { 
    1312                 if ($pkt =~ /^(.*?)\s+\S+\s+kernel:/) { 
    1313                     $scan{$src}{$dst}{'s_time'} = $1; 
    1314                 } elsif ($pkt =~ /^\s*(\S+\s+\S+\s+\S+)/) { 
    1315                     $scan{$src}{$dst}{'s_time'} = $1; 
     1136                if ($pkt_str =~ /^(.*?)\s+\S+\s+kernel:/) { 
     1137                    $scan{$pkt{'src'}}{$pkt{'dst'}}{'s_time'} = $1; 
     1138                } elsif ($pkt_str =~ /^\s*(\S+\s+\S+\s+\S+)/) { 
     1139                    $scan{$pkt{'src'}}{$pkt{'dst'}}{'s_time'} = $1; 
    13161140                } else { 
    1317                     die "[*] Could not extract time from packet: $pkt\n", 
     1141                    die "[*] Could not extract time from packet: $pkt_str\n", 
    13181142                        "    Please send a bug report to: ", 
    13191143                        "mbr\@cipherdyne.org\n"; 
    13201144                } 
    13211145            } else { 
    1322                 $scan{$src}{$dst}{'s_time'} = time(); 
     1146                $scan{$pkt{'src'}}{$pkt{'dst'}}{'s_time'} = time(); 
    13231147            } 
    13241148        } 
    13251149 
    13261150        ### increment hash values 
    1327         $scan{$src}{$dst}{'absnum'}++; 
    1328         $scan{$src}{$dst}{'chain'}{$chain}{$intf}{$proto}++; 
    1329         $curr_scan{$src}{$dst}{$proto}{'pkts'}++; 
    1330         $curr_scan{$src}{$dst}{$proto}{'flags'}{$flags}++ 
    1331             if $flags; 
     1151        $scan{$pkt{'src'}}{$pkt{'dst'}}{'absnum'}++; 
     1152        $scan{$pkt{'src'}}{$pkt{'dst'}}{'chain'} 
     1153            {$pkt{'nf_chain'}}{$pkt{'intf'}}{$pkt{'proto'}}++; 
     1154        $curr_scan{$pkt{'src'}}{$pkt{'dst'}}{$pkt{'proto'}}{'pkts'}++; 
     1155        $curr_scan{$pkt{'src'}}{$pkt{'dst'}} 
     1156            {$pkt{'proto'}}{'flags'}{$pkt{'flags'}}++ if $pkt{'flags'}; 
    13321157 
    13331158        ### keep track of MAC addresses 
    1334         $curr_scan{$src}{$dst}{'s_mac'} = $src_mac
    1335         $curr_scan{$src}{$dst}{'d_mac'} = $dst_mac
     1159        $curr_scan{$pkt{'src'}}{$pkt{'dst'}}{'s_mac'} = $pkt{'src_mac'}
     1160        $curr_scan{$pkt{'src'}}{$pkt{'dst'}}{'d_mac'} = $pkt{'dst_mac'}
    13361161 
    13371162        ### keep track of which syslog daemon reported the message. 
    1338         $curr_scan{$src}{$dst}{'syslog_host'}{$syslog_host} = '' 
    1339             if $syslog_host
    1340  
    1341         if ($log_prefix) { 
     1163        $curr_scan{$pkt{'src'}}{$pkt{'dst'}}{'syslog_host'} 
     1164            {$pkt{'syslog_host'}} = '' if $pkt{'syslog_host'}
     1165 
     1166        if ($pkt{'nf_log_prefix'}) { 
    13421167            ### see if the logging prefix matches the blocking 
    13431168            ### regex, and if not the IP will not be blocked 
     
    13461171                    and $config{'AUTO_BLOCK_REGEX'} ne 'NONE') { 
    13471172                ### we require a match 
    1348                 if (not defined $auto_block_regex_match{$src
    1349                     and $log_prefix =~ /$config{'AUTO_BLOCK_REGEX'}/) { 
    1350                     $auto_block_regex_match{$src} = ''; 
     1173                if (not defined $auto_block_regex_match{$pkt{'src'}
     1174                    and $pkt{'nf_log_prefix'} =~ /$config{'AUTO_BLOCK_REGEX'}/) { 
     1175                    $auto_block_regex_match{$pkt{'src'}} = ''; 
    13511176                } 
    13521177            } 
    13531178        } else { 
    1354             $log_prefix = '*noprfx*'; 
     1179            $pkt{'nf_log_prefix'} = '*noprfx*'; 
    13551180        } 
    13561181 
    13571182        ### keep track of Netfilter chain and logging prefix 
    1358         $curr_scan{$src}{$dst}{$proto}{'chain'} 
    1359                 {$chain}{$log_prefix}++; 
    1360  
    1361         unless ($proto eq 'icmp') { 
     1183        $curr_scan{$pkt{'src'}}{$pkt{'dst'}}{$pkt{'proto'}}{'chain'} 
     1184                {$pkt{'nf_chain'}}{$pkt{'nf_log_prefix'}}++; 
     1185 
     1186        unless ($pkt{'proto'} eq 'icmp') { 
    13621187            ### initialize the start and end port for the scanned port range 
    1363             if (not defined $curr_scan{$src}{$dst}{$proto}{'strtp'}) { 
     1188            if (not defined $curr_scan{$pkt{'src'}}{$pkt{'dst'}}{$pkt{'proto'}}{'strtp'}) { 
    13641189                ### make sure the initial start port is not too low 
    1365                 $curr_scan{$src}{$dst}{$proto}{'strtp'} = 65535; 
     1190                $curr_scan{$pkt{'src'}}{$pkt{'dst'}}{$pkt{'proto'}}{'strtp'} = 65535; 
    13661191                ### make sure the initial end port is not too high 
    1367                 $curr_scan{$src}{$dst}{$proto}{'endp'} = 0; 
    1368             } 
    1369             if (not defined $scan{$src}{$dst}{$proto}{'abs_sp'}) { 
     1192                $curr_scan{$pkt{'src'}}{$pkt{'dst'}}{$pkt{'proto'}}{'endp'} = 0; 
     1193            } 
     1194            if (not defined $scan{$pkt{'src'}}{$pkt{'dst'}}{$pkt{'proto'}}{'abs_sp'}) { 
    13701195                ### This is the absolute starting port since the 
    13711196                ### first packet was detected.  Make sure the initial 
    13721197                ### start port is not too low 
    1373                 $scan{$src}{$dst}{$proto}{'abs_sp'} = 65535; 
     1198                $scan{$pkt{'src'}}{$pkt{'dst'}}{$pkt{'proto'}}{'abs_sp'} = 65535; 
    13741199                ### make sure the initial end port is not too high 
    1375                 $scan{$src}{$dst}{$proto}{'abs_ep'} = 0; 
     1200                $scan{$pkt{'src'}}{$pkt{'dst'}}{$pkt{'proto'}}{'abs_ep'} = 0; 
    13761201            } 
    13771202 
    13781203            ### see if the destination port lies outside our current range 
    13791204            ### and change if needed 
    1380             ($curr_scan{$src}{$dst}{$proto}{'strtp'}, 
    1381                     $curr_scan{$src}{$dst}{$proto}{'endp'}) = 
    1382                 &check_range($dp
    1383                     $curr_scan{$src}{$dst}{$proto}{'strtp'}, 
    1384                     $curr_scan{$src}{$dst}{$proto}{'endp'}); 
    1385             ($scan{$src}{$dst}{$proto}{'abs_sp'}, 
    1386                     $scan{$src}{$dst}{$proto}{'abs_ep'}) = 
    1387                 &check_range($dp
    1388                     $scan{$src}{$dst}{$proto}{'abs_sp'}, 
    1389                     $scan{$src}{$dst}{$proto}{'abs_ep'}); 
    1390         } 
    1391  
    1392         print STDERR Dumper $scan{$src}{$dst} if $debug and $verbose; 
     1205            ($curr_scan{$pkt{'src'}}{$pkt{'dst'}}{$pkt{'proto'}}{'strtp'}, 
     1206                    $curr_scan{$pkt{'src'}}{$pkt{'dst'}}{$pkt{'proto'}}{'endp'}) = 
     1207                &check_range($pkt{'dp'}
     1208                    $curr_scan{$pkt{'src'}}{$pkt{'dst'}}{$pkt{'proto'}}{'strtp'}, 
     1209                    $curr_scan{$pkt{'src'}}{$pkt{'dst'}}{$pkt{'proto'}}{'endp'}); 
     1210            ($scan{$pkt{'src'}}{$pkt{'dst'}}{$pkt{'proto'}}{'abs_sp'}, 
     1211                    $scan{$pkt{'src'}}{$pkt{'dst'}}{$pkt{'proto'}}{'abs_ep'}) = 
     1212                &check_range($pkt{'dp'}
     1213                    $scan{$pkt{'src'}}{$pkt{'dst'}}{$pkt{'proto'}}{'abs_sp'}, 
     1214                    $scan{$pkt{'src'}}{$pkt{'dst'}}{$pkt{'proto'}}{'abs_ep'}); 
     1215        } 
     1216 
     1217        print STDERR Dumper $scan{$pkt{'src'}}{$pkt{'dst'}} if $debug and $verbose; 
    13931218 
    13941219        ### attempt to passively guess the remote operating 
     
    14011226            ### and if we have been unsuccessful in guessing 
    14021227            ### the OS after 100 packets don't keep trying. 
    1403             if ($proto eq 'tcp' and $flags =~ /SYN/) { 
    1404                 if ($tcp_options) {  ### got the tcp options portion of the header 
     1228            if ($pkt{'proto'} eq 'tcp' and $pkt{'flags'} =~ /SYN/) { 
     1229                if ($pkt{'tcp_opt'}) {  ### got the tcp options portion of the header 
    14051230 
    14061231                    ### p0f based fingerprinting 
    1407                     &p0f($src, $len, $frag_bit, $ttl, $win, $tcp_options); 
    1408  
    1409                 } elsif (not defined $posf{$src}{'guess'} 
    1410                         and $scan{$src}{$dst}{'absnum'} < 100) { 
    1411                     &posf($src, $len, $tos, $ttl, $id, $win) 
    1412                 } 
    1413             } 
    1414         } 
    1415  
    1416         if ($sid and not $no_snort_sids) { 
     1232                    &p0f($pkt{'src'}, $pkt{'ip_len'}, $pkt{'frag_bit'}, 
     1233                            $pkt{'ttl'}, $pkt{'win'}, $pkt{'tcp_opt'}); 
     1234 
     1235                } elsif (not defined $posf{$pkt{'src'}}{'guess'} 
     1236                        and $scan{$pkt{'src'}}{$pkt{'dst'}}{'absnum'} < 100) { 
     1237                    &posf($pkt{'src'}, $pkt{'ip_len'}, $pkt{'tos'}, 
     1238                            $pkt{'ttl'}, $pkt{'ip_id'}, $pkt{'win'}) 
     1239                } 
     1240            } 
     1241        } 
     1242 
     1243        if ($pkt{'fwsnort_sid'} and not $no_snort_sids) { 
    14171244            ### found a snort sid in the packet log message 
    1418             my $dl = &add_snort_sid($src, $dst
    1419                 $chain, $proto, $sid); 
    1420             $curr_sids_dl{$src} = $dl if $dl; 
     1245            my $dl = &add_snort_sid($pkt{'src'}, $pkt{'dst'}
     1246                $pkt{'nf_chain'}, $pkt{'proto'}, $pkt{'fwsnort_sid'}); 
     1247            $curr_sids_dl{$pkt{'src'}} = $dl if $dl; 
    14211248        } else { 
    14221249            ### attempt to match any tcp/udp/icmp signatures in the 
    14231250            ### main signatures hash 
    14241251            unless ($no_signatures) { 
    1425                 my $dl = &match_sigs($src, $dst, $chain, $sp, 
    1426                     $dp, $proto, $flags, $len, $ttl, 
    1427                     $type, $code, $id, $seq); 
    1428                 $curr_sigs_dl{$src} = $dl if $dl; 
     1252 
     1253                my $dl = &match_sigs(\%pkt); 
     1254 
     1255                $curr_sigs_dl{$pkt{'src'}} = $dl if $dl; 
    14291256            } 
    14301257        } 
     
    14621289} 
    14631290 
     1291sub parse_NF_pkt_str() { 
     1292    my ($pkt_hr, $pkt_str) = @_; 
     1293 
     1294    print STDERR $pkt_str, "\n" if $debug; 
     1295 
     1296    ### see if there is a logging prefix (used for scan email alert even 
     1297    ### if we are running with FW_SEARCH_ALL = Y).  Note that sometimes 
     1298    ### there is a buffering issue in the kernel ring buffer that is used 
     1299    ### to hold the Netfilter log message, so we want to get only the 
     1300    ### very last possible candidate for the log prefix (this is why the 
     1301    ### "kernel:" string is preceded by .*). 
     1302    if ($pkt_str =~ /.*kernel:\s+(.*?)\s*IN=/) { 
     1303        $pkt_hr->{'nf_log_prefix'} = $1; 
     1304        if ($pkt_hr->{'nf_log_prefix'} =~ /\S/) { 
     1305            if ($config{'IGNORE_LOG_PREFIXES'} ne 'NONE') { 
     1306                return $PKT_IGNORE if $pkt_hr->{'nf_log_prefix'} 
     1307                        =~ m|$config{'IGNORE_LOG_PREFIXES'}|; 
     1308            } 
     1309            $ipt_prefixes{$pkt_hr->{'nf_log_prefix'}}++; 
     1310        } 
     1311    } 
     1312 
     1313    ### get the in/out interface and Netfilter chain 
     1314    if ($pkt_str =~ /IN=(\S+)\s+OUT=\s/) { 
     1315        $pkt_hr->{'intf'} = $1; 
     1316        $pkt_hr->{'chain'} = 'INPUT'; 
     1317    } elsif ($pkt_str =~ /IN=(\S+)\s+OUT=\S/) { 
     1318        $pkt_hr->{'intf'} = $1; 
     1319        $pkt_hr->{'chain'} = 'FORWARD'; 
     1320    } elsif ($pkt_str =~ /IN=\s+OUT=(\S+)/) { 
     1321        $pkt_hr->{'intf'} = $1; 
     1322        $pkt_hr->{'chain'} = 'OUTPUT'; 
     1323    } 
     1324 
     1325    if ($pkt_str =~ /\sMAC=(\S+)/) { 
     1326        my $mac_str = $1; 
     1327        if ($mac_str =~ /^((?:\w{2}\:){6})((?:\w{2}\:){6})/) { 
     1328            $pkt_hr->{'dst_mac'} = $1; 
     1329            $pkt_hr->{'src_mac'} = $2; 
     1330        } 
     1331    } 
     1332    if ($pkt_hr->{'src_mac'}) { 
     1333        $pkt_hr->{'src_mac'} =~ s/:$//; 
     1334        print STDERR "[+] src mac addr: $pkt_hr->{'src_mac'}\n" if $debug; 
     1335    } 
     1336    if ($pkt_hr->{'dst_mac'}) { 
     1337        $pkt_hr->{'dst_mac'} =~ s/:$//; 
     1338        print STDERR "[+] dst mac addr: $pkt_hr->{'dst_mac'}\n" if $debug; 
     1339    } 
     1340 
     1341    unless ($pkt_hr->{'intf'} and $pkt_hr->{'chain'}) { 
     1342        print STDERR "[-] err packet: could not determine ", 
     1343            "interface and chain.\n" if $debug; 
     1344        return $PKT_ERROR; 
     1345    } 
     1346 
     1347    if (%ignore_interfaces) { 
     1348        for my $ignore_intf (keys %ignore_interfaces) { 
     1349            return $PKT_IGNORE if $pkt_hr->{'intf'} eq $ignore_intf; 
     1350        } 
     1351    } 
     1352 
     1353    ### get the syslog logging host for this packet 
     1354    if ($pkt_str =~ /(\S+)\s+kernel:/) { 
     1355        $pkt_hr->{'syslog_host'} = $1; 
     1356    } elsif ($pkt_str =~ /^\s*\S+\s+\S+\s+\S+\s+(\S+)/) { 
     1357        ### parsed packet from the beginning where the time portion 
     1358        ### of the syslog message is 
     1359        $pkt_hr->{'syslog_host'} = $1; 
     1360    } 
     1361 
     1362    ### try to extract a snort sid (generated by fwsnort) from 
     1363    ### the packet 
     1364    unless ($no_snort_sids) { 
     1365        if ($pkt_str =~ /$config{'SNORT_SID_STR'}(\d+)/) { 
     1366            $pkt_hr->{'fwsnort_sid'} = $1; 
     1367        } 
     1368    } 
     1369 
     1370    unless ($pkt_hr->{'fwsnort_sid'} or $config{'FW_SEARCH_ALL'} eq 'Y') { 
     1371        ### note that this is not _too_ strict since people 
     1372        ### have different ways of writing --log-prefix strings 
     1373        my $matched = 0; 
     1374        for my $fw_search_str (@fw_search) { 
     1375            $matched = 1 if $pkt_str =~ /$fw_search_str/; 
     1376        } 
     1377        return $PKT_IGNORE unless $matched; 
     1378    } 
     1379 
     1380    ### May 18 22:21:26 orthanc kernel: DROP IN=eth2 OUT= 
     1381    ### MAC=00:60:1d:23:d0:01:00:60:1d:23:d3:0e:08:00 SRC=192.168.20.25 
     1382    ### DST=192.168.20.1 LEN=60 TOS=0x10 PREC=0x00 TTL=64 ID=47300 DF 
     1383    ### PROTO=TCP SPT=34111 DPT=6345 WINDOW=5840 RES=0x00 SYN URGP=0 
     1384 
     1385    if ($pkt_str =~ /SRC=($ip_re)\s+DST=($ip_re)\s+LEN=(\d+)\s+TOS=(\S+) 
     1386                \s*.*\s+TTL=(\d+)\s+ID=(\d+)\s*.*\s+PROTO=TCP\s+ 
     1387                SPT=(\d+)\s+DPT=(\d+)\s.*\s*WINDOW=(\d+)\s+ 
     1388                (.*)\s+URGP=/x) { 
     1389 
     1390        ($pkt_hr->{'src'}, $pkt_hr->{'dst'}, $pkt_hr->{'ip_len'}, 
     1391            $pkt_hr->{'tos'}, $pkt_hr->{'ttl'}, $pkt_hr->{'ip_id'}, 
     1392            $pkt_hr->{'sp'}, $pkt_hr->{'dp'}, $pkt_hr->{'win'}, 
     1393            $pkt_hr->{'flags'}) 
     1394                = ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10); 
     1395 
     1396        ### the reserve bits are not reported by ulogd, but normal 
     1397        ### Netfilter syslog messages contain them. 
     1398        $pkt_hr->{'flags'} =~ s/\s*RES=\S+\s*//; 
     1399 
     1400        $pkt_hr->{'proto'} = 'tcp'; 
     1401 
     1402        ### default to NULL 
     1403        $pkt_hr->{'flags'} = 'NULL' unless $pkt_hr->{'flags'}; 
     1404 
     1405        if (not $pkt_hr->{'fwsnort_sid'} 
     1406                and $config{'IGNORE_CONNTRACK_BUG_PKTS'} eq 'Y' && 
     1407                ($pkt_hr->{'flags'} =~ /ACK/ || $pkt_hr->{'flags'} =~ /RST/)) { 
     1408 
     1409###                 $dp > 1024 && ($pkt_hr->{'flags'} =~ /ACK/ || 
     1410 
     1411            ### FIXME: ignore TCP packets that have the ACK or RST 
     1412            ### bits set (unless we matched a snort sid) since 
     1413            ### _usually_ we see these packets as a result of the 
     1414            ### Netfilter connection tracking bug.  Also, note that 
     1415            ### no signatures make use of the RST flag. 
     1416 
     1417            print STDERR "[-] err packet: matched ACK or RST flag.\n" 
     1418                if $debug; 
     1419            return $PKT_IGNORE; 
     1420        } 
     1421        ### per page 595 of the Camel book, "if /blah1|blah2/" 
     1422        ### can be slower than "if /blah1/ || /blah2/ 
     1423        unless ($pkt_hr->{'flags'} !~ /WIN/ && 
     1424                $pkt_hr->{'flags'} =~ /ACK/ || 
     1425                $pkt_hr->{'flags'} =~ /SYN/ || 
     1426                $pkt_hr->{'flags'} =~ /RST/ || 
     1427                $pkt_hr->{'flags'} =~ /URG/ || 
     1428                $pkt_hr->{'flags'} =~ /PSH/ || 
     1429                $pkt_hr->{'flags'} =~ /FIN/ || 
     1430                $pkt_hr->{'flags'} eq 'NULL') { 
     1431 
     1432            print STDERR "[-] err packet: bad tcp flags.\n" if $debug; 
     1433            return $PKT_ERROR; 
     1434        } 
     1435        $pkt_hr->{'frag_bit'} = 1 if $pkt_str =~ /\sDF\s+PROTO/; 
     1436 
     1437        ### don't pickup IP options if --log-ip-options is used 
     1438        ### (they appear before the PROTO= field). 
     1439        if ($pkt_str =~ /URGP=\S+\s+OPT\s+\((\S+)\)/) { 
     1440            $pkt_hr->{'tcp_opt'} = $1; 
     1441        } 
     1442 
     1443        ### make sure we have a "reasonable" packet (note that nmap 
     1444        ### can scan port 0 and Netfilter can report this fact) 
     1445        unless ($pkt_hr->{'ip_len'} >= 0 and $pkt_hr->{'tos'} 
     1446                and $pkt_hr->{'ttl'} >= 0 and $pkt_hr->{'ip_id'} >= 0 
     1447                and $pkt_hr->{'proto'} and $pkt_hr->{'sp'} >= 0 
     1448                and $pkt_hr->{'dp'} >= 0 and $pkt_hr->{'win'} >= 0 
     1449                and $pkt_hr->{'flags'}) { 
     1450            return $PKT_ERROR; 
     1451        } 
     1452 
     1453        ### see if we need to ignore this packet based on the 
     1454        ### IGNORE_PORTS config keyword 
     1455        return $PKT_IGNORE if &check_ignore_port($pkt_hr->{'dp'}, 
     1456                $pkt_hr->{'proto'}); 
     1457 
     1458        if ($config{'ENABLE_DSHIELD_ALERTS'} eq 'Y' 
     1459                and not $benchmark 
     1460                and not $analyze_msgs) { 
     1461 
     1462            my $dflags = $pkt_hr->{'flags'}; 
     1463            $dflags =~ s/\s/,/g; 
     1464 
     1465            $pkt_hr->{'dshield_str'} = "$pkt_hr->{'src'}\t$pkt_hr->{'sp'}\t" . 
     1466                "$pkt_hr->{'dst'}\t$pkt_hr->{'dp'}\t$pkt_hr->{'proto'}\t" . 
     1467                "$dflags"; 
     1468        } 
     1469 
     1470    ### May 18 22:21:26 orthanc kernel: DROP IN=eth2 OUT= 
     1471    ### MAC=00:60:1d:23:d0:01:00:60:1d:23:d3:0e:08:00 
     1472    ### SRC=192.168.20.25 DST=192.168.20.1 LEN=28 TOS=0x00 PREC=0x00 
     1473    ### TTL=40 ID=47523 PROTO=UDP SPT=57339 DPT=305 LEN=8 
     1474 
     1475    } elsif ($pkt_str =~ /SRC=($ip_re)\s+DST=($ip_re)\s+LEN=(\d+)\s+TOS=(\S+) 
     1476                      \s.*TTL=(\d+)\s+ID=(\d+)\s*.*\s+PROTO=UDP\s+ 
     1477                      SPT=(\d+)\s+DPT=(\d+)\s+LEN=(\d+)/x) { 
     1478 
     1479        ($pkt_hr->{'src'}, $pkt_hr->{'dst'}, $pkt_hr->{'ip_len'}, 
     1480            $pkt_hr->{'tos'}, $pkt_hr->{'ttl'}, $pkt_hr->{'ip_id'}, 
     1481            $pkt_hr->{'sp'}, $pkt_hr->{'dp'}, $pkt_hr->{'udp_len'}) 
     1482                = ($1,$2,$3,$4,$5,$6,$7,$8,$9); 
     1483 
     1484        $pkt_hr->{'proto'} = 'udp'; 
     1485 
     1486        ### make sure we have a "reasonable" packet (note that nmap 
     1487        ### can scan port 0 and Netfilter can report this fact) 
     1488        unless ($pkt_hr->{'ip_len'} >= 0 
     1489                and $pkt_hr->{'tos'} and $pkt_hr->{'ttl'} >= 0 
     1490                and $pkt_hr->{'ip_id'} >= 0 and $pkt_hr->{'proto'} 
     1491                and $pkt_hr->{'sp'} >= 0 and $pkt_hr->{'dp'} >= 0 
     1492                and $pkt_hr->{'udp_len'} >= 0) { 
     1493 
     1494            return $PKT_ERROR; 
     1495        } 
     1496 
     1497        ### see if we need to ignore this packet based on the 
     1498        ### IGNORE_PROTOCOLS config keyword. 
     1499        return $PKT_IGNORE if &check_ignore_proto($pkt_hr->{'proto'}); 
     1500 
     1501        ### see if we need to ignore this packet based on the 
     1502        ### IGNORE_PORTS config keyword 
     1503        return $PKT_IGNORE if &check_ignore_port($pkt_hr->{'dp'}, 
     1504                $pkt_hr->{'proto'}); 
     1505 
     1506        if ($config{'ENABLE_DSHIELD_ALERTS'} eq 'Y' 
     1507                and not $benchmark 
     1508                and not $analyze_msgs) { 
     1509 
     1510            $pkt_hr->{'dshield_str'} = "$pkt_hr->{'src'}\t$pkt_hr->{'sp'}\t" . 
     1511                "$pkt_hr->{'dst'}\t$pkt_hr->{'dp'}\t$pkt_hr->{'proto'}"; 
     1512        } 
     1513 
     1514    ### Nov 27 15:45:51 orthanc kernel: DROP IN=eth1 OUT= MAC=00:a0:cc:e2:1f:f2:00: 
     1515    ### 20:78:10:70:e7:08:00 SRC=192.168.10.20 DST=192.168.10.1 LEN=84 TOS=0x00 
     1516    ### PREC=0x00 TTL=64 ID=0 DF PROTO=ICMP TYPE=8 CODE=0 ID=61055 SEQ=256 
     1517 
     1518    } elsif ($pkt_str =~ /SRC=($ip_re)\s+DST=($ip_re)\s+LEN=(\d+).* 
     1519                      TTL=(\d+)\s+ID=(\d+).*PROTO=ICMP\s+TYPE=(\d+)\s+ 
     1520                      CODE=(\d+)\s+ID=(\d+)\s+SEQ=(\d+)/x) { 
     1521 
     1522        ($pkt_hr->{'src'}, $pkt_hr->{'dst'}, $pkt_hr->{'ip_len'}, 
     1523            $pkt_hr->{'ttl'}, $pkt_hr->{'ip_id'}, $pkt_hr->{'itype'}, 
     1524