diff options
Diffstat (limited to 'ifconfig.c')
-rw-r--r-- | ifconfig.c | 437 |
1 files changed, 196 insertions, 241 deletions
diff --git a/ifconfig.c b/ifconfig.c index a3e2c0fdb..2a50a9605 100644 --- a/ifconfig.c +++ b/ifconfig.c | |||
@@ -15,16 +15,19 @@ | |||
15 | * Foundation; either version 2 of the License, or (at | 15 | * Foundation; either version 2 of the License, or (at |
16 | * your option) any later version. | 16 | * your option) any later version. |
17 | * | 17 | * |
18 | * $Id: ifconfig.c,v 1.3 2001/02/20 06:14:07 andersen Exp $ | 18 | * $Id: ifconfig.c,v 1.4 2001/03/06 00:48:59 andersen Exp $ |
19 | * | ||
20 | * Majorly hacked up by Larry Doolittle <ldoolitt@recycle.lbl.gov> | ||
19 | * | 21 | * |
20 | */ | 22 | */ |
21 | 23 | ||
24 | #include "busybox.h" | ||
25 | #include <sys/types.h> | ||
22 | #include <stdio.h> | 26 | #include <stdio.h> |
23 | #include <stdlib.h> | 27 | #include <stdlib.h> |
24 | #include <errno.h> | 28 | #include <errno.h> |
25 | #include <string.h> // strcmp and friends | 29 | #include <string.h> // strcmp and friends |
26 | #include <ctype.h> // isdigit and friends | 30 | #include <ctype.h> // isdigit and friends |
27 | #include <sys/types.h> | ||
28 | #include <sys/socket.h> | 31 | #include <sys/socket.h> |
29 | #include <sys/ioctl.h> | 32 | #include <sys/ioctl.h> |
30 | #include <netinet/in.h> | 33 | #include <netinet/in.h> |
@@ -32,10 +35,50 @@ | |||
32 | #include <net/if.h> | 35 | #include <net/if.h> |
33 | #include <net/if_arp.h> | 36 | #include <net/if_arp.h> |
34 | #include <linux/if_ether.h> | 37 | #include <linux/if_ether.h> |
35 | #include "busybox.h" | ||
36 | 38 | ||
37 | static int sockfd; /* socket fd we use to manipulate stuff with */ | 39 | static int sockfd; /* socket fd we use to manipulate stuff with */ |
38 | 40 | ||
41 | #define TESTME 0 | ||
42 | #if TESTME | ||
43 | #define ioctl test_ioctl | ||
44 | char *saddr_to_a(struct sockaddr *s) | ||
45 | { | ||
46 | if (s->sa_family == ARPHRD_ETHER) { | ||
47 | static char hw[18]; | ||
48 | sprintf(hw, "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x", | ||
49 | s->sa_data[0], s->sa_data[1], s->sa_data[2], | ||
50 | s->sa_data[3], s->sa_data[4], s->sa_data[5]); | ||
51 | return hw; | ||
52 | } else if (s->sa_family == AF_INET) { | ||
53 | struct sockaddr_in *ss = (struct sockaddr_in *) s; | ||
54 | return inet_ntoa(ss->sin_addr); | ||
55 | } else { | ||
56 | return NULL; | ||
57 | } | ||
58 | } | ||
59 | |||
60 | int test_ioctl(int __fd, unsigned long int __request, void *param) | ||
61 | { | ||
62 | struct ifreq *i=(struct ifreq *)param; | ||
63 | printf("ioctl fd=%d, request=%ld\n", __fd, __request); | ||
64 | |||
65 | switch(__request) { | ||
66 | case SIOCGIFFLAGS: printf(" SIOCGIFFLAGS\n"); i->ifr_flags = 0; break; | ||
67 | case SIOCSIFFLAGS: printf(" SIOCSIFFLAGS, %x\n", i->ifr_flags); break; | ||
68 | case SIOCSIFMETRIC: printf(" SIOCSIFMETRIC, %d\n", i->ifr_metric); break; | ||
69 | case SIOCSIFMTU: printf(" SIOCSIFMTU, %d\n", i->ifr_mtu); break; | ||
70 | case SIOCSIFBRDADDR: printf(" SIOCSIFBRDADDR, %s\n", saddr_to_a(&(i->ifr_broadaddr))); break; | ||
71 | case SIOCSIFDSTADDR: printf(" SIOCSIFDSTADDR, %s\n", saddr_to_a(&(i->ifr_dstaddr ))); break; | ||
72 | case SIOCSIFNETMASK: printf(" SIOCSIFNETMASK, %s\n", saddr_to_a(&(i->ifr_netmask ))); break; | ||
73 | case SIOCSIFADDR: printf(" SIOCSIFADDR, %s\n", saddr_to_a(&(i->ifr_addr ))); break; | ||
74 | case SIOCSIFHWADDR: printf(" SIOCSIFHWADDR, %s\n", saddr_to_a(&(i->ifr_hwaddr ))); break; /* broken */ | ||
75 | default: | ||
76 | } | ||
77 | return 0; | ||
78 | } | ||
79 | #endif | ||
80 | |||
81 | |||
39 | /* print usage and exit */ | 82 | /* print usage and exit */ |
40 | 83 | ||
41 | #define _(x) x | 84 | #define _(x) x |
@@ -49,7 +92,7 @@ set_flag(char *ifname, short flag) | |||
49 | strcpy(ifr.ifr_name, ifname); | 92 | strcpy(ifr.ifr_name, ifname); |
50 | if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) { | 93 | if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) { |
51 | perror("SIOCGIFFLAGS"); | 94 | perror("SIOCGIFFLAGS"); |
52 | return (-1); | 95 | return -1; |
53 | } | 96 | } |
54 | strcpy(ifr.ifr_name, ifname); | 97 | strcpy(ifr.ifr_name, ifname); |
55 | ifr.ifr_flags |= flag; | 98 | ifr.ifr_flags |= flag; |
@@ -57,7 +100,7 @@ set_flag(char *ifname, short flag) | |||
57 | perror("SIOCSIFFLAGS"); | 100 | perror("SIOCSIFFLAGS"); |
58 | return -1; | 101 | return -1; |
59 | } | 102 | } |
60 | return (0); | 103 | return 0; |
61 | } | 104 | } |
62 | 105 | ||
63 | 106 | ||
@@ -78,9 +121,62 @@ clr_flag(char *ifname, short flag) | |||
78 | perror("SIOCSIFFLAGS"); | 121 | perror("SIOCSIFFLAGS"); |
79 | return -1; | 122 | return -1; |
80 | } | 123 | } |
81 | return (0); | 124 | return 0; |
82 | } | 125 | } |
83 | 126 | ||
127 | /* which element in struct ifreq to frob */ | ||
128 | enum frob { | ||
129 | L_METRIC, | ||
130 | L_MTU, | ||
131 | L_DATA, | ||
132 | L_BROAD, | ||
133 | L_DEST, | ||
134 | L_MASK, | ||
135 | L_HWAD, | ||
136 | }; | ||
137 | |||
138 | |||
139 | struct flag_map { | ||
140 | char *name; | ||
141 | enum frob frob; | ||
142 | int flag; | ||
143 | int sflag; | ||
144 | int action; | ||
145 | }; | ||
146 | |||
147 | /* action: | ||
148 | * 2 set | ||
149 | * 4 clear | ||
150 | * 6 set/clear | ||
151 | * 8 clear/set | ||
152 | * 10 numeric | ||
153 | * 12 address | ||
154 | * 14 address/clear | ||
155 | */ | ||
156 | const static struct flag_map flag_table[] = { | ||
157 | {"arp", 0, IFF_NOARP, 0, 6}, | ||
158 | {"trailers", 0, IFF_NOTRAILERS, 0, 6}, | ||
159 | {"promisc", 0, IFF_PROMISC, 0, 8}, | ||
160 | {"multicast", 0, IFF_MULTICAST, 0, 8}, | ||
161 | {"allmulti", 0, IFF_ALLMULTI, 0, 8}, | ||
162 | {"up", 0, (IFF_UP | IFF_RUNNING), 0, 2}, | ||
163 | {"down", 0, IFF_UP, 0, 4}, | ||
164 | {"metric", L_METRIC, 0, SIOCSIFMETRIC, 10}, | ||
165 | {"mtu", L_MTU, 0, SIOCSIFMTU, 10}, | ||
166 | #ifdef SIOCSKEEPALIVE | ||
167 | {"keepalive", L_DATA, 0, SIOCSKEEPALIVE, 10}, | ||
168 | #endif | ||
169 | #ifdef SIOCSOUTFILL | ||
170 | {"outfill", L_DATA, 0, SIOCSOUTFILL, 10}, | ||
171 | #endif | ||
172 | {"broadcast", L_BROAD, IFF_BROADCAST, SIOCSIFBRDADDR, 14}, | ||
173 | {"dstaddr", L_DEST, 0, SIOCSIFDSTADDR, 12}, | ||
174 | {"netmask", L_MASK, 0, SIOCSIFNETMASK, 12}, | ||
175 | {"pointopoint", L_DEST, IFF_POINTOPOINT, SIOCSIFDSTADDR, 14}, | ||
176 | {"hw", L_HWAD, 0, SIOCSIFHWADDR, 14}, | ||
177 | }; | ||
178 | |||
179 | |||
84 | /* resolve XXX.YYY.ZZZ.QQQ -> binary */ | 180 | /* resolve XXX.YYY.ZZZ.QQQ -> binary */ |
85 | 181 | ||
86 | static int | 182 | static int |
@@ -90,15 +186,16 @@ INET_resolve(char *name, struct sockaddr_in *sin) | |||
90 | sin->sin_port = 0; | 186 | sin->sin_port = 0; |
91 | 187 | ||
92 | /* Default is special, meaning 0.0.0.0. */ | 188 | /* Default is special, meaning 0.0.0.0. */ |
93 | if (!strcmp(name, "default")) { | 189 | if (strcmp(name, "default")==0) { |
94 | sin->sin_addr.s_addr = INADDR_ANY; | 190 | sin->sin_addr.s_addr = INADDR_ANY; |
95 | return (1); | 191 | return 1; |
96 | } | 192 | } |
97 | /* Look to see if it's a dotted quad. */ | 193 | /* Look to see if it's a dotted quad. */ |
98 | if (inet_aton(name, &sin->sin_addr)) { | 194 | if (inet_aton(name, &sin->sin_addr)) { |
99 | return 0; | 195 | return 0; |
100 | } | 196 | } |
101 | /* guess not.. */ | 197 | /* guess not.. */ |
198 | errno = EINVAL; | ||
102 | return -1; | 199 | return -1; |
103 | } | 200 | } |
104 | 201 | ||
@@ -127,12 +224,12 @@ in_ether(char *bufp, struct sockaddr *sap) | |||
127 | val = c - 'A' + 10; | 224 | val = c - 'A' + 10; |
128 | else { | 225 | else { |
129 | #ifdef DEBUG | 226 | #ifdef DEBUG |
130 | fprintf(stderr, | 227 | error_msg( |
131 | _("in_ether(%s): invalid ether address!\n"), | 228 | _("in_ether(%s): invalid ether address!"), |
132 | orig); | 229 | orig); |
133 | #endif | 230 | #endif |
134 | errno = EINVAL; | 231 | errno = EINVAL; |
135 | return (-1); | 232 | return -1; |
136 | } | 233 | } |
137 | val <<= 4; | 234 | val <<= 4; |
138 | c = *bufp; | 235 | c = *bufp; |
@@ -146,22 +243,19 @@ in_ether(char *bufp, struct sockaddr *sap) | |||
146 | val >>= 4; | 243 | val >>= 4; |
147 | else { | 244 | else { |
148 | #ifdef DEBUG | 245 | #ifdef DEBUG |
149 | fprintf(stderr, | 246 | error_msg( |
150 | _("in_ether(%s): invalid ether address!\n"), | 247 | _("in_ether(%s): invalid ether address!"), |
151 | orig); | 248 | orig); |
152 | #endif | 249 | #endif |
153 | errno = EINVAL; | 250 | errno = EINVAL; |
154 | return (-1); | 251 | return -1; |
155 | } | 252 | } |
156 | if (c != 0) | 253 | if (c != 0) |
157 | bufp++; | 254 | bufp++; |
158 | *ptr++ = (unsigned char) (val & 0377); | 255 | *ptr++ = (unsigned char) (val & 0377); |
159 | i++; | 256 | i++; |
160 | 257 | ||
161 | /* We might get a semicolon here - not required. */ | 258 | /* optional colon already handled, don't swallow a second */ |
162 | if (*bufp == ':') | ||
163 | bufp++; | ||
164 | |||
165 | } | 259 | } |
166 | 260 | ||
167 | if(i != ETH_ALEN) { | 261 | if(i != ETH_ALEN) { |
@@ -171,25 +265,37 @@ in_ether(char *bufp, struct sockaddr *sap) | |||
171 | 265 | ||
172 | return 0; | 266 | return 0; |
173 | } | 267 | } |
268 | |||
269 | #ifdef BB_FEATURE_IFCONFIG_STATUS | ||
270 | extern int display_interfaces(void); | ||
271 | #else | ||
272 | int display_interfaces(void) | ||
273 | { | ||
274 | show_usage(); | ||
275 | } | ||
276 | #endif | ||
174 | 277 | ||
175 | int ifconfig_main(int argc, char **argv) | 278 | int ifconfig_main(int argc, char **argv) |
176 | { | 279 | { |
177 | struct ifreq ifr; | 280 | struct ifreq ifr; |
178 | struct sockaddr_in sa; | 281 | struct sockaddr_in sa; |
179 | struct sockaddr sa2; | 282 | char **spp, *cmd; |
180 | char **spp; | ||
181 | int goterr = 0; | 283 | int goterr = 0; |
182 | int r, didnetmask = 0; | 284 | int r; |
285 | /* int didnetmask = 0; special case input error detection no longer implemented */ | ||
183 | char host[128]; | 286 | char host[128]; |
287 | const struct flag_map *ft; | ||
288 | int i, sense; | ||
289 | int a, ecode; | ||
290 | struct sockaddr *d; | ||
184 | 291 | ||
185 | if(argc < 2) { | 292 | if(argc < 2) { |
186 | show_usage(); | 293 | return(display_interfaces()); |
187 | } | 294 | } |
188 | 295 | ||
189 | /* Create a channel to the NET kernel. */ | 296 | /* Create a channel to the NET kernel. */ |
190 | if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { | 297 | if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { |
191 | perror("socket"); | 298 | perror_msg_and_die("socket"); |
192 | exit(1); | ||
193 | } | 299 | } |
194 | 300 | ||
195 | /* skip argv[0] */ | 301 | /* skip argv[0] */ |
@@ -205,235 +311,84 @@ int ifconfig_main(int argc, char **argv) | |||
205 | 311 | ||
206 | /* Process the remaining arguments. */ | 312 | /* Process the remaining arguments. */ |
207 | while (*spp != (char *) NULL) { | 313 | while (*spp != (char *) NULL) { |
208 | if (!strcmp(*spp, "arp")) { | 314 | cmd = *spp; |
209 | goterr |= clr_flag(ifr.ifr_name, IFF_NOARP); | 315 | sense=0; |
210 | spp++; | 316 | if (*cmd=='-') { |
211 | continue; | 317 | sense=1; |
212 | } | 318 | cmd++; |
213 | if (!strcmp(*spp, "-arp")) { | ||
214 | goterr |= set_flag(ifr.ifr_name, IFF_NOARP); | ||
215 | spp++; | ||
216 | continue; | ||
217 | } | ||
218 | |||
219 | if (!strcmp(*spp, "trailers")) { | ||
220 | goterr |= clr_flag(ifr.ifr_name, IFF_NOTRAILERS); | ||
221 | spp++; | ||
222 | continue; | ||
223 | } | ||
224 | if (!strcmp(*spp, "-trailers")) { | ||
225 | goterr |= set_flag(ifr.ifr_name, IFF_NOTRAILERS); | ||
226 | spp++; | ||
227 | continue; | ||
228 | } | ||
229 | if (!strcmp(*spp, "promisc")) { | ||
230 | goterr |= set_flag(ifr.ifr_name, IFF_PROMISC); | ||
231 | spp++; | ||
232 | continue; | ||
233 | } | ||
234 | if (!strcmp(*spp, "-promisc")) { | ||
235 | goterr |= clr_flag(ifr.ifr_name, IFF_PROMISC); | ||
236 | spp++; | ||
237 | continue; | ||
238 | } | ||
239 | if (!strcmp(*spp, "multicast")) { | ||
240 | goterr |= set_flag(ifr.ifr_name, IFF_MULTICAST); | ||
241 | spp++; | ||
242 | continue; | ||
243 | } | ||
244 | if (!strcmp(*spp, "-multicast")) { | ||
245 | goterr |= clr_flag(ifr.ifr_name, IFF_MULTICAST); | ||
246 | spp++; | ||
247 | continue; | ||
248 | } | ||
249 | if (!strcmp(*spp, "allmulti")) { | ||
250 | goterr |= set_flag(ifr.ifr_name, IFF_ALLMULTI); | ||
251 | spp++; | ||
252 | continue; | ||
253 | } | ||
254 | if (!strcmp(*spp, "-allmulti")) { | ||
255 | goterr |= clr_flag(ifr.ifr_name, IFF_ALLMULTI); | ||
256 | spp++; | ||
257 | continue; | ||
258 | } | ||
259 | if (!strcmp(*spp, "up")) { | ||
260 | goterr |= set_flag(ifr.ifr_name, (IFF_UP | IFF_RUNNING)); | ||
261 | spp++; | ||
262 | continue; | ||
263 | } | ||
264 | if (!strcmp(*spp, "down")) { | ||
265 | goterr |= clr_flag(ifr.ifr_name, IFF_UP); | ||
266 | spp++; | ||
267 | continue; | ||
268 | } | ||
269 | |||
270 | if (!strcmp(*spp, "metric")) { | ||
271 | if (*++spp == NULL) | ||
272 | show_usage(); | ||
273 | ifr.ifr_metric = atoi(*spp); | ||
274 | if (ioctl(sockfd, SIOCSIFMETRIC, &ifr) < 0) { | ||
275 | fprintf(stderr, "SIOCSIFMETRIC: %s\n", strerror(errno)); | ||
276 | goterr++; | ||
277 | } | ||
278 | spp++; | ||
279 | continue; | ||
280 | } | ||
281 | if (!strcmp(*spp, "mtu")) { | ||
282 | if (*++spp == NULL) | ||
283 | show_usage(); | ||
284 | ifr.ifr_mtu = atoi(*spp); | ||
285 | if (ioctl(sockfd, SIOCSIFMTU, &ifr) < 0) { | ||
286 | fprintf(stderr, "SIOCSIFMTU: %s\n", strerror(errno)); | ||
287 | goterr++; | ||
288 | } | ||
289 | spp++; | ||
290 | continue; | ||
291 | } | 319 | } |
292 | #ifdef SIOCSKEEPALIVE | 320 | ft = NULL; |
293 | if (!strcmp(*spp, "keepalive")) { | 321 | for (i=0; i<(sizeof(flag_table)/sizeof(struct flag_map)); i++) { |
294 | if (*++spp == NULL) | 322 | if (strcmp(cmd, flag_table[i].name)==0) { |
295 | show_usage(); | 323 | ft=flag_table+i; |
296 | ifr.ifr_data = (caddr_t) atoi(*spp); | 324 | spp++; |
297 | if (ioctl(sockfd, SIOCSKEEPALIVE, &ifr) < 0) { | 325 | break; |
298 | fprintf(stderr, "SIOCSKEEPALIVE: %s\n", strerror(errno)); | ||
299 | goterr++; | ||
300 | } | ||
301 | spp++; | ||
302 | continue; | ||
303 | } | ||
304 | #endif | ||
305 | |||
306 | #ifdef SIOCSOUTFILL | ||
307 | if (!strcmp(*spp, "outfill")) { | ||
308 | if (*++spp == NULL) | ||
309 | show_usage(); | ||
310 | ifr.ifr_data = (caddr_t) atoi(*spp); | ||
311 | if (ioctl(sockfd, SIOCSOUTFILL, &ifr) < 0) { | ||
312 | fprintf(stderr, "SIOCSOUTFILL: %s\n", strerror(errno)); | ||
313 | goterr++; | ||
314 | } | 326 | } |
315 | spp++; | ||
316 | continue; | ||
317 | } | 327 | } |
318 | #endif | 328 | if (ft) { |
329 | switch (ft->action+sense) { | ||
330 | case 4: | ||
331 | case 7: | ||
332 | case 8: | ||
333 | case 15: | ||
334 | goterr |= clr_flag(ifr.ifr_name, ft->flag); | ||
335 | break; | ||
336 | case 2: | ||
337 | case 6: | ||
338 | case 9: | ||
339 | goterr |= set_flag(ifr.ifr_name, ft->flag); | ||
340 | break; | ||
341 | case 10: | ||
342 | if (*spp == NULL) | ||
343 | show_usage(); | ||
344 | a = atoi(*spp++); | ||
345 | switch (ft->frob) { | ||
346 | case L_METRIC: ifr.ifr_metric = a; break; | ||
347 | case L_MTU: ifr.ifr_mtu = a; break; | ||
348 | case L_DATA: ifr.ifr_data = (caddr_t) a; break; | ||
349 | default: error_msg_and_die("bugaboo"); | ||
350 | } | ||
319 | 351 | ||
320 | if (!strcmp(*spp, "-broadcast")) { | 352 | if (ioctl(sockfd, ft->sflag, &ifr) < 0) { |
321 | goterr |= clr_flag(ifr.ifr_name, IFF_BROADCAST); | 353 | perror(ft->name); /* imperfect */ |
322 | spp++; | ||
323 | continue; | ||
324 | } | ||
325 | if (!strcmp(*spp, "broadcast")) { | ||
326 | if (*++spp != NULL) { | ||
327 | safe_strncpy(host, *spp, (sizeof host)); | ||
328 | if (INET_resolve(host, &sa) < 0) { | ||
329 | goterr++; | 354 | goterr++; |
330 | spp++; | ||
331 | continue; | ||
332 | } | 355 | } |
333 | memcpy((char *) &ifr.ifr_broadaddr, | 356 | break; |
334 | (char *) &sa, | 357 | case 12: |
335 | sizeof(struct sockaddr)); | 358 | case 14: |
336 | if (ioctl(sockfd, SIOCSIFBRDADDR, &ifr) < 0) { | 359 | if (ft->action+sense==10 && *spp == NULL) { |
337 | perror("SIOCSIFBRDADDR"); | 360 | show_usage(); |
338 | goterr++; | 361 | break; |
339 | } | 362 | } |
340 | spp++; | 363 | if (*spp != NULL) { |
341 | } | 364 | safe_strncpy(host, *spp, (sizeof host)); |
342 | goterr |= set_flag(ifr.ifr_name, IFF_BROADCAST); | ||
343 | continue; | ||
344 | } | ||
345 | if (!strcmp(*spp, "dstaddr")) { | ||
346 | if (*++spp == NULL) | ||
347 | show_usage(); | ||
348 | safe_strncpy(host, *spp, (sizeof host)); | ||
349 | if (INET_resolve(host, &sa) < 0) { | ||
350 | goterr++; | ||
351 | spp++; | ||
352 | continue; | ||
353 | } | ||
354 | memcpy((char *) &ifr.ifr_dstaddr, (char *) &sa, | ||
355 | sizeof(struct sockaddr)); | ||
356 | if (ioctl(sockfd, SIOCSIFDSTADDR, &ifr) < 0) { | ||
357 | fprintf(stderr, "SIOCSIFDSTADDR: %s\n", | ||
358 | strerror(errno)); | ||
359 | goterr++; | ||
360 | } | ||
361 | spp++; | ||
362 | continue; | ||
363 | } | ||
364 | if (!strcmp(*spp, "netmask")) { | ||
365 | if (*++spp == NULL || didnetmask) | ||
366 | show_usage(); | ||
367 | safe_strncpy(host, *spp, (sizeof host)); | ||
368 | if (INET_resolve(host, &sa) < 0) { | ||
369 | goterr++; | ||
370 | spp++; | ||
371 | continue; | ||
372 | } | ||
373 | didnetmask++; | ||
374 | memcpy((char *) &ifr.ifr_netmask, (char *) &sa, | ||
375 | sizeof(struct sockaddr)); | ||
376 | if (ioctl(sockfd, SIOCSIFNETMASK, &ifr) < 0) { | ||
377 | perror("SIOCSIFNETMASK"); | ||
378 | goterr++; | ||
379 | } | ||
380 | spp++; | ||
381 | continue; | ||
382 | } | ||
383 | |||
384 | if (!strcmp(*spp, "-pointopoint")) { | ||
385 | goterr |= clr_flag(ifr.ifr_name, IFF_POINTOPOINT); | ||
386 | spp++; | ||
387 | continue; | ||
388 | } | ||
389 | if (!strcmp(*spp, "pointopoint")) { | ||
390 | if (*(spp + 1) != NULL) { | ||
391 | spp++; | ||
392 | safe_strncpy(host, *spp, (sizeof host)); | ||
393 | if (INET_resolve(host, &sa)) { | ||
394 | goterr++; | ||
395 | spp++; | 365 | spp++; |
396 | continue; | 366 | if (ft->frob == L_HWAD) { |
367 | ecode = in_ether(host, &ifr.ifr_hwaddr); | ||
368 | } else { | ||
369 | switch (ft->frob) { | ||
370 | case L_BROAD: d = &ifr.ifr_broadaddr; break; | ||
371 | case L_DEST: d = &ifr.ifr_dstaddr; break; | ||
372 | case L_MASK: d = &ifr.ifr_netmask; break; | ||
373 | default: error_msg_and_die("bugaboo"); | ||
374 | } | ||
375 | ecode = INET_resolve(host, (struct sockaddr_in *) d); | ||
376 | } | ||
377 | if (ecode < 0 || ioctl(sockfd, ft->sflag, &ifr) < 0) { | ||
378 | perror(ft->name); /* imperfect */ | ||
379 | goterr++; | ||
380 | } | ||
397 | } | 381 | } |
398 | memcpy((char *) &ifr.ifr_dstaddr, (char *) &sa, | 382 | if (ft->flag != 0) { |
399 | sizeof(struct sockaddr)); | 383 | goterr |= set_flag(ifr.ifr_name, ft->flag); |
400 | if (ioctl(sockfd, SIOCSIFDSTADDR, &ifr) < 0) { | ||
401 | perror("SIOCSIFDSTADDR"); | ||
402 | goterr++; | ||
403 | } | 384 | } |
404 | } | 385 | break; |
405 | goterr |= set_flag(ifr.ifr_name, IFF_POINTOPOINT); | 386 | default: |
406 | spp++; | ||
407 | continue; | ||
408 | }; | ||
409 | |||
410 | if (!strcmp(*spp, "hw")) { | ||
411 | if (*++spp == NULL || strcmp("ether", *spp)) { | ||
412 | show_usage(); | 387 | show_usage(); |
413 | } | 388 | } /* end of switch */ |
414 | |||
415 | if (*++spp == NULL) { | ||
416 | /* silently ignore it if no address */ | ||
417 | continue; | ||
418 | } | ||
419 | |||
420 | safe_strncpy(host, *spp, (sizeof host)); | ||
421 | if (in_ether(host, &sa2) < 0) { | ||
422 | fprintf(stderr, "invalid hw-addr %s\n", host); | ||
423 | goterr++; | ||
424 | spp++; | ||
425 | continue; | ||
426 | } | ||
427 | memcpy((char *) &ifr.ifr_hwaddr, (char *) &sa2, | ||
428 | sizeof(struct sockaddr)); | ||
429 | if (ioctl(sockfd, SIOCSIFHWADDR, &ifr) < 0) { | ||
430 | perror("SIOCSIFHWADDR"); | ||
431 | goterr++; | ||
432 | } | ||
433 | spp++; | ||
434 | continue; | 389 | continue; |
435 | } | 390 | } |
436 | 391 | ||
437 | /* If the next argument is a valid hostname, assume OK. */ | 392 | /* If the next argument is a valid hostname, assume OK. */ |
438 | safe_strncpy(host, *spp, (sizeof host)); | 393 | safe_strncpy(host, *spp, (sizeof host)); |
439 | 394 | ||
@@ -471,6 +426,6 @@ int ifconfig_main(int argc, char **argv) | |||
471 | 426 | ||
472 | } /* end of while-loop */ | 427 | } /* end of while-loop */ |
473 | 428 | ||
474 | exit(0); | 429 | return goterr; |
475 | } | 430 | } |
476 | 431 | ||