#!/usr/bin/perl # ipa2int.pl--Translate an IP Address to a MySQL-style integer # $Id: ipa2int.pl 1.1 2004/01/31 04:35:33 JP Exp $ # $Log: ipa2int.pl $ # Revision 1.1 2004/01/31 04:35:33 JP # Add -v and converted to using pack/unpack # # Revision 1.0 2003/08/17 04:46:18 jp # Initial Revision # $ver = '$Revision: 1.1 $'; # JP Vossen ########################################################################## (($myname = $0) =~ s/^.*(\/|\\)//ig); # remove up to last "\" or "/" $Greeting = ("$myname $ver Copyright 2003-2004 JP Vossen (http://www.jpsdomain.org/)\n"); $Greeting .= (" Licensed under the GNU GENERAL PUBLIC LICENSE:\n"); $Greeting .= (" See http://www.gnu.org/copyleft/gpl.html for full text and details.\n"); if (("@ARGV" =~ /\?/) || ("@ARGV" =~ /-h/) || "@ARGV" =~ /--help/) { print STDERR ("\n$Greeting\n\n"); print STDERR <<"EoN"; # Usage notes Usage: $myname [OPTIONS] (-i [FILE]) (-o [FILE] | -W) (-q) -i {infile} = Use infile as the input file, otherwise use STDIN. -o {outfile} = Use outfile as the output file, otherwise use STDOUT. -d {delimiter} = Use as input delimiter, default is TAB. -D {delimiter} = Use as output delimiter, default is TAB. -v = Do the reVerse, Int2IPA (not for in-line data). -W = Write output to the Windows Clipboard instead of a file. -q = Be quiet about it. -B = Print deBug messages to STDERR. Translate an IP Address to a MySQL-style integer. Useful for pre-processing data (i.e. FW logs) before it is imported into MySQL. IPA2Int works in-line in your records. Int2IPA can only work on packed IPAs due to the difficulty of recognizing what to convert in in-line data. UNIX Perl one-liners: perl -e 'use Socket; print (inet_ntoa (pack "N", 168430090));' perl -e 'use Socket; print (unpack "N", inet_aton("10.10.10.10"));' MySQL code: select inet_ntoa(168430090); select inet_aton('10.10.10.10'); EoN die ("\n"); } # end of usage use Socket; # Needed for 'inet_aton' use Getopt::Std; # Use Perl5 built-in program argument handler getopts('i:o:d:WvqD:B'); # Define possible args. # Set defaults $delimiter_in = $opt_d || "\t"; $delimiter_out = $opt_D || "\t"; if (! $opt_i) { $opt_i = "-"; } # If no input file specified, use STDIN if (! $opt_o) { $opt_o = "-"; } # If no output file specified, use STDOUT open (INFILE, "$opt_i") or die ("$myname: error opening '$opt_i' for input: $!\n"); if ($opt_W) { # We're sending the output directly into the Clipboard # If output not STDOUT, then we're confused: if ($opt_o ne "-") { die ("$myname: Can't use -o and -W at the same time!\n"); } use Win32::Clipboard; # Import the clipboard module use IO::File; # Import File IO (for a temp file) # Use a secure temp file that's automatically deleted when we're finished. $OUTFILE = IO::File->new_tmpfile || die ("$myname: error opening temp file: $!\n"); } else { # Note use of indirect file handle (e.g. '$' on $OUTFILE), needed for temp file open ($OUTFILE, ">$opt_o") or die ("$myname: error opening '$opt_o' for output: $!\n"); } # end of if using clipboard if (! $opt_q) { print STDERR ("\n$Greeting\n"); } while ($aline = ) { undef(@infields); # Start from scratch with the arrays... Since we're undef(@outfields); # 'pushing' into them, they need to be cleared. chomp($aline); # Split fields on delimiter @infields = split (/$delimiter_in/, $aline); # Process EACH field foreach $field (@infields) { if ($opt_B) { warn ("Trimming: ~$field~.\n"); } $field =~ s/^\s+|\s+$//g; # Remove leading/trailing whitespace if ($field =~ m/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) { # Looks like this field is an IP Address if ($opt_B) { warn ("Have an IPA: ~$field~.\n"); } # OBSOLETE $field = &jp_aton($field); # Convert the IPA (OBSOLETE) # N = A long in "network" (big-endian) order $field = (unpack "N", (inet_aton($field))); # Convert the IPA push(@outfields, $field); # Add to the output } elsif ((defined $opt_v) and ($field =~ m/^\d{8,10}$/)) { # Looks like this field is an INT if ($opt_B) { warn ("Have an INT: ~$field~.\n"); } # N = A long in "network" (big-endian) order $field = (inet_ntoa (pack "N", $field)); # Convert the IPA push(@outfields, $field); # Add to the output } else { if ($opt_B) { warn ("Normal field: ~$field~.\n"); } push(@outfields, $field); # Add to the output } # end of if IPA } # end of foreach field # Re-combine the output, using the specified delimiter $aline = join ($delimiter_out, @outfields); # Write the output print $OUTFILE ("$aline\n"); } # end of while input if ($opt_W) { # We're sending the output directly into the Clipboard seek($OUTFILE, 0, 0) or die ("$myname: error couldn't rewind temp OUTPUT file: $!\n"); undef ($/); # Undefine the input line terminator so we grab the whole thing my $cboard = <$OUTFILE>; # Grab it ALL Win32::Clipboard::Set("$cboard"); # Send it to the clipboard } # end of output to clipboard if (! $opt_q) { print STDERR ("\n\a$myname finished in ",time()-$^T," seconds.\n"); } ########################################################################## #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # OBSOLETE--For documentation only #sub jp_aton { # # Given an IP Address, returns a MySQL-style integer. # # # New, much better code, but obsolete since it's done about without # # the function call! # my $ipa = $_[0]; # # N = A long in "network" (big-endian) order # return (unpack "N", (inet_aton($ipa))); # # # This is redundant, since we only ever CALL this sub if we have an IPA. # # But it might be useful in other cases. (Not tested) # # if ($ipa !~ m/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) { # # warn ("~$ipa~ does not look like an IP Address. Returning NULL.\n"); # # return (""); # # } # end of sanity check # # # OLD, code, but does not require "use Socket" or pack # # ($a, $b, $c, $d) = split(/\./, "$ipa"); # # return (($a << 24) + ($b << 16) + ($c << 8) + $d); # #} # end of sub jp_aton #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++