summaryrefslogtreecommitdiff
path: root/usr/src/man/man7p/ndp.7p
blob: 28d4d2a1d445ab7dc3b5974026f75bd0370d1a5e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
.\"
.\" This file and its contents are supplied under the terms of the
.\" Common Development and Distribution License ("CDDL"), version 1.0.
.\" You may only use this file in accordance with the terms of version
.\" 1.0 of the CDDL.
.\"
.\" A full copy of the text of the CDDL should have accompanied this
.\" source.  A copy of the CDDL is also available via the Internet at
.\" http://www.illumos.org/license/CDDL.
.\"
.\"
.\" Copyright (c) 2015, Joyent, Inc.  All rights reserved.
.\"
.Dd Sep 02, 2015
.Dt NDP 7P
.Os
.Sh NAME
.Nm ndp ,
.Nm NDP
.Nd Neighbor Discovery Protocol
.Sh SYNOPSIS
.In sys/socket.h
.In sys/sockio.h
.In netinet/in.h
.In net/if.h
.Bd -literal
s = socket(PF_INET6, SOCK_DGRAM, 0);

struct lifreq lifr;
ioctl(s, SIOCLIFGETND, &lifr);
ioctl(s, SIOCLIFSETND, &lifr);
ioctl(s, SIOCLIFDELND, &lifr);
.Ed
.Sh DESCRIPTION
The Neighbor Discovery Protocol (NDP) is a protocol used to distribute and
request information about neighboring IPv6 systems on the local network, much
like
.Xr ARP 7P
for IPv4.
NDP is also responsible for spreading information about the network gateway and
how hosts should configure themselves
.Pq see Xr in.ndpd 1M for more on how this happens .
.Sh APPLICATION PROGRAMMING INTERFACE
The operating system provides several ioctls to help manipulate the mappings
obtained through NDP.
They are
.Sy SIOCLIFGETND ,
.Sy SIOCLIFSETND ,
and
.Sy SIOCLIFDELND ,
for getting, setting, and deleting respectively.
Each of these ioctls takes a
.Vt struct lifreq
.Pq see Xr if 7P for details ,
where the
.Fa lifr_lifru
field is of type
.Vt struct lif_nd_req :
.Bd -literal -offset 2m
typedef struct lif_nd_req {
        struct sockaddr_storage lnr_addr;
        uint8_t                 lnr_state_create;
        uint8_t                 lnr_state_same_lla;
        uint8_t                 lnr_state_diff_lla;
        int                     lnr_hdw_len;
        int                     lnr_flags;
        int                     lnr_pad0;
        char                    lnr_hdw_addr[ND_MAX_HDW_LEN];
} lif_nd_req_t;
.Ed
.Pp
The
.Fa lnr_addr
field should be filled in with an IPv6 address
.Pq see Xr sockaddr_in6 3SOCKET ,
and the
.Fa lnr_hdw_addr
is the link-layer address of length
.Fa lnr_hdw_len .
.Pp
State flags for
.Fa lnr_state_create ,
.Fa lnr_state_same_lla ,
and
.Fa lnr_state_diff_lla
can be set to one of the following values:
.Bl -tag -offset indent -width 16m
.It Sy ND_UNCHANGED
For ioctls that don't modify state
.It Sy ND_INCOMPLETE
Address resolution is currently in progress
.It Sy ND_REACHABLE
The link-layer address has recently been reachable
.It Sy ND_STALE
The link-layer address may be unreachable, and the system shouldn't do anything
.It Sy ND_DELAY
This entry hasn't yet started sending Neighbor Solicitations
.It Sy ND_PROBE
The operating system is currently sending out Neighbor Solicitations for the address
.It Sy ND_UNREACHABLE
The link-layer address is unreachable, and this entry is going to be deleted.
.El
.sp
When creating a new entry, the only valid values for
.Fa lnr_state_create
are
.Sy ND_REACHABLE
and
.Sy ND_STALE .
Any other value will return
.Sy EINVAL .
The
.Fa lnr_state_same_lla
and
.Fa lnr_state_diff_lla
fields are reserved for future use and can be safely set to
.Sy ND_UNCHANGED
and
.Sy ND_STALE
respectively.
.Pp
Flags that can be placed in
.Fa lnr_flags
are:
.Bl -tag -offset indent -width 16m
.It Sy NDF_ISROUTER_ON
Mark this entry as being a router.
This will cause Neighbor Advertisements for this address to be sent with the
R-bit (Router).
.It Sy NDF_ISROUTER_OFF
If this entry was flagged as being a router, remove the flag.
.It Sy NDF_ANYCAST_ON
Mark this entry as being for an anycast address.
This prevents sending Neighbor Advertisements with the O-bit (Override).
.It Sy NDF_ANYCAST_OFF
If this entry was flagged as an anycast address, remove the flag.
.It Sy NDF_STATIC
Prevent this entry from being deleted by the system.
.El
.sp
When using
.Sy SIOCLIFGETND ,
these flags represent the current state of the corresponding Neighbor Cache
Entry.
When using
.Sy SIOCLIFSETND ,
these flags represent what changes should be applied to the underlying entry.
.Pp
The only fields that need to be set for the
.Sy SIOCLIFGETND
or
.Sy SIOCLIFDELND
ioctls are
.Fa lifr_name
and
.Fa lnr_addr .
All other fields should be zeroed out.
After successfully getting an entry, the other fields will be filled in.
When using
.Sy SIOCLIFSETND ,
all fields should be set to an appropriate value, as described above, with the
exception of
.Fa lnr_pad0 ,
which is unused and only exists for padding purposes.
.Pp
After performing the ioctl, the following errors may be returned through the
global
.Sy errno
variable:
.Bl -tag -offset indent -width 16m
.It Sy EAFNOSUPPORT
A non-IPv6 socket was used to perform the ioctl.
.It Sy EINVAL
The request contents were bad.
This could be because conflicting flags were used, the specified interface
wasn't logical unit zero, or another reason.
.It Sy ENOMEM
The system ran out of memory for internal data structures.
.It Sy ENXIO
The specified interface does not exist.
.It Sy EPERM
The caller does not have permission to modify the Neighbor Cache Entries
associated with this interface.
They may be lacking the
.Sy PRIV_SYS_NET_CONFIG
privilege
.Po see Xr privileges 5 Pc ,
or the interface is managed by IPMP (IP Network Multipathing).
.It Sy ESRCH
There is no entry matching the specified address.
.El
.Sh EXAMPLES
The following examples demonstrate how to get and set NDP mappings using the
provided ioctls.
They can be compiled by using a C compiler and linking against the sockets
library.
.Ss Example 1: Getting a mapping
.Bd -literal -offset indent
$ gcc -Wall -lsocket -o get get.c
$ cat get.c
/*
 * Example of getting a mapping for a node name.
 */
#include <strings.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <unistd.h>
#include <netdb.h>
#include <net/if.h>

int get(char *host) {
	struct lifreq lifr;
	struct addrinfo hints, *serverinfo, *p;
	int err, s;

	bzero(&hints, sizeof (struct addrinfo));
	hints.ai_family = PF_INET6;
	hints.ai_protocol = IPPROTO_IPV6;

	if ((err = getaddrinfo(host, NULL, &hints, &serverinfo)) != 0) {
		(void) fprintf(stderr, "Unable to lookup %s: %s\\n", host,
		    gai_strerror(err));
		return (1);
	}

	s = socket(AF_INET6, SOCK_DGRAM, 0);
	if (s < 0) {
		perror("Failed to open IPv6 socket");
		return (1);
	}

	for (p = serverinfo; p != NULL; p = p->ai_next) {
		/* Zero out structure */
		bzero(&lifr, sizeof (struct lifreq));
		(void) strlcpy(lifr.lifr_name, "net0",
		    sizeof (lifr.lifr_name));
		(void) memcpy(&lifr.lifr_nd.lnr_addr, p->ai_addr,
		    sizeof (struct sockaddr_storage));

		/* Get mapping */
		if (ioctl(s, SIOCLIFGETND, &lifr) < 0) {
			perror("Unable to get NDP mapping");
			continue;
		}

		/*
		 * lifr.lifr_nd.lnr_hdw_addr now contains the MAC address,
		 * and can be used as desired.
		 */
	}

	/*
	 * Clean up linked list.
	 */
	freeaddrinfo(serverinfo);
	return (0);
}

int main(int argc, char *argv[]) {
	if (argc < 2)
		exit(1);
	return (get(argv[1]));
}
.Ed
.sp
Deleting a mapping would work similarly, except that instead of using
.Sy SIOCLIFGETND ,
you would instead use the
.Sy SIOCLIFDELND
ioctl.
.Ss Example 2: Adding a mapping
.Bd -literal -offset indent
$ gcc -Wall -lsocket -o set set.c
$ cat set.c
/*
 * Example of setting a mapping to an all-zero Ethernet address.
 */
#include <strings.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <unistd.h>
#include <netdb.h>
#include <net/if.h>

int set(char *host) {
	struct lifreq lifr;
	struct addrinfo hints, *serverinfo, *p;
	int err, s;

	bzero(&hints, sizeof (struct addrinfo));
	hints.ai_family = PF_INET6;
	hints.ai_protocol = IPPROTO_IPV6;

	if ((err = getaddrinfo(host, NULL, &hints, &serverinfo)) != 0) {
		(void) fprintf(stderr, "Unable to lookup %s: %s\\n", host,
		    gai_strerror(err));
		return (1);
	}

	s = socket(AF_INET6, SOCK_DGRAM, 0);
	if (s < 0) {
		perror("Failed to open IPv6 socket");
		return (1);
	}

	for (p = serverinfo; p != NULL; p = p->ai_next) {
		/* Zero out structure */
		bzero(&lifr, sizeof (struct lifreq));
		(void) strlcpy(lifr.lifr_name, "net0",
		    sizeof (lifr.lifr_name));
		(void) memcpy(&lifr.lifr_nd.lnr_addr, p->ai_addr,
		    sizeof (struct sockaddr_storage));

		lifr.lifr_nd.lnr_state_create = ND_REACHABLE;
		lifr.lifr_nd.lnr_flags = NDF_STATIC;

		/* Get mapping */
		if (ioctl(s, SIOCLIFSETND, &lifr) < 0) {
			perror("Unable to set NDP mapping");
			continue;
		}
	}

	/*
	 * Clean up linked list.
	 */
	freeaddrinfo(serverinfo);
	return (0);
}

int main(int argc, char *argv[]) {
	if (argc < 2)
		exit(1);
	return (set(argv[1]));
}
.Ed
.Sh SEE ALSO
.Xr ifconfig 1M ,
.Xr in.ndpd 1M ,
.Xr ndp 1M ,
.Xr sockaddr_in6 3SOCKET ,
.Xr privileges 5
.Rs
.%A Narten, T.
.%A Nordmark, E.
.%A Simpson, W.
.%A Soliman, H.
.%R Neighbor Discovery for IP version 6
.%T RFC 4861
.%D September 2007
.Re