]>
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)', | |
35 | PeerAddr => inet_ntoa(INADDR_LOOPBACK),#(INADDR_BROADCAST), | |
094c3a58 | 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 | |
41 | $discover = Net::DHCP::Packet->new( | |
42 | Chaddr => $mymac, | |
43 | Giaddr => $send->sockhost(), | |
44 | Xid => int(rand(0xFFFFFFFF)), # random xid | |
45 | DHO_DHCP_MESSAGE_TYPE() => DHCPDISCOVER(), | |
46 | Flags => 0x8000, | |
47 | DHO_VENDOR_CLASS_IDENTIFIER() => 'foo', | |
094c3a58 | 48 | DHO_HOST_NAME() => $hostname, |
45adf788 MR |
49 | ); |
50 | ||
51 | logger("Sending DISCOVER to " . $send->peerhost . ":" . $send->peerport); | |
52 | logger($discover->toString()); | |
53 | $send->send($discover->serialize(), 0) | |
54 | or die "Error sending:$!\n"; | |
55 | ||
56 | $receive = IO::Socket::IP->new( Proto => 'udp', | |
57 | Broadcast => 1, | |
58 | LocalPort => 'bootpc(68)', | |
59 | #LocalAddr => inet_ntoa(INADDR_LOOPBACK),#(INADDR_ANY), | |
094c3a58 | 60 | LocalAddr => inet_ntoa(INADDR_ANY), |
45adf788 MR |
61 | ) |
62 | || die "Socket (receive) creation error: $@\n"; # yes, it uses $@ here | |
63 | ||
64 | logger("Listen: " . $receive->sockhost . ":" . $receive->sockport); | |
65 | logger("Waiting for response from server"); | |
66 | $receive->recv($buf, 1024, 0); | |
67 | logger("Got response from " . $receive->peerhost . ":" . $receive->peerport); | |
68 | $receive->close; | |
69 | $response = new Net::DHCP::Packet($buf); | |
094c3a58 MR |
70 | if ($response->getOptionValue(DHO_DHCP_MESSAGE_TYPE()) == DHCPNAK()) { |
71 | logger("Request for ip was denied"); | |
72 | exit; | |
73 | } | |
45adf788 MR |
74 | $serverip = $response->getOptionValue(DHO_DHCP_SERVER_IDENTIFIER()); |
75 | $myip = $response->yiaddr(); | |
76 | ||
77 | logger($response->toString()); | |
78 | ||
79 | # create DHCP Packet REQUEST | |
80 | $request = Net::DHCP::Packet->new( | |
81 | Xid => int(rand(0xFFFFFFFF)), # random xid | |
82 | Chaddr => $mymac, | |
83 | Giaddr => $send->sockhost(), | |
84 | DHO_DHCP_MESSAGE_TYPE() => DHCPREQUEST(), | |
85 | DHO_VENDOR_CLASS_IDENTIFIER() => 'foo', | |
094c3a58 | 86 | DHO_HOST_NAME() => $hostname, |
45adf788 MR |
87 | DHO_DHCP_REQUESTED_ADDRESS() => $myip, |
88 | ); | |
89 | ||
90 | logger("Sending REQUEST to " . $send->peerhost . ":" . $send->peerport); | |
91 | logger($request->toString()); | |
92 | ||
93 | $send->send($request->serialize()) | |
94 | or die "Error sending:$!\n"; | |
95 | $send->close; | |
96 | ||
97 | $receive = IO::Socket::IP->new( Proto => 'udp', | |
98 | Broadcast => 1, | |
99 | LocalPort => 'bootpc(68)', | |
100 | #LocalAddr => inet_ntoa(INADDR_LOOPBACK),#inet_ntoa(INADDR_ANY), | |
094c3a58 | 101 | LocalAddr => inet_ntoa(INADDR_ANY), |
45adf788 MR |
102 | ) |
103 | || die "Socket creation error: $@\n"; # yes, it uses $@ here | |
104 | ||
105 | logger("Waiting for response from server"); | |
106 | $receive->recv($buf, 1024, 0); | |
107 | logger("Got response from " . $receive->peerhost . ":" . $receive->peerport); | |
108 | $receive->close; | |
109 | $response = new Net::DHCP::Packet($buf); | |
110 | logger($response->toString()); | |
111 | ||
112 | if ($response->getOptionValue(DHO_DHCP_MESSAGE_TYPE()) == DHCPACK()) { | |
113 | $send = IO::Socket::IP->new( Proto => 'udp', | |
114 | Broadcast => 1, | |
115 | PeerPort => 'bootps(67)', | |
116 | PeerAddr => $serverip, | |
117 | ) | |
118 | || die "Socket (send) creation error: $@\n"; # yes, it uses $@ here | |
119 | ||
120 | # create DHCP Packet REQUEST | |
121 | $request = Net::DHCP::Packet->new( | |
122 | op => BOOTREQUEST(), | |
123 | Xid => int(rand(0xFFFFFFFF)), # random xid | |
124 | Chaddr => $mymac, | |
125 | Ciaddr => $myip, | |
126 | Giaddr => $send->sockhost(), | |
127 | DHO_VENDOR_CLASS_IDENTIFIER() => 'foo', | |
094c3a58 | 128 | DHO_HOST_NAME() => $hostname, |
45adf788 MR |
129 | DHO_DHCP_MESSAGE_TYPE() => DHCPRELEASE() |
130 | ); | |
131 | ||
132 | logger("Sending REQUEST to " . $send->peerhost . ":" . $send->peerport); | |
133 | logger($request->toString()); | |
134 | ||
135 | $send->send($request->serialize()) | |
136 | or die "Error sending:$!\n"; | |
137 | $send->close; | |
138 | } else { | |
139 | logger("Request for ip $myip was denied") | |
140 | } |