-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscanzone.d
More file actions
104 lines (92 loc) · 3.2 KB
/
Copy pathscanzone.d
File metadata and controls
104 lines (92 loc) · 3.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/* read zone file a store hosts and their ip addresses to database */
/* naive implementation - should be redone to RFC 1035 */
module scanzone;
import std.stdio, std.regex;
import hosts, zones;
auto RE_ORIGIN = regex(r"^\s*\$ORIGIN\s+([a-z0-9.-]+)","i");
auto RE_HOST = regex(r"^([a-z0-9@*.-]*)\s+[0-9dmhsIN\s]*(A|AAAA)\s+([0-9a-f.:]{4,})","i");
void scanZone(ref Hostdb db, Zone zone)
{
//debug stderr.writefln("DEBUG scanzone(%s): %s ", zone.name, zone.changed);
auto file = File(zone.zonfil);
origin = zone.name ~ ".";
lastname = origin.idup;
foreach (line; file.byLine())
{
if (auto m = matchFirst(line, RE_ORIGIN))
origin = m[1].idup;
else
if (auto m = matchFirst(line, RE_HOST))
addToDB(db, m[1].idup, m[2].idup, m[3].idup, zone.changed);
}
}
private: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
string origin;
string lastname;
/* parametry jsou buffer z match, neukladat */
void addToDB(ref Hostdb db, string name, string rr, string data, bool changed)
{
import std.string;
string hostname;
//debug stderr.writef("scanzone: %s, %s, %s, %s => ", origin, name, rr, data);
//debug scope(success) stderr.writeln(hostname);
if (name.length)
lastname = name;
else
name = lastname;
if (name == "@")
hostname = origin;
else if (name[$-1] == '.')
hostname = name;
else
hostname = name ~ "." ~ origin;
final switch(rr.toUpper)
{
case "A": db.add4(hostname, data, changed); break;
case "AAAA": db.add6(hostname, data, changed); break;
}
}
unittest
{
import std.file, std.algorithm, std.range;
Hostdb testdb;
string input =
`
$TTL 2d
$ORIGIN testunit.cz.
@ SOA bid.iline.cz. mk.krej.cz. (2014022100 4h 1h 30d 15m)
@ NS stroj
@ MX 10 mail.iline.cz.
A 11.12.13.100
stroj A 11.12.13.10
15m IN A 11.12.14.10 ; TTL ignored, stroj jiz ma nastavene TTL
;stroj A 11.12.13.11
rrtype A 11.12.13.11 ; ERROR, mezera nazacatku, takze to neni hostname !
jedna 12h A 11.12.13.1
dva.testunit.cz. 6h A 11.12.13.2
@ A 192.168.254.136
$ORIGIN test.testunit.cz.
tri-3 A 150.16.0.10
jedna IN A 11.12.13.1
knedlik IN TXT "toto A 1.2.3.4"
`;
auto file = File("scanzone_unittest.tmp.db", "w");
file.write(input);
file.close;
scope testzone = new Zone("testunit.cz", "scanzone_unittest.tmp");
scanZone(testdb, testzone);
remove("scanzone_unittest.tmp.db");
//debug writeln(testdb);
assert(testdb.filterHost!"true"().count == 6);
assert(testdb.filterIPv4!"true"().count == 7);
assert(testdb.filterHost("stroj.testunit.cz.").front.i4s.length == 2);
assert(testdb["stroj.testunit.cz."].i4s.length == 2);
assert(testdb.filterHost("dva.testunit.cz.").front.i4s[0].ad == IPv4("11.12.13.2"));
assert(testdb["dva.testunit.cz."].i4s[0].ad == IPv4("11.12.13.2"));
assert(testdb.filterHost!(a => a.hn=="testunit.cz.")().front.i4s[1].ad == IPv4("192.168.254.136/32")); //pouze host testunit.cz.
assert(testdb["testunit.cz."].i4s[1].ad == IPv4("192.168.254.136/32"));
assert(testdb.filterIPv4("11.12.13.1/32").front.hns.length == 2);
assert(testdb[IPv4("11.12.13.1/32")].hns.length == 2);
assert(testdb.filterIPv4("150.16.0.10/32").front.hns[0].hn == "tri-3.test.testunit.cz.");
assert(testdb[IPv4("150.16.0.10")].hns[0].hn == "tri-3.test.testunit.cz.");
}