From 6907f014c93587855a49fce5bc77f5cca6a7ee35 Mon Sep 17 00:00:00 2001 From: bert hubert Date: Wed, 27 Jan 2016 12:34:34 +0100 Subject: [PATCH] implement mac address stuffing in dnsdist FOR QUERIES WITHOUT EDNS ALREADY. --- pdns/dnsdist-lua.cc | 5 +++++ pdns/dnsrulactions.hh | 45 +++++++++++++++++++++++++++++++++++++++++++ pdns/misc.cc | 26 +++++++++++++++++++++++++ pdns/misc.hh | 2 +- 4 files changed, 77 insertions(+), 1 deletion(-) diff --git a/pdns/dnsdist-lua.cc b/pdns/dnsdist-lua.cc index d05baf19d..62562ac29 100644 --- a/pdns/dnsdist-lua.cc +++ b/pdns/dnsdist-lua.cc @@ -536,6 +536,11 @@ vector> setupLua(bool client, const std::string& confi return std::shared_ptr(new NoRecurseAction); }); + g_lua.writeFunction("MacAddrAction", [](int code) { + return std::shared_ptr(new MacAddrAction(code)); + }); + + g_lua.writeFunction("PoolAction", [](const string& a) { return std::shared_ptr(new PoolAction(a)); }); diff --git a/pdns/dnsrulactions.hh b/pdns/dnsrulactions.hh index 5af45777f..b047d7beb 100644 --- a/pdns/dnsrulactions.hh +++ b/pdns/dnsrulactions.hh @@ -511,6 +511,51 @@ private: DNSName d_cname; }; +class MacAddrAction : public DNSAction +{ +public: + MacAddrAction(uint16_t code) : d_code(code) + {} + DNSAction::Action operator()(DNSQuestion* dq, string* ruleresult) const override + { + if(dq->dh->arcount) + return Action::None; + + char* dest = ((char*)dq->dh) + dq->len; + dnsrecordheader dh; + EDNS0Record edns0; + edns0.extRCode = 0; + edns0.version = 0; + edns0.Z = 0; + + dh.d_type = htons(QType::OPT); + dh.d_class = htons(1500); + memcpy(&dh.d_ttl, &edns0, sizeof edns0); + string optRData; + const uint16_t optionCode=htons(d_code), optionLen=htons(6); + optRData.append((const char*)&optionCode, 2); + optRData.append((const char*)&optionLen, 2); + string mac=getMACAddress(*dq->remote); + if(!mac.empty()) { + dq->dh->arcount=ntohs(1); + optRData.append(mac); + dh.d_clen = htons((uint16_t) optRData.length()); + uint8_t name=0; + string res((const char *) &name, sizeof name); + res.append((const char *) &dh, sizeof dh); + res.append(optRData.c_str(), optRData.length()); + memcpy(dest, res.c_str(), res.length()); + dq->len+=res.length(); + } + return Action::None; + } + string toString() const override + { + return "add EDNS MAC (code="+std::to_string(d_code)+")"; + } +private: + uint16_t d_code{3}; +}; class NoRecurseAction : public DNSAction { diff --git a/pdns/misc.cc b/pdns/misc.cc index b60eb6dc2..e4eb2d58a 100644 --- a/pdns/misc.cc +++ b/pdns/misc.cc @@ -1082,6 +1082,32 @@ bool setCloseOnExec(int sock) return true; } +string getMACAddress(const ComboAddress& ca) +{ + string ret; +#ifdef __linux__ + ifstream ifs("/proc/net/arp"); + if(!ifs) + return ret; + string line; + string match=ca.toString()+' '; + while(getline(ifs, line)) { + if(boost::starts_with(line, match)) { + vector parts; + stringtok(parts, line, " \n\t\r"); + if(parts.size() < 4) + return ret; + unsigned int tmp[6]; + sscanf(parts[3].c_str(), "%02x:%02x:%02x:%02x:%02x:%02x", tmp, tmp+1, tmp+2, tmp+3, tmp+4, tmp+5); + for(int i = 0 ; i< 6 ; ++i) + ret.append(1, (char)tmp[i]); + return ret; + } + } +#endif + return ret; +} + uint64_t udpErrorStats(const std::string& str) { #ifdef __linux__ diff --git a/pdns/misc.hh b/pdns/misc.hh index 51cae92f9..731c3df8c 100644 --- a/pdns/misc.hh +++ b/pdns/misc.hh @@ -609,7 +609,7 @@ uint64_t getRealMemoryUsage(const std::string&); uint64_t getOpenFileDescriptors(const std::string&); uint64_t getCPUTimeUser(const std::string&); uint64_t getCPUTimeSystem(const std::string&); - +std::string getMACAddress(const ComboAddress& ca); template std::unique_ptr make_unique(Args&&... args) { -- 2.40.0