1 ;;;; -*- Mode: Lisp; Syntax: ANSI-Common-Lisp; Indent-tabs-mode: NIL -*-
3 ;;; address-predicates.lisp --- Predicate functions for addresses.
5 ;;; Copyright (C) 2006-2007, Stelian Ionescu <sionescu@common-lisp.net>
7 ;;; This code is free software; you can redistribute it and/or
8 ;;; modify it under the terms of the version 2.1 of
9 ;;; the GNU Lesser General Public License as published by
10 ;;; the Free Software Foundation, as clarified by the
11 ;;; preamble found here:
12 ;;; http://opensource.franz.com/preamble.html
14 ;;; This program is distributed in the hope that it will be useful,
15 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;;; GNU General Public License for more details.
19 ;;; You should have received a copy of the GNU Lesser General
20 ;;; Public License along with this library; if not, write to the
21 ;;; Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
22 ;;; Boston, MA 02110-1301, USA
24 (in-package :net.sockets
)
26 ;;;; Well-known addresses
28 ;;; Defines a constant address. We need ENSURE-ADDRESS at compile
29 ;;; time which is why these functions are in a separate file from
31 (defmacro define-address
(name address-string docstring
)
32 `(define-constant ,name
(ensure-address ,address-string
)
33 :documentation
,(format nil
"~A (~A)" docstring address-string
)
36 (define-address +ipv4-unspecified
+ "0.0.0.0" "Unspecified IPv4 address.")
37 (define-address +ipv4-loopback
+ "127.0.0.1" "Loopback IPv4 address.")
38 (define-address +ipv6-unspecified
+ "::" "Unspecified IPv6 address.")
39 (define-address +ipv6-loopback
+ "::1" "Loopback IPv6 address.")
41 (define-symbol-macro +any-host
+
42 (if *ipv6
* +ipv6-unspecified
+ +ipv4-unspecified
+))
44 (define-symbol-macro +loopback
+
45 (if *ipv6
* +ipv6-loopback
+ +ipv4-loopback
+))
47 ;;;; Multicast addresses replacing IPv4 broadcast addresses
49 (define-address +ipv6-interface-local-all-nodes
+ "ff01::1"
50 "Interface local all nodes address.")
52 (define-address +ipv6-link-local-all-nodes
+ "ff02::1"
53 "Link local all nodes address.")
55 (define-address +ipv6-interface-local-all-routers
+ "ff01::2"
56 "Interface local all routers address.")
58 (define-address +ipv6-link-local-all-routers
+ "ff02::2"
59 "Link local all routers address.")
61 (define-address +ipv6-site-local-all-routers
+ "ff05::2"
62 "Site local all routers address.")
66 (defun addressp (address)
67 "Returns T if ADDRESS is an object of class ADDRESS. Does not
68 return T for other low-level address representations."
69 (typep address
'address
))
71 (defun inet-address-p (address)
72 "Returns T if ADDRESS is an Inet address object."
73 (typep address
'inet-address
))
75 (defun ipv4-address-p (address)
76 "Returns T if ADDRESS is an IPv4 address object."
77 (typep address
'ipv4-address
))
79 (defun ipv6-address-p (address)
80 "Returns T if ADDRESS is an IPv6 address object."
81 (typep address
'ipv6-address
))
83 (defun local-address-p (address)
84 "Returns T if ADDRESS is a local address object."
85 (typep address
'local-address
))
87 (defgeneric address-type
(address)
88 (:documentation
"Returns a keyword symbol denoting the kind of
89 ADDRESS (:IPV4, :IPV6 or :LOCAL). If ADDRESS is not a known
90 address object, NIL is returned.")
91 (:method
((address ipv4-address
)) :ipv4
)
92 (:method
((address ipv6-address
)) :ipv6
)
93 (:method
((address local-address
)) :local
)
95 (declare (ignore address
))
98 (defgeneric inet-address-unspecified-p
(addr)
99 (:documentation
"Returns T if ADDR is an \"unspecified\" internet address.")
100 (:method
((address ipv4-address
))
101 (address= address
+ipv4-unspecified
+))
102 (:method
((address ipv6-address
))
103 (address= address
+ipv6-unspecified
+)))
105 (defgeneric inet-address-loopback-p
(address)
106 (:documentation
"Returns T if ADDRESS is a loopback internet address.")
107 (:method
((address ipv4-address
))
108 (address= address
+ipv4-loopback
+))
109 (:method
((address ipv6-address
))
110 (address= address
+ipv6-loopback
+)))
112 (defgeneric inet-address-multicast-p
(address)
113 (:documentation
"Returns T if ADDRESS is an multicast internet address.")
114 (:method
((address ipv4-address
))
115 (= (logand (aref (address-name address
) 0) #xE0
)
117 (:method
((address ipv6-address
))
118 (= (logand (aref (address-name address
) 0) #xFF00
)
121 (defgeneric inet-address-unicast-p
(address)
122 (:documentation
"Returns T if ADDRESS is an unicast internet address.")
123 (:method
((address ipv4-address
))
124 (and (not (inet-address-unspecified-p address
))
125 (not (inet-address-loopback-p address
))
126 (not (inet-address-multicast-p address
))))
127 (:method
((address ipv6-address
))
128 (or (ipv6-link-local-unicast-p address
)
129 (and (not (inet-address-unspecified-p address
))
130 (not (inet-address-loopback-p address
))
131 (not (inet-address-multicast-p address
))))))
133 (defun ipv6-ipv4-mapped-p (address)
134 "Returns T if ADDRESS is an IPv6 address representing an IPv4
136 (and (ipv6-address-p address
)
137 (ipv4-on-ipv6-mapped-vector-p (address-name address
))))
139 (defun ipv6-interface-local-multicast-p (address)
140 "Returns T if ADDRESS is an interface-local IPv6 address."
141 (check-type address ipv6-address
"an IPv6 address")
142 (= (logand (aref (address-name address
) 0) #xFF0F
)
145 (defun ipv6-link-local-multicast-p (address)
146 "Returns T if ADDRESS is a link-local IPv6 address."
147 (check-type address ipv6-address
"an IPv6 address")
148 (= (logand (aref (address-name address
) 0) #xFF0F
)
151 (defun ipv6-admin-local-multicast-p (address)
152 "Returns T if ADDRESS is a admin-local multicast IPv6 address."
153 (check-type address ipv6-address
"an IPv6 address")
154 (= (logand (aref (address-name address
) 0) #xFF0F
)
157 (defun ipv6-site-local-multicast-p (address)
158 "Returns T if ADDRESS is an site-local multicast IPv6 address."
159 (check-type address ipv6-address
"an IPv6 address")
160 (= (logand (aref (address-name address
) 0) #xFF0F
)
163 (defun ipv6-organization-local-multicast-p (address)
164 "Returns T if ADDRESS is an organization-local multicast IPv6 address."
165 (check-type address ipv6-address
"an IPv6 address")
166 (= (logand (aref (address-name address
) 0) #xFF0F
)
169 (defun ipv6-global-multicast-p (address)
170 "Returns T if ADDRESS is a global multicast IPv6 address."
171 (check-type address ipv6-address
"an IPv6 address")
172 (= (logand (aref (address-name address
) 0) #xFF0F
)
175 (defun ipv6-reserved-multicast-p (address)
176 "Returns T if ADDRESS is a reserved multicast IPv6 address."
177 (check-type address ipv6-address
"an IPv6 address")
178 (member (logand (aref (address-name address
) 0) #xFF0F
)
179 '(#xFF00
#xFF03
#xFF0F
)))
181 (defun ipv6-unassigned-multicast-p (address)
182 "Returns T if ADDRESS is an unassigned multicast IPv6 address."
183 (check-type address ipv6-address
"an IPv6 address")
184 (member (logand (aref (address-name address
) 0) #xFF0F
)
185 '(#xFF06
#xFF07
#xFF09
#xFF0A
#xFF0B
#xFF0C
#xFF0D
)))
187 (defun ipv6-transient-multicast-p (address)
188 "Returns T if ADDRESS is a transient multicast IPv6 address."
189 (check-type address ipv6-address
"an IPv6 address")
190 (= (logand (aref (address-name address
) 0) #xFF10
)
193 (defun ipv6-solicited-node-multicast-p (address)
194 "Returns T if ADDRESS is a solicited-node multicast IPv6 address."
195 (check-type address ipv6-address
"an IPv6 address")
196 (let ((vec (address-name address
)))
197 (and (= (aref vec
0) #xFF02
) ; link-local permanent multicast
199 (= (logand (aref vec
6) #xFF00
)
202 (defun ipv6-link-local-unicast-p (address)
203 "Returns T if ADDRESS is an link-local unicast IPv6 address."
204 (check-type address ipv6-address
"an IPv6 address")
205 (= (aref (address-name address
) 0) #xFE80
))
207 (defun ipv6-site-local-unicast-p (address)
208 "Returns T if ADDRESS is an site-local unicast IPv6 address."
209 (check-type address ipv6-address
"an IPv6 address")
210 (= (aref (address-name address
) 0) #xFEC0
))
212 (defun ipv6-global-unicast-p (address)
213 "Returns T if ADDRESS is an global unicasst IPv6 address."
214 (check-type address ipv6-address
"an IPv6 address")
215 (and (not (inet-address-unspecified-p address
))
216 (not (inet-address-loopback-p address
))
217 (not (inet-address-multicast-p address
))
218 (not (ipv6-link-local-unicast-p address
))))
220 (defun ipv6-multicast-type (address)
221 "Returns the multicast type of ADDRESS or NIL if it's not a
223 (check-type address ipv6-address
"an IPv6 address")
225 ((ipv6-interface-local-multicast-p address
) :interface-local
)
226 ((ipv6-link-local-multicast-p address
) :link-local
)
227 ((ipv6-admin-local-multicast-p address
) :admin-local
)
228 ((ipv6-site-local-multicast-p address
) :site-local
)
229 ((ipv6-organization-local-multicast-p address
) :organization-local
)
230 ((ipv6-global-multicast-p address
) :global
)
231 ((ipv6-reserved-multicast-p address
) :reserved
)
232 ((ipv6-unassigned-multicast-p address
) :unassigned
)))
234 (defun ipv6-unicast-type (address)
235 "Returns the unicast type of ADDRESS or NIL if it's not a
237 (check-type address ipv6-address
"an IPv6 address")
239 ((ipv6-link-local-unicast-p address
) :link-local
)
240 ((ipv6-site-local-unicast-p address
) :site-local
)
241 ((ipv6-global-unicast-p address
) :global
)))
243 (defgeneric inet-address-type
(address)
244 (:documentation
"Returns the address type of ADDRESS as 2 values:
246 * protocol, one of :IPV4 or :IPV6
247 * kind, one of :UNSPECIFIED, :LOOPBACK, :MULTICAST or :UNICAST
249 For unicast or multicast IPv6 addresses, a third value is
250 returned which corresponds to the return value of
251 IPV6-UNICAST-TYPE or IPV6-MULTICAST-TYPE, respectively." ))
253 (defmethod inet-address-type ((addr ipv6-address
))
255 ((inet-address-unspecified-p addr
) (values :ipv6
:unspecified
))
256 ((inet-address-loopback-p addr
) (values :ipv6
:loopback
))
257 ((inet-address-multicast-p addr
)
258 (values :ipv6
:multicast
(ipv6-multicast-type addr
)))
259 (t (values :ipv6
:unicast
(ipv6-unicast-type addr
)))))
261 (defmethod inet-address-type ((addr ipv4-address
))
264 ((inet-address-unspecified-p addr
) :unspecified
)
265 ((inet-address-loopback-p addr
) :loopback
)
266 ((inet-address-multicast-p addr
) :multicast
)
267 ((inet-address-unicast-p addr
) :unicast
))))