chiark / gitweb /
net.lisp, sys.lisp: Merge packages.
[zone] / net.lisp
index 08efe56ed2b9fd18f4052ed1d832da6c9b751f41..e764581e9780d96ee7fe9fdb5d5e249a2eecad8b 100644 (file)
--- a/net.lisp
+++ b/net.lisp
@@ -1,7 +1,5 @@
 ;;; -*-lisp-*-
 ;;;
-;;; $Id$
-;;;
 ;;; Network (numbering) tools
 ;;;
 ;;; (c) 2006 Straylight/Edgeware
 ;;; it under the terms of the GNU General Public License as published by
 ;;; the Free Software Foundation; either version 2 of the License, or
 ;;; (at your option) any later version.
-;;; 
+;;;
 ;;; This program 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 this program; if not, write to the Free Software Foundation,
 ;;; Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
-;;;--------------------------------------------------------------------------
-;;; Packaging.
-
-(defpackage #:net
-  (:use #:common-lisp #:mdw.base #:mdw.str #:collect)
-  (:export #:ipaddr #:string-ipaddr #:ipaddr-byte #:ipaddr-string #:ipaddrp
-          #:integer-netmask #:ipmask #:ipmask-cidl-slash #:make-ipnet
-            #:string-ipnet #:ipnet #:ipnet-net #:ipnet-mask #:with-ipnet
-            #:ipnet-pretty #:ipnet-string #:ipnet-broadcast #:ipnet-hosts
-            #:ipnet-host #:ipaddr-networkp #:ipnet-subnetp
-            #:ipnet-changeable-bytes
-          #:host-find #:host-create #:defhost #:parse-ipaddr
-            #:resolve-hostname #:canonify-hostname
-            #:net #:net-find #:net-get-as-ipnet #:net-create #:defnet
-            #:net-next-host #:net-host))
-
 (in-package #:net)
 
 ;;;--------------------------------------------------------------------------
@@ -52,6 +34,7 @@ (deftype u32 ()
   "The type of unsigned 32-bit values."
   '(unsigned-byte 32))
 
+(export 'ipaddr)
 (deftype ipaddr ()
   "The type of IP (version 4) addresses."
   'u32)
@@ -69,14 +52,14 @@ (defun count-low-zero-bits (n)
 ;;;--------------------------------------------------------------------------
 ;;; Simple messing with IP addresses.
 
+(export 'string-ipaddr)
 (defun string-ipaddr (str &key (start 0) (end nil))
   "Parse STR as an IP address in dotted-quad form and return the integer
    equivalent.  STR may be anything at all: it's converted as if by
    `stringify'.  The START and END arguments may be used to parse out a
    substring."
   (setf str (stringify str))
-  (unless end
-    (setf end (length str)))
+  (setf-default end (length str))
   (let ((addr 0) (noct 0))
     (loop
       (let* ((pos (position #\. str :start start :end end))
@@ -92,11 +75,13 @@ (defun string-ipaddr (str &key (start 0) (end nil))
       (error "Wrong number of octets in IP address"))
     addr))
 
+(export 'ipaddr-byte)
 (defun ipaddr-byte (ip n)
   "Return byte N (from most significant downwards) of an IP address."
   (assert (<= 0 n 3))
   (logand #xff (ash ip (* -8 (- 3 n)))))
 
+(export 'ipaddr-string)
 (defun ipaddr-string (ip)
   "Transform the address IP into a string in dotted-quad form."
   (check-type ip ipaddr)
@@ -104,6 +89,7 @@ (defun ipaddr-string (ip)
                      (dotimes (i 4)
                        (collect (ipaddr-byte ip i))))))
 
+(export 'ipaddrp)
 (defun ipaddrp (ip)
   "Answer true if IP is a valid IP address in integer form."
   (typep ip 'ipaddr))
@@ -118,10 +104,12 @@ (defun ipaddr (ip)
 ;;;--------------------------------------------------------------------------
 ;;; Netmasks.
 
+(export 'integer-netmask)
 (defun integer-netmask (i)
   "Given an integer I, return a netmask with its I top bits set."
   (- (ash 1 32) (ash 1 (- 32 i))))
 
+(export 'ipmask)
 (defun ipmask (ip)
   "Transform IP into a netmask.  If it's a small integer then it's converted
    by `integer-netmask'; if nil, then all-bits-set; otherwise convert using
@@ -131,6 +119,7 @@ (defun ipmask (ip)
     ((integer 0 32) (integer-netmask ip))
     (t (ipaddr ip))))
 
+(export 'ipmask-cidl-slash)
 (defun ipmask-cidl-slash (mask)
   "Given a netmask MASK, return an integer N such that (integer-netmask N) =
    MASK, or nil if this is impossible."
@@ -141,6 +130,7 @@ (defun ipmask-cidl-slash (mask)
 ;;;--------------------------------------------------------------------------
 ;;; Networks: pairing an address and netmask.
 
+(export 'make-ipnet)
 (defun make-ipnet (net mask)
   "Construct an IP-network object given the NET and MASK; these are
    transformed as though by `ipaddr' and `ipmask'."
@@ -148,10 +138,11 @@ (defun make-ipnet (net mask)
        (mask (ipmask mask)))
     (cons (logand net mask) mask)))
 
+(export 'string-ipnet)
 (defun string-ipnet (str &key (start 0) (end nil))
   "Parse an IP-network from the string STR."
   (setf str (stringify str))
-  (unless end (setf end (length str)))
+  (setf-default end (length str))
   (let ((sl (position #\/ str :start start :end end)))
     (if sl
        (make-ipnet (parse-ipaddr (subseq str start sl))
@@ -163,6 +154,7 @@ (defun string-ipnet (str &key (start 0) (end nil))
        (make-ipnet (parse-ipaddr (subseq str start end))
                    (integer-netmask 32)))))
 
+(export 'ipnet)
 (defun ipnet (net)
   "Construct an IP-network object from the given argument.  A number of forms
    are acceptable:
@@ -174,14 +166,17 @@ (defun ipnet (net)
   (cond ((or (stringp net) (symbolp net)) (string-ipnet net))
        (t (apply #'make-ipnet (pairify net 32)))))
 
+(export 'ipnet-net)
 (defun ipnet-net (ipn)
   "Return the base network address of IPN."
   (car ipn))
 
+(export 'ipnet-mask)
 (defun ipnet-mask (ipn)
   "Return the netmask of IPN."
   (cdr ipn))
 
+(export 'with-ipnet)
 (defmacro with-ipnet ((net mask) ipn &body body)
   "Evaluate BODY with NET and MASK bound to the base address and netmask of
    IPN.  Either NET or MASK (or, less usefully, both) may be nil if not
@@ -192,12 +187,14 @@ (defmacro with-ipnet ((net mask) ipn &body body)
             ,@(and mask `((,mask (ipnet-mask ,tmp)))))
         ,@body))))
 
+(export 'ipnet-pretty)
 (defun ipnet-pretty (ipn)
   "Convert IPN to a pretty cons-cell form."
   (with-ipnet (net mask) ipn
     (cons (ipaddr-string net)
          (or (ipmask-cidl-slash mask) (ipaddr-string mask)))))
 
+(export 'ipnet-string)
 (defun ipnet-string (ipn)
   "Convert IPN to a string."
   (with-ipnet (net mask) ipn
@@ -205,15 +202,18 @@ (defun ipnet-string (ipn)
            (ipaddr-string net)
            (or (ipmask-cidl-slash mask) (ipaddr-string mask)))))
 
+(export 'ipnet-broadcast)
 (defun ipnet-broadcast (ipn)
   "Return the broadcast address for the network IPN."
   (with-ipnet (net mask) ipn
     (logior net (logxor (mask 32) mask))))
 
+(export 'ipnet-hosts)
 (defun ipnet-hosts (ipn)
   "Return the number of available addresses in network IPN."
   (ash 1 (- 32 (logcount (ipnet-mask ipn)))))
 
+(export 'ipnet-host)
 (defun ipnet-host (ipn host)
   "Return the address of the given HOST in network IPN.  This works even with
    a non-contiguous netmask."
@@ -234,11 +234,13 @@ (defun ipnet-host (ipn host)
        (setf m (ash m 1))
        (incf i)))))
 
+(export 'ipaddr-networkp)
 (defun ipaddr-networkp (ip ipn)
   "Returns true if address IP is within network IPN."
   (with-ipnet (net mask) ipn
     (= net (logand ip mask))))
 
+(export 'ipnet-subnetp)
 (defun ipnet-subnetp (ipn subn)
   "Returns true if SUBN is a (non-strict) subnet of IPN."
   (with-ipnet (net mask) ipn
@@ -246,6 +248,7 @@ (defun ipnet-subnetp (ipn subn)
       (and (= net (logand subnet mask))
           (= submask (logior mask submask))))))
 
+(export 'ipnet-changeable-bytes)
 (defun ipnet-changeable-bytes (mask)
   "Answers how many low-order bytes of MASK are (entirely or partially)
    changeable.  This is used when constructing reverse zones."
@@ -253,27 +256,10 @@ (defun ipnet-changeable-bytes (mask)
     (when (/= (ipaddr-byte mask i) 255)
       (return (- 4 i)))))
 
-;;;--------------------------------------------------------------------------
-;;; Name resolution.
-
-(defun resolve-hostname (name)
-  "Resolve a hostname to an IP address using the DNS, or return nil."
-  #+cmu (let ((he (ext:lookup-host-entry name)))
-         (and he
-              (ext:host-entry-addr he)))
-  #-cmu nil
-)
-
-(defun canonify-hostname (name)
-  "Resolve a hostname to canonical form using the DNS, or return nil."
-  #+cmu (let ((he (ext:lookup-host-entry name)))
-         (and he
-              (ext:host-entry-name he)))
-  #-cmu nil)
-
 ;;;--------------------------------------------------------------------------
 ;;; Host names and specifiers.
 
+(export 'parse-ipaddr)
 (defun parse-ipaddr (addr)
   "Convert the string ADDR into an IP address: tries all sorts of things:
 
@@ -308,18 +294,20 @@ (defun parse-ipaddr (addr)
 (defvar *hosts* (make-hash-table :test #'equal)
   "The table of known hostnames.")
 
+(export 'host-find)
 (defun host-find (name)
   "Find a host by NAME."
   (gethash (string-downcase (stringify name)) *hosts*))
-
 (defun (setf host-find) (addr name)
   "Make NAME map to ADDR (must be an ipaddr in integer form)."
   (setf (gethash (string-downcase (stringify name)) *hosts*) addr))
 
+(export 'host-create)
 (defun host-create (name addr)
   "Make host NAME map to ADDR (anything acceptable to parse-ipaddr)."
   (setf (host-find name) (parse-ipaddr addr)))
 
+(export 'defhost)
 (defmacro defhost (name addr)
   "Main host definition macro.  Neither NAME nor ADDR is evaluated."
   `(progn
@@ -329,6 +317,7 @@ (defmacro defhost (name addr)
 ;;;--------------------------------------------------------------------------
 ;;; Network names and specifiers.
 
+(export 'net)
 (defstruct (net (:predicate netp))
   "A network structure.  Slots:
 
@@ -344,14 +333,15 @@ (defstruct (net (:predicate netp))
 (defvar *networks* (make-hash-table :test #'equal)
   "The table of known networks.")
 
+(export 'net-find)
 (defun net-find (name)
   "Find a network by NAME."
   (gethash (string-downcase (stringify name)) *networks*))
-
 (defun (setf net-find) (net name)
   "Make NAME map to NET."
   (setf (gethash (string-downcase (stringify name)) *networks*) net))
 
+(export 'net-get-as-ipnet)
 (defun net-get-as-ipnet (form)
   "Transform FORM into an ipnet.  FORM may be a network name, or something
 acceptable to the ipnet function."
@@ -387,6 +377,7 @@ (defun process-net-form (root addr subnets)
        (cons (list root net mask)
              (frob subnets (+ net (ipnet-hosts ipn) 1) net))))))
 
+(export 'net-create)
 (defun net-create (name net)
   "Construct a new network called NAME and add it to the map.  The ARGS
    describe the new network, in a form acceptable to the ipnet function."
@@ -397,6 +388,7 @@ (defun net-create (name net)
                    :hosts (ipnet-hosts ipn)
                    :next 1))))
 
+(export 'defnet)
 (defmacro defnet (name net &rest subnets)
   "Main network definition macro.  None of the arguments is evaluated."
   `(progn
@@ -404,6 +396,7 @@ (defmacro defnet (name net &rest subnets)
            collect `(net-create ',name '(,addr . ,mask)))
     ',name))
 
+(export 'net-next-host)
 (defun net-next-host (net)
   "Given a NET, return the IP address (as integer) of the next available
    address in the network."
@@ -413,6 +406,7 @@ (defun net-next-host (net)
     (incf (net-next net))
     (net-host net next)))
 
+(export 'net-host)
 (defun net-host (net host)
   "Return the given HOST on the NEXT.  HOST may be an index (in range, of
    course), or one of the keywords: