Merge commit 'c5bab7026b8e0ac44b25ee08507ea360f177d844' into merges
[unleashed.git] / share / man / man7p / ndp.7p
bloba8380c0233f9c6ec244e37bdaff2d673b128b9e3
1 .\"
2 .\" This file and its contents are supplied under the terms of the
3 .\" Common Development and Distribution License ("CDDL"), version 1.0.
4 .\" You may only use this file in accordance with the terms of version
5 .\" 1.0 of the CDDL.
6 .\"
7 .\" A full copy of the text of the CDDL should have accompanied this
8 .\" source.  A copy of the CDDL is also available via the Internet at
9 .\" http://www.illumos.org/license/CDDL.
10 .\"
11 .\"
12 .\" Copyright (c) 2015, Joyent, Inc.  All rights reserved.
13 .\"
14 .Dd Sep 02, 2015
15 .Dt NDP 7P
16 .Os
17 .Sh NAME
18 .Nm ndp ,
19 .Nm NDP
20 .Nd Neighbor Discovery Protocol
21 .Sh SYNOPSIS
22 .In sys/socket.h
23 .In sys/sockio.h
24 .In netinet/in.h
25 .In net/if.h
26 .Bd -literal
27 s = socket(PF_INET6, SOCK_DGRAM, 0);
29 struct lifreq lifr;
30 ioctl(s, SIOCLIFGETND, &lifr);
31 ioctl(s, SIOCLIFSETND, &lifr);
32 ioctl(s, SIOCLIFDELND, &lifr);
33 .Ed
34 .Sh DESCRIPTION
35 The Neighbor Discovery Protocol (NDP) is a protocol used to distribute and request
36 information about neighboring IPv6 systems on the local network, much like
37 .Xr ARP 7P
38 for IPv4. NDP is also responsible for spreading information about the network
39 gateway and how hosts should configure themselves
40 .Pq see Xr in.ndpd 8 for more on how this happens .
41 .Sh APPLICATION PROGRAMMING INTERFACE
42 The operating system provides several ioctls to help manipulate the mappings
43 obtained through NDP. They are
44 .Sy SIOCLIFGETND ,
45 .Sy SIOCLIFSETND ,
46 and
47 .Sy SIOCLIFDELND ,
48 for getting, setting, and deleting respectively. Each of these ioctls takes a
49 .Vt struct lifreq
50 .Pq see Xr if 7P for details ,
51 where the
52 .Fa lifr_lifru
53 field is of type
54 .Vt struct lif_nd_req :
55 .Bd -literal -offset 2m
56 typedef struct lif_nd_req {
57         struct sockaddr_storage lnr_addr;
58         uint8_t                 lnr_state_create;
59         uint8_t                 lnr_state_same_lla;
60         uint8_t                 lnr_state_diff_lla;
61         int                     lnr_hdw_len;
62         int                     lnr_flags;
63         int                     lnr_pad0;
64         char                    lnr_hdw_addr[ND_MAX_HDW_LEN];
65 } lif_nd_req_t;
66 .Ed
67 .Pp
68 The
69 .Fa lnr_addr
70 field should be filled in with an IPv6 address
71 .Pq see Xr sockaddr_in6 3SOCKET ,
72 and the
73 .Fa lnr_hdw_addr
74 is the link-layer address of length
75 .Fa lnr_hdw_len .
76 .Pp
77 State flags for
78 .Fa lnr_state_create ,
79 .Fa lnr_state_same_lla ,
80 and
81 .Fa lnr_state_diff_lla
82 can be set to one of the following values:
83 .Bl -tag -offset indent -width 16m
84 .It Sy ND_UNCHANGED
85 For ioctls that don't modify state
86 .It Sy ND_INCOMPLETE
87 Address resolution is currently in progress
88 .It Sy ND_REACHABLE
89 The link-layer address has recently been reachable
90 .It Sy ND_STALE
91 The link-layer address may be unreachable, and the system shouldn't do anything
92 .It Sy ND_DELAY
93 This entry hasn't yet started sending Neighbor Solicitations
94 .It Sy ND_PROBE
95 The operating system is currently sending out Neighbor Solicitations for the address
96 .It Sy ND_UNREACHABLE
97 The link-layer address is unreachable, and this entry is going to be deleted.
98 .El
99 .sp
100 When creating a new entry, the only valid values for
101 .Fa lnr_state_create
103 .Sy ND_REACHABLE
105 .Sy ND_STALE .
106 Any other value will return
107 .Sy EINVAL .
109 .Fa lnr_state_same_lla
111 .Fa lnr_state_diff_lla
112 fields are reserved for future use and can be safely set to
113 .Sy ND_UNCHANGED
115 .Sy ND_STALE
116 respectively.
118 Flags that can be placed in
119 .Fa lnr_flags
120 are:
121 .Bl -tag -offset indent -width 16m
122 .It Sy NDF_ISROUTER_ON
123 Mark this entry as being a router. This will cause Neighbor Advertisements for
124 this address to be sent with the R-bit (Router).
125 .It Sy NDF_ISROUTER_OFF
126 If this entry was flagged as being a router, remove the flag.
127 .It Sy NDF_ANYCAST_ON
128 Mark this entry as being for an anycast address. This prevents sending Neighbor
129 Advertisements with the O-bit (Override).
130 .It Sy NDF_ANYCAST_OFF
131 If this entry was flagged as an anycast address, remove the flag.
132 .It Sy NDF_STATIC
133 Prevent this entry from being deleted by the system.
136 When using
137 .Sy SIOCLIFGETND ,
138 these flags represent the current state of the corresponding Neighbor Cache
139 Entry. When using
140 .Sy SIOCLIFSETND ,
141 these flags represent what changes should be applied to the underlying entry.
143 The only fields that need to be set for the
144 .Sy SIOCLIFGETND
146 .Sy SIOCLIFDELND
147 ioctls are
148 .Fa lifr_name
150 .Fa lnr_addr .
151 All other fields should be zeroed out. After successfully getting an entry, the
152 other fields will be filled in. When using
153 .Sy SIOCLIFSETND ,
154 all fields should be set to an appropriate value, as described above, with the
155 exception of
156 .Fa lnr_pad0 ,
157 which is unused and only exists for padding purposes.
159 After performing the ioctl, the following errors may be returned through the
160 global
161 .Sy errno
162 variable:
163 .Bl -tag -offset indent -width 16m
164 .It Sy EAFNOSUPPORT
165 A non-IPv6 socket was used to perform the ioctl.
166 .It Sy EINVAL
167 The request contents were bad. This could be because conflicting flags were
168 used, the specified interface wasn't logical unit zero, or another reason.
169 .It Sy ENOMEM
170 The system ran out of memory for internal data structures.
171 .It Sy ENXIO
172 The specified interface does not exist.
173 .It Sy EPERM
174 The caller does not have permission to modify the Neighbor Cache Entries
175 associated with this interface. They may be lacking the
176 .Sy PRIV_SYS_NET_CONFIG
177 privilege
178 .Po see Xr privileges 5 Pc ,
179 or the interface is managed by IPMP (IP Network Multipathing).
180 .It Sy ESRCH
181 There is no entry matching the specified address.
183 .Sh EXAMPLES
184 The following examples demonstrate how to get and set NDP mappings using the
185 provided ioctls.
186 .Ss Example 1: Getting a mapping
187 .Bd -literal -offset indent
189  * Example of getting a mapping for a node name.
190  */
191 #include <strings.h>
192 #include <stdio.h>
193 #include <stdlib.h>
194 #include <sys/socket.h>
195 #include <sys/sockio.h>
196 #include <unistd.h>
197 #include <netdb.h>
198 #include <net/if.h>
200 int get(char *host) {
201         struct lifreq lifr;
202         struct addrinfo hints, *serverinfo, *p;
203         int err, s;
205         bzero(&hints, sizeof (struct addrinfo));
206         hints.ai_family = PF_INET6;
207         hints.ai_protocol = IPPROTO_IPV6;
209         if ((err = getaddrinfo(host, NULL, &hints, &serverinfo)) != 0) {
210                 (void) fprintf(stderr, "Unable to lookup %s: %s\\n", host,
211                     gai_strerror(err));
212                 return (1);
213         }
215         s = socket(AF_INET6, SOCK_DGRAM, 0);
216         if (s < 0) {
217                 perror("Failed to open IPv6 socket");
218                 return (1);
219         }
221         for (p = serverinfo; p != NULL; p = p->ai_next) {
222                 /* Zero out structure */
223                 bzero(&lifr, sizeof (struct lifreq));
224                 (void) strlcpy(lifr.lifr_name, "net0",
225                     sizeof (lifr.lifr_name));
226                 (void) memcpy(&lifr.lifr_nd.lnr_addr, p->ai_addr,
227                     sizeof (struct sockaddr_storage));
229                 /* Get mapping */
230                 if (ioctl(s, SIOCLIFGETND, &lifr) < 0) {
231                         perror("Unable to get NDP mapping");
232                         continue;
233                 }
235                 /*
236                  * lifr.lifr_nd.lnr_hdw_addr now contains the MAC address,
237                  * and can be used as desired.
238                  */
239         }
241         /*
242          * Clean up linked list.
243          */
244         freeaddrinfo(serverinfo);
245         return (0);
248 int main(int argc, char *argv[]) {
249         if (argc < 2)
250                 exit(1);
251         return (get(argv[1]));
255 Deleting a mapping would work similarly, except that instead of using
256 .Sy SIOCLIFGETND ,
257 you would instead use the
258 .Sy SIOCLIFDELND
259 ioctl.
260 .Ss Example 2: Adding a mapping
261 .Bd -literal -offset indent
263  * Example of setting a mapping to an all-zero Ethernet address.
264  */
265 #include <strings.h>
266 #include <stdio.h>
267 #include <stdlib.h>
268 #include <sys/socket.h>
269 #include <sys/sockio.h>
270 #include <unistd.h>
271 #include <netdb.h>
272 #include <net/if.h>
274 int set(char *host) {
275         struct lifreq lifr;
276         struct addrinfo hints, *serverinfo, *p;
277         int err, s;
279         bzero(&hints, sizeof (struct addrinfo));
280         hints.ai_family = PF_INET6;
281         hints.ai_protocol = IPPROTO_IPV6;
283         if ((err = getaddrinfo(host, NULL, &hints, &serverinfo)) != 0) {
284                 (void) fprintf(stderr, "Unable to lookup %s: %s\\n", host,
285                     gai_strerror(err));
286                 return (1);
287         }
289         s = socket(AF_INET6, SOCK_DGRAM, 0);
290         if (s < 0) {
291                 perror("Failed to open IPv6 socket");
292                 return (1);
293         }
295         for (p = serverinfo; p != NULL; p = p->ai_next) {
296                 /* Zero out structure */
297                 bzero(&lifr, sizeof (struct lifreq));
298                 (void) strlcpy(lifr.lifr_name, "net0",
299                     sizeof (lifr.lifr_name));
300                 (void) memcpy(&lifr.lifr_nd.lnr_addr, p->ai_addr,
301                     sizeof (struct sockaddr_storage));
303                 lifr.lifr_nd.lnr_state_create = ND_REACHABLE;
304                 lifr.lifr_nd.lnr_flags = NDF_STATIC;
306                 /* Get mapping */
307                 if (ioctl(s, SIOCLIFSETND, &lifr) < 0) {
308                         perror("Unable to set NDP mapping");
309                         continue;
310                 }
311         }
313         /*
314          * Clean up linked list.
315          */
316         freeaddrinfo(serverinfo);
317         return (0);
320 int main(int argc, char *argv[]) {
321         if (argc < 2)
322                 exit(1);
323         return (set(argv[1]));
326 .Sh SEE ALSO
327 .Xr ifconfig 8 ,
328 .Xr in.ndpd 8 ,
329 .Xr ndp 8 ,
330 .Xr sockaddr_in6 3SOCKET ,
331 .Xr privileges 5
333 .%A Narten, T.
334 .%A Nordmark, E.
335 .%A Simpson, W.
336 .%A Soliman, H.
337 .%R Neighbor Discovery for IP version 6
338 .%T RFC 4861
339 .%D September 2007