<?php namespace App\Classes\Protocol\DNS; use Illuminate\Support\Arr; use Illuminate\Support\Collection; use Illuminate\Support\Facades\Log; use App\Classes\Protocol\DNS; final class RR { private const LOGKEY = 'PDR'; public Collection $labels; public int $type; public int $class; private string $buf; public function __construct(string $buf) { $this->buf = $buf; $this->labels = collect(); $i = 0; $domain = strstr($buf,"\x00",TRUE); $i += strlen($domain)+1; try { $this->type = Arr::get(unpack('n',substr($buf,$i,2)),1); $this->class = Arr::get(unpack('n',substr($buf,$i+2,2)),1); } catch (\ErrorException $e) { Log::error(sprintf('%s:! Error unpacking buffer [%s]',self::LOGKEY,$buf),['buf'=>hex_dump($buf)]); return; } $i += 4; switch ($this->type) { case DNS::DNS_TYPE_CNAME: case DNS::DNS_TYPE_NS: case DNS::DNS_TYPE_DS: case DNS::DNS_TYPE_SOA: $i = 0; while (($len=ord(substr($domain,$i++,1))) !== 0x00) { $this->labels->push(substr($buf,$i,$len)); $i += $len; } break; case DNS::DNS_TYPE_OPT: // Domain is 0x00 $this->ttl = Arr::get(unpack('N',substr($buf,$i,4)),1); $this->rddata_len = Arr::get(unpack('n',substr($buf,$i+4,2)),1); $this->rddata = substr($buf,$i+6,$this->rddata_len); break; default: dd(['unknown type:'.$this->type,'buf'=>$this->buf]); } } public function __get(string $key): mixed { switch ($key) { case 'length': return strlen($this->buf); default: throw new \Exception(sprintf('%s:Unknown key [%s]',self::LOGKEY,$key)); } } public function __tostring(): string { return $this->buf; } }