Find the answer to your Linux question:
Page 1 of 2 1 2 LastLast
Results 1 to 10 of 11
Like Tree4Likes
First of all, thanks so much for taking the time to look at my post! I am not sure if I worded what I'm trying to achieve correctly within the ...
Enjoy an ad free experience by logging in. Not a member yet? Register.
  1. #1
    Just Joined! exelan's Avatar
    Join Date
    Jun 2012
    Location
    Montana
    Posts
    8

    Question Outputting Clean Search Results From A Large Config File?


    First of all, thanks so much for taking the time to look at my post!

    I am not sure if I worded what I'm trying to achieve correctly within the subject line, so forgive my vagueness. I am trying find the right commands or script that search through a very large Cisco config for "virtual names" and their associated IPv4 addresses as well as the same search criteria's IPv6 addresses and outputting it into a format that gets rid of all the extras.

    Below is an example of the config:

    Code:
     }
     virtual ipv4-site1.testsite.com_class_vs {
      pool ipv4-testsite.com_pl
      destination 192.168.141.142:https
      ip protocol tcp
      profiles tcp_default_pr {}
      vlans ipv4_192.168.245.12_25 enable
     }
     virtual ipv6-site1.testsite.com_class_vs {
      snatpool ipv6_testsite.com_sp
      pool ipv6-testsite.com_pl
      destination 2001:111:1111:1001::10.https
      ip protocol tcp
      profiles tcp_exception_300s_pr {}
      vlans ipv6_192.168.245.12_25 enable
     }
     virtual ipv4-site2.testsite.com_class_vs {
      pool ipv4-testsite.com_pl
      destination 192.168.141.143:https
      ip protocol tcp
      profiles tcp_default_pr {}
      vlans ipv4_192.168.245.12_25 enable
     }
     virtual ipv6-site2.testsite.com_class_vs {
      snatpool ipv6_testsite.com_sp
      pool ipv6-testsite.com_pl
      destination 2001:111:1111:1001::11.https
      ip protocol tcp
      profiles tcp_exception_300s_pr {}
      vlans ipv6_192.168.245.12_25 enable
     }
    Ultimately I'm trying to take the results of search strings "ipv6, virtual, and destination" and place them in the format below to compare what I need to create or change.

    So the output would be something like:

    Code:
    Results for site2.testsite.com
    
         v4 Virtual: ipv4-site2.testsite.com
         v4 Address: 192.168.141.143
    
    IPv6 addresses:
    
         v6 Virtual: ipv6-site2.testsite.com
         v6 Address: 2001:111:1111:1001::11
    And alternatively if it doesn't find any v6 -> v4 association or vice versa, to return some sort of result:

    Code:
    This is what was found for site2.testsite.com:
    
         v4 Virtual: ipv4-site2.testsite.com
         v4 Address: 192.168.141.143
    
    IPv6 addresses:
    
         <none>
    I know the names of the virtuals have different DNS prefixes, but the rest of the DNS name should be the same (ex: site2.testsite.com) for both the v4 and v6 addresess.

    Thank in advance you guys so much for looking!!

  2. #2
    Trusted Penguin
    Join Date
    May 2011
    Posts
    4,353
    try this out, works for me, based upon your example cisco config file. put it in a script (call it "read-vhosts.pl"), and make it executable. then when you execute it, pass it the path to the cisco config file as the first argument, e.g.:

    Code:
    chmod +x ~/read-vhosts.pl
    ~/read-vhosts.pl /path/to/cisco-vhosts.txt
    below is the code. i tried to comment it sufficiently to explain what i was doing:
    Code:
    #!/usr/bin/perl
    use strict;
    use warnings;
    
    # get the cisco config file as the 1st argument on the command line
    my $file = shift || die "Give me the Cisco config file\n";
    
    # hash ref containing lines of data, per virtual host
    my %lines;
    
    # virtual host counter
    my $i = 0;
    
    # open the file and read the contents
    open(FH,'<',$file) or die "can't open '$file': $!\n";
    while(<FH>){
      chomp;
    
      # match on the line containing the virtual host name
      if(/^[ \t]*virtual[ \t](ipv[46]-.*)_class_vs[ \t]{/){
    
        # save to hash
        $lines{$i}{'vhost'} = $1;
    
        # one-up the virtual hosts counter
        $i+=1;
      }else{
        # save to hash
        push(@{$lines{$i-1}{'lines'}},$_) if($i>0);
      }
    }
    
    # close the file
    close(FH);
    
    # hash to store ips, per ipv, per vhost
    my %vhosts;
    
    # get ip addresses and save into ipv4/6 groups
    for my $i(sort {$a<=>$b} keys %lines){
      (my $vhost = $lines{$i}{'vhost'}) =~ s/^(ipv[46])-//;
      my $ipv = $1;
      for my $line(@{$lines{$i}{'lines'}}){
        if($line =~ /^[ \t]*destination[ \t](.*)[.:]https/){
          $vhosts{$vhost}{$ipv} = $1;
          last;
        }
      }
    }
    
    # print what we've got
    for my $vhost(keys %vhosts){
      print "\nResults for virtual host: ",$vhost,"\n";
      for my $ipv(qw/ipv4 ipv6/){
        (my $v = $ipv) =~ s/^ip//;
        print "\nIP$v addresses:\n";
        if($vhosts{$vhost}{$ipv}){
          print "\t$v Virtual: ",$ipv,"-",$vhost,"\n";
          print "\t$v Address: ",$vhosts{$vhost}{$ipv},"\n\n";
        }else{
          print "\t<none>\n\n";
        }
      }
      print "---------------------------------------------\n";
    }
    
    exit(0);
    Last edited by atreyu; 07-03-2012 at 01:44 AM. Reason: removed unnecessary line from code
    Irithori and exelan like this.

  3. #3
    Just Joined! exelan's Avatar
    Join Date
    Jun 2012
    Location
    Montana
    Posts
    8
    Oh wow atreyu! This is fantastic! I can't thank you enough for this... Testing it against the sample Config data that I provided works like a charm Of course in order to maintain the privacy of the Cisco config content, the IP addresses and virtual names that I posted originally are generic. I'm trying to find where in the script I can make those changes based on different content within the config because running it against the real config file pulls nothing.

    Again, thanks so much for this!

  4. #4
    Trusted Penguin
    Join Date
    May 2011
    Posts
    4,353
    Quote Originally Posted by exelan View Post
    Of course in order to maintain the privacy of the Cisco config content, the IP addresses and virtual names that I posted originally are generic. I'm trying to find where in the script I can make those changes based on different content within the config because running it against the real config file pulls nothing.
    what is different about the real config files, apart from the ip addresses themselves?

    in any case, the line of interest in the code is probably

    Code:
    if($line =~ /^[ \t]*destination[ \t](.*)[.:]https/){
    exelan likes this.

  5. #5
    Just Joined! exelan's Avatar
    Join Date
    Jun 2012
    Location
    Montana
    Posts
    8
    Quote Originally Posted by atreyu View Post
    what is different about the real config files, apart from the ip addresses themselves?
    Well this is a sample of the actual config:

    What indicates IPv4 addresses in the virtual hosts line varies depending on the unique identifier of the virtual host name, occasionally it will have "relay" within the line, and sometimes it will have a different DNS A record as well.

    Code:
     }
     virtual bes911-relay.frstcp.com_osppe_443_vs {
      pool bes911-relay.frstcp.com_osppe_443_pl
      destination 131.53.49.212:https
      ip protocol tcp
      profiles tcp_default_gns_pr {}
      vlans p_osppe_f_r_131.53.49.128_25 enable
     }
     virtual boc912-relay.frstcp.com_osppe_443_vs {
      pool boc912-relay.frstcp.com_osppe_443_pl
      destination 131.53.49.215:https
      ip protocol tcp
      profiles tcp_default_gns_pr {}
      vlans p_osppe_f_r_131.53.49.128_25 enable
     }
    The commonality for the IPv6 addresses is the hostname prefix which I've found remains the same "ipv6_":

    Code:
    }
     virtual ipv6_bes911-relay.frstcp.com_osppe_443_vs {
      snatpool ipv6_ipv4_sp
      pool bes911-relay.frstcp.com_osppe_443_pl
      destination 2b01:122:f408:1001::22.https
      ip protocol tcp
      profiles tcp_default_gns_pr {}
      vlans p_osppe_f_r_131.53.49.128_25 enable
     }
     virtual ipv6_boc912-relay.frstcp.com_osppe_443_vs {
      snatpool ipv6_ipv4_sp
      pool boc912-relay.frstcp.com_osppe_443_pl
      destination 2b01:122:f408:1001::23.https
      ip protocol tcp
      profiles tcp_default_gns_pr {}
      vlans p_osppe_f_r_131.53.49.128_25 enable
     }
    My guess is that your script was working based on either 1 of 2 possible search results for the virtual hostname, either "ipv4-site1.testsite.com" or "ipv6-site1.testsite.com". Which I guess breaks everything lol :\ I'm so sorry, I should just just formatted the sample config to emulate a little more closely to the actual config.

  6. #6
    Just Joined! exelan's Avatar
    Join Date
    Jun 2012
    Location
    Montana
    Posts
    8
    I'm pretty sure this is the line that has to be modified for the virtual host search to work:

    Code:
    if(/^[ \t]*virtual[ \t](ipv[46]-.*)_class_vs[ \t]{/){
    Again, I'm not too savvy with Regex or perl but I'm pretty sure "(ipv[46]-.*)" can be changed to find "osppe" and "_class" can be removed entirely.

    Also:

    Code:
    (my $vhost = $lines{$i}{'vhost'}) =~ s/^(ipv[46])-//;
    I think needs to be modified as well.

    Again atreyu, thanks SO much for the help. I'm learning a lot and it's making what I'm doing so much easier

  7. #7
    Trusted Penguin
    Join Date
    May 2011
    Posts
    4,353
    Quote Originally Posted by exelan View Post
    I'm pretty sure this is the line that has to be modified for the virtual host search to work:

    Code:
    if(/^[ \t]*virtual[ \t](ipv[46]-.*)_class_vs[ \t]{/){
    Again, I'm not too savvy with Regex or perl but I'm pretty sure "(ipv[46]-.*)" can be changed to find "osppe" and "_class" can be removed entirely.

    Also:

    Code:
    (my $vhost = $lines{$i}{'vhost'}) =~ s/^(ipv[46])-//;
    I think needs to be modified as well.

    Again atreyu, thanks SO much for the help. I'm learning a lot and it's making what I'm doing so much easier
    yep, you are right on. try this modified code and see if it works:
    Code:
    #!/usr/bin/perl
    use strict;
    use warnings;
    
    # get the cisco config file as the 1st argument on the command line
    my $file = shift || die "Give me the Cisco config file\n";
    
    # hash ref containing lines of data, per virtual host
    my %lines;
    
    # virtual host counter
    my $i = 0;
    
    # open the file and read the contents
    open(FH,'<',$file) or die "can't open '$file': $!\n";
    while(<FH>){
      chomp;
    
    #  if(/^[ \t]*virtual[ \t](ipv[46]-.*)_class_vs[ \t]{/){
      if(/^[ \t]*virtual[ \t](.*)_osppe_443_vs[ \t]{/){
        $lines{$i}{'vhost'} = $1;
    
        # one-up the virtual hosts counter
        $i+=1;
      }else{
        push(@{$lines{$i-1}{'lines'}},$_) if($i>0);
      }
    }
    
    # close the file
    close(FH);
    
    # hash to store ips, per ipv, per vhost
    my %vhosts;
    
    # get ip addresses and save into ipv4/6 groups
    for my $i(sort {$a<=>$b} keys %lines){
      my $vname = $lines{$i}{'vhost'};
      my $ipv = ($vname =~ /^(ipv6)_/) ? $1 : 'ipv4';
      (my $vhost = $vname) =~ s/^ipv6_//;
      $vhosts{$vhost}{$ipv}{'virtual'} = $vname;
    #  print "vname is $vname\n";
      for my $line(@{$lines{$i}{'lines'}}){
        if($line =~ /^[ \t]*destination[ \t](.*)[.:]https/){
          $vhosts{$vhost}{$ipv}{'ipaddr'} = $1;
          last;
        }
      }
    }
    
    # print what we've got
    for my $vhost(keys %vhosts){
      print "\nResults for virtual host: ",$vhost,"\n";
      for my $ipv(qw/ipv4 ipv6/){
        (my $v = $ipv) =~ s/^ip//;
        print "\nIP$v addresses:\n";
        if($vhosts{$vhost}{$ipv}){
    #      print "\t$v Virtual: ",$ipv,"_",$vhost,"\n";
          print "\t$v Virtual: ",$vhosts{$vhost}{$ipv}{'virtual'},"\n";
          print "\t$v Address: ",$vhosts{$vhost}{$ipv}{'ipaddr'},"\n\n";
        }else{
          print "\t<none>\n\n";
        }
      }
      print "---------------------------------------------\n";
    }
    
    exit(0);
    exelan likes this.

  8. #8
    Just Joined! exelan's Avatar
    Join Date
    Jun 2012
    Location
    Montana
    Posts
    8
    Atreyu, you are a wizard. This works great from the first few times I've tried it Again, I can't thank you enough but I'll sure try by promoting your help on the boards!

  9. #9
    Trusted Penguin
    Join Date
    May 2011
    Posts
    4,353
    hey, happy to help!

  10. #10
    Trusted Penguin
    Join Date
    May 2011
    Posts
    4,353
    The more I've been investigating these Cisco devices I've found that the actual IPv6 -> IPv4 mapping is done through the defined "pool":

    Code:

    }
    virtual ipv6_bes911-relay.frstcp.com_osppe_443_vs {
    snatpool ipv6_ipv4_sp
    pool bes911-relay.frstcp.com_osppe_443_pl
    destination 2b01:122:f408:1001::22.https
    ip protocol tcp
    profiles tcp_default_gns_pr {}
    vlans p_osppe_f_r_131.53.49.128_25 enable
    }

    So essentially in order for the IPv6 addresses to work, their "pool" needs to be identical to the corresponding IPv4 "pool". In the config the commonality would be "_pl"

    Code:

    }
    virtual bes911-relay.frstcp.com_osppe_443_vs {
    pool bes911-relay.frstcp.com_osppe_443_pl
    destination 131.53.49.212:https
    ip protocol tcp
    profiles tcp_default_gns_pr {}
    vlans p_osppe_f_r_131.53.49.128_25 enable
    }

    I've just found a few extra IPv6 virtuals that were added to the config which didn't work, and that was due to the fact that they weren't part of the same associated IPv4 pool.
    i've modified the code to sort by the pool value. so if two entries have the same pool, they'll be sorted together when the results are printed.

    see if it works...

    Code:
    #!/usr/bin/perl
    use strict;
    use warnings;
    
    # get the cisco config file as the 1st argument on the command line
    my $file = shift || die "Give me the Cisco config file\n";
    
    # hash ref containing lines of data, per virtual host
    my %lines;
    
    # virtual host counter
    my $i = 0;
    
    # open the file and read the contents
    open(FH,'<',$file) or die "can't open '$file': $!\n";
    while(<FH>){
      chomp;
    
    #  if(/^[ \t]*virtual[ \t](ipv[46]-.*)_class_vs[ \t]{/){
      if(/^[ \t]*virtual[ \t](.*)_osppe_443_vs[ \t]{/){
        $lines{$i}{'vhost'} = $1;
    
        # one-up the virtual hosts counter
        $i+=1;
      }else{
        push(@{$lines{$i-1}{'lines'}},$_) if($i>0);
      }
    }
    
    # close the file
    close(FH);
    
    # hash to store ips, per ipv, per vhost
    my %vhosts;
    
    # get ip addresses and save into ipv4/6 groups
    for my $i(sort {$a<=>$b} keys %lines){
      my $vname = $lines{$i}{'vhost'};
      my $ipv = ($vname =~ /^(ipv6)_/) ? $1 : 'ipv4';
      (my $vhost = $vname) =~ s/^ipv6_//;
    #  $vhosts{$vhost}{$ipv}{'virtual'} = $vname;
    #print "vname is $vname\n";
      my($pool,$ipaddr);
      for my $line(@{$lines{$i}{'lines'}}){
        if($line =~ /^[ \t]*destination[ \t](.*)[.:]https/){
    #      $vhosts{$vhost}{$ipv}{'ipaddr'} = $1;
          $ipaddr = $1;
          last;
        }elsif($line =~ /^[ \t]*pool[ \t](.*)$/){
          $pool = $1;
        }
      }
    
      die "Failed to get pool for entry $i\n" unless($pool);
      die "Failed to get address for entry $i\n" unless($ipaddr);
      push(@{$vhosts{$pool}},{
        'id'    => $i,
        'vname' => $vname,
        'ipv'   => $ipv,
        'addr'  => $ipaddr,
      });
    }
    
    for my $pool(keys %vhosts){
      print "\nPool $pool:\n";
      for my $hash(@{$vhosts{$pool}}){
        print "\n";
        for(qw/ipv vname addr/){
          printf("\t%-10s%s\n",$_.':',$hash->{$_});
        }
      }
      print "\n";
    }

Page 1 of 2 1 2 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •