next up previous contents
Next: Restricting check names Up: Hosts files Previous: Hosts files   Contents


IP addresses

An IP address, as mentioned before, consists of four numbers between 0 and 255 separated by dots. If we don't want to use a regular expression for this, we should use some Lisp code. Specifically, we need a function which takes a string as an argument and returns a boolean based on whether or not the string is a valid IP address:

(defun ip-address-p (string)
  (multiple-value-bind (matched groups)
      (cl-ppcre:scan-to-strings
       "^([0-9]{0,3})\.([0-9]{0,3})\.([0-9]{0,3})\.([0-9]{0,3})$"
       string)
    (let ((numbers (mapcar #'read-from-string (coerce groups 'list))))
      (and matched
           (every #'(lambda (number)
                      (<= 0 number 255))
                  numbers)))))

This function makes sure that a basic regular expression matches and uses it to pull apart the string. It then checks that each of the four numbers are in the proper range. Let's test it:

* (ip-address-p "12.36.212.56")

T
* (ip-address-p "12.00000.212.56")

NIL
* (ip-address-p "12.512.212.56")

NIL
* (ip-address-p "12.512.212.hello")

NIL

It sure seems to work. Now that we have this, though, what do we do with it? We plug it into our validation code:

(toplevel-match
 (tag "hostlist" ()
      (tag+ "host" ((attr "name" :matches-regexp "[a-zA-Z]+"))
            (tag "ip" ()
                 (pcdata :test-fn #'ip-address-p))
            (tag? "description" ()
                  (pcdata))
            (tag "checks" ()
                 (tag+ "check" ()
                       (pcdata)))))
 (parse-xml-file "hosts.xml"))

Try messing up IP addresses in the hosts.xml file and running the new code. It now detects problems!



root 2004-10-26