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.57 2002/12/10 00:56:41 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
);
115 res
= do_if_fetch(ife
);
122 /* Set a certain interface flag. */
123 static int set_flag(char *ifname
, short flag
)
127 safe_strncpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
128 if (ioctl(skfd
, SIOCGIFFLAGS
, &ifr
) < 0) {
129 fprintf(stderr
, _("%s: ERROR while getting interface flags: %s\n"),
130 ifname
, strerror(errno
));
133 safe_strncpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
134 ifr
.ifr_flags
|= flag
;
135 if (ioctl(skfd
, SIOCSIFFLAGS
, &ifr
) < 0) {
136 perror("SIOCSIFFLAGS");
142 /* Clear a certain interface flag. */
143 static int clr_flag(char *ifname
, short flag
)
148 if (strchr(ifname
, ':')) {
149 /* This is a v4 alias interface. Downing it via a socket for
150 another AF may have bad consequences. */
151 fd
= get_socket_for_af(AF_INET
);
153 fprintf(stderr
, _("No support for INET on this system.\n"));
159 safe_strncpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
160 if (ioctl(fd
, SIOCGIFFLAGS
, &ifr
) < 0) {
161 fprintf(stderr
, _("%s: ERROR while getting interface flags: %s\n"),
162 ifname
, strerror(errno
));
165 safe_strncpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
166 ifr
.ifr_flags
&= ~flag
;
167 if (ioctl(fd
, SIOCSIFFLAGS
, &ifr
) < 0) {
168 perror("SIOCSIFFLAGS");
174 /** test is a specified flag is set */
175 static int test_flag(char *ifname
, short flags
)
180 if (strchr(ifname
, ':')) {
181 /* This is a v4 alias interface. Downing it via a socket for
182 another AF may have bad consequences. */
183 fd
= get_socket_for_af(AF_INET
);
185 fprintf(stderr
, _("No support for INET on this system.\n"));
191 safe_strncpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
192 if (ioctl(fd
, SIOCGIFFLAGS
, &ifr
) < 0) {
193 fprintf(stderr
, _("%s: ERROR while testing interface flags: %s\n"),
194 ifname
, strerror(errno
));
197 return (ifr
.ifr_flags
& flags
);
200 static void usage(void)
202 fprintf(stderr
, _("Usage:\n ifconfig [-a] [-v] [-s] <interface> [[<AF>] <address>]\n"));
204 fprintf(stderr
, _(" [add <address>[/<prefixlen>]]\n"));
205 fprintf(stderr
, _(" [del <address>[/<prefixlen>]]\n"));
206 fprintf(stderr
, _(" [[-]broadcast [<address>]] [[-]pointopoint [<address>]]\n"));
207 fprintf(stderr
, _(" [netmask <address>] [dstaddr <address>] [tunnel <address>]\n"));
209 #ifdef SIOCSKEEPALIVE
210 fprintf(stderr
, _(" [outfill <NN>] [keepalive <NN>]\n"));
212 fprintf(stderr
, _(" [hw <HW> <address>] [metric <NN>] [mtu <NN>]\n"));
213 fprintf(stderr
, _(" [[-]trailers] [[-]arp] [[-]allmulti]\n"));
214 fprintf(stderr
, _(" [multicast] [[-]promisc]\n"));
215 fprintf(stderr
, _(" [mem_start <NN>] [io_addr <NN>] [irq <NN>] [media <type>]\n"));
216 #ifdef HAVE_TXQUEUELEN
217 fprintf(stderr
, _(" [txqueuelen <NN>]\n"));
220 fprintf(stderr
, _(" [[-]dynamic]\n"));
222 fprintf(stderr
, _(" [up|down] ...\n\n"));
224 fprintf(stderr
, _(" <HW>=Hardware Type.\n"));
225 fprintf(stderr
, _(" List of possible hardware types:\n"));
226 print_hwlist(0); /* 1 = ARPable */
227 fprintf(stderr
, _(" <AF>=Address family. Default: %s\n"), DFLT_AF
);
228 fprintf(stderr
, _(" List of possible address families:\n"));
229 print_aflist(0); /* 1 = routeable */
233 static void version(void)
235 fprintf(stderr
, "%s\n%s\n", Release
, Version
);
239 static int set_netmask(int skfd
, struct ifreq
*ifr
, struct sockaddr
*sa
)
243 memcpy((char *) &ifr
->ifr_netmask
, (char *) sa
,
244 sizeof(struct sockaddr
));
245 if (ioctl(skfd
, SIOCSIFNETMASK
, ifr
) < 0) {
246 fprintf(stderr
, "SIOCSIFNETMASK: %s\n",
253 int main(int argc
, char **argv
)
256 struct sockaddr samask
;
257 struct sockaddr_in sin
;
262 int goterr
= 0, didnetmask
= 0, neednetmask
=0;
266 extern struct aftype inet6_aftype
;
267 struct sockaddr_in6 sa6
;
268 struct in6_ifreq ifr6
;
269 unsigned long prefix_len
;
273 extern struct aftype inet_aftype
;
277 setlocale (LC_ALL
, "");
278 bindtextdomain("net-tools", "/usr/share/locale");
279 textdomain("net-tools");
282 /* Find any options. */
285 while (argc
&& *argv
[0] == '-') {
286 if (!strcmp(*argv
, "-a"))
289 else if (!strcmp(*argv
, "-s"))
292 else if (!strcmp(*argv
, "-v"))
295 else if (!strcmp(*argv
, "-V") || !strcmp(*argv
, "-version") ||
296 !strcmp(*argv
, "--version"))
299 else if (!strcmp(*argv
, "-?") || !strcmp(*argv
, "-h") ||
300 !strcmp(*argv
, "-help") || !strcmp(*argv
, "--help"))
304 fprintf(stderr
, _("ifconfig: option `%s' not recognised.\n"),
306 fprintf(stderr
, _("ifconfig: `--help' gives usage information.\n"));
314 /* Create a channel to the NET kernel. */
315 if ((skfd
= sockets_open(0)) < 0) {
320 /* Do we have to show the current setup? */
322 int err
= if_print((char *) NULL
);
326 /* No. Fetch the interface name. */
328 safe_strncpy(ifr
.ifr_name
, *spp
++, IFNAMSIZ
);
329 if (*spp
== (char *) NULL
) {
330 int err
= if_print(ifr
.ifr_name
);
335 /* The next argument is either an address family name, or an option. */
336 if ((ap
= get_aftype(*spp
)) != NULL
)
337 spp
++; /* it was a AF name */
339 ap
= get_aftype(DFLT_AF
);
342 addr_family
= ap
->af
;
346 /* Process the remaining arguments. */
347 while (*spp
!= (char *) NULL
) {
348 if (!strcmp(*spp
, "arp")) {
349 goterr
|= clr_flag(ifr
.ifr_name
, IFF_NOARP
);
353 if (!strcmp(*spp
, "-arp")) {
354 goterr
|= set_flag(ifr
.ifr_name
, IFF_NOARP
);
359 if (!strcmp(*spp
, "media") || !strcmp(*spp
, "port")) {
362 if (!strcasecmp(*spp
, "auto")) {
363 goterr
|= set_flag(ifr
.ifr_name
, IFF_AUTOMEDIA
);
367 newport
= strtol(*spp
, &endp
, 10);
370 for (i
= 0; if_port_text
[i
][0] && newport
== -1; i
++) {
371 for (j
= 0; if_port_text
[i
][j
]; j
++) {
372 if (!strcasecmp(*spp
, if_port_text
[i
][j
])) {
381 fprintf(stderr
, _("Unknown media type.\n"));
384 if (ioctl(skfd
, SIOCGIFMAP
, &ifr
) < 0) {
385 perror("port: SIOCGIFMAP");
389 ifr
.ifr_map
.port
= newport
;
390 if (ioctl(skfd
, SIOCSIFMAP
, &ifr
) < 0) {
391 perror("port: SIOCSIFMAP");
400 if (!strcmp(*spp
, "trailers")) {
401 goterr
|= clr_flag(ifr
.ifr_name
, IFF_NOTRAILERS
);
405 if (!strcmp(*spp
, "-trailers")) {
406 goterr
|= set_flag(ifr
.ifr_name
, IFF_NOTRAILERS
);
410 if (!strcmp(*spp
, "promisc")) {
411 goterr
|= set_flag(ifr
.ifr_name
, IFF_PROMISC
);
415 if (!strcmp(*spp
, "-promisc")) {
416 goterr
|= clr_flag(ifr
.ifr_name
, IFF_PROMISC
);
417 if (test_flag(ifr
.ifr_name
, IFF_PROMISC
) > 0)
418 fprintf(stderr
, _("Warning: Interface %s still in promisc mode... maybe other application is running?\n"), ifr
.ifr_name
);
422 if (!strcmp(*spp
, "multicast")) {
423 goterr
|= set_flag(ifr
.ifr_name
, IFF_MULTICAST
);
427 if (!strcmp(*spp
, "-multicast")) {
428 goterr
|= clr_flag(ifr
.ifr_name
, IFF_MULTICAST
);
429 if (test_flag(ifr
.ifr_name
, IFF_MULTICAST
) > 0)
430 fprintf(stderr
, _("Warning: Interface %s still in MULTICAST mode.\n"), ifr
.ifr_name
);
434 if (!strcmp(*spp
, "allmulti")) {
435 goterr
|= set_flag(ifr
.ifr_name
, IFF_ALLMULTI
);
439 if (!strcmp(*spp
, "-allmulti")) {
440 goterr
|= clr_flag(ifr
.ifr_name
, IFF_ALLMULTI
);
441 if (test_flag(ifr
.ifr_name
, IFF_MULTICAST
) > 0)
442 fprintf(stderr
, _("Warning: Interface %s still in ALLMULTI mode.\n"), ifr
.ifr_name
);
446 if (!strcmp(*spp
, "up")) {
447 goterr
|= set_flag(ifr
.ifr_name
, (IFF_UP
| IFF_RUNNING
));
451 if (!strcmp(*spp
, "down")) {
452 goterr
|= clr_flag(ifr
.ifr_name
, IFF_UP
);
457 if (!strcmp(*spp
, "dynamic")) {
458 goterr
|= set_flag(ifr
.ifr_name
, IFF_DYNAMIC
);
462 if (!strcmp(*spp
, "-dynamic")) {
463 goterr
|= clr_flag(ifr
.ifr_name
, IFF_DYNAMIC
);
465 if (test_flag(ifr
.ifr_name
, IFF_MULTICAST
) > 0)
466 fprintf(stderr
, _("Warning: Interface %s still in DYNAMIC mode.\n"), ifr
.ifr_name
);
471 if (!strcmp(*spp
, "metric")) {
474 ifr
.ifr_metric
= atoi(*spp
);
475 if (ioctl(skfd
, SIOCSIFMETRIC
, &ifr
) < 0) {
476 fprintf(stderr
, "SIOCSIFMETRIC: %s\n", strerror(errno
));
482 if (!strcmp(*spp
, "mtu")) {
485 ifr
.ifr_mtu
= atoi(*spp
);
486 if (ioctl(skfd
, SIOCSIFMTU
, &ifr
) < 0) {
487 fprintf(stderr
, "SIOCSIFMTU: %s\n", strerror(errno
));
493 #ifdef SIOCSKEEPALIVE
494 if (!strcmp(*spp
, "keepalive")) {
497 ifr
.ifr_data
= (caddr_t
) atoi(*spp
);
498 if (ioctl(skfd
, SIOCSKEEPALIVE
, &ifr
) < 0) {
499 fprintf(stderr
, "SIOCSKEEPALIVE: %s\n", strerror(errno
));
508 if (!strcmp(*spp
, "outfill")) {
511 ifr
.ifr_data
= (caddr_t
) atoi(*spp
);
512 if (ioctl(skfd
, SIOCSOUTFILL
, &ifr
) < 0) {
513 fprintf(stderr
, "SIOCSOUTFILL: %s\n", strerror(errno
));
521 if (!strcmp(*spp
, "-broadcast")) {
522 goterr
|= clr_flag(ifr
.ifr_name
, IFF_BROADCAST
);
523 if (test_flag(ifr
.ifr_name
, IFF_MULTICAST
) > 0)
524 fprintf(stderr
, _("Warning: Interface %s still in BROADCAST mode.\n"), ifr
.ifr_name
);
528 if (!strcmp(*spp
, "broadcast")) {
529 if (*++spp
!= NULL
) {
530 safe_strncpy(host
, *spp
, (sizeof host
));
531 if (ap
->input(0, host
, &sa
) < 0) {
535 fprintf(stderr
, _("ifconfig: Error resolving '%s' for broadcast\n"), host
);
540 memcpy((char *) &ifr
.ifr_broadaddr
, (char *) &sa
,
541 sizeof(struct sockaddr
));
542 if (ioctl(ap
->fd
, SIOCSIFBRDADDR
, &ifr
) < 0) {
543 fprintf(stderr
, "SIOCSIFBRDADDR: %s\n",
549 goterr
|= set_flag(ifr
.ifr_name
, IFF_BROADCAST
);
552 if (!strcmp(*spp
, "dstaddr")) {
555 safe_strncpy(host
, *spp
, (sizeof host
));
556 if (ap
->input(0, host
, &sa
) < 0) {
560 fprintf(stderr
, _("ifconfig: Error resolving '%s' for dstaddr\n"), host
);
565 memcpy((char *) &ifr
.ifr_dstaddr
, (char *) &sa
,
566 sizeof(struct sockaddr
));
567 if (ioctl(ap
->fd
, SIOCSIFDSTADDR
, &ifr
) < 0) {
568 fprintf(stderr
, "SIOCSIFDSTADDR: %s\n",
575 if (!strcmp(*spp
, "netmask")) {
576 if (*++spp
== NULL
|| didnetmask
)
578 safe_strncpy(host
, *spp
, (sizeof host
));
579 if (ap
->input(0, host
, &sa
) < 0) {
583 fprintf(stderr
, _("ifconfig: Error resolving '%s' for netmask\n"), host
);
589 goterr
|= set_netmask(ap
->fd
, &ifr
, &sa
);
593 #ifdef HAVE_TXQUEUELEN
594 if (!strcmp(*spp
, "txqueuelen")) {
597 ifr
.ifr_qlen
= strtoul(*spp
, NULL
, 0);
598 if (ioctl(skfd
, SIOCSIFTXQLEN
, &ifr
) < 0) {
599 fprintf(stderr
, "SIOCSIFTXQLEN: %s\n", strerror(errno
));
607 if (!strcmp(*spp
, "mem_start")) {
610 if (ioctl(skfd
, SIOCGIFMAP
, &ifr
) < 0) {
611 fprintf(stderr
, "mem_start: SIOCGIFMAP: %s\n", strerror(errno
));
616 ifr
.ifr_map
.mem_start
= strtoul(*spp
, NULL
, 0);
617 if (ioctl(skfd
, SIOCSIFMAP
, &ifr
) < 0) {
618 fprintf(stderr
, "mem_start: SIOCSIFMAP: %s\n", strerror(errno
));
624 if (!strcmp(*spp
, "io_addr")) {
627 if (ioctl(skfd
, SIOCGIFMAP
, &ifr
) < 0) {
628 fprintf(stderr
, "io_addr: SIOCGIFMAP: %s\n", strerror(errno
));
633 ifr
.ifr_map
.base_addr
= strtol(*spp
, NULL
, 0);
634 if (ioctl(skfd
, SIOCSIFMAP
, &ifr
) < 0) {
635 fprintf(stderr
, "io_addr: SIOCSIFMAP: %s\n", strerror(errno
));
641 if (!strcmp(*spp
, "irq")) {
644 if (ioctl(skfd
, SIOCGIFMAP
, &ifr
) < 0) {
645 fprintf(stderr
, "irq: SIOCGIFMAP: %s\n", strerror(errno
));
650 ifr
.ifr_map
.irq
= atoi(*spp
);
651 if (ioctl(skfd
, SIOCSIFMAP
, &ifr
) < 0) {
652 fprintf(stderr
, "irq: SIOCSIFMAP: %s\n", strerror(errno
));
658 if (!strcmp(*spp
, "-pointopoint")) {
659 goterr
|= clr_flag(ifr
.ifr_name
, IFF_POINTOPOINT
);
661 if (test_flag(ifr
.ifr_name
, IFF_MULTICAST
) > 0)
662 fprintf(stderr
, _("Warning: Interface %s still in POINTOPOINT mode.\n"), ifr
.ifr_name
);
665 if (!strcmp(*spp
, "pointopoint")) {
666 if (*(spp
+ 1) != NULL
) {
668 safe_strncpy(host
, *spp
, (sizeof host
));
669 if (ap
->input(0, host
, &sa
)) {
673 fprintf(stderr
, _("ifconfig: Error resolving '%s' for pointopoint\n"), host
);
678 memcpy((char *) &ifr
.ifr_dstaddr
, (char *) &sa
,
679 sizeof(struct sockaddr
));
680 if (ioctl(ap
->fd
, SIOCSIFDSTADDR
, &ifr
) < 0) {
681 fprintf(stderr
, "SIOCSIFDSTADDR: %s\n",
686 goterr
|= set_flag(ifr
.ifr_name
, IFF_POINTOPOINT
);
691 if (!strcmp(*spp
, "hw")) {
694 if ((hw
= get_hwtype(*spp
)) == NULL
)
696 if (hw
->input
== NULL
) {
697 fprintf(stderr
, _("hw address type `%s' has no handler to set address. failed.\n"), *spp
);
704 safe_strncpy(host
, *spp
, (sizeof host
));
705 if (hw
->input(host
, &sa
) < 0) {
706 fprintf(stderr
, _("%s: invalid %s address.\n"), host
, hw
->name
);
711 memcpy((char *) &ifr
.ifr_hwaddr
, (char *) &sa
,
712 sizeof(struct sockaddr
));
713 if (ioctl(skfd
, SIOCSIFHWADDR
, &ifr
) < 0) {
715 fprintf(stderr
, "SIOCSIFHWADDR: %s - you may need to down the interface\n",
718 fprintf(stderr
, "SIOCSIFHWADDR: %s\n",
725 #if HAVE_AFINET || HAVE_AFINET6
726 if (!strcmp(*spp
, "add")) {
730 if (strchr(*spp
, ':')) {
732 if ((cp
= strchr(*spp
, '/'))) {
733 prefix_len
= atol(cp
+ 1);
734 if ((prefix_len
< 0) || (prefix_len
> 128))
740 safe_strncpy(host
, *spp
, (sizeof host
));
741 if (inet6_aftype
.input(1, host
,
742 (struct sockaddr
*) &sa6
) < 0) {
743 if (inet6_aftype
.herror
)
744 inet6_aftype
.herror(host
);
746 fprintf(stderr
, _("ifconfig: Error resolving '%s' for add\n"), host
);
751 memcpy((char *) &ifr6
.ifr6_addr
, (char *) &sa6
.sin6_addr
,
752 sizeof(struct in6_addr
));
754 fd
= get_socket_for_af(AF_INET6
);
757 _("No support for INET6 on this system.\n"));
762 if (ioctl(fd
, SIOGIFINDEX
, &ifr
) < 0) {
763 perror("SIOGIFINDEX");
768 ifr6
.ifr6_ifindex
= ifr
.ifr_ifindex
;
769 ifr6
.ifr6_prefixlen
= prefix_len
;
770 if (ioctl(fd
, SIOCSIFADDR
, &ifr6
) < 0) {
771 perror("SIOCSIFADDR");
779 { /* ipv4 address a.b.c.d */
780 unsigned long ip
, nm
, bc
;
781 safe_strncpy(host
, *spp
, (sizeof host
));
782 if (inet_aftype
.input(0, host
, (struct sockaddr
*)&sin
) < 0) {
788 fd
= get_socket_for_af(AF_INET
);
791 _("No support for INET on this system.\n"));
797 memcpy(&ip
, &sin
.sin_addr
.s_addr
, sizeof(unsigned long));
799 if (get_nmbc_parent(ifr
.ifr_name
, &nm
, &bc
) < 0) {
800 fprintf(stderr
, _("Interface %s not initialized\n"),
806 set_ifstate(ifr
.ifr_name
, ip
, nm
, bc
, 1);
812 fprintf(stderr
, _("Bad address.\n"));
817 #if HAVE_AFINET || HAVE_AFINET6
818 if (!strcmp(*spp
, "del")) {
824 if (strchr(*spp
, ':')) { /* INET6 */
825 if ((cp
= strchr(*spp
, '/'))) {
826 prefix_len
= atol(cp
+ 1);
827 if ((prefix_len
< 0) || (prefix_len
> 128))
833 safe_strncpy(host
, *spp
, (sizeof host
));
834 if (inet6_aftype
.input(1, host
,
835 (struct sockaddr
*) &sa6
) < 0) {
836 inet6_aftype
.herror(host
);
841 memcpy((char *) &ifr6
.ifr6_addr
, (char *) &sa6
.sin6_addr
,
842 sizeof(struct in6_addr
));
844 fd
= get_socket_for_af(AF_INET6
);
847 _("No support for INET6 on this system.\n"));
852 if (ioctl(fd
, SIOGIFINDEX
, &ifr
) < 0) {
853 perror("SIOGIFINDEX");
858 ifr6
.ifr6_ifindex
= ifr
.ifr_ifindex
;
859 ifr6
.ifr6_prefixlen
= prefix_len
;
861 fprintf(stderr
, "now deleting: ioctl(SIOCDIFADDR,{ifindex=%d,prefixlen=%ld})\n",ifr
.ifr_ifindex
,prefix_len
);
862 if (ioctl(fd
, SIOCDIFADDR
, &ifr6
) < 0) {
863 fprintf(stderr
, "SIOCDIFADDR: %s\n",
873 /* ipv4 address a.b.c.d */
874 unsigned long ip
, nm
, bc
;
875 safe_strncpy(host
, *spp
, (sizeof host
));
876 if (inet_aftype
.input(0, host
, (struct sockaddr
*)&sin
) < 0) {
882 fd
= get_socket_for_af(AF_INET
);
884 fprintf(stderr
, _("No support for INET on this system.\n"));
890 memcpy(&ip
, &sin
.sin_addr
.s_addr
, sizeof(unsigned long));
892 if (get_nmbc_parent(ifr
.ifr_name
, &nm
, &bc
) < 0) {
893 fprintf(stderr
, _("Interface %s not initialized\n"),
899 set_ifstate(ifr
.ifr_name
, ip
, nm
, bc
, 0);
904 fprintf(stderr
, _("Bad address.\n"));
907 fprintf(stderr
, _("Address deletion not supported on this system.\n"));
912 if (!strcmp(*spp
, "tunnel")) {
915 if ((cp
= strchr(*spp
, '/'))) {
916 prefix_len
= atol(cp
+ 1);
917 if ((prefix_len
< 0) || (prefix_len
> 128))
923 safe_strncpy(host
, *spp
, (sizeof host
));
924 if (inet6_aftype
.input(1, host
, (struct sockaddr
*) &sa6
) < 0) {
925 inet6_aftype
.herror(host
);
930 memcpy((char *) &ifr6
.ifr6_addr
, (char *) &sa6
.sin6_addr
,
931 sizeof(struct in6_addr
));
933 fd
= get_socket_for_af(AF_INET6
);
935 fprintf(stderr
, _("No support for INET6 on this system.\n"));
940 if (ioctl(fd
, SIOGIFINDEX
, &ifr
) < 0) {
941 perror("SIOGIFINDEX");
946 ifr6
.ifr6_ifindex
= ifr
.ifr_ifindex
;
947 ifr6
.ifr6_prefixlen
= prefix_len
;
949 if (ioctl(fd
, SIOCSIFDSTADDR
, &ifr6
) < 0) {
950 fprintf(stderr
, "SIOCSIFDSTADDR: %s\n",
959 /* If the next argument is a valid hostname, assume OK. */
960 safe_strncpy(host
, *spp
, (sizeof host
));
962 /* FIXME: sa is too small for INET6 addresses, inet6 should use that too,
963 broadcast is unexpected */
965 switch (ap
->getmask(host
, &samask
, NULL
)) {
973 // remeber to set the netmask from samask later
978 if (ap
->input
== NULL
) {
979 fprintf(stderr
, _("ifconfig: Cannot set address for this protocol family.\n"));
982 if (ap
->input(0, host
, &sa
) < 0) {
986 fprintf(stderr
,_("ifconfig: error resolving '%s' to set address for af=%s\n"), host
, ap
->name
); fprintf(stderr
,
987 _("ifconfig: `--help' gives usage information.\n")); exit(1);
989 memcpy((char *) &ifr
.ifr_addr
, (char *) &sa
, sizeof(struct sockaddr
));
991 int r
= 0; /* to shut gcc up */
995 fd
= get_socket_for_af(AF_INET
);
997 fprintf(stderr
, _("No support for INET on this system.\n"));
1000 r
= ioctl(fd
, SIOCSIFADDR
, &ifr
);
1005 fd
= get_socket_for_af(AF_ECONET
);
1007 fprintf(stderr
, _("No support for ECONET on this system.\n"));
1010 r
= ioctl(fd
, SIOCSIFADDR
, &ifr
);
1015 _("Don't know how to set addresses for family %d.\n"), ap
->af
);
1019 perror("SIOCSIFADDR");
1025 * Don't do the set_flag() if the address is an alias with a - at the
1026 * end, since it's deleted already! - Roman
1028 * Should really use regex.h here, not sure though how well it'll go
1029 * with the cross-platform support etc.
1033 short int found_colon
= 0;
1034 for (ptr
= ifr
.ifr_name
; *ptr
; ptr
++ )
1035 if (*ptr
== ':') found_colon
++;
1037 if (!(found_colon
&& *(ptr
- 1) == '-'))
1038 goterr
|= set_flag(ifr
.ifr_name
, (IFF_UP
| IFF_RUNNING
));
1045 goterr
|= set_netmask(skfd
, &ifr
, &samask
);
1049 if (opt_v
&& goterr
)
1050 fprintf(stderr
, _("WARNING: at least one error occured. (%d)\n"), goterr
);
1062 static unsigned char searcher
[256];
1064 static int set_ip_using(const char *name
, int c
, unsigned long ip
)
1067 struct sockaddr_in sin
;
1069 safe_strncpy(ifr
.ifr_name
, name
, IFNAMSIZ
);
1070 memset(&sin
, 0, sizeof(struct sockaddr
));
1071 sin
.sin_family
= AF_INET
;
1072 sin
.sin_addr
.s_addr
= ip
;
1073 memcpy(&ifr
.ifr_addr
, &sin
, sizeof(struct sockaddr
));
1074 if (ioctl(skfd
, c
, &ifr
) < 0)
1079 static int do_ifcmd(struct interface
*x
, struct ifcmd
*ptr
)
1082 struct sockaddr_in
*sin
;
1085 if (do_if_fetch(x
) < 0)
1087 if (strncmp(x
->name
, ptr
->base
, ptr
->baselen
) != 0)
1088 return 0; /* skip */
1089 z
= strchr(x
->name
, ':');
1093 for (e
= z
; *e
; e
++)
1094 if (*e
== '-') /* deleted */
1097 if (i
< 0 || i
> 255)
1102 sin
= (struct sockaddr_in
*)&x
->dstaddr
;
1103 if (sin
->sin_addr
.s_addr
!= ptr
->addr
) {
1109 if (set_flag(x
->name
, IFF_UP
| IFF_RUNNING
) == -1)
1113 if (clr_flag(x
->name
, IFF_UP
) == -1)
1117 return 1; /* all done! */
1121 static int get_nmbc_parent(char *parent
,
1122 unsigned long *nm
, unsigned long *bc
)
1124 struct interface
*i
;
1125 struct sockaddr_in
*sin
;
1127 i
= lookup_interface(parent
);
1130 if (do_if_fetch(i
) < 0)
1132 sin
= (struct sockaddr_in
*)&i
->netmask
;
1133 memcpy(nm
, &sin
->sin_addr
.s_addr
, sizeof(unsigned long));
1134 sin
= (struct sockaddr_in
*)&i
->broadaddr
;
1135 memcpy(bc
, &sin
->sin_addr
.s_addr
, sizeof(unsigned long));
1139 static int set_ifstate(char *parent
, unsigned long ip
,
1140 unsigned long nm
, unsigned long bc
,
1148 pt
.baselen
= strlen(parent
);
1151 memset(searcher
, 0, sizeof(searcher
));
1152 i
= for_all_interfaces((int (*)(struct interface
*,void *))do_ifcmd
,
1159 /* add a new interface */
1160 for (i
= 0; i
< 256; i
++)
1161 if (searcher
[i
] == 0)
1165 return -1; /* FAILURE!!! out of ip addresses */
1167 if (snprintf(buf
, IFNAMSIZ
, "%s:%d", parent
, i
) > IFNAMSIZ
)
1169 if (set_ip_using(buf
, SIOCSIFADDR
, ip
) == -1)
1171 if (set_ip_using(buf
, SIOCSIFNETMASK
, nm
) == -1)
1173 if (set_ip_using(buf
, SIOCSIFBRDADDR
, bc
) == -1)
1175 if (set_flag(buf
, IFF_BROADCAST
) == -1)