Link to home
Start Free TrialLog in
Avatar of richsark
richsarkFlag for United States of America

asked on

parse through a dhcp.netsh file

Hi Guys,

I have a microsoft netsh dump. This file named. 1.2.3.4.netsh has invalid MAC addresses defined. meaning not enough digits. I have high lighted them.

Dhcp Server 10.104.164.112 Scope 10.104.164.0 Add reservedip 10.104.165.152 0002a56b94ce "stvfntest.bhmstv.help.corp" "" ""
Dhcp Server 10.104.164.112 Scope 10.104.164.0 Add reservedip 10.104.165.153 0a0a0a0a000a "aixtest1" "" ""
Dhcp Server 10.104.164.112 Scope 10.104.164.0 Add reservedip 10.104.165.154 0a0a0a0a000b "aixtest2" "" ""
Dhcp Server 10.104.164.112 Scope 10.104.164.0 Add reservedip 10.104.165.155 000c2903fdfd "LinuxIMG" "" ""
Dhcp Server 10.104.164.112 Scope 10.104.164.0 Add reservedip 10.104.165.156 a000000001 "VS_MGMT_336" "" ""
Dhcp Server 10.104.164.112 Scope 10.104.164.0 Add reservedip 10.104.165.157 a000000002 "VS_MGMT_352" "" ""


Is there a quick perl script that I can feed a file to report on stuff like this on a separate report log showing what DHCP server and Scope it came from?

Thank you kindly

Avatar of FishMonger
FishMonger
Flag of United States of America image

There isn't any pre-made script that I'm aware of, but it would be very easy to write one that loops over the file splitting the line into fields and checks the length of the mac address field.

Have you tried writing it?  Do you have any code which you'd like someone to help you troubleshoot?

make_netsh_log.pl
------------------------
while (<>)
{
if (/Dhcp Server (\d+\.\d+\.\d+\.\d+) Scope (\d+\.\d+\.\d+\.\d+) Add reservedip (\d+\.\d+\.\d+\.\d+) ([a-f][0-9]*)/)
{
if (length($4)<12)
{
print "INVALID MAC $4\n";
}
}
}
Avatar of richsark

ASKER

Hello mankowitz:,

I ran the above perl,

But it showing:
$ perl make_netsh_log.pl merged.netsh

INVALID MAC a
INVALID MAC d0
INVALID MAC d0
INVALID MAC d0
INVALID MAC d0
INVALID MAC a
INVALID MAC a000000001
INVALID MAC a000000002
INVALID MAC a000000003
INVALID MAC a000000004
INVALID MAC a000000005
INVALID MAC a000000006

It also does not show the DHCP server and Scope it came from.

I appreciate your help !
Avatar of torvir
torvir

I think you should do the last match like this
([a-f0-9]*)
Otherwise it only matches a letter a-f followed by numbers. There will be a-f at random places in the real mac-addresses
so here is the revised match row:

if (/Dhcp Server (\d+\.\d+\.\d+\.\d+) Scope (\d+\.\d+\.\d+\.\d+) Add reservedip (\d+\.\d+\.\d+\.\d+) ([a-f0-9]*)/)

You could easy change the script to show whatever you want.

$1 is the DHCP server¨
$2 is the scope

change to
print "INVALID MAC $4 from DHCP server $1 scope $2\n";
Adjusting this to pass the file to the script would be trivial.
#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;

while ( <DATA> ){
    my ($dhcp_srv, $scope, $ip, $mac, $host) = (split(/\s/, $_))[2,4,7,8,9];
    if ( length($mac) != 12 ) {
        # output your log entry as needed
        print Dumper($dhcp_srv, $scope, $ip, $mac, $host), $/;
    }
}

__DATA__
Dhcp Server 10.104.164.112 Scope 10.104.164.0 Add reservedip 10.104.165.152 0002a56b94ce "stvfntest.bhmstv.help.corp" "" ""
Dhcp Server 10.104.164.112 Scope 10.104.164.0 Add reservedip 10.104.165.153 0a0a0a0a000a "aixtest1" "" ""
Dhcp Server 10.104.164.112 Scope 10.104.164.0 Add reservedip 10.104.165.154 0a0a0a0a000b "aixtest2" "" ""
Dhcp Server 10.104.164.112 Scope 10.104.164.0 Add reservedip 10.104.165.155 000c2903fdfd "LinuxIMG" "" ""
Dhcp Server 10.104.164.112 Scope 10.104.164.0 Add reservedip 10.104.165.156 a000000001 "VS_MGMT_336" "" ""
Dhcp Server 10.104.164.112 Scope 10.104.164.0 Add reservedip 10.104.165.157 a000000002 "VS_MGMT_352" "" ""

Open in new window

Hi FishMonger !

I created a file named make_netsh_log.pl

I then ran it  as

$ ./make_netsh_log.pl  merged.netsh

Name "main::DATA" used only once: possible typo at ./make_netsh_log.pl line 7.
readline() on unopened filehandle DATA at ./make_netsh_log.pl line 7.

What did I miss?

#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;

while ( <DATA> ){
    my ($dhcp_srv, $scope, $ip, $mac, $host) = (split(/\s/, $_))[2,4,7,8,9];
    if ( length($mac) != 12 ) {
        # output your log entry as needed
        print Dumper($dhcp_srv, $scope, $ip, $mac, $host), $/;
    }
}

Open in new window

ok, some modification:

while (<>)
{
if (/Dhcp Server (\d+\.\d+\.\d+\.\d+) Scope (\d+\.\d+\.\d+\.\d+) Add reservedip (\d+\.\d+\.\d+\.\d+) ([a-f0-9]*)/i)
{
if (length($4)<12)
{
print "INVALID MAC $4 DHCP $1 Scope $2 ReservedIP 3\n";

}

}

}
Added scope, server and reserved IP

while (<>)
{
   if (/Dhcp Server (\d+\.\d+\.\d+\.\d+) Scope (\d+\.\d+\.\d+\.\d+) Add reservedip (\d+\.\d+\.\d+\.\d+) ([a-f0-9]*)/i)
   {
   if (length($4)<12)
      {
         print "INVALID MAC $4 DHCP $1 Scope $2 ReservedIP 3\n";
      }
   }
}

Open in new window

Change:
while ( <DATA> ){


to:
while ( <> ){
For production scripts I'd actually open a filehandle and add error handling, but these posts are just to jet you started.
Hi Mankowitz,

I ran above, looks good so far :)

$ perl make2.pl merged.netsh

INVALID MAC 01 DHCP 10.104.132.110 Scope 10.104.140.0 ReservedIP 3
INVALID MAC 01 DHCP 10.104.164.112 Scope 10.104.164.0 ReservedIP 3

So maybe a report like
INVALID MAC "01" for host "Moxa119" DHCP 10.104.164.112 Scope 10.104.164.0 ReservedIP 3


Can we also get the hostname in there?
Dhcp Server 10.104.132.110 Scope 10.104.140.0 Add reservedip 10.104.143.180 01 "Moxa119" "" ""

#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;

unless ( @ARGV ) { die "useage: $0 <filename>\n"; }

open my $fh, '<', $ARGV[0] or die "failed to open '$ARGV[0] $!";

while ( my $line = <$fh> ){
    my ($dhcp_srv, $scope, $ip, $mac, $host) = (split(/\s/, $line))[2,4,7,8,9];
    
    if ( length($mac) != 12 ) {
        print "INVALID MAC:$mac for host:$host DHCP:$dhcp_srv Scope:$scope Reserved IP:$ip\n";
    }
}

Open in new window

Hi Fishmonger,

I ran your revised code: got this

$ ./fish.pl merged.netsh
Use of uninitialized value $mac in length at ./fish.pl line 14, <$fh> line 1.
Use of uninitialized value $mac in concatenation (.) or string at ./fish.pl line 15, <$fh> line 1.
Use of uninitialized value $host in concatenation (.) or string at ./fish.pl line 15, <$fh> line 1.
Use of uninitialized value $dhcp_srv in concatenation (.) or string at ./fish.pl line 15, <$fh> line 1.
Use of uninitialized value $scope in concatenation (.) or string at ./fish.pl line 15, <$fh> line 1.
Use of uninitialized value $ip in concatenation (.) or string at ./fish.pl line 15, <$fh> line 1.
INVALID MAC: for host: DHCP: Scope: Reserved IP:
Use of uninitialized value $mac in length at ./fish.pl line 14, <$fh> line 2.
Use of uninitialized value $mac in concatenation (.) or string at ./fish.pl line 15, <$fh> line 2.
Use of uninitialized value $host in concatenation (.) or string at ./fish.pl line 15, <$fh> line 2.
Use of uninitialized value $dhcp_srv in concatenation (.) or string at ./fish.pl line 15, <$fh> line 2.
Use of uninitialized value $scope in concatenation (.) or string at ./fish.pl line 15, <$fh> line 2.
Use of uninitialized value $ip in concatenation (.) or string at ./fish.pl line 15, <$fh> line 2.
INVALID MAC: for host: DHCP: Scope: Reserved IP:
Use of uninitialized value $mac in length at ./fish.pl line 14, <$fh> line 3.
while (<>)
{
   if (/Dhcp Server (\d+\.\d+\.\d+\.\d+) Scope (\d+\.\d+\.\d+\.\d+) Add reservedip (\d+\.\d+\.\d+\.\d+) ([a-f0-9]*)\s"[^"]*"/i)
   {
   if (length($4)<12)
      {
         print "INVALID MAC \"$4\" for host \"$5\" DHCP $1 Scope $2 ReservedIP $3\n";
      }
   }
}

Open in new window

Your merged.netsh file is not formatted like the sample data you posted.

Here's the output I get using the data and format that you posted.

E:\TEMP\test>perl-1.pl merged.netsh
INVALID MAC:a000000001 for host:"VS_MGMT_336" DHCP:10.104.164.112 Scope:10.104.164.0 Reserved IP:10.104.165.156
INVALID MAC:a000000002 for host:"VS_MGMT_352" DHCP:10.104.164.112 Scope:10.104.164.0 Reserved IP:10.104.165.157
Hi Fishmonger,

Odd?? I have attached the full file merged.netsh.txt
Hello mankowitz: I ran your code as


$ perl make2.pl merged.netsh.txt
INVALID MAC "01" for host "" DHCP 10.104.132.110 Scope 10.104.140.0 ReservedIP 10.104.143.180
INVALID MAC "01" for host "" DHCP 10.104.164.112 Scope 10.104.164.0 ReservedIP 10.104.164.91
INVALID MAC "a000000001" for host "" DHCP 10.104.164.112 Scope 10.104.164.0 ReservedIP 10.104.165.156
INVALID MAC "a000000002" for host "" DHCP 10.104.164.112 Scope 10.104.164.0 ReservedIP 10.104.165.157
INVALID MAC "a000000003" for host "" DHCP 10.104.164.112 Scope 10.104.164.0 ReservedIP 10.104.165.158
INVALID MAC "a000000004" for host "" DHCP 10.104.164.112 Scope 10.104.164.0 ReservedIP 10.104.165.159
INVALID MAC "a000000005" for host "" DHCP 10.104.164.112 Scope 10.104.164.0 ReservedIP 10.104.165.160
INVALID MAC "a000000006" for host "" DHCP 10.104.164.112 Scope 10.104.164.0 ReservedIP 10.104.165.161

For the host its only ""?
while (<>)
{
   if (/Dhcp Server (\d+\.\d+\.\d+\.\d+) Scope (\d+\.\d+\.\d+\.\d+) Add reservedip (\d+\.\d+\.\d+\.\d+) ([a-f0-9]*)\s"[^"]*"/i)
   {
   if (length($4)<12)
      {
         print "INVALID MAC \"$4\" for host \"$5\" DHCP $1 Scope $2 ReservedIP $3\n";
      }
   }
}

Open in new window

As I stated, your file is not formatted the same, meaning you have blank lines and comments and other lines with similar, but not the exact same format as the ones you previously posted.

You could either use the regex that others have shown or you could add additional checks to the split approach.  I don't have time right now to make the adjustments to the script, but since you've posted over 40 other Perl questions here as well as on other forums that I follow, I think you should now have enough Perl knowledge to make some adjustments on your own.
while (<>)
{
   if (/Dhcp Server (\d+\.\d+\.\d+\.\d+) Scope (\d+\.\d+\.\d+\.\d+) Add reservedip (\d+\.\d+\.\d+\.\d+) ([a-f0-9]*)\s"([^"]*)"/i)
   {
   if (length($4)<12)
      {
         print "INVALID MAC \"$4\" for host \"$5\" DHCP $1 Scope $2 ReservedIP $3\n";
      }
   }
}

Open in new window

Thanks mankowitz, It worked !

Would it be hard to report a line saying " No Issues Found" if the file is ok?

Again Much appericated
SOLUTION
Avatar of mankowitz
mankowitz
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Or, slightly more concisely:
...
}
print "No Issues Found.\n" unless $issues;
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks to all Fishmonger and to Mankowitz