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