From e97012de8f47dd6ae68e288b4e983731a3b96b13 Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Mon, 28 Apr 2014 10:05:20 +0100 Subject: [PATCH] zone.lisp: Output format for Daniel Bernstein's `tinydns' server. --- zone.lisp | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/zone.lisp b/zone.lisp index ea7a2f1..2228c07 100644 --- a/zone.lisp +++ b/zone.lisp @@ -1080,4 +1080,90 @@ $TTL ~2@*~D~2%" (bind-record-type type) format args))) +;;;-------------------------------------------------------------------------- +;;; tinydns-data output format. + +(defun tinydns-output (code &rest fields) + (format *zone-output-stream* "~C~{~@[~A~]~^:~}~%" code fields)) + +(defun tinydns-raw-record (type zr data) + (tinydns-output #\: (zr-name zr) type + (with-output-to-string (out) + (dotimes (i (length data)) + (let ((byte (aref data i))) + (if (or (<= byte 32) + (>= byte 128) + (member byte '(#\: #\\) :key #'char-code)) + (format out "\\~3,'0O" byte) + (write-char (code-char byte) out))))) + (zr-ttl zr))) + +(defgeneric tinydns-record (type zr) + (:method ((type (eql :a)) zr) + (tinydns-output #\+ (zr-name zr) + (ipaddr-string (zr-data zr)) (zr-ttl zr))) + (:method ((type (eql :aaaa)) zr) + (tinydns-output #\3 (zr-name zr) + (format nil "~(~32,'0X~)" (ipaddr-addr (zr-data zr))) + (zr-ttl zr))) + (:method ((type (eql :ptr)) zr) + (tinydns-output #\^ (zr-name zr) (zr-data zr) (zr-ttl zr))) + (:method ((type (eql :cname)) zr) + (tinydns-output #\C (zr-name zr) (zr-data zr) (zr-ttl zr))) + (:method ((type (eql :ns)) zr) + (tinydns-output #\& (zr-name zr) nil (zr-data zr) (zr-ttl zr))) + (:method ((type (eql :mx)) zr) + (let ((name (car (zr-data zr))) + (prio (cdr (zr-data zr)))) + (tinydns-output #\@ (zr-name zr) nil name prio (zr-ttl zr)))) + (:method ((type (eql :txt)) zr) + (tinydns-raw-record 16 zr + (build-record + (dolist (s (zr-data zr)) + (rec-u8 (length s)) + (rec-raw-string s))))) + (:method ((type (eql :srv)) zr) + (destructuring-bind (prio weight port host) (zr-data zr) + (tinydns-raw-record 33 zr + (build-record + (rec-u16 prio) + (rec-u16 weight) + (rec-u16 port) + (rec-name host))))) + (:method ((type (eql :sshfp)) zr) + (destructuring-bind (alg type fpr) (zr-data zr) + (tinydns-raw-record 44 zr + (build-record + (rec-u8 alg) + (rec-u8 type) + (do ((i 0 (+ i 2)) + (n (length fpr))) + ((>= i n)) + (rec-u8 (parse-integer fpr + :start i :end (+ i 2) + :radix 16)))))))) + +(defmethod zone-write ((format (eql :tinydns)) zone stream) + (format stream "~ +### Zone file `~(~A~)' +### (generated ~A) +~%" + (zone-name zone) + (iso-date :now :datep t :timep t)) + (let ((soa (zone-soa zone))) + (tinydns-output #\Z + (zone-name zone) + (soa-source soa) + (let* ((name (copy-seq (soa-admin soa))) + (at (position #\@ name))) + (when at (setf (char name at) #\.)) + name) + (soa-serial soa) + (soa-refresh soa) + (soa-expire soa) + (soa-min-ttl soa) + (zone-default-ttl zone))) + (dolist (zr (zone-records zone)) + (tinydns-record (zr-type zr) zr))) + ;;;----- That's all, folks -------------------------------------------------- -- 2.11.0