Mark ENOLINK and EMULTIHOP as optional
[iolib.git] / src / sockets / address-predicates.lisp
blob69d69c8ff7aecfc3e0930c1f459c243fa0e2a698
1 ;;;; -*- Mode: Lisp; indent-tabs-mode: nil -*-
2 ;;;
3 ;;; --- Predicate functions for addresses.
4 ;;;
6 (in-package :iolib/sockets)
8 ;;;; Well-known addresses
10 ;;; Defines a constant address. We need ENSURE-ADDRESS at compile
11 ;;; time which is why these functions are in a separate file from
12 ;;; address.lisp.
13 (defmacro define-address (name address-string docstring)
14 `(defconstant (,name :test 'address=) (ensure-address ,address-string)
15 ,(format nil "~A (~A)" docstring address-string)))
17 (define-address +ipv4-unspecified+ "0.0.0.0" "Unspecified IPv4 address.")
18 (define-address +ipv4-loopback+ "127.0.0.1" "Loopback IPv4 address.")
19 (define-address +ipv6-unspecified+ "::" "Unspecified IPv6 address.")
20 (define-address +ipv6-loopback+ "::1" "Loopback IPv6 address.")
22 (define-symbol-macro +any-host+
23 (if *ipv6* +ipv6-unspecified+ +ipv4-unspecified+))
25 (define-symbol-macro +loopback+
26 (if *ipv6* +ipv6-loopback+ +ipv4-loopback+))
28 ;;;; Multicast addresses replacing IPv4 broadcast addresses
30 (define-address +ipv6-interface-local-all-nodes+ "ff01::1"
31 "Interface local all nodes address.")
33 (define-address +ipv6-link-local-all-nodes+ "ff02::1"
34 "Link local all nodes address.")
36 (define-address +ipv6-interface-local-all-routers+ "ff01::2"
37 "Interface local all routers address.")
39 (define-address +ipv6-link-local-all-routers+ "ff02::2"
40 "Link local all routers address.")
42 (define-address +ipv6-site-local-all-routers+ "ff05::2"
43 "Site local all routers address.")
45 ;;;; Predicates
47 (defun addressp (address)
48 "Returns T if ADDRESS is an object of class ADDRESS. Does not
49 return T for other low-level address representations."
50 (typep address 'address))
52 (defun inet-address-p (address)
53 "Returns T if ADDRESS is an Inet address object."
54 (typep address 'inet-address))
56 (defun ipv4-address-p (address)
57 "Returns T if ADDRESS is an IPv4 address object."
58 (typep address 'ipv4-address))
60 (defun ipv6-address-p (address)
61 "Returns T if ADDRESS is an IPv6 address object."
62 (typep address 'ipv6-address))
64 (defun local-address-p (address)
65 "Returns T if ADDRESS is a local address object."
66 (typep address 'local-address))
68 (defgeneric address-type (address)
69 (:documentation "Returns a keyword symbol denoting the kind of
70 ADDRESS (:IPV4, :IPV6 or :LOCAL). If ADDRESS is not a known
71 address object, NIL is returned.")
72 (:method ((address ipv4-address)) :ipv4)
73 (:method ((address ipv6-address)) :ipv6)
74 (:method ((address local-address)) :local)
75 (:method (address)
76 (declare (ignore address))
77 nil))
79 (defgeneric inet-address-unspecified-p (addr)
80 (:documentation "Returns T if ADDR is an \"unspecified\" internet address.")
81 (:method ((address ipv4-address))
82 (address= address +ipv4-unspecified+))
83 (:method ((address ipv6-address))
84 (address= address +ipv6-unspecified+)))
86 (defgeneric inet-address-loopback-p (address)
87 (:documentation "Returns T if ADDRESS is a loopback internet address.")
88 (:method ((address ipv4-address))
89 (address= address +ipv4-loopback+))
90 (:method ((address ipv6-address))
91 (address= address +ipv6-loopback+)))
93 (defgeneric inet-address-multicast-p (address)
94 (:documentation "Returns T if ADDRESS is an multicast internet address.")
95 (:method ((address ipv4-address))
96 (= (logand (aref (address-name address) 0) #xE0)
97 #xE0))
98 (:method ((address ipv6-address))
99 (= (logand (aref (address-name address) 0) #xFF00)
100 #xFF00)))
102 (defgeneric inet-address-unicast-p (address)
103 (:documentation "Returns T if ADDRESS is an unicast internet address.")
104 (:method ((address ipv4-address))
105 (and (not (inet-address-unspecified-p address))
106 (not (inet-address-loopback-p address))
107 (not (inet-address-multicast-p address))))
108 (:method ((address ipv6-address))
109 (or (ipv6-link-local-unicast-p address)
110 (and (not (inet-address-unspecified-p address))
111 (not (inet-address-loopback-p address))
112 (not (inet-address-multicast-p address))))))
114 (defun ipv6-ipv4-mapped-p (address)
115 "Returns T if ADDRESS is an IPv6 address representing an IPv4
116 mapped address."
117 (and (ipv6-address-p address)
118 (ipv4-on-ipv6-mapped-vector-p (address-name address))))
120 (defun ipv6-interface-local-multicast-p (address)
121 "Returns T if ADDRESS is an interface-local IPv6 address."
122 (check-type address ipv6-address "an IPv6 address")
123 (= (logand (aref (address-name address) 0) #xFF0F)
124 #xFF01))
126 (defun ipv6-link-local-multicast-p (address)
127 "Returns T if ADDRESS is a link-local IPv6 address."
128 (check-type address ipv6-address "an IPv6 address")
129 (= (logand (aref (address-name address) 0) #xFF0F)
130 #xFF02))
132 (defun ipv6-admin-local-multicast-p (address)
133 "Returns T if ADDRESS is a admin-local multicast IPv6 address."
134 (check-type address ipv6-address "an IPv6 address")
135 (= (logand (aref (address-name address) 0) #xFF0F)
136 #xFF04))
138 (defun ipv6-site-local-multicast-p (address)
139 "Returns T if ADDRESS is an site-local multicast IPv6 address."
140 (check-type address ipv6-address "an IPv6 address")
141 (= (logand (aref (address-name address) 0) #xFF0F)
142 #xFF05))
144 (defun ipv6-organization-local-multicast-p (address)
145 "Returns T if ADDRESS is an organization-local multicast IPv6 address."
146 (check-type address ipv6-address "an IPv6 address")
147 (= (logand (aref (address-name address) 0) #xFF0F)
148 #xFF08))
150 (defun ipv6-global-multicast-p (address)
151 "Returns T if ADDRESS is a global multicast IPv6 address."
152 (check-type address ipv6-address "an IPv6 address")
153 (= (logand (aref (address-name address) 0) #xFF0F)
154 #xFF0E))
156 (defun ipv6-reserved-multicast-p (address)
157 "Returns T if ADDRESS is a reserved multicast IPv6 address."
158 (check-type address ipv6-address "an IPv6 address")
159 (member (logand (aref (address-name address) 0) #xFF0F)
160 '(#xFF00 #xFF03 #xFF0F)))
162 (defun ipv6-unassigned-multicast-p (address)
163 "Returns T if ADDRESS is an unassigned multicast IPv6 address."
164 (check-type address ipv6-address "an IPv6 address")
165 (member (logand (aref (address-name address) 0) #xFF0F)
166 '(#xFF06 #xFF07 #xFF09 #xFF0A #xFF0B #xFF0C #xFF0D)))
168 (defun ipv6-transient-multicast-p (address)
169 "Returns T if ADDRESS is a transient multicast IPv6 address."
170 (check-type address ipv6-address "an IPv6 address")
171 (= (logand (aref (address-name address) 0) #xFF10)
172 #xFF10))
174 (defun ipv6-solicited-node-multicast-p (address)
175 "Returns T if ADDRESS is a solicited-node multicast IPv6 address."
176 (check-type address ipv6-address "an IPv6 address")
177 (let ((vec (address-name address)))
178 (and (= (aref vec 0) #xFF02) ; link-local permanent multicast
179 (= (aref vec 5) 1)
180 (= (logand (aref vec 6) #xFF00)
181 #xFF00))))
183 (defun ipv6-link-local-unicast-p (address)
184 "Returns T if ADDRESS is an link-local unicast IPv6 address."
185 (check-type address ipv6-address "an IPv6 address")
186 (= (aref (address-name address) 0) #xFE80))
188 (defun ipv6-site-local-unicast-p (address)
189 "Returns T if ADDRESS is an site-local unicast IPv6 address."
190 (check-type address ipv6-address "an IPv6 address")
191 (= (aref (address-name address) 0) #xFEC0))
193 (defun ipv6-global-unicast-p (address)
194 "Returns T if ADDRESS is an global unicasst IPv6 address."
195 (check-type address ipv6-address "an IPv6 address")
196 (and (not (inet-address-unspecified-p address))
197 (not (inet-address-loopback-p address))
198 (not (inet-address-multicast-p address))
199 (not (ipv6-link-local-unicast-p address))))
201 (defun ipv6-multicast-type (address)
202 "Returns the multicast type of ADDRESS or NIL if it's not a
203 multicast address."
204 (check-type address ipv6-address "an IPv6 address")
205 (cond
206 ((ipv6-interface-local-multicast-p address) :interface-local)
207 ((ipv6-link-local-multicast-p address) :link-local)
208 ((ipv6-admin-local-multicast-p address) :admin-local)
209 ((ipv6-site-local-multicast-p address) :site-local)
210 ((ipv6-organization-local-multicast-p address) :organization-local)
211 ((ipv6-global-multicast-p address) :global)
212 ((ipv6-reserved-multicast-p address) :reserved)
213 ((ipv6-unassigned-multicast-p address) :unassigned)))
215 (defun ipv6-unicast-type (address)
216 "Returns the unicast type of ADDRESS or NIL if it's not a
217 unicast address."
218 (check-type address ipv6-address "an IPv6 address")
219 (cond
220 ((ipv6-link-local-unicast-p address) :link-local)
221 ((ipv6-site-local-unicast-p address) :site-local)
222 ((ipv6-global-unicast-p address) :global)))
224 (defgeneric inet-address-type (address)
225 (:documentation "Returns the address type of ADDRESS as 2 values:
227 * protocol, one of :IPV4 or :IPV6
228 * kind, one of :UNSPECIFIED, :LOOPBACK, :MULTICAST or :UNICAST
230 For unicast or multicast IPv6 addresses, a third value is
231 returned which corresponds to the return value of
232 IPV6-UNICAST-TYPE or IPV6-MULTICAST-TYPE, respectively." ))
234 (defmethod inet-address-type ((addr ipv6-address))
235 (cond
236 ((inet-address-unspecified-p addr) (values :ipv6 :unspecified))
237 ((inet-address-loopback-p addr) (values :ipv6 :loopback))
238 ((inet-address-multicast-p addr)
239 (values :ipv6 :multicast (ipv6-multicast-type addr)))
240 (t (values :ipv6 :unicast (ipv6-unicast-type addr)))))
242 (defmethod inet-address-type ((addr ipv4-address))
243 (values :ipv4
244 (cond
245 ((inet-address-unspecified-p addr) :unspecified)
246 ((inet-address-loopback-p addr) :loopback)
247 ((inet-address-multicast-p addr) :multicast)
248 ((inet-address-unicast-p addr) :unicast))))