贴一下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_PORTSEL
if (!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;
}
#endif if (!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_DYNAMIC
if (!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;
}
#endif if (!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 SIOCSKEEPALIVE
if (!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 SIOCSOUTFILL
if (!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;
}
#endif if (!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_TXQUEUELEN
if (!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;
}
#endif if (!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));
else
fprintf(stderr, "SIOCSIFHWADDR: %s\n",
strerror(errno));
goterr = 1;
}
spp++;
continue;
}
#if HAVE_AFINET || HAVE_AFINET6
if (!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_AFINET6
if (!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_AFINET6
if (!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 later
neednetmask = 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 源码的更多相关文章

  1. ifconfig源码分析之与内核交互数据

    <ifconfig源码分析之与内核交互数据>本文档的Copyleft归rosetta所有,使用GPL发布,可以自由拷贝.转载,转载时请保持文档的完整性.参考资料:<Linux设备驱动 ...

  2. 【转】Docker网络详解及pipework源码解读与实践

    好文必转 原文地址: http://www.infoq.com/cn/articles/docker-network-and-pipework-open-source-explanation-prac ...

  3. Cenos(6.6/7.1)下从源码安装Python+Django+uwsgi+nginx到写nginx的环境部署(一)

    梳理下这几个的关系: centos是redhat的社区版操作系统. Python2.7.5是开发语言(centos6.5下自带的python是2.6.6版本,所以需要源码更新,而centos7.1下面 ...

  4. LAMP最新源码一键安装脚本

    Linux+Apache+MySQL+PHP (脚本可以选择是否安装+Pureftpd+User manager for PureFTPd+phpMyAdmin+memcache),添加虚拟主机请执行 ...

  5. MySQL 5.6.26源码安装

    5.6.26源码安装包:http://pan.baidu.com/s/1kUl44WRcmake安装包链接:http://pan.baidu.com/s/1c0LuwJA 操作系统版本:CentOS ...

  6. Java文件操作源码大全

    Java文件操作源码大全 1.创建文件夹 52.创建文件 53.删除文件 54.删除文件夹 65.删除一个文件下夹所有的文件夹 76.清空文件夹 87.读取文件 88.写入文件 99.写入随机文件 9 ...

  7. CentOS 6.4源码编译安装httpd并启动测试

    今天来总结一下在Linux中软件安装,通常我们应该知道,安装软件有两种方法:一种是软件包的安装,也就是rpm包的安装,就是指这些软件包都是 已经编译好的二进制rpm包,我们通过rpm安装工具和yum安 ...

  8. Android源码浅析(六)——SecureCRT远程连接Linux,配置端点和字节码

    Android源码浅析(六)--SecureCRT远程连接Linux,配置端点和字节码 需要编译源码的同学,一般都是win+虚拟机吧,但是再虚拟机里体验并不是很好,所有市面上有很多的软件能够做到在wi ...

  9. Android源码浅析(三)——Android AOSP 5.1.1源码的同步sync和编译make,搭建Samba服务器进行更便捷的烧录刷机

    Android源码浅析(三)--Android AOSP 5.1.1源码的同步sync和编译make,搭建Samba服务器进行更便捷的烧录刷机 最近比较忙,而且又要维护自己的博客,视频和公众号,也就没 ...

随机推荐

  1. 一步一步重写 CodeIgniter 框架 (2) —— 实现简单的路由功能

    在上一课中,我们实现了简单的根据 URI 执行某个类的某个方法.但是这种映射没有扩展性,对于一个成熟易用的框架肯定是行不通的.那么,我们可以让 框架的用户 通过自定义这种转换来控制,用 CI 的术语就 ...

  2. Fragment保持状态切换,fragment状态切换

    在使用Activity管理多个Fragment时,每次切换Fragment使用的是replace,结果导致出现xxx is not currently in the FragmentManager异常 ...

  3. 数据交换工具Kettle

    网上搜集了一些关于开源数据交换工具Kattle的文章,特收藏例如以下: 文章一:ETL和Kettle简单介绍 ETL即数据抽取(Extract).转换(Transform).装载(Load)的过程.它 ...

  4. Bee Framework_百度百科

    Bee Framework_百度百科 Bee Framework 编辑   目录 1详细信息 简介 特性 2工作 主要模块 编译要求 运行要求 目录结构 运行例程 安装步骤     1详细信息 简介 ...

  5. TIA Portal V12不能添加新的CPU

    4核AMD 740,10G内存,Win7 X64,打开TIA Portal V12,依旧慢如牛,鼠标指针转啊转,TIA窗口写着 无响应... 真没志气,STM32要是玩转了,坚决不用这老牛. 上图为正 ...

  6. Use GraceNote SDK in iOS(二)获取音乐的完整信息

    在需求彻底明朗化,外加从MusicFans转到GraceNote,再从GraceNote的GNSDK转到iOS SDK后,最终完毕了在iOS上通过音乐的部分信息获取完整信息的功能了.(好吧,我承认是相 ...

  7. 配置rhel 6.4(64位)安装使用syslog-ng 3.5

    我基本的博客地址是:www.cppblog.com/zdhsoft 相应的CentOS 6.x也就可能使用. 下载地址: 第一步:安装 wget http://www.balabit.com/down ...

  8. 基于visual Studio2013解决面试题之0807strstr函数

     题目

  9. jqueryui datepicker refresh

    http://stackoverflow.com/questions/6056287/jquery-ui-datepicker-prevent-refresh-onselect 给选中的TD加背景色

  10. 5.单行函数,多行函数,字符函数,数字函数,日期函数,数据类型转换,数字和字符串转换,通用函数(case和decode)

     1  多行函数(理解:有多个输入,但仅仅输出1个结果) SQL>select count(*) from emp; COUNT(*) ------------- 14 B 字符函数Lowe ...