]>
Commit | Line | Data |
---|---|---|
45adf788 MR |
1 | #!/usr/bin/perl |
2 | # Simple DHCP client - sending a broadcasted DHCP Discover request | |
3 | ||
4 | use strict; | |
5 | use warnings; | |
6 | use IO::Socket::IP -register; | |
7 | ||
8 | use Net::DHCP::Packet; | |
9 | use Net::DHCP::Constants; | |
10 | ||
11 | use POSIX qw(setsid strftime); | |
12 | ||
094c3a58 | 13 | my ($request, $send, $receive, $discover, $response, $buf, $serverip, $myip, $mymac, $hostname); |
45adf788 MR |
14 | |
15 | $mymac = qx/ \/sbin\/ifconfig | grep -P '^eth0.+HWaddr\\s*' | awk '{print \$5}' /; | |
16 | $mymac =~ tr/://d; | |
094c3a58 | 17 | chomp($hostname = `hostname -s`); |
45adf788 MR |
18 | # Overrule when testing |
19 | #$mymac = '001cc0c33317'; | |
20 | logger("mac: $mymac"); | |
21 | ||
22 | # sample logger | |
23 | sub logger{ | |
24 | my $str = shift; | |
25 | print STDOUT strftime "[%d/%b/%Y:%H:%M:%S] ", localtime; | |
26 | print STDOUT "$str\n"; | |
27 | } | |
28 | ||
29 | logger("DHCPd tester - dummy client"); | |
30 | ||
31 | logger("Opening socket"); | |
32 | $send = IO::Socket::IP->new( Proto => 'udp', | |
33 | Broadcast => 1, | |
34 | PeerPort => 'bootps(67)', | |
26c136cd MR |
35 | #PeerAddr => inet_ntoa(INADDR_LOOPBACK),#(INADDR_BROADCAST), |
36 | PeerAddr => inet_ntoa(INADDR_BROADCAST), | |
45adf788 MR |
37 | ) |
38 | || die "Socket (send) creation error: $@\n"; # yes, it uses $@ here | |
39 | ||
40 | # create DHCP Packet DISCOVER | |
26c136cd | 41 | my $xid = int(rand(0xFFFFFFFF)); |
45adf788 MR |
42 | $discover = Net::DHCP::Packet->new( |
43 | Chaddr => $mymac, | |
44 | Giaddr => $send->sockhost(), | |
26c136cd | 45 | Xid => $xid, # random xid |
45adf788 MR |
46 | DHO_DHCP_MESSAGE_TYPE() => DHCPDISCOVER(), |
47 | Flags => 0x8000, | |
48 | DHO_VENDOR_CLASS_IDENTIFIER() => 'foo', | |
094c3a58 | 49 | DHO_HOST_NAME() => $hostname, |
45adf788 MR |
50 | ); |
51 | ||
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"; | |
56 | ||
57 | $receive = IO::Socket::IP->new( Proto => 'udp', | |
58 | Broadcast => 1, | |
59 | LocalPort => 'bootpc(68)', | |
60 | #LocalAddr => inet_ntoa(INADDR_LOOPBACK),#(INADDR_ANY), | |
094c3a58 | 61 | LocalAddr => inet_ntoa(INADDR_ANY), |
45adf788 MR |
62 | ) |
63 | || die "Socket (receive) creation error: $@\n"; # yes, it uses $@ here | |
64 | ||
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); | |
69 | $receive->close; | |
70 | $response = new Net::DHCP::Packet($buf); | |
094c3a58 MR |
71 | if ($response->getOptionValue(DHO_DHCP_MESSAGE_TYPE()) == DHCPNAK()) { |
72 | logger("Request for ip was denied"); | |
73 | exit; | |
74 | } | |
26c136cd | 75 | |
45adf788 MR |
76 | $serverip = $response->getOptionValue(DHO_DHCP_SERVER_IDENTIFIER()); |
77 | $myip = $response->yiaddr(); | |
78 | ||
79 | logger($response->toString()); | |
80 | ||
81 | # create DHCP Packet REQUEST | |
82 | $request = Net::DHCP::Packet->new( | |
26c136cd | 83 | Xid => $xid, # random xid |
45adf788 MR |
84 | Chaddr => $mymac, |
85 | Giaddr => $send->sockhost(), | |
86 | DHO_DHCP_MESSAGE_TYPE() => DHCPREQUEST(), | |
87 | DHO_VENDOR_CLASS_IDENTIFIER() => 'foo', | |
094c3a58 | 88 | DHO_HOST_NAME() => $hostname, |
45adf788 MR |
89 | DHO_DHCP_REQUESTED_ADDRESS() => $myip, |
90 | ); | |
91 | ||
92 | logger("Sending REQUEST to " . $send->peerhost . ":" . $send->peerport); | |
93 | logger($request->toString()); | |
94 | ||
95 | $send->send($request->serialize()) | |
96 | or die "Error sending:$!\n"; | |
97 | $send->close; | |
98 | ||
99 | $receive = IO::Socket::IP->new( Proto => 'udp', | |
100 | Broadcast => 1, | |
101 | LocalPort => 'bootpc(68)', | |
102 | #LocalAddr => inet_ntoa(INADDR_LOOPBACK),#inet_ntoa(INADDR_ANY), | |
094c3a58 | 103 | LocalAddr => inet_ntoa(INADDR_ANY), |
45adf788 MR |
104 | ) |
105 | || die "Socket creation error: $@\n"; # yes, it uses $@ here | |
106 | ||
107 | logger("Waiting for response from server"); | |
108 | $receive->recv($buf, 1024, 0); | |
109 | logger("Got response from " . $receive->peerhost . ":" . $receive->peerport); | |
110 | $receive->close; | |
111 | $response = new Net::DHCP::Packet($buf); | |
112 | logger($response->toString()); | |
113 | ||
114 | if ($response->getOptionValue(DHO_DHCP_MESSAGE_TYPE()) == DHCPACK()) { | |
115 | $send = IO::Socket::IP->new( Proto => 'udp', | |
116 | Broadcast => 1, | |
117 | PeerPort => 'bootps(67)', | |
118 | PeerAddr => $serverip, | |
119 | ) | |
120 | || die "Socket (send) creation error: $@\n"; # yes, it uses $@ here | |
121 | ||
122 | # create DHCP Packet REQUEST | |
123 | $request = Net::DHCP::Packet->new( | |
124 | op => BOOTREQUEST(), | |
125 | Xid => int(rand(0xFFFFFFFF)), # random xid | |
126 | Chaddr => $mymac, | |
127 | Ciaddr => $myip, | |
128 | Giaddr => $send->sockhost(), | |
129 | DHO_VENDOR_CLASS_IDENTIFIER() => 'foo', | |
094c3a58 | 130 | DHO_HOST_NAME() => $hostname, |
45adf788 MR |
131 | DHO_DHCP_MESSAGE_TYPE() => DHCPRELEASE() |
132 | ); | |
133 | ||
134 | logger("Sending REQUEST to " . $send->peerhost . ":" . $send->peerport); | |
135 | logger($request->toString()); | |
136 | ||
137 | $send->send($request->serialize()) | |
138 | or die "Error sending:$!\n"; | |
139 | $send->close; | |
140 | } else { | |
141 | logger("Request for ip $myip was denied") | |
142 | } |