Better buffer synchronization macro.
[iolib/alendvai.git] / net.sockets / address-predicates.lisp
blob94d56f0e0524b0f6854cdd012033e3af6a838449
1 ;;;; -*- Mode: Lisp; Syntax: ANSI-Common-Lisp; indent-tabs-mode: nil -*-
2 ;;;
3 ;;; --- Predicate functions for addresses.
4 ;;;
6 (in-package :net.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 `(define-constant ,name (ensure-address ,address-string)
15 :documentation ,(format nil "~A (~A)" docstring address-string)
16 :test 'address=))
18 (define-address +ipv4-unspecified+ "0.0.0.0" "Unspecified IPv4 address.")
19 (define-address +ipv4-loopback+ "127.0.0.1" "Loopback IPv4 address.")
20 (define-address +ipv6-unspecified+ "::" "Unspecified IPv6 address.")
21 (define-address +ipv6-loopback+ "::1" "Loopback IPv6 address.")
23 (define-symbol-macro +any-host+
24 (if *ipv6* +ipv6-unspecified+ +ipv4-unspecified+))
26 (define-symbol-macro +loopback+
27 (if *ipv6* +ipv6-loopback+ +ipv4-loopback+))
29 ;;;; Multicast addresses replacing IPv4 broadcast addresses
31 (define-address +ipv6-interface-local-all-nodes+ "ff01::1"
32 "Interface local all nodes address.")
34 (define-address +ipv6-link-local-all-nodes+ "ff02::1"
35 "Link local all nodes address.")
37 (define-address +ipv6-interface-local-all-routers+ "ff01::2"
38 "Interface local all routers address.")
40 (define-address +ipv6-link-local-all-routers+ "ff02::2"
41 "Link local all routers address.")
43 (define-address +ipv6-site-local-all-routers+ "ff05::2"
44 "Site local all routers address.")
46 ;;;; Predicates
48 (defun addressp (address)
49 "Returns T if ADDRESS is an object of class ADDRESS. Does not
50 return T for other low-level address representations."
51 (typep address 'address))
53 (defun inet-address-p (address)
54 "Returns T if ADDRESS is an Inet address object."
55 (typep address 'inet-address))
57 (defun ipv4-address-p (address)
58 "Returns T if ADDRESS is an IPv4 address object."
59 (typep address 'ipv4-address))
61 (defun ipv6-address-p (address)
62 "Returns T if ADDRESS is an IPv6 address object."
63 (typep address 'ipv6-address))
65 (defun local-address-p (address)
66 "Returns T if ADDRESS is a local address object."
67 (typep address 'local-address))
69 (defgeneric address-type (address)
70 (:documentation "Returns a keyword symbol denoting the kind of
71 ADDRESS (:IPV4, :IPV6 or :LOCAL). If ADDRESS is not a known
72 address object, NIL is returned.")
73 (:method ((address ipv4-address)) :ipv4)
74 (:method ((address ipv6-address)) :ipv6)
75 (:method ((address local-address)) :local)
76 (:method (address)
77 (declare (ignore address))
78 nil))
80 (defgeneric inet-address-unspecified-p (addr)
81 (:documentation "Returns T if ADDR is an \"unspecified\" internet address.")
82 (:method ((address ipv4-address))
83 (address= address +ipv4-unspecified+))
84 (:method ((address ipv6-address))
85 (address= address +ipv6-unspecified+)))
87 (defgeneric inet-address-loopback-p (address)
88 (:documentation "Returns T if ADDRESS is a loopback internet address.")
89 (:method ((address ipv4-address))
90 (address= address +ipv4-loopback+))
91 (:method ((address ipv6-address))
92 (address= address +ipv6-loopback+)))
94 (defgeneric inet-address-multicast-p (address)
95 (:documentation "Returns T if ADDRESS is an multicast internet address.")
96 (:method ((address ipv4-address))
97 (= (logand (aref (address-name address) 0) #xE0)
98 #xE0))
99 (:method ((address ipv6-address))
100 (= (logand (aref (address-name address) 0) #xFF00)
101 #xFF00)))
103 (defgeneric inet-address-unicast-p (address)
104 (:documentation "Returns T if ADDRESS is an unicast internet address.")
105 (:method ((address ipv4-address))
106 (and (not (inet-address-unspecified-p address))
107 (not (inet-address-loopback-p address))
108 (not (inet-address-multicast-p address))))
109 (:method ((address ipv6-address))
110 (or (ipv6-link-local-unicast-p address)
111 (and (not (inet-address-unspecified-p address))
112 (not (inet-address-loopback-p address))
113 (not (inet-address-multicast-p address))))))
115 (defun ipv6-ipv4-mapped-p (address)
116 "Returns T if ADDRESS is an IPv6 address representing an IPv4
117 mapped address."
118 (and (ipv6-address-p address)
119 (ipv4-on-ipv6-mapped-vector-p (address-name address))))
121 (defun ipv6-interface-local-multicast-p (address)
122 "Returns T if ADDRESS is an interface-local IPv6 address."
123 (check-type address ipv6-address "an IPv6 address")
124 (= (logand (aref (address-name address) 0) #xFF0F)
125 #xFF01))
127 (defun ipv6-link-local-multicast-p (address)
128 "Returns T if ADDRESS is a link-local IPv6 address."
129 (check-type address ipv6-address "an IPv6 address")
130 (= (logand (aref (address-name address) 0) #xFF0F)
131 #xFF02))
133 (defun ipv6-admin-local-multicast-p (address)
134 "Returns T if ADDRESS is a admin-local multicast IPv6 address."
135 (check-type address ipv6-address "an IPv6 address")
136 (= (logand (aref (address-name address) 0) #xFF0F)
137 #xFF04))
139 (defun ipv6-site-local-multicast-p (address)
140 "Returns T if ADDRESS is an site-local multicast IPv6 address."
141 (check-type address ipv6-address "an IPv6 address")
142 (= (logand (aref (address-name address) 0) #xFF0F)
143 #xFF05))
145 (defun ipv6-organization-local-multicast-p (address)
146 "Returns T if ADDRESS is an organization-local multicast IPv6 address."
147 (check-type address ipv6-address "an IPv6 address")
148 (= (logand (aref (address-name address) 0) #xFF0F)
149 #xFF08))
151 (defun ipv6-global-multicast-p (address)
152 "Returns T if ADDRESS is a global multicast IPv6 address."
153 (check-type address ipv6-address "an IPv6 address")
154 (= (logand (aref (address-name address) 0) #xFF0F)
155 #xFF0E))
157 (defun ipv6-reserved-multicast-p (address)
158 "Returns T if ADDRESS is a reserved multicast IPv6 address."
159 (check-type address ipv6-address "an IPv6 address")
160 (member (logand (aref (address-name address) 0) #xFF0F)
161 '(#xFF00 #xFF03 #xFF0F)))
163 (defun ipv6-unassigned-multicast-p (address)
164 "Returns T if ADDRESS is an unassigned multicast IPv6 address."
165 (check-type address ipv6-address "an IPv6 address")
166 (member (logand (aref (address-name address) 0) #xFF0F)
167 '(#xFF06 #xFF07 #xFF09 #xFF0A #xFF0B #xFF0C #xFF0D)))
169 (defun ipv6-transient-multicast-p (address)
170 "Returns T if ADDRESS is a transient multicast IPv6 address."
171 (check-type address ipv6-address "an IPv6 address")
172 (= (logand (aref (address-name address) 0) #xFF10)
173 #xFF10))
175 (defun ipv6-solicited-node-multicast-p (address)
176 "Returns T if ADDRESS is a solicited-node multicast IPv6 address."
177 (check-type address ipv6-address "an IPv6 address")
178 (let ((vec (address-name address)))
179 (and (= (aref vec 0) #xFF02) ; link-local permanent multicast
180 (= (aref vec 5) 1)
181 (= (logand (aref vec 6) #xFF00)
182 #xFF00))))
184 (defun ipv6-link-local-unicast-p (address)
185 "Returns T if ADDRESS is an link-local unicast IPv6 address."
186 (check-type address ipv6-address "an IPv6 address")
187 (= (aref (address-name address) 0) #xFE80))
189 (defun ipv6-site-local-unicast-p (address)
190 "Returns T if ADDRESS is an site-local unicast IPv6 address."
191 (check-type address ipv6-address "an IPv6 address")
192 (= (aref (address-name address) 0) #xFEC0))
194 (defun ipv6-global-unicast-p (address)
195 "Returns T if ADDRESS is an global unicasst IPv6 address."
196 (check-type address ipv6-address "an IPv6 address")
197 (and (not (inet-address-unspecified-p address))
198 (not (inet-address-loopback-p address))
199 (not (inet-address-multicast-p address))
200 (not (ipv6-link-local-unicast-p address))))
202 (defun ipv6-multicast-type (address)
203 "Returns the multicast type of ADDRESS or NIL if it's not a
204 multicast address."
205 (check-type address ipv6-address "an IPv6 address")
206 (cond
207 ((ipv6-interface-local-multicast-p address) :interface-local)
208 ((ipv6-link-local-multicast-p address) :link-local)
209 ((ipv6-admin-local-multicast-p address) :admin-local)
210 ((ipv6-site-local-multicast-p address) :site-local)
211 ((ipv6-organization-local-multicast-p address) :organization-local)
212 ((ipv6-global-multicast-p address) :global)
213 ((ipv6-reserved-multicast-p address) :reserved)
214 ((ipv6-unassigned-multicast-p address) :unassigned)))
216 (defun ipv6-unicast-type (address)
217 "Returns the unicast type of ADDRESS or NIL if it's not a
218 unicast address."
219 (check-type address ipv6-address "an IPv6 address")
220 (cond
221 ((ipv6-link-local-unicast-p address) :link-local)
222 ((ipv6-site-local-unicast-p address) :site-local)
223 ((ipv6-global-unicast-p address) :global)))
225 (defgeneric inet-address-type (address)
226 (:documentation "Returns the address type of ADDRESS as 2 values:
228 * protocol, one of :IPV4 or :IPV6
229 * kind, one of :UNSPECIFIED, :LOOPBACK, :MULTICAST or :UNICAST
231 For unicast or multicast IPv6 addresses, a third value is
232 returned which corresponds to the return value of
233 IPV6-UNICAST-TYPE or IPV6-MULTICAST-TYPE, respectively." ))
235 (defmethod inet-address-type ((addr ipv6-address))
236 (cond
237 ((inet-address-unspecified-p addr) (values :ipv6 :unspecified))
238 ((inet-address-loopback-p addr) (values :ipv6 :loopback))
239 ((inet-address-multicast-p addr)
240 (values :ipv6 :multicast (ipv6-multicast-type addr)))
241 (t (values :ipv6 :unicast (ipv6-unicast-type addr)))))
243 (defmethod inet-address-type ((addr ipv4-address))
244 (values :ipv4
245 (cond
246 ((inet-address-unspecified-p addr) :unspecified)
247 ((inet-address-loopback-p addr) :loopback)
248 ((inet-address-multicast-p addr) :multicast)
249 ((inet-address-unicast-p addr) :unicast))))