This is an automated email from the ASF dual-hosted git repository.

dgelinas pushed a commit to branch 3.0.x
in repository https://gitbox.apache.org/repos/asf/trafficcontrol.git


The following commit(s) were added to refs/heads/3.0.x by this push:
     new 4f724b3  Updates to ToDSCPCheck.pl (#3441)
4f724b3 is described below

commit 4f724b39aba7176bd608cb4ee2b3bae625b98828
Author: Hank Beatty <[email protected]>
AuthorDate: Wed Mar 27 16:33:36 2019 -0400

    Updates to ToDSCPCheck.pl (#3441)
    
    * Updates to ToDSCPCheck.pl
    
    * added -x option to check a specific xmlId
    * increased number of logging levels
    * commented some code to add matchList to the DS details because matchList 
was put back in the return from the API
    * Fixed the code so that if the server option is used the script doesn't 
loop through all of the servers
    * Added code to get the CDNs because the domain name was removed from the 
API route that I was using before
    * Condensed the curl to a single line instead of 2 curl lines
    * Changed "80" to used the tcpPort in get_dscp function
    
    * Updates after ocket8888's review
    
    * Ran perltidy
    * removed some debug that was left over
    * removed a .json
    * fixed an IP variable
    * fixed the curl string so it could be read it easier
    
    * updated changelog
---
 CHANGELOG.md                              |  14 +-
 traffic_ops/app/bin/checks/ToDSCPCheck.pl | 700 +++++++++++++++++-------------
 2 files changed, 404 insertions(+), 310 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 55f70ba..ead7a64 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,17 +8,21 @@ The format is based on [Keep a 
Changelog](http://keepachangelog.com/en/1.0.0/).
 
 ### Changed
 - Update golang requirement to allow versions greater than 1.9.4.
+- Traffic Router, added TLS certificate validation on certificates imported 
from Traffic Ops
+  - validates modulus of private and public keys
+  - validates current timestamp falls within the certificate date bracket
+  - validates certificate subjects against the DS URL
+- Modified Traffic Router logging format to include an additional field for 
DNS log entries, namely `rhi`. This defaults to '-' and is only used when EDNS0 
client subnet extensions are enabled and a client subnet is present in the 
request. When enabled and a subnet is present, the subnet appears in the `chi` 
field and the resolver address is in the `rhi` field.
+
+### Fixed
+- ToDSCPCheck.pl - Changed "80" to used the tcpPort in get_dscp function
 - ORT bugfix for self-signed SSL certs.
 - Correct regex capture prefix for cachekey plugin.
 - Fix docs building.
 - Fix port handling for traffic ops port checks on ports other than 80.
 - Return a json response with a 200 for a successful snapshot PUT.
 - Correct FQDN case mismatch when generating DNSSEC.
-- Traffic Router, added TLS certificate validation on certificates imported 
from Traffic Ops
-  - validates modulus of private and public keys
-  - validates current timestamp falls within the certificate date bracket
-  - validates certificate subjects against the DS URL
-- Modified Traffic Router logging format to include an additional field for 
DNS log entries, namely `rhi`. This defaults to '-' and is only used when EDNS0 
client subnet extensions are enabled and a client subnet is present in the 
request. When enabled and a subnet is present, the subnet appears in the `chi` 
field and the resolver address is in the `rhi` field.
+
 
 ## [3.0.0] - 2019-02-13
 ### Added
diff --git a/traffic_ops/app/bin/checks/ToDSCPCheck.pl 
b/traffic_ops/app/bin/checks/ToDSCPCheck.pl
index 787b995..09600d3 100755
--- a/traffic_ops/app/bin/checks/ToDSCPCheck.pl
+++ b/traffic_ops/app/bin/checks/ToDSCPCheck.pl
@@ -28,6 +28,7 @@ use Data::Dumper;
 use Getopt::Std;
 use Log::Log4perl qw(:easy);
 use Net::PcapUtils;
+use NetAddr::IP;
 use NetPacket::Ethernet qw(:strip);
 use NetPacket::IP qw(:strip);
 use NetPacket::IPv6 qw(:strip);
@@ -37,364 +38,453 @@ use Extensions::Helper;
 use Sys::Syslog qw(:standard :macros);
 use IO::Handle;
 
-my $VERSION = "0.03";
+# TODO Figure out how to make this match the TC release version
+my $VERSION = "0.07";
 
 STDOUT->autoflush(1);
 
 my %args = ();
-getopts( "c:f:hl:q", \%args );
+getopts( "c:f:hl:qs:x:", \%args );
 
-if ($args{h}) {
-   &help();
-   exit();
+if ( $args{h} ) {
+       &help();
+       exit();
 }
 
 Log::Log4perl->easy_init($ERROR);
 if ( defined( $args{l} ) ) {
-   if    ( $args{l} == 1 ) { Log::Log4perl->easy_init($INFO); }
-   elsif ( $args{l} == 2 ) { Log::Log4perl->easy_init($DEBUG); }
-   elsif ( $args{l} >= 3 ) { Log::Log4perl->easy_init($TRACE); }
-   else                    { Log::Log4perl->easy_init($INFO); }
+       if    ( $args{l} == 1 ) { Log::Log4perl->easy_init($FATAL); }
+       elsif ( $args{l} == 2 ) { Log::Log4perl->easy_init($ERROR); }
+       elsif ( $args{l} == 3 ) { Log::Log4perl->easy_init($WARN); }
+       elsif ( $args{l} == 4 ) { Log::Log4perl->easy_init($INFO); }
+       elsif ( $args{l} == 5 ) { Log::Log4perl->easy_init($DEBUG); }
+       elsif ( $args{l} == 6 ) { Log::Log4perl->easy_init($TRACE); }
+       else                    { Log::Log4perl->easy_init($INFO); }
 }
 
-DEBUG( "Including DEBUG messages in output. Config is \'" . $args{c} . "\'" );
-TRACE( "Including TRACE messages in output. Config is \'" . $args{c} . "\'" );
+DEBUG("Including DEBUG messages in output");
+TRACE("Including TRACE messages in output");
 
 if ( !defined( $args{c} ) ) {
-   &help();
-   exit(1);
+       &help();
+       exit(1);
 }
 
 my $jconf = undef;
 eval { $jconf = decode_json( $args{c} ) };
 if ($@) {
-   ERROR("Bad json config: $@");
-   print "\n\n";
-   &help();
-   exit(1);
+       FATAL "FATAL Bad json config: $@";
+       print "\n\n";
+       &help();
+       exit(1);
 }
 
 my $sslg = undef;
 my $chck_lng_nm;
-if (defined($jconf->{syslog_facility})) {
-   $chck_lng_nm = $jconf->{name};
-   setlogmask(LOG_UPTO(LOG_INFO));
-   openlog ('ToChecks', '', $jconf->{syslog_facility});
-   $sslg = 1;
+if ( defined( $jconf->{syslog_facility} ) ) {
+       $chck_lng_nm = $jconf->{name};
+       setlogmask( LOG_UPTO(LOG_INFO) );
+       openlog( 'ToChecks', '', $jconf->{syslog_facility} );
+       $sslg = 1;
 }
 
 my $cms_int = undef;
-if (defined($jconf->{cms_interface})) {
-   $cms_int = $jconf->{cms_interface};
-} else {
-   ERROR "cms_interface must be defined.";
-   print "\n\n";
-   &help();
-   exit(1);
+if ( defined( $jconf->{cms_interface} ) ) {
+       $cms_int = $jconf->{cms_interface};
+}
+else {
+       FATAL "FATAL cms_interface must be defined.";
+       print "\n\n";
+       &help();
+       exit(1);
 }
 
 my $force = 0;
-if (defined($args{f})) {
-   $force = $args{f};
+if ( defined( $args{f} ) ) {
+       $force = $args{f};
+       DEBUG "DEBUG force: " . $args{f} . "";
 }
 
 my $quiet;
-if ($args{q}) {
-   $quiet = 1;
+if ( $args{q} ) {
+       $quiet = 1;
 }
 
 my $check_name = $jconf->{check_name};
 if ( $check_name ne "DSCP" ) {
-   ERROR "This Check Extension is exclusively for DSCP.";
-   print "\n\n";
-   &help();
-   exit(4);
+       FATAL "FATAL This Check Extension is exclusively for DSCP.";
+       print "\n\n";
+       &help();
+       exit(4);
 }
 
-
-TRACE( "force: " . $args{f} . "" );
-
-TRACE Dumper($jconf);
+DEBUG "DEBUG " . Dumper($jconf);
 my $b_url = $jconf->{base_url};
 Extensions::Helper->import();
 my $ext = Extensions::Helper->new( { base_url => $b_url, token => 
'91504CE6-8E4A-46B2-9F9F-FE7C15228498' } );
 
 my %ds_info           = ();
-my $jdeliveryservices = $ext->get( Extensions::Helper::DSLIST_PATH );
+my $jdeliveryservices = $ext->get(Extensions::Helper::DSLIST_PATH);
 
-# Get all the Deliver Services
+# Get all the Delivery Services
 foreach my $ds ( @{$jdeliveryservices} ) {
-   $ds_info{ $ds->{id} } = $ds;
+       $ds_info{ $ds->{id} } = $ds;
+
+       # Get the DS details and add the matchList
+       my $ds_details = $ext->get( '/api/1.2/deliveryservices/' . $ds->{id} );
+
+       #DEBUG "Debug matchList before push: " . 
Dumper($ds_details->[0]{matchList});
+       # The matchList was removed at one point and now it's back.
+       # Leaving this here for when that happens again.
+       #push( @{ $ds_info{ $ds->{id} }{matchList} }, @{ 
$ds_details->[0]{matchList} } );
+       #DEBUG "Debug matchList after push: " . Dumper($ds_info{ $ds->{id} 
}{matchList});
+}
+
+my $jdataserver = ();
+if ( defined( $args{s} ) ) {
+       DEBUG "DEBUG Getting single server";
+
+       # TODO check for a successful return
+       # This returns a reference to a hash
+       $jdataserver = $ext->get( '/api/1.1/servers/hostname/' . $args{s} . 
'/details' );
+
+       # create an array
+       my @tmp = ();
+
+       # put the hash reference in the array
+       $tmp[0] = $jdataserver;
+
+       # clear $jdataserver
+       $jdataserver = ();
+
+       # create a reference to the array
+       $jdataserver = \@tmp;
+
+}
+else {
+       # This is a reference to an array
+       $jdataserver = $ext->get(Extensions::Helper::SERVERLIST_PATH);
+}
+
+my %cdns  = ();
+my $jcdns = $ext->get('/api/1.1/cdns');
+
+# convert the cdns to a hash
+foreach my $cdn ( @{$jcdns} ) {
+       DEBUG "DEBUG cdn_name: " . $cdn->{name};
+       $cdns{ $cdn->{name} } = $cdn;
+       DEBUG "DEBUG domain_name: " . $cdns{ $cdn->{name} }->{domainName};
 }
 
-my %domain_name_for_profile = ();
-my $jdataserver = $ext->get( Extensions::Helper::SERVERLIST_PATH );
 foreach my $server ( @{$jdataserver} ) {
-   next unless $server->{type} =~ m/^EDGE/;    # We know this is DSCP, so we 
know we want edges only
-   my $ip         = trim($server->{ipAddress});
-   my $ip6        = trim($server->{ip6Address});
-   my $host_name  = trim($server->{hostName});
-   my $fqdn       = $host_name.".".trim($server->{domainName});
-   my $interface  = trim($server->{interfaceName});
-   my $http_port  = $server->{tcpPort};
-   my $https_port = $server->{httpsPort};
-   my $status     = $server->{status};
-   my $details    = $ext->get( '/api/1.1/servers/hostname/' . $host_name . 
'/details.json' );
-   my $successful = 1; # assume all is good
-   $ip6 =~ s/\/\d+$//;
-
-   TRACE "Checking: ".$host_name;
-
-   # Loop thru each delivery service associated with this server
-   foreach my $dsid ( @{ $details->{deliveryservices} } ) {
-      my $ds = $ds_info{$dsid};
-      TRACE "Profile: ".$ds->{profileName}." xmlId: ".$ds->{xmlId}." active: 
".$ds->{active}." checkpath: ".$ds->{checkPath}." protocol: ".$ds->{protocol};
-      #if (!defined($ds->{checkPath}) || $ds->{checkPath} eq "") {
-      #   #WARN "checkPath for ".$host_name."/".$ds->{xmlId}." not defined.";
-      #   if ($sslg) {
-      #      my @tmp = ($fqdn, $check_name, $chck_lng_nm, 'FAIL',$ds->{xmlId},
-      #                 "\'Check Path\' is not defined for this Delivery 
Service in Traffic Ops");
-      #      syslog(LOG_WARNING, "hostname=%s check=%s name=\"%s\" result=%s 
target=%s msg=\"%s\"", @tmp);
-      #   }
-      #   $successful = 0;
-      #   next;
-      #}
-      if ( $ds->{active} && defined( $ds->{checkPath} ) && $ds->{checkPath} ne 
"" && $ds->{protocol} == 0 ) {
-         foreach my $match ( @{ $ds->{matchList} } ) {
-            my $header;
-            my $prefix;
-            if ( $match->{type} eq 'HOST_REGEXP' ) {
-               if ($match->{pattern} =~ /\*/) {
-                  my $tmp = $match->{pattern};
-                  $tmp =~ s/\\//g;
-                  $tmp =~ s/\.\*//g;
-                  $header .= $tmp;
-                  if ( !defined( $domain_name_for_profile{ $ds->{profileName} 
} ) ) {
-                     my $param_list = $ext->get( 
'/api/1.1/parameters/profile/' . $ds->{profileName} . '.json' );
-                     foreach my $p ( @{$param_list} ) {
-                        if ( $p->{name} eq 'domain_name' ) {
-                           $domain_name_for_profile{ $ds->{profileName} } = 
$p->{value};
-                        }
-                     }
-                  }
-                  if ( $ds->{type} =~ /^DNS/ ) {
-                     $prefix = $ds->{routingName};
-                  } else {
-                     $prefix = $host_name;
-                  }
-                  $header .= $domain_name_for_profile{ $ds->{profileName} };
-                  $header = $prefix.$header;
-               } else {
-                  $header = $match->{pattern};
-               }
-            }
-
-            ## check ipv4
-            # TODO "http://"; should be a var so that we can also check https
-            my $url = "http://".$ip.":".$tcpPort.$ds->{checkPath};
-
-            TRACE "About to check header: ".$header." url: ".$url;
-
-
-            my $dscp_found;
-            if ($force == 0) {
-               $dscp_found = &get_dscp( $url, $ip, $cms_int, $header, "ipv4");
-            } elsif ($force == 1) {
-               $dscp_found = -1;
-            } elsif ($force == 2) {
-               $dscp_found = $ds->{dscp};
-            } elsif ($force == 3) {
-               $dscp_found = $ds->{dscp} + 1;
-            }
-            my $target = $ds->{xmlId}.":ipv4";
-            if ($dscp_found == -1) {
-               $successful = 0;
-               TRACE "Failed deliveryService: ".$ds->{profileName};
-               if ($sslg) {
-                  my @tmp = ($fqdn, $check_name, $chck_lng_nm, 'FAIL',$status,
-                             $target,$header,"Unable to connect to server");
-                  syslog(LOG_INFO, "hostname=%s check=%s name=\"%s\" result=%s 
status=%s target=%s url=%s msg=\"%s\"", @tmp);
-               }
-            } elsif ($dscp_found == $ds->{dscp}) {
-               TRACE "Success deliveryService: ".$ds->{profileName}." xmlId: 
".$ds->{xmlId};
-               if ($sslg) {
-                  my @tmp = ($fqdn,$check_name,$chck_lng_nm,'OK',$status,
-                             $target,$header);
-                  syslog(LOG_INFO, "hostname=%s check=%s name=\"%s\" result=%s 
status=%s target=%s url=%s msg=\"\"", @tmp);
-               }
-            } else {
-               $successful = 0;
-               TRACE "Fail deliveryService: ".$ds->{profileName};
-               if ($sslg) {
-                  my @tmp = ($fqdn,$check_name,$chck_lng_nm,'FAIL',$status,
-                             $target,$header,"Expected DSCP value of 
$ds->{dscp} got $dscp_found");
-                  syslog(LOG_ERR, "hostname=%s check=%s name=\"%s\" result=%s 
status=%s target=%s url=%s msg=\"%s\"", @tmp);
-               }
-            }
-
-
-            ## check ipv6
-            # TODO "http://"; should be a var so that we can also check https
-            # TODO "80" should be var when we add https
-            $url = "http://".$ip.":".$tcpPort.$ds->{checkPath};
-
-            TRACE "About to check header: ".$header." url: ".$url;
-
-            if ($force == 0) {
-               $dscp_found = &get_dscp( $url, $ip6, $cms_int, $header, "ipv6");
-            } elsif ($force == 1) {
-               $dscp_found = -1;
-            } elsif ($force == 2) {
-               $dscp_found = $ds->{dscp};
-            } elsif ($force == 3) {
-               $dscp_found = $ds->{dscp} + 1;
-            }
-            $target = $ds->{xmlId}.":ipv6";
-            if ($dscp_found == -1) {
-               $successful = 0;
-               TRACE "Failed deliveryService: ".$ds->{profileName};
-               if ($sslg) {
-                  my @tmp = ($fqdn, $check_name, $chck_lng_nm, 'FAIL',$status,
-                             $target,$header,"Unable to connect to edge 
server");
-                  syslog(LOG_INFO, "hostname=%s check=%s name=\"%s\" result=%s 
status=%s target=%s url=%s msg=\"%s\"", @tmp);
-               }
-            } elsif ( $dscp_found == $ds->{dscp} ) {
-               TRACE "Success deliveryService: ".$ds->{profileName};
-               if ($sslg) {
-                  my @tmp = ($fqdn,$check_name,$chck_lng_nm,'OK',$status,
-                             $target,$header);
-                  syslog(LOG_INFO, "hostname=%s check=%s name=\"%s\" result=%s 
status=%s target=%s url=%s msg=\"\"", @tmp);
-               }
-            } else {
-               $successful = 0;
-               TRACE "Fail deliveryService: ".$ds->{profileName};
-               if ($sslg) {
-                  my $target = $ds->{xmlId}.":ipv6";
-                  my @tmp = ($fqdn, $check_name, $chck_lng_nm, 'FAIL',$status,
-                             $target,$header,"Expected DSCP value of 
$ds->{dscp} got $dscp_found");
-                  syslog(LOG_ERR, "hostname=%s check=%s name=\"%s\" result=%s 
status=%s target=%s url=%s msg=\"%s\"", @tmp);
-               }
-            }
-         }
-
-         TRACE "Finished checking";
-         #last;
-      }
-   }
-   if ($successful) {
-      $ext->post_result( $server->{id}, $check_name, 1 ) if (!$quiet);
-   } else {
-      $ext->post_result( $server->{id}, $check_name, 0 ) if (!$quiet);
-   }
+       next unless $server->{type} =~ m/^EDGE/;    # We know this is DSCP, so 
we know we want edges only
+       if ( $server->{status} ne 'REPORTED' ) {
+               INFO "INFO Skipping server: $server->{hostName} because status 
is: $server->{status}";
+               next;
+       }
+       my @ip_addrs    = ( $server->{ipAddress}, $server->{ip6Address} );
+       my $host_name   = trim( $server->{hostName} );
+       my $fqdn        = $host_name . "." . trim( $server->{domainName} );
+       my $interface   = trim( $server->{interfaceName} );
+       my $status      = $server->{status};
+       my $port        = $server->{tcpPort};                                   
                 # this is for both http and https
+       my $protocol    = "http";
+       my $ip_protocol = "ipv4";
+       my $domain_name = undef;
+       my $details     = $ext->get( '/api/1.1/servers/hostname/' . $host_name 
. '/details' );
+       my $successful  = 1;                                                    
                 # assume all is good
+
+       if ( ( defined( $ip_addrs[1] ) ) && ( $ip_addrs[1] =~ m/:/ ) ) {
+               $ip_addrs[1] = new NetAddr::IP( $ip_addrs[1] );
+               $ip_addrs[1] =~ s/\/\d+$//;
+               $ip_addrs[1] = lc( $ip_addrs[1] );
+       }
+
+       DEBUG "DEBUG Checking: " . $host_name;
+
+       # Loop thru each delivery service associated with this server
+       foreach my $dsid ( @{ $details->{deliveryservices} } ) {
+               my $ds = $ds_info{$dsid};
+               if ( defined( $args{x} ) ) {
+
+                       # TODO figure out how to not loop through all DSs
+                       next unless trim( $ds->{xmlId} ) eq $args{x};
+               }
+               $domain_name = $cdns{ $ds->{cdnName} }->{domainName};
+               DEBUG "DEBUG xmlId: "
+                       . $ds->{xmlId}
+                       . " dsid: "
+                       . $dsid
+                       . " cdnName: "
+                       . $ds->{cdnName}
+                       . " domain_name: "
+                       . $domain_name
+                       . " active: "
+                       . $ds->{active}
+                       . " checkpath: "
+                       . ( defined( $ds->{checkPath} ) ? $ds->{checkPath} : 
"not defined" )
+                       . " protocol: "
+                       . $ds->{protocol};
+
+               if ( $ds->{protocol} == 1 || $ds->{protocol} == 3 ) {
+                       $protocol = "https";
+                       $port     = trim( $server->{httpsPort} );
+               }
+
+               if ( $ds->{active} && defined( $ds->{checkPath} ) && 
$ds->{checkPath} ne "" ) {
+                       my $target = $ds->{xmlId} . ":" . $ip_protocol;
+                       my $header = "";
+                       if ( !defined( $ds->{matchList} ) || ( $ds->{matchList} 
eq "" ) ) {
+                               $successful = 0;
+                               ERROR "ERROR Failed deliveryService xmlId: " . 
$ds->{xmlId} . " matchList undefined";
+                               if ($sslg) {
+                                       my @tmp = ( $fqdn, $check_name, 
$chck_lng_nm, 'FAIL', $status, $target, $header, "matchList undefined" );
+                                       syslog( LOG_INFO, "hostname=%s check=%s 
name=\"%s\" result=%s status=%s target=%s url=%s msg=\"%s\"", @tmp );
+                               }
+                       }
+                       else {
+                               foreach my $match ( @{ $ds->{matchList} } ) {
+                                       TRACE "TRACE checking match: " . 
$match->{pattern};
+                                       my $prefix;
+                                       if ( $match->{type} eq 'HOST_REGEXP' ) {
+                                               if ( $match->{pattern} =~ /\*/ 
) {
+                                                       my $tmp = 
$match->{pattern};
+                                                       $tmp =~ s/\\//g;
+                                                       $tmp =~ s/\.\*//g;
+                                                       $header .= $tmp;
+                                                       if ( ( $ds->{type} =~ 
/^DNS/ ) && ( $match->{pattern} =~ m/^\.\*/ ) ) {
+                                                               DEBUG "DEBUG 
setting prefix to edge";
+                                                               $prefix = 
'edge';
+                                                       }
+                                                       elsif ( $ds->{type} =~ 
/^DNS/ ) {
+                                                               DEBUG "DEBUG 
setting prefix to ''";
+                                                               $prefix = '';
+                                                       }
+                                                       else {
+                                                               # this is the 
hostname, not the fqdn
+                                                               $prefix = 
$host_name;
+                                                       }
+
+                                                       # TODO There may still 
be a bug here when a DS has a regex
+                                                       # that is a FQDN and 
ds->{type} of HTTP.
+                                                       $header .= $domain_name;
+                                                       $header = $prefix . 
$header;
+                                               }
+                                               else {
+                                                       # TODO How to handle 
the other regex patterns
+                                                       TRACE "TRACE Not a Host 
Regex. Going to next regex.";
+                                                       next;
+                                               }
+                                       }
+                                       foreach my $ip (@ip_addrs) {
+                                               TRACE "TRACE checking " . $ip;
+                                               if ( !defined($ip) ) {
+                                                       TRACE "TRACE IP not 
defined. Should go to next ip";
+                                                       next;
+                                               }
+                                               elsif ( $ip =~ m/\./ ) {
+                                                       DEBUG "DEBUG ipv4: " . 
$ip;
+                                                       $ip_protocol = "ipv4";
+                                               }
+                                               elsif ( $ip =~ m/:/ ) {
+                                                       $ip_protocol = "ipv6";
+                                                       $ip          = new 
NetAddr::IP($ip);
+                                                       $ip =~ s/\/\d+$//;
+                                                       $ip = lc($ip);
+                                                       DEBUG "DEBUG ipv6: " . 
$ip;
+                                               }
+                                               else {
+                                                       TRACE "TRACE Not an 
IPv4 or IPv6 IP. Should go to next IP.";
+                                                       next;
+                                               }
+                                               my $checkpath = 
$ds->{checkPath};
+                                               $checkpath =~ s/^\///;
+                                               my $url = $protocol . "://" . 
$ip . ":" . $port . "/" . $checkpath;
+
+                                               DEBUG "DEBUG About to check 
header: " . $header . " url: " . $url . " ip_protocol: " . $ip_protocol;
+
+                                               my $dscp_found;
+                                               if ( $force == 0 ) {
+                                                       $dscp_found = get_dscp( 
$url, $ip, $cms_int, $header, $ip_protocol, $port );
+                                                       if ( ( $dscp_found == 
-1 ) || ( $dscp_found != $ds->{dscp} ) ) {
+                                                               sleep 1;
+                                                               DEBUG "DEBUG 
About to check again header: " . $header . " url: " . $url . " ip_protocol: " . 
$ip_protocol;
+                                                               $dscp_found = 
&get_dscp( $url, $ip, $cms_int, $header, $ip_protocol, $port );
+                                                       }
+                                               }
+                                               elsif ( $force == 1 ) {
+                                                       $dscp_found = -1;
+                                               }
+                                               elsif ( $force == 2 ) {
+                                                       $dscp_found = 
$ds->{dscp};
+                                               }
+                                               elsif ( $force == 3 ) {
+                                                       $dscp_found = 
$ds->{dscp} + 1;
+                                               }
+                                               if ( $dscp_found == -1 ) {
+                                                       $successful = 0;
+                                                       ERROR "ERROR Failed 
xmlId: " . $ds->{xmlId};
+                                                       if ($sslg) {
+                                                               my @tmp = ( 
$fqdn, $check_name, $chck_lng_nm, 'FAIL', $status, $target, $header, "Unable to 
connect to edge server" );
+                                                               syslog( 
LOG_INFO, "hostname=%s check=%s name=\"%s\" result=%s status=%s target=%s 
url=%s msg=\"%s\"", @tmp );
+                                                       }
+                                               }
+                                               elsif ( $dscp_found == 
$ds->{dscp} ) {
+                                                       INFO "INFO Success 
xmlId: " . $ds->{xmlId};
+                                                       if ($sslg) {
+                                                               my @tmp = ( 
$fqdn, $check_name, $chck_lng_nm, 'OK', $status, $target, $header );
+                                                               syslog( 
LOG_INFO, "hostname=%s check=%s name=\"%s\" result=%s status=%s target=%s 
url=%s msg=\"\"", @tmp );
+                                                       }
+                                               }
+                                               else {
+                                                       $successful = 0;
+                                                       ERROR "ERROR Failed 
xmlId: " . $ds->{xmlId};
+                                                       if ($sslg) {
+                                                               $successful = 0;
+                                                               my @tmp = (
+                                                                       $fqdn, 
$check_name, $chck_lng_nm, 'FAIL', $status,
+                                                                       
$target, $header, "Expected DSCP value of $ds->{dscp} got $dscp_found"
+                                                               );
+                                                               syslog( 
LOG_ERR, "hostname=%s check=%s name=\"%s\" result=%s status=%s target=%s url=%s 
msg=\"%s\"", @tmp );
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+                       DEBUG "DEBUG Finished checking";
+               }
+       }
+       if ($successful) {
+               $ext->post_result( $server->{id}, $check_name, 1 ) if ( !$quiet 
);
+       }
+       else {
+               $ext->post_result( $server->{id}, $check_name, 0 ) if ( !$quiet 
);
+       }
 }
 
 closelog();
 
-sub get_dscp() {
-   my $url      = shift;
-   my $ip       = shift;
-   my $dev      = shift;
-   my $header   = shift;
-   my $protocol = shift;
-
-   my $tos     = undef;
-   my $max_len = 0;
-
-   my $src_port = int( rand( 65535 - 1024 ) ) + 1024;
-   TRACE "get_dscp ip:" . $ip . " url:" . $url . " dev:" . $dev . " port:" . 
$src_port . " ip protocol: ".$protocol;
-
-   # Use curl to get some traffic from the URL, but send the command to the 
background, so the capture that follows
-   # is while traffic is being returned
-   if ($ip =~ m/:/) {
-      TRACE "running ip6";
-      my $curl = "curl --local-port " . $src_port . " --".$protocol." -s 
".$url." -H \"Host: ".$header."\" 2>&1 > /dev/null";
-      TRACE "curl: ".$curl;
-      system( "(sleep 1; ".$curl." || ping6 -c 10 $ip 2>&1 > /dev/null)  &" );
-   } else {
-      system( "(sleep 1; curl --local-port " . $src_port . " --".$protocol." 
-s ".$url." -H \"Host: ".$header."\" 2>&1 > /dev/null || ping -c 10 $ip 2>&1 > 
/dev/null)  &" );
-   }
-
-   Net::PcapUtils::loop(
-      sub {
-         my ( $user, $hdr, $pkt ) = @_;
-         my $ip_obj;
-         if ($protocol eq "ipv4") {
-            $ip_obj = NetPacket::IP->decode( eth_strip($pkt) );
-            TRACE " <=> $ip_obj->{src_ip} -> $ip_obj->{dest_ip} proto: 
$ip_obj->{proto} tos $ip_obj->{tos} len $ip_obj->{len}\n";
-            my $tcp_obj = NetPacket::TCP->decode( $ip_obj->{data} );
-            TRACE " TCP1 $ip_obj->{src_ip}:$tcp_obj->{src_port} -> 
$ip_obj->{dest_ip}:$tcp_obj->{dest_port} proto: $ip_obj->{proto} tos 
$ip_obj->{tos} len $ip_obj->{len}\n";
-            if ( $ip_obj->{src_ip} eq $ip && $ip_obj->{len} > $max_len && 
$ip_obj->{proto} == 6 ) {
-               my $tcp_obj = NetPacket::TCP->decode( $ip_obj->{data} );
-               TRACE " TCP2 $ip_obj->{src_ip}:$tcp_obj->{src_port} -> 
$ip_obj->{dest_ip}:$tcp_obj->{dest_port} $ip_obj->{proto} tos $ip_obj->{tos} 
len $ip_obj->{len}\n";
-               if ( ($tcp_obj->{src_port} == $http_port) && 
($tcp_obj->{dest_port} == $src_port) ) {
-                  TRACE " TCP3 $ip_obj->{src_ip}:$tcp_obj->{src_port} -> 
$ip_obj->{dest_ip}:$tcp_obj->{dest_port} $ip_obj->{proto} tos $ip_obj->{tos} 
len $ip_obj->{len}\n";
-                  $max_len = $ip_obj->{len};
-                  $tos     = $ip_obj->{tos};
-               }
-            }
-         } elsif ($protocol eq "ipv6") {
-            $ip_obj = NetPacket::IPv6->decode( eth_strip($pkt) );
-            TRACE " <=> $ip_obj->{src_ip} -> $ip_obj->{dest_ip} proto: 
$ip_obj->{nxt} tos $ip_obj->{class} len $ip_obj->{plen}\n";
-            my $tcp_obj = NetPacket::TCP->decode( $ip_obj->{data} );
-            TRACE " TCP1 $ip_obj->{src_ip}:$tcp_obj->{src_port} -> 
$ip_obj->{dest_ip}:$tcp_obj->{dest_port} proto: $ip_obj->{nxt} tos 
$ip_obj->{class} len $ip_obj->{plen}\n";
-            if ( $ip_obj->{src_ip} eq $ip && $ip_obj->{plen} > $max_len && 
$ip_obj->{nxt} == 6 ) {
-               my $tcp_obj = NetPacket::TCP->decode( $ip_obj->{data} );
-               TRACE " TCP2 $ip_obj->{src_ip}:$tcp_obj->{src_port} -> 
$ip_obj->{dest_ip}:$tcp_obj->{dest_port} $ip_obj->{nxt} tos $ip_obj->{class} 
len $ip_obj->{plen}\n";
-               if ( $tcp_obj->{src_port} == $http_port && 
$tcp_obj->{dest_port} == $src_port ) {
-                  TRACE " TCP3 $ip_obj->{src_ip}:$tcp_obj->{src_port} -> 
$ip_obj->{dest_ip}:$tcp_obj->{dest_port} $ip_obj->{nxt} tos $ip_obj->{class} 
len $ip_obj->{plen}\n";
-                  $max_len = $ip_obj->{plen};
-                  $tos     = $ip_obj->{class};
-               }
-            }
-         }
-
-      },
-      FILTER     => 'host ' . $ip,
-      DEV        => $dev,
-      NUMPACKETS => 7,
-      TIMEOUT    => 10
-   );
-
-
-   #TRACE "tos: ".$tos;
-   my $dscp;
-   if (defined($tos)) {
-      $dscp = $tos >> 2;
-   } else {
-      $dscp = -1;
-   }
-   #my $dscp = $tos >> 2;
-   TRACE "returning " . $dscp;
-   return $dscp;
+sub get_dscp {
+       my $url      = shift;
+       my $ip       = shift;
+       my $dev      = shift;
+       my $header   = shift;
+       my $protocol = shift;
+       my $port     = shift;
+
+       my $tos     = undef;
+       my $max_len = 0;
+
+       my $src_port = int( rand( 65535 - 1024 ) ) + 1024;
+       TRACE "TRACE In sub get_dscp";
+       DEBUG "DEBUG get_dscp ip:" . $ip . " url:" . $url . " dev:" . $dev . " 
port:" . $src_port . " ip protocol: " . $protocol;
+
+       # Use curl to get some traffic from the URL, but send the command to 
the background, so the capture that follows
+       # is while traffic is being returned
+       my $curl = 'curl --connect-timeout 2 --local-port ' . $src_port . ' --' 
. $protocol . ' -s -H "Host: ' . $header . '" ' . $url . ' 2>&1 > /dev/null';
+       DEBUG "DEBUG curl: " . $curl;
+       if ( $protocol eq 'ipv6' ) {
+               DEBUG "DEBUG running ip6";
+               system( "(sleep 1; " . $curl . " || ping6 -c 10 $ip 2>&1 > 
/dev/null)  &" );
+       }
+       else {
+               DEBUG "DEBUG running ip4";
+               system( "(sleep 1; " . $curl . " || ping -c 10 $ip 2>&1 > 
/dev/null)  &" );
+       }
+
+       Net::PcapUtils::loop(
+               sub {
+                       my ( $user, $hdr, $pkt ) = @_;
+                       my $ip_obj;
+                       $ip_obj->{src_ip} = new NetAddr::IP( $ip_obj->{src_ip} 
);
+                       if ( $protocol eq "ipv4" ) {
+                               $ip_obj = NetPacket::IP->decode( 
eth_strip($pkt) );
+                               DEBUG "DEBUG <=> $ip_obj->{src_ip} -> 
$ip_obj->{dest_ip} proto: $ip_obj->{proto} tos $ip_obj->{tos} len 
$ip_obj->{len}\n";
+                               my $tcp_obj = NetPacket::TCP->decode( 
$ip_obj->{data} );
+                               DEBUG
+                                       "DEBUG TCP1 
$ip_obj->{src_ip}:$tcp_obj->{src_port} -> 
$ip_obj->{dest_ip}:$tcp_obj->{dest_port} proto: $ip_obj->{proto} tos 
$ip_obj->{tos} len $ip_obj->{len}\n";
+                               if ( $ip_obj->{src_ip} eq $ip && $ip_obj->{len} 
> $max_len && $ip_obj->{proto} == 6 ) {
+                                       my $tcp_obj = NetPacket::TCP->decode( 
$ip_obj->{data} );
+                                       DEBUG
+                                               "DEBUG TCP2 
$ip_obj->{src_ip}:$tcp_obj->{src_port} -> 
$ip_obj->{dest_ip}:$tcp_obj->{dest_port} $ip_obj->{proto} tos $ip_obj->{tos} 
len $ip_obj->{len}\n";
+                                       if ( ( $tcp_obj->{src_port} == $port ) 
&& ( $tcp_obj->{dest_port} == $src_port ) ) {
+                                               DEBUG
+                                                       "DEBUG TCP3 
$ip_obj->{src_ip}:$tcp_obj->{src_port} -> 
$ip_obj->{dest_ip}:$tcp_obj->{dest_port} $ip_obj->{proto} tos $ip_obj->{tos} 
len $ip_obj->{len}\n";
+                                               $max_len = $ip_obj->{len};
+                                               $tos     = $ip_obj->{tos};
+                                       }
+                               }
+                       }
+                       elsif ( $protocol eq "ipv6" ) {
+                               $ip_obj = NetPacket::IPv6->decode( 
eth_strip($pkt) );
+                               DEBUG "DEBUG <=> $ip_obj->{src_ip} -> 
$ip_obj->{dest_ip} proto: $ip_obj->{nxt} tos $ip_obj->{class} len 
$ip_obj->{plen}\n";
+                               my $tcp_obj = NetPacket::TCP->decode( 
$ip_obj->{data} );
+
+                               # DEBUG "DEBUG Comparison of IPs 
ip_obj->{src_ip}: $ip_obj->{src_ip}, ip: $ip\n"
+                               DEBUG
+                                       "DEBUG TCP1 
$ip_obj->{src_ip}:$tcp_obj->{src_port} -> 
$ip_obj->{dest_ip}:$tcp_obj->{dest_port} proto: $ip_obj->{nxt} tos 
$ip_obj->{class} len $ip_obj->{plen}\n";
+                               if ( $ip_obj->{src_ip} eq $ip && 
$ip_obj->{plen} > $max_len && $ip_obj->{nxt} == 6 ) {
+                                       my $tcp_obj = NetPacket::TCP->decode( 
$ip_obj->{data} );
+                                       DEBUG
+                                               "DEBUG TCP2 
$ip_obj->{src_ip}:$tcp_obj->{src_port} -> 
$ip_obj->{dest_ip}:$tcp_obj->{dest_port} $ip_obj->{nxt} tos $ip_obj->{class} 
len $ip_obj->{plen}\n";
+                                       if ( $tcp_obj->{src_port} == $port && 
$tcp_obj->{dest_port} == $src_port ) {
+                                               DEBUG
+                                                       "DEBUG TCP3 
$ip_obj->{src_ip}:$tcp_obj->{src_port} -> 
$ip_obj->{dest_ip}:$tcp_obj->{dest_port} $ip_obj->{nxt} tos $ip_obj->{class} 
len $ip_obj->{plen}\n";
+                                               $max_len = $ip_obj->{plen};
+                                               $tos     = $ip_obj->{class};
+                                       }
+                               }
+                       }
+               },
+               FILTER     => 'host ' . $ip,
+               DEV        => $dev,
+               NUMPACKETS => 7,
+               TIMEOUT    => 10
+       );
+
+       my $dscp;
+       if ( defined($tos) ) {
+               $dscp = $tos >> 2;
+       }
+       else {
+               $dscp = -1;
+       }
+       TRACE "TRACE exiting sub get_dscp returning $dscp for dscp";
+       return $dscp;
 }
 
-sub ltrim { my $s = shift; $s =~ s/^\s+//;       return $s };
-sub rtrim { my $s = shift; $s =~ s/\s+$//;       return $s };
-sub  trim { my $s = shift; $s =~ s/^\s+|\s+$//g; return $s };
+sub ltrim { my $s = shift; $s =~ s/^\s+//;       return $s }
+sub rtrim { my $s = shift; $s =~ s/\s+$//;       return $s }
+sub trim  { my $s = shift; $s =~ s/^\s+|\s+$//g; return $s }
 
 sub help() {
-   print "ToDSCPCheck.pl -c \"{\\\"base_url\\\": \\\"https://localhost\\\";, 
\\\"check_name\\\": \\\"DSCP\\\", \\\"cms_interface\\\": \\\"eth0\\\"[, 
\\\"name\\\": \\\"DSCP Service Check\\\", \\\"syslog_facility\\\": 
\\\"local0\\\"]}\" [-f <1-3>] [-l <1-3>]\n";
-   print "\n";
-   print "-c   json formatted list of variables\n";
-   print "     base_url: required\n";
-   print "        URL of the Traffic Ops server.\n";
-   print "     check_name: required\n";
-   print "        The name of this check.\n";
-   print "     cms_interface: required\n";
-   print "        Interface used to communicate with edges.\n";
-   print "     name: optional\n";
-   print "        The long name of this check. used in conjuction with 
syslog_facility.\n";
-   print "     syslog_facility: optional\n";
-   print "        The syslog facility to send messages. Requires the \"name\" 
option to\n";
-   print "        be set.\n";
-   print "-f   Force a FAIL or OK message\n";
-   print "        1: FAIL Unable to connect to edge server.\n";
-   print "        2: OK\n";
-   print "        3: FAIL DSCP values didn't match.\n";
-   print "-h   Print this message\n";
-   print "-l   Debug level\n";
-   print "-q   Don't post results to Traffic Ops.\n";
-   print 
"================================================================================\n";
-   # the above line of equal signs is 80 columns
-   print "\n";
+       print
+               "ToDSCPCheck.pl -c \"{\\\"base_url\\\": 
\\\"https://localhost\\\";, \\\"check_name\\\": \\\"DSCP\\\", 
\\\"cms_interface\\\": \\\"eth0\\\"[, \\\"name\\\": \\\"DSCP Service Check\\\", 
\\\"syslog_facility\\\": \\\"local0\\\"]}\" [-f <1-3>] [-l <1-3>]  [-q]    [-s  
   <hostname>]     [-x     <xmlId>]\n";
+       print "\n";
+       print "-c   json formatted list of variables\n";
+       print "     base_url: required\n";
+       print "        URL of the Traffic Ops server.\n";
+       print "     check_name: required\n";
+       print "        The name of this check.\n";
+       print "     cms_interface: required\n";
+       print "        Interface used to communicate with edges.\n";
+       print "     name: optional\n";
+       print "        The long name of this check. used in conjuction with 
syslog_facility.\n";
+       print "     syslog_facility: optional\n";
+       print "        The syslog facility to send messages. Requires the 
\"name\" option to\n";
+       print "        be set.\n";
+       print "-f   Force a FAIL or OK message\n";
+       print "        1: FAIL Unable to connect to edge server.\n";
+       print "        2: OK\n";
+       print "        3: FAIL DSCP values didn't match.\n";
+       print "-h   Print this message\n";
+       print "-l   Logging level. 1 - 6. 1 being least (FATAL). 6 being most 
(TRACE). Default\n";
+       print "     is 2 (INFO).\n";
+       print "-q   Don't post results to Traffic Ops.\n";
+       print "-s   Check a specific server. Host name as it appears in Traffic 
Ops. Not FQDN.\n";
+       print "-x   Check a specific xmlId.\n";
+       print 
"================================================================================\n";
+
+       # the above line of equal signs is 80 columns
+       print "\n";
 }

Reply via email to