2 * ifconfig This file contains an implementation of the command
3 * that either displays or sets the characteristics of
4 * one or more of the system's networking interfaces.
6 * Version: $Id: ifconfig.c,v 1.59 2011-01-01 03:22:31 ecki Exp $
8 * Author: Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
9 * and others. Copyright 1993 MicroWalt Corporation
11 * This program is free software; you can redistribute it
12 * and/or modify it under the terms of the GNU General
13 * Public License as published by the Free Software
14 * Foundation; either version 2 of the License, or (at
15 * your option) any later version.
17 * Patched to support 'add' and 'del' keywords for INET(4) addresses
18 * by Mrs. Brisby <mrs.brisby@nimh.org>
20 * {1.34} - 19980630 - Arnaldo Carvalho de Melo <acme@conectiva.com.br>
21 * - gettext instead of catgets for i18n
22 * 10/1998 - Andi Kleen. Use interface list primitives.
23 * 20001008 - Bernd Eckenfels, Patch from RH for setting mtu
24 * (default AF was wrong)
25 * 20010404 - Arnaldo Carvalho de Melo, use setlocale
28 #define DFLT_AF "inet"
33 #include <sys/types.h>
34 #include <sys/socket.h>
35 #include <sys/ioctl.h>
36 #include <netinet/in.h>
38 #include <net/if_arp.h>
48 /* Ugh. But libc5 doesn't provide POSIX types. */
49 #include <asm/types.h>
53 #include <linux/if_slip.h>
60 * This is in linux/include/net/ipv6.h.
64 struct in6_addr ifr6_addr;
66 unsigned int ifr6_ifindex;
71 #endif /* HAVE_AFINET6 */
74 #if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1)
75 #include <netipx/ipx.h>
80 #include "net-support.h"
81 #include "pathnames.h"
84 #include "interface.h"
88 char *Release = RELEASE, *Version = "ifconfig 1.42 (2001-04-13)";
90 int opt_a = 0; /* show all interfaces */
91 int opt_v = 0; /* debugging output flag */
93 int addr_family = 0; /* currently selected AF */
95 /* for ipv4 add/del modes */
96 static int get_nmbc_parent(char *parent, unsigned long *nm,
98 static int set_ifstate(char *parent, unsigned long ip,
99 unsigned long nm, unsigned long bc,
102 static int if_print(char *ifname)
107 printf(_("Iface MTU Met RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg\n"));
110 res = for_all_interfaces(do_if_print, &opt_a);
112 struct interface *ife;
114 ife = lookup_interface(ifname);
118 res = do_if_fetch(ife);
125 /* Set a certain interface flag. */
126 static int set_flag(char *ifname, short flag)
130 safe_strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
131 if (ioctl(skfd, SIOCGIFFLAGS, &ifr) < 0) {
132 fprintf(stderr, _("%s: ERROR while getting interface flags: %s\n"),
133 ifname, strerror(errno));
136 safe_strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
137 ifr.ifr_flags |= flag;
138 if (ioctl(skfd, SIOCSIFFLAGS, &ifr) < 0) {
139 perror("SIOCSIFFLAGS");
145 /* Clear a certain interface flag. */
146 static int clr_flag(char *ifname, short flag)
151 if (strchr(ifname, ':')) {
152 /* This is a v4 alias interface. Downing it via a socket for
153 another AF may have bad consequences. */
154 fd = get_socket_for_af(AF_INET);
156 fprintf(stderr, _("No support for INET on this system.\n"));
162 safe_strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
163 if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) {
164 fprintf(stderr, _("%s: ERROR while getting interface flags: %s\n"),
165 ifname, strerror(errno));
168 safe_strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
169 ifr.ifr_flags &= ~flag;
170 if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0) {
171 perror("SIOCSIFFLAGS");
177 /** test is a specified flag is set */
178 static int test_flag(char *ifname, short flags)
183 if (strchr(ifname, ':')) {
184 /* This is a v4 alias interface. Downing it via a socket for
185 another AF may have bad consequences. */
186 fd = get_socket_for_af(AF_INET);
188 fprintf(stderr, _("No support for INET on this system.\n"));
194 safe_strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
195 if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) {
196 fprintf(stderr, _("%s: ERROR while testing interface flags: %s\n"),
197 ifname, strerror(errno));
200 return (ifr.ifr_flags & flags);
203 static void usage(void)
205 fprintf(stderr, _("Usage:\n ifconfig [-a] [-v] [-s] <interface> [[<AF>] <address>]\n"));
207 fprintf(stderr, _(" [add <address>[/<prefixlen>]]\n"));
208 fprintf(stderr, _(" [del <address>[/<prefixlen>]]\n"));
209 fprintf(stderr, _(" [[-]broadcast [<address>]] [[-]pointopoint [<address>]]\n"));
210 fprintf(stderr, _(" [netmask <address>] [dstaddr <address>] [tunnel <address>]\n"));
212 #ifdef SIOCSKEEPALIVE
213 fprintf(stderr, _(" [outfill <NN>] [keepalive <NN>]\n"));
215 fprintf(stderr, _(" [hw <HW> <address>] [metric <NN>] [mtu <NN>]\n"));
216 fprintf(stderr, _(" [[-]trailers] [[-]arp] [[-]allmulti]\n"));
217 fprintf(stderr, _(" [multicast] [[-]promisc]\n"));
218 fprintf(stderr, _(" [mem_start <NN>] [io_addr <NN>] [irq <NN>] [media <type>]\n"));
219 #ifdef HAVE_TXQUEUELEN
220 fprintf(stderr, _(" [txqueuelen <NN>]\n"));
223 fprintf(stderr, _(" [[-]dynamic]\n"));
225 fprintf(stderr, _(" [up|down] ...\n\n"));
227 fprintf(stderr, _(" <HW>=Hardware Type.\n"));
228 fprintf(stderr, _(" List of possible hardware types:\n"));
229 print_hwlist(0); /* 1 = ARPable */
230 fprintf(stderr, _(" <AF>=Address family. Default: %s\n"), DFLT_AF);
231 fprintf(stderr, _(" List of possible address families:\n"));
232 print_aflist(0); /* 1 = routeable */
236 static void version(void)
238 fprintf(stderr, "%s\n%s\n", Release, Version);
242 static int set_netmask(int skfd, struct ifreq *ifr, struct sockaddr *sa)
246 memcpy((char *) &ifr->ifr_netmask, (char *) sa,
247 sizeof(struct sockaddr));
248 if (ioctl(skfd, SIOCSIFNETMASK, ifr) < 0) {
249 fprintf(stderr, "SIOCSIFNETMASK: %s\n",
256 int main(int argc, char **argv)
259 struct sockaddr samask;
260 struct sockaddr_in sin;
265 int goterr = 0, didnetmask = 0, neednetmask=0;
269 extern struct aftype inet6_aftype;
270 struct sockaddr_in6 sa6;
271 struct in6_ifreq ifr6;
272 unsigned long prefix_len;
276 extern struct aftype inet_aftype;
280 setlocale (LC_ALL, "");
281 bindtextdomain("net-tools", "/usr/share/locale");
282 textdomain("net-tools");
285 /* Find any options. */
288 while (argc && *argv[0] == '-') {
289 if (!strcmp(*argv, "-a"))
292 else if (!strcmp(*argv, "-s"))
295 else if (!strcmp(*argv, "-v"))
298 else if (!strcmp(*argv, "-V") || !strcmp(*argv, "-version") ||
299 !strcmp(*argv, "--version"))
302 else if (!strcmp(*argv, "-?") || !strcmp(*argv, "-h") ||
303 !strcmp(*argv, "-help") || !strcmp(*argv, "--help"))
307 fprintf(stderr, _("ifconfig: option `%s' not recognised.\n"),
309 fprintf(stderr, _("ifconfig: `--help' gives usage information.\n"));
317 /* Create a channel to the NET kernel. */
318 if ((skfd = sockets_open(0)) < 0) {
323 /* Do we have to show the current setup? */
325 int err = if_print((char *) NULL);
329 /* No. Fetch the interface name. */
331 safe_strncpy(ifr.ifr_name, *spp++, IFNAMSIZ);
332 if (*spp == (char *) NULL) {
333 int err = if_print(ifr.ifr_name);
338 /* The next argument is either an address family name, or an option. */
339 if ((ap = get_aftype(*spp)) != NULL)
340 spp++; /* it was a AF name */
342 ap = get_aftype(DFLT_AF);
345 addr_family = ap->af;
349 /* Process the remaining arguments. */
350 while (*spp != (char *) NULL) {
351 if (!strcmp(*spp, "arp")) {
352 goterr |= clr_flag(ifr.ifr_name, IFF_NOARP);
356 if (!strcmp(*spp, "-arp")) {
357 goterr |= set_flag(ifr.ifr_name, IFF_NOARP);
362 if (!strcmp(*spp, "media") || !strcmp(*spp, "port")) {
365 if (!strcasecmp(*spp, "auto")) {
366 goterr |= set_flag(ifr.ifr_name, IFF_AUTOMEDIA);
370 newport = strtol(*spp, &endp, 10);
373 for (i = 0; if_port_text[i][0] && newport == -1; i++) {
374 for (j = 0; if_port_text[i][j]; j++) {
375 if (!strcasecmp(*spp, if_port_text[i][j])) {
384 fprintf(stderr, _("Unknown media type.\n"));
387 if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) {
388 perror("port: SIOCGIFMAP");
392 ifr.ifr_map.port = newport;
393 if (ioctl(skfd, SIOCSIFMAP, &ifr) < 0) {
394 perror("port: SIOCSIFMAP");
403 if (!strcmp(*spp, "trailers")) {
404 goterr |= clr_flag(ifr.ifr_name, IFF_NOTRAILERS);
408 if (!strcmp(*spp, "-trailers")) {
409 goterr |= set_flag(ifr.ifr_name, IFF_NOTRAILERS);
413 if (!strcmp(*spp, "promisc")) {
414 goterr |= set_flag(ifr.ifr_name, IFF_PROMISC);
418 if (!strcmp(*spp, "-promisc")) {
419 goterr |= clr_flag(ifr.ifr_name, IFF_PROMISC);
420 if (test_flag(ifr.ifr_name, IFF_PROMISC) > 0)
421 fprintf(stderr, _("Warning: Interface %s still in promisc mode... maybe other application is running?\n"), ifr.ifr_name);
425 if (!strcmp(*spp, "multicast")) {
426 goterr |= set_flag(ifr.ifr_name, IFF_MULTICAST);
430 if (!strcmp(*spp, "-multicast")) {
431 goterr |= clr_flag(ifr.ifr_name, IFF_MULTICAST);
432 if (test_flag(ifr.ifr_name, IFF_MULTICAST) > 0)
433 fprintf(stderr, _("Warning: Interface %s still in MULTICAST mode.\n"), ifr.ifr_name);
437 if (!strcmp(*spp, "allmulti")) {
438 goterr |= set_flag(ifr.ifr_name, IFF_ALLMULTI);
442 if (!strcmp(*spp, "-allmulti")) {
443 goterr |= clr_flag(ifr.ifr_name, IFF_ALLMULTI);
444 if (test_flag(ifr.ifr_name, IFF_MULTICAST) > 0)
445 fprintf(stderr, _("Warning: Interface %s still in ALLMULTI mode.\n"), ifr.ifr_name);
449 if (!strcmp(*spp, "up")) {
450 goterr |= set_flag(ifr.ifr_name, (IFF_UP | IFF_RUNNING));
454 if (!strcmp(*spp, "down")) {
455 goterr |= clr_flag(ifr.ifr_name, IFF_UP);
460 if (!strcmp(*spp, "dynamic")) {
461 goterr |= set_flag(ifr.ifr_name, IFF_DYNAMIC);
465 if (!strcmp(*spp, "-dynamic")) {
466 goterr |= clr_flag(ifr.ifr_name, IFF_DYNAMIC);
468 if (test_flag(ifr.ifr_name, IFF_MULTICAST) > 0)
469 fprintf(stderr, _("Warning: Interface %s still in DYNAMIC mode.\n"), ifr.ifr_name);
474 if (!strcmp(*spp, "metric")) {
477 ifr.ifr_metric = atoi(*spp);
478 if (ioctl(skfd, SIOCSIFMETRIC, &ifr) < 0) {
479 fprintf(stderr, "SIOCSIFMETRIC: %s\n", strerror(errno));
485 if (!strcmp(*spp, "mtu")) {
488 ifr.ifr_mtu = atoi(*spp);
489 if (ioctl(skfd, SIOCSIFMTU, &ifr) < 0) {
490 fprintf(stderr, "SIOCSIFMTU: %s\n", strerror(errno));
496 #ifdef SIOCSKEEPALIVE
497 if (!strcmp(*spp, "keepalive")) {
500 ifr.ifr_data = (caddr_t) (uintptr_t) atoi(*spp);
501 if (ioctl(skfd, SIOCSKEEPALIVE, &ifr) < 0) {
502 fprintf(stderr, "SIOCSKEEPALIVE: %s\n", strerror(errno));
511 if (!strcmp(*spp, "outfill")) {
514 ifr.ifr_data = (caddr_t) (uintptr_t) atoi(*spp);
515 if (ioctl(skfd, SIOCSOUTFILL, &ifr) < 0) {
516 fprintf(stderr, "SIOCSOUTFILL: %s\n", strerror(errno));
524 if (!strcmp(*spp, "-broadcast")) {
525 goterr |= clr_flag(ifr.ifr_name, IFF_BROADCAST);
526 if (test_flag(ifr.ifr_name, IFF_MULTICAST) > 0)
527 fprintf(stderr, _("Warning: Interface %s still in BROADCAST mode.\n"), ifr.ifr_name);
531 if (!strcmp(*spp, "broadcast")) {
532 if (*++spp != NULL) {
533 safe_strncpy(host, *spp, (sizeof host));
534 if (ap->input(0, host, &sa) < 0) {
538 fprintf(stderr, _("ifconfig: Error resolving '%s' for broadcast\n"), host);
543 memcpy((char *) &ifr.ifr_broadaddr, (char *) &sa,
544 sizeof(struct sockaddr));
545 if (ioctl(ap->fd, SIOCSIFBRDADDR, &ifr) < 0) {
546 fprintf(stderr, "SIOCSIFBRDADDR: %s\n",
552 goterr |= set_flag(ifr.ifr_name, IFF_BROADCAST);
555 if (!strcmp(*spp, "dstaddr")) {
558 safe_strncpy(host, *spp, (sizeof host));
559 if (ap->input(0, host, &sa) < 0) {
563 fprintf(stderr, _("ifconfig: Error resolving '%s' for dstaddr\n"), host);
568 memcpy((char *) &ifr.ifr_dstaddr, (char *) &sa,
569 sizeof(struct sockaddr));
570 if (ioctl(ap->fd, SIOCSIFDSTADDR, &ifr) < 0) {
571 fprintf(stderr, "SIOCSIFDSTADDR: %s\n",
578 if (!strcmp(*spp, "netmask")) {
579 if (*++spp == NULL || didnetmask)
581 safe_strncpy(host, *spp, (sizeof host));
582 if (ap->input(0, host, &sa) < 0) {
586 fprintf(stderr, _("ifconfig: Error resolving '%s' for netmask\n"), host);
592 goterr |= set_netmask(ap->fd, &ifr, &sa);
596 #ifdef HAVE_TXQUEUELEN
597 if (!strcmp(*spp, "txqueuelen")) {
600 ifr.ifr_qlen = strtoul(*spp, NULL, 0);
601 if (ioctl(skfd, SIOCSIFTXQLEN, &ifr) < 0) {
602 fprintf(stderr, "SIOCSIFTXQLEN: %s\n", strerror(errno));
610 if (!strcmp(*spp, "mem_start")) {
613 if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) {
614 fprintf(stderr, "mem_start: SIOCGIFMAP: %s\n", strerror(errno));
619 ifr.ifr_map.mem_start = strtoul(*spp, NULL, 0);
620 if (ioctl(skfd, SIOCSIFMAP, &ifr) < 0) {
621 fprintf(stderr, "mem_start: SIOCSIFMAP: %s\n", strerror(errno));
627 if (!strcmp(*spp, "io_addr")) {
630 if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) {
631 fprintf(stderr, "io_addr: SIOCGIFMAP: %s\n", strerror(errno));
636 ifr.ifr_map.base_addr = strtol(*spp, NULL, 0);
637 if (ioctl(skfd, SIOCSIFMAP, &ifr) < 0) {
638 fprintf(stderr, "io_addr: SIOCSIFMAP: %s\n", strerror(errno));
644 if (!strcmp(*spp, "irq")) {
647 if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) {
648 fprintf(stderr, "irq: SIOCGIFMAP: %s\n", strerror(errno));
653 ifr.ifr_map.irq = atoi(*spp);
654 if (ioctl(skfd, SIOCSIFMAP, &ifr) < 0) {
655 fprintf(stderr, "irq: SIOCSIFMAP: %s\n", strerror(errno));
661 if (!strcmp(*spp, "-pointopoint")) {
662 goterr |= clr_flag(ifr.ifr_name, IFF_POINTOPOINT);
664 if (test_flag(ifr.ifr_name, IFF_MULTICAST) > 0)
665 fprintf(stderr, _("Warning: Interface %s still in POINTOPOINT mode.\n"), ifr.ifr_name);
668 if (!strcmp(*spp, "pointopoint")) {
669 if (*(spp + 1) != NULL) {
671 safe_strncpy(host, *spp, (sizeof host));
672 if (ap->input(0, host, &sa)) {
676 fprintf(stderr, _("ifconfig: Error resolving '%s' for pointopoint\n"), host);
681 memcpy((char *) &ifr.ifr_dstaddr, (char *) &sa,
682 sizeof(struct sockaddr));
683 if (ioctl(ap->fd, SIOCSIFDSTADDR, &ifr) < 0) {
684 fprintf(stderr, "SIOCSIFDSTADDR: %s\n",
689 goterr |= set_flag(ifr.ifr_name, IFF_POINTOPOINT);
694 if (!strcmp(*spp, "hw")) {
697 if ((hw = get_hwtype(*spp)) == NULL)
699 if (hw->input == NULL) {
700 fprintf(stderr, _("hw address type `%s' has no handler to set address. failed.\n"), *spp);
707 safe_strncpy(host, *spp, (sizeof host));
708 if (hw->input(host, &sa) < 0) {
709 fprintf(stderr, _("%s: invalid %s address.\n"), host, hw->name);
714 memcpy((char *) &ifr.ifr_hwaddr, (char *) &sa,
715 sizeof(struct sockaddr));
716 if (ioctl(skfd, SIOCSIFHWADDR, &ifr) < 0) {
718 fprintf(stderr, "SIOCSIFHWADDR: %s - you may need to down the interface\n",
721 fprintf(stderr, "SIOCSIFHWADDR: %s\n",
728 #if HAVE_AFINET || HAVE_AFINET6
729 if (!strcmp(*spp, "add")) {
733 if (strchr(*spp, ':')) {
735 if ((cp = strchr(*spp, '/'))) {
736 prefix_len = atol(cp + 1);
737 if ((prefix_len < 0) || (prefix_len > 128))
743 safe_strncpy(host, *spp, (sizeof host));
744 if (inet6_aftype.input(1, host,
745 (struct sockaddr *) &sa6) < 0) {
746 if (inet6_aftype.herror)
747 inet6_aftype.herror(host);
749 fprintf(stderr, _("ifconfig: Error resolving '%s' for add\n"), host);
754 memcpy((char *) &ifr6.ifr6_addr, (char *) &sa6.sin6_addr,
755 sizeof(struct in6_addr));
757 fd = get_socket_for_af(AF_INET6);
760 _("No support for INET6 on this system.\n"));
765 if (ioctl(fd, SIOGIFINDEX, &ifr) < 0) {
766 perror("SIOGIFINDEX");
771 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
772 ifr6.ifr6_prefixlen = prefix_len;
773 if (ioctl(fd, SIOCSIFADDR, &ifr6) < 0) {
774 perror("SIOCSIFADDR");
782 { /* ipv4 address a.b.c.d */
783 unsigned long ip, nm, bc;
784 safe_strncpy(host, *spp, (sizeof host));
785 if (inet_aftype.input(0, host, (struct sockaddr *)&sin) < 0) {
791 fd = get_socket_for_af(AF_INET);
794 _("No support for INET on this system.\n"));
800 memcpy(&ip, &sin.sin_addr.s_addr, sizeof(unsigned long));
802 if (get_nmbc_parent(ifr.ifr_name, &nm, &bc) < 0) {
803 fprintf(stderr, _("Interface %s not initialized\n"),
809 set_ifstate(ifr.ifr_name, ip, nm, bc, 1);
815 fprintf(stderr, _("Bad address.\n"));
820 #if HAVE_AFINET || HAVE_AFINET6
821 if (!strcmp(*spp, "del")) {
827 if (strchr(*spp, ':')) { /* INET6 */
828 if ((cp = strchr(*spp, '/'))) {
829 prefix_len = atol(cp + 1);
830 if ((prefix_len < 0) || (prefix_len > 128))
836 safe_strncpy(host, *spp, (sizeof host));
837 if (inet6_aftype.input(1, host,
838 (struct sockaddr *) &sa6) < 0) {
839 inet6_aftype.herror(host);
844 memcpy((char *) &ifr6.ifr6_addr, (char *) &sa6.sin6_addr,
845 sizeof(struct in6_addr));
847 fd = get_socket_for_af(AF_INET6);
850 _("No support for INET6 on this system.\n"));
855 if (ioctl(fd, SIOGIFINDEX, &ifr) < 0) {
856 perror("SIOGIFINDEX");
861 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
862 ifr6.ifr6_prefixlen = prefix_len;
864 fprintf(stderr, "now deleting: ioctl(SIOCDIFADDR,{ifindex=%d,prefixlen=%ld})\n",ifr.ifr_ifindex,prefix_len);
865 if (ioctl(fd, SIOCDIFADDR, &ifr6) < 0) {
866 fprintf(stderr, "SIOCDIFADDR: %s\n",
876 /* ipv4 address a.b.c.d */
877 unsigned long ip, nm, bc;
878 safe_strncpy(host, *spp, (sizeof host));
879 if (inet_aftype.input(0, host, (struct sockaddr *)&sin) < 0) {
885 fd = get_socket_for_af(AF_INET);
887 fprintf(stderr, _("No support for INET on this system.\n"));
893 memcpy(&ip, &sin.sin_addr.s_addr, sizeof(unsigned long));
895 if (get_nmbc_parent(ifr.ifr_name, &nm, &bc) < 0) {
896 fprintf(stderr, _("Interface %s not initialized\n"),
902 set_ifstate(ifr.ifr_name, ip, nm, bc, 0);
907 fprintf(stderr, _("Bad address.\n"));
910 fprintf(stderr, _("Address deletion not supported on this system.\n"));
915 if (!strcmp(*spp, "tunnel")) {
918 if ((cp = strchr(*spp, '/'))) {
919 prefix_len = atol(cp + 1);
920 if ((prefix_len < 0) || (prefix_len > 128))
926 safe_strncpy(host, *spp, (sizeof host));
927 if (inet6_aftype.input(1, host, (struct sockaddr *) &sa6) < 0) {
928 inet6_aftype.herror(host);
933 memcpy((char *) &ifr6.ifr6_addr, (char *) &sa6.sin6_addr,
934 sizeof(struct in6_addr));
936 fd = get_socket_for_af(AF_INET6);
938 fprintf(stderr, _("No support for INET6 on this system.\n"));
943 if (ioctl(fd, SIOGIFINDEX, &ifr) < 0) {
944 perror("SIOGIFINDEX");
949 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
950 ifr6.ifr6_prefixlen = prefix_len;
952 if (ioctl(fd, SIOCSIFDSTADDR, &ifr6) < 0) {
953 fprintf(stderr, "SIOCSIFDSTADDR: %s\n",
962 /* If the next argument is a valid hostname, assume OK. */
963 safe_strncpy(host, *spp, (sizeof host));
965 /* FIXME: sa is too small for INET6 addresses, inet6 should use that too,
966 broadcast is unexpected */
968 switch (ap->getmask(host, &samask, NULL)) {
976 // remeber to set the netmask from samask later
981 if (ap->input == NULL) {
982 fprintf(stderr, _("ifconfig: Cannot set address for this protocol family.\n"));
985 if (ap->input(0, host, &sa) < 0) {
989 fprintf(stderr,_("ifconfig: error resolving '%s' to set address for af=%s\n"), host, ap->name); fprintf(stderr,
990 _("ifconfig: `--help' gives usage information.\n")); exit(1);
992 memcpy((char *) &ifr.ifr_addr, (char *) &sa, sizeof(struct sockaddr));
994 int r = 0; /* to shut gcc up */
998 fd = get_socket_for_af(AF_INET);
1000 fprintf(stderr, _("No support for INET on this system.\n"));
1003 r = ioctl(fd, SIOCSIFADDR, &ifr);
1008 fd = get_socket_for_af(AF_ECONET);
1010 fprintf(stderr, _("No support for ECONET on this system.\n"));
1013 r = ioctl(fd, SIOCSIFADDR, &ifr);
1018 _("Don't know how to set addresses for family %d.\n"), ap->af);
1022 perror("SIOCSIFADDR");
1028 * Don't do the set_flag() if the address is an alias with a - at the
1029 * end, since it's deleted already! - Roman
1031 * Should really use regex.h here, not sure though how well it'll go
1032 * with the cross-platform support etc.
1036 short int found_colon = 0;
1037 for (ptr = ifr.ifr_name; *ptr; ptr++ )
1038 if (*ptr == ':') found_colon++;
1040 if (!(found_colon && *(ptr - 1) == '-'))
1041 goterr |= set_flag(ifr.ifr_name, (IFF_UP | IFF_RUNNING));
1048 goterr |= set_netmask(skfd, &ifr, &samask);
1052 if (opt_v && goterr)
1053 fprintf(stderr, _("WARNING: at least one error occured. (%d)\n"), goterr);
1065 static unsigned char searcher[256];
1067 static int set_ip_using(const char *name, int c, unsigned long ip)
1070 struct sockaddr_in sin;
1072 safe_strncpy(ifr.ifr_name, name, IFNAMSIZ);
1073 memset(&sin, 0, sizeof(struct sockaddr));
1074 sin.sin_family = AF_INET;
1075 sin.sin_addr.s_addr = ip;
1076 memcpy(&ifr.ifr_addr, &sin, sizeof(struct sockaddr));
1077 if (ioctl(skfd, c, &ifr) < 0)
1082 static int do_ifcmd(struct interface *x, struct ifcmd *ptr)
1085 struct sockaddr_in *sin;
1088 if (do_if_fetch(x) < 0)
1090 if (strncmp(x->name, ptr->base, ptr->baselen) != 0)
1091 return 0; /* skip */
1092 z = strchr(x->name, ':');
1096 for (e = z; *e; e++)
1097 if (*e == '-') /* deleted */
1100 if (i < 0 || i > 255)
1105 sin = (struct sockaddr_in *)&x->dstaddr;
1106 if (sin->sin_addr.s_addr != ptr->addr) {
1112 if (set_flag(x->name, IFF_UP | IFF_RUNNING) == -1)
1116 if (clr_flag(x->name, IFF_UP) == -1)
1120 return 1; /* all done! */
1124 static int get_nmbc_parent(char *parent,
1125 unsigned long *nm, unsigned long *bc)
1127 struct interface *i;
1128 struct sockaddr_in *sin;
1130 i = lookup_interface(parent);
1133 if (do_if_fetch(i) < 0)
1135 sin = (struct sockaddr_in *)&i->netmask;
1136 memcpy(nm, &sin->sin_addr.s_addr, sizeof(unsigned long));
1137 sin = (struct sockaddr_in *)&i->broadaddr;
1138 memcpy(bc, &sin->sin_addr.s_addr, sizeof(unsigned long));
1142 static int set_ifstate(char *parent, unsigned long ip,
1143 unsigned long nm, unsigned long bc,
1151 pt.baselen = strlen(parent);
1154 memset(searcher, 0, sizeof(searcher));
1155 i = for_all_interfaces((int (*)(struct interface *,void *))do_ifcmd,
1162 /* add a new interface */
1163 for (i = 0; i < 256; i++)
1164 if (searcher[i] == 0)
1168 return -1; /* FAILURE!!! out of ip addresses */
1170 if (snprintf(buf, IFNAMSIZ, "%s:%d", parent, i) > IFNAMSIZ)
1172 if (set_ip_using(buf, SIOCSIFADDR, ip) == -1)
1174 if (set_ip_using(buf, SIOCSIFNETMASK, nm) == -1)
1176 if (set_ip_using(buf, SIOCSIFBRDADDR, bc) == -1)
1178 if (set_flag(buf, IFF_BROADCAST) == -1)