ifconfig 源码
来源:互联网 发布:云计算的行业应用 编辑:程序博客网 时间:2024/05/22 09:38
贴一下ifconfig的源码(它属于net-tool软件包),以备平时查看网络信息的配置。
/* * ifconfig This file contains an implementation of the command * that either displays or sets the characteristics of * one or more of the system's networking interfaces. * * Version: $Id: ifconfig.c,v 1.58 2008-10-02 23:31:04 ecki Exp $ * * Author: Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org> * and others. Copyright 1993 MicroWalt Corporation * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software * Foundation; either version 2 of the License, or (at * your option) any later version. * * Patched to support 'add' and 'del' keywords for INET(4) addresses * by Mrs. Brisby <mrs.brisby@nimh.org> * * {1.34} - 19980630 - Arnaldo Carvalho de Melo <acme@conectiva.com.br> * - gettext instead of catgets for i18n * 10/1998 - Andi Kleen. Use interface list primitives. * 20001008 - Bernd Eckenfels, Patch from RH for setting mtu *(default AF was wrong) * 20010404 - Arnaldo Carvalho de Melo, use setlocale */#define DFLT_AF "inet"#include "config.h"#include <features.h>#include <sys/types.h>#include <sys/socket.h>#include <sys/ioctl.h>#include <netinet/in.h>#include <net/if.h>#include <net/if_arp.h>#include <stdio.h>#include <errno.h>#include <fcntl.h>#include <ctype.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <netdb.h>/* Ugh. But libc5 doesn't provide POSIX types. */#include <asm/types.h>#ifdef HAVE_HWSLIP#include <linux/if_slip.h>#endif#if HAVE_AFINET6#ifndef _LINUX_IN6_H/* * This is in linux/include/net/ipv6.h. */struct in6_ifreq { struct in6_addr ifr6_addr; __u32 ifr6_prefixlen; unsigned int ifr6_ifindex;};#endif#endif/* HAVE_AFINET6 */#if HAVE_AFIPX#if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1)#include <netipx/ipx.h>#else#include "ipx.h"#endif#endif#include "net-support.h"#include "pathnames.h"#include "version.h"#include "../intl.h"#include "interface.h"#include "sockets.h"#include "util.h"char *Release = RELEASE, *Version = "ifconfig 1.42 (2001-04-13)";int opt_a = 0;/* show all interfaces */int opt_v = 0;/* debugging output flag */int addr_family = 0;/* currently selected AF *//* for ipv4 add/del modes */static int get_nmbc_parent(char *parent, unsigned long *nm, unsigned long *bc);static int set_ifstate(char *parent, unsigned long ip, unsigned long nm, unsigned long bc, int flag);static int if_print(char *ifname){ int res; if (ife_short)printf(_("Iface MTU Met RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg\n")); if (!ifname) {res = for_all_interfaces(do_if_print, &opt_a); } else {struct interface *ife;ife = lookup_interface(ifname);if (!ife) {return -1;}res = do_if_fetch(ife); if (res >= 0) ife_print(ife); } return res; }/* Set a certain interface flag. */static int set_flag(char *ifname, short flag){ struct ifreq ifr; safe_strncpy(ifr.ifr_name, ifname, IFNAMSIZ); if (ioctl(skfd, SIOCGIFFLAGS, &ifr) < 0) {fprintf(stderr, _("%s: ERROR while getting interface flags: %s\n"), ifname,strerror(errno));return (-1); } safe_strncpy(ifr.ifr_name, ifname, IFNAMSIZ); ifr.ifr_flags |= flag; if (ioctl(skfd, SIOCSIFFLAGS, &ifr) < 0) {perror("SIOCSIFFLAGS");return -1; } return (0);}/* Clear a certain interface flag. */static int clr_flag(char *ifname, short flag){ struct ifreq ifr; int fd; if (strchr(ifname, ':')) { /* This is a v4 alias interface. Downing it via a socket for another AF may have bad consequences. */ fd = get_socket_for_af(AF_INET);if (fd < 0) { fprintf(stderr, _("No support for INET on this system.\n")); return -1;} } else fd = skfd; safe_strncpy(ifr.ifr_name, ifname, IFNAMSIZ); if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) {fprintf(stderr, _("%s: ERROR while getting interface flags: %s\n"), ifname, strerror(errno));return -1; } safe_strncpy(ifr.ifr_name, ifname, IFNAMSIZ); ifr.ifr_flags &= ~flag; if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0) {perror("SIOCSIFFLAGS");return -1; } return (0);}/** test is a specified flag is set */static int test_flag(char *ifname, short flags){ struct ifreq ifr; int fd; if (strchr(ifname, ':')) { /* This is a v4 alias interface. Downing it via a socket for another AF may have bad consequences. */ fd = get_socket_for_af(AF_INET);if (fd < 0) { fprintf(stderr, _("No support for INET on this system.\n")); return -1;} } else fd = skfd; safe_strncpy(ifr.ifr_name, ifname, IFNAMSIZ); if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) {fprintf(stderr, _("%s: ERROR while testing interface flags: %s\n"), ifname, strerror(errno));return -1; } return (ifr.ifr_flags & flags);}static void usage(void){ fprintf(stderr, _("Usage:\n ifconfig [-a] [-v] [-s] <interface> [[<AF>] <address>]\n"));#if HAVE_AFINET fprintf(stderr, _(" [add <address>[/<prefixlen>]]\n")); fprintf(stderr, _(" [del <address>[/<prefixlen>]]\n")); fprintf(stderr, _(" [[-]broadcast [<address>]] [[-]pointopoint [<address>]]\n")); fprintf(stderr, _(" [netmask <address>] [dstaddr <address>] [tunnel <address>]\n"));#endif#ifdef SIOCSKEEPALIVE fprintf(stderr, _(" [outfill <NN>] [keepalive <NN>]\n"));#endif fprintf(stderr, _(" [hw <HW> <address>] [metric <NN>] [mtu <NN>]\n")); fprintf(stderr, _(" [[-]trailers] [[-]arp] [[-]allmulti]\n")); fprintf(stderr, _(" [multicast] [[-]promisc]\n")); fprintf(stderr, _(" [mem_start <NN>] [io_addr <NN>] [irq <NN>] [media <type>]\n"));#ifdef HAVE_TXQUEUELEN fprintf(stderr, _(" [txqueuelen <NN>]\n"));#endif#ifdef HAVE_DYNAMIC fprintf(stderr, _(" [[-]dynamic]\n"));#endif fprintf(stderr, _(" [up|down] ...\n\n")); fprintf(stderr, _(" <HW>=Hardware Type.\n")); fprintf(stderr, _(" List of possible hardware types:\n")); print_hwlist(0); /* 1 = ARPable */ fprintf(stderr, _(" <AF>=Address family. Default: %s\n"), DFLT_AF); fprintf(stderr, _(" List of possible address families:\n")); print_aflist(0); /* 1 = routeable */ exit(E_USAGE);}static void version(void){ fprintf(stderr, "%s\n%s\n", Release, Version); exit(E_USAGE);}static int set_netmask(int skfd, struct ifreq *ifr, struct sockaddr *sa){ int err = 0; memcpy((char *) &ifr->ifr_netmask, (char *) sa, sizeof(struct sockaddr)); if (ioctl(skfd, SIOCSIFNETMASK, ifr) < 0) {fprintf(stderr, "SIOCSIFNETMASK: %s\n",strerror(errno));err = 1; } return err;}int main(int argc, char **argv){ struct sockaddr sa; struct sockaddr samask; struct sockaddr_in sin; char host[128]; struct aftype *ap; struct hwtype *hw; struct ifreq ifr; int goterr = 0, didnetmask = 0, neednetmask=0; char **spp; int fd;#if HAVE_AFINET6 extern struct aftype inet6_aftype; struct sockaddr_in6 sa6; struct in6_ifreq ifr6; unsigned long prefix_len; char *cp;#endif#if HAVE_AFINET extern struct aftype inet_aftype;#endif#if I18N setlocale (LC_ALL, ""); bindtextdomain("net-tools", "/usr/share/locale"); textdomain("net-tools");#endif /* Find any options. */ argc--; argv++; while (argc && *argv[0] == '-') {if (!strcmp(*argv, "-a")) opt_a = 1;else if (!strcmp(*argv, "-s")) ife_short = 1;else if (!strcmp(*argv, "-v")) opt_v = 1;else if (!strcmp(*argv, "-V") || !strcmp(*argv, "-version") || !strcmp(*argv, "--version")) version();else if (!strcmp(*argv, "-?") || !strcmp(*argv, "-h") || !strcmp(*argv, "-help") || !strcmp(*argv, "--help")) usage();else { fprintf(stderr, _("ifconfig: option `%s' not recognised.\n"), argv[0]); fprintf(stderr, _("ifconfig: `--help' gives usage information.\n")); exit(1);}argv++;argc--; } /* Create a channel to the NET kernel. */ if ((skfd = sockets_open(0)) < 0) {perror("socket");exit(1); } /* Do we have to show the current setup? */ if (argc == 0) {int err = if_print((char *) NULL);(void) close(skfd);exit(err < 0); } /* No. Fetch the interface name. */ spp = argv; safe_strncpy(ifr.ifr_name, *spp++, IFNAMSIZ); if (*spp == (char *) NULL) {int err = if_print(ifr.ifr_name);(void) close(skfd);exit(err < 0); } /* The next argument is either an address family name, or an option. */ if ((ap = get_aftype(*spp)) != NULL)spp++; /* it was a AF name */ else ap = get_aftype(DFLT_AF); if (ap) {addr_family = ap->af;skfd = ap->fd; } /* Process the remaining arguments. */ while (*spp != (char *) NULL) {if (!strcmp(*spp, "arp")) { goterr |= clr_flag(ifr.ifr_name, IFF_NOARP); spp++; continue;}if (!strcmp(*spp, "-arp")) { goterr |= set_flag(ifr.ifr_name, IFF_NOARP); spp++; continue;}#ifdef IFF_PORTSELif (!strcmp(*spp, "media") || !strcmp(*spp, "port")) { if (*++spp == NULL)usage(); if (!strcasecmp(*spp, "auto")) {goterr |= set_flag(ifr.ifr_name, IFF_AUTOMEDIA); } else {int i, j, newport;char *endp;newport = strtol(*spp, &endp, 10);if (*endp != 0) { newport = -1; for (i = 0; if_port_text[i][0] && newport == -1; i++) {for (j = 0; if_port_text[i][j]; j++) { if (!strcasecmp(*spp, if_port_text[i][j])) {newport = i;break; }} }}spp++;if (newport == -1) { fprintf(stderr, _("Unknown media type.\n")); goterr = 1;} else { if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) {perror("port: SIOCGIFMAP"); goterr = 1;continue; } ifr.ifr_map.port = newport; if (ioctl(skfd, SIOCSIFMAP, &ifr) < 0) {perror("port: SIOCSIFMAP");goterr = 1; }} } continue;}#endifif (!strcmp(*spp, "trailers")) { goterr |= clr_flag(ifr.ifr_name, IFF_NOTRAILERS); spp++; continue;}if (!strcmp(*spp, "-trailers")) { goterr |= set_flag(ifr.ifr_name, IFF_NOTRAILERS); spp++; continue;}if (!strcmp(*spp, "promisc")) { goterr |= set_flag(ifr.ifr_name, IFF_PROMISC); spp++; continue;}if (!strcmp(*spp, "-promisc")) { goterr |= clr_flag(ifr.ifr_name, IFF_PROMISC); if (test_flag(ifr.ifr_name, IFF_PROMISC) > 0) fprintf(stderr, _("Warning: Interface %s still in promisc mode... maybe other application is running?\n"), ifr.ifr_name); spp++; continue;}if (!strcmp(*spp, "multicast")) { goterr |= set_flag(ifr.ifr_name, IFF_MULTICAST); spp++; continue;}if (!strcmp(*spp, "-multicast")) { goterr |= clr_flag(ifr.ifr_name, IFF_MULTICAST); if (test_flag(ifr.ifr_name, IFF_MULTICAST) > 0) fprintf(stderr, _("Warning: Interface %s still in MULTICAST mode.\n"), ifr.ifr_name); spp++; continue;}if (!strcmp(*spp, "allmulti")) { goterr |= set_flag(ifr.ifr_name, IFF_ALLMULTI); spp++; continue;}if (!strcmp(*spp, "-allmulti")) { goterr |= clr_flag(ifr.ifr_name, IFF_ALLMULTI); if (test_flag(ifr.ifr_name, IFF_MULTICAST) > 0) fprintf(stderr, _("Warning: Interface %s still in ALLMULTI mode.\n"), ifr.ifr_name); spp++; continue;}if (!strcmp(*spp, "up")) { goterr |= set_flag(ifr.ifr_name, (IFF_UP | IFF_RUNNING)); spp++; continue;}if (!strcmp(*spp, "down")) { goterr |= clr_flag(ifr.ifr_name, IFF_UP); spp++; continue;}#ifdef HAVE_DYNAMICif (!strcmp(*spp, "dynamic")) { goterr |= set_flag(ifr.ifr_name, IFF_DYNAMIC); spp++; continue;}if (!strcmp(*spp, "-dynamic")) { goterr |= clr_flag(ifr.ifr_name, IFF_DYNAMIC); spp++; if (test_flag(ifr.ifr_name, IFF_MULTICAST) > 0) fprintf(stderr, _("Warning: Interface %s still in DYNAMIC mode.\n"), ifr.ifr_name); continue;}#endifif (!strcmp(*spp, "metric")) { if (*++spp == NULL)usage(); ifr.ifr_metric = atoi(*spp); if (ioctl(skfd, SIOCSIFMETRIC, &ifr) < 0) {fprintf(stderr, "SIOCSIFMETRIC: %s\n", strerror(errno));goterr = 1; } spp++; continue;}if (!strcmp(*spp, "mtu")) { if (*++spp == NULL)usage(); ifr.ifr_mtu = atoi(*spp); if (ioctl(skfd, SIOCSIFMTU, &ifr) < 0) {fprintf(stderr, "SIOCSIFMTU: %s\n", strerror(errno));goterr = 1; } spp++; continue;}#ifdef SIOCSKEEPALIVEif (!strcmp(*spp, "keepalive")) { if (*++spp == NULL)usage(); ifr.ifr_data = (caddr_t) atoi(*spp); if (ioctl(skfd, SIOCSKEEPALIVE, &ifr) < 0) {fprintf(stderr, "SIOCSKEEPALIVE: %s\n", strerror(errno));goterr = 1; } spp++; continue;}#endif#ifdef SIOCSOUTFILLif (!strcmp(*spp, "outfill")) { if (*++spp == NULL)usage(); ifr.ifr_data = (caddr_t) atoi(*spp); if (ioctl(skfd, SIOCSOUTFILL, &ifr) < 0) {fprintf(stderr, "SIOCSOUTFILL: %s\n", strerror(errno));goterr = 1; } spp++; continue;}#endifif (!strcmp(*spp, "-broadcast")) { goterr |= clr_flag(ifr.ifr_name, IFF_BROADCAST); if (test_flag(ifr.ifr_name, IFF_MULTICAST) > 0) fprintf(stderr, _("Warning: Interface %s still in BROADCAST mode.\n"), ifr.ifr_name); spp++; continue;}if (!strcmp(*spp, "broadcast")) { if (*++spp != NULL) {safe_strncpy(host, *spp, (sizeof host));if (ap->input(0, host, &sa) < 0) { if (ap->herror) ap->herror(host); else fprintf(stderr, _("ifconfig: Error resolving '%s' for broadcast\n"), host); goterr = 1; spp++; continue;}memcpy((char *) &ifr.ifr_broadaddr, (char *) &sa, sizeof(struct sockaddr));if (ioctl(ap->fd, SIOCSIFBRDADDR, &ifr) < 0) { fprintf(stderr, "SIOCSIFBRDADDR: %s\n", strerror(errno)); goterr = 1;}spp++; } goterr |= set_flag(ifr.ifr_name, IFF_BROADCAST); continue;}if (!strcmp(*spp, "dstaddr")) { if (*++spp == NULL)usage(); safe_strncpy(host, *spp, (sizeof host)); if (ap->input(0, host, &sa) < 0) { if (ap->herror) ap->herror(host); else fprintf(stderr, _("ifconfig: Error resolving '%s' for dstaddr\n"), host);goterr = 1;spp++;continue; } memcpy((char *) &ifr.ifr_dstaddr, (char *) &sa, sizeof(struct sockaddr)); if (ioctl(ap->fd, SIOCSIFDSTADDR, &ifr) < 0) {fprintf(stderr, "SIOCSIFDSTADDR: %s\n",strerror(errno));goterr = 1; } spp++; continue;}if (!strcmp(*spp, "netmask")) { if (*++spp == NULL || didnetmask)usage(); safe_strncpy(host, *spp, (sizeof host)); if (ap->input(0, host, &sa) < 0) { if (ap->herror) ap->herror(host); else fprintf(stderr, _("ifconfig: Error resolving '%s' for netmask\n"), host);goterr = 1;spp++;continue; } didnetmask++; goterr |= set_netmask(ap->fd, &ifr, &sa); spp++; continue;}#ifdef HAVE_TXQUEUELENif (!strcmp(*spp, "txqueuelen")) { if (*++spp == NULL)usage(); ifr.ifr_qlen = strtoul(*spp, NULL, 0); if (ioctl(skfd, SIOCSIFTXQLEN, &ifr) < 0) {fprintf(stderr, "SIOCSIFTXQLEN: %s\n", strerror(errno));goterr = 1; } spp++; continue;}#endifif (!strcmp(*spp, "mem_start")) { if (*++spp == NULL)usage(); if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) {fprintf(stderr, "mem_start: SIOCGIFMAP: %s\n", strerror(errno)); spp++; goterr = 1;continue; } ifr.ifr_map.mem_start = strtoul(*spp, NULL, 0); if (ioctl(skfd, SIOCSIFMAP, &ifr) < 0) {fprintf(stderr, "mem_start: SIOCSIFMAP: %s\n", strerror(errno));goterr = 1; } spp++; continue;}if (!strcmp(*spp, "io_addr")) { if (*++spp == NULL)usage(); if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) {fprintf(stderr, "io_addr: SIOCGIFMAP: %s\n", strerror(errno)); spp++; goterr = 1;continue; } ifr.ifr_map.base_addr = strtol(*spp, NULL, 0); if (ioctl(skfd, SIOCSIFMAP, &ifr) < 0) {fprintf(stderr, "io_addr: SIOCSIFMAP: %s\n", strerror(errno));goterr = 1; } spp++; continue;}if (!strcmp(*spp, "irq")) { if (*++spp == NULL)usage(); if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) {fprintf(stderr, "irq: SIOCGIFMAP: %s\n", strerror(errno)); goterr = 1;spp++; continue; } ifr.ifr_map.irq = atoi(*spp); if (ioctl(skfd, SIOCSIFMAP, &ifr) < 0) {fprintf(stderr, "irq: SIOCSIFMAP: %s\n", strerror(errno));goterr = 1; } spp++; continue;}if (!strcmp(*spp, "-pointopoint")) { goterr |= clr_flag(ifr.ifr_name, IFF_POINTOPOINT); spp++; if (test_flag(ifr.ifr_name, IFF_MULTICAST) > 0) fprintf(stderr, _("Warning: Interface %s still in POINTOPOINT mode.\n"), ifr.ifr_name); continue;}if (!strcmp(*spp, "pointopoint")) { if (*(spp + 1) != NULL) {spp++;safe_strncpy(host, *spp, (sizeof host));if (ap->input(0, host, &sa)) { if (ap->herror) ap->herror(host); else fprintf(stderr, _("ifconfig: Error resolving '%s' for pointopoint\n"), host); goterr = 1; spp++; continue;}memcpy((char *) &ifr.ifr_dstaddr, (char *) &sa, sizeof(struct sockaddr));if (ioctl(ap->fd, SIOCSIFDSTADDR, &ifr) < 0) { fprintf(stderr, "SIOCSIFDSTADDR: %s\n", strerror(errno)); goterr = 1;} } goterr |= set_flag(ifr.ifr_name, IFF_POINTOPOINT); spp++; continue;};if (!strcmp(*spp, "hw")) { if (*++spp == NULL)usage(); if ((hw = get_hwtype(*spp)) == NULL)usage(); if (hw->input == NULL) { fprintf(stderr, _("hw address type `%s' has no handler to set address. failed.\n"), *spp); spp+=2; goterr = 1; continue; } if (*++spp == NULL)usage(); safe_strncpy(host, *spp, (sizeof host)); if (hw->input(host, &sa) < 0) {fprintf(stderr, _("%s: invalid %s address.\n"), host, hw->name);goterr = 1;spp++;continue; } memcpy((char *) &ifr.ifr_hwaddr, (char *) &sa, sizeof(struct sockaddr)); if (ioctl(skfd, SIOCSIFHWADDR, &ifr) < 0) {if (errno == EBUSY)fprintf(stderr, "SIOCSIFHWADDR: %s - you may need to down the interface\n",strerror(errno));elsefprintf(stderr, "SIOCSIFHWADDR: %s\n",strerror(errno));goterr = 1; } spp++; continue;}#if HAVE_AFINET || HAVE_AFINET6if (!strcmp(*spp, "add")) { if (*++spp == NULL)usage();#if HAVE_AFINET6 if (strchr(*spp, ':')) {/* INET6 */if ((cp = strchr(*spp, '/'))) { prefix_len = atol(cp + 1); if ((prefix_len < 0) || (prefix_len > 128))usage(); *cp = 0;} else { prefix_len = 128;}safe_strncpy(host, *spp, (sizeof host));if (inet6_aftype.input(1, host, (struct sockaddr *) &sa6) < 0) { if (inet6_aftype.herror) inet6_aftype.herror(host); else fprintf(stderr, _("ifconfig: Error resolving '%s' for add\n"), host); goterr = 1; spp++; continue;}memcpy((char *) &ifr6.ifr6_addr, (char *) &sa6.sin6_addr, sizeof(struct in6_addr));fd = get_socket_for_af(AF_INET6);if (fd < 0) { fprintf(stderr, _("No support for INET6 on this system.\n")); goterr = 1; spp++; continue;}if (ioctl(fd, SIOGIFINDEX, &ifr) < 0) { perror("SIOGIFINDEX"); goterr = 1; spp++; continue;}ifr6.ifr6_ifindex = ifr.ifr_ifindex;ifr6.ifr6_prefixlen = prefix_len;if (ioctl(fd, SIOCSIFADDR, &ifr6) < 0) { perror("SIOCSIFADDR"); goterr = 1;}spp++;continue; }#endif#ifdef HAVE_AFINET { /* ipv4 address a.b.c.d */unsigned long ip, nm, bc;safe_strncpy(host, *spp, (sizeof host));if (inet_aftype.input(0, host, (struct sockaddr *)&sin) < 0) { ap->herror(host); goterr = 1; spp++; continue;}fd = get_socket_for_af(AF_INET);if (fd < 0) { fprintf(stderr, _("No support for INET on this system.\n")); goterr = 1; spp++; continue;}memcpy(&ip, &sin.sin_addr.s_addr, sizeof(unsigned long));if (get_nmbc_parent(ifr.ifr_name, &nm, &bc) < 0) {fprintf(stderr, _("Interface %s not initialized\n"),ifr.ifr_name);goterr = 1;spp++;continue;}set_ifstate(ifr.ifr_name, ip, nm, bc, 1); } spp++; continue;#else fprintf(stderr, _("Bad address.\n"));#endif}#endif#if HAVE_AFINET || HAVE_AFINET6if (!strcmp(*spp, "del")) { if (*++spp == NULL)usage();#ifdef SIOCDIFADDR#if HAVE_AFINET6 if (strchr(*spp, ':')) {/* INET6 */if ((cp = strchr(*spp, '/'))) { prefix_len = atol(cp + 1); if ((prefix_len < 0) || (prefix_len > 128))usage(); *cp = 0;} else { prefix_len = 128;}safe_strncpy(host, *spp, (sizeof host));if (inet6_aftype.input(1, host, (struct sockaddr *) &sa6) < 0) { inet6_aftype.herror(host); goterr = 1; spp++; continue;}memcpy((char *) &ifr6.ifr6_addr, (char *) &sa6.sin6_addr, sizeof(struct in6_addr));fd = get_socket_for_af(AF_INET6);if (fd < 0) { fprintf(stderr, _("No support for INET6 on this system.\n")); goterr = 1; spp++; continue;}if (ioctl(fd, SIOGIFINDEX, &ifr) < 0) { perror("SIOGIFINDEX"); goterr = 1; spp++; continue;}ifr6.ifr6_ifindex = ifr.ifr_ifindex;ifr6.ifr6_prefixlen = prefix_len;if (opt_v)fprintf(stderr, "now deleting: ioctl(SIOCDIFADDR,{ifindex=%d,prefixlen=%ld})\n",ifr.ifr_ifindex,prefix_len);if (ioctl(fd, SIOCDIFADDR, &ifr6) < 0) { fprintf(stderr, "SIOCDIFADDR: %s\n", strerror(errno)); goterr = 1;}spp++;continue; }#endif#ifdef HAVE_AFINET {/* ipv4 address a.b.c.d */unsigned long ip, nm, bc;safe_strncpy(host, *spp, (sizeof host));if (inet_aftype.input(0, host, (struct sockaddr *)&sin) < 0) { ap->herror(host); goterr = 1; spp++; continue;}fd = get_socket_for_af(AF_INET);if (fd < 0) { fprintf(stderr, _("No support for INET on this system.\n")); goterr = 1; spp++; continue;}memcpy(&ip, &sin.sin_addr.s_addr, sizeof(unsigned long));if (get_nmbc_parent(ifr.ifr_name, &nm, &bc) < 0) { fprintf(stderr, _("Interface %s not initialized\n"), ifr.ifr_name); goterr = 1; spp++; continue;}set_ifstate(ifr.ifr_name, ip, nm, bc, 0); } spp++; continue;#else fprintf(stderr, _("Bad address.\n"));#endif#else fprintf(stderr, _("Address deletion not supported on this system.\n"));#endif}#endif#if HAVE_AFINET6if (!strcmp(*spp, "tunnel")) { if (*++spp == NULL)usage(); if ((cp = strchr(*spp, '/'))) {prefix_len = atol(cp + 1);if ((prefix_len < 0) || (prefix_len > 128)) usage();*cp = 0; } else {prefix_len = 128; } safe_strncpy(host, *spp, (sizeof host)); if (inet6_aftype.input(1, host, (struct sockaddr *) &sa6) < 0) {inet6_aftype.herror(host);goterr = 1;spp++;continue; } memcpy((char *) &ifr6.ifr6_addr, (char *) &sa6.sin6_addr, sizeof(struct in6_addr)); fd = get_socket_for_af(AF_INET6); if (fd < 0) {fprintf(stderr, _("No support for INET6 on this system.\n"));goterr = 1;spp++;continue; } if (ioctl(fd, SIOGIFINDEX, &ifr) < 0) {perror("SIOGIFINDEX");goterr = 1;spp++;continue; } ifr6.ifr6_ifindex = ifr.ifr_ifindex; ifr6.ifr6_prefixlen = prefix_len; if (ioctl(fd, SIOCSIFDSTADDR, &ifr6) < 0) {fprintf(stderr, "SIOCSIFDSTADDR: %s\n",strerror(errno));goterr = 1; } spp++; continue;}#endif/* If the next argument is a valid hostname, assume OK. */safe_strncpy(host, *spp, (sizeof host));/* FIXME: sa is too small for INET6 addresses, inet6 should use that too, broadcast is unexpected */if (ap->getmask) { switch (ap->getmask(host, &samask, NULL)) { case -1:usage();break; case 1:if (didnetmask) usage();// remeber to set the netmask from samask laterneednetmask = 1;break; }}if (ap->input == NULL) { fprintf(stderr, _("ifconfig: Cannot set address for this protocol family.\n")); exit(1);}if (ap->input(0, host, &sa) < 0) { if (ap->herror) ap->herror(host); else fprintf(stderr,_("ifconfig: error resolving '%s' to set address for af=%s\n"), host, ap->name); fprintf(stderr, _("ifconfig: `--help' gives usage information.\n")); exit(1);}memcpy((char *) &ifr.ifr_addr, (char *) &sa, sizeof(struct sockaddr));{ int r = 0;/* to shut gcc up */ switch (ap->af) {#if HAVE_AFINET case AF_INET:fd = get_socket_for_af(AF_INET);if (fd < 0) { fprintf(stderr, _("No support for INET on this system.\n")); exit(1);}r = ioctl(fd, SIOCSIFADDR, &ifr);break;#endif#if HAVE_AFECONET case AF_ECONET:fd = get_socket_for_af(AF_ECONET);if (fd < 0) { fprintf(stderr, _("No support for ECONET on this system.\n")); exit(1);}r = ioctl(fd, SIOCSIFADDR, &ifr);break;#endif default:fprintf(stderr,_("Don't know how to set addresses for family %d.\n"), ap->af);exit(1); } if (r < 0) {perror("SIOCSIFADDR");goterr = 1; }} /* * Don't do the set_flag() if the address is an alias with a - at the * end, since it's deleted already! - Roman * * Should really use regex.h here, not sure though how well it'll go * with the cross-platform support etc. */ { char *ptr; short int found_colon = 0; for (ptr = ifr.ifr_name; *ptr; ptr++ ) if (*ptr == ':') found_colon++; if (!(found_colon && *(ptr - 1) == '-')) goterr |= set_flag(ifr.ifr_name, (IFF_UP | IFF_RUNNING)); }spp++; } if (neednetmask) {goterr |= set_netmask(skfd, &ifr, &samask);didnetmask++; } if (opt_v && goterr) fprintf(stderr, _("WARNING: at least one error occured. (%d)\n"), goterr); return (goterr);}struct ifcmd { int flag; unsigned long addr; char *base; int baselen;};static unsigned char searcher[256];static int set_ip_using(const char *name, int c, unsigned long ip){ struct ifreq ifr; struct sockaddr_in sin; safe_strncpy(ifr.ifr_name, name, IFNAMSIZ); memset(&sin, 0, sizeof(struct sockaddr)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = ip; memcpy(&ifr.ifr_addr, &sin, sizeof(struct sockaddr)); if (ioctl(skfd, c, &ifr) < 0)return -1; return 0;}static int do_ifcmd(struct interface *x, struct ifcmd *ptr){ char *z, *e; struct sockaddr_in *sin; int i; if (do_if_fetch(x) < 0)return 0; if (strncmp(x->name, ptr->base, ptr->baselen) != 0)return 0; /* skip */ z = strchr(x->name, ':'); if (!z || !*z)return 0; z++; for (e = z; *e; e++)if (*e == '-') /* deleted */ return 0; i = atoi(z); if (i < 0 || i > 255)abort(); searcher[i] = 1; /* copy */ sin = (struct sockaddr_in *)&x->dstaddr; if (sin->sin_addr.s_addr != ptr->addr) {return 0; } if (ptr->flag) {/* turn UP */if (set_flag(x->name, IFF_UP | IFF_RUNNING) == -1) return -1; } else {/* turn DOWN */if (clr_flag(x->name, IFF_UP) == -1) return -1; } return 1; /* all done! */}static int get_nmbc_parent(char *parent, unsigned long *nm, unsigned long *bc){ struct interface *i; struct sockaddr_in *sin; i = lookup_interface(parent); if (!i)return -1; if (do_if_fetch(i) < 0)return 0; sin = (struct sockaddr_in *)&i->netmask; memcpy(nm, &sin->sin_addr.s_addr, sizeof(unsigned long)); sin = (struct sockaddr_in *)&i->broadaddr; memcpy(bc, &sin->sin_addr.s_addr, sizeof(unsigned long)); return 0;}static int set_ifstate(char *parent, unsigned long ip, unsigned long nm, unsigned long bc, int flag){ char buf[IFNAMSIZ]; struct ifcmd pt; int i; pt.base = parent; pt.baselen = strlen(parent); pt.addr = ip; pt.flag = flag; memset(searcher, 0, sizeof(searcher)); i = for_all_interfaces((int (*)(struct interface *,void *))do_ifcmd, &pt); if (i == -1)return -1; if (i == 1)return 0; /* add a new interface */ for (i = 0; i < 256; i++)if (searcher[i] == 0) break; if (i == 256)return -1; /* FAILURE!!! out of ip addresses */ if (snprintf(buf, IFNAMSIZ, "%s:%d", parent, i) > IFNAMSIZ)return -1; if (set_ip_using(buf, SIOCSIFADDR, ip) == -1)return -1; if (set_ip_using(buf, SIOCSIFNETMASK, nm) == -1)return -1; if (set_ip_using(buf, SIOCSIFBRDADDR, bc) == -1)return -1; if (set_flag(buf, IFF_BROADCAST) == -1)return -1; return 0;}
- ifconfig 源码
- ifconfig 源码分析
- ifconfig源码分析
- ifconfig源码-Linux
- ifconfig 源码, MAC地址分类
- ifconfig
- ifconfig
- ifconfig
- ifconfig
- ifconfig
- ifconfig
- ifconfig
- ifconfig
- ifconfig
- ifconfig
- ifconfig
- ifconfig
- ifconfig
- java中的UDP简单编程
- openware 7.0中文乱码问题
- eclipse下的打包插件fatjar
- sql server 2005 中的同义词
- iOS ARC详解
- ifconfig 源码
- DevExpress VCL 13.1触摸体验增强
- VC++ .NET 2003学习
- (转)禁止QQ直播、p2p软件的方法
- vs2010 drag class to classdiagram not working
- 单机同时提供VMWARE LIUNX+WIN2000的IP访问
- PHP 5.0 Pear安装方法
- (转)JDK 1.5中的ENUM用法
- 世界前五大IT咨询公司