Re: Logwatch Exim script

Chris Wilson <[email protected]>
Newsgroups gmane.comp.log.logwatch.devel
Message-ID <alpine.LRH.2.00.0908231623420.24717@localhost>
Dear sirs,

I've done some more work on "improving" the exim script. At least it works well 
for me now. Please find a new, much more invasive patch attached.

Changes made by this patch:

* Fix the control of display of restarts and queue runs to work properly
    (was using the wrong variable name).

* Increase detail level required to display restarts and queue runs to 10,
    as these are completely normal, expected and boring events IMHO.

* Add a new configuration option to set the detail level required to
    display "relaying denied" (Bad Hosts) messages grouped by type (not by
    type and host). This reduces ~600 lines per day, in my case, to nine:

  --- Refused Relays 249 times

   --- Bad Hosts ---
     Rejected HELO/EHLO: Invalid HELO: 328 times
     Rejected HELO/EHLO: You are SO lying: 28 times
     Rejected HELO/EHLO: syntactically invalid argument(s): 3 times
     SMTP protocol synchronization error: 1 times
     Sudden disconnect while expecting remote input: 81 times

   --- SMTP Connection Issues
     SMTP Timeout errors: 3 Time(s)

    I find this level of detail much more appropriate, as I don't care for
    the IP addresses of random spambots and would rather see the real errors
    than the noise. The info above is displayed at level 5 or above by
    default, and the original detailed log lines at level 10 or above.

* Add a new configuration option for display of DNS lookup failures. Again
    I find these uninteresting and noisy. Default level is 10.

* "SMTP connection from" regex would match some unexpected lines,
    including DNS lookup failures, and misclassify them as SMTP protocol
    errors.

* Ignore "Warning: HELO verify failed" as in previous patch.

* Detect "rejected EHLO or HELO" and process similarly to "rejected HELO"
    and "rejected EHLO" (similar to previous patch but works better).

* Remove redundant information from "no IP address found for host" lines.

* Rename variables $mid, $aa, $bb and $cc to reflect their purpose and
    make the code easier to read.

* Rationalise the SMTP/Bad Host errors a bit, by putting messages into
    either one or the other depending on whether I think a well-behaved host
    might cause it in normal operation.

* Improve consistency of line indenting a bit to make the output neater.

I hope you will consider my patch and merge it into Logwatch, or let me know 
what I can do to improve it.

I also find the choice of three-space indents and lack of "use warnings" 
and "use strict" in this script baffling and difficult to work with. Can 
anyone tell me the reasons behind it?

Cheers, Chris.
-- 
_____ __     _
\  __/ / ,__(_)_  | Chris Wilson <0000 at qwirx.com> - Cambs UK |
/ (_/ ,\/ _/ /_ \ | Security/C/C++/Java/Ruby/Perl/SQL Developer |
\__/_/_/_//_/___/ | We are GNU : free your mind & your software |

_______________________________________________
Logwatch-Devel mailing list
[email protected]
http://www2.list.logwatch.org:81/mailman/listinfo/logwatch-devel
logwatch-exim.patch (text/plain, 19.8 KB)
--- /usr/share/logwatch/scripts/services/exim.orig	2009-08-23 10:41:51.000000000 +0100
+++ /usr/share/logwatch/scripts/services/exim	2009-08-23 16:17:55.000000000 +0100
@@ -44,11 +44,12 @@
 #        Prints administrative rejections (by category)
 #        Prints Refused Relay count
 #
-#     5: Prints Queue Run count
-#        Prints server Stop/Start
+#     5: Prints Refused Relay reasons
 #
 #    10: Prints Refused Relay (individual lines)
 #        Prints Per Message Tracking
+#        Prints server restarts and queue runs
+#        Prints DNS lookup errors
 ########################################################
 
 use Logwatch ':dates';
@@ -56,18 +57,22 @@
 $Detail       = $ENV{'LOGWATCH_DETAIL_LEVEL'}  || 0;
 
 $LvlBadFormat    = $ENV{'exim_misformat'}     || 0;
-$LvlRestarts     = $ENV{'exim_restart'}       || 5;
+$LvlRestarts     = $ENV{'exim_restart'}       || 10;
 $LvlVirus        = $ENV{'exim_virus'}         || 0;
 $LvlProtocl      = $ENV{'exim_protocol'}      || 0;
 $LvlProtoclLines = $ENV{'exim_protocol_lines'}|| 5;
 $LvlDontAccept   = $ENV{'exim_dontaccept'}    || 0;
-$LvlDontAcceptLines = $ENV{'exim_dontaccept_lines'}    || 0;
+$LvlDontAcceptLines = $ENV{'exim_dontaccept_lines'} || 0;
 $LvlVerify       = $ENV{'exim_verify'}        || 0;
 $LvlVerifyLines  = $ENV{'exim_verify_lines'}  || 5;
 $LvlRuns         = $ENV{'exim_runs'}          || 5;
 $LvlRelay        = $ENV{'exim_relay'}         || 0;
 $LvlRelayLines   = $ENV{'exim_relay_lines'}   || 10;
+$LvlRelayReasons = $ENV{'exim_relay_reasons'} || 5;
 $LvlMsgs         = $ENV{'exim_mesgs'}         || 10;
+$LvlDnsLookups   = $ENV{'exim_dns_lookups'}   || 10;
+
+# print "Exim report detail level: $Detail\n\n";
 
 # procedura sortujaca tak jak ja chce (bo tamta sotrowala po ASCII)
 # procedure to compare numbers at the beginning of submitted strings.
@@ -152,7 +157,7 @@
       # Exim >= 4.50 compiled with WITH_CONTENT_SCAN=yes (Running AntiVirus Software)
       $Virus{$ThisLine}++;
    }
-   elsif ( $ThisLine =~ /SMTP connection from/ ) {
+   elsif ( $ThisLine =~ /SMTP connection from (.*) \[(\d+\.\d+\.\d+\.\d+)\] (.*)/ ) {
       # Common error from SPAM hosts.
       $Proto{$ThisLine}++;
    }
@@ -168,6 +173,10 @@
       # Common error from SPAM hosts.
       $Proto{$ThisLine}++;
    }
+   elsif ( $ThisLine =~ /Warning: HELO verify failed/ ) {
+      # Common error from SPAM hosts.
+      $HeloVerify{$ThisLine}++;
+   }
    elsif ( $ThisLine =~ /unexpected disconnection while reading SMTP command/ ) {
       # Common error from SPAM hosts.
       $Proto{$ThisLine}++;
@@ -209,7 +218,7 @@
 	  # this is an extra error message when logging is high
 	  # and since another message duplicates it, we can just ignore this
    }
-   elsif ( $ThisLine =~ /rejected [HE][EH]LO from\s/ ) {
+   elsif ( $ThisLine =~ /rejected ((HELO|EHLO) from|EHLO or HELO)\s/ ) {
       # Typically due to underscores _ in the HELO line
       #   (a common protocol violation)
       # Also can be due to odd escape sequences 
@@ -236,9 +245,9 @@
       $ReverseLookup++;
       @ReverseLookupH = (@ReverseLookupH, $ThisLine);
    }
-   elsif ( $ThisLine =~ /no IP address found for host/ ) {
+   elsif ( $ThisLine =~ /(.* no IP address found for host \S+)/ ) {
       $Lookup++;
-      @LookupH = (@LookupH, $ThisLine);
+      @LookupH = (@LookupH, $1);
    }
    elsif ( $ThisLine =~ /^\d+\-\d+\-\d+\s\d+\:\d+\:\d+\s\w+\-\w+\-\w+\s/ ) { # inne wiadomosci przesylane przez EXIMA
     # Collect Message ID specific notes...
@@ -246,7 +255,6 @@
       # Count of individual Message Lines, used for sort
     $licze++;         # Dodaje taki licznik aby potem przy wypisaniu posortowac po nim, bo wypisywal nie po kolei
     $mmsg{$mid}{$licze.$mrest} = "$mdate $mtime";
-
    }
    else 
    {
@@ -265,7 +273,7 @@
 }
 
 # Print server Stops/Starts
-if ($Detail >= $LvlRestart) {
+if ($Detail >= $LvlRestarts) {
    if (@Restart) {
       print "\n--- Exim Restarted ---\n";
       foreach $ThisOne (sort @Restart) {
@@ -274,7 +282,7 @@
    }
 }
 
-if ($Detail >= $LvlRestart) {
+if ($Detail >= $LvlRestarts) {
    print "\n--- Queue Runners ---\n";
    # Start Queue
    $StartQueue and print "  Start queue run: $StartQueue Time(s)\n";
@@ -332,6 +340,22 @@
             print "$ThisOne\n";
          }
       }
+      elsif ( $Detail >= $LvlRelayReasons ) {
+	 my %reasons;
+         foreach my $line (@RelayH) {
+	    if ($line =~ /rejected RCPT: (.*)/)
+	    {
+	       $reasons{$1}++;
+	    }
+	    else
+	    {
+	       print "unmatched: $ThisOne\n";
+	    }
+	 }
+	 foreach my $reason (sort keys %reasons) {
+	    print "$reason: $reasons{$reason}\n";
+	 }
+      }
    }
 }
 
@@ -389,77 +413,79 @@
       # Probable SPAM hosts...
       print "\n--- Admin Policy Blocking ---\n";
       foreach $ThisOne (sort(keys %DontAccept)) {
-         # We need this blank.
-         $mid = "";
          # IP address/current issue holder.
-         $bb = "";
+         my $offender = "";
          # Extract exim date and time string...
          ($mdate, $mtime) = ($ThisOne =~ m/^(\d+-\d+-\d+)\s(\d+\:\d+\:\d+)\s/);
          # Link date and time (looks cleaner)...
-         $aa = "$mdate $mtime";
+         my $date_time = "$mdate $mtime";
+	 my $reason = "unknown";
 
          if ( $ThisOne =~ m/do not accept mail from ([\w\*-._]+)@([\w.-_]+)/ ) {
-            $cc = "Blocked Email Domain";
-            $bb = "$1\@$2";
+            $reason = "Blocked Email Domain";
+            $offender = "$1\@$2";
          }
          elsif ( $ThisOne =~ m/mail not permitted from sender ([\w\*-_.]+)@([\w.-_]+)/ ) {
-            $cc = "Blocked Email Address";
-            $bb = "$1\@$2";
+            $reason = "Blocked Email Address";
+            $offender = "$1\@$2";
          }
          elsif ( $ThisOne =~ m/contains attached ".(.*)" file, which is blacklisted/ ) {
-            $cc = "Blocked Attachment";
-            ( $bb ) = ($ThisOne =~ m/\[(\d+\.\d+\.\d+\.\d+)\]/);
+            $reason = "Blocked Attachment";
+            ( $offender ) = ($ThisOne =~ m/\[(\d+\.\d+\.\d+\.\d+)\]/);
          }
          elsif ( $ThisOne =~ /believed to be spam/ ) {
-            $cc = "Blocked Fragmented Message";
-            ( $bb ) = ($ThisOne =~ m/\[(\d+\.\d+\.\d+\.\d+)\]/);
+            $reason = "Blocked Fragmented Message";
+            ( $offender ) = ($ThisOne =~ m/\[(\d+\.\d+\.\d+\.\d+)\]/);
          }
          elsif ( $ThisOne =~ /[Ww]arning: dnsbl\.sorbs\.net/ ) {
-            $cc = "Blocked by DNSBL (SORBS)";
-            ( $bb ) = ($ThisOne =~ m/\[(\d+\.\d+\.\d+\.\d+)\]/);
+            $reason = "Blocked by DNSBL (SORBS)";
+            ( $offender ) = ($ThisOne =~ m/\[(\d+\.\d+\.\d+\.\d+)\]/);
          }
          elsif ( $ThisOne =~ /fragments administratively prohibited/ ) {
-            $cc = "Blocked Fragmented Message";
-            ( $bb ) = ($ThisOne =~ m/\[(\d+\.\d+\.\d+\.\d+)\]/);
+            $reason = "Blocked Fragmented Message";
+            ( $offender ) = ($ThisOne =~ m/\[(\d+\.\d+\.\d+\.\d+)\]/);
          }
          elsif ( $ThisOne =~ m/unqualified sender rejected: <(.*)>/ ) {
-            $cc = "Unqualified Sender";
-            $bb = "$1";
+            $reason = "Unqualified Sender";
+            $offender = "$1";
          }
          elsif ( $ThisOne =~ m/unqualified recipient rejected: <(.*)>/ ) {
-            $cc = "Unqualified Receipient";
-            $bb = "$1";
+            $reason = "Unqualified Receipient";
+            $offender = "$1";
          }
          elsif ( $ThisOne =~ m/not accept Windows executables/ ) {
-            $cc = "Blocked Attachment";
-            ( $bb ) = ($ThisOne =~ m/\[(\d+\.\d+\.\d+\.\d+)\]/);
+            $reason = "Blocked Attachment";
+            ( $offender ) = ($ThisOne =~ m/\[(\d+\.\d+\.\d+\.\d+)\]/);
          }
          elsif ( $ThisOne =~ m/remote host address is the local host/ ) {
-            $cc = "Invalid local domain";
-            ( $bb ) = ($ThisOne =~ m/\@\[^>]+/);
+            $reason = "Invalid local domain";
+            ( $offender ) = ($ThisOne =~ m/\@\[^>]+/);
          }
          else {
             # If we picked up a malfunction but didn't collect it here,
             # no need to make the user suffer with superfluous error 
             # messages.
-            #next;
             print "Didn't Summarize: $ThisOne\n";
+	    next;
          }
-         if (defined( $spam{$cc} )) {
-            $mid = $spam{$cc};
+         if ($spam{$reason}) {
+	    $spam{$reason} .= ",$date_time: $offender";
          }
-         $spam{$cc} = "$mid$aa : $bb,";
+	 else {
+	    $spam{$reason} = "$date_time: $offender";
+	 }
       }
-      foreach $ThisOne (sort(keys %spam)) {
+
+      foreach my $reason (sort(keys %spam)) {
          if ($Detail >= $LvlDontAcceptLines) {
-            print "  $ThisOne\n";
-            foreach $aa ( sort( split /,/, $spam{$ThisOne} )) {
-               print "    $aa\n";
+            print "  $reason:\n";
+            foreach my $offender ( sort( split /,/, $spam{$ThisOne} )) {
+               print "    $offender\n";
             }
          }
          else {
-            @errList = split /,/, $spam{$ThisOne};
-            print "  $ThisOne ".scalar @errList." times\n";
+            @errList = split /,/, $spam{$reason};
+            print "  $reason: ".scalar @errList." times\n";
          }
       }
    }
@@ -473,151 +499,174 @@
       # Probable SPAM hosts...
       print "\n--- Bad Hosts ---\n";
       foreach $ThisOne (sort(keys %Proto)) {
-         # We need this blank.
-         $mid = "";
          # IP address/current issue holder.
-         $bb = "";
-         $cc = "";
+         my $offender = "";
+         my $reason = "";
          # Extract exim date and time string...
          ($mdate, $mtime) = ($ThisOne =~ m/^(\d+-\d+-\d+)\s(\d+\:\d+\:\d+)\s/);
          # Link date and time (looks cleaner)...
-         $aa = "$mdate $mtime";
+	 my $date_time = "$mdate $mtime";
+         if ($ThisOne =~ m/\[(\d+\.\d+\.\d+\.\d+)\]/) {
+	    $offender = $1;
+	 }
 
          if ( $ThisOne =~ m/SMTP protocol violation\:\s(.*?\(.*?\))\:/ ) {
-            $cc = $1;
-            ( $bb ) = ($ThisOne =~ m/\[(\d+\.\d+\.\d+\.\d+)\]/);
+            $reason = $1;
          }
          elsif ( $ThisOne =~ /unexpected disconnection while reading SMTP command/ ) {
-            $cc = "Sudden disconnect while expecting remote input";
-            ( $bb ) = ($ThisOne =~ m/\[(\d+\.\d+\.\d+\.\d+)\]/);
+            $reason = "Sudden disconnect while expecting remote input";
          }
-         elsif ( $ThisOne =~ m/rejected ([HE][EH])LO from \[(\d+\.\d+\.\d+\.\d+)\]\:\s(.*?):\s(.*?)$/ ) {
-            $cc = "Rejected HELO/EHLO: $3";
-            $bb = "$2 ($1LO $4)";
+         elsif ( $ThisOne =~ m/rejected (HELO|EHLO) from \[(\d+\.\d+\.\d+\.\d+)\]\:\s(.*?):\s(.*?)$/ ) {
+	    if (not $4) {
+	       print "Rejected HELO/EHLO for unknown reason: $ThisOne\n";
+	    }
+            $reason = "Rejected HELO/EHLO: $3";
+            $offender = sprintf("%-15s claiming to be '%s'", $2, $4);
+         }
+         elsif ( $ThisOne =~ m/\[(\d+\.\d+\.\d+\.\d+)\] rejected EHLO or HELO (.*): (.*)/ ) {
+	    if (not $3) {
+	       print "Rejected HELO/EHLO for unknown reason: $ThisOne\n";
+	    }
+            $reason = "Rejected HELO/EHLO: $3";
+            $offender = sprintf("%-15s claiming to be '%s'", $1, $2);
          }
          elsif ( $ThisOne =~ /SMTP data timeout \(message abandoned\) on connection from/ ) {
-            $cc = "SMTP Timeout errors";
-            ( $bb ) = ($ThisOne =~ m/\[(\d+\.\d+\.\d+\.\d+)\]/);
+            $reason = "SMTP Timeout errors";
+            $SmtpConnection{$reason}++;
          }
          elsif ( $ThisOne =~ /SMTP command timeout on connection from/ ) {
-            $cc = "SMTP Timeout errors";
-            ( $bb ) = ($ThisOne =~ m/\[(\d+\.\d+\.\d+\.\d+)\]/);
+            $reason = "SMTP Timeout errors";
+            $SmtpConnection{$reason}++;
          }
          elsif ( $ThisOne =~ /syntactically invalid argument/ ) {
-            $cc = "SMTP Syntax errors";
-            ( $bb ) = ($ThisOne =~ m/\[(\d+\.\d+\.\d+\.\d+)\]/);
+            $reason = "SMTP Syntax errors";
          }
          elsif ( $ThisOne =~ /SMTP syntax error in/ ) {
-            $cc = "SMTP Syntax errors";
-            ( $bb ) = ($ThisOne =~ m/\[(\d+\.\d+\.\d+\.\d+)\]/);
+            $reason = "SMTP Syntax errors";
          }
          elsif ( $ThisOne =~ /remote host used my name in HELO/ ) {
-            $cc = "My name in HELO";
-            ( $bb ) = ($ThisOne =~ m/\[(\d+\.\d+\.\d+\.\d+)\]/);
+            $reason = "My name in HELO";
          }
          elsif ( $ThisOne =~ /remote host used IP address in HELO/ ) {
-            $cc = "IP address in HELO";
-            ( $bb ) = ($ThisOne =~ m/\[(\d+\.\d+\.\d+\.\d+)\]/);
+            $reason = "IP address in HELO";
          }
          elsif ( $ThisOne =~ /incomplete transaction (\(.*\))/ ) {
-            $bb = "SMTP transaction cut short $1";
-            $SmtpConnection{$bb}++;
+            $reason = "SMTP transaction cut short $1";
+            $SmtpConnection{$reason}++;
          }
          elsif ( $ThisOne =~ /SMTP protocol synchronization error/ ) {
-            $bb = "SMTP protocol synchronization error";
-            $SmtpConnection{$bb}++;
+            $reason = "SMTP protocol synchronization error";
+            # spammer, not normal error
          }
          elsif ( $ThisOne =~ /dropped: too many nonmail commands/ ) {
-            $bb = "Connection dropped after too many nonmail SMTP commands";
-            $SmtpConnection{$bb}++;
+            $reason = "Connection dropped after too many nonmail SMTP commands";
          }
          elsif ( $ThisOne =~ /dropped: too many syntax or protocol errors/ ) {
-            $bb = "Connection dropped after too many syntax/protocol errors";
-            $SmtpConnection{$bb}++;
+            $reason = "Connection dropped after too many syntax/protocol errors";
          }
          elsif ( $ThisOne =~ /(SMTP protocol error in \"\w+\")/ ) {
-            $bb = $1;
-            $SmtpConnection{$bb}++;
+            $reason = $1;
+            $SmtpConnection{$reason}++;
          }
-         elsif ( $ThisOne =~ /SMTP connection from/ ) {
-            if ( $ThisOne =~ /lost while reading message data/ ) {
-               $bb = "SMTP connection lost while reading message data";
-            }
-            elsif ( $ThisOne =~ /Connection reset by peer/ ) {
-               $bb = "SMTP connection lost when connection reset by peer ";
-            }
-            elsif ( $ThisOne =~ /lost/ ) {
-               $bb = "SMTP connection lost (non-specific)";
-            }
-            elsif ( $ThisOne =~ /closed by QUIT/ ) {
-               $bb = "SMTP connection closed by QUIT";
-            }
-            elsif ( $ThisOne =~ /closed after SIGTERM/ ) {
-               $bb = "SMTP connection closed after SIGTERM";
-            }
-            elsif ( $ThisOne =~ /TCP\/IP connection count/ ) {
-               $bb = "SMTP connection TCP/IP connection count (warning)";
-            }
-            if ( $bb ne "" ) {
-               $SmtpConnection{$bb}++;
+         elsif ( $ThisOne =~ /SMTP connection from (.*) \[(\d+\.\d+\.\d+\.\d+)\] (.*)/ ) {
+	    # if we set $smtp_reason then it's a random/expected SMTP
+	    # error; otherwise it's a bad host error.
+	    $reason = $3;
+
+            if ( $reason eq 'lost while reading message data' ) {
+               $smtp_reason = "SMTP connection lost while reading message data";
+            }
+            elsif ( $reason eq 'Connection reset by peer' ) {
+               $smtp_reason = "SMTP connection lost when connection reset by peer ";
+            }
+            elsif ( $reason eq 'lost' ) {
+               $smtp_reason = "SMTP connection lost (non-specific)";
+            }
+            elsif ( $reason eq 'closed by QUIT' ) {
+               $smtp_reason = "SMTP connection closed by QUIT";
+            }
+            elsif ( $reason =~ /closed after SIGTERM/ ) {
+               $smtp_reason = "SMTP connection closed after SIGTERM";
+            }
+            elsif ( $reason =~ /TCP\/IP connection count/ ) {
+               $reason = "SMTP connection TCP/IP connection count (warning)";
+	    }
+	    else {
+	       # unexpected error, probably SMTP and not bad host
+	       $smtp_reason = $reason;
+	    }
+
+            if ( $smtp_reason ne "" ) {
+               $SmtpConnection{$smtp_reason}++;
+	       next; # don't process it twice
             }
          }
          else {
             # If we picked up a malfunction but didn't collect it here,
             # no need to make the user suffer with superfluous error 
             # messages.
-            #next;
             print "Didn't Summarize: $ThisOne\n";
+	    next;
          }
-         if (defined( $spam{$cc} )) {
-            $mid = $spam{$cc};
-         }
-         # We're picking things up in this larger block that do not
-         #  ... fit into this mold, so - let's make sure that this is valid
-         #  ... before we set it:
-         if (( $cc ne '' ) && ( $bb ne '' )) {
-            $spam{$cc} = "$mid$aa : IP:$bb,";
-         }
+
+	 if (not $reason) {
+	    print "No reason for: $ThisOne\n";
+	    next;
+	 }
+
+	 if (not $offender) {
+	    print "No offender for: $ThisOne\n";
+	    next;
+	 }
+
+	 if ($SmtpConnection{$reason}) {
+	    next; # don't list it twice, both SMTP and Spam
+	 }
+
+         $spam{$reason} ||= { };
+         $spam{$reason}{$offender} ||= [ ];
+         
+	 push @{ $spam{$reason}{$offender} }, $date_time;
       }
-      foreach $ThisOne (sort(keys %spam)) {
+
+      foreach $reason (sort keys %spam) {
+         $offenders = $spam{$reason};
+
          if ($Detail >= $LvlProtoclLines) {
-            print " $ThisOne:\n";
-            foreach $aa ( sort( split /,/, $spam{$ThisOne} )) {
-               print "    $aa\n";
+            print "  $reason:\n";
+            foreach $offender (sort keys %$offenders) {
+	       $times = $offenders->{$offender};
+               print "    $offender: ".(scalar @$times)." times\n";
             }
          }
          else {
-            @errList = split /,/, $spam{$ThisOne};
-            print "  $ThisOne ".scalar @errList." times\n";
+            print "  $reason: ".(scalar keys %$offenders)." times\n";
          }
       }
 
       if ( %SmtpConnection ) {
          print "\n--- SMTP Connection Issues \n";
-         foreach $ThisOne (keys %SmtpConnection) {
-            $bb = $SmtpConnection{$ThisOne};
-            print "  $ThisOne: $bb Time(s)\n";
+         foreach $reason (keys %SmtpConnection) {
+            print "  $reason: $SmtpConnection{$reason} Time(s)\n";
          }
       }
 
-      if (@ReverseLookupH) {
-         print "\n--- Failed Reverse Lookups \n";
-         print "--- $ReverseLookup  Time(s)\n\n";
+      if (@ReverseLookupH and $Detail >= $LvlDnsLookups) {
+         print "\n--- Failed Reverse Lookups (clueless admin) $ReverseLookup time(s)\n\n";
 
          if ($Detail >= $LvlProtoclLines) {
             foreach $ThisOne (@ReverseLookupH) {
-               print "   $ThisOne\n";
+               print "  $ThisOne\n";
             }
          }
       }
 
-      if (@LookupH) {
-         print "\n--- Failed Reverse Lookups \n";
-         print "--- (eg. spam try): $Lookup  Time(s)\n\n";
+      if (@LookupH and $Detail >= $LvlDnsLookups) {
+         print "\n--- Failed Forward Lookups (fake hostname) $Lookup time(s)\n\n";
 
          if ($Detail >= $LvlProtoclLines) {
             foreach $ThisOne (@LookupH) {
-               print "$ThisOne\n";
+               print "  $ThisOne\n";
             }
          }
       }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.