chiark / gitweb /
WIP dns transport packets etc.
[secnet.git] / dns-transp-client.c
diff --git a/dns-transp-client.c b/dns-transp-client.c
new file mode 100644 (file)
index 0000000..deec7b6
--- /dev/null
@@ -0,0 +1,48 @@
+/**/
+
+uint8_t qid[2];
+
+#define PKT_PREPEND_START(pe, size, body) do{          \
+    assert((pe)->ptr - (pe)->buf >= (size));           \
+    const uint8_t *pkt_prepend_orig = (pe)->ptr;       \
+    uint8_t *pkt = (pe)->ptr -= (size);                        \
+    { body; }                                          \
+    assert(pkt == pkt_prepend_orig);                   \
+  }while(0)
+
+#define PKT_ADDB(byte) (*pkt++ = (byte))
+#define PKT_ADDW(word) (*pkt++ = ((w) >> 8), *pkt++ = (w))
+
+#define DNS_HDRLEN (6*2)
+
+void dnsqueryenc_start(struct dnspacketenc *pe,
+                      int mydompathlen, const char *mydompath) {
+    dnspacketenc_start(pe);
+    
+    PKT_PREPEND(pe, 4, {
+       PKT_ADDW(QTYPE_CNAME);
+       PKT_ADDW(QCLASS_IN);
+    });
+
+    return dnsdomainenc_start(&pe->dom, pe->buf,
+                             pe->ptr - pe->buf - DNS_HDRLEN,
+                             mydompathlen, mydompath);
+}
+
+void dnsqueryenc_finish(uint16_t qid, const uint8_t **result, int *reslen) {
+    pe->ptr = dnsdomainenc_getresult(&pe->dom);
+
+    PKT_PREPEND(pe, DNS_HDRLEN, {
+       PKT_ADDW(qid);
+       PKT_ADDB(0x00); /* QR=0(q); Opcode=QUERY; !AA,!TC,!RD */
+       PKT_ADDB(0x00); /* !RA; Z; RCODE=NOERROR */
+       PKT_ADDW(0x01); /* QDCOUNT=1 */
+       PKT_ADDW(0x00); /* ANCOUNT=0 */
+       PKT_ADDW(0x00); /* NSCOUNT=0 */
+       PKT_ADDW(0x00); *hdr++ = 0x00; /* ARCOUNT=0 */
+    });
+
+    *result = pe->ptr;
+    *reslen = (pe->buf + MAX_DNSPACKET_BYTES) - pe->ptr;
+}
+