8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / man / man7p / ndp.7p
blob28d4d2a1d445ab7dc3b5974026f75bd0370d1a5e
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
36 request information about neighboring IPv6 systems on the local network, much
37 like
38 .Xr ARP 7P
39 for IPv4.
40 NDP is also responsible for spreading information about the network gateway and
41 how hosts should configure themselves
42 .Pq see Xr in.ndpd 1M for more on how this happens .
43 .Sh APPLICATION PROGRAMMING INTERFACE
44 The operating system provides several ioctls to help manipulate the mappings
45 obtained through NDP.
46 They are
47 .Sy SIOCLIFGETND ,
48 .Sy SIOCLIFSETND ,
49 and
50 .Sy SIOCLIFDELND ,
51 for getting, setting, and deleting respectively.
52 Each of these ioctls takes a
53 .Vt struct lifreq
54 .Pq see Xr if 7P for details ,
55 where the
56 .Fa lifr_lifru
57 field is of type
58 .Vt struct lif_nd_req :
59 .Bd -literal -offset 2m
60 typedef struct lif_nd_req {
61         struct sockaddr_storage lnr_addr;
62         uint8_t                 lnr_state_create;
63         uint8_t                 lnr_state_same_lla;
64         uint8_t                 lnr_state_diff_lla;
65         int                     lnr_hdw_len;
66         int                     lnr_flags;
67         int                     lnr_pad0;
68         char                    lnr_hdw_addr[ND_MAX_HDW_LEN];
69 } lif_nd_req_t;
70 .Ed
71 .Pp
72 The
73 .Fa lnr_addr
74 field should be filled in with an IPv6 address
75 .Pq see Xr sockaddr_in6 3SOCKET ,
76 and the
77 .Fa lnr_hdw_addr
78 is the link-layer address of length
79 .Fa lnr_hdw_len .
80 .Pp
81 State flags for
82 .Fa lnr_state_create ,
83 .Fa lnr_state_same_lla ,
84 and
85 .Fa lnr_state_diff_lla
86 can be set to one of the following values:
87 .Bl -tag -offset indent -width 16m
88 .It Sy ND_UNCHANGED
89 For ioctls that don't modify state
90 .It Sy ND_INCOMPLETE
91 Address resolution is currently in progress
92 .It Sy ND_REACHABLE
93 The link-layer address has recently been reachable
94 .It Sy ND_STALE
95 The link-layer address may be unreachable, and the system shouldn't do anything
96 .It Sy ND_DELAY
97 This entry hasn't yet started sending Neighbor Solicitations
98 .It Sy ND_PROBE
99 The operating system is currently sending out Neighbor Solicitations for the address
100 .It Sy ND_UNREACHABLE
101 The link-layer address is unreachable, and this entry is going to be deleted.
104 When creating a new entry, the only valid values for
105 .Fa lnr_state_create
107 .Sy ND_REACHABLE
109 .Sy ND_STALE .
110 Any other value will return
111 .Sy EINVAL .
113 .Fa lnr_state_same_lla
115 .Fa lnr_state_diff_lla
116 fields are reserved for future use and can be safely set to
117 .Sy ND_UNCHANGED
119 .Sy ND_STALE
120 respectively.
122 Flags that can be placed in
123 .Fa lnr_flags
124 are:
125 .Bl -tag -offset indent -width 16m
126 .It Sy NDF_ISROUTER_ON
127 Mark this entry as being a router.
128 This will cause Neighbor Advertisements for this address to be sent with the
129 R-bit (Router).
130 .It Sy NDF_ISROUTER_OFF
131 If this entry was flagged as being a router, remove the flag.
132 .It Sy NDF_ANYCAST_ON
133 Mark this entry as being for an anycast address.
134 This prevents sending Neighbor Advertisements with the O-bit (Override).
135 .It Sy NDF_ANYCAST_OFF
136 If this entry was flagged as an anycast address, remove the flag.
137 .It Sy NDF_STATIC
138 Prevent this entry from being deleted by the system.
141 When using
142 .Sy SIOCLIFGETND ,
143 these flags represent the current state of the corresponding Neighbor Cache
144 Entry.
145 When using
146 .Sy SIOCLIFSETND ,
147 these flags represent what changes should be applied to the underlying entry.
149 The only fields that need to be set for the
150 .Sy SIOCLIFGETND
152 .Sy SIOCLIFDELND
153 ioctls are
154 .Fa lifr_name
156 .Fa lnr_addr .
157 All other fields should be zeroed out.
158 After successfully getting an entry, the other fields will be filled in.
159 When using
160 .Sy SIOCLIFSETND ,
161 all fields should be set to an appropriate value, as described above, with the
162 exception of
163 .Fa lnr_pad0 ,
164 which is unused and only exists for padding purposes.
166 After performing the ioctl, the following errors may be returned through the
167 global
168 .Sy errno
169 variable:
170 .Bl -tag -offset indent -width 16m
171 .It Sy EAFNOSUPPORT
172 A non-IPv6 socket was used to perform the ioctl.
173 .It Sy EINVAL
174 The request contents were bad.
175 This could be because conflicting flags were used, the specified interface
176 wasn't logical unit zero, or another reason.
177 .It Sy ENOMEM
178 The system ran out of memory for internal data structures.
179 .It Sy ENXIO
180 The specified interface does not exist.
181 .It Sy EPERM
182 The caller does not have permission to modify the Neighbor Cache Entries
183 associated with this interface.
184 They may be lacking the
185 .Sy PRIV_SYS_NET_CONFIG
186 privilege
187 .Po see Xr privileges 5 Pc ,
188 or the interface is managed by IPMP (IP Network Multipathing).
189 .It Sy ESRCH
190 There is no entry matching the specified address.
192 .Sh EXAMPLES
193 The following examples demonstrate how to get and set NDP mappings using the
194 provided ioctls.
195 They can be compiled by using a C compiler and linking against the sockets
196 library.
197 .Ss Example 1: Getting a mapping
198 .Bd -literal -offset indent
199 $ gcc -Wall -lsocket -o get get.c
200 $ cat get.c
202  * Example of getting a mapping for a node name.
203  */
204 #include <strings.h>
205 #include <stdio.h>
206 #include <stdlib.h>
207 #include <sys/socket.h>
208 #include <sys/sockio.h>
209 #include <unistd.h>
210 #include <netdb.h>
211 #include <net/if.h>
213 int get(char *host) {
214         struct lifreq lifr;
215         struct addrinfo hints, *serverinfo, *p;
216         int err, s;
218         bzero(&hints, sizeof (struct addrinfo));
219         hints.ai_family = PF_INET6;
220         hints.ai_protocol = IPPROTO_IPV6;
222         if ((err = getaddrinfo(host, NULL, &hints, &serverinfo)) != 0) {
223                 (void) fprintf(stderr, "Unable to lookup %s: %s\\n", host,
224                     gai_strerror(err));
225                 return (1);
226         }
228         s = socket(AF_INET6, SOCK_DGRAM, 0);
229         if (s < 0) {
230                 perror("Failed to open IPv6 socket");
231                 return (1);
232         }
234         for (p = serverinfo; p != NULL; p = p->ai_next) {
235                 /* Zero out structure */
236                 bzero(&lifr, sizeof (struct lifreq));
237                 (void) strlcpy(lifr.lifr_name, "net0",
238                     sizeof (lifr.lifr_name));
239                 (void) memcpy(&lifr.lifr_nd.lnr_addr, p->ai_addr,
240                     sizeof (struct sockaddr_storage));
242                 /* Get mapping */
243                 if (ioctl(s, SIOCLIFGETND, &lifr) < 0) {
244                         perror("Unable to get NDP mapping");
245                         continue;
246                 }
248                 /*
249                  * lifr.lifr_nd.lnr_hdw_addr now contains the MAC address,
250                  * and can be used as desired.
251                  */
252         }
254         /*
255          * Clean up linked list.
256          */
257         freeaddrinfo(serverinfo);
258         return (0);
261 int main(int argc, char *argv[]) {
262         if (argc < 2)
263                 exit(1);
264         return (get(argv[1]));
268 Deleting a mapping would work similarly, except that instead of using
269 .Sy SIOCLIFGETND ,
270 you would instead use the
271 .Sy SIOCLIFDELND
272 ioctl.
273 .Ss Example 2: Adding a mapping
274 .Bd -literal -offset indent
275 $ gcc -Wall -lsocket -o set set.c
276 $ cat set.c
278  * Example of setting a mapping to an all-zero Ethernet address.
279  */
280 #include <strings.h>
281 #include <stdio.h>
282 #include <stdlib.h>
283 #include <sys/socket.h>
284 #include <sys/sockio.h>
285 #include <unistd.h>
286 #include <netdb.h>
287 #include <net/if.h>
289 int set(char *host) {
290         struct lifreq lifr;
291         struct addrinfo hints, *serverinfo, *p;
292         int err, s;
294         bzero(&hints, sizeof (struct addrinfo));
295         hints.ai_family = PF_INET6;
296         hints.ai_protocol = IPPROTO_IPV6;
298         if ((err = getaddrinfo(host, NULL, &hints, &serverinfo)) != 0) {
299                 (void) fprintf(stderr, "Unable to lookup %s: %s\\n", host,
300                     gai_strerror(err));
301                 return (1);
302         }
304         s = socket(AF_INET6, SOCK_DGRAM, 0);
305         if (s < 0) {
306                 perror("Failed to open IPv6 socket");
307                 return (1);
308         }
310         for (p = serverinfo; p != NULL; p = p->ai_next) {
311                 /* Zero out structure */
312                 bzero(&lifr, sizeof (struct lifreq));
313                 (void) strlcpy(lifr.lifr_name, "net0",
314                     sizeof (lifr.lifr_name));
315                 (void) memcpy(&lifr.lifr_nd.lnr_addr, p->ai_addr,
316                     sizeof (struct sockaddr_storage));
318                 lifr.lifr_nd.lnr_state_create = ND_REACHABLE;
319                 lifr.lifr_nd.lnr_flags = NDF_STATIC;
321                 /* Get mapping */
322                 if (ioctl(s, SIOCLIFSETND, &lifr) < 0) {
323                         perror("Unable to set NDP mapping");
324                         continue;
325                 }
326         }
328         /*
329          * Clean up linked list.
330          */
331         freeaddrinfo(serverinfo);
332         return (0);
335 int main(int argc, char *argv[]) {
336         if (argc < 2)
337                 exit(1);
338         return (set(argv[1]));
341 .Sh SEE ALSO
342 .Xr ifconfig 1M ,
343 .Xr in.ndpd 1M ,
344 .Xr ndp 1M ,
345 .Xr sockaddr_in6 3SOCKET ,
346 .Xr privileges 5
348 .%A Narten, T.
349 .%A Nordmark, E.
350 .%A Simpson, W.
351 .%A Soliman, H.
352 .%R Neighbor Discovery for IP version 6
353 .%T RFC 4861
354 .%D September 2007