Adding upstream version 1.0.2.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
a04160a00d
commit
36fe29e3d5
464 changed files with 372850 additions and 0 deletions
172
src/payload_file.cpp
Normal file
172
src/payload_file.cpp
Normal file
|
@ -0,0 +1,172 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, OARC, Inc.
|
||||
* Copyright (c) 2019, DENIC eG
|
||||
* All rights reserved.
|
||||
*
|
||||
* This file is part of dnsmeter.
|
||||
*
|
||||
* dnsmeter is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* dnsmeter is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with dnsmeter. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "payload_file.h"
|
||||
#include "exceptions.h"
|
||||
#include "query.h"
|
||||
|
||||
#define __FAVOR_BSD 1
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <pcap/pcap.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/udp.h>
|
||||
|
||||
#pragma pack(push) /* push current alignment to stack */
|
||||
#pragma pack(1) /* set alignment to 1 byte boundary */
|
||||
struct ETHER {
|
||||
unsigned char destination[6];
|
||||
unsigned char source[6];
|
||||
unsigned short type;
|
||||
};
|
||||
#pragma pack(pop) /* restore original alignment from stack */
|
||||
|
||||
PayloadFile::PayloadFile()
|
||||
{
|
||||
validLinesInQueryFile = 0;
|
||||
payloadIsPcap = false;
|
||||
}
|
||||
|
||||
bool PayloadFile::detectPcap(ppl7::File& ff)
|
||||
{
|
||||
unsigned char buffer[8];
|
||||
if (ff.read(buffer, 8) != 8) {
|
||||
ff.seek(0);
|
||||
return false;
|
||||
}
|
||||
ff.seek(0);
|
||||
unsigned int magic = ppl7::Peek32(buffer + 0);
|
||||
if (magic == 0xa1b2c3d4 || magic == 0xa1b23c4d)
|
||||
return true;
|
||||
if (magic == 0xd4c3b2a1 || magic == 0x4d3cb2a1)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void PayloadFile::openQueryFile(const ppl7::String& Filename)
|
||||
{
|
||||
if (Filename.isEmpty())
|
||||
throw InvalidQueryFile("File not given");
|
||||
ppl7::File QueryFile;
|
||||
QueryFile.open(Filename, ppl7::File::READ);
|
||||
if (QueryFile.size() == 0) {
|
||||
throw InvalidQueryFile("File is empty [%s]", (const char*)Filename);
|
||||
}
|
||||
printf("INFO: Loading and precompile payload. This could take some time...\n");
|
||||
if (detectPcap(QueryFile)) {
|
||||
loadAndCompilePcapFile(Filename);
|
||||
} else {
|
||||
loadAndCompile(QueryFile);
|
||||
}
|
||||
printf("INFO: %llu queries loaded\n", validLinesInQueryFile);
|
||||
it = querycache.begin();
|
||||
}
|
||||
|
||||
void PayloadFile::loadAndCompile(ppl7::File& ff)
|
||||
{
|
||||
ppl7::ByteArray buf(4096);
|
||||
ppl7::String buffer;
|
||||
validLinesInQueryFile = 0;
|
||||
unsigned char* compiled_query = (unsigned char*)buf.ptr();
|
||||
while (1) {
|
||||
try {
|
||||
if (ff.eof())
|
||||
throw ppl7::EndOfFileException();
|
||||
ff.gets(buffer, 1024);
|
||||
buffer.trim();
|
||||
if (buffer.isEmpty())
|
||||
continue;
|
||||
if (buffer.c_str()[0] == '#')
|
||||
continue;
|
||||
try {
|
||||
// Precompile Query
|
||||
int size = MakeQuery(buffer, compiled_query, 4096, false);
|
||||
querycache.push_back(ppl7::ByteArray(compiled_query, size));
|
||||
validLinesInQueryFile++;
|
||||
} catch (...) {
|
||||
// ignore invalid queries
|
||||
continue;
|
||||
}
|
||||
} catch (const ppl7::EndOfFileException&) {
|
||||
if (validLinesInQueryFile == 0) {
|
||||
throw InvalidQueryFile("No valid Queries found in Queryfile");
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PayloadFile::loadAndCompilePcapFile(const ppl7::String& Filename)
|
||||
{
|
||||
char errorbuffer[PCAP_ERRBUF_SIZE];
|
||||
struct pcap_pkthdr hdr;
|
||||
payloadIsPcap = true;
|
||||
validLinesInQueryFile = 0;
|
||||
pcap_t* pp = pcap_open_offline((const char*)Filename, errorbuffer);
|
||||
if (!pp)
|
||||
throw InvalidQueryFile("%s", errorbuffer);
|
||||
ppluint64 pkts_total = 0;
|
||||
const u_char* pkt;
|
||||
while ((pkt = pcap_next(pp, &hdr)) != NULL) {
|
||||
pkts_total++;
|
||||
//printf ("len=%d, caplen=%d\n",hdr.len,hdr.caplen);
|
||||
const struct ETHER* eth = (const struct ETHER*)pkt;
|
||||
if (hdr.caplen > 4096)
|
||||
continue;
|
||||
if (eth->type != htons(0x0800))
|
||||
continue;
|
||||
const struct ip* iphdr = (const struct ip*)(pkt + 14);
|
||||
if (iphdr->ip_v != 4)
|
||||
continue;
|
||||
const struct udphdr* udp = (const struct udphdr*)(pkt + 14 + sizeof(struct ip));
|
||||
if (udp->uh_dport != htons(53))
|
||||
continue;
|
||||
const struct DNS_HEADER* dns = (const struct DNS_HEADER*)(pkt + 14 + sizeof(struct ip) + sizeof(struct udphdr));
|
||||
if (dns->qr != 0 || dns->opcode != 0)
|
||||
continue;
|
||||
querycache.push_back(ppl7::ByteArray(pkt, hdr.caplen));
|
||||
validLinesInQueryFile++;
|
||||
}
|
||||
printf("Packets read from pcap file: %llu, valid UDP DNS queries: %llu\n",
|
||||
pkts_total, validLinesInQueryFile);
|
||||
pcap_close(pp);
|
||||
if (validLinesInQueryFile == 0) {
|
||||
throw InvalidQueryFile("No valid Queries found in pcap file [%s]", (const char*)Filename);
|
||||
}
|
||||
}
|
||||
|
||||
const ppl7::ByteArrayPtr& PayloadFile::getQuery()
|
||||
{
|
||||
QueryMutex.lock();
|
||||
const ppl7::ByteArrayPtr& bap = *it;
|
||||
++it;
|
||||
if (it == querycache.end())
|
||||
it = querycache.begin();
|
||||
QueryMutex.unlock();
|
||||
return bap;
|
||||
}
|
||||
|
||||
bool PayloadFile::isPcap()
|
||||
{
|
||||
return payloadIsPcap;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue