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 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>] [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_ALLMULTI) > 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_DYNAMIC) > 0)
469 fprintf(stderr, _("Warning: Interface %s still in DYNAMIC mode.\n"), ifr.ifr_name);
474 if (!strcmp(*spp, "mtu")) {
477 ifr.ifr_mtu = atoi(*spp);
478 if (ioctl(skfd, SIOCSIFMTU, &ifr) < 0) {
479 fprintf(stderr, "SIOCSIFMTU: %s\n", strerror(errno));
485 #ifdef SIOCSKEEPALIVE
486 if (!strcmp(*spp, "keepalive")) {
489 ifr.ifr_data = (caddr_t) (uintptr_t) atoi(*spp);
490 if (ioctl(skfd, SIOCSKEEPALIVE, &ifr) < 0) {
491 fprintf(stderr, "SIOCSKEEPALIVE: %s\n", strerror(errno));
500 if (!strcmp(*spp, "outfill")) {
503 ifr.ifr_data = (caddr_t) (uintptr_t) atoi(*spp);
504 if (ioctl(skfd, SIOCSOUTFILL, &ifr) < 0) {
505 fprintf(stderr, "SIOCSOUTFILL: %s\n", strerror(errno));
513 if (!strcmp(*spp, "-broadcast")) {
514 goterr |= clr_flag(ifr.ifr_name, IFF_BROADCAST);
515 if (test_flag(ifr.ifr_name, IFF_BROADCAST) > 0)
516 fprintf(stderr, _("Warning: Interface %s still in BROADCAST mode.\n"), ifr.ifr_name);
520 if (!strcmp(*spp, "broadcast")) {
521 if (*++spp != NULL) {
522 safe_strncpy(host, *spp, (sizeof host));
523 if (ap->input(0, host, &sa) < 0) {
527 fprintf(stderr, _("ifconfig: Error resolving '%s' for broadcast\n"), host);
532 memcpy((char *) &ifr.ifr_broadaddr, (char *) &sa,
533 sizeof(struct sockaddr));
534 if (ioctl(ap->fd, SIOCSIFBRDADDR, &ifr) < 0) {
535 fprintf(stderr, "SIOCSIFBRDADDR: %s\n",
541 goterr |= set_flag(ifr.ifr_name, IFF_BROADCAST);
544 if (!strcmp(*spp, "dstaddr")) {
547 safe_strncpy(host, *spp, (sizeof host));
548 if (ap->input(0, host, &sa) < 0) {
552 fprintf(stderr, _("ifconfig: Error resolving '%s' for dstaddr\n"), host);
557 memcpy((char *) &ifr.ifr_dstaddr, (char *) &sa,
558 sizeof(struct sockaddr));
559 if (ioctl(ap->fd, SIOCSIFDSTADDR, &ifr) < 0) {
560 fprintf(stderr, "SIOCSIFDSTADDR: %s\n",
567 if (!strcmp(*spp, "netmask")) {
568 if (*++spp == NULL || didnetmask)
570 safe_strncpy(host, *spp, (sizeof host));
571 if (ap->input(0, host, &sa) < 0) {
575 fprintf(stderr, _("ifconfig: Error resolving '%s' for netmask\n"), host);
581 goterr |= set_netmask(ap->fd, &ifr, &sa);
585 #ifdef HAVE_TXQUEUELEN
586 if (!strcmp(*spp, "txqueuelen")) {
589 ifr.ifr_qlen = strtoul(*spp, NULL, 0);
590 if (ioctl(skfd, SIOCSIFTXQLEN, &ifr) < 0) {
591 fprintf(stderr, "SIOCSIFTXQLEN: %s\n", strerror(errno));
599 if (!strcmp(*spp, "mem_start")) {
602 if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) {
603 fprintf(stderr, "mem_start: SIOCGIFMAP: %s\n", strerror(errno));
608 ifr.ifr_map.mem_start = strtoul(*spp, NULL, 0);
609 if (ioctl(skfd, SIOCSIFMAP, &ifr) < 0) {
610 fprintf(stderr, "mem_start: SIOCSIFMAP: %s\n", strerror(errno));
616 if (!strcmp(*spp, "io_addr")) {
619 if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) {
620 fprintf(stderr, "io_addr: SIOCGIFMAP: %s\n", strerror(errno));
625 ifr.ifr_map.base_addr = strtol(*spp, NULL, 0);
626 if (ioctl(skfd, SIOCSIFMAP, &ifr) < 0) {
627 fprintf(stderr, "io_addr: SIOCSIFMAP: %s\n", strerror(errno));
633 if (!strcmp(*spp, "irq")) {
636 if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) {
637 fprintf(stderr, "irq: SIOCGIFMAP: %s\n", strerror(errno));
642 ifr.ifr_map.irq = atoi(*spp);
643 if (ioctl(skfd, SIOCSIFMAP, &ifr) < 0) {
644 fprintf(stderr, "irq: SIOCSIFMAP: %s\n", strerror(errno));
650 if (!strcmp(*spp, "-pointopoint")) {
651 goterr |= clr_flag(ifr.ifr_name, IFF_POINTOPOINT);
653 if (test_flag(ifr.ifr_name, IFF_POINTOPOINT) > 0)
654 fprintf(stderr, _("Warning: Interface %s still in POINTOPOINT mode.\n"), ifr.ifr_name);
657 if (!strcmp(*spp, "pointopoint")) {
658 if (*(spp + 1) != NULL) {
660 safe_strncpy(host, *spp, (sizeof host));
661 if (ap->input(0, host, &sa)) {
665 fprintf(stderr, _("ifconfig: Error resolving '%s' for pointopoint\n"), host);
670 memcpy((char *) &ifr.ifr_dstaddr, (char *) &sa,
671 sizeof(struct sockaddr));
672 if (ioctl(ap->fd, SIOCSIFDSTADDR, &ifr) < 0) {
673 fprintf(stderr, "SIOCSIFDSTADDR: %s\n",
678 goterr |= set_flag(ifr.ifr_name, IFF_POINTOPOINT);
683 if (!strcmp(*spp, "hw")) {
686 if ((hw = get_hwtype(*spp)) == NULL)
688 if (hw->input == NULL) {
689 fprintf(stderr, _("hw address type `%s' has no handler to set address. failed.\n"), *spp);
696 safe_strncpy(host, *spp, (sizeof host));
697 if (hw->input(host, &sa) < 0) {
698 fprintf(stderr, _("%s: invalid %s address.\n"), host, hw->name);
703 memcpy((char *) &ifr.ifr_hwaddr, (char *) &sa,
704 sizeof(struct sockaddr));
705 if (ioctl(skfd, SIOCSIFHWADDR, &ifr) < 0) {
707 fprintf(stderr, "SIOCSIFHWADDR: %s - you may need to down the interface\n",
710 fprintf(stderr, "SIOCSIFHWADDR: %s\n",
717 #if HAVE_AFINET || HAVE_AFINET6
718 if (!strcmp(*spp, "add")) {
722 if (strchr(*spp, ':')) {
724 if ((cp = strchr(*spp, '/'))) {
725 prefix_len = atol(cp + 1);
726 if ((prefix_len < 0) || (prefix_len > 128))
732 safe_strncpy(host, *spp, (sizeof host));
733 if (inet6_aftype.input(1, host,
734 (struct sockaddr *) &sa6) < 0) {
735 if (inet6_aftype.herror)
736 inet6_aftype.herror(host);
738 fprintf(stderr, _("ifconfig: Error resolving '%s' for add\n"), host);
743 memcpy((char *) &ifr6.ifr6_addr, (char *) &sa6.sin6_addr,
744 sizeof(struct in6_addr));
746 fd = get_socket_for_af(AF_INET6);
749 _("No support for INET6 on this system.\n"));
754 if (ioctl(fd, SIOGIFINDEX, &ifr) < 0) {
755 perror("SIOGIFINDEX");
760 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
761 ifr6.ifr6_prefixlen = prefix_len;
762 if (ioctl(fd, SIOCSIFADDR, &ifr6) < 0) {
763 perror("SIOCSIFADDR");
771 { /* ipv4 address a.b.c.d */
772 unsigned long ip, nm, bc;
773 safe_strncpy(host, *spp, (sizeof host));
774 if (inet_aftype.input(0, host, (struct sockaddr *)&sin) < 0) {
780 fd = get_socket_for_af(AF_INET);
783 _("No support for INET on this system.\n"));
789 memcpy(&ip, &sin.sin_addr.s_addr, sizeof(unsigned long));
791 if (get_nmbc_parent(ifr.ifr_name, &nm, &bc) < 0) {
792 fprintf(stderr, _("Interface %s not initialized\n"),
798 set_ifstate(ifr.ifr_name, ip, nm, bc, 1);
804 fprintf(stderr, _("Bad address.\n"));
809 #if HAVE_AFINET || HAVE_AFINET6
810 if (!strcmp(*spp, "del")) {
816 if (strchr(*spp, ':')) { /* INET6 */
817 if ((cp = strchr(*spp, '/'))) {
818 prefix_len = atol(cp + 1);
819 if ((prefix_len < 0) || (prefix_len > 128))
825 safe_strncpy(host, *spp, (sizeof host));
826 if (inet6_aftype.input(1, host,
827 (struct sockaddr *) &sa6) < 0) {
828 inet6_aftype.herror(host);
833 memcpy((char *) &ifr6.ifr6_addr, (char *) &sa6.sin6_addr,
834 sizeof(struct in6_addr));
836 fd = get_socket_for_af(AF_INET6);
839 _("No support for INET6 on this system.\n"));
844 if (ioctl(fd, SIOGIFINDEX, &ifr) < 0) {
845 perror("SIOGIFINDEX");
850 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
851 ifr6.ifr6_prefixlen = prefix_len;
853 fprintf(stderr, "now deleting: ioctl(SIOCDIFADDR,{ifindex=%d,prefixlen=%ld})\n",ifr.ifr_ifindex,prefix_len);
854 if (ioctl(fd, SIOCDIFADDR, &ifr6) < 0) {
855 fprintf(stderr, "SIOCDIFADDR: %s\n",
865 /* ipv4 address a.b.c.d */
866 unsigned long ip, nm, bc;
867 safe_strncpy(host, *spp, (sizeof host));
868 if (inet_aftype.input(0, host, (struct sockaddr *)&sin) < 0) {
874 fd = get_socket_for_af(AF_INET);
876 fprintf(stderr, _("No support for INET on this system.\n"));
882 /* Clear "ip" in case sizeof(unsigned long) > sizeof(sin.sin_addr.s_addr) */
884 memcpy(&ip, &sin.sin_addr.s_addr, sizeof(sin.sin_addr.s_addr));
886 if (get_nmbc_parent(ifr.ifr_name, &nm, &bc) < 0) {
887 fprintf(stderr, _("Interface %s not initialized\n"),
893 set_ifstate(ifr.ifr_name, ip, nm, bc, 0);
898 fprintf(stderr, _("Bad address.\n"));
901 fprintf(stderr, _("Address deletion not supported on this system.\n"));
906 if (!strcmp(*spp, "tunnel")) {
909 if ((cp = strchr(*spp, '/'))) {
910 prefix_len = atol(cp + 1);
911 if ((prefix_len < 0) || (prefix_len > 128))
917 safe_strncpy(host, *spp, (sizeof host));
918 if (inet6_aftype.input(1, host, (struct sockaddr *) &sa6) < 0) {
919 inet6_aftype.herror(host);
924 memcpy((char *) &ifr6.ifr6_addr, (char *) &sa6.sin6_addr,
925 sizeof(struct in6_addr));
927 fd = get_socket_for_af(AF_INET6);
929 fprintf(stderr, _("No support for INET6 on this system.\n"));
934 if (ioctl(fd, SIOGIFINDEX, &ifr) < 0) {
935 perror("SIOGIFINDEX");
940 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
941 ifr6.ifr6_prefixlen = prefix_len;
943 if (ioctl(fd, SIOCSIFDSTADDR, &ifr6) < 0) {
944 fprintf(stderr, "SIOCSIFDSTADDR: %s\n",
953 /* If the next argument is a valid hostname, assume OK. */
954 safe_strncpy(host, *spp, (sizeof host));
956 /* FIXME: sa is too small for INET6 addresses, inet6 should use that too,
957 broadcast is unexpected */
959 switch (ap->getmask(host, &samask, NULL)) {
967 // remeber to set the netmask from samask later
972 if (ap->input == NULL) {
973 fprintf(stderr, _("ifconfig: Cannot set address for this protocol family.\n"));
976 if (ap->input(0, host, &sa) < 0) {
980 fprintf(stderr,_("ifconfig: error resolving '%s' to set address for af=%s\n"), host, ap->name); fprintf(stderr,
981 _("ifconfig: `--help' gives usage information.\n")); exit(1);
983 memcpy((char *) &ifr.ifr_addr, (char *) &sa, sizeof(struct sockaddr));
985 int r = 0; /* to shut gcc up */
989 fd = get_socket_for_af(AF_INET);
991 fprintf(stderr, _("No support for INET on this system.\n"));
994 r = ioctl(fd, SIOCSIFADDR, &ifr);
999 fd = get_socket_for_af(AF_ECONET);
1001 fprintf(stderr, _("No support for ECONET on this system.\n"));
1004 r = ioctl(fd, SIOCSIFADDR, &ifr);
1009 _("Don't know how to set addresses for family %d.\n"), ap->af);
1013 perror("SIOCSIFADDR");
1019 * Don't do the set_flag() if the address is an alias with a - at the
1020 * end, since it's deleted already! - Roman
1022 * Should really use regex.h here, not sure though how well it'll go
1023 * with the cross-platform support etc.
1027 short int found_colon = 0;
1028 for (ptr = ifr.ifr_name; *ptr; ptr++ )
1029 if (*ptr == ':') found_colon++;
1031 if (!(found_colon && *(ptr - 1) == '-'))
1032 goterr |= set_flag(ifr.ifr_name, (IFF_UP | IFF_RUNNING));
1039 goterr |= set_netmask(skfd, &ifr, &samask);
1043 if (opt_v && goterr)
1044 fprintf(stderr, _("WARNING: at least one error occured. (%d)\n"), goterr);
1056 static unsigned char searcher[256];
1058 static int set_ip_using(const char *name, int c, unsigned long ip)
1061 struct sockaddr_in sin;
1063 safe_strncpy(ifr.ifr_name, name, IFNAMSIZ);
1064 memset(&sin, 0, sizeof(struct sockaddr));
1065 sin.sin_family = AF_INET;
1066 sin.sin_addr.s_addr = ip;
1067 memcpy(&ifr.ifr_addr, &sin, sizeof(struct sockaddr));
1068 if (ioctl(skfd, c, &ifr) < 0)
1073 static int do_ifcmd(struct interface *x, struct ifcmd *ptr)
1076 struct sockaddr_in *sin;
1079 if (do_if_fetch(x) < 0)
1081 if (strncmp(x->name, ptr->base, ptr->baselen) != 0)
1082 return 0; /* skip */
1083 z = strchr(x->name, ':');
1087 for (e = z; *e; e++)
1088 if (*e == '-') /* deleted */
1091 if (i < 0 || i > 255)
1096 sin = (struct sockaddr_in *)&x->dstaddr;
1097 if (sin->sin_addr.s_addr != ptr->addr) {
1103 if (set_flag(x->name, IFF_UP | IFF_RUNNING) == -1)
1107 if (clr_flag(x->name, IFF_UP) == -1)
1111 return 1; /* all done! */
1115 static int get_nmbc_parent(char *parent,
1116 unsigned long *nm, unsigned long *bc)
1118 struct interface *i;
1119 struct sockaddr_in *sin;
1121 i = lookup_interface(parent);
1124 if (do_if_fetch(i) < 0)
1126 sin = (struct sockaddr_in *)&i->netmask;
1127 memcpy(nm, &sin->sin_addr.s_addr, sizeof(unsigned long));
1128 sin = (struct sockaddr_in *)&i->broadaddr;
1129 memcpy(bc, &sin->sin_addr.s_addr, sizeof(unsigned long));
1133 static int set_ifstate(char *parent, unsigned long ip,
1134 unsigned long nm, unsigned long bc,
1142 pt.baselen = strlen(parent);
1145 memset(searcher, 0, sizeof(searcher));
1146 i = for_all_interfaces((int (*)(struct interface *,void *))do_ifcmd,
1153 /* add a new interface */
1154 for (i = 0; i < 256; i++)
1155 if (searcher[i] == 0)
1159 return -1; /* FAILURE!!! out of ip addresses */
1161 if (snprintf(buf, IFNAMSIZ, "%s:%d", parent, i) > IFNAMSIZ)
1163 if (set_ip_using(buf, SIOCSIFADDR, ip) == -1)
1165 if (set_ip_using(buf, SIOCSIFNETMASK, nm) == -1)
1167 if (set_ip_using(buf, SIOCSIFBRDADDR, bc) == -1)
1169 if (set_flag(buf, IFF_BROADCAST) == -1)