From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: peder@klingenberg.no (Peder O. Klingenberg) Newsgroups: gmane.emacs.bugs Subject: bug#26820: 26.0.50; DNS mode and IPv6 reverse zones Date: Sun, 07 May 2017 20:58:59 +0200 Message-ID: References: NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: blaine.gmane.org 1494183656 31356 195.159.176.226 (7 May 2017 19:00:56 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Sun, 7 May 2017 19:00:56 +0000 (UTC) User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.0.50 (darwin) To: 26820@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Sun May 07 21:00:52 2017 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1d7RQJ-0007zM-BW for geb-bug-gnu-emacs@m.gmane.org; Sun, 07 May 2017 21:00:52 +0200 Original-Received: from localhost ([::1]:56481 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1d7RQK-0002gr-6z for geb-bug-gnu-emacs@m.gmane.org; Sun, 07 May 2017 15:00:52 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:59100) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1d7RPa-0002J3-96 for bug-gnu-emacs@gnu.org; Sun, 07 May 2017 15:00:08 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1d7RPX-0000UC-5Y for bug-gnu-emacs@gnu.org; Sun, 07 May 2017 15:00:06 -0400 Original-Received: from debbugs.gnu.org ([208.118.235.43]:34275) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1d7RPX-0000U1-14 for bug-gnu-emacs@gnu.org; Sun, 07 May 2017 15:00:03 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1d7RPW-0005Bk-QJ for bug-gnu-emacs@gnu.org; Sun, 07 May 2017 15:00:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: peder@klingenberg.no (Peder O. Klingenberg) Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 07 May 2017 19:00:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 26820 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: Original-Received: via spool by 26820-submit@debbugs.gnu.org id=B26820.149418355719851 (code B ref 26820); Sun, 07 May 2017 19:00:02 +0000 Original-Received: (at 26820) by debbugs.gnu.org; 7 May 2017 18:59:17 +0000 Original-Received: from localhost ([127.0.0.1]:60704 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1d7ROn-0005A7-2d for submit@debbugs.gnu.org; Sun, 07 May 2017 14:59:17 -0400 Original-Received: from tarrant.klingenberg.no ([80.91.231.253]:43191) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1d7ROk-00059z-VZ for 26820@debbugs.gnu.org; Sun, 07 May 2017 14:59:15 -0400 Original-Received: from 179.51-175-138.customer.lyse.net ([51.175.138.179] helo=modesty.local) by tarrant.klingenberg.no with esmtpsa (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.80) (envelope-from ) id 1d7ROc-0007fT-ET for 26820@debbugs.gnu.org; Sun, 07 May 2017 20:59:14 +0200 Original-Received: by modesty.local (Postfix, from userid 502) id 2979117F651B; Sun, 7 May 2017 20:58:59 +0200 (CEST) In-Reply-To: (Peder O. Klingenberg's message of "Sun, 07 May 2017 20:51:03 +0200") X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 208.118.235.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.org gmane.emacs.bugs:132358 Archived-At: --=-=-= Content-Type: text/plain peder@klingenberg.no (Peder O. Klingenberg) writes: > I'll pass along the patch as soon as I get a bug# to attach to it. :) As promised, here's the patch. I even wrote tests, which is a first for me. I couldn't find dns-mode documented in any manual, so I haven't written any info docs, but the docstrings should hopefully give enough information to use the feature. --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0001-Command-to-convert-IPv6-addresses-in-zone-files.patch >From 8fe87aafd6aa77f5d4c1ac126e2d2e7e69ce236c Mon Sep 17 00:00:00 2001 From: "Peder O. Klingenberg" Date: Sun, 7 May 2017 17:58:41 +0200 Subject: [PATCH] Command to convert IPv6 addresses in zone files * lisp/textmodes/dns-mode.el (dns-mode-ipv6-to-nibbles): New command to convert IPv6 addresses to a format suitable for reverse lookup zone files. (dns-mode-reverse-and-expand-ipv6): The algorithm central to the command above. (dns-mode-map, dns-mode-menu): Key and menu item for the new command. * test/lisp/textmodes/dns-mode-tests.el (dns-mode-ipv6-conversion) (dns-mode-ipv6-text-replacement): Tests for new functionality in dns-mode.el (bug#26820) --- etc/NEWS | 8 +++ lisp/textmodes/dns-mode.el | 102 +++++++++++++++++++++++++++++++++- test/lisp/textmodes/dns-mode-tests.el | 58 +++++++++++++++++++ 3 files changed, 167 insertions(+), 1 deletion(-) create mode 100644 test/lisp/textmodes/dns-mode-tests.el diff --git a/etc/NEWS b/etc/NEWS index 4599efd7da..293ef4f960 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -784,6 +784,14 @@ file. *** Emacs does no longer prompt the user before killing Flymake processes on exit. +** DNS mode + ++++ +*** DNS mode has a tool to convert IPv6 addresses +Reverse zones for IPv6 needs IPv6 addresses spelled out in a +cumbersome format. A new command 'dns-mode-ipv6-to-nibbles' helps +with the conversion. + * New Modes and Packages in Emacs 26.1 diff --git a/lisp/textmodes/dns-mode.el b/lisp/textmodes/dns-mode.el index 01f509d913..6f2f40cd2c 100644 --- a/lisp/textmodes/dns-mode.el +++ b/lisp/textmodes/dns-mode.el @@ -113,6 +113,7 @@ dns-mode-syntax-table (defvar dns-mode-map (let ((map (make-sparse-keymap))) (define-key map "\C-c\C-s" 'dns-mode-soa-increment-serial) + (define-key map "\C-c\C-e" 'dns-mode-ipv6-to-nibbles) map) "Keymap for DNS master file mode.") @@ -124,7 +125,8 @@ dns-mode-menu (easy-menu-define dns-mode-menu dns-mode-map "DNS Menu." '("DNS" - ["Increment SOA serial" dns-mode-soa-increment-serial t])) + ["Increment SOA serial" dns-mode-soa-increment-serial t] + ["Convert IPv6 address to nibbles" dns-mode-ipv6-to-nibbles t])) ;; Mode. @@ -220,6 +222,104 @@ dns-mode-soa-maybe-increment-serial ;; We return nil in case this is used in write-contents-functions. nil))) +;;;###autoload +(defun dns-mode-ipv6-to-nibbles (negate-prefix-p) + "Replace an IPv6 address around or preceeding point by its +ip6.arpa-representation for use in reverse zone files. The +replaced address is placed in the kill ring. + +The address can be a complete address (no prefix designator), can +have a normal prefix designator (e.g. /48), in which case only +the required number of nibbles are output, or can have a negative +prefix designator (e.g. /-112), in which case only the parts of +the address *not* covered by the absolute value of the prefix +length is output, as a relative address (without .ip6.arpa. at +the end). This is useful when $ORIGIN is specified in the zone +file. + +If called with a prefix argument (C-u), the value of the detected +prefix length is negated. + +Examples: + +2001:db8::12 => +2.1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa. + +2001:db8::12/32 => +8.b.d.0.1.0.0.2.ip6.arpa. + +2001:db8::12/-32 => +2.1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 + +::42/112 (with C-u prefix) => +2.4.0.0" + (interactive "P") + (skip-syntax-backward " ") + (skip-syntax-backward "w_.") + (re-search-forward "\\([[:xdigit:]:]+\\)\\(/-?[0-9]\\{2,3\\}\\)?") + (kill-new (match-string 0)) + (let ((address (match-string 1)) + (prefix-length (match-string 2))) + (if prefix-length + (progn + (setq prefix-length (string-to-number (substring prefix-length 1))) + (if negate-prefix-p + (setq prefix-length (* -1 prefix-length))))) + (replace-match (save-match-data + (dns-mode-reverse-and-expand-ipv6 address prefix-length))))) + +(defun dns-mode-reverse-and-expand-ipv6 (address &optional prefix-length) + "Convert an IPv6 address to (parts of) an ip6.arpa nibble format. + +ADDRESS must be an IPv6 address in the usual colon-separaated +format, without a prefix designator at the end. PREFIX-LENGTH, +if given, must be a number whose absolute value is the length in +bits of the network part of the address. + +If PREFIX-LENGTH is `nil', an absolute address is returned +representing the full IPv6 address. + +If PREFIX-LENGTH is positive, an absolute address is returned +representing the network prefix indicated. + +If PREFIX-LENGTH is negative, a relative address is returned +representing the host parts of the address with respect to the +indicated network prefix. + +See `dns-mode-ipv6-to-nibbles' for examples." + (let* ((chunks (split-string address ":")) + (prefix-length-nibbles (if prefix-length + (ceiling (abs prefix-length) 4) + 32)) + (filler-chunks (- 8 (length (remove "" chunks)))) + (expanded-address (apply #'concat + (loop with filler-done = nil + for chunk in chunks + if (and (not filler-done) + (string= "" chunk)) + append (prog1 + (loop repeat filler-chunks + collect "0000") + (setq filler-done t)) + else + if (not (string= "" chunk)) + collect (format "%04x" (string-to-number chunk 16))))) + (rev-address-nibbles (nreverse (if (and prefix-length + (minusp prefix-length)) + (substring expanded-address prefix-length-nibbles) + (substring expanded-address 0 prefix-length-nibbles))))) + (with-temp-buffer + (loop for char across rev-address-nibbles + do + (insert char) + (insert ".")) + (if (and prefix-length + (minusp prefix-length)) + (delete-char -1) + (insert "ip6.arpa.")) + (insert " ") + (buffer-string)))) + (provide 'dns-mode) ;;; dns-mode.el ends here diff --git a/test/lisp/textmodes/dns-mode-tests.el b/test/lisp/textmodes/dns-mode-tests.el new file mode 100644 index 0000000000..34e86201d8 --- /dev/null +++ b/test/lisp/textmodes/dns-mode-tests.el @@ -0,0 +1,58 @@ +;;; dns-mode-tests.el --- Test suite for dns-mode -*- lexical-binding: t; -*- + +;; Copyright (C) 2017 Free Software Foundation, Inc. + +;; Author: Peder O. Klingenberg +;; Keywords: dns zone + +;; This file is part of GNU Emacs. + +;; GNU Emacs 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. + +;; GNU Emacs 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 GNU Emacs. If not, see . + +;;; Code: + +(require 'ert) +(require 'dns-mode) + +;;; IPv6 reverse zones +(ert-deftest dns-mode-ipv6-conversion () + (let ((address "2001:db8::42")) + (should (equal (dns-mode-reverse-and-expand-ipv6 address) + "2.4.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa. ")) + (should (equal (dns-mode-reverse-and-expand-ipv6 address 32) + "8.b.d.0.1.0.0.2.ip6.arpa. ")) + (should (equal (dns-mode-reverse-and-expand-ipv6 address -112) + "2.4.0.0 ")))) + +(ert-deftest dns-mode-ipv6-text-replacement () + (let ((address "2001:db8::42/32")) + (with-temp-buffer + ;; Conversion with point directly after address + (insert address) + (dns-mode-ipv6-to-nibbles nil) + (should (equal (buffer-string) "8.b.d.0.1.0.0.2.ip6.arpa. ")) + ;; Kill ring contains the expected + (erase-buffer) + (yank) + (should (equal (buffer-string) address)) + ;; Point at beginning of address (and prefix arg to command) + (goto-char (point-min)) + (dns-mode-ipv6-to-nibbles t) + (should (equal (buffer-string) "2.4.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 ")) + ;; Point separated from address by whitespace + (erase-buffer) + (insert address) + (insert " ") + (dns-mode-ipv6-to-nibbles nil) + (should (equal (buffer-string) "8.b.d.0.1.0.0.2.ip6.arpa. "))))) -- 2.11.0 --=-=-=--