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