+(defun process-net-form (root addr subnets)
+ "Unpack a net-form. The return value is a list of entries, each of which
+is a list of the form (NAME ADDR MASK). The first entry is merely repeats
+the given ROOT and ADDR arguments (unpacking ADDR into separate network
+address and mask). The SUBNETS are then processed: they are a list of items
+of the form (NAME NUM-HOSTS . SUBNETS), where NAME names the subnet,
+NUM-HOSTS is the number of hosts in it, and SUBNETS are its sub-subnets in
+the same form. An error is signalled if a net's subnets use up more hosts
+than the net has to start with."
+ (labels ((frob (subnets limit finger)
+ (when subnets
+ (destructuring-bind (name size &rest subs) (car subnets)
+ (when (> (count-low-zero-bits size)
+ (count-low-zero-bits finger))
+ (error "Bad subnet size for ~A." name))
+ (when (> (+ finger size) limit)
+ (error "Subnet ~A out of range." name))
+ (append (and name
+ (list (list name finger (- (ash 1 32) size))))
+ (frob subs (+ finger size) finger)
+ (frob (cdr subnets) limit (+ finger size)))))))
+ (let ((ipn (ipnet addr)))
+ (with-ipnet (net mask) ipn
+ (unless (ipmask-cidl-slash mask)
+ (error "Bad mask for subnet form."))
+ (cons (list root net mask)
+ (frob subnets (+ net (ipnet-hosts ipn) 1) net))))))
+
+(defun net-create (name net)