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