]>
git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/lua-base4.cc
2 #include <unordered_set>
3 #include <unordered_map>
8 #include "dnsparser.hh"
9 #include "dnspacket.hh"
10 #include "namespaces.hh"
11 #include "ednssubnet.hh"
12 #include "lua-base4.hh"
13 #include "dns_random.hh"
15 BaseLua4::BaseLua4() {
18 void BaseLua4::loadFile(const std::string
&fname
) {
19 std::ifstream
ifs(fname
);
21 g_log
<<Logger::Error
<<"Unable to read configuration file from '"<<fname
<<"': "<<strerror(errno
)<<endl
;
27 void BaseLua4::loadString(const std::string
&script
) {
28 std::istringstream
iss(script
);
32 #if !defined(HAVE_LUA)
34 void BaseLua4::prepareContext() { return; }
35 void BaseLua4::loadStream(std::istream
&is
) { return; }
36 BaseLua4::~BaseLua4() { }
40 #include "ext/luawrapper/include/LuaContext.hpp"
42 void BaseLua4::prepareContext() {
43 d_lw
= std::unique_ptr
<LuaContext
>(new LuaContext
);
46 d_lw
->registerFunction
<int(dnsheader::*)()>("getID", [](dnsheader
& dh
) { return ntohs(dh
.id
); });
47 d_lw
->registerFunction
<bool(dnsheader::*)()>("getCD", [](dnsheader
& dh
) { return dh
.cd
; });
48 d_lw
->registerFunction
<bool(dnsheader::*)()>("getTC", [](dnsheader
& dh
) { return dh
.tc
; });
49 d_lw
->registerFunction
<bool(dnsheader::*)()>("getRA", [](dnsheader
& dh
) { return dh
.ra
; });
50 d_lw
->registerFunction
<bool(dnsheader::*)()>("getAD", [](dnsheader
& dh
) { return dh
.ad
; });
51 d_lw
->registerFunction
<bool(dnsheader::*)()>("getAA", [](dnsheader
& dh
) { return dh
.aa
; });
52 d_lw
->registerFunction
<bool(dnsheader::*)()>("getRD", [](dnsheader
& dh
) { return dh
.rd
; });
53 d_lw
->registerFunction
<int(dnsheader::*)()>("getRCODE", [](dnsheader
& dh
) { return dh
.rcode
; });
54 d_lw
->registerFunction
<int(dnsheader::*)()>("getOPCODE", [](dnsheader
& dh
) { return dh
.opcode
; });
55 d_lw
->registerFunction
<int(dnsheader::*)()>("getQDCOUNT", [](dnsheader
& dh
) { return ntohs(dh
.qdcount
); });
56 d_lw
->registerFunction
<int(dnsheader::*)()>("getANCOUNT", [](dnsheader
& dh
) { return ntohs(dh
.ancount
); });
57 d_lw
->registerFunction
<int(dnsheader::*)()>("getNSCOUNT", [](dnsheader
& dh
) { return ntohs(dh
.nscount
); });
58 d_lw
->registerFunction
<int(dnsheader::*)()>("getARCOUNT", [](dnsheader
& dh
) { return ntohs(dh
.arcount
); });
61 d_lw
->writeFunction("newDN", [](const std::string
& dom
){ return DNSName(dom
); });
62 d_lw
->registerFunction("__lt", &DNSName::operator<);
63 d_lw
->registerFunction("canonCompare", &DNSName::canonCompare
);
64 d_lw
->registerFunction("makeRelative", &DNSName::makeRelative
);
65 d_lw
->registerFunction("isPartOf", &DNSName::isPartOf
);
66 d_lw
->registerFunction("getRawLabels", &DNSName::getRawLabels
);
67 d_lw
->registerFunction
<unsigned int(DNSName::*)()>("countLabels", [](const DNSName
& name
) { return name
.countLabels(); });
68 d_lw
->registerFunction
<size_t(DNSName::*)()>("wireLength", [](const DNSName
& name
) { return name
.wirelength(); });
69 d_lw
->registerFunction
<size_t(DNSName::*)()>("wirelength", [](const DNSName
& name
) { return name
.wirelength(); });
70 d_lw
->registerFunction
<bool(DNSName::*)(const std::string
&)>("equal", [](const DNSName
& lhs
, const std::string
& rhs
) { return lhs
==DNSName(rhs
); });
71 d_lw
->registerEqFunction(&DNSName::operator==);
72 d_lw
->registerToStringFunction
<string(DNSName::*)()>([](const DNSName
&dn
) { return dn
.toString(); });
73 d_lw
->registerFunction
<string(DNSName::*)()>("toString", [](const DNSName
&dn
) { return dn
.toString(); });
74 d_lw
->registerFunction
<string(DNSName::*)()>("toStringNoDot", [](const DNSName
&dn
) { return dn
.toStringNoDot(); });
75 d_lw
->registerFunction
<bool(DNSName::*)()>("chopOff", [](DNSName
&dn
) { return dn
.chopOff(); });
78 d_lw
->writeFunction("newDRR", [](const DNSName
& qname
, const string
& qtype
, const unsigned int ttl
, const string
& content
, boost::optional
<int> domain_id
, boost::optional
<int> auth
){
79 auto drr
= DNSResourceRecord();
83 drr
.setContent(content
);
85 drr
.domain_id
= *domain_id
;
90 d_lw
->registerEqFunction(&DNSResourceRecord::operator==);
91 d_lw
->registerFunction("__lt", &DNSResourceRecord::operator<);
92 d_lw
->registerToStringFunction
<string(DNSResourceRecord::*)()>([](const DNSResourceRecord
& rec
) { return rec
.getZoneRepresentation(); });
93 d_lw
->registerFunction
<string(DNSResourceRecord::*)()>("toString", [](const DNSResourceRecord
& rec
) { return rec
.getZoneRepresentation();} );
94 d_lw
->registerFunction
<DNSName(DNSResourceRecord::*)()>("qname", [](DNSResourceRecord
& rec
) { return rec
.qname
; });
95 d_lw
->registerFunction
<DNSName(DNSResourceRecord::*)()>("wildcardName", [](DNSResourceRecord
& rec
) { return rec
.wildcardname
; });
96 d_lw
->registerFunction
<string(DNSResourceRecord::*)()>("content", [](DNSResourceRecord
& rec
) { return rec
.content
; });
97 d_lw
->registerFunction
<time_t(DNSResourceRecord::*)()>("lastModified", [](DNSResourceRecord
& rec
) { return rec
.last_modified
; });
98 d_lw
->registerFunction
<uint32_t(DNSResourceRecord::*)()>("ttl", [](DNSResourceRecord
& rec
) { return rec
.ttl
; });
99 d_lw
->registerFunction
<uint32_t(DNSResourceRecord::*)()>("signttl", [](DNSResourceRecord
& rec
) { return rec
.signttl
; });
100 d_lw
->registerFunction
<int(DNSResourceRecord::*)()>("domainId", [](DNSResourceRecord
& rec
) { return rec
.domain_id
; });
101 d_lw
->registerFunction
<uint16_t(DNSResourceRecord::*)()>("qtype", [](DNSResourceRecord
& rec
) { return rec
.qtype
.getCode(); });
102 d_lw
->registerFunction
<uint16_t(DNSResourceRecord::*)()>("qclass", [](DNSResourceRecord
& rec
) { return rec
.qclass
; });
103 d_lw
->registerFunction
<uint8_t(DNSResourceRecord::*)()>("scopeMask", [](DNSResourceRecord
& rec
) { return rec
.scopeMask
; });
104 d_lw
->registerFunction
<bool(DNSResourceRecord::*)()>("auth", [](DNSResourceRecord
& rec
) { return rec
.auth
; });
105 d_lw
->registerFunction
<bool(DNSResourceRecord::*)()>("disabled", [](DNSResourceRecord
& rec
) { return rec
.disabled
; });
108 d_lw
->registerFunction
<bool(ComboAddress::*)()>("isIPv4", [](const ComboAddress
& ca
) { return ca
.sin4
.sin_family
== AF_INET
; });
109 d_lw
->registerFunction
<bool(ComboAddress::*)()>("isIPv6", [](const ComboAddress
& ca
) { return ca
.sin4
.sin_family
== AF_INET6
; });
110 d_lw
->registerFunction
<uint16_t(ComboAddress::*)()>("getPort", [](const ComboAddress
& ca
) { return ntohs(ca
.sin4
.sin_port
); } );
111 d_lw
->registerFunction
<bool(ComboAddress::*)()>("isMappedIPv4", [](const ComboAddress
& ca
) { return ca
.isMappedIPv4(); });
112 d_lw
->registerFunction
<ComboAddress(ComboAddress::*)()>("mapToIPv4", [](const ComboAddress
& ca
) { return ca
.mapToIPv4(); });
113 d_lw
->registerFunction
<void(ComboAddress::*)(unsigned int)>("truncate", [](ComboAddress
& ca
, unsigned int bits
) { ca
.truncate(bits
); });
114 d_lw
->registerFunction
<string(ComboAddress::*)()>("toString", [](const ComboAddress
& ca
) { return ca
.toString(); });
115 d_lw
->registerToStringFunction
<string(ComboAddress::*)()>([](const ComboAddress
& ca
) { return ca
.toString(); });
116 d_lw
->registerFunction
<string(ComboAddress::*)()>("toStringWithPort", [](const ComboAddress
& ca
) { return ca
.toStringWithPort(); });
117 d_lw
->registerFunction
<string(ComboAddress::*)()>("getRaw", [](const ComboAddress
& ca
) {
118 if(ca
.sin4
.sin_family
== AF_INET
) {
119 auto t
=ca
.sin4
.sin_addr
.s_addr
; return string((const char*)&t
, 4);
122 return string((const char*)&ca
.sin6
.sin6_addr
.s6_addr
, 16);
125 d_lw
->writeFunction("newCA", [](const std::string
& a
) { return ComboAddress(a
); });
126 typedef std::unordered_set
<ComboAddress
,ComboAddress::addressOnlyHash
,ComboAddress::addressOnlyEqual
> cas_t
;
127 d_lw
->registerFunction
<bool(ComboAddress::*)(const ComboAddress
&)>("equal", [](const ComboAddress
& lhs
, const ComboAddress
& rhs
) { return ComboAddress::addressOnlyEqual()(lhs
, rhs
); });
130 d_lw
->writeFunction("newCAS", []{ return cas_t(); });
131 d_lw
->registerFunction
<void(cas_t::*)(boost::variant
<string
,ComboAddress
, vector
<pair
<unsigned int,string
> > >)>("add",
132 [](cas_t
& cas
, const boost::variant
<string
,ComboAddress
,vector
<pair
<unsigned int,string
> > >& in
)
135 if(auto s
= boost::get
<string
>(&in
)) {
136 cas
.insert(ComboAddress(*s
));
138 else if(auto v
= boost::get
<vector
<pair
<unsigned int, string
> > >(&in
)) {
139 for(const auto& str
: *v
)
140 cas
.insert(ComboAddress(str
.second
));
143 cas
.insert(boost::get
<ComboAddress
>(in
));
145 catch(std::exception
& e
) { g_log
<<Logger::Error
<<e
.what()<<endl
; }
147 d_lw
->registerFunction
<bool(cas_t::*)(const ComboAddress
&)>("check",[](const cas_t
& cas
, const ComboAddress
&ca
) { return cas
.count(ca
)>0; });
150 d_lw
->writeFunction("newQType", [](const string
& s
) { QType q
; q
= s
; return q
; });
151 d_lw
->registerFunction("getCode", &QType::getCode
);
152 d_lw
->registerFunction("getName", &QType::getName
);
153 d_lw
->registerEqFunction
<bool(QType::*)(const QType
&)>([](const QType
& a
, const QType
& b
){ return a
== b
;}); // operator overloading confuses LuaContext
154 d_lw
->registerToStringFunction(&QType::getName
);
157 d_lw
->writeFunction("newNetmask", [](const string
& s
) { return Netmask(s
); });
158 d_lw
->registerFunction
<ComboAddress(Netmask::*)()>("getNetwork", [](const Netmask
& nm
) { return nm
.getNetwork(); } ); // const reference makes this necessary
159 d_lw
->registerFunction
<ComboAddress(Netmask::*)()>("getMaskedNetwork", [](const Netmask
& nm
) { return nm
.getMaskedNetwork(); } );
160 d_lw
->registerFunction("isIpv4", &Netmask::isIpv4
);
161 d_lw
->registerFunction("isIpv6", &Netmask::isIpv6
);
162 d_lw
->registerFunction("getBits", &Netmask::getBits
);
163 d_lw
->registerFunction("toString", &Netmask::toString
);
164 d_lw
->registerFunction("empty", &Netmask::empty
);
165 d_lw
->registerFunction("match", (bool (Netmask::*)(const string
&) const)&Netmask::match
);
166 d_lw
->registerEqFunction(&Netmask::operator==);
167 d_lw
->registerToStringFunction(&Netmask::toString
);
170 d_lw
->writeFunction("newNMG", []() { return NetmaskGroup(); });
171 d_lw
->registerFunction
<void(NetmaskGroup::*)(const std::string
&mask
)>("addMask", [](NetmaskGroup
&nmg
, const std::string
& mask
) { nmg
.addMask(mask
); });
172 d_lw
->registerFunction
<void(NetmaskGroup::*)(const vector
<pair
<unsigned int, std::string
>>&)>("addMasks", [](NetmaskGroup
&nmg
, const vector
<pair
<unsigned int, std::string
>>& masks
) { for(const auto& mask
: masks
) { nmg
.addMask(mask
.second
); } });
173 d_lw
->registerFunction("match", (bool (NetmaskGroup::*)(const ComboAddress
&) const)&NetmaskGroup::match
);
176 d_lw
->writeFunction("newDR", [](const DNSName
&name
, const std::string
&type
, unsigned int ttl
, const std::string
&content
, int place
){ QType qtype
; qtype
= type
; auto dr
= DNSRecord(); dr
.d_name
= name
; dr
.d_type
= qtype
.getCode(); dr
.d_ttl
= ttl
; dr
.d_content
= shared_ptr
<DNSRecordContent
>(DNSRecordContent::mastermake(dr
.d_type
, 1, content
)); dr
.d_place
= static_cast<DNSResourceRecord::Place
>(place
); return dr
; });
177 d_lw
->registerMember("name", &DNSRecord::d_name
);
178 d_lw
->registerMember("type", &DNSRecord::d_type
);
179 d_lw
->registerMember("ttl", &DNSRecord::d_ttl
);
180 d_lw
->registerMember("place", &DNSRecord::d_place
);
181 d_lw
->registerFunction
<string(DNSRecord::*)()>("getContent", [](const DNSRecord
& dr
) { return dr
.d_content
->getZoneRepresentation(); });
182 d_lw
->registerFunction
<boost::optional
<ComboAddress
>(DNSRecord::*)()>("getCA", [](const DNSRecord
& dr
) {
183 boost::optional
<ComboAddress
> ret
;
185 if(auto arec
= std::dynamic_pointer_cast
<ARecordContent
>(dr
.d_content
))
187 else if(auto aaaarec
= std::dynamic_pointer_cast
<AAAARecordContent
>(dr
.d_content
))
188 ret
=aaaarec
->getCA(53);
191 d_lw
->registerFunction
<void(DNSRecord::*)(const std::string
&)>("changeContent", [](DNSRecord
& dr
, const std::string
& newContent
) { dr
.d_content
= shared_ptr
<DNSRecordContent
>(DNSRecordContent::mastermake(dr
.d_type
, 1, newContent
)); });
194 d_lw
->writeFunction("pdnslog", [](const std::string
& msg
, boost::optional
<int> loglevel
) { g_log
<< (Logger::Urgency
)loglevel
.get_value_or(Logger::Warning
) << msg
<<endl
; });
195 d_lw
->writeFunction("pdnsrandom", [](boost::optional
<uint32_t> maximum
) { return dns_random(maximum
.get_value_or(0xffffffff)); });
198 d_pd
.push_back({"PASS", (int)PolicyDecision::PASS
});
199 d_pd
.push_back({"DROP", (int)PolicyDecision::DROP
});
200 d_pd
.push_back({"TRUNCATE", (int)PolicyDecision::TRUNCATE
});
202 vector
<pair
<string
, int> > rcodes
= {{"NOERROR", RCode::NoError
},
203 {"FORMERR", RCode::FormErr
},
204 {"SERVFAIL", RCode::ServFail
},
205 {"NXDOMAIN", RCode::NXDomain
},
206 {"NOTIMP", RCode::NotImp
},
207 {"REFUSED", RCode::Refused
},
208 {"YXDOMAIN", RCode::YXDomain
},
209 {"YXRRSET", RCode::YXRRSet
},
210 {"NXRRSET", RCode::NXRRSet
},
211 {"NOTAUTH", RCode::NotAuth
},
212 {"NOTZONE", RCode::NotZone
}};
213 for(const auto& rcode
: rcodes
)
214 d_pd
.push_back({rcode
.first
, rcode
.second
});
216 d_pd
.push_back({"place", in_t
{
223 d_pd
.push_back({"loglevels", in_t
{
224 {"Alert", LOG_ALERT
},
225 {"Critical", LOG_CRIT
},
226 {"Debug", LOG_DEBUG
},
227 {"Emergency", LOG_EMERG
},
229 {"Notice", LOG_NOTICE
},
230 {"Warning", LOG_WARNING
},
234 for(const auto& n
: QType::names
)
235 d_pd
.push_back({n
.first
, n
.second
});
237 d_lw
->registerMember("tv_sec", &timeval::tv_sec
);
238 d_lw
->registerMember("tv_usec", &timeval::tv_usec
);
240 postPrepareContext();
242 // so we can let postprepare do changes to this
243 d_lw
->writeVariable("pdns", d_pd
);
246 void BaseLua4::loadStream(std::istream
&is
) {
247 d_lw
->executeCode(is
);
252 BaseLua4::~BaseLua4() { }