]> git.saurik.com Git - apple/network_cmds.git/blame - ip6conf.tproj/ip6tool.c
network_cmds-245.1.4.tar.gz
[apple/network_cmds.git] / ip6conf.tproj / ip6tool.c
CommitLineData
7ba0088d
A
1/* Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
2*
3* @APPLE_LICENSE_HEADER_START@
4*
a2c93a76
A
5* "Portions Copyright (c) 2002 Apple Computer, Inc. All Rights
6* Reserved. This file contains Original Code and/or Modifications of
7* Original Code as defined in and that are subject to the Apple Public
8* Source License Version 1.0 (the 'License'). You may not use this file
9* except in compliance with the License. Please obtain a copy of the
10* License at http://www.apple.com/publicsource and read it before using
11* this file.
7ba0088d
A
12*
13* The Original Code and all software distributed under the License are
14* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
a2c93a76
A
17* FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
18* License for the specific language governing rights and limitations
19* under the License."
7ba0088d
A
20*
21* @APPLE_LICENSE_HEADER_END@
22*
23*/
24
25#include <stdio.h>
26#include <unistd.h>
27#include <string.h>
ac2f15b3 28#include <sys/errno.h>
7ba0088d 29#include <sys/socket.h>
7ba0088d 30#include <sys/ioctl.h>
7ba0088d
A
31#include <net/if.h>
32#include <sys/types.h>
ac2f15b3
A
33#include <netinet/in.h>
34#include <netinet6/in6_var.h>
7ba0088d
A
35#include <ifaddrs.h>
36
ac2f15b3
A
37/* From netinet6/in6_var.h */
38#ifndef SIOCPROTOATTACH_IN6
39#define SIOCPROTOATTACH_IN6 _IOWR('i', 110, struct in6_aliasreq) /* attach proto to interface */
40#endif
41#ifndef SIOCPROTODETACH_IN6
42#define SIOCPROTODETACH_IN6 _IOWR('i', 111, struct in6_ifreq) /* detach proto from interface */
43#endif
44#ifndef SIOCLL_START
45#define SIOCLL_START _IOWR('i', 130, struct in6_aliasreq) /* start aquiring linklocal on interface */
46#endif
47#ifndef SIOCLL_STOP
48#define SIOCLL_STOP _IOWR('i', 131, struct in6_ifreq) /* deconfigure linklocal from interface */
49#endif
7ba0088d
A
50
51/* options */
52#define IPv6_STARTUP 1
53#define IPv6_SHUTDOWN 2
54#define IPv6_STARTUP_ALL 3
55#define IPv6_SHUTDOWN_ALL 4
56
57const char *if_exceptions[] = {"lo0", "gif0", "faith0", "stf0"};
58
59extern char *optarg;
60
61void do_usage(void);
62int do_protoattach(int s, char *name);
63int do_protodetach(int s, char *name);
ac2f15b3
A
64void do_protoattach_all(int s);
65void do_protodetach_all(int s);
7ba0088d
A
66
67
68int
69main(int argc, char **argv)
70{
71 int s,
72 ch,
73 option = 0,
74 err;
75 char *interface = NULL;
76
77 if ((ch = getopt(argc, argv, "u:d:ax")) != -1) {
78 switch (ch) {
79 case 'u':
80 /* option -u: start up proto */
81 option = IPv6_STARTUP;
82 interface = optarg;
83 break;
84 case 'd':
85 /* option -d: shut down proto */
86 option = IPv6_SHUTDOWN;
87 interface = optarg;
88 break;
89 case 'a':
90 /* option -a: start up proto on all interfaces */
91 option = IPv6_STARTUP_ALL;
92 break;
93 case 'x':
94 /* option -x: shut down proto on all interfaces */
95 option = IPv6_SHUTDOWN_ALL;
96 break;
97 default:
98 break;
99 }
100 }
101
102 if (!option) {
103 do_usage();
104 return 0;
105 }
106
107 if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
108 err = s;
109 printf("%s: Error %d creating socket.\n", argv[0], err);
110 return 0;
111 }
112
113 switch (option) {
114 case IPv6_STARTUP:
115 err = do_protoattach(s, interface);
116 if (err < 0)
ac2f15b3 117 printf("%s: Error %d encountered attaching interface %s.\n", argv[0], err, interface);
7ba0088d
A
118
119 break;
120 case IPv6_SHUTDOWN:
121 err = do_protodetach(s, interface);
122 if (err < 0)
ac2f15b3 123 printf("%s: Error %d encountered detaching interface %s.\n", argv[0], err, interface);
7ba0088d
A
124
125 break;
126 case IPv6_STARTUP_ALL:
ac2f15b3 127 do_protoattach_all(s);
7ba0088d
A
128
129 break;
130 case IPv6_SHUTDOWN_ALL:
ac2f15b3 131 do_protodetach_all(s);
7ba0088d
A
132
133 break;
134 default:
135 break;
136 }
137
138 close(s);
139
140 return 0;
141}
142
143void
144do_usage(void)
145{
146 printf("Usage: \n\
147 Start up IPv6 on ALL interfaces: -a\n\
148 Shut down IPv6 on ALL interfaces: -x\n\
149 Start up IPv6 on given interface: -u [interface]\n\
150 Shut down IPv6 on given interface: -d [interface].\n");
151}
152
153int
154do_protoattach(int s, char *name)
155{
ac2f15b3
A
156 struct in6_aliasreq ifr;
157 int err;
7ba0088d
A
158
159 bzero(&ifr, sizeof(ifr));
ac2f15b3
A
160 strncpy(ifr.ifra_name, name, sizeof(ifr.ifra_name));
161
162 if ((err = ioctl(s, SIOCPROTOATTACH_IN6, &ifr)) != 0)
163 return (err);
164
165 return (ioctl(s, SIOCLL_START, &ifr));
7ba0088d
A
166}
167
168int
169do_protodetach(int s, char *name)
170{
ac2f15b3
A
171 struct in6_ifreq ifr;
172 int err;
7ba0088d
A
173
174 bzero(&ifr, sizeof(ifr));
175 strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
ac2f15b3
A
176
177 if ((err = ioctl(s, SIOCLL_STOP, &ifr)) != 0)
178 return (err);
179
180 return (ioctl(s, SIOCPROTODETACH_IN6, &ifr));
7ba0088d
A
181}
182
ac2f15b3 183void
7ba0088d
A
184do_protoattach_all(int s)
185{
186 struct ifaddrs *ifaddrs, *ifa;
ac2f15b3
A
187
188 if (getifaddrs(&ifaddrs)) {
189 printf("ip6: getifaddrs returned error (%s)", strerror(errno));
190 }
7ba0088d
A
191
192 for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
193 /* skip over invalid interfaces */
194 if ((strcmp(ifa->ifa_name, if_exceptions[0])))
195 if (strcmp(ifa->ifa_name, if_exceptions[1]))
196 if (strcmp(ifa->ifa_name, if_exceptions[2]))
197 if (strcmp(ifa->ifa_name, if_exceptions[3])) {
198 /* this is a valid interface */
ac2f15b3
A
199 if (do_protoattach(s, ifa->ifa_name)) {
200 printf("ip6: error attaching %s\n", ifa->ifa_name);
201 }
7ba0088d
A
202
203 while (ifa->ifa_next != NULL &&
204 !(strcmp(ifa->ifa_name, ifa->ifa_next->ifa_name))) {
205 /* skip multiple entries for same interface */
206 ifa = ifa->ifa_next;
207 }
208 }
209 }
210
211 freeifaddrs(ifaddrs);
212
ac2f15b3 213 return;
7ba0088d
A
214}
215
ac2f15b3 216void
7ba0088d
A
217do_protodetach_all(int s)
218{
219 struct ifaddrs *ifaddrs, *ifa;
7ba0088d 220
ac2f15b3
A
221 if (getifaddrs(&ifaddrs)) {
222 printf("ip6: getifaddrs returned error (%s)", strerror(errno));
223 }
7ba0088d
A
224
225 for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
226 /* skip over invalid interfaces */
227 if ((strcmp(ifa->ifa_name, if_exceptions[0])))
228 if (strcmp(ifa->ifa_name, if_exceptions[1]))
229 if (strcmp(ifa->ifa_name, if_exceptions[2]))
230 if (strcmp(ifa->ifa_name, if_exceptions[3])) {
231 /* this is a valid interface */
ac2f15b3
A
232 if (do_protodetach(s, ifa->ifa_name)) {
233 printf("ip6: error detaching %s\n", ifa->ifa_name);
234 }
7ba0088d
A
235
236 while (ifa->ifa_next != NULL &&
237 !(strcmp(ifa->ifa_name, ifa->ifa_next->ifa_name))) {
238 /* skip multiple entries for same interface */
239 ifa = ifa->ifa_next;
240 }
241 }
242 }
243
244 freeifaddrs(ifaddrs);
245
ac2f15b3
A
246 return;
247}