Link to home
Start Free TrialLog in
Avatar of rangers80
rangers80Flag for Italy

asked on

DHCP server monitored by end to end transaction

I wrote a perl script deployed in a probe server (that has static ip address). That script send a dhcp  discovery message that is propely catched by dhcp server.
The discover request is logged in the dhcp server (file dhcpd.log)
"
Jan 17 11:28:38 esacom66 dhcpd: DHCPDISCOVER from 00:18:8b:f9:b2:a5 via bond0: network 131.176.129/24: no free leases
Jan 17 11:28:38 esacom66 dhcpd: DHCPDISCOVER from 00:18:8b:f9:b2:a5 via 10.16.12.251
Jan 17 11:28:39 esacom66 dhcpd: DHCPOFFER on 10.16.12.241 to 00:18:8b:f9:b2:a5 via 10.16.12.251
"

The issue is that this dhcp message does not arrived to  probe server. I have tried to put the interface in promisc mode by sw ethereal but without success. The dhcp message does not arrived to interface on probe server..
You consider tha I need only to trace the ip offered by dhcp server for my end 2 end transaction, it Must not change the ipaddress of probe server.
Avatar of edster9999
edster9999
Flag of Ireland image

Hmmm strange way of monitoring your network.  If your card got offered an IP that doesn't mean the next pc would.  
You might be taking the last address.

Wouldn't it be better to have the monitoring pc read the log file of the DHCPD server and look for that line.  if it sees errors like 'no free leases' it flags it to you.
Combine this with a basic check to see the DHCP service is running and responding on the right port and you have a pretty good check.

Avatar of rangers80

ASKER

Escuse me but this is another matter. The dhcp server is already monitored as you have suggested

I need to make also a end 2 end transacation. I must simulate the following steps by probe server:
- dhcp discovery from probe server (that is ok)
- dhcp server offers an ip address (that is ok)
- the dhcp probe doesn't receive the dhcp offer message (that is NOT OK)

Avatar of arnold
It seems the issue is that while you are generating the DHCP request, you are not catching the DHCP offer or another packet.

Are you using this module in perl or are you using Socket to create the packet?

http://search.cpan.org/~shadinger/Net-DHCP-0.65/lib/Net/DHCP/Packet.pm

Make sure to send a DHCPNOAK or DHCPDECLINE to avoid tying up DHCP IPs unnecessarily.

Presumably the test is to see that the DHCP is responsive.
This is the perl code:
I'm using a perl module:

The issue is before the  dhcp request:

The discover request is logged in the dhcp server (file dhcpd.log)
"
Jan 17 11:28:38 esacom66 dhcpd: DHCPDISCOVER from 00:18:8b:f9:b2:a5 via bond0: network 131.176.129/24: no free leases
Jan 17 11:28:38 esacom66 dhcpd: DHCPDISCOVER from 00:18:8b:f9:b2:a5 via 10.16.12.251
Jan 17 11:28:39 esacom66 dhcpd: DHCPOFFER on 10.16.12.241 to 00:18:8b:f9:b2:a5 via 10.16.12.251
"
As you can see the dhcp serve offers the following ip 10.16.12.241 to my probe server (that has 0:18:8b:f9:b2:a5  as mac address). The issue is that this dhcp message does not arrived to  probe server. I have tried to put the interface in promisc mode by sw ethereal but without success. The dhcp message does not arrived to interface on probe server..
You consider tha I need only to trace the ip offered by dhcp server for my end 2 end transaction, it Must not change the ipaddress of probe server.

This is the perl code:

#!/usr/bin/perl
# Simple DHCP client - sending a broadcasted DHCP Discover request

use IO::Socket::INET;
use Net::DHCP::Packet;
use Net::DHCP::Constants;

use POSIX qw(setsid strftime);

# sample logger
sub logger{
    my $str = shift;
    print STDOUT strftime "[%d/%b/%Y:%H:%M:%S] ", localtime;
    print STDOUT "$str\n";
}

logger("DHCPd tester - dummy client");

logger("Opening socket");
$handle = IO::Socket::INET->new(Proto => 'udp',
                                Broadcast => 1,
                                PeerPort => '67',
                                LocalPort => '68',
                                PeerAddr => '255.255.255.255',
                        )
      || die "Socket creation error: $@\n";     # yes, it uses $@ here


# create DHCP Packet DISCOVER
$discover = Net::DHCP::Packet->new(
                      Chaddr => '00188BF9B2A5',
                      Xid => 0x12345678,
                      DHO_DHCP_MESSAGE_TYPE() => DHCPDISCOVER(),
                      DHO_VENDOR_CLASS_IDENTIFIER() => 'foo',
                      );
logger("Sending DISCOVER to 127.0.0.1:67");
logger($discover->toString());
$handle->send($discover->serialize())
              or die "Error sending:$!\n";

logger("Waiting for response from server");
$handle->recv($buf, 4096) || die("recv:$!");
logger("Got response");
$response = new Net::DHCP::Packet($buf);
logger($response->toString());

# create DHCP Packet REQUEST
$request = Net::DHCP::Packet->new(
                      Xid => 0x12345678,
                      Ciaddr => $response->yiaddr(),
                      DHO_DHCP_MESSAGE_TYPE() => DHCPREQUEST(),
                      DHO_VENDOR_CLASS_IDENTIFIER() => 'foo',
                      DHO_DHCP_REQUESTED_ADDRESS() => $response->yiaddr(),
                      );

logger("Sending REQUEST to 127.0.0.1:67");
logger($request->toString());

$handle->send($request->serialize())
              or die "Error sending:$!\n";
logger("Waiting for response from server");
$handle->recv($buf, 4096) || die("recv:$!");
logger("Got response");
$response = new Net::DHCP::Packet($buf);
logger($response->toString());

DHCP can not cross router boundaries.  It seems that the packet finds itsway but your system might not know how to get back.

131.176.129/24: seems to be the IP of your DHCP server and it is allocating an IP of 10.x.x.x which means either you have a bad DHCP relay agent or the path your request takes is incorrect.

Are you probing the DHCP server from an external location?
My dhcp server has 131.176.129.1 as IP address.
I understand that
"
It seems that the packet finds itsway but your system might not know how to get back.
"
but I need your help for this. I don't understand WHY the DHCP packet arrives to destination!
How can I check?

for your question
"
Are you probing the DHCP server from an external location?
"
the answer is now.

Thanks for your availability
The packet is addressed to a system based on the MAC address from which the request is sent.  Those packets will not cross router/vlan boundaries.
i.e. if you broadcast


You do not have a Listener socket.

The only socket you've defined is the PeerAddress (sender)
Not sure why you are defining the localPort as 68,but You need to define a listener socket with port 68 (or matching port from PeerAddress) on which it will listen for the responses.


If you use screen, and tcpdump src host 131.176.129.1 does it see the responses without the above modifications?
The packets will cross the router/vlan boundaries, in fact the dhcp disovery message arrives to dhcp server. (in the dhpcd.log I see the request from client) :
The discover request is logged in the dhcp server (file dhcpd.log)
"
Jan 17 11:28:38 esacom66 dhcpd: DHCPDISCOVER from 00:18:8b:f9:b2:a5 via bond0: network 131.176.129/24: no free leases
Jan 17 11:28:38 esacom66 dhcpd: DHCPDISCOVER from 00:18:8b:f9:b2:a5 via 10.16.12.251
Jan 17 11:28:39 esacom66 dhcpd: DHCPOFFER on 10.16.12.241 to 00:18:8b:f9:b2:a5 via 10.16.12.251
"
The problem is that dhcpoffer message doesn't arrive to  client. I have installed ethereal sw for capture the packet and there is no packet from dhcp server.

Do you have the capacity to probe the various locations to see whether the packet gets stuck?

I.e. if a DHCP and the system you probing are on the same unmanaged switch. Does your probe receive the response?
What how are you trying to capture the packets.
I tested your script. I see responses from DHCP using port 67 as the source from the DHCP server, but your script  does not acknowledge receipt of response.

use screen in one screen run tcpdump and in the other screen run your dhcp client test.
tcpdump -n -i eth0 src port 67
You are missing the docoding of the packet.  your script seems similar to the one at http://www.perlmonks.org/?node_id=716547

The packets from the multiple DHCP servers are received with the IPs they offer.
You either not configured wireshark to display the packets correctly or something else is preventing their arrival, but your script will not display any information as it currently does not work to handle a response.
Hi arnalod,
first of all thanks for your availability.

This part of perl code is dedicated to capture the answer from DHCP server

"
logger("Waiting for response from server");
$handle->recv($buf, 4096) || die("recv:$!");
logger("Got response");
$response = new Net::DHCP::Packet($buf);
logger($response->toString());
"
I also doubt that it does not work..but I don't know how can I capture the answer.
However the problem persists.
I'm using the ethereal sw to put the interface in promiscuous mode, so I can see all the packets that arrive to the interface.but I don't see udp packet from dhcp server (you cann see the file attached)

I cannot use
tcpdump -n -i eth0 src port 67
because my probe is server ha W2003 as operating system





connections.jpg
i remember that th probe server has as ip address:
10.16.12.97

the dhcp servers have as ip address:
131.176.129.1
131.176.131.1

By the attached file yon can see the dhcp messages captured by ethereal sw(Ii presume that iit is similar to tcpdump):
10.16.12.97 -> 255.255.255.255.
10.16.12.251-> 10.16.12.8
10.16.12.251 -> 10.16.12.241

I suppose that these ip address: 10.16.12.8, 10.16.12.241 are dhcp relay. Is it right?
What do you suggest to check? I can contact the network team.

It's very important forme resolve the issue as soon as possble

Regards

 
I understand that you have the handle that is supposed to receive the response and process.  What I am saying that neither your example nor the code sample that is part of the Perl Module works i.e. it does not display the response even though one is sent.
And as your image points out received.
No,the IPs 10.16.12.8 and 10.16.12.241 are IPs of/on your probe system.
The DHCP relay agent is 10.16.12.251.

The problem is that you are sorting based on IP which makes reading the info some what more complicated.
A time based flow with a filter to only display DHCP type packets would make it easier to read. bootp || (udp.port == 67|| udp.port == 68)  

You should upgrade to wireshark (wireshark.net) which is a replacement in name only because ethereal was a registered name or something like that.


I think the network interface intercepts the packet and that may explain why it does not find its way to your probe.

tried to tweak it quickly to see whether I could get a response, but did not.
Attached to the process (strace), but all it is doing is waiting for the response packet but never gets it.

Ok undestand that
IPs 10.16.12.8 and 10.16.12.241 are IPs of/on your probe system.

Then I need to capture and logged this information.
By peerl it seems not possible. Do you know other methods?

Thanks again
I've looked at other modules on this, but not sure whether there is.one.
There is a Net::DHCPClient module but it does not include an example on usage that would satisfy what you are trying to do.

How are you with C/C++

http://stackoverflow.com/questions/1791616/implementing-dhcp-client
Not working example but has a reference to look at a working dhcpclient to learn the flow.

Alternatively you could use the check mechanism used in Nagios
http://exchange.nagios.org/directory/Plugins/Network-Protocols/DHCP-and-BOOTP/Perl-check-dhcp/details
Modules you would need IO::Interface and Net::DHCP::Watch

You might want to consider using nagios directly it can generate alerts. Aswell as monitor without .....
http://exchange.nagios.org/directory/Plugins/Network-Protocols/DHCP-and-BOOTP/Perl-check-dhcp/details
The pourpose of this script is different: with this script it is necessary that the probe server has as ip address one provided by dhcp server.
In my case the probe server has a ipf fix address not provided by dhcp server
In fact In the dhcpd.log I found :
"Jan 25 18:48:48 esacom66 dhcpd: DHCPREQUEST for 10.16.12.97 from 00:18:8b:f9:b2:a5 via bond0: unknown lease 10.16.12.97".
However also in this case the script go to loop. It doesn't intercept the dhcp watch reply.

It's strange...there is something that escapes me....
For me it's important use a perl or vbs script. Only if it's impossible I can use other language.

I understand what you are trying to do, I am not clear why a response is not seen/detected by the script.
http://www.nber.org/sys-admin/
http://www.nber.org/sys-admin/rogue-dhcp.txt
This one works. (remove the </xmp> from the end of the file.
I tried but the result is the same. The script goes in timeout :-(
Which script did you run that timed out?
To make the script you have there is a need to modify the Packet to modify how it acts with the initial Discover packet not to have the PeerAddress included in the packet.
The issue I think deals with the recv is waiting for a response from the PeerAddress (255.255.255.255) that never arrives.

The script above have to run

Worked for me.
Which timeout error is displayed?
Use -t 10 and see if that fixes things.  You are going through a relay agent and that may exceed the 3 second default timeout used in the script.
The script goes in timeout as you can see

"C:\Custom_Scripts\dhcp>dhcp_rogue.pl -t 10 -d
The system cannot find the path specified.
About to start socket
About to send DHCPDISCOVER packet
Waiting for UDP messages..."
I think that the problem is the same!!
Why do you get this error: "The system cannot find the path specified."
can you run perl -c dhcp_rogue.pl
C:\Custom_Scripts\dhcp>perl -c dhcp_rogue.pl
dhcp_rogue.pl syntax OK
What can i check to resolve the issue.

Tks again
try
perl dhcp_rogue.pl
C:\Perl\bin>perl.exe C:\Custom_Scripts\dhcp\dhcp_rogue.pl -d
The system cannot find the path specified.
About to start socket
About to send DHCPDISCOVER packet
Waiting for UDP messages

I don't kony WHY the followed message is showed:
"The system cannot find the path specified."
Any idea?? Sorry for disturbe
Perhaps the script is optimized for a probe server that has unix as operating system
In fact I have tried the reason..look these lines of perl code:
"
my $ifconfig = `/sbin/ifconfig -a`; # this works on FreeBSD and FC Linux
# we guess that the first ethernet address is the one we want to use
# ether is FreeBSD, HWaddr is Linux
$ifconfig =~ m/\s+(ether|HWaddr) (\S+)/ or die "Could not determine my ethernet MAC address";
my $ether = $2;
"
I have replaced with this line code:
"my $ether ='00:18:8b:f9:b2:a5';
"

but the scripts go in timeout, the reason is the same:
"
C:\Custom_Scripts\dhcp>dhcp_rogue.pl -d -t 10
About to start socket
About to send DHCPDISCOVER packet
Waiting for UDP messages

"

"
possibly, use wireshark/etherreal and see if this perl code actually generating DHCP packets. and whether responses are seen.

I'm trying to modify the prior one to work in a similar fashion to this one. But will take some time.
I have tried and I have the same result...By ethereal I see the same dhcp packet  that we had with the first script

Also I I'm trying to modify the first scipt...but It seems very difficult..

However Thanls for your effort.
ASKER CERTIFIED SOLUTION
Avatar of arnold
arnold
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
"
C:\Documents and Settings\Administrator>netsh dhcp show server
The DHCP service could not contact Active Directory.
"

I tried the test suggested by you. I have changed the peeraddress 255.255.255.255 with the relay agent IP 10.16.12.251. The issue persists unfortunately

I

I'm not familiar with perl/socket interaction in windows
IS the system you are on (running the above test)  a member of the AD?
Also I I'm not familiar with perl/socket interaction in windows, but sure the probelm is that we cannot try to caputre the dhcp response packet. It seems easy but...

However the answer of your question is: Yes the probe server is a member of AD.

netsh dhcp show server
should reflect AD authorized servers. Is the DHCP server you are running not auhtorized or is not on a windows box/using windows DHCP but something else??
I don't understand what do you say me..

The probe server has ip fixed address with W2003 as operating system.

I need to test the DHCP servers that are in the same network and that are used to assign a valid ip address for onlly laptop that requires a network connection.
The netsh dhcp show server
should report back AD authorized servers.
dhcploc.exe from support tools
dhcploc.exe 0.0.0.0
(hit d) to get the discovery process going, should report the DHCP servers on your network.
Do you have updates regarding the perl scrpt capturing the DHCP packets?


"
C:\Documents and Settings\Administrator>netsh dhcp show server
The DHCP service could not contact Active Directory.

C:\Documents and Settings\Administrator>dhcploc.exe 0.0.0.0

"no answer, go in timeout"

"
Have not resolved the socket/windows interaction and what is preventing perl to tie into it.

Did you hit the d?
This is strange, you should have at least gotten a response using a windows app that I works in windows..

What OS are you running on this system?
Do you have windows firewall that might be preventing the packets from passing?
What do you mean for : "Did you hit the d?"

What OS are you running on this system? W 2003 SE SP2

Do you have windows firewall that might be preventing the packets from passing?
No there are no fw, and then We see by ethereal the dhcp packets arrive to interface, the issue is that we try not to capure the packets. Is it right? In your opinion it can be a perl limit?

I need to resolve the issue as soon as possible, I need to give an answer to may conterpart, if this monitoring can be made or not..

Tks again for your avalability
Which perl are you running on your server? ActivePerl or some other source?
I've requested that this question be closed as follows:

Accepted answer: 0 points for rangers80's comment #a37476647

for the following reason:

I followed the expert