⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 interface.c

📁 ifconfig源码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * 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$ * * 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) * stolen from net-tools-1.59 and stripped down for busybox by  *			Erik Andersen <andersee@debian.org> *//* * Heavily modified by Manuel Novoa III       Mar 12, 2001 * * Pruned unused code using KEEP_UNUSED define. * Added print_bytes_scaled function to reduce code size. * Added some (potentially) missing defines. * Improved display support for -a and for a named interface. *//* #define KEEP_UNUSED */#include "busybox.h"/*  *  * Protocol Families. *  */#define HAVE_AFINET 1#undef HAVE_AFINET6#undef HAVE_AFIPX#undef HAVE_AFATALK#undef HAVE_AFNETROM#undef HAVE_AFX25#undef HAVE_AFECONET/*  *  * Device Hardware types. *  */#define HAVE_HWETHER	1#define HAVE_HWPPP	1#undef HAVE_HWSLIP#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>#include <netinet/in.h>#include <arpa/inet.h>#include <arpa/nameser.h>#define _(x) x#define _PATH_PROCNET_DEV               "/proc/net/dev"#define new(p) ((p) = xcalloc(1,sizeof(*(p))))#define KRELEASE(maj,min,patch) ((maj) * 10000 + (min)*1000 + (patch))static int procnetdev_vsn = 1;/* 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/* Defines for glibc2.0 users. */#ifndef SIOCSIFTXQLEN#define SIOCSIFTXQLEN      0x8943#define SIOCGIFTXQLEN      0x8942#endif/* ifr_qlen is ifru_ivalue, but it isn't present in 2.0 kernel headers */#ifndef ifr_qlen#define ifr_qlen        ifr_ifru.ifru_mtu#endif#ifndef HAVE_TXQUEUELEN#define HAVE_TXQUEUELEN 1#endif#ifndef IFF_DYNAMIC#define IFF_DYNAMIC     0x8000  /* dialup device with changing addresses */#endif/* This structure defines protocol families and their handlers. */struct aftype {    const char *name;    const char *title;    int af;    int alen;    char *(*print) (unsigned char *);    char *(*sprint) (struct sockaddr *, int numeric);    int (*input) (int type, char *bufp, struct sockaddr *);    void (*herror) (char *text);    int (*rprint) (int options);    int (*rinput) (int typ, int ext, char **argv);    /* may modify src */    int (*getmask) (char *src, struct sockaddr * mask, char *name);    int fd;    char *flag_file;};static struct aftype *aftypes[];#ifdef KEEP_UNUSEDstatic int flag_unx;static int flag_ipx;static int flag_ax25;static int flag_ddp;static int flag_netrom;static int flag_inet;static int flag_inet6;static int flag_econet;static int flag_x25 = 0;static int flag_ash;static struct aftrans_t {    char *alias;    char *name;    int *flag;} aftrans[] = {    {	"ax25", "ax25", &flag_ax25    },    {	"ip", "inet", &flag_inet    },    {	"ip6", "inet6", &flag_inet6    },    {	"ipx", "ipx", &flag_ipx    },    {	"appletalk", "ddp", &flag_ddp    },    {	"netrom", "netrom", &flag_netrom    },    {	"inet", "inet", &flag_inet    },    {	"inet6", "inet6", &flag_inet6    },    {	"ddp", "ddp", &flag_ddp    },    {	"unix", "unix", &flag_unx    },    {	"tcpip", "inet", &flag_inet    },    {	"econet", "ec", &flag_econet    },    {	"x25", "x25", &flag_x25    },    {        "ash", "ash", &flag_ash    },    {	0, 0, 0    }};static char afname[256] = "";#endif /* KEEP_UNUSED */#if HAVE_AFUNIX/* Display a UNIX domain address. */static char *UNIX_print(unsigned char *ptr){    return (ptr);}/* Display a UNIX domain address. */static char *UNIX_sprint(struct sockaddr *sap, int numeric){    static char buf[64];    if (sap->sa_family == 0xFFFF || sap->sa_family == 0)	return safe_strncpy(buf, _("[NONE SET]"), sizeof(buf));    return (UNIX_print(sap->sa_data));}static struct aftype unix_aftype ={    "unix", "UNIX Domain", AF_UNIX, 0,    UNIX_print, UNIX_sprint, NULL, NULL,    NULL, NULL, NULL,    -1,    "/proc/net/unix"};#endif				/* HAVE_AFUNIX */#if HAVE_AFINET/* cache */struct addr {    struct sockaddr_in addr;    char *name;    int host;    struct addr *next;};static struct addr *INET_nn = NULL;	/* addr-to-name cache           */#ifdef KEEP_UNUSEDstatic int INET_resolve(char *name, struct sockaddr_in *sin, int hostfirst){    struct hostent *hp;    struct netent *np;    /* Grmpf. -FvK */    sin->sin_family = AF_INET;    sin->sin_port = 0;    /* Default is special, meaning 0.0.0.0. */    if (!strcmp(name, "default")) {	sin->sin_addr.s_addr = INADDR_ANY;	return (1);    }    /* Look to see if it's a dotted quad. */    if (inet_aton(name, &sin->sin_addr)) {	return 0;    }    /* If we expect this to be a hostname, try hostname database first */#ifdef DEBUG    if (hostfirst) fprintf (stderr, "gethostbyname (%s)\n", name);#endif    if (hostfirst && 	(hp = gethostbyname(name)) != (struct hostent *) NULL) {	memcpy((char *) &sin->sin_addr, (char *) hp->h_addr_list[0], 		sizeof(struct in_addr));	return 0;    }    /* Try the NETWORKS database to see if this is a known network. */#ifdef DEBUG    fprintf (stderr, "getnetbyname (%s)\n", name);#endif    if ((np = getnetbyname(name)) != (struct netent *) NULL) {	sin->sin_addr.s_addr = htonl(np->n_net);	return 1;    }    if (hostfirst) {	/* Don't try again */	errno = h_errno;	return -1;    }#ifdef DEBUG    res_init();    _res.options |= RES_DEBUG;#endif#ifdef DEBUG    fprintf (stderr, "gethostbyname (%s)\n", name);#endif    if ((hp = gethostbyname(name)) == (struct hostent *) NULL) {	errno = h_errno;	return -1;    }    memcpy((char *) &sin->sin_addr, (char *) hp->h_addr_list[0], 	   sizeof(struct in_addr));    return 0;}#endif /* KEEP_UNUSED *//* numeric: & 0x8000: default instead of *,  *	    & 0x4000: host instead of net,  *	    & 0x0fff: don't resolve */static int INET_rresolve(char *name, size_t len, struct sockaddr_in *sin, 			 int numeric, unsigned int netmask){    struct hostent *ent;    struct netent *np;    struct addr *pn;    unsigned long ad, host_ad;    int host = 0;    /* Grmpf. -FvK */    if (sin->sin_family != AF_INET) {#ifdef DEBUG	fprintf(stderr, _("rresolve: unsupport address family %d !\n"), sin->sin_family);#endif	errno = EAFNOSUPPORT;	return (-1);    }    ad = (unsigned long) sin->sin_addr.s_addr;#ifdef DEBUG    fprintf (stderr, "rresolve: %08lx, mask %08x, num %08x \n", ad, netmask, numeric);#endif    if (ad == INADDR_ANY) {	if ((numeric & 0x0FFF) == 0) {	    if (numeric & 0x8000)		safe_strncpy(name, "default", len);	    else	        safe_strncpy(name, "*", len);	    return (0);	}    }    if (numeric & 0x0FFF) {        safe_strncpy(name, inet_ntoa(sin->sin_addr), len);	return (0);    }    if ((ad & (~netmask)) != 0 || (numeric & 0x4000))	host = 1;    pn = INET_nn;    while (pn != NULL) {	if (pn->addr.sin_addr.s_addr == ad && pn->host == host) {	    safe_strncpy(name, pn->name, len);#ifdef DEBUG	    fprintf (stderr, "rresolve: found %s %08lx in cache\n", (host? "host": "net"), ad);#endif	    return (0);	}	pn = pn->next;    }    host_ad = ntohl(ad);    np = NULL;    ent = NULL;    if (host) {#ifdef DEBUG	fprintf (stderr, "gethostbyaddr (%08lx)\n", ad);#endif	ent = gethostbyaddr((char *) &ad, 4, AF_INET);	if (ent != NULL)	    safe_strncpy(name, ent->h_name, len);    } else {#ifdef DEBUG	fprintf (stderr, "getnetbyaddr (%08lx)\n", host_ad);#endif	np = getnetbyaddr(host_ad, AF_INET);	if (np != NULL)	    safe_strncpy(name, np->n_name, len);    }    if ((ent == NULL) && (np == NULL))	safe_strncpy(name, inet_ntoa(sin->sin_addr), len);    pn = (struct addr *) xmalloc(sizeof(struct addr));    pn->addr = *sin;    pn->next = INET_nn;    pn->host = host;    pn->name = (char *) xmalloc(strlen(name) + 1);    strcpy(pn->name, name);    INET_nn = pn;    return (0);}#ifdef KEEP_UNUSEDstatic void INET_reserror(char *text){    herror(text);}/* Display an Internet socket address. */static char *INET_print(unsigned char *ptr){    return (inet_ntoa((*(struct in_addr *) ptr)));}#endif /* KEEP_UNUSED *//* Display an Internet socket address. */static char *INET_sprint(struct sockaddr *sap, int numeric){    static char buff[128];    if (sap->sa_family == 0xFFFF || sap->sa_family == 0)	return safe_strncpy(buff, _("[NONE SET]"), sizeof(buff));    if (INET_rresolve(buff, sizeof(buff), (struct sockaddr_in *) sap, 		      numeric, 0xffffff00) != 0)	return (NULL);    return (buff);}#ifdef KEEP_UNUSEDstatic char *INET_sprintmask(struct sockaddr *sap, int numeric, 		      unsigned int netmask){    static char buff[128];    if (sap->sa_family == 0xFFFF || sap->sa_family == 0)	return safe_strncpy(buff, _("[NONE SET]"), sizeof(buff));    if (INET_rresolve(buff, sizeof(buff), (struct sockaddr_in *) sap, 		      numeric, netmask) != 0)	return (NULL);    return (buff);}static int INET_getsock(char *bufp, struct sockaddr *sap){    char *sp = bufp, *bp;    unsigned int i;    unsigned val;    struct sockaddr_in *sin;    sin = (struct sockaddr_in *) sap;    sin->sin_family = AF_INET;    sin->sin_port = 0;    val = 0;    bp = (char *) &val;    for (i = 0; i < sizeof(sin->sin_addr.s_addr); i++) {	*sp = toupper(*sp);	if ((*sp >= 'A') && (*sp <= 'F'))	    bp[i] |= (int) (*sp - 'A') + 10;	else if ((*sp >= '0') && (*sp <= '9'))	    bp[i] |= (int) (*sp - '0');	else	    return (-1);	bp[i] <<= 4;	sp++;	*sp = toupper(*sp);	if ((*sp >= 'A') && (*sp <= 'F'))	    bp[i] |= (int) (*sp - 'A') + 10;	else if ((*sp >= '0') && (*sp <= '9'))	    bp[i] |= (int) (*sp - '0');	else	    return (-1);	sp++;    }    sin->sin_addr.s_addr = htonl(val);    return (sp - bufp);}static int INET_input(int type, char *bufp, struct sockaddr *sap){    switch (type) {    case 1:	return (INET_getsock(bufp, sap));    case 256:	return (INET_resolve(bufp, (struct sockaddr_in *) sap, 1));    default:	return (INET_resolve(bufp, (struct sockaddr_in *) sap, 0));    }}static int INET_getnetmask(char *adr, struct sockaddr *m, char *name){    struct sockaddr_in *mask = (struct sockaddr_in *) m;    char *slash, *end;    int prefix;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -