Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
CentralNic
Badcow-DNS
Commits
ff126e8b
Unverified
Commit
ff126e8b
authored
Sep 25, 2019
by
Sam Williams
Committed by
GitHub
Sep 25, 2019
Browse files
Merge pull request #41 from Badcow/PTR
Ensure reverse records parse correctly.
parents
73f8f948
a2906357
Changes
4
Hide whitespace changes
Inline
Side-by-side
lib/Parser/Parser.php
View file @
ff126e8b
...
...
@@ -62,7 +62,11 @@ class Parser
*/
public
function
__construct
(
array
$rdataHandlers
=
[])
{
$this
->
rdataHandlers
=
array_merge
(
RdataHandlers
::
getHandlers
(),
$rdataHandlers
);
$this
->
rdataHandlers
=
array_merge
(
RdataHandlers
::
getHandlers
(),
[
'PTR'
=>
__CLASS__
.
'::ptrHandler'
],
$rdataHandlers
);
}
/**
...
...
@@ -127,7 +131,6 @@ class Parser
{
if
(
$this
->
isTTL
(
$iterator
))
{
$this
->
currentResourceRecord
->
setTtl
((
int
)
$iterator
->
current
());
$this
->
lastStatedTtl
=
(
int
)
$iterator
->
current
();
$iterator
->
next
();
$this
->
processEntry
(
$iterator
);
...
...
@@ -136,7 +139,6 @@ class Parser
if
(
$this
->
isClass
(
$iterator
))
{
$this
->
currentResourceRecord
->
setClass
(
strtoupper
(
$iterator
->
current
()));
$this
->
lastStatedClass
=
strtoupper
(
$iterator
->
current
());
$iterator
->
next
();
$this
->
processEntry
(
$iterator
);
...
...
@@ -145,7 +147,6 @@ class Parser
if
(
$this
->
isResourceName
(
$iterator
)
&&
null
===
$this
->
currentResourceRecord
->
getName
())
{
$this
->
currentResourceRecord
->
setName
(
$iterator
->
current
());
$this
->
lastStatedDomain
=
$iterator
->
current
();
$iterator
->
next
();
$this
->
processEntry
(
$iterator
);
...
...
@@ -171,14 +172,20 @@ class Parser
{
if
(
null
===
$this
->
currentResourceRecord
->
getName
())
{
$this
->
currentResourceRecord
->
setName
(
$this
->
lastStatedDomain
);
}
else
{
$this
->
lastStatedDomain
=
$this
->
currentResourceRecord
->
getName
();
}
if
(
null
===
$this
->
currentResourceRecord
->
getTtl
())
{
$this
->
currentResourceRecord
->
setTtl
(
$this
->
lastStatedTtl
);
}
else
{
$this
->
lastStatedTtl
=
$this
->
currentResourceRecord
->
getTtl
();
}
if
(
null
===
$this
->
currentResourceRecord
->
getClass
())
{
$this
->
currentResourceRecord
->
setClass
(
$this
->
lastStatedClass
);
}
else
{
$this
->
lastStatedClass
=
$this
->
currentResourceRecord
->
getClass
();
}
}
...
...
@@ -211,21 +218,25 @@ class Parser
}
$isName
=
$this
->
isTTL
(
$iterator
)
||
$this
->
isClass
(
$iterator
)
||
$this
->
isClass
(
$iterator
,
'DOMAIN'
)
||
$this
->
isType
(
$iterator
);
$iterator
->
prev
();
return
$isName
;
}
private
function
isClass
(
ResourceRecordIterator
$iterator
):
bool
private
function
isClass
(
ResourceRecordIterator
$iterator
,
$origin
=
null
):
bool
{
if
(
!
Classes
::
isValid
(
$iterator
->
current
()))
{
return
false
;
}
$iterator
->
next
();
$isClass
=
$this
->
isTTL
(
$iterator
)
||
$this
->
isType
(
$iterator
);
if
(
'TTL'
===
$origin
)
{
$isClass
=
$this
->
isType
(
$iterator
);
}
else
{
$isClass
=
$this
->
isTTL
(
$iterator
,
'CLASS'
)
||
$this
->
isType
(
$iterator
);
}
$iterator
->
prev
();
return
$isClass
;
...
...
@@ -252,17 +263,22 @@ class Parser
* Determine if the iterant is a TTL (i.e. it is an integer).
*
* @param ResourceRecordIterator $iterator
* @param string $origin
*
* @return bool
*/
private
function
isTTL
(
ResourceRecordIterator
$iterator
):
bool
private
function
isTTL
(
ResourceRecordIterator
$iterator
,
$origin
=
null
):
bool
{
if
(
1
!==
preg_match
(
'/^\d+$/'
,
$iterator
->
current
()))
{
return
false
;
}
$iterator
->
next
();
$isTtl
=
$this
->
isClass
(
$iterator
)
||
$this
->
isType
(
$iterator
);
if
(
'CLASS'
===
$origin
)
{
$isTtl
=
$this
->
isType
(
$iterator
);
}
else
{
$isTtl
=
$this
->
isClass
(
$iterator
,
'TTL'
)
||
$this
->
isType
(
$iterator
);
}
$iterator
->
prev
();
return
$isTtl
;
...
...
@@ -290,4 +306,31 @@ class Parser
return
RdataHandlers
::
catchAll
(
$type
,
$iterator
);
}
/**
* This handler addresses the special case where an integer resource name could be confused for a TTL, for instance:
* 50 IN PTR mx1.acme.com.
*
* In the above, if the integer is below 256 then it is assumed to represent an octet of an IPv4 address.
*
* @param ResourceRecordIterator $iterator
*
* @return Rdata\PTR
*/
private
function
ptrHandler
(
ResourceRecordIterator
$iterator
):
Rdata
\
PTR
{
if
(
null
===
$this
->
currentResourceRecord
->
getName
()
&&
null
!==
$this
->
currentResourceRecord
->
getTtl
())
{
if
(
$this
->
currentResourceRecord
->
getTtl
()
<
256
)
{
$this
->
currentResourceRecord
->
setName
((
string
)
$this
->
currentResourceRecord
->
getTtl
());
$this
->
currentResourceRecord
->
setTtl
(
null
);
}
}
$ptr
=
RdataHandlers
::
catchAll
(
Rdata\PTR
::
TYPE
,
$iterator
);
if
(
!
$ptr
instanceof
Rdata\PTR
)
{
throw
new
\
UnexpectedValueException
();
}
return
$ptr
;
}
}
tests/Parser/ParserTest.php
View file @
ff126e8b
...
...
@@ -137,7 +137,7 @@ class ParserTest extends TestCase
$zone
=
Parser
::
parse
(
'example.com.'
,
$file
);
$this
->
assertEquals
(
'example.com.'
,
$zone
->
getName
());
$this
->
assertEquals
(
'::1'
,
$this
->
findRecord
(
'ipv6.domain'
,
$zone
)[
0
]
->
getRdata
()
->
getAddress
());
$this
->
assertEquals
(
'::1'
,
self
::
findRecord
(
'ipv6.domain'
,
$zone
)[
0
]
->
getRdata
()
->
getAddress
());
$this
->
assertEquals
(
1337
,
$zone
->
getDefaultTtl
());
}
...
...
@@ -164,10 +164,10 @@ class ParserTest extends TestCase
$txt2
=
'Some text another Some text'
;
$this
->
assertEquals
(
$txt
,
$this
->
findRecord
(
$txt
->
getName
(),
$zone
)[
0
]);
$this
->
assertEquals
(
$txt2
,
$this
->
findRecord
(
'test'
,
$zone
)[
0
]
->
getRdata
()
->
getText
());
$this
->
assertCount
(
1
,
$this
->
findRecord
(
'xn----7sbfndkfpirgcajeli2a4pnc.xn----7sbbfcqfo2cfcagacemif0ap5q'
,
$zone
));
$this
->
assertCount
(
4
,
$this
->
findRecord
(
'testmx'
,
$zone
));
$this
->
assertEquals
(
$txt
,
self
::
findRecord
(
$txt
->
getName
(),
$zone
)[
0
]);
$this
->
assertEquals
(
$txt2
,
self
::
findRecord
(
'test'
,
$zone
)[
0
]
->
getRdata
()
->
getText
());
$this
->
assertCount
(
1
,
self
::
findRecord
(
'xn----7sbfndkfpirgcajeli2a4pnc.xn----7sbbfcqfo2cfcagacemif0ap5q'
,
$zone
));
$this
->
assertCount
(
4
,
self
::
findRecord
(
'testmx'
,
$zone
));
}
/**
...
...
@@ -200,7 +200,7 @@ class ParserTest extends TestCase
$zone
=
Parser
::
parse
(
'example.com.'
,
$file
);
/** @var APL $apl */
$apl
=
$this
->
findRecord
(
'multicast'
,
$zone
)[
0
]
->
getRdata
();
$apl
=
self
::
findRecord
(
'multicast'
,
$zone
)[
0
]
->
getRdata
();
$this
->
assertCount
(
2
,
$apl
->
getIncludedAddressRanges
());
$this
->
assertCount
(
2
,
$apl
->
getExcludedAddressRanges
());
...
...
@@ -276,8 +276,8 @@ TXT;
{
$file
=
NormaliserTest
::
readFile
(
__DIR__
.
'/Resources/ambiguous.acme.org.txt'
);
$zone
=
Parser
::
parse
(
'ambiguous.acme.org.'
,
$file
);
$mxRecords
=
$this
->
findRecord
(
'mx'
,
$zone
);
$a4Records
=
$this
->
findRecord
(
'aaaa'
,
$zone
);
$mxRecords
=
self
::
findRecord
(
'mx'
,
$zone
);
$a4Records
=
self
::
findRecord
(
'aaaa'
,
$zone
);
$this
->
assertCount
(
3
,
$mxRecords
);
$this
->
assertCount
(
2
,
$a4Records
);
...
...
@@ -334,7 +334,7 @@ TXT;
*
* @return ResourceRecord[]
*/
p
rivate
function
findRecord
(
?string
$name
,
Zone
$zone
):
array
p
ublic
static
function
findRecord
(
?string
$name
,
Zone
$zone
):
array
{
$records
=
[];
...
...
tests/Parser/Resources/50.100.200.in-addr.arpa.db
0 → 100644
View file @
ff126e8b
$ORIGIN 50.100.200.in-addr.arpa.
$TTL 3600
@ IN SOA (
ns.acme.com. ; MNAME
noc.acme.com. ; RNAME
2014110501 ; SERIAL
3600 ; REFRESH
14400 ; RETRY
604800 ; EXPIRE
3600 ; MINIMUM
)
; NS RECORDS
@ NS ns1.acme.com.
@ NS ns2.acme.com.
1 IN 1080 PTR gw01.core.acme.com.
1 IN 1080 PTR gw02.core.acme.com.
50 IN PTR mx1.acme.com.
52 IN PTR mx2.acme.com.
70 7200 IN PTR ns1.acme.com.
72 7200 IN PTR ns2.acme.com.
150 200 PTR smtp.example.com.
170 150 IN PTR netscape.com.
tests/Parser/ReverseRecordTest.php
0 → 100644
View file @
ff126e8b
<?php
/*
* This file is part of Badcow DNS Library.
*
* (c) Samuel Williams <sam@badcow.co>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace
Badcow\DNS\Tests\Parser
;
use
Badcow\DNS\Classes
;
use
Badcow\DNS\Parser\Parser
;
use
Badcow\DNS\Rdata\PTR
;
use
PHPUnit\Framework\TestCase
;
class
ReverseRecordTest
extends
TestCase
{
/**
* @throws \Badcow\DNS\Parser\ParseException
*/
public
function
testReverseRecord
()
{
$ptr
=
'1 1080 IN PTR gw01.core.acme.com.'
;
$zone
=
Parser
::
parse
(
'50.100.200.in-addr.arpa.'
,
$ptr
);
$rr
=
$zone
->
getResourceRecords
()[
0
];
$this
->
assertEquals
(
'1'
,
$rr
->
getName
());
$this
->
assertEquals
(
Classes
::
INTERNET
,
$rr
->
getClass
());
$this
->
assertEquals
(
PTR
::
TYPE
,
$rr
->
getType
());
$this
->
assertEquals
(
'gw01.core.acme.com.'
,
$rr
->
getRdata
()
->
getTarget
());
}
/**
* @throws \Badcow\DNS\Parser\ParseException|\Exception
*/
public
function
testParseReverseRecordFile
()
{
$file
=
NormaliserTest
::
readFile
(
__DIR__
.
'/Resources/50.100.200.in-addr.arpa.db'
);
$zone
=
Parser
::
parse
(
'50.100.200.in-addr.arpa.'
,
$file
);
$parentRecords
=
ParserTest
::
findRecord
(
'@'
,
$zone
);
$_1Records
=
ParserTest
::
findRecord
(
'1'
,
$zone
);
$_50Records
=
ParserTest
::
findRecord
(
'50'
,
$zone
);
$_150Records
=
ParserTest
::
findRecord
(
'150'
,
$zone
);
$_170Records
=
ParserTest
::
findRecord
(
'170'
,
$zone
);
$this
->
assertCount
(
11
,
$zone
);
$this
->
assertCount
(
3
,
$parentRecords
);
$this
->
assertCount
(
2
,
$_1Records
);
$this
->
assertCount
(
1
,
$_50Records
);
$this
->
assertCount
(
1
,
$_150Records
);
$_1
=
$_1Records
[
0
];
$_50
=
$_50Records
[
0
];
$_150
=
$_150Records
[
0
];
$_170
=
$_170Records
[
0
];
$this
->
assertEquals
(
'1'
,
$_1
->
getName
());
$this
->
assertEquals
(
1080
,
$_1
->
getTtl
());
$this
->
assertEquals
(
Classes
::
INTERNET
,
$_1
->
getClass
());
$this
->
assertEquals
(
PTR
::
TYPE
,
$_1
->
getType
());
$this
->
assertEquals
(
'gw01.core.acme.com.'
,
$_1
->
getRdata
()
->
getTarget
());
$this
->
assertEquals
(
'50'
,
$_50
->
getName
());
$this
->
assertEquals
(
1080
,
$_50
->
getTtl
());
$this
->
assertEquals
(
Classes
::
INTERNET
,
$_50
->
getClass
());
$this
->
assertEquals
(
PTR
::
TYPE
,
$_50
->
getType
());
$this
->
assertEquals
(
'mx1.acme.com.'
,
$_50
->
getRdata
()
->
getTarget
());
$this
->
assertEquals
(
'150'
,
$_150
->
getName
());
$this
->
assertEquals
(
200
,
$_150
->
getTtl
());
$this
->
assertEquals
(
Classes
::
INTERNET
,
$_150
->
getClass
());
$this
->
assertEquals
(
PTR
::
TYPE
,
$_150
->
getType
());
$this
->
assertEquals
(
'smtp.example.com.'
,
$_150
->
getRdata
()
->
getTarget
());
$this
->
assertEquals
(
'170'
,
$_170
->
getName
());
$this
->
assertEquals
(
150
,
$_170
->
getTtl
());
$this
->
assertEquals
(
Classes
::
INTERNET
,
$_170
->
getClass
());
$this
->
assertEquals
(
PTR
::
TYPE
,
$_170
->
getType
());
$this
->
assertEquals
(
'netscape.com.'
,
$_170
->
getRdata
()
->
getTarget
());
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment