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