--- /dev/null
+<?php
+$dhcp = new dhcp_proto();
+$socket = stream_socket_server("udp://0.0.0.0:67", $errno, $errstr, STREAM_SERVER_BIND);
+if (!$socket) {
+ die("$errstr ($errno)");
+}
+
+do {
+ $pkt = stream_socket_recvfrom($socket, 1500, 0, $peer);
+ echo "$peer: \n";
+ $dhcp->parse($pkt);
+ exit();
+} while ($pkt !== false);
+
+class dhcp_proto
+{
+
+ public function parse($packet)
+ {
+ $parse = unpack('Cop/Chtype/Chlen/Chops/Ixid/nsecs/nflags/Iciaddr/Iyiaddr/Isiaddr/Igiaddr/H32chaddr/Z64sname/Z128file/H8magic/a*options',$packet);
+ var_dump($parse);
+ $opt_stack = $parse['options'];
+ $OPTS = [];
+ $stopflag = FALSE;
+ $DHCPOptions = [];
+ do
+ {
+ $optnum = unpack('C', $opt_stack);
+ if ($optnum[1] == 255)
+ {
+ break;
+ }
+ if ($optnum[1] == 0)
+ {
+ continue;
+ }
+ $opt_stack = substr($opt_stack, 1);
+ $optsize = unpack('C', $opt_stack);
+ $opt_stack = substr($opt_stack, 1);
+ $optpayload = unpack('a'.$optsize[1], $opt_stack);
+ $opt_stack = substr($opt_stack, $optsize[1]);
+ var_dump($optnum[1], $optpayload[1]);
+ $DHCPOptions[] = $this->OptDictonaryPostprocessor($optnum[1], $optpayload[1]);
+ }
+ while (strlen($opt_stack) > 0);
+
+ var_dump($DHCPOptions);
+ }
+ protected function OptDictonaryPostprocessor($opt,$payload)
+ {
+ switch ($opt)
+ {
+ case 1:
+ $DecodedOption['number'] = $opt;
+ $DecodedOption['name'] = 'SubnetMask';
+ $tmp = long2ip(unpack('N',$payload));
+ $DecodedOption['data'] = $tmp[1];
+ break;
+ case 12:
+ $DecodedOption['number'] = $opt;
+ $DecodedOption['name'] = 'HostName';
+ $DecodedOption['data'] = $payload;
+ break;
+
+ case 53:
+ $DecodedOption['number'] = $opt;
+ $DecodedOption['name'] = 'DhcpPacketType';
+ $type = unpack('C',$payload);
+ switch ($type[1])
+ {
+ case 1:
+ {
+ $DecodedOption['data'] = 'DHCPDISCOVER';
+ break;
+ }
+ case 2:
+ {
+ $DecodedOption['data'] = 'DHCPOFFER';
+ break;
+ }
+ case 3:
+ {
+ $DecodedOption['data'] = 'DHCPREQUEST';
+ break;
+ }
+ case 4:
+ {
+ $DecodedOption['data'] = 'DHCPDECLINE';
+ break;
+ }
+ case 5:
+ {
+ $DecodedOption['data'] = 'DHCPACK';
+ break;
+ }
+ case 6:
+ {
+ $DecodedOption['data'] = 'DHCPNAK';
+ break;
+ }
+ case 7:
+ {
+ $DecodedOption['data'] = 'DHCPRELEASE';
+ break;
+ }
+ case 8:
+ {
+ $DecodedOption['data'] = 'DHCPINFORM';
+ break;
+ }
+ case 9:
+ {
+ $DecodedOption['data'] = 'RESERVED';
+ break;
+ }
+ case 0:
+ {
+ $DecodedOption['data'] = 'RESERVED';
+ break;
+ }
+ }
+ break;
+ case 55:
+ $DecodedOption['number'] = $opt;
+ $DecodedOption['name'] = 'RequestOptionCodes';
+ $DecodedOption['data'] = unpack('C*',$payload);
+ break;
+ case 61:
+ $DecodedOption['number'] = $opt;
+ $DecodedOption['name'] = 'ClientIdentifier';
+ $tmp = unpack('H*',$payload);
+ $DecodedOption['data'] = $tmp[1];
+ break;
+ default:
+ $DecodedOption['number'] = $opt;
+ $DecodedOption['name'] = 'UnsupportedOption';
+ $DecodedOption['data'] = FALSE;
+ break;
+ }
+ return $DecodedOption;
+ }
+}
\ No newline at end of file