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