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.44 2001/02/12 21:06:47 pb 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)
27 #define DFLT_AF "inet"
32 #include <sys/types.h>
33 #include <sys/socket.h>
34 #include <sys/ioctl.h>
35 #include <netinet/in.h>
37 #include <net/if_arp.h>
47 /* Ugh. But libc5 doesn't provide POSIX types. */
48 #include <asm/types.h>
52 #include <linux/if_slip.h>
59 * This is in linux/include/net/ipv6.h.
63 struct in6_addr ifr6_addr
;
65 unsigned int ifr6_ifindex
;
70 #endif /* HAVE_AFINET6 */
73 #if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1)
74 #include <netipx/ipx.h>
79 #include "net-support.h"
80 #include "pathnames.h"
83 #include "interface.h"
87 char *Release
= RELEASE
, *Version
= "ifconfig 1.40 (2000-05-21)";
89 int opt_a
= 0; /* show all interfaces */
90 int opt_i
= 0; /* show the statistics */
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
,
97 unsigned long *nm
, unsigned long *bc
);
98 static int set_ifstate(char *parent
,
105 static int if_print(char *ifname
)
110 printf(_("Iface MTU Met RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg\n"));
113 res
= for_all_interfaces(do_if_print
, &opt_a
);
115 struct interface
*ife
;
117 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 strcpy(ifr
.ifr_name
, ifname
);
131 if (ioctl(skfd
, SIOCGIFFLAGS
, &ifr
) < 0) {
132 fprintf(stderr
, _("%s: unknown interface: %s\n"),
133 ifname
, strerror(errno
));
136 strcpy(ifr
.ifr_name
, ifname
);
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 strcpy(ifr
.ifr_name
, ifname
);
163 if (ioctl(fd
, SIOCGIFFLAGS
, &ifr
) < 0) {
164 fprintf(stderr
, _("%s: unknown interface: %s\n"),
165 ifname
, strerror(errno
));
168 strcpy(ifr
.ifr_name
, ifname
);
169 ifr
.ifr_flags
&= ~flag
;
170 if (ioctl(fd
, SIOCSIFFLAGS
, &ifr
) < 0) {
171 perror("SIOCSIFFLAGS");
177 static void usage(void)
179 fprintf(stderr
, _("Usage:\n ifconfig [-a] [-i] [-v] [-s] <interface> [[<AF>] <address>]\n"));
181 fprintf(stderr
, _(" [add <address>[/<prefixlen>]]\n"));
182 fprintf(stderr
, _(" [del <address>[/<prefixlen>]]\n"));
183 fprintf(stderr
, _(" [[-]broadcast [<address>]] [[-]pointopoint [<address>]]\n"));
184 fprintf(stderr
, _(" [netmask <address>] [dstaddr <address>] [tunnel <address>]\n"));
186 #ifdef SIOCSKEEPALIVE
187 fprintf(stderr
, _(" [outfill <NN>] [keepalive <NN>]\n"));
189 fprintf(stderr
, _(" [hw <HW> <address>] [metric <NN>] [mtu <NN>]\n"));
190 fprintf(stderr
, _(" [[-]trailers] [[-]arp] [[-]allmulti]\n"));
191 fprintf(stderr
, _(" [multicast] [[-]promisc]\n"));
192 fprintf(stderr
, _(" [mem_start <NN>] [io_addr <NN>] [irq <NN>] [media <type>]\n"));
193 #ifdef HAVE_TXQUEUELEN
194 fprintf(stderr
, _(" [txqueuelen <NN>]\n"));
197 fprintf(stderr
, _(" [[-]dynamic]\n"));
199 fprintf(stderr
, _(" [up|down] ...\n\n"));
201 fprintf(stderr
, _(" <HW>=Hardware Type.\n"));
202 fprintf(stderr
, _(" List of possible hardware types:\n"));
203 print_hwlist(0); /* 1 = ARPable */
204 fprintf(stderr
, _(" <AF>=Address family. Default: %s\n"), DFLT_AF
);
205 fprintf(stderr
, _(" List of possible address families:\n"));
206 print_aflist(0); /* 1 = routeable */
210 static void version(void)
212 fprintf(stderr
, "%s\n%s\n", Release
, Version
);
216 static int set_netmask(int skfd
, struct ifreq
*ifr
, struct sockaddr
*sa
)
220 memcpy((char *) &ifr
->ifr_netmask
, (char *) sa
,
221 sizeof(struct sockaddr
));
222 if (ioctl(skfd
, SIOCSIFNETMASK
, ifr
) < 0) {
223 fprintf(stderr
, "SIOCSIFNETMASK: %s\n",
230 int main(int argc
, char **argv
)
233 struct sockaddr_in sin
;
238 int goterr
= 0, didnetmask
= 0;
242 extern struct aftype inet6_aftype
;
243 struct sockaddr_in6 sa6
;
244 struct in6_ifreq ifr6
;
245 unsigned long prefix_len
;
249 extern struct aftype inet_aftype
;
253 bindtextdomain("net-tools", "/usr/share/locale");
254 textdomain("net-tools");
258 /* Find any options. */
261 while (argc
&& *argv
[0] == '-') {
262 if (!strcmp(*argv
, "-a"))
265 else if (!strcmp(*argv
, "-s"))
268 else if (!strcmp(*argv
, "-v"))
271 else if (!strcmp(*argv
, "-V") || !strcmp(*argv
, "-version") ||
272 !strcmp(*argv
, "--version"))
275 else if (!strcmp(*argv
, "-?") || !strcmp(*argv
, "-h") ||
276 !strcmp(*argv
, "-help") || !strcmp(*argv
, "--help"))
280 fprintf(stderr
, "ifconfig: unknown option %s\n", argv
[0]);
281 fprintf(stderr
, "(Use --help for usage information.\n)");
289 /* Create a channel to the NET kernel. */
290 if ((skfd
= sockets_open(0)) < 0) {
295 /* Do we have to show the current setup? */
297 int err
= if_print((char *) NULL
);
301 /* No. Fetch the interface name. */
303 safe_strncpy(ifr
.ifr_name
, *spp
++, IFNAMSIZ
);
304 if (*spp
== (char *) NULL
) {
305 int err
= if_print(ifr
.ifr_name
);
309 /* The next argument is either an address family name, or an option. */
310 if ((ap
= get_aftype(*spp
)) != NULL
)
311 spp
++; /* it was a AF name */
313 ap
= get_aftype(DFLT_AF
);
316 addr_family
= ap
->af
;
317 if ((fd
=sockets_open(addr_family
)) < 0) {
318 perror("family socket");
321 if (skfd
> 0 && skfd
!= fd
) close(skfd
);
326 /* Process the remaining arguments. */
327 while (*spp
!= (char *) NULL
) {
328 if (!strcmp(*spp
, "arp")) {
329 goterr
|= clr_flag(ifr
.ifr_name
, IFF_NOARP
);
333 if (!strcmp(*spp
, "-arp")) {
334 goterr
|= set_flag(ifr
.ifr_name
, IFF_NOARP
);
339 if (!strcmp(*spp
, "media") || !strcmp(*spp
, "port")) {
342 if (!strcasecmp(*spp
, "auto")) {
343 goterr
|= set_flag(ifr
.ifr_name
, IFF_AUTOMEDIA
);
347 newport
= strtol(*spp
, &endp
, 10);
350 for (i
= 0; if_port_text
[i
][0] && newport
== -1; i
++) {
351 for (j
= 0; if_port_text
[i
][j
]; j
++) {
352 if (!strcasecmp(*spp
, if_port_text
[i
][j
])) {
361 fprintf(stderr
, _("Unknown media type.\n"));
364 if (ioctl(skfd
, SIOCGIFMAP
, &ifr
) < 0) {
365 perror("port: SIOCGIFMAP");
369 ifr
.ifr_map
.port
= newport
;
370 if (ioctl(skfd
, SIOCSIFMAP
, &ifr
) < 0) {
371 perror("port: SIOCSIFMAP");
380 if (!strcmp(*spp
, "trailers")) {
381 goterr
|= clr_flag(ifr
.ifr_name
, IFF_NOTRAILERS
);
385 if (!strcmp(*spp
, "-trailers")) {
386 goterr
|= set_flag(ifr
.ifr_name
, IFF_NOTRAILERS
);
390 if (!strcmp(*spp
, "promisc")) {
391 goterr
|= set_flag(ifr
.ifr_name
, IFF_PROMISC
);
395 if (!strcmp(*spp
, "-promisc")) {
396 goterr
|= clr_flag(ifr
.ifr_name
, IFF_PROMISC
);
400 if (!strcmp(*spp
, "multicast")) {
401 goterr
|= set_flag(ifr
.ifr_name
, IFF_MULTICAST
);
405 if (!strcmp(*spp
, "-multicast")) {
406 goterr
|= clr_flag(ifr
.ifr_name
, IFF_MULTICAST
);
410 if (!strcmp(*spp
, "allmulti")) {
411 goterr
|= set_flag(ifr
.ifr_name
, IFF_ALLMULTI
);
415 if (!strcmp(*spp
, "-allmulti")) {
416 goterr
|= clr_flag(ifr
.ifr_name
, IFF_ALLMULTI
);
420 if (!strcmp(*spp
, "up")) {
421 goterr
|= set_flag(ifr
.ifr_name
, (IFF_UP
| IFF_RUNNING
));
425 if (!strcmp(*spp
, "down")) {
426 goterr
|= clr_flag(ifr
.ifr_name
, IFF_UP
);
431 if (!strcmp(*spp
, "dynamic")) {
432 goterr
|= set_flag(ifr
.ifr_name
, IFF_DYNAMIC
);
436 if (!strcmp(*spp
, "-dynamic")) {
437 goterr
|= clr_flag(ifr
.ifr_name
, IFF_DYNAMIC
);
443 if (!strcmp(*spp
, "metric")) {
446 ifr
.ifr_metric
= atoi(*spp
);
447 if (ioctl(skfd
, SIOCSIFMETRIC
, &ifr
) < 0) {
448 fprintf(stderr
, "SIOCSIFMETRIC: %s\n", strerror(errno
));
454 if (!strcmp(*spp
, "mtu")) {
457 ifr
.ifr_mtu
= atoi(*spp
);
458 if (ioctl(skfd
, SIOCSIFMTU
, &ifr
) < 0) {
459 fprintf(stderr
, "SIOCSIFMTU: %s\n", strerror(errno
));
465 #ifdef SIOCSKEEPALIVE
466 if (!strcmp(*spp
, "keepalive")) {
469 ifr
.ifr_data
= (caddr_t
) atoi(*spp
);
470 if (ioctl(skfd
, SIOCSKEEPALIVE
, &ifr
) < 0) {
471 fprintf(stderr
, "SIOCSKEEPALIVE: %s\n", strerror(errno
));
480 if (!strcmp(*spp
, "outfill")) {
483 ifr
.ifr_data
= (caddr_t
) atoi(*spp
);
484 if (ioctl(skfd
, SIOCSOUTFILL
, &ifr
) < 0) {
485 fprintf(stderr
, "SIOCSOUTFILL: %s\n", strerror(errno
));
493 if (!strcmp(*spp
, "-broadcast")) {
494 goterr
|= clr_flag(ifr
.ifr_name
, IFF_BROADCAST
);
498 if (!strcmp(*spp
, "broadcast")) {
499 if (*++spp
!= NULL
) {
500 safe_strncpy(host
, *spp
, (sizeof host
));
501 if (ap
->input(0, host
, &sa
) < 0) {
507 memcpy((char *) &ifr
.ifr_broadaddr
, (char *) &sa
,
508 sizeof(struct sockaddr
));
509 if (ioctl(ap
->fd
, SIOCSIFBRDADDR
, &ifr
) < 0) {
510 fprintf(stderr
, "SIOCSIFBRDADDR: %s\n",
516 goterr
|= set_flag(ifr
.ifr_name
, IFF_BROADCAST
);
519 if (!strcmp(*spp
, "dstaddr")) {
522 safe_strncpy(host
, *spp
, (sizeof host
));
523 if (ap
->input(0, host
, &sa
) < 0) {
529 memcpy((char *) &ifr
.ifr_dstaddr
, (char *) &sa
,
530 sizeof(struct sockaddr
));
531 if (ioctl(ap
->fd
, SIOCSIFDSTADDR
, &ifr
) < 0) {
532 fprintf(stderr
, "SIOCSIFDSTADDR: %s\n",
539 if (!strcmp(*spp
, "netmask")) {
540 if (*++spp
== NULL
|| didnetmask
)
542 safe_strncpy(host
, *spp
, (sizeof host
));
543 if (ap
->input(0, host
, &sa
) < 0) {
550 goterr
= set_netmask(ap
->fd
, &ifr
, &sa
);
554 #ifdef HAVE_TXQUEUELEN
555 if (!strcmp(*spp
, "txqueuelen")) {
558 ifr
.ifr_qlen
= strtoul(*spp
, NULL
, 0);
559 if (ioctl(skfd
, SIOCSIFTXQLEN
, &ifr
) < 0) {
560 fprintf(stderr
, "SIOCSIFTXQLEN: %s\n", strerror(errno
));
568 if (!strcmp(*spp
, "mem_start")) {
571 if (ioctl(skfd
, SIOCGIFMAP
, &ifr
) < 0) {
572 fprintf(stderr
, "mem_start: SIOCGIFMAP: %s\n", strerror(errno
));
577 ifr
.ifr_map
.mem_start
= strtoul(*spp
, NULL
, 0);
578 if (ioctl(skfd
, SIOCSIFMAP
, &ifr
) < 0) {
579 fprintf(stderr
, "mem_start: SIOCSIFMAP: %s\n", strerror(errno
));
585 if (!strcmp(*spp
, "io_addr")) {
588 if (ioctl(skfd
, SIOCGIFMAP
, &ifr
) < 0) {
589 fprintf(stderr
, "io_addr: SIOCGIFMAP: %s\n", strerror(errno
));
594 ifr
.ifr_map
.base_addr
= strtol(*spp
, NULL
, 0);
595 if (ioctl(skfd
, SIOCSIFMAP
, &ifr
) < 0) {
596 fprintf(stderr
, "io_addr: SIOCSIFMAP: %s\n", strerror(errno
));
602 if (!strcmp(*spp
, "irq")) {
605 if (ioctl(skfd
, SIOCGIFMAP
, &ifr
) < 0) {
606 fprintf(stderr
, "irq: SIOCGIFMAP: %s\n", strerror(errno
));
611 ifr
.ifr_map
.irq
= atoi(*spp
);
612 if (ioctl(skfd
, SIOCSIFMAP
, &ifr
) < 0) {
613 fprintf(stderr
, "irq: SIOCSIFMAP: %s\n", strerror(errno
));
619 if (!strcmp(*spp
, "-pointopoint")) {
620 goterr
|= clr_flag(ifr
.ifr_name
, IFF_POINTOPOINT
);
624 if (!strcmp(*spp
, "pointopoint")) {
625 if (*(spp
+ 1) != NULL
) {
627 safe_strncpy(host
, *spp
, (sizeof host
));
628 if (ap
->input(0, host
, &sa
)) {
634 memcpy((char *) &ifr
.ifr_dstaddr
, (char *) &sa
,
635 sizeof(struct sockaddr
));
636 if (ioctl(ap
->fd
, SIOCSIFDSTADDR
, &ifr
) < 0) {
637 fprintf(stderr
, "SIOCSIFDSTADDR: %s\n",
642 goterr
|= set_flag(ifr
.ifr_name
, IFF_POINTOPOINT
);
647 if (!strcmp(*spp
, "hw")) {
650 if ((hw
= get_hwtype(*spp
)) == NULL
)
652 if (hw
->input
== NULL
) {
653 fprintf(stderr
, _("hw address type `%s' has no handler to set address. failed.\n"), *spp
);
660 safe_strncpy(host
, *spp
, (sizeof host
));
661 if (hw
->input(host
, &sa
) < 0) {
662 fprintf(stderr
, _("%s: invalid %s address.\n"), host
, hw
->name
);
667 memcpy((char *) &ifr
.ifr_hwaddr
, (char *) &sa
,
668 sizeof(struct sockaddr
));
669 if (ioctl(skfd
, SIOCSIFHWADDR
, &ifr
) < 0) {
670 fprintf(stderr
, "SIOCSIFHWADDR: %s\n",
677 #if HAVE_AFINET || HAVE_AFINET6
678 if (!strcmp(*spp
, "add")) {
682 if (strchr(*spp
, ':')) {
684 if ((cp
= strchr(*spp
, '/'))) {
685 prefix_len
= atol(cp
+ 1);
686 if ((prefix_len
< 0) || (prefix_len
> 128))
692 safe_strncpy(host
, *spp
, (sizeof host
));
693 if (inet6_aftype
.input(1, host
,
694 (struct sockaddr
*) &sa6
) < 0) {
695 inet6_aftype
.herror(host
);
700 memcpy((char *) &ifr6
.ifr6_addr
, (char *) &sa6
.sin6_addr
,
701 sizeof(struct in6_addr
));
703 fd
= get_socket_for_af(AF_INET6
);
706 _("No support for INET6 on this system.\n"));
711 if (ioctl(fd
, SIOGIFINDEX
, &ifr
) < 0) {
712 perror("SIOGIFINDEX");
717 ifr6
.ifr6_ifindex
= ifr
.ifr_ifindex
;
718 ifr6
.ifr6_prefixlen
= prefix_len
;
719 if (ioctl(fd
, SIOCSIFADDR
, &ifr6
) < 0) {
720 perror("SIOCSIFADDR");
728 { /* ipv4 address a.b.c.d */
729 unsigned long ip
, nm
, bc
;
730 safe_strncpy(host
, *spp
, (sizeof host
));
731 if (inet_aftype
.input(0, host
, (struct sockaddr
*)&sin
) < 0) {
737 fd
= get_socket_for_af(AF_INET
);
740 _("No support for INET on this system.\n"));
746 memcpy(&ip
, &sin
.sin_addr
.s_addr
, sizeof(unsigned long));
748 if (get_nmbc_parent(ifr
.ifr_name
, &nm
, &bc
) < 0) {
749 fprintf(stderr
, _("Interface %s not initialized\n"),
755 set_ifstate(ifr
.ifr_name
, ip
, nm
, bc
, 1);
761 fprintf(stderr
, _("Bad address.\n"));
766 #if HAVE_AFINET || HAVE_AFINET6
767 if (!strcmp(*spp
, "del")) {
773 if (strchr(*spp
, ':')) { /* INET6 */
774 if ((cp
= strchr(*spp
, '/'))) {
775 prefix_len
= atol(cp
+ 1);
776 if ((prefix_len
< 0) || (prefix_len
> 128))
782 safe_strncpy(host
, *spp
, (sizeof host
));
783 if (inet6_aftype
.input(1, host
,
784 (struct sockaddr
*) &sa6
) < 0) {
785 inet6_aftype
.herror(host
);
790 memcpy((char *) &ifr6
.ifr6_addr
, (char *) &sa6
.sin6_addr
,
791 sizeof(struct in6_addr
));
793 fd
= get_socket_for_af(AF_INET6
);
796 _("No support for INET6 on this system.\n"));
801 if (ioctl(fd
, SIOGIFINDEX
, &ifr
) < 0) {
802 perror("SIOGIFINDEX");
807 ifr6
.ifr6_ifindex
= ifr
.ifr_ifindex
;
808 ifr6
.ifr6_prefixlen
= prefix_len
;
809 if (ioctl(fd
, SIOCDIFADDR
, &ifr6
) < 0) {
810 fprintf(stderr
, "SIOCDIFADDR: %s\n",
820 /* ipv4 address a.b.c.d */
821 unsigned long ip
, nm
, bc
;
822 safe_strncpy(host
, *spp
, (sizeof host
));
823 if (inet_aftype
.input(0, host
, (struct sockaddr
*)&sin
) < 0) {
829 fd
= get_socket_for_af(AF_INET
);
831 fprintf(stderr
, _("No support for INET on this system.\n"));
837 memcpy(&ip
, &sin
.sin_addr
.s_addr
, sizeof(unsigned long));
839 if (get_nmbc_parent(ifr
.ifr_name
, &nm
, &bc
) < 0) {
840 fprintf(stderr
, _("Interface %s not initialized\n"),
846 set_ifstate(ifr
.ifr_name
, ip
, nm
, bc
, 0);
851 fprintf(stderr
, _("Bad address.\n"));
854 fprintf(stderr
, _("Address deletion not supported on this system.\n"));
859 if (!strcmp(*spp
, "tunnel")) {
862 if ((cp
= strchr(*spp
, '/'))) {
863 prefix_len
= atol(cp
+ 1);
864 if ((prefix_len
< 0) || (prefix_len
> 128))
870 safe_strncpy(host
, *spp
, (sizeof host
));
871 if (inet6_aftype
.input(1, host
, (struct sockaddr
*) &sa6
) < 0) {
872 inet6_aftype
.herror(host
);
877 memcpy((char *) &ifr6
.ifr6_addr
, (char *) &sa6
.sin6_addr
,
878 sizeof(struct in6_addr
));
880 fd
= get_socket_for_af(AF_INET6
);
882 fprintf(stderr
, _("No support for INET6 on this system.\n"));
887 if (ioctl(fd
, SIOGIFINDEX
, &ifr
) < 0) {
888 perror("SIOGIFINDEX");
893 ifr6
.ifr6_ifindex
= ifr
.ifr_ifindex
;
894 ifr6
.ifr6_prefixlen
= prefix_len
;
896 if (ioctl(fd
, SIOCSIFDSTADDR
, &ifr6
) < 0) {
897 fprintf(stderr
, "SIOCSIFDSTADDR: %s\n",
906 /* If the next argument is a valid hostname, assume OK. */
907 safe_strncpy(host
, *spp
, (sizeof host
));
909 /* FIXME: sa is too small for INET6 addresses, inet6 should use that too,
910 broadcast is unexpected */
912 switch (ap
->getmask(host
, &sa
, NULL
)) {
920 goterr
= set_netmask(skfd
, &ifr
, &sa
);
925 if (ap
->input(0, host
, &sa
) < 0) {
929 memcpy((char *) &ifr
.ifr_addr
, (char *) &sa
, sizeof(struct sockaddr
));
931 int r
= 0; /* to shut gcc up */
935 fd
= get_socket_for_af(AF_INET
);
937 fprintf(stderr
, _("No support for INET on this system.\n"));
940 r
= ioctl(fd
, SIOCSIFADDR
, &ifr
);
945 fd
= get_socket_for_af(AF_ECONET
);
947 fprintf(stderr
, _("No support for ECONET on this system.\n"));
950 r
= ioctl(fd
, SIOCSIFADDR
, &ifr
);
955 _("Don't know how to set addresses for family %d.\n"), ap
->af
);
959 perror("SIOCSIFADDR");
964 * Don't do the set_flag() if the address is an alias with a - at the
965 * end, since it's deleted already! - Roman
967 * Should really use regex.h here, not sure though how well it'll go
968 * with the cross-platform support etc.
972 short int found_colon
= 0;
973 for (ptr
= ifr
.ifr_name
; *ptr
; ptr
++ )
974 if (*ptr
== ':') found_colon
++;
976 if (!(found_colon
&& *(ptr
- 1) == '-'))
977 goterr
|= set_flag(ifr
.ifr_name
, (IFF_UP
| IFF_RUNNING
));
991 static unsigned char searcher
[256];
993 static int set_ip_using(const char *name
, int c
, unsigned long ip
)
996 struct sockaddr_in sin
;
998 strcpy(ifr
.ifr_name
, name
);
999 memset(&sin
, 0, sizeof(struct sockaddr
));
1000 sin
.sin_family
= AF_INET
;
1001 sin
.sin_addr
.s_addr
= ip
;
1002 memcpy(&ifr
.ifr_addr
, &sin
, sizeof(struct sockaddr
));
1003 if (ioctl(skfd
, c
, &ifr
) < 0)
1007 static int do_ifcmd(struct interface
*x
, struct ifcmd
*ptr
)
1010 struct sockaddr_in
*sin
;
1013 if (do_if_fetch(x
) < 0)
1015 if (strncmp(x
->name
, ptr
->base
, ptr
->baselen
) != 0)
1016 return 0; /* skip */
1017 z
= strchr(x
->name
, ':');
1021 for (e
= z
; *e
; e
++)
1022 if (*e
== '-') /* deleted */
1028 sin
= (struct sockaddr_in
*)&x
->dstaddr
;
1029 if (sin
->sin_addr
.s_addr
!= ptr
->addr
) {
1035 if (set_flag(x
->name
, IFF_UP
| IFF_RUNNING
) == -1)
1039 if (clr_flag(x
->name
, IFF_UP
) == -1)
1043 return 1; /* all done! */
1047 static int get_nmbc_parent(char *parent
,
1048 unsigned long *nm
, unsigned long *bc
)
1050 struct interface
*i
;
1051 struct sockaddr_in
*sin
;
1053 i
= lookup_interface(parent
);
1056 if (do_if_fetch(i
) < 0)
1058 sin
= (struct sockaddr_in
*)&i
->netmask
;
1059 memcpy(nm
, &sin
->sin_addr
.s_addr
, sizeof(unsigned long));
1060 sin
= (struct sockaddr_in
*)&i
->broadaddr
;
1061 memcpy(bc
, &sin
->sin_addr
.s_addr
, sizeof(unsigned long));
1065 static int set_ifstate(char *parent
, unsigned long ip
,
1066 unsigned long nm
, unsigned long bc
,
1074 pt
.baselen
= strlen(parent
);
1077 memset(searcher
, 0, sizeof(searcher
));
1078 i
= for_all_interfaces((int (*)(struct interface
*,void *))do_ifcmd
,
1085 /* add a new interface */
1086 for (i
= 0; i
< 256; i
++)
1087 if (searcher
[i
] == 0)
1090 return -1; /* FAILURE!!! out of ip addresses */
1092 sprintf(buf
, "%s:%d", parent
, i
);
1093 if (set_ip_using(buf
, SIOCSIFADDR
, ip
) == -1)
1095 if (set_ip_using(buf
, SIOCSIFNETMASK
, nm
) == -1)
1097 if (set_ip_using(buf
, SIOCSIFBRDADDR
, bc
) == -1)
1099 if (set_flag(buf
, IFF_BROADCAST
) == -1)