Solved

shell/perl script to output data in IP format

Posted on 2013-06-13
24
513 Views
Last Modified: 2013-06-14
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
Comment
Question by:richsark
  • 14
  • 10
24 Comments
 
LVL 12

Expert Comment

by:adrian_brooks
Comment Utility
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
 
LVL 1

Author Comment

by:richsark
Comment Utility
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
 
LVL 12

Expert Comment

by:adrian_brooks
Comment Utility
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
 
LVL 1

Author Comment

by:richsark
Comment Utility
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
 
LVL 1

Author Comment

by:richsark
Comment Utility
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
 
LVL 12

Expert Comment

by:adrian_brooks
Comment Utility
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
 
LVL 1

Author Comment

by:richsark
Comment Utility
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
 
LVL 1

Author Comment

by:richsark
Comment Utility
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
 
LVL 1

Author Comment

by:richsark
Comment Utility
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
 
LVL 12

Expert Comment

by:adrian_brooks
Comment Utility
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
 
LVL 1

Author Comment

by:richsark
Comment Utility
Fantastic ! Thank you !

Actually, I need just the PTR lines :)

/Rich
0
 
LVL 12

Expert Comment

by:adrian_brooks
Comment Utility
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
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 1

Author Comment

by:richsark
Comment Utility
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
 
LVL 1

Author Comment

by:richsark
Comment Utility
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
 
LVL 12

Accepted Solution

by:
adrian_brooks earned 500 total points
Comment Utility
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
 
LVL 1

Author Comment

by:richsark
Comment Utility
Cool. Will try. On way home now.
0
 
LVL 1

Author Closing Comment

by:richsark
Comment Utility
Nice work !!!

Thanks a Mill !
0
 
LVL 12

Expert Comment

by:adrian_brooks
Comment Utility
Glad to be able to help, richsark!

Happy coding :)

~AB
0
 
LVL 1

Author Comment

by:richsark
Comment Utility
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
 
LVL 12

Expert Comment

by:adrian_brooks
Comment Utility
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
 
LVL 1

Author Comment

by:richsark
Comment Utility
yes. I am. I think I have it already :)
0
 
LVL 12

Expert Comment

by:adrian_brooks
Comment Utility
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
 
LVL 1

Author Comment

by:richsark
Comment Utility
Nice.  Will try.  Thanks a mill
0
 
LVL 12

Expert Comment

by:adrian_brooks
Comment Utility
You bet. :)
0

Featured Post

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

I've just discovered very important differences between Windows an Unix formats in Perl,at least 5.xx.. MOST IMPORTANT: Use Unix file format while saving Your script. otherwise it will have ^M s or smth likely weird in the EOL, Then DO NOT use m…
Email validation in proper way is  very important validation required in any web pages. This code is self explainable except that Regular Expression which I used for pattern matching. I originally published as a thread on my website : http://www…
Learn several ways to interact with files and get file information from the bash shell. ls lists the contents of a directory: Using the -a flag displays hidden files: Using the -l flag formats the output in a long list: The file command gives us mor…
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now