]> git.saurik.com Git - apple/network_cmds.git/blob - ip6conf.tproj/ip6tool.c
network_cmds-115.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/socket.h>
29 /* this is needed to get SIOCPROTOATTACH/SIOCPROTODETACH */
30 #define KERNEL_PRIVATE
31 #include <sys/ioctl.h>
32 #undef KERNEL_PRIVATE
33 #include <net/if.h>
34 #include <sys/types.h>
35 #include <ifaddrs.h>
36
37
38 /* options */
39 #define IPv6_STARTUP 1
40 #define IPv6_SHUTDOWN 2
41 #define IPv6_STARTUP_ALL 3
42 #define IPv6_SHUTDOWN_ALL 4
43
44 const char *if_exceptions[] = {"lo0", "gif0", "faith0", "stf0"};
45
46 extern char *optarg;
47
48 void do_usage(void);
49 int do_protoattach(int s, char *name);
50 int do_protodetach(int s, char *name);
51 int do_protoattach_all(int s);
52 int do_protodetach_all(int s);
53
54
55 int
56 main(int argc, char **argv)
57 {
58 int s,
59 ch,
60 option = 0,
61 err;
62 char *interface = NULL;
63
64 if ((ch = getopt(argc, argv, "u:d:ax")) != -1) {
65 switch (ch) {
66 case 'u':
67 /* option -u: start up proto */
68 option = IPv6_STARTUP;
69 interface = optarg;
70 break;
71 case 'd':
72 /* option -d: shut down proto */
73 option = IPv6_SHUTDOWN;
74 interface = optarg;
75 break;
76 case 'a':
77 /* option -a: start up proto on all interfaces */
78 option = IPv6_STARTUP_ALL;
79 break;
80 case 'x':
81 /* option -x: shut down proto on all interfaces */
82 option = IPv6_SHUTDOWN_ALL;
83 break;
84 default:
85 break;
86 }
87 }
88
89 if (!option) {
90 do_usage();
91 return 0;
92 }
93
94 if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
95 err = s;
96 printf("%s: Error %d creating socket.\n", argv[0], err);
97 return 0;
98 }
99
100 switch (option) {
101 case IPv6_STARTUP:
102 err = do_protoattach(s, interface);
103 if (err < 0)
104 printf("%s: Error %d encountered attaching to interface %s.\n", argv[0], err, interface);
105
106 break;
107 case IPv6_SHUTDOWN:
108 err = do_protodetach(s, interface);
109 if (err < 0)
110 printf("%s: Error %d encountered detaching to interface %s.\n", argv[0], err, interface);
111
112 break;
113 case IPv6_STARTUP_ALL:
114 err = do_protoattach_all(s);
115 if (err < 0)
116 printf("%s: Error %d encountered attaching to interfaces.\n", argv[0], err);
117
118 break;
119 case IPv6_SHUTDOWN_ALL:
120 err = do_protodetach_all(s);
121 if (err < 0)
122 printf("%s: Error %d encountered detaching to interfaces.\n", argv[0], err);
123
124 break;
125 default:
126 break;
127 }
128
129 close(s);
130
131 return 0;
132 }
133
134 void
135 do_usage(void)
136 {
137 printf("Usage: \n\
138 Start up IPv6 on ALL interfaces: -a\n\
139 Shut down IPv6 on ALL interfaces: -x\n\
140 Start up IPv6 on given interface: -u [interface]\n\
141 Shut down IPv6 on given interface: -d [interface].\n");
142 }
143
144 int
145 do_protoattach(int s, char *name)
146 {
147 struct ifreq ifr;
148
149 bzero(&ifr, sizeof(ifr));
150 strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
151 return (ioctl(s, SIOCPROTOATTACH, &ifr));
152 }
153
154 int
155 do_protodetach(int s, char *name)
156 {
157 struct ifreq ifr;
158
159 bzero(&ifr, sizeof(ifr));
160 strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
161 return (ioctl(s, SIOCPROTODETACH, &ifr));
162 }
163
164 int
165 do_protoattach_all(int s)
166 {
167 struct ifaddrs *ifaddrs, *ifa;
168 int err;
169
170 if ((err = getifaddrs(&ifaddrs)) < 0)
171 return err; /* getifaddrs properly sets errno */
172
173 for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
174 /* skip over invalid interfaces */
175 if ((strcmp(ifa->ifa_name, if_exceptions[0])))
176 if (strcmp(ifa->ifa_name, if_exceptions[1]))
177 if (strcmp(ifa->ifa_name, if_exceptions[2]))
178 if (strcmp(ifa->ifa_name, if_exceptions[3])) {
179 /* this is a valid interface */
180 err = do_protoattach(s, ifa->ifa_name);
181 if (err)
182 break;
183
184 while (ifa->ifa_next != NULL &&
185 !(strcmp(ifa->ifa_name, ifa->ifa_next->ifa_name))) {
186 /* skip multiple entries for same interface */
187 ifa = ifa->ifa_next;
188 }
189 }
190 }
191
192 freeifaddrs(ifaddrs);
193
194 return err;
195 }
196
197 int
198 do_protodetach_all(int s)
199 {
200 struct ifaddrs *ifaddrs, *ifa;
201 int err;
202
203 if ((err = getifaddrs(&ifaddrs)) < 0)
204 return err; /* getifaddrs properly sets errno */
205
206 for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
207 /* skip over invalid interfaces */
208 if ((strcmp(ifa->ifa_name, if_exceptions[0])))
209 if (strcmp(ifa->ifa_name, if_exceptions[1]))
210 if (strcmp(ifa->ifa_name, if_exceptions[2]))
211 if (strcmp(ifa->ifa_name, if_exceptions[3])) {
212 /* this is a valid interface */
213 err = do_protodetach(s, ifa->ifa_name);
214 if (err)
215 break;
216
217 while (ifa->ifa_next != NULL &&
218 !(strcmp(ifa->ifa_name, ifa->ifa_next->ifa_name))) {
219 /* skip multiple entries for same interface */
220 ifa = ifa->ifa_next;
221 }
222 }
223 }
224
225 freeifaddrs(ifaddrs);
226
227 return err;
228 }