3

wonder if I can get another pair of eyes on this.

Use case; grabbing DNS records from zone file in order to run shell_exec to import them into another platform.

I am trying to grab all types of DNS records from a zone file, A record, CNAME, TXT, MX etc. I am doing well so far in that I have managed to do CNAME, TXT and MX records.

I am stuck on the A record. Unfortunately, as I am searching each line of the file for A, this is causing CNAME and the SOA to be returned also. Here's what I have:

// Looking for:
$search_a = 'A';

// Read from file
$lines = file("$domain.");

// Check if the line contains A
foreach($lines as $a) {
    if(strpos($a, $search_a) !== false) {
    $a_array = "$a";
    $a_record_output = preg_split('/(.'.$domain.'.|\s)/', $a_array, -1, PREG_SPLIT_NO_EMPTY);
    print_r($a_record_output);
    }
}

This returns:

Array
(
    [0] => domain.io.
    [1] => SOA
    [2] => ns1.domain.io.
    [3] => stuff.
    [4] => (64719
    [5] => 14400
    [6] => 7200
    [7] => 2419200
    [8] => 3600)
)
Array
(
    [0] => domain.io.
    [1] => A
    [2] => 8.8.8.8
)
Array
(
    [0] => autodiscover
    [1] => CNAME
    [2] => autodiscover.outlook.com.
)

Obviously it is working, however, I need to exclude the SOA and CNAME record as I am only searching for A records.

I need to completely ignore the CNAME and SOA arrays and only return ones which contain just A. Here's an extract from the zone file

domain.io.      A   8.8.8.8
www             CNAME domain.io

Is there a way of doing this?

2 Answers2

0

You can check if the second element of the resulting array is A and only if it is, continue with your logic. Else, skip the row:

if ($a_record_output[1] !== "A") continue;

Demo

It’d probably be better though if you didn’t select the record at all rather than filtering them. You can use preg_match() with a word boundary rather than strpos() for this:

if (preg_match("/\b".$search_a."\b/i", $a)) {

Demo

ishegg
  • 9,685
  • 3
  • 16
  • 31
  • Your second version seems perfect to what I need. I didn't even think about adding $search_a into the preg_match. Thank you very much! Saved me a ton of time! –  Oct 21 '17 at 11:25
0

If you are going to put your text file into array form, you can just filter with preg_grep(). This is a logical replacement to using preg_match() to search in a loop.

$search_a = 'A';
var_export(preg_grep('/^[^\t]+\t+'.$search_a.'\t/',file("$domain.")));

This matches from the front of each line, one or more non-tab characters, then one or more tab characters, then the needle string, then a tab character to make sure we are making a tight match.

preg_quote() may be necessary depending on what characters will be used in $search.

...there are a few ways to skin this cat.


p.s. your preg_split() pattern could use some refinement as well. If you provide the raw text from the file, I can craft a better one for you.

mickmackusa
  • 43,625
  • 12
  • 83
  • 136