]>
git.cameronkatri.com Git - apple_cmds.git/blob - network_cmds/rtsol.tproj/probe.c
2 * Copyright (c) 2009 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 /* $KAME: probe.c,v 1.10 2000/08/13 06:14:59 itojun Exp $ */
32 * Copyright (C) 1998 WIDE Project.
33 * All rights reserved.
35 * Redistribution and use in source and binary forms, with or without
36 * modification, are permitted provided that the following conditions
38 * 1. Redistributions of source code must retain the above copyright
39 * notice, this list of conditions and the following disclaimer.
40 * 2. Redistributions in binary form must reproduce the above copyright
41 * notice, this list of conditions and the following disclaimer in the
42 * documentation and/or other materials provided with the distribution.
43 * 3. Neither the name of the project nor the names of its contributors
44 * may be used to endorse or promote products derived from this software
45 * without specific prior written permission.
47 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
48 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
49 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
50 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
51 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
52 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
53 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
54 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
55 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
56 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59 * $FreeBSD: src/usr.sbin/rtsold/probe.c,v 1.2.2.3 2001/07/03 11:02:16 ume Exp $
62 #include <sys/param.h>
63 #include <sys/types.h>
64 #include <sys/ioctl.h>
65 #include <sys/socket.h>
67 #include <sys/queue.h>
70 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
71 #include <net/if_var.h>
72 #endif /* __FreeBSD__ >= 3 */
74 #include <netinet/in.h>
75 #include <netinet6/in6_var.h>
76 #include <netinet/icmp6.h>
77 #include <netinet6/nd6.h>
79 #include <arpa/inet.h>
89 static struct msghdr sndmhdr
;
90 static struct iovec sndiov
[2];
92 static void sendprobe
__P((struct in6_addr
*addr
, int ifindex
));
98 int scmsglen
= CMSG_SPACE(sizeof(struct in6_pktinfo
)) +
99 CMSG_SPACE(sizeof(int));
100 static u_char
*sndcmsgbuf
= NULL
;
102 if (sndcmsgbuf
== NULL
&&
103 (sndcmsgbuf
= (u_char
*)malloc(scmsglen
)) == NULL
) {
104 warnmsg(LOG_ERR
, __FUNCTION__
, "malloc failed");
108 if ((probesock
= socket(AF_INET6
, SOCK_RAW
, IPPROTO_NONE
)) < 0) {
109 warnmsg(LOG_ERR
, __FUNCTION__
, "socket: %s", strerror(errno
));
114 /* make the socket send-only */
115 if (shutdown(probesock
, 0)) {
116 warnmsg(LOG_ERR
, __FUNCTION__
, "shutdown: %s", strerror(errno
));
119 #endif /* __APPLE__ */
121 /* initialize msghdr for sending packets */
122 sndmhdr
.msg_namelen
= sizeof(struct sockaddr_in6
);
123 sndmhdr
.msg_iov
= sndiov
;
124 sndmhdr
.msg_iovlen
= 1;
125 sndmhdr
.msg_control
= (caddr_t
)sndcmsgbuf
;
126 sndmhdr
.msg_controllen
= scmsglen
;
132 * Probe if each router in the default router list is still alive.
135 defrouter_probe(int ifindex
)
137 struct in6_drlist dr
;
139 u_char ntopbuf
[INET6_ADDRSTRLEN
];
141 if ((s
= socket(AF_INET6
, SOCK_DGRAM
, 0)) < 0) {
142 warnmsg(LOG_ERR
, __FUNCTION__
, "socket: %s", strerror(errno
));
145 bzero(&dr
, sizeof(dr
));
146 strlcpy(dr
.ifname
, "lo0", sizeof(dr
.ifname
)); /* dummy interface */
147 if (ioctl(s
, SIOCGDRLST_IN6
, (caddr_t
)&dr
) < 0) {
148 warnmsg(LOG_ERR
, __FUNCTION__
, "ioctl(SIOCGDRLST_IN6): %s",
153 for(i
= 0; dr
.defrouter
[i
].if_index
&& i
< PRLSTSIZ
; i
++) {
154 if (ifindex
&& dr
.defrouter
[i
].if_index
== ifindex
) {
156 if (!IN6_IS_ADDR_LINKLOCAL(&dr
.defrouter
[i
].rtaddr
)) {
157 warnmsg(LOG_ERR
, __FUNCTION__
,
158 "default router list contains a "
159 "non-linklocal address(%s)",
161 &dr
.defrouter
[i
].rtaddr
,
162 (char *)ntopbuf
, INET6_ADDRSTRLEN
));
163 continue; /* ignore the address */
165 sendprobe(&dr
.defrouter
[i
].rtaddr
,
166 dr
.defrouter
[i
].if_index
);
176 sendprobe(struct in6_addr
*addr
, int ifindex
)
178 struct sockaddr_in6 sa6_probe
;
179 struct in6_pktinfo
*pi
;
181 u_char ntopbuf
[INET6_ADDRSTRLEN
], ifnamebuf
[IFNAMSIZ
];;
183 bzero(&sa6_probe
, sizeof(sa6_probe
));
184 sa6_probe
.sin6_family
= AF_INET6
;
185 sa6_probe
.sin6_len
= sizeof(sa6_probe
);
186 sa6_probe
.sin6_addr
= *addr
;
188 sndmhdr
.msg_name
= (caddr_t
)&sa6_probe
;
189 sndmhdr
.msg_iov
[0].iov_base
= NULL
;
190 sndmhdr
.msg_iov
[0].iov_len
= 0;
192 cm
= CMSG_FIRSTHDR(&sndmhdr
);
193 /* specify the outgoing interface */
194 cm
->cmsg_level
= IPPROTO_IPV6
;
195 cm
->cmsg_type
= IPV6_PKTINFO
;
196 cm
->cmsg_len
= CMSG_LEN(sizeof(struct in6_pktinfo
));
197 pi
= (struct in6_pktinfo
*)CMSG_DATA(cm
);
198 memset(&pi
->ipi6_addr
, 0, sizeof(pi
->ipi6_addr
)); /*XXX*/
199 pi
->ipi6_ifindex
= ifindex
;
201 /* specify the hop limit of the packet for safety */
205 cm
= CMSG_NXTHDR(&sndmhdr
, cm
);
206 cm
->cmsg_level
= IPPROTO_IPV6
;
207 cm
->cmsg_type
= IPV6_HOPLIMIT
;
208 cm
->cmsg_len
= CMSG_LEN(sizeof(int));
209 memcpy(CMSG_DATA(cm
), &hoplimit
, sizeof(int));
212 warnmsg(LOG_DEBUG
, __FUNCTION__
, "probe a router %s on %s",
213 inet_ntop(AF_INET6
, addr
, (char *)ntopbuf
, INET6_ADDRSTRLEN
),
214 if_indextoname(ifindex
, (char *)ifnamebuf
));
216 if (sendmsg(probesock
, &sndmhdr
, 0))
217 warnmsg(LOG_ERR
, __FUNCTION__
, "sendmsg on %s: %s",
218 if_indextoname(ifindex
, (char *)ifnamebuf
), strerror(errno
));