Linux, IO::Socket::INET and recv'ing broadcasted UDP

Discussion in 'Perl Misc' started by DJ Stunks, Feb 17, 2008.

  1. DJ Stunks

    DJ Stunks Guest

    Hey all, it's been a while since I hung out here but I still use Perl
    from time to time (and miss using it!).

    Anyway, I originally posted this question at comp.lang.perl.modules
    but I'm not getting any responses and I'm not sure it's a modules
    question anyway - maybe more a socket/Linux problem.

    Original post here (includes code):

    http://groups.google.com/group/comp.lang.perl.modules/msg/8ce530096fe7fdac?

    In summary, I'm attempting to use Net::DHCP::packet and
    IO::Socket::INET to generate, transmit and receive DHCP messages
    (discover, offer, request, ack). The problem is that I'm not able to
    use the IO::Socket recv method to receive a broadcasted DHCP offer
    packet. My script blocks indefinitely though I see the offer arrive
    via Wireshark.

    I'm following the example from the Net::DHCP::packet package and, in
    Googling, no one else mentions issues with this. Therefore I assume
    that the error is on my part - probably a simple error - but I don't
    know enough to diagnose it.

    As I mentioned, I'm using Linux with eth0 set up with a static IP
    (10.0.0.1). I was not able to set the interface to 0.0.0.0 as I'd
    assumed I should in order to perform DHCP transactions.

    I'm open to any and all suggestions, tips, etc.

    Thanks in advance,
    -jp
    DJ Stunks, Feb 17, 2008
    #1
    1. Advertising

  2. DJ Stunks

    Ben Morrow Guest

    Quoth DJ Stunks <>:
    > Hey all, it's been a while since I hung out here but I still use Perl
    > from time to time (and miss using it!).
    >
    > Anyway, I originally posted this question at comp.lang.perl.modules
    > but I'm not getting any responses and I'm not sure it's a modules
    > question anyway - maybe more a socket/Linux problem.
    >
    > Original post here (includes code):
    >
    > http://groups.google.com/group/comp.lang.perl.modules/msg/8ce530096fe7fdac?
    >
    > In summary, I'm attempting to use Net::DHCP::packet and
    > IO::Socket::INET to generate, transmit and receive DHCP messages
    > (discover, offer, request, ack). The problem is that I'm not able to
    > use the IO::Socket recv method to receive a broadcasted DHCP offer
    > packet. My script blocks indefinitely though I see the offer arrive
    > via Wireshark.


    In that message, you wrote:
    |
    | #open socket for packet tx & rx
    | my $socket = IO::Socket::INET->new( Proto => 'udp',
    | Broadcast => 1,
    | LocalAddr => '10.0.0.1',
    | LocalPort => 68,
    | PeerAddr => '255.255.255.255',
    | PeerPort => 67,
    | ) || die "Unable to create socket: $@\n";
    |
    | my $discover = Net::DHCP::packet->new(
    | Xid => int rand(0xFFFFFFFF),
    | Chaddr => 00011aabbccd,
    | DHO_DHCP_MESSAGE_TYPE() => DHCPDISCOVER(),
    | DHO_VENDOR_CLASS_IDENTIFIER() => 'MyVendorClassID',
    | DHO_DHCP_PARAMETER_REQUEST_LIST() => '1 2 6 12 15 28 67',
    | );

    RFC 2131 says "If the broadcast bit is not set and 'giaddr' is zero and
    'ciaddr' is zero, then the server unicasts DHCPOFFER and DHCPACK
    messages to the client's hardware address and 'yiaddr' address.". That
    applies here, so the packet will not be broadcast, it will be sent as a
    unicast Ethernet frame to your claimed hardware address
    (00:01:1a:ab:bc:cd) with an IP packet addressed to your claimed IP addr
    (0.0.0.0, since you didn't set yiaddr) inside.

    Even if this packet gets to you (are you using your real hardware
    address?) you can't read such a packet from an IP socket under Linux.
    You need to put the interface in promiscuous mode (which requires root)
    and use a PF_PACKET socket with an appropriate filter to get hold of the
    packet. See e.g. setup_packet_filters, open_socket and get_packet in
    http://git.marples.name/?p=dhcpcd/.git;a=blob;f=socket.c (make sure you
    read the #ifdef __linux__ version).

    Alternatively, you could try setting Flags => 1, which asks for the
    reply to be broadcast (for the sake of clients whose IP stacks can't
    cope with confusingly-addressed packets), in which case an ordinary UDP
    socket should be able to pick it up.

    Ben
    Ben Morrow, Feb 18, 2008
    #2
    1. Advertising

  3. DJ Stunks

    DJ Stunks Guest

    On Feb 17, 9:10 pm, Ben Morrow <> wrote:
    > Quoth DJ Stunks <>:
    >
    >
    >
    > > Hey all, it's been a while since I hung out here but I still use Perl
    > > from time to time (and miss using it!).

    >
    > > Anyway, I originally posted this question at comp.lang.perl.modules
    > > but I'm not getting any responses and I'm not sure it's a modules
    > > question anyway - maybe more a socket/Linux problem.

    >
    > > Original post here (includes code):

    >
    > >http://groups.google.com/group/comp.lang.perl.modules/msg/8ce530096fe...

    >
    > > In summary, I'm attempting to use Net::DHCP::packet and
    > > IO::Socket::INET to generate, transmit and receive DHCP messages
    > > (discover, offer, request, ack). The problem is that I'm not able to
    > > use the IO::Socket recv method to receive a broadcasted DHCP offer
    > > packet. My script blocks indefinitely though I see the offer arrive
    > > via Wireshark.

    >
    > In that message, you wrote:
    > |
    > | #open socket for packet tx & rx
    > | my $socket = IO::Socket::INET->new( Proto => 'udp',
    > | Broadcast => 1,
    > | LocalAddr => '10.0.0.1',
    > | LocalPort => 68,
    > | PeerAddr => '255.255.255.255',
    > | PeerPort => 67,
    > | ) || die "Unable to create socket: $@\n";
    > |
    > | my $discover = Net::DHCP::packet->new(
    > | Xid => int rand(0xFFFFFFFF),
    > | Chaddr => 00011aabbccd,
    > | DHO_DHCP_MESSAGE_TYPE() => DHCPDISCOVER(),
    > | DHO_VENDOR_CLASS_IDENTIFIER() => 'MyVendorClassID',
    > | DHO_DHCP_PARAMETER_REQUEST_LIST() => '1 2 6 12 15 28 67',
    > | );
    >
    > RFC 2131 says "If the broadcast bit is not set and 'giaddr' is zero and
    > 'ciaddr' is zero, then the server unicasts DHCPOFFER and DHCPACK
    > messages to the client's hardware address and 'yiaddr' address.". That
    > applies here, so the packet will not be broadcast, it will be sent as a
    > unicast Ethernet frame to your claimed hardware address
    > (00:01:1a:ab:bc:cd) with an IP packet addressed to your claimed IP addr
    > (0.0.0.0, since you didn't set yiaddr) inside.
    >
    > Even if this packet gets to you (are you using your real hardware
    > address?) you can't read such a packet from an IP socket under Linux.
    > You need to put the interface in promiscuous mode (which requires root)
    > and use a PF_PACKET socket with an appropriate filter to get hold of the
    > packet. See e.g. setup_packet_filters, open_socket and get_packet inhttp://git.marples.name/?p=dhcpcd/.git;a=blob;f=socket.c(make sure you
    > read the #ifdef __linux__ version).
    >
    > Alternatively, you could try setting Flags => 1, which asks for the
    > reply to be broadcast (for the sake of clients whose IP stacks can't
    > cope with confusingly-addressed packets), in which case an ordinary UDP
    > socket should be able to pick it up.


    Hi Ben,

    Thanks for the reply.

    The DHCP Offer I'm receiving is definitely addressed to destination IP
    255.255.255.255:68 (perhaps my DHCP server is non-compliant?). I did
    try setting Flags => 1 as one of my tests and it didn't make a
    difference but I'll repeat it to be sure.

    The Linux stuff is interesting. I'm not using my true hardware
    address because the goal of the test is to check the DHCP behavior for
    various hardware classes. Perhaps that's the problem. I'll go over
    what you suggested and give it a try in the morning.

    I wasn't able to set eth0 to 0.0.0.0 using ifconfig but you're right,
    yiaddr is 0.0.0.0 within the discover payload.

    -jp
    DJ Stunks, Feb 18, 2008
    #3
  4. DJ Stunks

    DJ Stunks Guest

    On Feb 17, 8:24 am, DJ Stunks <> wrote:
    > Hey all, it's been a while since I hung out here but I still use Perl
    > from time to time (and miss using it!).
    >
    > Anyway, I originally posted this question at comp.lang.perl.modules
    > but I'm not getting any responses and I'm not sure it's a modules
    > question anyway - maybe more a socket/Linux problem.
    >
    > Original post here (includes code):
    >
    > http://groups.google.com/group/comp.lang.perl.modules/msg/8ce530096fe...
    >
    > In summary, I'm attempting to use Net::DHCP::packet and
    > IO::Socket::INET to generate, transmit and receive DHCP messages
    > (discover, offer, request, ack). The problem is that I'm not able to
    > use the IO::Socket recv method to receive a broadcasted DHCP offer
    > packet. My script blocks indefinitely though I see the offer arrive
    > via Wireshark.
    >
    > I'm following the example from the Net::DHCP::packet package and, in
    > Googling, no one else mentions issues with this. Therefore I assume
    > that the error is on my part - probably a simple error - but I don't
    > know enough to diagnose it.
    >
    > As I mentioned, I'm using Linux with eth0 set up with a static IP
    > (10.0.0.1). I was not able to set the interface to 0.0.0.0 as I'd
    > assumed I should in order to perform DHCP transactions.
    >
    > I'm open to any and all suggestions, tips, etc.


    Well, after Ben mentioned promiscuous mode I did some more Googling
    and it turns out Abigail had problems with the same issue in 2004
    (http://www.perlmonks.org/index.pl?node_id=325248).

    So I feel a lot better if it can happen to him too ;-)

    Abigail was on RH; I'm on Fedora. So now to figure out what was
    blocked and how to unblock it. iptables? I'll check tomorrow but I
    thought I tried with the thing wide open at least once...

    -jp
    DJ Stunks, Feb 18, 2008
    #4
  5. DJ Stunks

    DJ Stunks Guest

    On Feb 17, 10:16 pm, DJ Stunks <> wrote:
    > On Feb 17, 8:24 am, DJ Stunks <> wrote:
    > > In summary, I'm attempting to use Net::DHCP::packet and
    > > IO::Socket::INET to generate, transmit and receive DHCP messages
    > > (discover, offer, request, ack). The problem is that I'm not able to
    > > use the IO::Socket recv method to receive a broadcasted DHCP offer
    > > packet. My script blocks indefinitely though I see the offer arrive
    > > via Wireshark.



    > Well, after Ben mentioned promiscuous mode I did some more Googling
    > and it turns out Abigail had problems with the same issue in 2004
    > (http://www.perlmonks.org/index.pl?node_id=325248).
    >
    > So I feel a lot better if it can happen to him too ;-)
    >
    > Abigail was on RH; I'm on Fedora. So now to figure out what was
    > blocked and how to unblock it. iptables? I'll check tomorrow but I
    > thought I tried with the thing wide open at least once...


    Still no luck. Have tried with Flags => 1 in the IO::Socket::INET
    constructor. The DHCPOFFER is broadcasted regardless (Ethernet
    destination MAC = ff:ff:ff:ff:ff:ff; destination IP = 255.255.255.255;
    destination udp port = 68) but my socket never receives it.

    Have run with iptables completely flushed. Tried running the same
    script on FreeBSD with the same results.

    Does Abigail still hang out here? It sounds like he had an identical
    issue...

    Last thing to do: trying to set interface as promiscuous. Can I do it
    from Perl? I tried ifconfig eth0 promisc before running the script,
    but identical results.

    Thanks,
    -jp
    DJ Stunks, Feb 18, 2008
    #5
  6. DJ Stunks

    Ben Morrow Guest

    Quoth DJ Stunks <>:
    >
    > Still no luck. Have tried with Flags => 1 in the IO::Socket::INET
    > constructor.


    The Flags => 1 was in the Net::DHCP::packet constructor.

    > The DHCPOFFER is broadcasted regardless (Ethernet
    > destination MAC = ff:ff:ff:ff:ff:ff; destination IP = 255.255.255.255;
    > destination udp port = 68) but my socket never receives it.


    That's... odd. Can you recieve other broadcast datagrams?

    Have you tried using a PF_PACKET socket?

    Ben
    Ben Morrow, Feb 18, 2008
    #6
  7. DJ Stunks

    DJ Stunks Guest

    On Feb 18, 4:42 pm, Ben Morrow <> wrote:
    > Quoth DJ Stunks <>:
    >
    >
    >
    > > Still no luck. Have tried with Flags => 1 in the IO::Socket::INET
    > > constructor.

    >
    > The Flags => 1 was in the Net::DHCP::packet constructor.


    Right, my bad. I think I tried that too, but I'll repeat to be sure.

    > > The DHCPOFFER is broadcasted regardless (Ethernet
    > > destination MAC = ff:ff:ff:ff:ff:ff; destination IP = 255.255.255.255;
    > > destination udp port = 68) but my socket never receives it.

    >
    > That's... odd. Can you recieve other broadcast datagrams?
    >
    > Have you tried using a PF_PACKET socket?


    I thought it was odd too, but I'm continuing to research (so
    frustrated! ;-)) and I think what I'm finding is that it's not that
    odd...

    Here's a post from Solaris' bug tracker: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4191980.
    The originator had a similar problem, but with Java. The response
    was:

    "The Solaris (& Linux for that matter) behavior is
    that to be able to receive broadcasts a UDP socket has to be bound to
    the
    wildcard address (aka anylocal). This has been the defacto standard
    behavior
    since the days of BSD 4.3. Win32 behaviors differs from that. So the
    only way
    to be guaranteed to receive the broadcasts on any platform is to bind
    to
    the wildcard address."

    So I tried changing my IO::Socket::INET constructor to use INADDR_ANY,
    but no luck. The constructor seems to ignore PeerAddr => '0.0.0.0';

    This page (http://wiki.forum.nokia.com/index.php/
    How_to_use_udp_broadcast) shows how to set up a Python socket for UDP
    broadcast.

    So now my question is, how do I set up a Perl socket similarly? Can I
    still use IO::Socket::INET to set PF_INET (is that the same as
    PF_PACKET?) or do I have to use Socket instead?

    As I'm sure everyone can tell, I'm out of my depth, but learning...
    slowly.

    Thanks Ben,
    -jp
    DJ Stunks, Feb 19, 2008
    #7
  8. DJ Stunks

    Ben Morrow Guest

    Quoth DJ Stunks <>:
    > On Feb 18, 4:42 pm, Ben Morrow <> wrote:
    > > Quoth DJ Stunks <>:
    > >
    > > > The DHCPOFFER is broadcasted regardless (Ethernet
    > > > destination MAC = ff:ff:ff:ff:ff:ff; destination IP = 255.255.255.255;
    > > > destination udp port = 68) but my socket never receives it.

    > >
    > > That's... odd. Can you recieve other broadcast datagrams?
    > >
    > > Have you tried using a PF_PACKET socket?

    >
    > I thought it was odd too, but I'm continuing to research (so
    > frustrated! ;-)) and I think what I'm finding is that it's not that
    > odd...
    >
    > Here's a post from Solaris' bug tracker:
    > http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4191980.
    > The originator had a similar problem, but with Java. The response
    > was:
    >
    > "The Solaris (& Linux for that matter) behavior is that to be able to
    > receive broadcasts a UDP socket has to be bound to the wildcard
    > address (aka anylocal). This has been the defacto standard behavior
    > since the days of BSD 4.3. Win32 behaviors differs from that. So the
    > only way to be guaranteed to receive the broadcasts on any platform is
    > to bind to the wildcard address."


    OK. I didn't know that, but it makes some sense.

    > So I tried changing my IO::Socket::INET constructor to use INADDR_ANY,
    > but no luck. The constructor seems to ignore PeerAddr => '0.0.0.0';


    No, you need LocalAddr => '0.0.0.0'. It's the address of *this* socket
    you're setting, not the address you're talking to. For UDP sockets,
    PeerAddr sets the default destination for sends.

    > This page (http://wiki.forum.nokia.com/index.php/
    > How_to_use_udp_broadcast) shows how to set up a Python socket for UDP
    > broadcast.


    Whoa... that page is about PyS60, otherwise known as 'Python for itty
    bitty Symbian phones with rather weird network stacks' :). However, the
    code they give is basically the same as on any other platform; here
    (FreeBSD) I can send and recieve broadcast datagrams with

    #!/usr/bin/perl -l

    use warnings;
    use strict;

    use IO::Socket::INET;

    use Data::Dump qw/dump/;

    my $port = 8091;

    if ($ARGV[0] eq 'recv') {
    my $SCK = IO::Socket::INET->new(
    Type => SOCK_DGRAM,
    Proto => 'udp',
    LocalAddr => '0.0.0.0',
    LocalPort => $port,
    Broadcast => 1,
    ) or die "socket: $@";

    $SCK->recv(my $buf, 512, 0)
    or die "recv: $@ $!";

    print dump $buf;
    }
    else {
    my $SCK = IO::Socket::INET->new(
    Type => SOCK_DGRAM,
    Proto => 'udp',
    PeerAddr => $ARGV[1],
    PeerPort => $port,
    Broadcast => 1,
    ) or die "socket: $!";

    my $buf = 'Hello world!';
    $SCK->send($buf)
    or die "send: $!";
    }

    __END__

    though I find I have to send to 192.168.1.255 (the local net broadcast
    addr) rather than 255.255.255.255, which ought to be the same. I don't
    know why that is.

    > So now my question is, how do I set up a Perl socket similarly? Can I
    > still use IO::Socket::INET to set PF_INET (is that the same as
    > PF_PACKET?) or do I have to use Socket instead?


    No, PF_PACKET isn't the same as PF_INET. PF_INET is the normal Internet
    protocol family: basically TCP or UDP over IP, though on most OSen you
    can use PF_INET/SOCK_RAW sockets to talk any IP protocol, including
    ICMP. In Perl you can use IO::Socket::INET to do anything your OS will
    let you do with PF_INET sockets.

    PF_PACKET is a Linux-specific protocol family for talking directly to
    the network driver; it allows you to send and receive raw Ethernet
    frames, for example. Perl has no IO::Socket support for PF_PACKET
    (though writing an IO::Socket::pACKET wouldn't be too hard: it's mostly
    just packing and unpacking the addresses, which is code you'd need to
    write to use these sockets anyway), so if you need these you would have
    to use the socket builtins (Socket wouldn't help, here, as that only has
    AF_INET/AF_UNIX support).

    Ben
    Ben Morrow, Feb 19, 2008
    #8
  9. DJ Stunks

    Guest

    All

    I know this is a pretty old thread, but looks like i hit the exact same problem this week while trying to use DHCP::packet.

    My requirement is that i want to use this perl module to get the IP's from DHCP server to do some PoC. I have two VM's , one act as DHCP server (RHEL564bit), and another RHEL5 64bit to run this script to get IP's from the DHCP server , both having two interfaces eth0 and eth1; eth1 of both the VM'sconnected to a VMware VSwitch to isolate these two VM's from others; eth0 of both the VM's having a valid IP in the range 10.72.x.x ; DHCP server listens on eth1 from the first VM.

    When i use a script like this one, i can see the DHCPDISCOVER is sent properly as it reaches the server and DHCPOFFER is also being made by the serveras per the logs ; but my script does not pick up the packet for some reasons which i am unable to understand.

    --script --

    #!/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,
    LocalAddr => '192.168.1.3',
    PeerAddr => '255.255.255.255')
    || die "Socket creation error: $@\n"; # yes, it uses $@ here

    # create DHCP Packet DISCOVER
    $discover = Net::DHCP::packet->new(
    Xid => 0x12345678,
    Flags => 1,
    Chaddr => '0050569821A9',
    DHO_DHCP_MESSAGE_TYPE() => DHCPDISCOVER(),
    DHO_VENDOR_CLASS_IDENTIFIER() => 'foo',
    );

    logger("Sending DISCOVER to 192.168.1.2:67");
    logger($discover->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());

    -- /var/log/messages of DHCP Server ---
    Jul 26 22:21:03 vmlnx64-30 dhcpd: DHCPDISCOVER from 00:50:56:98:21:a9 via eth1
    Jul 26 22:21:03 vmlnx64-30 dhcpd: DHCPOFFER on 192.168.1.49 to 00:50:56:98:21:a9 via eth1

    ** TCPDUMP of DHCP Server and Client when this is being run ***

    DHCPSERVER
    **********
    dhcp-Server>tcpdump -i eth1 -vvv
    tcpdump: listening on eth1, link-type EN10MB (Ethernet), capture size 96 bytes
    17:40:27.555097 IP (tos 0x0, ttl 1, id 0, offset 0, flags [none], proto: IGMP (2), length: 36, options ( RA (148) len
    4 )) 10.0.0.0 > all-systems.mcast.net: igmp query v3 [max resp time 1s]
    17:40:27.634538 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [DF], proto: IGMP (2), length: 40, options ( RA (148) len 4
    )) 192.168.1.2 > igmp.mcast.net: igmp v3 report, 1 group record(s) [gaddr 224.0.0.251 is_ex { }]
    17:40:33.120044 IP (tos 0x0, ttl 64, id 2290, offset 0, flags [DF], proto:UDP (17), length: 328) 192.168.1.3.bootpc >
    255.255.255.255.bootps: BOOTP/DHCP, Request from 00:50:56:98:23:8d (oui Unknown), length: 300, xid:0x12345678, flags: [none] (0x0000)
    Client Ethernet Address: 00:50:56:98:23:8d (oui Unknown) [|bootp]
    17:40:33.121657 arp who-has 192.168.1.50 tell 192.168.1.2
    17:40:34.001555 IP (tos 0x10, ttl 16, id 0, offset 0, flags [none], proto:UDP (17), length: 328) 192.168.1.2.bootps > 192.168.1.50.bootpc: BOOTP/DHCP, Reply, length: 300, xid:0x12345678, flags: [none] (0x0000)
    Your IP: 192.168.1.50
    Client Ethernet Address: 00:50:56:98:23:8d (oui Unknown) [|bootp]
    17:40:34.122468 arp who-has 192.168.1.50 tell 192.168.1.2
    17:40:34.554985 IP (tos 0x0, ttl 1, id 0, offset 0, flags [none], proto: IGMP (2), length: 36, options ( RA (148) len 4 )) 10.0.0.0 > all-systems.mcast.net: igmp query v3 [max resp time 1s]
    17:40:34.585378 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [DF], proto: IGMP (2), length: 40, options ( RA (148) len 4 )) 192.168.1.2 > igmp.mcast.net: igmp v3 report, 1 group record(s) [gaddr 224.0.0.251 is_ex { }]
    17:40:35.122279 arp who-has 192.168.1.50 tell 192.168.1.2
    17:41:06.957198 rarp who-is 00:50:56:98:23:8d (oui Unknown) tell 00:50:56:98:23:8d (oui Unknown)
    17:41:06.957210 rarp who-is 00:50:56:98:23:8d (oui Unknown) tell 00:50:56:98:23:8d (oui Unknown)
    17:41:06.957211 rarp who-is 00:50:56:98:23:8d (oui Unknown) tell 00:50:56:98:23:8d (oui Unknown)
    17:41:06.957223 rarp who-is 00:50:56:98:23:8d (oui Unknown) tell 00:50:56:98:23:8d (oui Unknown)
    17:41:07.556639 rarp who-is 00:50:56:98:23:8d (oui Unknown) tell 00:50:56:98:23:8d (oui Unknown)
    17:41:07.630083 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [DF], proto: IGMP (2), length: 40, options ( RA (148) len 4 )) 192.168.1.3 > igmp.mcast.net: igmp v3 report, 1 group record(s) [
    gaddr 224.0.0.251 is_ex { }]
    17:41:08.558188 rarp who-is 00:50:56:98:23:8d (oui Unknown) tell 00:50:56:98:23:8d (oui Unknown)
    17:41:09.557206 rarp who-is 00:50:56:98:23:8d (oui Unknown) tell 00:50:56:98:23:8d (oui Unknown)
    17:41:09.706661 IP (tos 0x0, ttl 64, id 38874, offset 0, flags [DF], proto: UDP (17), length: 328) 192.168.1.3.bootpc > 255.255.255.255.bootps: BOOTP/DHCP, Request from 00:50:56:98:23:8d (oui Unknown), length: 300, xid:0x12345678, flags: [none] (0x0000)
    Client Ethernet Address: 00:50:56:98:23:8d (oui Unknown) [|bootp]
    17:41:09.706840 IP (tos 0x10, ttl 16, id 0, offset 0, flags [none], proto:UDP (17), length: 328) 192.168.1.2.bootps > 192.168.1.50.bootpc: BOOTP/DHCP,
    Reply, length: 300, xid:0x12345678, flags: [none] (0x0000)
    Your IP: 192.168.1.50
    Client Ethernet Address: 00:50:56:98:23:8d (oui Unknown) [|bootp]
    17:41:11.556846 rarp who-is 00:50:56:98:23:8d (oui Unknown) tell 00:50:56:98:23:8d (oui Unknown)
    17:41:14.557189 rarp who-is 00:50:56:98:23:8d (oui Unknown) tell 00:50:56:98:23:8d (oui Unknown)
    17:41:14.643834 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [DF], proto: IGMP (2), length: 40, options ( RA (148) len 4 )) 192.168.1.3 > igmp.mcast.net: igmp v3 report, 1 group record(s) [
    gaddr 224.0.0.251 is_ex { }]
    17:41:19.557221 rarp who-is 00:50:56:98:23:8d (oui Unknown) tell 00:50:56:98:23:8d (oui Unknown)
    17:41:27.559216 rarp who-is 00:50:56:98:23:8d (oui Unknown) tell 00:50:56:98:23:8d (oui Unknown)
    17:41:40.558913 rarp who-is 00:50:56:98:23:8d (oui Unknown) tell 00:50:56:98:23:8d (oui Unknown)


    DHCP CLIENT
    ***********
    dhcp-Client>tcpdump -i eth1 -vvv
    tcpdump: listening on eth1, link-type EN10MB (Ethernet), capture size 96 bytes
    17:41:07.553418 IP (tos 0x0, ttl 1, id 0, offset 0, flags [none], proto: IGMP (2), length: 36, options ( RA (148) len 4 )) 10.0.0.0 > all-systems.mcast.net: igmp query v3 [max resp time 1s]
    17:41:07.626696 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [DF], proto: IGMP (2), length: 40, options ( RA (148) len 4 )) 192.168.1.3 > igmp.mcast.net: igmp v3 report, 1 group record(s) [gaddr 224.0.0.251 is_ex { }]
    17:41:09.703284 IP (tos 0x0, ttl 64, id 38874, offset 0, flags [DF], proto: UDP (17), length: 328) 192.168.1.3.bootpc > 255.255.255.255.bootps: BOOTP/DHCP, Request from 00:50:56:98:23:8d (oui Unknown), length: 300, xid:0x12345678, flags: [none] (0x0000)
    Client Ethernet Address: 00:50:56:98:23:8d (oui Unknown) [|bootp]
    17:41:09.703796 IP (tos 0x10, ttl 16, id 0, offset 0, flags [none], proto:UDP (17), length: 328) 192.168.1.2.bootps > 192.168.1.50.bootpc: BOOTP/DHCP, Reply, length: 300, xid:0x12345678, flags: [none] (0x0000)
    Your IP: 192.168.1.50
    Client Ethernet Address: 00:50:56:98:23:8d (oui Unknown) [|bootp]
    17:41:14.553952 IP (tos 0x0, ttl 1, id 0, offset 0, flags [none], proto: IGMP (2), length: 36, options ( RA (148) len 4 )) 10.0.0.0 > all-systems.mcast.net: igmp query v3 [max resp time 1s]
    17:41:14.640463 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [DF], proto: IGMP (2), length: 40, options ( RA (148) len 4 )) 192.168.1.3 > igmp.mcast.net: igmp v3 report, 1 group record(s) [gaddr 224.0.0.251 is_ex { }]
    17:41:21.554244 rarp who-is 00:50:56:98:04:36 (oui Unknown) tell 00:50:56:98:04:36 (oui Unknown)

    There is no iptables as i can verify.

    Any help to figure out why my script unable to receive the DHCP Offer Packets(that has the Your_IP details )would be much appreciated. Thanks for the help.


    PK
    , Jul 26, 2012
    #9
  10. On 2012-07-26 17:03, <> wrote:
    > All
    >
    > I know this is a pretty old thread, but looks like i hit the exact
    > same problem this week while trying to use DHCP::packet.

    [...]
    > When i use a script like this one, i can see the DHCPDISCOVER is sent
    > properly as it reaches the server and DHCPOFFER is also being made by
    > the server as per the logs ; but my script does not pick up the packet
    > for some reasons which i am unable to understand.
    >
    > --script --

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

    [...]
    > 17:41:09.706661 IP (tos 0x0, ttl 64, id 38874, offset 0, flags [DF], proto: UDP (17), length: 328) 192.168.1.3.bootpc > 255.255.255.255.bootps: BOOTP/DHCP, Request from 00:50:56:98:23:8d (oui Unknown), length: 300, xid:0x12345678, flags: [none] (0x0000)
    > Client Ethernet Address: 00:50:56:98:23:8d (oui Unknown) [|bootp]
    > 17:41:09.706840 IP (tos 0x10, ttl 16, id 0, offset 0, flags [none], proto: UDP (17), length: 328) 192.168.1.2.bootps > 192.168.1.50.bootpc: BOOTP/DHCP,
    > Reply, length: 300, xid:0x12345678, flags: [none] (0x0000)
    > Your IP: 192.168.1.50
    > Client Ethernet Address: 00:50:56:98:23:8d (oui Unknown) [|bootp]


    I guess this is the reason: You are sending the request from 192.168.1.3
    and have bound the socket to this address. But the answer is sent to
    192.168.1.50, so you won't receive it. Binding to 0.0.0.0 may help, but
    I doubt it: If you currently don't have the address 192.168.1.50, I
    think the kernel is supposed to discard the packet. You may have to use
    a raw socket.

    hp

    --
    _ | Peter J. Holzer | Deprecating human carelessness and
    |_|_) | Sysadmin WSR | ignorance has no successful track record.
    | | | |
    __/ | http://www.hjp.at/ | -- Bill Code on
    Peter J. Holzer, Jul 27, 2012
    #10
  11. DJ Stunks

    Guest

    Thank you Ben and Peter for your replies. Now my comments specific to your ideas ..

    #1 I did check the promiscuous mode before replying and it was indeed open and i got it open through the 'ip link' for the interface too, but those did not help. Since I was able to see the packets floating in the tcpdump at the server and client i believed that the issue is with the script only andindeed it was.
    #2 when i set the 'PeerAddr' to 0.0.0.0, it did not help so i reverted backto my client eth1 IP.
    #3 I changed the PeerPort and LocalPort to '67'
    #4 I checked the dhclient and it got the ip from my server so if that can work and my script can't , proves a point that the script has an issue. Later i played around in the script and got it working..

    Now my script looks like this
    .....
    $handle = IO::Socket::INET->new(Proto => 'udp',
    Broadcast => 1,
    PeerPort => 67,
    LocalPort => 67,
    PeerAddr => '192.168.1.2')
    || die "Socket creation error: $@\n"; # yes, it uses $@ here

    # create DHCP Packet DISCOVER
    $discover = Net::DHCP::packet->new(
    op=> BOOTREQUEST(),
    Htype => '0',
    Hlen => '6',
    Ciaddr => '0',
    Chaddr => $MAC,
    Giaddr => $handle -> sockhost(),
    Xid => int(rand(0xFFFFFFFF)),
    DHO_DHCP_MESSAGE_TYPE() => DHCPDISCOVER(),
    );
    ....

    Now, I receive the IP's from the client and i can read the packet as i wanted , works GREAT !!

    But, a new challenge, I noticed that every time i send the 'DHCPREQUEST' , my client gets a new IP though i pass on a hard-coded mac-address(MAC1 as an argument to pass on with different MACs for my try's) in the script. Server reads this MAC but rather than throwing an IP that was already given (per leases, its not expired) it gives a new IP. Is this expected ?

    Now questions ..

    1. Are there any settings in the dhcpd.conf that has to explicitly say to look for leases before giving new Ip's?
    2. How do i determine if the server has a valid lease for the mac i am sending before i can initiate a DHCPREQUEST ? ( Since i m scripting i want to make sure that for a particular mac , server gives the IP as per the lease if it is not expired and if it is let it renew rather than giving a new valid lease with a different IP. makes sense ? ) ; I came across 'DHCPLEASEQUERY' and realized (may be) it is not supported in 3.0.5 dhcpd version i am using ? I have told the support to upgrade to dhcp3.1 on RHEL5.

    My requirement is like : <script> MAC which has to talk to my server , getsa IP if it has not having a valid lease . if new, get the IP and mark a lease. I am OK to check if it has a valid lease before placing a DHCPREQUEST but just not sure how i can do(what type of DHO_DHCP_MESSAGE_TYPE does that? )

    Param
    , Jul 31, 2012
    #11
  12. DJ Stunks

    Guest

    I am back again. I upgraded the dhcp server to 4.1.11 on RHEL6 and the LEASEQUERY works great now.

    perl inform.pl 192.168.1.2 192.168.1.14
    marshall: packet too small (286), minimum size is 300 at inform.pl line 34
    op = BOOTREPLY
    htype = HTYPE_ETHER
    hlen = 6
    hops = 0
    xid = 95aba24
    secs = 0
    flags = 0
    ciaddr = 192.168.1.14
    yiaddr = 0.0.0.0
    siaddr = 0.0.0.0
    giaddr = 192.168.1.3
    chaddr = 005056aabbcc
    sname =
    file =
    Options :
    DHO_DHCP_MESSAGE_TYPE(53) = DHCPLEASEACTIVE
    DHO_DHCP_SERVER_IDENTIFIER(54) = 192.168.1.2
    DHO_DHCP_LEASE_TIME(51) = 1531
    DHO_SUBNET_MASK(1) = 255.255.255.0
    DHO_ROUTERS(3) = 192.168.1.0
    DHO_DHCP_RENEWAL_TIME(58) = 31
    DHO_DHCP_REBINDING_TIME(59) = 1156
    DHO_CLIENT_LAST_TRANSACTION_TIME(91) = \x00\x00\x05\xBD
    padding [0] =

    Interestingly, I am unable to RENEW that IP to extend the lease. I am stillto crack this. If i can achieve the RENEW and RELEASE methods, i am all done since i would be able to successfully mimic the end-to-end dhcp cycle sothat my script can handle whatever is required according to the scenario. Any pointers ? DHCPRENEW is not accepted DHCP message type, and i found DHCPFORCERENEW is, but it fails, may be i am yet to understand how i must passthat to the server. Let me know if you guys have tried this before ? Thanks.
    , Aug 7, 2012
    #12
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. deepak nayak
    Replies:
    3
    Views:
    407
    =?UTF-8?B?RXJpayBXaWtzdHLDtm0=?=
    Oct 25, 2007
  2. Mark Zvilius
    Replies:
    1
    Views:
    211
    Bill Kelly
    Sep 3, 2007
  3. Sébastien Cottalorda

    Pb with IO::Socket::INET and recv

    Sébastien Cottalorda, Sep 5, 2003, in forum: Perl Misc
    Replies:
    1
    Views:
    234
    Sébastien Cottalorda
    Sep 16, 2003
  4. Joe
    Replies:
    10
    Views:
    267
  5. Snail
    Replies:
    0
    Views:
    292
    Snail
    Mar 9, 2005
Loading...

Share This Page