2 # Simple DHCP client - sending a broadcasted DHCP Discover request
6 use IO
::Socket
::IP
-register
;
9 use Net
::DHCP
::Constants
;
11 use POSIX
qw(setsid strftime);
13 my ($request, $send, $receive, $discover, $response, $buf, $serverip, $myip, $mymac, $hostname);
15 $mymac = qx/ \/sbin\
/ifconfig | grep -P '^eth0.+HWaddr\\s*' | awk '{print \$5}' /;
17 chomp($hostname = `hostname -s`);
18 # Overrule when testing
19 #$mymac = '001cc0c33317';
20 logger
("mac: $mymac");
25 print STDOUT strftime
"[%d/%b/%Y:%H:%M:%S] ", localtime;
26 print STDOUT
"$str\n";
29 logger
("DHCPd tester - dummy client");
31 logger
("Opening socket");
32 $send = IO
::Socket
::IP
->new( Proto
=> 'udp',
34 PeerPort
=> 'bootps(67)',
35 #PeerAddr => inet_ntoa(INADDR_LOOPBACK),#(INADDR_BROADCAST),
36 PeerAddr
=> inet_ntoa
(INADDR_BROADCAST
),
38 || die "Socket (send) creation error: $@\n"; # yes, it uses $@ here
40 # create DHCP Packet DISCOVER
41 my $xid = int(rand(0xFFFFFFFF));
42 $discover = Net
::DHCP
::Packet
->new(
44 Giaddr
=> $send->sockhost(),
45 Xid
=> $xid, # random xid
46 DHO_DHCP_MESSAGE_TYPE
() => DHCPDISCOVER
(),
48 DHO_VENDOR_CLASS_IDENTIFIER
() => 'foo',
49 DHO_HOST_NAME
() => $hostname,
52 logger
("Sending DISCOVER to " . $send->peerhost . ":" . $send->peerport);
53 logger
($discover->toString());
54 $send->send($discover->serialize(), 0)
55 or die "Error sending:$!\n";
57 $receive = IO
::Socket
::IP
->new( Proto
=> 'udp',
59 LocalPort
=> 'bootpc(68)',
60 #LocalAddr => inet_ntoa(INADDR_LOOPBACK),#(INADDR_ANY),
61 LocalAddr
=> inet_ntoa
(INADDR_ANY
),
63 || die "Socket (receive) creation error: $@\n"; # yes, it uses $@ here
65 logger
("Listen: " . $receive->sockhost . ":" . $receive->sockport);
66 logger
("Waiting for response from server");
67 $receive->recv($buf, 1024, 0);
68 logger
("Got response from " . $receive->peerhost . ":" . $receive->peerport);
70 $response = new Net
::DHCP
::Packet
($buf);
71 if ($response->getOptionValue(DHO_DHCP_MESSAGE_TYPE
()) == DHCPNAK
()) {
72 logger
("Request for ip was denied");
76 $serverip = $response->getOptionValue(DHO_DHCP_SERVER_IDENTIFIER
());
77 $myip = $response->yiaddr();
79 logger
($response->toString());
81 # create DHCP Packet REQUEST
82 $request = Net
::DHCP
::Packet
->new(
83 Xid
=> $xid, # random xid
85 Giaddr
=> $send->sockhost(),
86 DHO_DHCP_MESSAGE_TYPE
() => DHCPREQUEST
(),
87 DHO_VENDOR_CLASS_IDENTIFIER
() => 'foo',
88 DHO_HOST_NAME
() => $hostname,
89 DHO_DHCP_REQUESTED_ADDRESS
() => $myip,
92 logger
("Sending REQUEST to " . $send->peerhost . ":" . $send->peerport);
93 logger
($request->toString());
95 $send->send($request->serialize())
96 or die "Error sending:$!\n";
99 $receive = IO
::Socket
::IP
->new( Proto
=> 'udp',
101 LocalPort
=> 'bootpc(68)',
102 #LocalAddr => inet_ntoa(INADDR_LOOPBACK),#inet_ntoa(INADDR_ANY),
103 LocalAddr
=> inet_ntoa
(INADDR_ANY
),
105 || die "Socket creation error: $@\n"; # yes, it uses $@ here
107 logger
("Waiting for response from server");
108 $receive->recv($buf, 1024, 0);
109 logger
("Got response from " . $receive->peerhost . ":" . $receive->peerport);
111 $response = new Net
::DHCP
::Packet
($buf);
112 logger
($response->toString());
114 if ($response->getOptionValue(DHO_DHCP_MESSAGE_TYPE
()) == DHCPACK
()) {
115 $send = IO
::Socket
::IP
->new( Proto
=> 'udp',
117 PeerPort
=> 'bootps(67)',
118 PeerAddr
=> $serverip,
120 || die "Socket (send) creation error: $@\n"; # yes, it uses $@ here
122 # create DHCP Packet REQUEST
123 $request = Net
::DHCP
::Packet
->new(
125 Xid
=> int(rand(0xFFFFFFFF)), # random xid
128 Giaddr
=> $send->sockhost(),
129 DHO_VENDOR_CLASS_IDENTIFIER
() => 'foo',
130 DHO_HOST_NAME
() => $hostname,
131 DHO_DHCP_MESSAGE_TYPE
() => DHCPRELEASE
()
134 logger
("Sending REQUEST to " . $send->peerhost . ":" . $send->peerport);
135 logger
($request->toString());
137 $send->send($request->serialize())
138 or die "Error sending:$!\n";
141 logger
("Request for ip $myip was denied")