summaryrefslogtreecommitdiffstats
path: root/src/core/object
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/object')
-rw-r--r--src/core/object/dns.c471
-rw-r--r--src/core/object/dns.h184
-rw-r--r--src/core/object/dns.hh119
-rw-r--r--src/core/object/dns.lua797
-rw-r--r--src/core/object/dns/label.lua118
-rw-r--r--src/core/object/dns/q.lua52
-rw-r--r--src/core/object/dns/rr.lua85
-rw-r--r--src/core/object/ether.c45
-rw-r--r--src/core/object/ether.h38
-rw-r--r--src/core/object/ether.hh33
-rw-r--r--src/core/object/ether.lua78
-rw-r--r--src/core/object/gre.c45
-rw-r--r--src/core/object/gre.h38
-rw-r--r--src/core/object/gre.hh37
-rw-r--r--src/core/object/gre.lua87
-rw-r--r--src/core/object/icmp.c45
-rw-r--r--src/core/object/icmp.h38
-rw-r--r--src/core/object/icmp.hh33
-rw-r--r--src/core/object/icmp.lua78
-rw-r--r--src/core/object/icmp6.c45
-rw-r--r--src/core/object/icmp6.h38
-rw-r--r--src/core/object/icmp6.hh33
-rw-r--r--src/core/object/icmp6.lua78
-rw-r--r--src/core/object/ieee802.c45
-rw-r--r--src/core/object/ieee802.h38
-rw-r--r--src/core/object/ieee802.hh35
-rw-r--r--src/core/object/ieee802.lua84
-rw-r--r--src/core/object/ip.c45
-rw-r--r--src/core/object/ip.h38
-rw-r--r--src/core/object/ip.hh40
-rw-r--r--src/core/object/ip.lua122
-rw-r--r--src/core/object/ip6.c45
-rw-r--r--src/core/object/ip6.h42
-rw-r--r--src/core/object/ip6.hh42
-rw-r--r--src/core/object/ip6.lua130
-rw-r--r--src/core/object/linuxsll.c45
-rw-r--r--src/core/object/linuxsll.h38
-rw-r--r--src/core/object/linuxsll.hh35
-rw-r--r--src/core/object/linuxsll.lua84
-rw-r--r--src/core/object/loop.c45
-rw-r--r--src/core/object/loop.h38
-rw-r--r--src/core/object/loop.hh31
-rw-r--r--src/core/object/loop.lua72
-rw-r--r--src/core/object/null.c45
-rw-r--r--src/core/object/null.h38
-rw-r--r--src/core/object/null.hh31
-rw-r--r--src/core/object/null.lua72
-rw-r--r--src/core/object/payload.c50
-rw-r--r--src/core/object/payload.h38
-rw-r--r--src/core/object/payload.hh32
-rw-r--r--src/core/object/payload.lua83
-rw-r--r--src/core/object/pcap.c50
-rw-r--r--src/core/object/pcap.h38
-rw-r--r--src/core/object/pcap.hh38
-rw-r--r--src/core/object/pcap.lua98
-rw-r--r--src/core/object/tcp.c45
-rw-r--r--src/core/object/tcp.h39
-rw-r--r--src/core/object/tcp.hh43
-rw-r--r--src/core/object/tcp.lua110
-rw-r--r--src/core/object/udp.c45
-rw-r--r--src/core/object/udp.h38
-rw-r--r--src/core/object/udp.hh34
-rw-r--r--src/core/object/udp.lua86
63 files changed, 4762 insertions, 0 deletions
diff --git a/src/core/object/dns.c b/src/core/object/dns.c
new file mode 100644
index 0000000..49aec6d
--- /dev/null
+++ b/src/core/object/dns.c
@@ -0,0 +1,471 @@
+/*
+ * Copyright (c) 2018-2021, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of dnsjit.
+ *
+ * dnsjit 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.
+ *
+ * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "core/object/dns.h"
+#include "core/object/payload.h"
+#include "core/assert.h"
+
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_ENDIAN_H
+#include <endian.h>
+#else
+#ifdef HAVE_SYS_ENDIAN_H
+#include <sys/endian.h>
+#else
+#ifdef HAVE_MACHINE_ENDIAN_H
+#include <machine/endian.h>
+#endif
+#endif
+#endif
+#ifdef HAVE_BYTESWAP_H
+#include <byteswap.h>
+#endif
+#ifndef bswap_16
+#ifndef bswap16
+#define bswap_16(x) swap16(x)
+#define bswap_32(x) swap32(x)
+#define bswap_64(x) swap64(x)
+#else
+#define bswap_16(x) bswap16(x)
+#define bswap_32(x) bswap32(x)
+#define bswap_64(x) bswap64(x)
+#endif
+#endif
+
+#define _ERR_MALFORMED -2
+#define _ERR_NEEDLABELS -3
+
+static core_log_t _log = LOG_T_INIT("core.object.dns");
+static core_object_dns_t _defaults = CORE_OBJECT_DNS_INIT(0);
+
+static core_object_dns_label_t _defaults_label = { 0 };
+static core_object_dns_rr_t _defaults_rr = { 0 };
+static core_object_dns_q_t _defaults_q = { 0 };
+
+core_log_t* core_object_dns_log()
+{
+ return &_log;
+}
+
+core_object_dns_t* core_object_dns_new()
+{
+ core_object_dns_t* self;
+
+ mlfatal_oom(self = malloc(sizeof(core_object_dns_t)));
+ *self = _defaults;
+
+ return self;
+}
+
+core_object_dns_t* core_object_dns_copy(const core_object_dns_t* self)
+{
+ core_object_dns_t* copy;
+ mlassert_self();
+
+ mlfatal_oom(copy = malloc(sizeof(core_object_dns_t)));
+ memcpy(copy, self, sizeof(core_object_dns_t));
+ copy->obj_prev = 0;
+
+ return (core_object_dns_t*)copy;
+}
+
+void core_object_dns_free(core_object_dns_t* self)
+{
+ mlassert_self();
+ free(self);
+}
+
+#define need8(v, p, l) \
+ if (l < 1) { \
+ break; \
+ } \
+ v = *p; \
+ p += 1; \
+ l -= 1
+
+static inline uint16_t _need16(const void* ptr)
+{
+ uint16_t v;
+ memcpy(&v, ptr, sizeof(v));
+ return be16toh(v);
+}
+
+#define need16(v, p, l) \
+ if (l < 2) { \
+ break; \
+ } \
+ v = _need16(p); \
+ p += 2; \
+ l -= 2
+
+static inline uint32_t _need32(const void* ptr)
+{
+ uint32_t v;
+ memcpy(&v, ptr, sizeof(v));
+ return be32toh(v);
+}
+
+#define need32(v, p, l) \
+ if (l < 4) { \
+ break; \
+ } \
+ v = _need32(p); \
+ p += 4; \
+ l -= 4
+
+#define needxb(b, x, p, l) \
+ if (l < x) { \
+ break; \
+ } \
+ memcpy(b, p, x); \
+ p += x; \
+ l -= x
+
+#define advancexb(x, p, l) \
+ if (l < x) { \
+ break; \
+ } \
+ p += x; \
+ l -= x
+
+int core_object_dns_parse_header(core_object_dns_t* self)
+{
+ const core_object_payload_t* payload;
+ uint8_t byte;
+ mlassert_self();
+
+ if (!(payload = (core_object_payload_t*)self->obj_prev) || payload->obj_type != CORE_OBJECT_PAYLOAD) {
+ mlfatal("no obj_prev or invalid type");
+ }
+ if (!payload->payload || !payload->len) {
+ mlfatal("no payload set or zero length");
+ }
+
+ self->payload = self->at = payload->payload;
+ self->len = self->left = payload->len;
+
+ for (;;) {
+ if (self->includes_dnslen) {
+ need16(self->dnslen, self->at, self->left);
+ self->have_dnslen = 1;
+ }
+ need16(self->id, self->at, self->left);
+ self->have_id = 1;
+
+ need8(byte, self->at, self->left);
+ self->qr = byte & (1 << 7) ? 1 : 0;
+ self->opcode = (byte >> 3) & 0xf;
+ self->aa = byte & (1 << 2) ? 1 : 0;
+ self->tc = byte & (1 << 1) ? 1 : 0;
+ self->rd = byte & (1 << 0) ? 1 : 0;
+ self->have_qr = self->have_opcode = self->have_aa = self->have_tc = self->have_rd = 1;
+
+ need8(byte, self->at, self->left);
+ self->ra = byte & (1 << 7) ? 1 : 0;
+ self->z = byte & (1 << 6) ? 1 : 0;
+ self->ad = byte & (1 << 5) ? 1 : 0;
+ self->cd = byte & (1 << 4) ? 1 : 0;
+ self->rcode = byte & 0xf;
+ self->have_ra = self->have_z = self->have_ad = self->have_cd = self->have_rcode = 1;
+
+ need16(self->qdcount, self->at, self->left);
+ self->have_qdcount = 1;
+
+ need16(self->ancount, self->at, self->left);
+ self->have_ancount = 1;
+
+ need16(self->nscount, self->at, self->left);
+ self->have_nscount = 1;
+
+ need16(self->arcount, self->at, self->left);
+ self->have_arcount = 1;
+
+ return 0;
+ }
+
+ // TODO: error here on malformed/truncated? could be quite spammy
+ return _ERR_MALFORMED;
+}
+
+static inline size_t _rdata_labels(uint16_t type)
+{
+ switch (type) {
+ case CORE_OBJECT_DNS_TYPE_NS:
+ case CORE_OBJECT_DNS_TYPE_MD:
+ case CORE_OBJECT_DNS_TYPE_MF:
+ case CORE_OBJECT_DNS_TYPE_CNAME:
+ case CORE_OBJECT_DNS_TYPE_MB:
+ case CORE_OBJECT_DNS_TYPE_MG:
+ case CORE_OBJECT_DNS_TYPE_MR:
+ case CORE_OBJECT_DNS_TYPE_PTR:
+ case CORE_OBJECT_DNS_TYPE_NXT:
+ case CORE_OBJECT_DNS_TYPE_DNAME:
+ case CORE_OBJECT_DNS_TYPE_NSEC:
+ case CORE_OBJECT_DNS_TYPE_TKEY:
+ case CORE_OBJECT_DNS_TYPE_TSIG:
+ return 1;
+
+ case CORE_OBJECT_DNS_TYPE_SOA:
+ case CORE_OBJECT_DNS_TYPE_MINFO:
+ case CORE_OBJECT_DNS_TYPE_RP:
+ case CORE_OBJECT_DNS_TYPE_TALINK:
+ return 2;
+
+ case CORE_OBJECT_DNS_TYPE_MX:
+ case CORE_OBJECT_DNS_TYPE_AFSDB:
+ case CORE_OBJECT_DNS_TYPE_RT:
+ case CORE_OBJECT_DNS_TYPE_KX:
+ case CORE_OBJECT_DNS_TYPE_LP:
+ return 1;
+
+ case CORE_OBJECT_DNS_TYPE_PX:
+ return 2;
+
+ case CORE_OBJECT_DNS_TYPE_SIG:
+ case CORE_OBJECT_DNS_TYPE_RRSIG:
+ return 1;
+
+ case CORE_OBJECT_DNS_TYPE_SRV:
+ return 1;
+
+ case CORE_OBJECT_DNS_TYPE_NAPTR:
+ return 1;
+
+ case CORE_OBJECT_DNS_TYPE_HIP:
+ return 1;
+
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static inline size_t _label(core_object_dns_t* self, core_object_dns_label_t* label, size_t labels)
+{
+ size_t n;
+
+ for (n = 0; self->left && n < labels; n++) {
+ core_object_dns_label_t* l = &label[n];
+ *l = _defaults_label;
+
+ need8(l->length, self->at, self->left);
+
+ if ((l->length & 0xc0) == 0xc0) {
+ need8(l->offset, self->at, self->left);
+ l->offset |= (l->length & 0x3f) << 8;
+ l->have_offset = 1;
+ return n;
+ } else if (l->length & 0xc0) {
+ l->extension_bits = l->length >> 6;
+ l->have_extension_bits = 1;
+ return n;
+ } else if (l->length) {
+ l->have_length = 1;
+
+ l->offset = self->at - self->payload - 1;
+ advancexb(l->length, self->at, self->left);
+ l->have_dn = 1;
+ } else {
+ l->is_end = 1;
+ return n;
+ }
+ }
+
+ return n;
+}
+
+int core_object_dns_parse_q(core_object_dns_t* self, core_object_dns_q_t* q, core_object_dns_label_t* label, size_t labels)
+{
+ mlassert_self();
+ mlassert(q, "q is nil");
+ mlassert(label, "label is nil");
+ mlassert(labels, "labels is zero");
+ mlassert(self->at, "at is nil");
+
+ for (;;) {
+ *q = _defaults_q;
+ q->labels = _label(self, label, labels);
+ if (q->labels < labels) {
+ core_object_dns_label_t* l = &label[q->labels];
+ if (!(l->have_offset | l->have_extension_bits | l->is_end)) {
+ // TODO: error here on malformed/truncated? could be quite spammy
+ return _ERR_MALFORMED;
+ }
+ } else {
+ mlwarning("need more labels, aborting DNS parsing");
+ return _ERR_NEEDLABELS;
+ }
+ q->labels++;
+
+ need16(q->type, self->at, self->left);
+ q->have_type = 1;
+
+ need16(q->class, self->at, self->left);
+ q->have_class = 1;
+
+ return 0;
+ }
+
+ // TODO: error here on malformed/truncated? could be quite spammy
+ return _ERR_MALFORMED;
+}
+
+int core_object_dns_parse_rr(core_object_dns_t* self, core_object_dns_rr_t* rr, core_object_dns_label_t* label, size_t labels)
+{
+ size_t rdata_label_sets;
+ mlassert_self();
+ mlassert(rr, "rr is nil");
+ mlassert(label, "label is nil");
+ mlassert(labels, "labels is zero");
+ mlassert(self->at, "at is nil");
+
+ for (;;) {
+ *rr = _defaults_rr;
+ rr->labels = _label(self, label, labels);
+ if (rr->labels < labels) {
+ core_object_dns_label_t* l = &label[rr->labels];
+ if (!(l->have_offset | l->have_extension_bits | l->is_end)) {
+ // TODO: error here on malformed/truncated? could be quite spammy
+ return _ERR_MALFORMED;
+ }
+ } else {
+ mlwarning("need more labels, aborting DNS parsing");
+ return _ERR_NEEDLABELS;
+ }
+ rr->labels++;
+
+ need16(rr->type, self->at, self->left);
+ rr->have_type = 1;
+
+ need16(rr->class, self->at, self->left);
+ rr->have_class = 1;
+
+ need32(rr->ttl, self->at, self->left);
+ rr->have_ttl = 1;
+
+ need16(rr->rdlength, self->at, self->left);
+ rr->have_rdlength = 1;
+
+ rr->rdata_offset = self->at - self->payload;
+ if (!(rdata_label_sets = _rdata_labels(rr->type))) {
+ advancexb(rr->rdlength, self->at, self->left);
+ rr->have_rdata = 1;
+ return 0;
+ }
+
+ switch (rr->type) {
+ case CORE_OBJECT_DNS_TYPE_MX:
+ case CORE_OBJECT_DNS_TYPE_AFSDB:
+ case CORE_OBJECT_DNS_TYPE_RT:
+ case CORE_OBJECT_DNS_TYPE_KX:
+ case CORE_OBJECT_DNS_TYPE_LP:
+ case CORE_OBJECT_DNS_TYPE_PX:
+ advancexb(2, self->at, self->left);
+ break;
+
+ case CORE_OBJECT_DNS_TYPE_SIG:
+ case CORE_OBJECT_DNS_TYPE_RRSIG:
+ advancexb(18, self->at, self->left);
+ break;
+
+ case CORE_OBJECT_DNS_TYPE_SRV:
+ advancexb(6, self->at, self->left);
+ break;
+
+ case CORE_OBJECT_DNS_TYPE_NAPTR: {
+ uint8_t naptr_length;
+
+ advancexb(4, self->at, self->left);
+ need8(naptr_length, self->at, self->left);
+ advancexb(naptr_length, self->at, self->left);
+ need8(naptr_length, self->at, self->left);
+ advancexb(naptr_length, self->at, self->left);
+ need8(naptr_length, self->at, self->left);
+ advancexb(naptr_length, self->at, self->left);
+ } break;
+
+ case CORE_OBJECT_DNS_TYPE_HIP: {
+ uint8_t hit_length;
+ uint16_t pk_length;
+
+ need8(hit_length, self->at, self->left);
+ advancexb(1, self->at, self->left);
+ need16(pk_length, self->at, self->left);
+ advancexb(hit_length, self->at, self->left);
+ advancexb(pk_length, self->at, self->left);
+
+ if (self->at - self->payload >= rr->rdata_offset + rr->rdlength) {
+ rdata_label_sets = 0;
+ }
+ } break;
+ }
+
+ while (rdata_label_sets) {
+ rr->rdata_labels += _label(self, &label[rr->labels + rr->rdata_labels], labels - rr->labels - rr->rdata_labels);
+ if (rr->labels + rr->rdata_labels < labels) {
+ core_object_dns_label_t* l = &label[rr->labels + rr->rdata_labels];
+ if (!(l->have_offset | l->have_extension_bits | l->is_end)) {
+ // TODO: error here on malformed/truncated? could be quite spammy
+ return _ERR_MALFORMED;
+ }
+ } else {
+ mlwarning("need more labels, aborting DNS parsing");
+ return _ERR_NEEDLABELS;
+ }
+ rr->rdata_labels++;
+
+ if (rr->type == CORE_OBJECT_DNS_TYPE_HIP && self->at - self->payload < rr->rdata_offset + rr->rdlength) {
+ continue;
+ }
+
+ rdata_label_sets--;
+ }
+
+ if (self->at - self->payload < rr->rdata_offset + rr->rdlength) {
+ rr->padding_offset = self->at - self->payload;
+ rr->padding_length = rr->rdlength - (rr->padding_offset - rr->rdata_offset);
+
+ advancexb(rr->padding_length, self->at, self->left);
+
+ /*
+ * TODO:
+ *
+ * This can indicate padding but we do not set that we have padding
+ * yet because we need to fully understand all record types before
+ * that and process valid data after the labels
+ *
+ rr->have_padding = 1;
+ */
+ } else if (self->at - self->payload > rr->rdata_offset + rr->rdlength) {
+ // TODO: error here on malformed/truncated? could be quite spammy
+ return _ERR_MALFORMED;
+ }
+ rr->have_rdata = 1;
+
+ return 0;
+ }
+
+ // TODO: error here on malformed/truncated? could be quite spammy
+ return _ERR_MALFORMED;
+}
diff --git a/src/core/object/dns.h b/src/core/object/dns.h
new file mode 100644
index 0000000..5fbaf53
--- /dev/null
+++ b/src/core/object/dns.h
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 2018-2021, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of dnsjit.
+ *
+ * dnsjit 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.
+ *
+ * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "core/log.h"
+#include "core/object.h"
+
+#ifndef __dnsjit_core_object_dns_h
+#define __dnsjit_core_object_dns_h
+
+#include <netinet/in.h>
+#include <sys/types.h>
+
+#include "core/object/dns.hh"
+
+#define CORE_OBJECT_DNS_INIT(prev) \
+ { \
+ CORE_OBJECT_INIT(CORE_OBJECT_DNS, prev) \
+ , \
+ 0, 0, 0, 0, 0, \
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+ }
+
+/*
+ * 2016-12-09 https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml
+ */
+
+#define CORE_OBJECT_DNS_CLASS_IN 1
+#define CORE_OBJECT_DNS_CLASS_CH 3
+#define CORE_OBJECT_DNS_CLASS_HS 4
+#define CORE_OBJECT_DNS_CLASS_NONE 254
+#define CORE_OBJECT_DNS_CLASS_ANY 255
+
+#define CORE_OBJECT_DNS_TYPE_A 1
+#define CORE_OBJECT_DNS_TYPE_NS 2
+#define CORE_OBJECT_DNS_TYPE_MD 3
+#define CORE_OBJECT_DNS_TYPE_MF 4
+#define CORE_OBJECT_DNS_TYPE_CNAME 5
+#define CORE_OBJECT_DNS_TYPE_SOA 6
+#define CORE_OBJECT_DNS_TYPE_MB 7
+#define CORE_OBJECT_DNS_TYPE_MG 8
+#define CORE_OBJECT_DNS_TYPE_MR 9
+#define CORE_OBJECT_DNS_TYPE_NULL 10
+#define CORE_OBJECT_DNS_TYPE_WKS 11
+#define CORE_OBJECT_DNS_TYPE_PTR 12
+#define CORE_OBJECT_DNS_TYPE_HINFO 13
+#define CORE_OBJECT_DNS_TYPE_MINFO 14
+#define CORE_OBJECT_DNS_TYPE_MX 15
+#define CORE_OBJECT_DNS_TYPE_TXT 16
+#define CORE_OBJECT_DNS_TYPE_RP 17
+#define CORE_OBJECT_DNS_TYPE_AFSDB 18
+#define CORE_OBJECT_DNS_TYPE_X25 19
+#define CORE_OBJECT_DNS_TYPE_ISDN 20
+#define CORE_OBJECT_DNS_TYPE_RT 21
+#define CORE_OBJECT_DNS_TYPE_NSAP 22
+#define CORE_OBJECT_DNS_TYPE_NSAP_PTR 23
+#define CORE_OBJECT_DNS_TYPE_SIG 24
+#define CORE_OBJECT_DNS_TYPE_KEY 25
+#define CORE_OBJECT_DNS_TYPE_PX 26
+#define CORE_OBJECT_DNS_TYPE_GPOS 27
+#define CORE_OBJECT_DNS_TYPE_AAAA 28
+#define CORE_OBJECT_DNS_TYPE_LOC 29
+#define CORE_OBJECT_DNS_TYPE_NXT 30
+#define CORE_OBJECT_DNS_TYPE_EID 31
+#define CORE_OBJECT_DNS_TYPE_NIMLOC 32
+#define CORE_OBJECT_DNS_TYPE_SRV 33
+#define CORE_OBJECT_DNS_TYPE_ATMA 34
+#define CORE_OBJECT_DNS_TYPE_NAPTR 35
+#define CORE_OBJECT_DNS_TYPE_KX 36
+#define CORE_OBJECT_DNS_TYPE_CERT 37
+#define CORE_OBJECT_DNS_TYPE_A6 38
+#define CORE_OBJECT_DNS_TYPE_DNAME 39
+#define CORE_OBJECT_DNS_TYPE_SINK 40
+#define CORE_OBJECT_DNS_TYPE_OPT 41
+#define CORE_OBJECT_DNS_TYPE_APL 42
+#define CORE_OBJECT_DNS_TYPE_DS 43
+#define CORE_OBJECT_DNS_TYPE_SSHFP 44
+#define CORE_OBJECT_DNS_TYPE_IPSECKEY 45
+#define CORE_OBJECT_DNS_TYPE_RRSIG 46
+#define CORE_OBJECT_DNS_TYPE_NSEC 47
+#define CORE_OBJECT_DNS_TYPE_DNSKEY 48
+#define CORE_OBJECT_DNS_TYPE_DHCID 49
+#define CORE_OBJECT_DNS_TYPE_NSEC3 50
+#define CORE_OBJECT_DNS_TYPE_NSEC3PARAM 51
+#define CORE_OBJECT_DNS_TYPE_TLSA 52
+#define CORE_OBJECT_DNS_TYPE_SMIMEA 53
+#define CORE_OBJECT_DNS_TYPE_HIP 55
+#define CORE_OBJECT_DNS_TYPE_NINFO 56
+#define CORE_OBJECT_DNS_TYPE_RKEY 57
+#define CORE_OBJECT_DNS_TYPE_TALINK 58
+#define CORE_OBJECT_DNS_TYPE_CDS 59
+#define CORE_OBJECT_DNS_TYPE_CDNSKEY 60
+#define CORE_OBJECT_DNS_TYPE_OPENPGPKEY 61
+#define CORE_OBJECT_DNS_TYPE_CSYNC 62
+#define CORE_OBJECT_DNS_TYPE_SPF 99
+#define CORE_OBJECT_DNS_TYPE_UINFO 100
+#define CORE_OBJECT_DNS_TYPE_UID 101
+#define CORE_OBJECT_DNS_TYPE_GID 102
+#define CORE_OBJECT_DNS_TYPE_UNSPEC 103
+#define CORE_OBJECT_DNS_TYPE_NID 104
+#define CORE_OBJECT_DNS_TYPE_L32 105
+#define CORE_OBJECT_DNS_TYPE_L64 106
+#define CORE_OBJECT_DNS_TYPE_LP 107
+#define CORE_OBJECT_DNS_TYPE_EUI48 108
+#define CORE_OBJECT_DNS_TYPE_EUI64 109
+#define CORE_OBJECT_DNS_TYPE_TKEY 249
+#define CORE_OBJECT_DNS_TYPE_TSIG 250
+#define CORE_OBJECT_DNS_TYPE_IXFR 251
+#define CORE_OBJECT_DNS_TYPE_AXFR 252
+#define CORE_OBJECT_DNS_TYPE_MAILB 253
+#define CORE_OBJECT_DNS_TYPE_MAILA 254
+#define CORE_OBJECT_DNS_TYPE_ANY 255
+#define CORE_OBJECT_DNS_TYPE_URI 256
+#define CORE_OBJECT_DNS_TYPE_CAA 257
+#define CORE_OBJECT_DNS_TYPE_AVC 258
+#define CORE_OBJECT_DNS_TYPE_TA 32768
+#define CORE_OBJECT_DNS_TYPE_DLV 32769
+
+#define CORE_OBJECT_DNS_OPCODE_QUERY 0
+#define CORE_OBJECT_DNS_OPCODE_IQUERY 1
+#define CORE_OBJECT_DNS_OPCODE_STATUS 2
+#define CORE_OBJECT_DNS_OPCODE_NOTIFY 4
+#define CORE_OBJECT_DNS_OPCODE_UPDATE 5
+
+#define CORE_OBJECT_DNS_RCODE_NOERROR 0
+#define CORE_OBJECT_DNS_RCODE_FORMERR 1
+#define CORE_OBJECT_DNS_RCODE_SERVFAIL 2
+#define CORE_OBJECT_DNS_RCODE_NXDOMAIN 3
+#define CORE_OBJECT_DNS_RCODE_NOTIMP 4
+#define CORE_OBJECT_DNS_RCODE_REFUSED 5
+#define CORE_OBJECT_DNS_RCODE_YXDOMAIN 6
+#define CORE_OBJECT_DNS_RCODE_YXRRSET 7
+#define CORE_OBJECT_DNS_RCODE_NXRRSET 8
+#define CORE_OBJECT_DNS_RCODE_NOTAUTH 9
+#define CORE_OBJECT_DNS_RCODE_NOTZONE 10
+#define CORE_OBJECT_DNS_RCODE_BADVERS 16
+#define CORE_OBJECT_DNS_RCODE_BADSIG 16
+#define CORE_OBJECT_DNS_RCODE_BADKEY 17
+#define CORE_OBJECT_DNS_RCODE_BADTIME 18
+#define CORE_OBJECT_DNS_RCODE_BADMODE 19
+#define CORE_OBJECT_DNS_RCODE_BADNAME 20
+#define CORE_OBJECT_DNS_RCODE_BADALG 21
+#define CORE_OBJECT_DNS_RCODE_BADTRUNC 22
+#define CORE_OBJECT_DNS_RCODE_BADCOOKIE 23
+
+#define CORE_OBJECT_DNS_AFSDB_SUBTYPE_AFS3LOCSRV 1
+#define CORE_OBJECT_DNS_AFSDB_SUBTYPE_DCENCA_ROOT 2
+
+#define CORE_OBJECT_DNS_DHCID_TYPE_1OCTET 0
+#define CORE_OBJECT_DNS_DHCID_TYPE_DATAOCTET 1
+#define CORE_OBJECT_DNS_DHCID_TYPE_CLIENT_DUID 2
+
+#define CORE_OBJECT_DNS_EDNS0_OPT_LLQ 1
+#define CORE_OBJECT_DNS_EDNS0_OPT_UL 2
+#define CORE_OBJECT_DNS_EDNS0_OPT_NSID 3
+#define CORE_OBJECT_DNS_EDNS0_OPT_DAU 5
+#define CORE_OBJECT_DNS_EDNS0_OPT_DHU 6
+#define CORE_OBJECT_DNS_EDNS0_OPT_N3U 7
+#define CORE_OBJECT_DNS_EDNS0_OPT_CLIENT_SUBNET 8
+#define CORE_OBJECT_DNS_EDNS0_OPT_EXPIRE 9
+#define CORE_OBJECT_DNS_EDNS0_OPT_COOKIE 10
+#define CORE_OBJECT_DNS_EDNS0_OPT_TCP_KEEPALIVE 11
+#define CORE_OBJECT_DNS_EDNS0_OPT_PADDING 12
+#define CORE_OBJECT_DNS_EDNS0_OPT_CHAIN 13
+#define CORE_OBJECT_DNS_EDNS0_OPT_DEVICEID 26946
+
+#endif
diff --git a/src/core/object/dns.hh b/src/core/object/dns.hh
new file mode 100644
index 0000000..dfe9719
--- /dev/null
+++ b/src/core/object/dns.hh
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2018-2021, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of dnsjit.
+ *
+ * dnsjit 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.
+ *
+ * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+//lua:require("dnsjit.core.log")
+//lua:require("dnsjit.core.object_h")
+
+typedef struct core_object_dns_label {
+ uint8_t is_end;
+ uint8_t have_length;
+ uint8_t have_offset;
+ uint8_t have_extension_bits;
+ uint8_t have_dn;
+ uint8_t extension_bits;
+
+ uint8_t length;
+ uint16_t offset;
+} core_object_dns_label_t;
+
+typedef struct core_object_dns_rr {
+ uint8_t have_type;
+ uint8_t have_class;
+ uint8_t have_ttl;
+ uint8_t have_rdlength;
+ uint8_t have_rdata;
+ uint8_t have_rdata_labels;
+ uint8_t have_padding;
+
+ uint16_t type;
+ uint16_t class;
+ uint32_t ttl;
+ uint16_t rdlength;
+
+ size_t labels;
+ size_t rdata_offset;
+ size_t rdata_labels;
+ size_t padding_offset;
+ size_t padding_length;
+} core_object_dns_rr_t;
+
+typedef struct core_object_dns_q {
+ uint8_t have_type;
+ uint8_t have_class;
+
+ uint16_t type;
+ uint16_t class;
+
+ size_t labels;
+} core_object_dns_q_t;
+
+typedef struct core_object_dns {
+ const core_object_t* obj_prev;
+ int32_t obj_type;
+
+ int includes_dnslen;
+ const uint8_t *payload, *at;
+ size_t len, left;
+
+ uint8_t have_dnslen;
+ uint8_t have_id;
+ uint8_t have_qr;
+ uint8_t have_opcode;
+ uint8_t have_aa;
+ uint8_t have_tc;
+ uint8_t have_rd;
+ uint8_t have_ra;
+ uint8_t have_z;
+ uint8_t have_ad;
+ uint8_t have_cd;
+ uint8_t have_rcode;
+ uint8_t have_qdcount;
+ uint8_t have_ancount;
+ uint8_t have_nscount;
+ uint8_t have_arcount;
+
+ uint16_t dnslen;
+ uint16_t id;
+ int8_t qr;
+ uint8_t opcode;
+ uint8_t aa;
+ uint8_t tc;
+ uint8_t rd;
+ uint8_t ra;
+ uint8_t z;
+ uint8_t ad;
+ uint8_t cd;
+ uint8_t rcode;
+ uint16_t qdcount;
+ uint16_t ancount;
+ uint16_t nscount;
+ uint16_t arcount;
+} core_object_dns_t;
+
+core_log_t* core_object_dns_log();
+
+core_object_dns_t* core_object_dns_new();
+core_object_dns_t* core_object_dns_copy(const core_object_dns_t* self);
+void core_object_dns_free(core_object_dns_t* self);
+void core_object_dns_reset(core_object_dns_t* self, const core_object_t* obj);
+
+int core_object_dns_parse_header(core_object_dns_t* self);
+int core_object_dns_parse_q(core_object_dns_t* self, core_object_dns_q_t* q, core_object_dns_label_t* label, size_t labels);
+int core_object_dns_parse_rr(core_object_dns_t* self, core_object_dns_rr_t* rr, core_object_dns_label_t* label, size_t labels);
diff --git a/src/core/object/dns.lua b/src/core/object/dns.lua
new file mode 100644
index 0000000..e8fb12b
--- /dev/null
+++ b/src/core/object/dns.lua
@@ -0,0 +1,797 @@
+-- Copyright (c) 2018-2021, OARC, Inc.
+-- All rights reserved.
+--
+-- This file is part of dnsjit.
+--
+-- dnsjit 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.
+--
+-- dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+
+-- dnsjit.core.object.dns
+-- Container of a DNS message
+-- .SS Parse DNS header and check if query or response
+-- local dns = require("dnsjit.core.object.dns").new(payload)
+-- if dns:parse_header() == 0 then
+-- if dns.qr == 0 then
+-- print(dns.id, dns.opcode_tostring(dns.opcode))
+-- else
+-- print(dns.id, dns.rcode_tostring(dns.rcode))
+-- end
+-- end
+-- .SS Print a DNS payload
+-- local dns = require("dnsjit.core.object.dns").new(payload)
+-- dns:print()
+-- .SS Parse a DNS payload
+-- local dns = require("dnsjit.core.object.dns").new(payload)
+-- local qs, q_labels, rrs, rr_labels = dns:parse()
+-- if qs and q_labels then
+-- ...
+-- if rrs and rr_labels then
+-- ...
+-- end
+-- end
+--
+-- The object that describes a DNS message.
+-- .SS Attributes
+-- .TP
+-- includes_dnslen
+-- If non-zero then this indicates that the DNS length is included in the
+-- payload (for example if the transport is TCP) and will affect parsing of it.
+-- .TP
+-- have_dnslen
+-- Set if the dnslen was included in the payload and could be read.
+-- .TP
+-- have_id
+-- Set if there is a DNS ID.
+-- .TP
+-- have_qr
+-- Set if there is a QR flag.
+-- .TP
+-- have_opcode
+-- Set if there is an OPCODE.
+-- .TP
+-- have_aa
+-- Set if there is a AA flag.
+-- .TP
+-- have_tc
+-- Set if there is a TC flag.
+-- .TP
+-- have_rd
+-- Set if there is a RD flag.
+-- .TP
+-- have_ra
+-- Set if there is a RA flag.
+-- .TP
+-- have_z
+-- Set if there is a Z flag.
+-- .TP
+-- have_ad
+-- Set if there is a AD flag.
+-- .TP
+-- have_cd
+-- Set if there is a CD flag.
+-- .TP
+-- have_rcode
+-- Set if there is a RCODE.
+-- .TP
+-- have_qdcount
+-- Set if there is an QDCOUNT.
+-- .TP
+-- have_ancount
+-- Set if there is an ANCOUNT.
+-- .TP
+-- have_nscount
+-- Set if there is a NSCOUNT.
+-- .TP
+-- have_arcount
+-- Set if there is an ARCOUNT.
+-- .TP
+-- dnslen
+-- The DNS length found in the payload.
+-- .TP
+-- id
+-- The DNS ID.
+-- .TP
+-- qr
+-- The QR flag.
+-- .TP
+-- opcode
+-- The OPCODE.
+-- .TP
+-- aa
+-- The AA flag.
+-- .TP
+-- tc
+-- The TC flag.
+-- .TP
+-- rd
+-- The RD flag.
+-- .TP
+-- ra
+-- The RA flag.
+-- .TP
+-- z
+-- The Z flag.
+-- .TP
+-- ad
+-- The AD flag.
+-- .TP
+-- cd
+-- The CD flag.
+-- .TP
+-- rcode
+-- The RCODE.
+-- .TP
+-- qdcount
+-- The QDCOUNT.
+-- .TP
+-- ancount
+-- The ANCOUNT.
+-- .TP
+-- nscount
+-- The NSCOUNT.
+-- .TP
+-- arcount
+-- The ARCOUNT.
+-- .SS Constants
+-- The following tables exists for DNS parameters, taken from
+-- .I https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml
+-- on the 2016-12-09.
+-- .LP
+-- .IR CLASS ,
+-- .IR CLASS_STR ,
+-- .IR TYPE ,
+-- .IR TYPE_STR ,
+-- .IR OPCODE ,
+-- .IR OPCODE_STR ,
+-- .IR RCODE ,
+-- .IR RCODE_STR ,
+-- .IR AFSDB ,
+-- .IR AFSDB_STR ,
+-- .IR DHCID ,
+-- .IR DHCID_STR ,
+-- .IR ENDS0 ,
+-- .IR ENDS0_STR
+-- .LP
+-- The
+-- .I *_STR
+-- tables can be used to get a textual representation of the numbers, see also
+-- .IR class_tostring() ,
+-- .IR type_tostring() ,
+-- .IR opcode_tostring() ,
+-- .IR rcode_tostring() ,
+-- .IR afsdb_tostring() ,
+-- .I dhcid_tostring()
+-- and
+-- .IR edns0_tostring() .
+module(...,package.seeall)
+
+require("dnsjit.core.object.dns_h")
+local label = require("dnsjit.core.object.dns.label")
+local Q = require("dnsjit.core.object.dns.q")
+local RR = require("dnsjit.core.object.dns.rr")
+local ffi = require("ffi")
+local C = ffi.C
+
+local t_name = "core_object_dns_t"
+local core_object_dns_t
+local Dns = {
+ CLASS = {
+ IN = 1,
+ CH = 3,
+ HS = 4,
+ NONE = 254,
+ ANY = 255,
+ },
+ TYPE = {
+ A = 1,
+ NS = 2,
+ MD = 3,
+ MF = 4,
+ CNAME = 5,
+ SOA = 6,
+ MB = 7,
+ MG = 8,
+ MR = 9,
+ NULL = 10,
+ WKS = 11,
+ PTR = 12,
+ HINFO = 13,
+ MINFO = 14,
+ MX = 15,
+ TXT = 16,
+ RP = 17,
+ AFSDB = 18,
+ X25 = 19,
+ ISDN = 20,
+ RT = 21,
+ NSAP = 22,
+ NSAP_PTR = 23,
+ SIG = 24,
+ KEY = 25,
+ PX = 26,
+ GPOS = 27,
+ AAAA = 28,
+ LOC = 29,
+ NXT = 30,
+ EID = 31,
+ NIMLOC = 32,
+ SRV = 33,
+ ATMA = 34,
+ NAPTR = 35,
+ KX = 36,
+ CERT = 37,
+ A6 = 38,
+ DNAME = 39,
+ SINK = 40,
+ OPT = 41,
+ APL = 42,
+ DS = 43,
+ SSHFP = 44,
+ IPSECKEY = 45,
+ RRSIG = 46,
+ NSEC = 47,
+ DNSKEY = 48,
+ DHCID = 49,
+ NSEC3 = 50,
+ NSEC3PARAM = 51,
+ TLSA = 52,
+ SMIMEA = 53,
+ HIP = 55,
+ NINFO = 56,
+ RKEY = 57,
+ TALINK = 58,
+ CDS = 59,
+ CDNSKEY = 60,
+ OPENPGPKEY = 61,
+ CSYNC = 62,
+ SPF = 99,
+ UINFO = 100,
+ UID = 101,
+ GID = 102,
+ UNSPEC = 103,
+ NID = 104,
+ L32 = 105,
+ L64 = 106,
+ LP = 107,
+ EUI48 = 108,
+ EUI64 = 109,
+ TKEY = 249,
+ TSIG = 250,
+ IXFR = 251,
+ AXFR = 252,
+ MAILB = 253,
+ MAILA = 254,
+ ANY = 255,
+ URI = 256,
+ CAA = 257,
+ AVC = 258,
+ TA = 32768,
+ DLV = 32769,
+ },
+ OPCODE = {
+ QUERY = 0,
+ IQUERY = 1,
+ STATUS = 2,
+ NOTIFY = 4,
+ UPDATE = 5,
+ },
+ RCODE = {
+ NOERROR = 0,
+ FORMERR = 1,
+ SERVFAIL = 2,
+ NXDOMAIN = 3,
+ NOTIMP = 4,
+ REFUSED = 5,
+ YXDOMAIN = 6,
+ YXRRSET = 7,
+ NXRRSET = 8,
+ NOTAUTH = 9,
+ NOTZONE = 10,
+ BADVERS = 16,
+ BADSIG = 16,
+ BADKEY = 17,
+ BADTIME = 18,
+ BADMODE = 19,
+ BADNAME = 20,
+ BADALG = 21,
+ BADTRUNC = 22,
+ BADCOOKIE = 23,
+ },
+ AFSDB = {
+ SUBTYPE_AFS3LOCSRV = 1,
+ SUBTYPE_DCENCA_ROOT = 2,
+ },
+ DHCID = {
+ TYPE_1OCTET = 0,
+ TYPE_DATAOCTET = 1,
+ TYPE_CLIENT_DUID = 2,
+ },
+ EDNS0 = {
+ OPT_LLQ = 1,
+ OPT_UL = 2,
+ OPT_NSID = 3,
+ OPT_DAU = 5,
+ OPT_DHU = 6,
+ OPT_N3U = 7,
+ OPT_CLIENT_SUBNET = 8,
+ OPT_EXPIRE = 9,
+ OPT_COOKIE = 10,
+ OPT_TCP_KEEPALIVE = 11,
+ OPT_PADDING = 12,
+ OPT_CHAIN = 13,
+ OPT_DEVICEID = 26946,
+ },
+}
+local _CLASS = {}
+_CLASS[Dns.CLASS.IN] = "IN"
+_CLASS[Dns.CLASS.CH] = "CH"
+_CLASS[Dns.CLASS.HS] = "HS"
+_CLASS[Dns.CLASS.NONE] = "NONE"
+_CLASS[Dns.CLASS.ANY] = "ANY"
+local _TYPE = {}
+_TYPE[Dns.TYPE.A] = "A"
+_TYPE[Dns.TYPE.NS] = "NS"
+_TYPE[Dns.TYPE.MD] = "MD"
+_TYPE[Dns.TYPE.MF] = "MF"
+_TYPE[Dns.TYPE.CNAME] = "CNAME"
+_TYPE[Dns.TYPE.SOA] = "SOA"
+_TYPE[Dns.TYPE.MB] = "MB"
+_TYPE[Dns.TYPE.MG] = "MG"
+_TYPE[Dns.TYPE.MR] = "MR"
+_TYPE[Dns.TYPE.NULL] = "NULL"
+_TYPE[Dns.TYPE.WKS] = "WKS"
+_TYPE[Dns.TYPE.PTR] = "PTR"
+_TYPE[Dns.TYPE.HINFO] = "HINFO"
+_TYPE[Dns.TYPE.MINFO] = "MINFO"
+_TYPE[Dns.TYPE.MX] = "MX"
+_TYPE[Dns.TYPE.TXT] = "TXT"
+_TYPE[Dns.TYPE.RP] = "RP"
+_TYPE[Dns.TYPE.AFSDB] = "AFSDB"
+_TYPE[Dns.TYPE.X25] = "X25"
+_TYPE[Dns.TYPE.ISDN] = "ISDN"
+_TYPE[Dns.TYPE.RT] = "RT"
+_TYPE[Dns.TYPE.NSAP] = "NSAP"
+_TYPE[Dns.TYPE.NSAP_PTR] = "NSAP_PTR"
+_TYPE[Dns.TYPE.SIG] = "SIG"
+_TYPE[Dns.TYPE.KEY] = "KEY"
+_TYPE[Dns.TYPE.PX] = "PX"
+_TYPE[Dns.TYPE.GPOS] = "GPOS"
+_TYPE[Dns.TYPE.AAAA] = "AAAA"
+_TYPE[Dns.TYPE.LOC] = "LOC"
+_TYPE[Dns.TYPE.NXT] = "NXT"
+_TYPE[Dns.TYPE.EID] = "EID"
+_TYPE[Dns.TYPE.NIMLOC] = "NIMLOC"
+_TYPE[Dns.TYPE.SRV] = "SRV"
+_TYPE[Dns.TYPE.ATMA] = "ATMA"
+_TYPE[Dns.TYPE.NAPTR] = "NAPTR"
+_TYPE[Dns.TYPE.KX] = "KX"
+_TYPE[Dns.TYPE.CERT] = "CERT"
+_TYPE[Dns.TYPE.A6] = "A6"
+_TYPE[Dns.TYPE.DNAME] = "DNAME"
+_TYPE[Dns.TYPE.SINK] = "SINK"
+_TYPE[Dns.TYPE.OPT] = "OPT"
+_TYPE[Dns.TYPE.APL] = "APL"
+_TYPE[Dns.TYPE.DS] = "DS"
+_TYPE[Dns.TYPE.SSHFP] = "SSHFP"
+_TYPE[Dns.TYPE.IPSECKEY] = "IPSECKEY"
+_TYPE[Dns.TYPE.RRSIG] = "RRSIG"
+_TYPE[Dns.TYPE.NSEC] = "NSEC"
+_TYPE[Dns.TYPE.DNSKEY] = "DNSKEY"
+_TYPE[Dns.TYPE.DHCID] = "DHCID"
+_TYPE[Dns.TYPE.NSEC3] = "NSEC3"
+_TYPE[Dns.TYPE.NSEC3PARAM] = "NSEC3PARAM"
+_TYPE[Dns.TYPE.TLSA] = "TLSA"
+_TYPE[Dns.TYPE.SMIMEA] = "SMIMEA"
+_TYPE[Dns.TYPE.HIP] = "HIP"
+_TYPE[Dns.TYPE.NINFO] = "NINFO"
+_TYPE[Dns.TYPE.RKEY] = "RKEY"
+_TYPE[Dns.TYPE.TALINK] = "TALINK"
+_TYPE[Dns.TYPE.CDS] = "CDS"
+_TYPE[Dns.TYPE.CDNSKEY] = "CDNSKEY"
+_TYPE[Dns.TYPE.OPENPGPKEY] = "OPENPGPKEY"
+_TYPE[Dns.TYPE.CSYNC] = "CSYNC"
+_TYPE[Dns.TYPE.SPF] = "SPF"
+_TYPE[Dns.TYPE.UINFO] = "UINFO"
+_TYPE[Dns.TYPE.UID] = "UID"
+_TYPE[Dns.TYPE.GID] = "GID"
+_TYPE[Dns.TYPE.UNSPEC] = "UNSPEC"
+_TYPE[Dns.TYPE.NID] = "NID"
+_TYPE[Dns.TYPE.L32] = "L32"
+_TYPE[Dns.TYPE.L64] = "L64"
+_TYPE[Dns.TYPE.LP] = "LP"
+_TYPE[Dns.TYPE.EUI48] = "EUI48"
+_TYPE[Dns.TYPE.EUI64] = "EUI64"
+_TYPE[Dns.TYPE.TKEY] = "TKEY"
+_TYPE[Dns.TYPE.TSIG] = "TSIG"
+_TYPE[Dns.TYPE.IXFR] = "IXFR"
+_TYPE[Dns.TYPE.AXFR] = "AXFR"
+_TYPE[Dns.TYPE.MAILB] = "MAILB"
+_TYPE[Dns.TYPE.MAILA] = "MAILA"
+_TYPE[Dns.TYPE.ANY] = "ANY"
+_TYPE[Dns.TYPE.URI] = "URI"
+_TYPE[Dns.TYPE.CAA] = "CAA"
+_TYPE[Dns.TYPE.AVC] = "AVC"
+_TYPE[Dns.TYPE.TA] = "TA"
+_TYPE[Dns.TYPE.DLV] = "DLV"
+local _OPCODE = {}
+_OPCODE[Dns.OPCODE.QUERY] = "QUERY"
+_OPCODE[Dns.OPCODE.IQUERY] = "IQUERY"
+_OPCODE[Dns.OPCODE.STATUS] = "STATUS"
+_OPCODE[Dns.OPCODE.NOTIFY] = "NOTIFY"
+_OPCODE[Dns.OPCODE.UPDATE] = "UPDATE"
+local _RCODE = {}
+_RCODE[Dns.RCODE.NOERROR] = "NOERROR"
+_RCODE[Dns.RCODE.FORMERR] = "FORMERR"
+_RCODE[Dns.RCODE.SERVFAIL] = "SERVFAIL"
+_RCODE[Dns.RCODE.NXDOMAIN] = "NXDOMAIN"
+_RCODE[Dns.RCODE.NOTIMP] = "NOTIMP"
+_RCODE[Dns.RCODE.REFUSED] = "REFUSED"
+_RCODE[Dns.RCODE.YXDOMAIN] = "YXDOMAIN"
+_RCODE[Dns.RCODE.YXRRSET] = "YXRRSET"
+_RCODE[Dns.RCODE.NXRRSET] = "NXRRSET"
+_RCODE[Dns.RCODE.NOTAUTH] = "NOTAUTH"
+_RCODE[Dns.RCODE.NOTZONE] = "NOTZONE"
+_RCODE[Dns.RCODE.BADVERS] = "BADVERS"
+_RCODE[Dns.RCODE.BADSIG] = "BADSIG"
+_RCODE[Dns.RCODE.BADKEY] = "BADKEY"
+_RCODE[Dns.RCODE.BADTIME] = "BADTIME"
+_RCODE[Dns.RCODE.BADMODE] = "BADMODE"
+_RCODE[Dns.RCODE.BADNAME] = "BADNAME"
+_RCODE[Dns.RCODE.BADALG] = "BADALG"
+_RCODE[Dns.RCODE.BADTRUNC] = "BADTRUNC"
+_RCODE[Dns.RCODE.BADCOOKIE] = "BADCOOKIE"
+local _AFSDB = {}
+_AFSDB[Dns.AFSDB.SUBTYPE_AFS3LOCSRV] = "SUBTYPE_AFS3LOCSRV"
+_AFSDB[Dns.AFSDB.SUBTYPE_DCENCA_ROOT] = "SUBTYPE_DCENCA_ROOT"
+local _DHCID = {}
+_DHCID[Dns.DHCID.TYPE_1OCTET] = "TYPE_1OCTET"
+_DHCID[Dns.DHCID.TYPE_DATAOCTET] = "TYPE_DATAOCTET"
+_DHCID[Dns.DHCID.TYPE_CLIENT_DUID] = "TYPE_CLIENT_DUID"
+local _EDNS0 = {}
+_EDNS0[Dns.EDNS0.OPT_LLQ] = "OPT_LLQ"
+_EDNS0[Dns.EDNS0.OPT_UL] = "OPT_UL"
+_EDNS0[Dns.EDNS0.OPT_NSID] = "OPT_NSID"
+_EDNS0[Dns.EDNS0.OPT_DAU] = "OPT_DAU"
+_EDNS0[Dns.EDNS0.OPT_DHU] = "OPT_DHU"
+_EDNS0[Dns.EDNS0.OPT_N3U] = "OPT_N3U"
+_EDNS0[Dns.EDNS0.OPT_CLIENT_SUBNET] = "OPT_CLIENT_SUBNET"
+_EDNS0[Dns.EDNS0.OPT_EXPIRE] = "OPT_EXPIRE"
+_EDNS0[Dns.EDNS0.OPT_COOKIE] = "OPT_COOKIE"
+_EDNS0[Dns.EDNS0.OPT_TCP_KEEPALIVE] = "OPT_TCP_KEEPALIVE"
+_EDNS0[Dns.EDNS0.OPT_PADDING] = "OPT_PADDING"
+_EDNS0[Dns.EDNS0.OPT_CHAIN] = "OPT_CHAIN"
+_EDNS0[Dns.EDNS0.OPT_DEVICEID] = "OPT_DEVICEID"
+Dns.CLASS_STR = _CLASS
+Dns.TYPE_STR = _TYPE
+Dns.OPCODE_STR = _OPCODE
+Dns.RCODE_STR = _RCODE
+Dns.AFSDB_STR = _AFSDB
+Dns.DHCID_STR = _DHCID
+Dns.EDNS0_STR = _EDNS0
+
+-- Create a new DNS object, optionally on-top of another object.
+function Dns.new(obj)
+ local self = C.core_object_dns_new()
+ self.obj_prev = obj
+ ffi.gc(self, C.core_object_dns_free)
+ return self
+end
+
+-- Return the textual type of the object.
+function Dns:type()
+ return "dns"
+end
+
+-- Return the previous object.
+function Dns:prev()
+ return self.obj_prev
+end
+
+-- Cast the object to the underlining object module and return it.
+function Dns:cast()
+ return self
+end
+
+-- Cast the object to the generic object module and return it.
+function Dns:uncast()
+ return ffi.cast("core_object_t*", self)
+end
+
+-- Make a copy of the object and return it.
+function Dns:copy()
+ return C.core_object_dns_copy(self)
+end
+
+-- Free the object, should only be used on copies or otherwise allocated.
+function Dns:free()
+ C.core_object_dns_free(self)
+end
+
+-- Return the Log object to control logging of this module.
+function Dns:log()
+ return C.core_object_dns_log()
+end
+
+-- Begin parsing the underlaying object, first the header is parsed then
+-- optionally continue calling
+-- .IR parse_q ()
+-- for the number of questions (see
+-- .IR qdcount ).
+-- After that continue calling
+-- .IR parse_rr ()
+-- for the number of answers, authorities and additionals resource records
+-- (see
+-- .IR ancount ", "
+-- .I nscount
+-- and
+-- .IR arcount ).
+-- Returns 0 on success or negative integer on error which can be for
+-- malformed or truncated DNS (-2) or if more space for labels is needed (-3).
+function Dns:parse_header()
+ return C.core_object_dns_parse_header(self)
+end
+
+-- Parse the next resource record as a question.
+-- Returns 0 on success or negative integer on error which can be for
+-- malformed or truncated DNS (-2) or if more space for labels is needed (-3).
+function Dns:parse_q(q, labels, num_labels)
+ return C.core_object_dns_parse_q(self, q, labels, num_labels)
+end
+
+-- Parse the next resource record.
+-- Returns 0 on success or negative integer on error which can be for
+-- malformed or truncated DNS (-2) or if more space for labels is needed (-3).
+function Dns:parse_rr(rr, labels, num_labels)
+ return C.core_object_dns_parse_rr(self, rr, labels, num_labels)
+end
+
+-- Begin parsing the underlaying object using
+-- .IR parse_header "(), "
+-- .IR parse_q ()
+-- and
+-- .IR parse_rr ().
+-- The optional
+-- .I num_labels
+-- can be used to set a specific number of labels used for each question
+-- and resource record (default 16).
+-- Returns result code, an array of questions, an array of question labels,
+-- an array of resource records and an array of resource records labels.
+-- Result code is 0 on success or negative integer on error which can be for
+-- malformed or truncated DNS (-2) or if more space for labels is needed (-3).
+function Dns:parse(num_labels)
+ local qs, qls, rrs, rrls = {}, {}, {}, {}
+ if num_labels == nil then
+ num_labels = 16
+ end
+
+ ret = self:parse_header()
+ if ret ~= 0 then
+ return ret, qs, qls, rrs, rrls
+ end
+ for n = 1, self.qdcount do
+ local labels = label.new(num_labels)
+ local q = Q.new()
+ local ret = C.core_object_dns_parse_q(self, q, labels, num_labels)
+
+ if ret ~= 0 then
+ return ret, qs, qls, rrs, rrls
+ end
+ table.insert(qs, q)
+ table.insert(qls, labels)
+ end
+ for n = 1, self.ancount do
+ local labels = label.new(num_labels)
+ local rr = RR.new()
+ local ret = C.core_object_dns_parse_rr(self, rr, labels, num_labels)
+
+ if ret ~= 0 then
+ return ret, qs, qls, rrs, rrls
+ end
+ table.insert(rrs, rr)
+ table.insert(rrls, labels)
+ end
+ for n = 1, self.nscount do
+ local labels = label.new(num_labels)
+ local rr = RR.new()
+ local ret = C.core_object_dns_parse_rr(self, rr, labels, num_labels)
+
+ if ret ~= 0 then
+ return ret, qs, qls, rrs, rrls
+ end
+ table.insert(rrs, rr)
+ table.insert(rrls, labels)
+ end
+ for n = 1, self.arcount do
+ local labels = label.new(num_labels)
+ local rr = RR.new()
+ local ret = C.core_object_dns_parse_rr(self, rr, labels, num_labels)
+
+ if ret ~= 0 then
+ return ret, qs, qls, rrs, rrls
+ end
+ table.insert(rrs, rr)
+ table.insert(rrls, labels)
+ end
+
+ return 0, qs, qls, rrs, rrls
+end
+
+-- Begin parsing the underlaying object using
+-- .IR parse_header "(), "
+-- .IR parse_q ()
+-- and
+-- .IR parse_rr (),
+-- and print it's content.
+-- The optional
+-- .I num_labels
+-- can be used to set a specific number of labels used for each question
+-- and resource record (default 16).
+function Dns:print(num_labels)
+ if num_labels == nil then
+ num_labels = 16
+ end
+ local labels = label.new(num_labels)
+ local q = Q.new()
+ local rr = RR.new()
+
+ if self:parse_header() ~= 0 then
+ return
+ end
+
+ local flags = {}
+ if self.have_aa and self.aa == 1 then
+ table.insert(flags, "AA")
+ end
+ if self.have_tc and self.tc == 1 then
+ table.insert(flags, "TC")
+ end
+ if self.have_rd and self.rd == 1 then
+ table.insert(flags, "RD")
+ end
+ if self.have_ra and self.ra == 1 then
+ table.insert(flags, "RA")
+ end
+ if self.have_z and self.z == 1 then
+ table.insert(flags, "Z")
+ end
+ if self.have_ad and self.ad == 1 then
+ table.insert(flags, "AD")
+ end
+ if self.have_cd and self.cd == 1 then
+ table.insert(flags, "CD")
+ end
+
+ print("id:", self.id)
+ print("", "qr:", self.qr)
+ print("", "opcode:", Dns.opcode_tostring(self.opcode))
+ print("", "flags:", table.concat(flags, " "))
+ print("", "rcode:", Dns.rcode_tostring(self.rcode))
+ print("", "qdcount:", self.qdcount)
+ print("", "ancount:", self.ancount)
+ print("", "nscount:", self.nscount)
+ print("", "arcount:", self.arcount)
+
+ if self.qdcount > 0 then
+ print("questions:", "class", "type", "labels")
+ for n = 1, self.qdcount do
+ if C.core_object_dns_parse_q(self, q, labels, num_labels) ~= 0 then
+ return
+ end
+ print("", Dns.class_tostring(q.class), Dns.type_tostring(q.type), label.tooffstr(self, labels, num_labels))
+ end
+ end
+ if self.ancount > 0 then
+ print("answers:", "class", "type", "ttl", "labels", "RR labels")
+ for n = 1, self.ancount do
+ if C.core_object_dns_parse_rr(self, rr, labels, num_labels) ~= 0 then
+ return
+ end
+ if rr.rdata_labels == 0 then
+ print("", Dns.class_tostring(rr.class), Dns.type_tostring(rr.type), rr.ttl, label.tooffstr(self, labels, rr.labels))
+ else
+ print("", Dns.class_tostring(rr.class), Dns.type_tostring(rr.type), rr.ttl, label.tooffstr(self, labels, rr.labels), label.tooffstr(self, labels, rr.rdata_labels, rr.labels))
+ end
+ end
+ end
+ if self.nscount > 0 then
+ print("authorities:", "class", "type", "ttl", "labels", "RR labels")
+ for n = 1, self.nscount do
+ if C.core_object_dns_parse_rr(self, rr, labels, num_labels) ~= 0 then
+ return
+ end
+ if rr.rdata_labels == 0 then
+ print("", Dns.class_tostring(rr.class), Dns.type_tostring(rr.type), rr.ttl, label.tooffstr(self, labels, rr.labels))
+ else
+ print("", Dns.class_tostring(rr.class), Dns.type_tostring(rr.type), rr.ttl, label.tooffstr(self, labels, rr.labels), label.tooffstr(self, labels, rr.rdata_labels, rr.labels))
+ end
+ end
+ end
+ if self.arcount > 0 then
+ print("additionals:", "class", "type", "ttl", "labels", "RR labels")
+ for n = 1, self.arcount do
+ if C.core_object_dns_parse_rr(self, rr, labels, num_labels) ~= 0 then
+ return
+ end
+ if rr.rdata_labels == 0 then
+ print("", Dns.class_tostring(rr.class), Dns.type_tostring(rr.type), rr.ttl, label.tooffstr(self, labels, rr.labels))
+ else
+ print("", Dns.class_tostring(rr.class), Dns.type_tostring(rr.type), rr.ttl, label.tooffstr(self, labels, rr.labels), label.tooffstr(self, labels, rr.rdata_labels, rr.labels))
+ end
+ end
+ end
+end
+
+-- Return the textual name for a class.
+function Dns.class_tostring(class)
+ if Dns.CLASS_STR[class] == nil then
+ return "UNKNOWN("..class..")"
+ end
+ return Dns.CLASS_STR[class]
+end
+
+-- Return the textual name for a type.
+function Dns.type_tostring(type)
+ if Dns.TYPE_STR[type] == nil then
+ return "UNKNOWN("..type..")"
+ end
+ return Dns.TYPE_STR[type]
+end
+
+-- Return the textual name for an opcode.
+function Dns.opcode_tostring(opcode)
+ if Dns.OPCODE_STR[opcode] == nil then
+ return "UNKNOWN("..opcode..")"
+ end
+ return Dns.OPCODE_STR[opcode]
+end
+
+-- Return the textual name for a rcode.
+function Dns.rcode_tostring(rcode)
+ if Dns.RCODE_STR[rcode] == nil then
+ return "UNKNOWN("..rcode..")"
+ end
+ return Dns.RCODE_STR[rcode]
+end
+
+-- Return the textual name for an afsdb subtype.
+function Dns.afsdb_tostring(afsdb)
+ if Dns.AFSDB_STR[afsdb] == nil then
+ return "UNKNOWN("..afsdb..")"
+ end
+ return Dns.AFSDB_STR[afsdb]
+end
+
+-- Return the textual name for a dhcid type.
+function Dns.dhcid_tostring(dhcid)
+ if Dns.DHCID_STR[dhcid] == nil then
+ return "UNKNOWN("..dhcid..")"
+ end
+ return Dns.DHCID_STR[dhcid]
+end
+
+-- Return the textual name for an EDNS0 OPT record.
+function Dns.edns0_tostring(edns0)
+ if Dns.EDNS0_STR[edns0] == nil then
+ return "UNKNOWN("..edns0..")"
+ end
+ return Dns.EDNS0_STR[edns0]
+end
+
+core_object_dns_t = ffi.metatype(t_name, { __index = Dns })
+
+-- dnsjit.core.object (3),
+-- dnsjit.core.object.payload (3),
+-- dnsjit.core.object.dns.label (3),
+-- dnsjit.core.object.dns.q (3),
+-- dnsjit.core.object.dns.rr (3)
+return Dns
diff --git a/src/core/object/dns/label.lua b/src/core/object/dns/label.lua
new file mode 100644
index 0000000..bc78758
--- /dev/null
+++ b/src/core/object/dns/label.lua
@@ -0,0 +1,118 @@
+-- Copyright (c) 2018-2021, OARC, Inc.
+-- All rights reserved.
+--
+-- This file is part of dnsjit.
+--
+-- dnsjit 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.
+--
+-- dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+
+-- dnsjit.core.object.dns.label
+-- Container of a DNS label
+--
+-- The object that describes a DNS label.
+-- To extract a domain name label first check that
+-- .I have_dn
+-- is set, then use
+-- .I "offset + 1"
+-- to indicate where in the payload the label start and
+-- .I length
+-- for how many bytes long it is.
+-- .SS Attributes
+-- .TP
+-- is_end
+-- .TP
+-- have_length
+-- Set if there is a length.
+-- .TP
+-- have_offset
+-- Set if there is an offset.
+-- .TP
+-- have_extension_bits
+-- Set if there is extension bits.
+-- .TP
+-- have_dn
+-- Set if the label contained a domain name.
+-- .TP
+-- extension_bits
+-- The extension bits.
+-- .TP
+-- length
+-- The length of the domain name.
+-- .TP
+-- offset
+-- If
+-- .I have_dn
+-- is set then this contains the offset within the payload to where this label
+-- start otherwise it contains the offset to another label.
+module(...,package.seeall)
+
+require("dnsjit.core.object.dns_h")
+local ffi = require("ffi")
+
+local Label = {}
+
+-- Create a new array of labels.
+function Label.new(size)
+ return ffi.new("core_object_dns_label_t[?]", size)
+end
+
+-- Returns labels as a string and an offset to the next label.
+-- The string may be nil if the first label was an offset.
+-- The offset may be nil if the last label was an extension bits or end marker.
+function Label.tostring(dns, labels, num_labels, offset_labels)
+ if offset_labels == nil then
+ offset_labels = 0
+ end
+ local dn
+ for n = 1, tonumber(num_labels) do
+ local label = labels[n - 1 + offset_labels]
+
+ if label.have_dn == 1 then
+ if dn == nil then
+ dn = ""
+ end
+ dn = dn .. ffi.string(dns.payload + label.offset + 1, label.length) .. "."
+ elseif label.have_offset == 1 then
+ return dn, label.offset
+ else
+ return dn, nil
+ end
+ end
+ return dn, nil
+end
+
+-- Returns labels as a string which also includes a textual notation of the
+-- offset in the form of
+-- .IR "<offset>label" .
+function Label.tooffstr(dns, labels, num_labels, offset_labels)
+ if offset_labels == nil then
+ offset_labels = 0
+ end
+ local dn = ""
+ for n = 1, tonumber(num_labels) do
+ local label = labels[n - 1 + offset_labels]
+
+ if label.have_dn == 1 then
+ dn = dn .. "<" .. tonumber(label.offset) .. ">" .. ffi.string(dns.payload + label.offset + 1, label.length) .. "."
+ elseif label.have_offset == 1 then
+ dn = dn .. "<" .. tonumber(label.offset) .. ">"
+ break
+ else
+ break
+ end
+ end
+ return dn
+end
+
+-- dnsjit.core.object.dns (3)
+return Label
diff --git a/src/core/object/dns/q.lua b/src/core/object/dns/q.lua
new file mode 100644
index 0000000..f65d9e8
--- /dev/null
+++ b/src/core/object/dns/q.lua
@@ -0,0 +1,52 @@
+-- Copyright (c) 2018-2021, OARC, Inc.
+-- All rights reserved.
+--
+-- This file is part of dnsjit.
+--
+-- dnsjit 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.
+--
+-- dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+
+-- dnsjit.core.object.dns.q
+-- Container of a DNS question
+--
+-- The object that describes a DNS question.
+-- .SS Attributes
+-- .TP
+-- have_type
+-- Set if there is a type.
+-- .TP
+-- have_class
+-- Set if there is a class.
+-- .TP
+-- type
+-- The type.
+-- .TP
+-- class
+-- The class.
+-- .TP
+-- labels
+-- The number of labels found in the question.
+module(...,package.seeall)
+
+require("dnsjit.core.object.dns_h")
+local ffi = require("ffi")
+
+local Q = {}
+
+-- Create a new question.
+function Q.new(size)
+ return ffi.new("core_object_dns_q_t")
+end
+
+-- dnsjit.core.object.dns (3)
+return Q
diff --git a/src/core/object/dns/rr.lua b/src/core/object/dns/rr.lua
new file mode 100644
index 0000000..d360d96
--- /dev/null
+++ b/src/core/object/dns/rr.lua
@@ -0,0 +1,85 @@
+-- Copyright (c) 2018-2021, OARC, Inc.
+-- All rights reserved.
+--
+-- This file is part of dnsjit.
+--
+-- dnsjit 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.
+--
+-- dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+
+-- dnsjit.core.object.dns.rr
+-- Container of a DNS resource record
+--
+-- The object that describes a DNS resource record.
+-- .SS Attributes
+-- .TP
+-- have_type
+-- Set if there is a type.
+-- .TP
+-- have_class
+-- Set if there is a class.
+-- .TP
+-- have_ttl
+-- Set if there is a ttl.
+-- .TP
+-- have_rdlength
+-- Set if there is a rdlength.
+-- .TP
+-- have_rdata
+-- Set if there is resource record data.
+-- .TP
+-- have_rdata_labels
+-- Set if there are any labels within the rdata.
+-- .TP
+-- have_padding
+-- Set if there is padding.
+-- .TP
+-- type
+-- The type.
+-- .TP
+-- class
+-- The class.
+-- .TP
+-- ttl
+-- The TTL.
+-- .TP
+-- rdlength
+-- The resource record data length.
+-- .TP
+-- labels
+-- The number of labels found in the record.
+-- .TP
+-- rdata_offset
+-- The offset within the payload for the resource record data.
+-- .TP
+-- rdata_labels
+-- The number of labels found inside the resource record data.
+-- .TP
+-- padding_offset
+-- The offset within the payload where the padding starts.
+-- .TP
+-- padding_length
+-- The length of the padding.
+module(...,package.seeall)
+
+require("dnsjit.core.object.dns_h")
+local ffi = require("ffi")
+
+local Rr = {}
+
+-- Create a new resource record.
+function Rr.new()
+ return ffi.new("core_object_dns_rr_t")
+end
+
+-- dnsjit.core.object.dns (3)
+return Rr
diff --git a/src/core/object/ether.c b/src/core/object/ether.c
new file mode 100644
index 0000000..dd7cd98
--- /dev/null
+++ b/src/core/object/ether.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2018-2021, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of dnsjit.
+ *
+ * dnsjit 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.
+ *
+ * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "core/object/ether.h"
+#include "core/assert.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+core_object_ether_t* core_object_ether_copy(const core_object_ether_t* self)
+{
+ core_object_ether_t* copy;
+ glassert_self();
+
+ glfatal_oom(copy = malloc(sizeof(core_object_ether_t)));
+ memcpy(copy, self, sizeof(core_object_ether_t));
+ copy->obj_prev = 0;
+
+ return copy;
+}
+
+void core_object_ether_free(core_object_ether_t* self)
+{
+ glassert_self();
+ free(self);
+}
diff --git a/src/core/object/ether.h b/src/core/object/ether.h
new file mode 100644
index 0000000..e35ecb2
--- /dev/null
+++ b/src/core/object/ether.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2018-2021, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of dnsjit.
+ *
+ * dnsjit 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.
+ *
+ * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "core/object.h"
+#include "core/timespec.h"
+
+#ifndef __dnsjit_core_object_ether_h
+#define __dnsjit_core_object_ether_h
+
+#include <stddef.h>
+
+#include "core/object/ether.hh"
+
+#define CORE_OBJECT_ETHER_INIT(prev) \
+ { \
+ CORE_OBJECT_INIT(CORE_OBJECT_ETHER, prev) \
+ , \
+ { 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0 }, 0 \
+ }
+
+#endif
diff --git a/src/core/object/ether.hh b/src/core/object/ether.hh
new file mode 100644
index 0000000..3b7a0cc
--- /dev/null
+++ b/src/core/object/ether.hh
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2018-2021, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of dnsjit.
+ *
+ * dnsjit 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.
+ *
+ * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+//lua:require("dnsjit.core.object_h")
+
+typedef struct core_object_ether {
+ const core_object_t* obj_prev;
+ int32_t obj_type;
+
+ uint8_t dhost[6];
+ uint8_t shost[6];
+ uint16_t type;
+} core_object_ether_t;
+
+core_object_ether_t* core_object_ether_copy(const core_object_ether_t* self);
+void core_object_ether_free(core_object_ether_t* self);
diff --git a/src/core/object/ether.lua b/src/core/object/ether.lua
new file mode 100644
index 0000000..3359d1f
--- /dev/null
+++ b/src/core/object/ether.lua
@@ -0,0 +1,78 @@
+-- Copyright (c) 2018-2021, OARC, Inc.
+-- All rights reserved.
+--
+-- This file is part of dnsjit.
+--
+-- dnsjit 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.
+--
+-- dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+
+-- dnsjit.core.object.ether
+-- Ether part of a packet
+--
+-- The ether part of a packet that usually can be found in the object chain
+-- after parsing with, for example, Layer filter.
+-- .SS Attributes
+-- .TP
+-- dhost
+-- The destination ether address.
+-- .TP
+-- shost
+-- The source ether address.
+-- .TP
+-- type
+-- The packet type ID field / EtherType field.
+module(...,package.seeall)
+
+require("dnsjit.core.object.ether_h")
+local ffi = require("ffi")
+local C = ffi.C
+
+local t_name = "core_object_ether_t"
+local core_object_ether_t
+local Ether = {}
+
+-- Return the textual type of the object.
+function Ether:type()
+ return "ether"
+end
+
+-- Return the previous object.
+function Ether:prev()
+ return self.obj_prev
+end
+
+-- Cast the object to the underlining object module and return it.
+function Ether:cast()
+ return self
+end
+
+-- Cast the object to the generic object module and return it.
+function Ether:uncast()
+ return ffi.cast("core_object_t*", self)
+end
+
+-- Make a copy of the object and return it.
+function Ether:copy()
+ return C.core_object_ether_copy(self)
+end
+
+-- Free the object, should only be used on copies or otherwise allocated.
+function Ether:free()
+ C.core_object_ether_free(self)
+end
+
+core_object_ether_t = ffi.metatype(t_name, { __index = Ether })
+
+-- dnsjit.core.object (3),
+-- dnsjit.filter.layer (3)
+return Ether
diff --git a/src/core/object/gre.c b/src/core/object/gre.c
new file mode 100644
index 0000000..9a467c3
--- /dev/null
+++ b/src/core/object/gre.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2018-2021, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of dnsjit.
+ *
+ * dnsjit 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.
+ *
+ * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "core/object/gre.h"
+#include "core/assert.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+core_object_gre_t* core_object_gre_copy(const core_object_gre_t* self)
+{
+ core_object_gre_t* copy;
+ glassert_self();
+
+ glfatal_oom(copy = malloc(sizeof(core_object_gre_t)));
+ memcpy(copy, self, sizeof(core_object_gre_t));
+ copy->obj_prev = 0;
+
+ return copy;
+}
+
+void core_object_gre_free(core_object_gre_t* self)
+{
+ glassert_self();
+ free(self);
+}
diff --git a/src/core/object/gre.h b/src/core/object/gre.h
new file mode 100644
index 0000000..8efa93c
--- /dev/null
+++ b/src/core/object/gre.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2018-2021, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of dnsjit.
+ *
+ * dnsjit 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.
+ *
+ * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "core/object.h"
+#include "core/timespec.h"
+
+#ifndef __dnsjit_core_object_gre_h
+#define __dnsjit_core_object_gre_h
+
+#include <stddef.h>
+
+#include "core/object/gre.hh"
+
+#define CORE_OBJECT_GRE_INIT(prev) \
+ { \
+ CORE_OBJECT_INIT(CORE_OBJECT_GRE, prev) \
+ , \
+ 0, 0, 0, 0, 0 \
+ }
+
+#endif
diff --git a/src/core/object/gre.hh b/src/core/object/gre.hh
new file mode 100644
index 0000000..67a89b1
--- /dev/null
+++ b/src/core/object/gre.hh
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2018-2021, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of dnsjit.
+ *
+ * dnsjit 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.
+ *
+ * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+//lua:require("dnsjit.core.object_h")
+
+typedef struct core_object_gre {
+ const core_object_t* obj_prev;
+ int32_t obj_type;
+
+ uint16_t gre_flags;
+ uint16_t ether_type;
+ uint16_t checksum;
+ uint16_t offset;
+ uint32_t key;
+ uint32_t sequence;
+ // TODO: routing list, check RFC 1701.
+} core_object_gre_t;
+
+core_object_gre_t* core_object_gre_copy(const core_object_gre_t* self);
+void core_object_gre_free(core_object_gre_t* self);
diff --git a/src/core/object/gre.lua b/src/core/object/gre.lua
new file mode 100644
index 0000000..703b02f
--- /dev/null
+++ b/src/core/object/gre.lua
@@ -0,0 +1,87 @@
+-- Copyright (c) 2018-2021, OARC, Inc.
+-- All rights reserved.
+--
+-- This file is part of dnsjit.
+--
+-- dnsjit 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.
+--
+-- dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+
+-- dnsjit.core.object.gre
+-- Generic Routing Encapsulation (GRE) part of a packet
+--
+-- The GRE part of a packet that usually can be found in the object chain
+-- after parsing with, for example, Layer filter.
+-- See RFC 1701.
+-- .SS Attributes
+-- .TP
+-- gre_flags
+-- The GRE flags.
+-- .TP
+-- ether_type
+-- The protocol type of the payload packet.
+-- .TP
+-- checksum
+-- The checksum of the GRE header and the payload packet.
+-- .TP
+-- key
+-- The Key field contains a four octet number which was inserted by
+-- the encapsulator.
+-- .TP
+-- sequence
+-- The Sequence Number field contains an unsigned 32 bit integer which is
+-- inserted by the encapsulator.
+module(...,package.seeall)
+
+require("dnsjit.core.object.gre_h")
+local ffi = require("ffi")
+local C = ffi.C
+
+local t_name = "core_object_gre_t"
+local core_object_gre_t
+local Gre = {}
+
+-- Return the textual type of the object.
+function Gre:type()
+ return "gre"
+end
+
+-- Return the previous object.
+function Gre:prev()
+ return self.obj_prev
+end
+
+-- Cast the object to the underlining object module and return it.
+function Gre:cast()
+ return self
+end
+
+-- Cast the object to the generic object module and return it.
+function Gre:uncast()
+ return ffi.cast("core_object_t*", self)
+end
+
+-- Make a copy of the object and return it.
+function Gre:copy()
+ return C.core_object_gre_copy(self)
+end
+
+-- Free the object, should only be used on copies or otherwise allocated.
+function Gre:free()
+ C.core_object_gre_free(self)
+end
+
+core_object_gre_t = ffi.metatype(t_name, { __index = Gre })
+
+-- dnsjit.core.object (3),
+-- dnsjit.filter.layer (3)
+return Gre
diff --git a/src/core/object/icmp.c b/src/core/object/icmp.c
new file mode 100644
index 0000000..ebd13dc
--- /dev/null
+++ b/src/core/object/icmp.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2018-2021, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of dnsjit.
+ *
+ * dnsjit 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.
+ *
+ * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "core/object/icmp.h"
+#include "core/assert.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+core_object_icmp_t* core_object_icmp_copy(const core_object_icmp_t* self)
+{
+ core_object_icmp_t* copy;
+ glassert_self();
+
+ glfatal_oom(copy = malloc(sizeof(core_object_icmp_t)));
+ memcpy(copy, self, sizeof(core_object_icmp_t));
+ copy->obj_prev = 0;
+
+ return copy;
+}
+
+void core_object_icmp_free(core_object_icmp_t* self)
+{
+ glassert_self();
+ free(self);
+}
diff --git a/src/core/object/icmp.h b/src/core/object/icmp.h
new file mode 100644
index 0000000..346a3ea
--- /dev/null
+++ b/src/core/object/icmp.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2018-2021, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of dnsjit.
+ *
+ * dnsjit 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.
+ *
+ * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "core/object.h"
+#include "core/timespec.h"
+
+#ifndef __dnsjit_core_object_icmp_h
+#define __dnsjit_core_object_icmp_h
+
+#include <stddef.h>
+
+#include "core/object/icmp.hh"
+
+#define CORE_OBJECT_ICMP_INIT(prev) \
+ { \
+ CORE_OBJECT_INIT(CORE_OBJECT_ICMP, prev) \
+ , \
+ 0, 0, 0 \
+ }
+
+#endif
diff --git a/src/core/object/icmp.hh b/src/core/object/icmp.hh
new file mode 100644
index 0000000..1a7aa88
--- /dev/null
+++ b/src/core/object/icmp.hh
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2018-2021, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of dnsjit.
+ *
+ * dnsjit 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.
+ *
+ * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+//lua:require("dnsjit.core.object_h")
+
+typedef struct core_object_icmp {
+ const core_object_t* obj_prev;
+ int32_t obj_type;
+
+ uint8_t type;
+ uint8_t code;
+ uint16_t cksum;
+} core_object_icmp_t;
+
+core_object_icmp_t* core_object_icmp_copy(const core_object_icmp_t* self);
+void core_object_icmp_free(core_object_icmp_t* self);
diff --git a/src/core/object/icmp.lua b/src/core/object/icmp.lua
new file mode 100644
index 0000000..52062ad
--- /dev/null
+++ b/src/core/object/icmp.lua
@@ -0,0 +1,78 @@
+-- Copyright (c) 2018-2021, OARC, Inc.
+-- All rights reserved.
+--
+-- This file is part of dnsjit.
+--
+-- dnsjit 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.
+--
+-- dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+
+-- dnsjit.core.object.icmp
+-- An ICMP packet
+--
+-- An ICMP packet which is usually at the top of the object chain
+-- after parsing with, for example, Layer filter.
+-- .SS Attributes
+-- .TP
+-- type
+-- The type of ICMP message.
+-- .TP
+-- code
+-- The (response/error) code for the ICMP type message.
+-- .TP
+-- cksum
+-- The ICMP checksum.
+module(...,package.seeall)
+
+require("dnsjit.core.object.icmp_h")
+local ffi = require("ffi")
+local C = ffi.C
+
+local t_name = "core_object_icmp_t"
+local core_object_icmp_t
+local Icmp = {}
+
+-- Return the textual type of the object.
+function Icmp:type()
+ return "icmp"
+end
+
+-- Return the previous object.
+function Icmp:prev()
+ return self.obj_prev
+end
+
+-- Cast the object to the underlining object module and return it.
+function Icmp:cast()
+ return self
+end
+
+-- Cast the object to the generic object module and return it.
+function Icmp:uncast()
+ return ffi.cast("core_object_t*", self)
+end
+
+-- Make a copy of the object and return it.
+function Icmp:copy()
+ return C.core_object_icmp_copy(self)
+end
+
+-- Free the object, should only be used on copies or otherwise allocated.
+function Icmp:free()
+ C.core_object_icmp_free(self)
+end
+
+core_object_icmp_t = ffi.metatype(t_name, { __index = Icmp })
+
+-- dnsjit.core.object (3),
+-- dnsjit.filter.layer (3)
+return Icmp
diff --git a/src/core/object/icmp6.c b/src/core/object/icmp6.c
new file mode 100644
index 0000000..b79fb17
--- /dev/null
+++ b/src/core/object/icmp6.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2018-2021, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of dnsjit.
+ *
+ * dnsjit 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.
+ *
+ * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "core/object/icmp6.h"
+#include "core/assert.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+core_object_icmp6_t* core_object_icmp6_copy(const core_object_icmp6_t* self)
+{
+ core_object_icmp6_t* copy;
+ glassert_self();
+
+ glfatal_oom(copy = malloc(sizeof(core_object_icmp6_t)));
+ memcpy(copy, self, sizeof(core_object_icmp6_t));
+ copy->obj_prev = 0;
+
+ return copy;
+}
+
+void core_object_icmp6_free(core_object_icmp6_t* self)
+{
+ glassert_self();
+ free(self);
+}
diff --git a/src/core/object/icmp6.h b/src/core/object/icmp6.h
new file mode 100644
index 0000000..569bf7f
--- /dev/null
+++ b/src/core/object/icmp6.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2018-2021, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of dnsjit.
+ *
+ * dnsjit 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.
+ *
+ * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "core/object.h"
+#include "core/timespec.h"
+
+#ifndef __dnsjit_core_object_icmp6_h
+#define __dnsjit_core_object_icmp6_h
+
+#include <stddef.h>
+
+#include "core/object/icmp6.hh"
+
+#define CORE_OBJECT_ICMP6_INIT(prev) \
+ { \
+ CORE_OBJECT_INIT(CORE_OBJECT_ICMP6, prev) \
+ , \
+ 0, 0, 0 \
+ }
+
+#endif
diff --git a/src/core/object/icmp6.hh b/src/core/object/icmp6.hh
new file mode 100644
index 0000000..2aa1ed4
--- /dev/null
+++ b/src/core/object/icmp6.hh
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2018-2021, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of dnsjit.
+ *
+ * dnsjit 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.
+ *
+ * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+//lua:require("dnsjit.core.object_h")
+
+typedef struct core_object_icmp6 {
+ const core_object_t* obj_prev;
+ int32_t obj_type;
+
+ uint8_t type;
+ uint8_t code;
+ uint16_t cksum;
+} core_object_icmp6_t;
+
+core_object_icmp6_t* core_object_icmp6_copy(const core_object_icmp6_t* self);
+void core_object_icmp6_free(core_object_icmp6_t* self);
diff --git a/src/core/object/icmp6.lua b/src/core/object/icmp6.lua
new file mode 100644
index 0000000..a3929bf
--- /dev/null
+++ b/src/core/object/icmp6.lua
@@ -0,0 +1,78 @@
+-- Copyright (c) 2018-2021, OARC, Inc.
+-- All rights reserved.
+--
+-- This file is part of dnsjit.
+--
+-- dnsjit 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.
+--
+-- dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+
+-- dnsjit.core.object.icmp6
+-- An ICMPv6 packet
+--
+-- An ICMPv6 packet which is usually at the top of the object chain
+-- after parsing with, for example, Layer filter.
+-- .SS Attributes
+-- .TP
+-- type
+-- The type of ICMPv6 message.
+-- .TP
+-- code
+-- The (response/error) code for the ICMPv6 type message.
+-- .TP
+-- cksum
+-- The ICMPv6 checksum.
+module(...,package.seeall)
+
+require("dnsjit.core.object.icmp6_h")
+local ffi = require("ffi")
+local C = ffi.C
+
+local t_name = "core_object_icmp6_t"
+local core_object_icmp6_t
+local Icmp6 = {}
+
+-- Return the textual type of the object.
+function Icmp6:type()
+ return "icmp6"
+end
+
+-- Return the previous object.
+function Icmp6:prev()
+ return self.obj_prev
+end
+
+-- Cast the object to the underlining object module and return it.
+function Icmp6:cast()
+ return self
+end
+
+-- Cast the object to the generic object module and return it.
+function Icmp6:uncast()
+ return ffi.cast("core_object_t*", self)
+end
+
+-- Make a copy of the object and return it.
+function Icmp6:copy()
+ return C.core_object_icmp6_copy(self)
+end
+
+-- Free the object, should only be used on copies or otherwise allocated.
+function Icmp6:free()
+ C.core_object_icmp6_free(self)
+end
+
+core_object_icmp6_t = ffi.metatype(t_name, { __index = Icmp6 })
+
+-- dnsjit.core.object (3),
+-- dnsjit.filter.layer (3)
+return Icmp6
diff --git a/src/core/object/ieee802.c b/src/core/object/ieee802.c
new file mode 100644
index 0000000..80dd4ea
--- /dev/null
+++ b/src/core/object/ieee802.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2018-2021, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of dnsjit.
+ *
+ * dnsjit 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.
+ *
+ * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "core/object/ieee802.h"
+#include "core/assert.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+core_object_ieee802_t* core_object_ieee802_copy(const core_object_ieee802_t* self)
+{
+ core_object_ieee802_t* copy;
+ glassert_self();
+
+ glfatal_oom(copy = malloc(sizeof(core_object_ieee802_t)));
+ memcpy(copy, self, sizeof(core_object_ieee802_t));
+ copy->obj_prev = 0;
+
+ return copy;
+}
+
+void core_object_ieee802_free(core_object_ieee802_t* self)
+{
+ glassert_self();
+ free(self);
+}
diff --git a/src/core/object/ieee802.h b/src/core/object/ieee802.h
new file mode 100644
index 0000000..ca4847c
--- /dev/null
+++ b/src/core/object/ieee802.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2018-2021, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of dnsjit.
+ *
+ * dnsjit 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.
+ *
+ * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "core/object.h"
+#include "core/timespec.h"
+
+#ifndef __dnsjit_core_object_ieee802_h
+#define __dnsjit_core_object_ieee802_h
+
+#include <stddef.h>
+
+#include "core/object/ieee802.hh"
+
+#define CORE_OBJECT_IEEE802_INIT(prev) \
+ { \
+ CORE_OBJECT_INIT(CORE_OBJECT_IEEE802, prev) \
+ , \
+ 0, 0, 0, 0, 0 \
+ }
+
+#endif
diff --git a/src/core/object/ieee802.hh b/src/core/object/ieee802.hh
new file mode 100644
index 0000000..1bce670
--- /dev/null
+++ b/src/core/object/ieee802.hh
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2018-2021, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of dnsjit.
+ *
+ * dnsjit 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.
+ *
+ * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+//lua:require("dnsjit.core.object_h")
+
+typedef struct core_object_ieee802 {
+ const core_object_t* obj_prev;
+ int32_t obj_type;
+
+ uint16_t tpid;
+ uint8_t pcp;
+ uint8_t dei;
+ uint8_t vid;
+ uint16_t ether_type;
+} core_object_ieee802_t;
+
+core_object_ieee802_t* core_object_ieee802_copy(const core_object_ieee802_t* self);
+void core_object_ieee802_free(core_object_ieee802_t* self);
diff --git a/src/core/object/ieee802.lua b/src/core/object/ieee802.lua
new file mode 100644
index 0000000..77519ef
--- /dev/null
+++ b/src/core/object/ieee802.lua
@@ -0,0 +1,84 @@
+-- Copyright (c) 2018-2021, OARC, Inc.
+-- All rights reserved.
+--
+-- This file is part of dnsjit.
+--
+-- dnsjit 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.
+--
+-- dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+
+-- dnsjit.core.object.ieee802
+-- IEEE802 part of a packet
+--
+-- The IEEE802 part of a packet that usually can be found in the object chain
+-- after parsing with, for example, Layer filter.
+-- .SS Attributes
+-- .TP
+-- tpid
+-- Tag protocol identifier.
+-- .TP
+-- pcp
+-- Priority code point.
+-- .TP
+-- dei
+-- Drop eligible indicator.
+-- .TP
+-- vid
+-- VLAN identifier.
+-- .TP
+-- ether_type
+-- The packet type ID field / EtherType field.
+module(...,package.seeall)
+
+require("dnsjit.core.object.ieee802_h")
+local ffi = require("ffi")
+local C = ffi.C
+
+local t_name = "core_object_ieee802_t"
+local core_object_ieee802_t
+local Ieee802 = {}
+
+-- Return the textual type of the object.
+function Ieee802:type()
+ return "ieee802"
+end
+
+-- Return the previous object.
+function Ieee802:prev()
+ return self.obj_prev
+end
+
+-- Cast the object to the underlining object module and return it.
+function Ieee802:cast()
+ return self
+end
+
+-- Cast the object to the generic object module and return it.
+function Ieee802:uncast()
+ return ffi.cast("core_object_t*", self)
+end
+
+-- Make a copy of the object and return it.
+function Ieee802:copy()
+ return C.core_object_ieee802_copy(self)
+end
+
+-- Free the object, should only be used on copies or otherwise allocated.
+function Ieee802:free()
+ C.core_object_ieee802_free(self)
+end
+
+core_object_ieee802_t = ffi.metatype(t_name, { __index = Ieee802 })
+
+-- dnsjit.core.object (3),
+-- dnsjit.filter.layer (3)
+return Ieee802
diff --git a/src/core/object/ip.c b/src/core/object/ip.c
new file mode 100644
index 0000000..4e50b60
--- /dev/null
+++ b/src/core/object/ip.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2018-2021, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of dnsjit.
+ *
+ * dnsjit 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.
+ *
+ * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "core/object/ip.h"
+#include "core/assert.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+core_object_ip_t* core_object_ip_copy(const core_object_ip_t* self)
+{
+ core_object_ip_t* copy;
+ glassert_self();
+
+ glfatal_oom(copy = malloc(sizeof(core_object_ip_t)));
+ memcpy(copy, self, sizeof(core_object_ip_t));
+ copy->obj_prev = 0;
+
+ return copy;
+}
+
+void core_object_ip_free(core_object_ip_t* self)
+{
+ glassert_self();
+ free(self);
+}
diff --git a/src/core/object/ip.h b/src/core/object/ip.h
new file mode 100644
index 0000000..c2b9312
--- /dev/null
+++ b/src/core/object/ip.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2018-2021, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of dnsjit.
+ *
+ * dnsjit 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.
+ *
+ * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "core/object.h"
+#include "core/timespec.h"
+
+#ifndef __dnsjit_core_object_ip_h
+#define __dnsjit_core_object_ip_h
+
+#include <stddef.h>
+
+#include "core/object/ip.hh"
+
+#define CORE_OBJECT_IP_INIT(prev) \
+ { \
+ CORE_OBJECT_INIT(CORE_OBJECT_IP, prev) \
+ , \
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, \
+ }
+
+#endif
diff --git a/src/core/object/ip.hh b/src/core/object/ip.hh
new file mode 100644
index 0000000..9a379a4
--- /dev/null
+++ b/src/core/object/ip.hh
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2018-2021, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of dnsjit.
+ *
+ * dnsjit 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.
+ *
+ * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+//lua:require("dnsjit.core.object_h")
+
+typedef struct core_object_ip {
+ const core_object_t* obj_prev;
+ int32_t obj_type;
+
+ uint8_t v;
+ uint8_t hl;
+ uint8_t tos;
+ uint16_t len;
+ uint16_t id;
+ uint16_t off;
+ uint8_t ttl;
+ uint8_t p;
+ uint16_t sum;
+ uint8_t src[4], dst[4];
+} core_object_ip_t;
+
+core_object_ip_t* core_object_ip_copy(const core_object_ip_t* self);
+void core_object_ip_free(core_object_ip_t* self);
diff --git a/src/core/object/ip.lua b/src/core/object/ip.lua
new file mode 100644
index 0000000..0294612
--- /dev/null
+++ b/src/core/object/ip.lua
@@ -0,0 +1,122 @@
+-- Copyright (c) 2018-2021, OARC, Inc.
+-- All rights reserved.
+--
+-- This file is part of dnsjit.
+--
+-- dnsjit 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.
+--
+-- dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+
+-- dnsjit.core.object.ip
+-- An IP packet
+--
+-- An IP packet that usually can be found in the object chain
+-- after parsing with, for example, Layer filter.
+-- .SS Attributes
+-- .TP
+-- v
+-- Version.
+-- .TP
+-- hl
+-- Header length.
+-- .TP
+-- tos
+-- Type of service.
+-- .TP
+-- len
+-- Total length.
+-- .TP
+-- id
+-- Identification.
+-- .TP
+-- off
+-- Fragment offset field.
+-- .TP
+-- ttl
+-- Time to live.
+-- .TP
+-- p
+-- Protocol.
+-- .TP
+-- sum
+-- Checksum.
+-- .TP
+-- src
+-- Source address.
+-- .TP
+-- dst
+-- Destination address.
+-- .TP
+-- payload
+-- A pointer to the payload.
+-- .TP
+-- plen
+-- The length of the payload.
+-- .TP
+-- pad_len
+-- The length of padding found, if any.
+module(...,package.seeall)
+
+require("dnsjit.core.object.ip_h")
+local ffi = require("ffi")
+local C = ffi.C
+local libip = require("dnsjit.lib.ip")
+
+local t_name = "core_object_ip_t"
+local core_object_ip_t
+local Ip = {}
+
+-- Return the textual type of the object.
+function Ip:type()
+ return "ip"
+end
+
+-- Return the previous object.
+function Ip:prev()
+ return self.obj_prev
+end
+
+-- Cast the object to the underlining object module and return it.
+function Ip:cast()
+ return self
+end
+
+-- Cast the object to the generic object module and return it.
+function Ip:uncast()
+ return ffi.cast("core_object_t*", self)
+end
+
+-- Make a copy of the object and return it.
+function Ip:copy()
+ return C.core_object_ip_copy(self)
+end
+
+-- Free the object, should only be used on copies or otherwise allocated.
+function Ip:free()
+ C.core_object_ip_free(self)
+end
+
+-- Return the IP source as a string.
+function Ip:source()
+ return libip.ipstring(self.src)
+end
+
+-- Return the IP destination as a string.
+function Ip:destination()
+ return libip.ipstring(self.dst)
+end
+
+core_object_ip_t = ffi.metatype(t_name, { __index = Ip })
+
+-- dnsjit.core.object (3),
+-- dnsjit.filter.layer (3)
+return Ip
diff --git a/src/core/object/ip6.c b/src/core/object/ip6.c
new file mode 100644
index 0000000..45db361
--- /dev/null
+++ b/src/core/object/ip6.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2018-2021, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of dnsjit.
+ *
+ * dnsjit 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.
+ *
+ * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "core/object/ip6.h"
+#include "core/assert.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+core_object_ip6_t* core_object_ip6_copy(const core_object_ip6_t* self)
+{
+ core_object_ip6_t* copy;
+ glassert_self();
+
+ glfatal_oom(copy = malloc(sizeof(core_object_ip6_t)));
+ memcpy(copy, self, sizeof(core_object_ip6_t));
+ copy->obj_prev = 0;
+
+ return copy;
+}
+
+void core_object_ip6_free(core_object_ip6_t* self)
+{
+ glassert_self();
+ free(self);
+}
diff --git a/src/core/object/ip6.h b/src/core/object/ip6.h
new file mode 100644
index 0000000..711f1a5
--- /dev/null
+++ b/src/core/object/ip6.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2018-2021, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of dnsjit.
+ *
+ * dnsjit 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.
+ *
+ * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "core/object.h"
+#include "core/timespec.h"
+
+#ifndef __dnsjit_core_object_ip6_h
+#define __dnsjit_core_object_ip6_h
+
+#include <stddef.h>
+
+#include "core/object/ip6.hh"
+
+#define CORE_OBJECT_IP6_INIT(prev) \
+ { \
+ CORE_OBJECT_INIT(CORE_OBJECT_IP6, prev) \
+ , \
+ 0, 0, 0, 0, \
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, \
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, \
+ 0, 0, 0, 0, \
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, \
+ }
+
+#endif
diff --git a/src/core/object/ip6.hh b/src/core/object/ip6.hh
new file mode 100644
index 0000000..5411dda
--- /dev/null
+++ b/src/core/object/ip6.hh
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2018-2021, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of dnsjit.
+ *
+ * dnsjit 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.
+ *
+ * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+//lua:require("dnsjit.core.object_h")
+
+typedef struct core_object_ip6 {
+ const core_object_t* obj_prev;
+ int32_t obj_type;
+
+ uint32_t flow;
+ uint16_t plen;
+ uint8_t nxt;
+ uint8_t hlim;
+ uint8_t src[16];
+ uint8_t dst[16];
+
+ uint8_t is_frag;
+ uint8_t have_rtdst;
+ uint16_t frag_offlg;
+ uint16_t frag_ident;
+ uint8_t rtdst[16];
+} core_object_ip6_t;
+
+core_object_ip6_t* core_object_ip6_copy(const core_object_ip6_t* self);
+void core_object_ip6_free(core_object_ip6_t* self);
diff --git a/src/core/object/ip6.lua b/src/core/object/ip6.lua
new file mode 100644
index 0000000..5271be3
--- /dev/null
+++ b/src/core/object/ip6.lua
@@ -0,0 +1,130 @@
+-- Copyright (c) 2018-2021, OARC, Inc.
+-- All rights reserved.
+--
+-- This file is part of dnsjit.
+--
+-- dnsjit 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.
+--
+-- dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+
+-- dnsjit.core.object.ip6
+-- An IPv6 packet
+--
+-- An IPv6 packet that usually can be found in the object chain
+-- after parsing with, for example, Layer filter.
+-- .SS Attributes
+-- .TP
+-- flow
+-- 4 bits version, 8 bits TC and 20 bits flow-ID.
+-- .TP
+-- plen
+-- Payload length (as in the IPv6 header).
+-- .TP
+-- nxt
+-- Next header.
+-- .TP
+-- hlim
+-- Hop limit.
+-- .TP
+-- src
+-- Source address.
+-- .TP
+-- dst
+-- Destination address.
+-- .TP
+-- is_frag
+-- 1 bit, set if packet is a fragment.
+-- .TP
+-- have_rtdst
+-- 1 bit, set if
+-- .I rtdst
+-- is set.
+-- .TP
+-- frag_offlg
+-- Offset, reserved, and flag taken from the fragment header.
+-- .TP
+-- frag_ident
+-- Identification taken from the fragment header.
+-- .TP
+-- rtdst
+-- Destination address found in the routing extension header.
+-- .TP
+-- payload
+-- A pointer to the payload.
+-- .TP
+-- len
+-- The length of the payload.
+-- .TP
+-- pad_len
+-- The length of padding found, if any.
+module(...,package.seeall)
+
+require("dnsjit.core.object.ip6_h")
+local ffi = require("ffi")
+local C = ffi.C
+local libip = require("dnsjit.lib.ip")
+
+local t_name = "core_object_ip6_t"
+local core_object_ip6_t
+local Ip6 = {}
+
+-- Return the textual type of the object.
+function Ip6:type()
+ return "ip6"
+end
+
+-- Return the previous object.
+function Ip6:prev()
+ return self.obj_prev
+end
+
+-- Cast the object to the underlining object module and return it.
+function Ip6:cast()
+ return self
+end
+
+-- Cast the object to the generic object module and return it.
+function Ip6:uncast()
+ return ffi.cast("core_object_t*", self)
+end
+
+-- Make a copy of the object and return it.
+function Ip6:copy()
+ return C.core_object_ip6_copy(self)
+end
+
+-- Free the object, should only be used on copies or otherwise allocated.
+function Ip6:free()
+ C.core_object_ip6_free(self)
+end
+
+-- Return the IPv6 source as a string.
+-- If
+-- .I pretty
+-- is true then return an easier to read IPv6 address.
+function Ip6:source(pretty)
+ return libip.ip6string(self.src, pretty)
+end
+
+-- Return the IPv6 destination as a string.
+-- If
+-- .I pretty
+-- is true then return an easier to read IPv6 address.
+function Ip6:destination(pretty)
+ return libip.ip6string(self.dst, pretty)
+end
+
+core_object_ip6_t = ffi.metatype(t_name, { __index = Ip6 })
+
+-- dnsjit.core.object (3),
+-- dnsjit.filter.layer (3)
+return Ip6
diff --git a/src/core/object/linuxsll.c b/src/core/object/linuxsll.c
new file mode 100644
index 0000000..cacd23a
--- /dev/null
+++ b/src/core/object/linuxsll.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2018-2021, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of dnsjit.
+ *
+ * dnsjit 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.
+ *
+ * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "core/object/linuxsll.h"
+#include "core/assert.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+core_object_linuxsll_t* core_object_linuxsll_copy(const core_object_linuxsll_t* self)
+{
+ core_object_linuxsll_t* copy;
+ glassert_self();
+
+ glfatal_oom(copy = malloc(sizeof(core_object_linuxsll_t)));
+ memcpy(copy, self, sizeof(core_object_linuxsll_t));
+ copy->obj_prev = 0;
+
+ return copy;
+}
+
+void core_object_linuxsll_free(core_object_linuxsll_t* self)
+{
+ glassert_self();
+ free(self);
+}
diff --git a/src/core/object/linuxsll.h b/src/core/object/linuxsll.h
new file mode 100644
index 0000000..9484c0d
--- /dev/null
+++ b/src/core/object/linuxsll.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2018-2021, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of dnsjit.
+ *
+ * dnsjit 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.
+ *
+ * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "core/object.h"
+#include "core/timespec.h"
+
+#ifndef __dnsjit_core_object_linuxsll_h
+#define __dnsjit_core_object_linuxsll_h
+
+#include <stddef.h>
+
+#include "core/object/linuxsll.hh"
+
+#define CORE_OBJECT_LINUXSLL_INIT(prev) \
+ { \
+ CORE_OBJECT_INIT(CORE_OBJECT_LINUXSLL, prev) \
+ , \
+ 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0 \
+ }
+
+#endif
diff --git a/src/core/object/linuxsll.hh b/src/core/object/linuxsll.hh
new file mode 100644
index 0000000..e808f96
--- /dev/null
+++ b/src/core/object/linuxsll.hh
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2018-2021, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of dnsjit.
+ *
+ * dnsjit 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.
+ *
+ * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+//lua:require("dnsjit.core.object_h")
+
+typedef struct core_object_linuxsll {
+ const core_object_t* obj_prev;
+ int32_t obj_type;
+
+ uint16_t packet_type;
+ uint16_t arp_hardware;
+ uint16_t link_layer_address_length;
+ uint8_t link_layer_address[8];
+ uint16_t ether_type;
+} core_object_linuxsll_t;
+
+core_object_linuxsll_t* core_object_linuxsll_copy(const core_object_linuxsll_t* self);
+void core_object_linuxsll_free(core_object_linuxsll_t* self);
diff --git a/src/core/object/linuxsll.lua b/src/core/object/linuxsll.lua
new file mode 100644
index 0000000..6b47525
--- /dev/null
+++ b/src/core/object/linuxsll.lua
@@ -0,0 +1,84 @@
+-- Copyright (c) 2018-2021, OARC, Inc.
+-- All rights reserved.
+--
+-- This file is part of dnsjit.
+--
+-- dnsjit 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.
+--
+-- dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+
+-- dnsjit.core.object.linuxsll
+-- Linux cooked-mode capture (SLL) part of a packet
+--
+-- The SLL part of a packet that usually can be found in the object chain
+-- after parsing with, for example, Layer filter.
+-- .SS Attributes
+-- .TP
+-- packet_type
+-- The packet type.
+-- .TP
+-- arp_hardware
+-- The link-layer device type.
+-- .TP
+-- link_layer_address_length
+-- The length of the link-layer address.
+-- .TP
+-- link_layer_address
+-- The link-layer address.
+-- .TP
+-- ether_type
+-- An Ethernet protocol type.
+module(...,package.seeall)
+
+require("dnsjit.core.object.linuxsll_h")
+local ffi = require("ffi")
+local C = ffi.C
+
+local t_name = "core_object_linuxsll_t"
+local core_object_linuxsll_t
+local Linuxsll = {}
+
+-- Return the textual type of the object.
+function Linuxsll:type()
+ return "linuxsll"
+end
+
+-- Return the previous object.
+function Linuxsll:prev()
+ return self.obj_prev
+end
+
+-- Cast the object to the underlining object module and return it.
+function Linuxsll:cast()
+ return self
+end
+
+-- Cast the object to the generic object module and return it.
+function Linuxsll:uncast()
+ return ffi.cast("core_object_t*", self)
+end
+
+-- Make a copy of the object and return it.
+function Linuxsll:copy()
+ return C.core_object_linuxsll_copy(self)
+end
+
+-- Free the object, should only be used on copies or otherwise allocated.
+function Linuxsll:free()
+ C.core_object_linuxsll_free(self)
+end
+
+core_object_linuxsll_t = ffi.metatype(t_name, { __index = Linuxsll })
+
+-- dnsjit.core.object (3).
+-- dnsjit.filter.layer (3)
+return Linuxsll
diff --git a/src/core/object/loop.c b/src/core/object/loop.c
new file mode 100644
index 0000000..4149f71
--- /dev/null
+++ b/src/core/object/loop.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2018-2021, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of dnsjit.
+ *
+ * dnsjit 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.
+ *
+ * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "core/object/loop.h"
+#include "core/assert.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+core_object_loop_t* core_object_loop_copy(const core_object_loop_t* self)
+{
+ core_object_loop_t* copy;
+ glassert_self();
+
+ glfatal_oom(copy = malloc(sizeof(core_object_loop_t)));
+ memcpy(copy, self, sizeof(core_object_loop_t));
+ copy->obj_prev = 0;
+
+ return copy;
+}
+
+void core_object_loop_free(core_object_loop_t* self)
+{
+ glassert_self();
+ free(self);
+}
diff --git a/src/core/object/loop.h b/src/core/object/loop.h
new file mode 100644
index 0000000..1d8670f
--- /dev/null
+++ b/src/core/object/loop.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2018-2021, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of dnsjit.
+ *
+ * dnsjit 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.
+ *
+ * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "core/object.h"
+#include "core/timespec.h"
+
+#ifndef __dnsjit_core_object_loop_h
+#define __dnsjit_core_object_loop_h
+
+#include <stddef.h>
+
+#include "core/object/loop.hh"
+
+#define CORE_OBJECT_LOOP_INIT(prev) \
+ { \
+ CORE_OBJECT_INIT(CORE_OBJECT_LOOP, prev) \
+ , \
+ 0 \
+ }
+
+#endif
diff --git a/src/core/object/loop.hh b/src/core/object/loop.hh
new file mode 100644
index 0000000..e8c5573
--- /dev/null
+++ b/src/core/object/loop.hh
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2018-2021, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of dnsjit.
+ *
+ * dnsjit 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.
+ *
+ * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+//lua:require("dnsjit.core.object_h")
+
+typedef struct core_object_loop {
+ const core_object_t* obj_prev;
+ int32_t obj_type;
+
+ uint32_t family;
+} core_object_loop_t;
+
+core_object_loop_t* core_object_loop_copy(const core_object_loop_t* self);
+void core_object_loop_free(core_object_loop_t* self);
diff --git a/src/core/object/loop.lua b/src/core/object/loop.lua
new file mode 100644
index 0000000..2cb441f
--- /dev/null
+++ b/src/core/object/loop.lua
@@ -0,0 +1,72 @@
+-- Copyright (c) 2018-2021, OARC, Inc.
+-- All rights reserved.
+--
+-- This file is part of dnsjit.
+--
+-- dnsjit 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.
+--
+-- dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+
+-- dnsjit.core.object.loop
+-- OpenBSD loopback encapsulation (loop) part of a packet
+--
+-- The loop part of a packet that usually can be found in the object chain
+-- after parsing with, for example, Layer filter.
+-- .SS Attributes
+-- .TP
+-- family
+-- The link-layer header describing what type of packet is encapsulated.
+module(...,package.seeall)
+
+require("dnsjit.core.object.loop_h")
+local ffi = require("ffi")
+local C = ffi.C
+
+local t_name = "core_object_loop_t"
+local core_object_loop_t
+local Loop = {}
+
+-- Return the textual type of the object.
+function Loop:type()
+ return "loop"
+end
+
+-- Return the previous object.
+function Loop:prev()
+ return self.obj_prev
+end
+
+-- Cast the object to the underlining object module and return it.
+function Loop:cast()
+ return self
+end
+
+-- Cast the object to the generic object module and return it.
+function Loop:uncast()
+ return ffi.cast("core_object_t*", self)
+end
+
+-- Make a copy of the object and return it.
+function Loop:copy()
+ return C.core_object_loop_copy(self)
+end
+
+-- Free the object, should only be used on copies or otherwise allocated.
+function Loop:free()
+ C.core_object_loop_free(self)
+end
+
+core_object_loop_t = ffi.metatype(t_name, { __index = Loop })
+
+-- dnsjit.core.object (3),
+-- dnsjit.filter.layer (3)
+return Loop
diff --git a/src/core/object/null.c b/src/core/object/null.c
new file mode 100644
index 0000000..7fe617a
--- /dev/null
+++ b/src/core/object/null.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2018-2021, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of dnsjit.
+ *
+ * dnsjit 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.
+ *
+ * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "core/object/null.h"
+#include "core/assert.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+core_object_null_t* core_object_null_copy(const core_object_null_t* self)
+{
+ core_object_null_t* copy;
+ glassert_self();
+
+ glfatal_oom(copy = malloc(sizeof(core_object_null_t)));
+ memcpy(copy, self, sizeof(core_object_null_t));
+ copy->obj_prev = 0;
+
+ return copy;
+}
+
+void core_object_null_free(core_object_null_t* self)
+{
+ glassert_self();
+ free(self);
+}
diff --git a/src/core/object/null.h b/src/core/object/null.h
new file mode 100644
index 0000000..0317fce
--- /dev/null
+++ b/src/core/object/null.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2018-2021, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of dnsjit.
+ *
+ * dnsjit 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.
+ *
+ * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "core/object.h"
+#include "core/timespec.h"
+
+#ifndef __dnsjit_core_object_null_h
+#define __dnsjit_core_object_null_h
+
+#include <stddef.h>
+
+#include "core/object/null.hh"
+
+#define CORE_OBJECT_NULL_INIT(prev) \
+ { \
+ CORE_OBJECT_INIT(CORE_OBJECT_NULL, prev) \
+ , \
+ 0 \
+ }
+
+#endif
diff --git a/src/core/object/null.hh b/src/core/object/null.hh
new file mode 100644
index 0000000..2e6c639
--- /dev/null
+++ b/src/core/object/null.hh
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2018-2021, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of dnsjit.
+ *
+ * dnsjit 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.
+ *
+ * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+//lua:require("dnsjit.core.object_h")
+
+typedef struct core_object_null {
+ const core_object_t* obj_prev;
+ int32_t obj_type;
+
+ uint32_t family;
+} core_object_null_t;
+
+core_object_null_t* core_object_null_copy(const core_object_null_t* self);
+void core_object_null_free(core_object_null_t* self);
diff --git a/src/core/object/null.lua b/src/core/object/null.lua
new file mode 100644
index 0000000..e6dfc5d
--- /dev/null
+++ b/src/core/object/null.lua
@@ -0,0 +1,72 @@
+-- Copyright (c) 2018-2021, OARC, Inc.
+-- All rights reserved.
+--
+-- This file is part of dnsjit.
+--
+-- dnsjit 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.
+--
+-- dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+
+-- dnsjit.core.object.null
+-- BSD loopback encapsulation (null) part of a packet
+--
+-- The null part of a packet that usually can be found in the object chain
+-- after parsing with, for example, Layer filter.
+-- .SS Attributes
+-- .TP
+-- family
+-- The link-layer header describing what type of packet is encapsulated.
+module(...,package.seeall)
+
+require("dnsjit.core.object.null_h")
+local ffi = require("ffi")
+local C = ffi.C
+
+local t_name = "core_object_null_t"
+local core_object_null_t
+local Null = {}
+
+-- Return the textual type of the object.
+function Null:type()
+ return "null"
+end
+
+-- Return the previous object.
+function Null:prev()
+ return self.obj_prev
+end
+
+-- Cast the object to the underlining object module and return it.
+function Null:cast()
+ return self
+end
+
+-- Cast the object to the generic object module and return it.
+function Null:uncast()
+ return ffi.cast("core_object_t*", self)
+end
+
+-- Make a copy of the object and return it.
+function Null:copy()
+ return C.core_object_null_copy(self)
+end
+
+-- Free the object, should only be used on copies or otherwise allocated.
+function Null:free()
+ C.core_object_null_free(self)
+end
+
+core_object_null_t = ffi.metatype(t_name, { __index = Null })
+
+-- dnsjit.core.object (3),
+-- dnsjit.filter.layer (3)
+return Null
diff --git a/src/core/object/payload.c b/src/core/object/payload.c
new file mode 100644
index 0000000..d6d2ee4
--- /dev/null
+++ b/src/core/object/payload.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2018-2021, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of dnsjit.
+ *
+ * dnsjit 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.
+ *
+ * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "core/object/payload.h"
+#include "core/assert.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+core_object_payload_t* core_object_payload_copy(const core_object_payload_t* self)
+{
+ core_object_payload_t* copy;
+ glassert_self();
+
+ glfatal_oom(copy = malloc(sizeof(core_object_payload_t) + self->len + self->padding));
+ memcpy(copy, self, sizeof(core_object_payload_t));
+ copy->obj_prev = 0;
+
+ if (copy->payload) {
+ copy->payload = (void*)copy + sizeof(core_object_payload_t);
+ memcpy((void*)copy->payload, self->payload, self->len + self->padding);
+ }
+
+ return copy;
+}
+
+void core_object_payload_free(core_object_payload_t* self)
+{
+ glassert_self();
+ free(self);
+}
diff --git a/src/core/object/payload.h b/src/core/object/payload.h
new file mode 100644
index 0000000..4b42a7c
--- /dev/null
+++ b/src/core/object/payload.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2018-2021, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of dnsjit.
+ *
+ * dnsjit 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.
+ *
+ * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "core/object.h"
+#include "core/timespec.h"
+
+#ifndef __dnsjit_core_object_payload_h
+#define __dnsjit_core_object_payload_h
+
+#include <stddef.h>
+
+#include "core/object/payload.hh"
+
+#define CORE_OBJECT_PAYLOAD_INIT(prev) \
+ { \
+ CORE_OBJECT_INIT(CORE_OBJECT_PAYLOAD, prev) \
+ , \
+ 0, 0, 0 \
+ }
+
+#endif
diff --git a/src/core/object/payload.hh b/src/core/object/payload.hh
new file mode 100644
index 0000000..fc2ad71
--- /dev/null
+++ b/src/core/object/payload.hh
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2018-2021, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of dnsjit.
+ *
+ * dnsjit 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.
+ *
+ * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+//lua:require("dnsjit.core.object_h")
+
+typedef struct core_object_payload {
+ const core_object_t* obj_prev;
+ int32_t obj_type;
+
+ const uint8_t* payload;
+ size_t len, padding;
+} core_object_payload_t;
+
+core_object_payload_t* core_object_payload_copy(const core_object_payload_t* self);
+void core_object_payload_free(core_object_payload_t* self);
diff --git a/src/core/object/payload.lua b/src/core/object/payload.lua
new file mode 100644
index 0000000..61ea867
--- /dev/null
+++ b/src/core/object/payload.lua
@@ -0,0 +1,83 @@
+-- Copyright (c) 2018-2021, OARC, Inc.
+-- All rights reserved.
+--
+-- This file is part of dnsjit.
+--
+-- dnsjit 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.
+--
+-- dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+
+-- dnsjit.core.object.payload
+-- Application data payload
+--
+-- Payload object contains the data carried by the underlying transport
+-- protocol.
+-- Payload is usually at the top of the object chain after parsing with,
+-- for example,
+-- .IR dnsjit.filter.layer .
+-- .SS Attributes
+-- .TP
+-- payload
+-- A pointer to the payload.
+-- .TP
+-- len
+-- The length of the payload.
+-- .TP
+-- padding
+-- The length of padding in the underlying packet.
+module(...,package.seeall)
+
+require("dnsjit.core.object.payload_h")
+local ffi = require("ffi")
+local C = ffi.C
+
+local t_name = "core_object_payload_t"
+local core_object_payload_t
+local Payload = {}
+
+-- Return the textual type of the object.
+function Payload:type()
+ return "payload"
+end
+
+-- Return the previous object.
+function Payload:prev()
+ return self.obj_prev
+end
+
+-- Cast the object to the underlining object module and return it.
+function Payload:cast()
+ return self
+end
+
+-- Cast the object to the generic object module and return it.
+function Payload:uncast()
+ return ffi.cast("core_object_t*", self)
+end
+
+-- Make a copy of the object and return it.
+function Payload:copy()
+ return C.core_object_payload_copy(self)
+end
+
+-- Free the object, should only be used on copies or otherwise allocated.
+function Payload:free()
+ C.core_object_payload_free(self)
+end
+
+core_object_payload_t = ffi.metatype(t_name, { __index = Payload })
+
+-- dnsjit.core.object (3),
+-- dnsjit.core.object.udp (3),
+-- dnsjit.core.object.tcp (3),
+-- dnsjit.filter.layer (3)
+return Payload
diff --git a/src/core/object/pcap.c b/src/core/object/pcap.c
new file mode 100644
index 0000000..576a94e
--- /dev/null
+++ b/src/core/object/pcap.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2018-2021, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of dnsjit.
+ *
+ * dnsjit 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.
+ *
+ * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "core/object/pcap.h"
+#include "core/assert.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+core_object_pcap_t* core_object_pcap_copy(const core_object_pcap_t* self)
+{
+ core_object_pcap_t* copy;
+ glassert_self();
+
+ glfatal_oom(copy = malloc(sizeof(core_object_pcap_t) + self->caplen));
+ memcpy(copy, self, sizeof(core_object_pcap_t));
+ copy->obj_prev = 0;
+
+ if (copy->bytes) {
+ copy->bytes = (void*)copy + sizeof(core_object_pcap_t);
+ memcpy((void*)copy->bytes, self->bytes, self->caplen);
+ }
+
+ return copy;
+}
+
+void core_object_pcap_free(core_object_pcap_t* self)
+{
+ glassert_self();
+ free(self);
+}
diff --git a/src/core/object/pcap.h b/src/core/object/pcap.h
new file mode 100644
index 0000000..093549b
--- /dev/null
+++ b/src/core/object/pcap.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2018-2021, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of dnsjit.
+ *
+ * dnsjit 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.
+ *
+ * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "core/object.h"
+#include "core/timespec.h"
+
+#ifndef __dnsjit_core_object_pcap_h
+#define __dnsjit_core_object_pcap_h
+
+#include "core/object/pcap.hh"
+
+#define CORE_OBJECT_PCAP_INIT(prev) \
+ { \
+ CORE_OBJECT_INIT(CORE_OBJECT_PCAP, prev) \
+ , \
+ 0, 0, \
+ { 0, 0 }, 0, 0, 0, \
+ 0 \
+ }
+
+#endif
diff --git a/src/core/object/pcap.hh b/src/core/object/pcap.hh
new file mode 100644
index 0000000..642a7e7
--- /dev/null
+++ b/src/core/object/pcap.hh
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2018-2021, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of dnsjit.
+ *
+ * dnsjit 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.
+ *
+ * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+//lua:require("dnsjit.core.object_h")
+//lua:require("dnsjit.core.timespec_h")
+
+typedef struct core_object_pcap {
+ const core_object_t* obj_prev;
+ int32_t obj_type;
+
+ uint32_t snaplen, linktype;
+
+ core_timespec_t ts;
+ uint32_t caplen, len;
+ const unsigned char* bytes;
+
+ uint8_t is_swapped;
+} core_object_pcap_t;
+
+core_object_pcap_t* core_object_pcap_copy(const core_object_pcap_t* self);
+void core_object_pcap_free(core_object_pcap_t* self);
diff --git a/src/core/object/pcap.lua b/src/core/object/pcap.lua
new file mode 100644
index 0000000..3d49326
--- /dev/null
+++ b/src/core/object/pcap.lua
@@ -0,0 +1,98 @@
+-- Copyright (c) 2018-2021, OARC, Inc.
+-- All rights reserved.
+--
+-- This file is part of dnsjit.
+--
+-- dnsjit 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.
+--
+-- dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+
+-- dnsjit.core.object.pcap
+-- Container of a packet found in a PCAP
+--
+-- Container of a PCAP packet which contains information both from the PCAP
+-- itself and the
+-- .I pcap_pkthdr
+-- object receied for each packet in the PCAP.
+-- .SS Attributes
+-- .TP
+-- snaplen
+-- Max length saved portion of each packet.
+-- .TP
+-- linktype
+-- Data link type for the PCAP.
+-- .TP
+-- ts
+-- Time stamp of this packet.
+-- .TP
+-- caplen
+-- Length of portion present.
+-- .TP
+-- len
+-- Length of this packet (off wire).
+-- .TP
+-- bytes
+-- A pointer to the packet.
+-- .TP
+-- is_swapped
+-- Indicate if the byte order of the PCAP is different then the host.
+-- This is used in, for example, the Layer filter to correctly parse null
+-- objects since they are stored in the capturers host byte order.
+module(...,package.seeall)
+
+require("dnsjit.core.object.pcap_h")
+local ffi = require("ffi")
+local C = ffi.C
+
+local t_name = "core_object_pcap_t"
+local core_object_pcap_t
+local Pcap = {}
+
+-- Return the textual type of the object.
+function Pcap:type()
+ return "pcap"
+end
+
+-- Return the previous object.
+function Pcap:prev()
+ return self.obj_prev
+end
+
+-- Cast the object to the underlining object module and return it.
+function Pcap:cast()
+ return self
+end
+
+-- Cast the object to the generic object module and return it.
+function Pcap:uncast()
+ return ffi.cast("core_object_t*", self)
+end
+
+-- Make a copy of the object and return it.
+function Pcap:copy()
+ return C.core_object_pcap_copy(self)
+end
+
+-- Free the object, should only be used on copies or otherwise allocated.
+function Pcap:free()
+ C.core_object_pcap_free(self)
+end
+
+core_object_pcap_t = ffi.metatype(t_name, { __index = Pcap })
+
+-- dnsjit.core.object (3),
+-- dnsjit.input.pcap (3),
+-- dnsjit.input.fpcap (3),
+-- dnsjit.input.mmpcap (3),
+-- dnsjit.filter.layer (3),
+-- dnsjit.output.pcap (3)
+return Pcap
diff --git a/src/core/object/tcp.c b/src/core/object/tcp.c
new file mode 100644
index 0000000..37f9548
--- /dev/null
+++ b/src/core/object/tcp.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2018-2021, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of dnsjit.
+ *
+ * dnsjit 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.
+ *
+ * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "core/object/tcp.h"
+#include "core/assert.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+core_object_tcp_t* core_object_tcp_copy(const core_object_tcp_t* self)
+{
+ core_object_tcp_t* copy;
+ glassert_self();
+
+ glfatal_oom(copy = malloc(sizeof(core_object_tcp_t)));
+ memcpy(copy, self, sizeof(core_object_tcp_t));
+ copy->obj_prev = 0;
+
+ return copy;
+}
+
+void core_object_tcp_free(core_object_tcp_t* self)
+{
+ glassert_self();
+ free(self);
+}
diff --git a/src/core/object/tcp.h b/src/core/object/tcp.h
new file mode 100644
index 0000000..e62ad42
--- /dev/null
+++ b/src/core/object/tcp.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2018-2021, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of dnsjit.
+ *
+ * dnsjit 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.
+ *
+ * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "core/object.h"
+#include "core/timespec.h"
+
+#ifndef __dnsjit_core_object_tcp_h
+#define __dnsjit_core_object_tcp_h
+
+#include <stddef.h>
+
+#include "core/object/tcp.hh"
+
+#define CORE_OBJECT_TCP_INIT(prev) \
+ { \
+ CORE_OBJECT_INIT(CORE_OBJECT_TCP, prev) \
+ , \
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+ { 0 }, 0 \
+ }
+
+#endif
diff --git a/src/core/object/tcp.hh b/src/core/object/tcp.hh
new file mode 100644
index 0000000..bd3167d
--- /dev/null
+++ b/src/core/object/tcp.hh
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2018-2021, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of dnsjit.
+ *
+ * dnsjit 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.
+ *
+ * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+//lua:require("dnsjit.core.object_h")
+
+typedef struct core_object_tcp {
+ const core_object_t* obj_prev;
+ int32_t obj_type;
+
+ uint16_t sport;
+ uint16_t dport;
+ uint32_t seq;
+ uint32_t ack;
+ uint8_t off : 4;
+ uint8_t x2 : 4;
+ uint8_t flags;
+ uint16_t win;
+ uint16_t sum;
+ uint16_t urp;
+
+ uint8_t opts[64];
+ size_t opts_len;
+} core_object_tcp_t;
+
+core_object_tcp_t* core_object_tcp_copy(const core_object_tcp_t* self);
+void core_object_tcp_free(core_object_tcp_t* self);
diff --git a/src/core/object/tcp.lua b/src/core/object/tcp.lua
new file mode 100644
index 0000000..e1d6dc2
--- /dev/null
+++ b/src/core/object/tcp.lua
@@ -0,0 +1,110 @@
+-- Copyright (c) 2018-2021, OARC, Inc.
+-- All rights reserved.
+--
+-- This file is part of dnsjit.
+--
+-- dnsjit 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.
+--
+-- dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+
+-- dnsjit.core.object.tcp
+-- A TCP segment header
+--
+-- A TCP segment header.
+-- The data itself is in the
+-- .I dnsjit.core.object.payload
+-- object, which is the next object in the chain after parsing with,
+-- for example,
+-- .IR dnsjit.filter.layer .
+-- .SS Attributes
+-- .TP
+-- sport
+-- Source port.
+-- .TP
+-- dport
+-- Destination port.
+-- .TP
+-- seq
+-- Sequence number.
+-- .TP
+-- ack
+-- Acknowledgement number.
+-- .TP
+-- off
+-- Data offset.
+-- .TP
+-- x2
+-- Unused.
+-- .TP
+-- flags
+-- TCP flags.
+-- .TP
+-- win
+-- Window.
+-- .TP
+-- sum
+-- Checksum.
+-- .TP
+-- urp
+-- Urgent pointer.
+-- .TP
+-- opts
+-- Array of bytes with the TCP options found.
+-- .TP
+-- opts_len
+-- Length of the TCP options.
+module(...,package.seeall)
+
+require("dnsjit.core.object.tcp_h")
+local ffi = require("ffi")
+local C = ffi.C
+
+local t_name = "core_object_tcp_t"
+local core_object_tcp_t
+local Tcp = {}
+
+-- Return the textual type of the object.
+function Tcp:type()
+ return "tcp"
+end
+
+-- Return the previous object.
+function Tcp:prev()
+ return self.obj_prev
+end
+
+-- Cast the object to the underlining object module and return it.
+function Tcp:cast()
+ return self
+end
+
+-- Cast the object to the generic object module and return it.
+function Tcp:uncast()
+ return ffi.cast("core_object_t*", self)
+end
+
+-- Make a copy of the object and return it.
+function Tcp:copy()
+ return C.core_object_tcp_copy(self)
+end
+
+-- Free the object, should only be used on copies or otherwise allocated.
+function Tcp:free()
+ C.core_object_tcp_free(self)
+end
+
+core_object_tcp_t = ffi.metatype(t_name, { __index = Tcp })
+
+-- dnsjit.core.object (3),
+-- dnsjit.core.object.payload (3),
+-- dnsjit.filter.layer (3)
+return Tcp
diff --git a/src/core/object/udp.c b/src/core/object/udp.c
new file mode 100644
index 0000000..3d05002
--- /dev/null
+++ b/src/core/object/udp.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2018-2021, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of dnsjit.
+ *
+ * dnsjit 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.
+ *
+ * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "core/object/udp.h"
+#include "core/assert.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+core_object_udp_t* core_object_udp_copy(const core_object_udp_t* self)
+{
+ core_object_udp_t* copy;
+ glassert_self();
+
+ glfatal_oom(copy = malloc(sizeof(core_object_udp_t)));
+ memcpy(copy, self, sizeof(core_object_udp_t));
+ copy->obj_prev = 0;
+
+ return copy;
+}
+
+void core_object_udp_free(core_object_udp_t* self)
+{
+ glassert_self();
+ free(self);
+}
diff --git a/src/core/object/udp.h b/src/core/object/udp.h
new file mode 100644
index 0000000..147e80b
--- /dev/null
+++ b/src/core/object/udp.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2018-2021, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of dnsjit.
+ *
+ * dnsjit 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.
+ *
+ * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "core/object.h"
+#include "core/timespec.h"
+
+#ifndef __dnsjit_core_object_udp_h
+#define __dnsjit_core_object_udp_h
+
+#include <stddef.h>
+
+#include "core/object/udp.hh"
+
+#define CORE_OBJECT_UDP_INIT(prev) \
+ { \
+ CORE_OBJECT_INIT(CORE_OBJECT_UDP, prev) \
+ , \
+ 0, 0, 0, 0, \
+ }
+
+#endif
diff --git a/src/core/object/udp.hh b/src/core/object/udp.hh
new file mode 100644
index 0000000..5efbd92
--- /dev/null
+++ b/src/core/object/udp.hh
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2018-2021, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of dnsjit.
+ *
+ * dnsjit 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.
+ *
+ * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+//lua:require("dnsjit.core.object_h")
+
+typedef struct core_object_udp {
+ const core_object_t* obj_prev;
+ int32_t obj_type;
+
+ uint16_t sport;
+ uint16_t dport;
+ uint16_t ulen;
+ uint16_t sum;
+} core_object_udp_t;
+
+core_object_udp_t* core_object_udp_copy(const core_object_udp_t* self);
+void core_object_udp_free(core_object_udp_t* self);
diff --git a/src/core/object/udp.lua b/src/core/object/udp.lua
new file mode 100644
index 0000000..1652574
--- /dev/null
+++ b/src/core/object/udp.lua
@@ -0,0 +1,86 @@
+-- Copyright (c) 2018-2021, OARC, Inc.
+-- All rights reserved.
+--
+-- This file is part of dnsjit.
+--
+-- dnsjit 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.
+--
+-- dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+
+-- dnsjit.core.object.udp
+-- A UDP datagram header
+--
+-- A UDP datagram header.
+-- The data itself is in the
+-- .I dnsjit.core.object.payload
+-- object, which is the next object in the chain after parsing with,
+-- for example,
+-- .IR dnsjit.filter.layer .
+-- .SS Attributes
+-- .TP
+-- sport
+-- Source port.
+-- .TP
+-- dport
+-- Destination port.
+-- .TP
+-- ulen
+-- UDP length (as described in the UDP header).
+-- .TP
+-- sum
+-- Checksum.
+module(...,package.seeall)
+
+require("dnsjit.core.object.udp_h")
+local ffi = require("ffi")
+local C = ffi.C
+
+local t_name = "core_object_udp_t"
+local core_object_udp_t
+local Udp = {}
+
+-- Return the textual type of the object.
+function Udp:type()
+ return "udp"
+end
+
+-- Return the previous object.
+function Udp:prev()
+ return self.obj_prev
+end
+
+-- Cast the object to the underlining object module and return it.
+function Udp:cast()
+ return self
+end
+
+-- Cast the object to the generic object module and return it.
+function Udp:uncast()
+ return ffi.cast("core_object_t*", self)
+end
+
+-- Make a copy of the object and return it.
+function Udp:copy()
+ return C.core_object_udp_copy(self)
+end
+
+-- Free the object, should only be used on copies or otherwise allocated.
+function Udp:free()
+ C.core_object_udp_free(self)
+end
+
+core_object_udp_t = ffi.metatype(t_name, { __index = Udp })
+
+-- dnsjit.core.object (3),
+-- dnsjit.core.object.payload (3),
+-- dnsjit.filter.layer (3)
+return Udp