• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 575
  • Last Modified:

shell/perl script to output data in IP format

Hello Folks

I have a dns zone db file called ( 128-255.163.107.64.in-addr.arpa.db) that looks like so

( small excerpt )

28-255.163.107.64.in-addr.arpa. 10800 IN SOA ns.sark.edu. admin.sark.edu. 2013060702 10800 3600 1209600 10800
128-255.163.107.64.in-addr.arpa.        10800   IN      NS      ns1.sark.edu.
128-255.163.107.64.in-addr.arpa.        10800   IN      NS      ns1.sark.net.
129.128-255.163.107.64.in-addr.arpa.    10800   IN      PTR     neiu-man-main-129.sark.edu.
130.128-255.163.107.64.in-addr.arpa.    10800   IN      PTR     neiu-man-main-130.sark.edu.
131.128-255.163.107.64.in-addr.arpa.    10800   IN      PTR     neiu-man-main-131.sark.edu.
132.128-255.163.107.64.in-addr.arpa.    10800   IN      PTR     neiu-man-main-132.sark.edu.

What I care about are the stuff after the NS section

so for example line 4
129.128-255.163.107.64.in-addr.arpa.    10800   IN      PTR     neiu-man-main-129.sark.edu.

I need to a way to convert the 129.128-255.163.107.64.in-addr.arpa. line

to just 64.197.163.129 to a separate file with just the IP's

So as you can see I dont need the 128-255 bit. I like to make it universal so when I run this script/shell it wont care on what the prefix is ( which is that dash on the in.addr.arpa line.

I am using a Mac if that helps.

Thank you,
0
richsark
Asked:
richsark
  • 14
  • 10
1 Solution
 
Richard DavisSenior Web DeveloperCommented:
So, I understand everything about your question except for the 128-255 part. How exactly would you have arrived at the 64.197.163.129 from the given string 129.128-255.163.107.64.in-addr.arpa.?

Without that particular tidbit of information, it's doubtful you can obtain the desired result you're asking for without further clarity regarding that item.

Based on your post, I am guessing that you want all of the IPs represented within the given range. e.g. if the range were 195-197, then you would want a result of;

64.195.163.129
64.196.163.129
64.197.163.129

written to a target file?

~AB
0
 
richsarkAuthor Commented:
Hi,

Yea, I just need the IP's
So its actually reversed on the file ( hence PTR record in DNS terms )

130.128-255.163.107.64.in-addr.arpa.

would become
64.107.163.130

So I just need the section on the dash taken out. In this case 128-255. Which is an RFC 2317 prefix name.

And yes, separate file called  130.128-255.163.107.64.-CHANGED

Thanks, let me know if that answers your question.
0
 
Richard DavisSenior Web DeveloperCommented:
Ahhhh! I see. In that case, that drastically simplifies things. Give this a shot;

#!/usr/bin/perl

use strict;
use warnings;

# I use Data::Dumper for debugging. Leave out if you do not have this module installed.
use Data::Dumper;

my $out_file = "ips.txt";

my $ip_rng   = "129.128-255.163.107.64.in-addr.arpa.";
my @ip_parts = split(/\./, $ip_rng);

# Get rid of the last two elements leaving only the ip sub parts.
pop @ip_parts;
pop @ip_parts;

# Now reverse the array so that we can reassemble the IP properly.
@ip_parts = reverse(@ip_parts);

# Identify and wipe out the hyphened value
@ip_parts = map {
  if($_ !~ /-/) {
    $_;
  }
} @ip_parts;

# Construct the new IP by concatenation and skipping any zero length elements
my $ip = "";
foreach my $ip_sub (@ip_parts) {
  $ip .= "$ip_sub." if length($ip_sub);
}

# Strip off the trailing period
$ip =~ s/\.$//;

warn Dumper $ip;

# Write the result to a file
open(my $FP, ">", $out_file) or die "Cannot open file $out_file\n";
print $FP "$ip\n";
close($FP);

Open in new window

0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
richsarkAuthor Commented:
Just one thing.. in my opening statement on the first thread when I wrote:

"I need to a way to convert the 129.128-255.163.107.64.in-addr.arpa. line

to just 64.197.163.129 to a separate file with just the IP's"


I should of read " I need to a way to convert the 129.128-255.163.107.64.in-addr.arpa. line

to just 64.107.163.129 to a separate file with just the IP's"
0
 
richsarkAuthor Commented:
Hi,

I run it as:

$ ./convert-2317.pl

$VAR1 = '64.107.163';

I just the above. Looking at the ips.txt it shows:

64.107.163
ips.txt (END)
0
 
Richard DavisSenior Web DeveloperCommented:
Did you modify the line;

my $ip_rng   = "129.128-255.163.107.64.in-addr.arpa.";

Open in new window


The way I wrote the code, it is meant to take the full string, break it up based on periods, and then perform the remaining operations on the resulting array from the split function. Thus returning the IP address you wanted extracted from that string.

~AB
0
 
richsarkAuthor Commented:
Yes, The file is actually called
128-255.163.107.64.in-addr.arpa.db

so I modified line 11
to
my $ip_rng   = "128-255.163.107.64.in-addr.arpa.db";

But, I sorta want it universal to use on any db file I tell it, but I guess for now lets get it working on this one file :)
0
 
richsarkAuthor Commented:
I changed it to

my $ip_rng   = "128-255.163.107.64.in-addr.arpa.";

and still get this in the ips.txt:
64.107.163
ips.txt (END)
0
 
richsarkAuthor Commented:
So, to confirm, The file name is called "129.128-255.163.107.64.in-addr.arpa.db"

I need your script to run against the contents of the above file name to produce the ip's

Sound ok?
0
 
Richard DavisSenior Web DeveloperCommented:
Yeah, I get it now. I'm at my office at the moment and just got pulled off onto something of a priority.

I'll reply back shortly with the full solution that will read a file and pull out just the NS lines and perform the IP scraping operations on the lines.


~AB
0
 
richsarkAuthor Commented:
Fantastic ! Thank you !

Actually, I need just the PTR lines :)

/Rich
0
 
Richard DavisSenior Web DeveloperCommented:
I'm back now. I can achieve what you want, except there's only one problem. Upon examining your DNS file more closely, I can't seem to figure something out.

Your NS lines are like this;

128-255.163.107.64.in-addr.arpa.

How am I supposed to get you the single IP from what appears to be a range of IPs?
I noticed that the NS records also don't have a leading IP quad like the others.

Secondly, I don't fully understand how a nameserver record can use a range like that also. That appears to be malformed, unless I am missing something here.

~AB
0
 
richsarkAuthor Commented:
Yes. It's classified as classless routing
It's called rfc 2317

I know it's malformed but that's DNS for ya.

So if we can get it to read a db and restructure the ptr parts like I mentioned above I am happy

Did that help u answer your question ?
0
 
richsarkAuthor Commented:
Do the contents of this db file had lots of ptr lines. Just want to pull one as an example.

129.128-255.163.107.64.in-addr.arpa.    10800   IN      PTR     neiu-man-main-129.sark.edu.

So the script would look into a file I tell it. Read the contents. When it hits a ptr line like above

It would spit out a txt file of the restructured ip

So this one example would spit out in a txt file

64.107.163.129
0
 
Richard DavisSenior Web DeveloperCommented:
Try this. It extracts only the PTR records. You will obviously need to have a file with the name specified in the $in_file variable.

#!/usr/bin/perl

use strict;
use warnings;

# I use Data::Dumper for debugging. Leave out if you do not have this module installed.
use Data::Dumper;

# Full path to your db file you want to extract from
my $in_file  = "130.128-255.163.107.64.in-addr.arpa.db";
# Full path to the resulting output file you want the results written to.
my $out_file = "ips.txt";

open(my $FP_IN, "<", $in_file) or die "Cannot open in file $in_file\n";
open(my $FP_OUT, ">", $out_file) or die "Cannot open out file $out_file\n";

while(my $line = <$FP_IN>) {
  if($line =~ /PTR/) {
    my @ip_parts = split(/\./, $line);

    # Get rid of the last six elements leaving only the ip sub parts.
    pop @ip_parts;
    pop @ip_parts;
    pop @ip_parts;
    pop @ip_parts;
    pop @ip_parts;
    pop @ip_parts;

    # Now reverse the array so that we can reassemble the IP properly.
    @ip_parts = reverse(@ip_parts);

    # Identify and wipe out the hyphened value
    @ip_parts = map {
      if($_ !~ /-/) {
        $_;
      }
    } @ip_parts;

    # Construct the new IP by concatenation and skipping any zero length elements
    my $ip = "";
    foreach my $ip_sub (@ip_parts) {
      $ip .= "$ip_sub." if length($ip_sub);
    }

    # Strip off the trailing period
    $ip =~ s/\.$//;

    print "Extracted PTR IP: $ip\n";

    # Write the result to a file
    print $FP_OUT "$ip\n";
  }
}
close($FP_IN);
close($FP_OUT);

Open in new window


~AB
0
 
richsarkAuthor Commented:
Cool. Will try. On way home now.
0
 
richsarkAuthor Commented:
Nice work !!!

Thanks a Mill !
0
 
Richard DavisSenior Web DeveloperCommented:
Glad to be able to help, richsark!

Happy coding :)

~AB
0
 
richsarkAuthor Commented:
Hey Adrian,

I can open another post, but much effort would it be to Update the script so you can pass it the zone and pass it the output file?

Thanks

Rich
0
 
Richard DavisSenior Web DeveloperCommented:
That's actually a fairly simple change. You'll want to ensure that you have the Getopt::Long perl module installed so that the script can accept command-line arguments.

Are you familiar with installing perl modules from CPAN?

~AB
0
 
richsarkAuthor Commented:
yes. I am. I think I have it already :)
0
 
Richard DavisSenior Web DeveloperCommented:
Cool.

So, this code will do what you requested. I commented out the original lines where the in and out filenames were hard coded in favor of the command-line implementation. There are no default values and this version of the script always requires both parameters to be present for it to work.

To see how to use the script, just execute it with a -help command-line option only;

./convert-2317.pl -help

Normal usage is as follows;

./convert-2317.pl -infile=/path/to/infile.db -outfile=/path/to/outfile.txt

#!/usr/bin/perl

use strict;
use warnings;

use Getopt::Long;

# I use Data::Dumper for debugging. Leave out if you do not have this module installed.
use Data::Dumper;

# Full path to your db file you want to extract from
#my $in_file  = "130.128-255.163.107.64.in-addr.arpa.db";
# Full path to the resulting output file you want the results written to.
#my $out_file = "ips.txt";

my $help     = 0;
my $in_file  = '';
my $out_file = '';

# Handler for accepting command-line arguments
##########################################################################
my $result = GetOptions (
  "help"      => \$help,
  "infile=s"  => \$in_file,
  "outfile=s" => \$out_file
);

usage() if $help;

die "You must supply a path and filename to your input file\n" if !length($in_file);
die "You must supply a path and filename to your output file\n" if !length($out_file);

sub usage {
print <<EOF;
################################################################################
USAGE: ./ip_parser.pl -infile=/path/to/infile.ext -outfile=/path/to/outfile.ext
--------------------------------------------------------------------------------
Both arguments are required and failure to supply either will result in the script
dying with a message specifying the missing argument.
################################################################################
EOF
}
##########################################################################

open(my $FP_IN, "<", $in_file) or die "Cannot open in file $in_file\n";
open(my $FP_OUT, ">", $out_file) or die "Cannot open out file $out_file\n";

while(my $line = <$FP_IN>) {
  if($line =~ /PTR/) {
    my @ip_parts = split(/\./, $line);

    # Get rid of the last six elements leaving only the ip sub parts.
    pop @ip_parts;
    pop @ip_parts;
    pop @ip_parts;
    pop @ip_parts;
    pop @ip_parts;
    pop @ip_parts;

    # Now reverse the array so that we can reassemble the IP properly.
    @ip_parts = reverse(@ip_parts);

    # Identify and wipe out the hyphened value
    @ip_parts = map {
      if($_ !~ /-/) {
        $_;
      }
    } @ip_parts;

    # Construct the new IP by concatenation and skipping any zero length elements
    my $ip = "";
    foreach my $ip_sub (@ip_parts) {
      $ip .= "$ip_sub." if length($ip_sub);
    }

    # Strip off the trailing period
    $ip =~ s/\.$//;

    print "Extracted PTR IP: $ip\n";

    # Write the result to a file
    print $FP_OUT "$ip\n";
  }
}
close($FP_IN);
close($FP_OUT);

Open in new window

0
 
richsarkAuthor Commented:
Nice.  Will try.  Thanks a mill
0
 
Richard DavisSenior Web DeveloperCommented:
You bet. :)
0

Featured Post

New feature and membership benefit!

New feature! Upgrade and increase expert visibility of your issues with Priority Questions.

  • 14
  • 10
Tackle projects and never again get stuck behind a technical roadblock.
Join Now