]> git.saurik.com Git - apple/network_cmds.git/blob - ip6conf.tproj/ip6tool.c
network_cmds-245.1.tar.gz
[apple/network_cmds.git] / ip6conf.tproj / ip6tool.c
1 /* Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
2 *
3 * @APPLE_LICENSE_HEADER_START@
4 *
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.
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,
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."
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 *
23 */
24
25 #include <stdio.h>
26 #include <unistd.h>
27 #include <string.h>
28 #include <sys/errno.h>
29 #include <sys/socket.h>
30 #include <sys/ioctl.h>
31 #include <net/if.h>
32 #include <sys/types.h>
33 #include <netinet/in.h>
34 #include <netinet6/in6_var.h>
35 #include <ifaddrs.h>
36
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
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
57 const char *if_exceptions[] = {"lo0", "gif0", "faith0", "stf0"};
58
59 extern char *optarg;
60
61 void do_usage(void);
62 int do_protoattach(int s, char *name);
63 int do_protodetach(int s, char *name);
64 void do_protoattach_all(int s);
65 void do_protodetach_all(int s);
66
67
68 int
69 main(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)
117 printf("%s: Error %d encountered attaching interface %s.\n", argv[0], err, interface);
118
119 break;
120 case IPv6_SHUTDOWN:
121 err = do_protodetach(s, interface);
122 if (err < 0)
123 printf("%s: Error %d encountered detaching interface %s.\n", argv[0], err, interface);
124
125 break;
126 case IPv6_STARTUP_ALL:
127 do_protoattach_all(s);
128
129 break;
130 case IPv6_SHUTDOWN_ALL:
131 do_protodetach_all(s);
132
133 break;
134 default:
135 break;
136 }
137
138 close(s);
139
140 return 0;
141 }
142
143 void
144 do_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
153 int
154 do_protoattach(int s, char *name)
155 {
156 struct in6_aliasreq ifr;
157 int err;
158
159 bzero(&ifr, sizeof(ifr));
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));
166 }
167
168 int
169 do_protodetach(int s, char *name)
170 {
171 struct in6_ifreq ifr;
172 int err;
173
174 bzero(&ifr, sizeof(ifr));
175 strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
176
177 if ((err = ioctl(s, SIOCLL_STOP, &ifr)) != 0)
178 return (err);
179
180 return (ioctl(s, SIOCPROTODETACH_IN6, &ifr));
181 }
182
183 void
184 do_protoattach_all(int s)
185 {
186 struct ifaddrs *ifaddrs, *ifa;
187
188 if (getifaddrs(&ifaddrs)) {
189 printf("ip6: getifaddrs returned error (%s)", strerror(errno));
190 }
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 */
199 if (do_protoattach(s, ifa->ifa_name)) {
200 printf("ip6: error attaching %s\n", ifa->ifa_name);
201 }
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
213 return;
214 }
215
216 void
217 do_protodetach_all(int s)
218 {
219 struct ifaddrs *ifaddrs, *ifa;
220
221 if (getifaddrs(&ifaddrs)) {
222 printf("ip6: getifaddrs returned error (%s)", strerror(errno));
223 }
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 */
232 if (do_protodetach(s, ifa->ifa_name)) {
233 printf("ip6: error detaching %s\n", ifa->ifa_name);
234 }
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
246 return;
247 }