📄 interface.c
字号:
/* * 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. * * ----------------------------------------------------------- * * 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: interface.c,v 1.8 2002/07/03 11:46:36 andersen 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) *//* #define KEEP_UNUSED *//* * * Protocol Families. * */#define HAVE_AFINET 1#undef HAVE_AFINET6#undef HAVE_AFIPX#undef HAVE_AFATALK#undef HAVE_AFNETROM#undef HAVE_AFX25#undef HAVE_AFECONET#undef HAVE_AFASH#if CONFIG_FEATURE_IPV6#define HAVE_AFINET6 1#endif/* * * Device Hardware types. * */#define HAVE_HWETHER 1#define HAVE_HWPPP 1#undef HAVE_HWSLIP#include "inet_common.h"#include <stdio.h>#include <errno.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <fcntl.h>#include <ctype.h>#include <sys/ioctl.h>#include <net/if.h>#include <net/if_arp.h>#include "libbb.h"#define _(x) x#define _PATH_PROCNET_DEV "/proc/net/dev"#define _PATH_PROCNET_IFINET6 "/proc/net/if_inet6"#define new(p) ((p) = xcalloc(1,sizeof(*(p))))#define KRELEASE(maj,min,patch) ((maj) * 65536 + (min)*256 + (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_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;#ifdef HAVE_AFIPXstatic int flag_ipx;#endif#ifdef HAVE_AFX25static int flag_ax25;#endif#ifdef HAVE_AFATALKstatic int flag_ddp;#endif#ifdef HAVE_AFNETROMstatic int flag_netrom;#endifstatic int flag_inet;#ifdef HAVE_AFINET6static int flag_inet6;#endif#ifdef HAVE_AFECONETstatic int flag_econet;#endif#ifdef HAVE_AFX25static int flag_x25 = 0;#endif#ifdef HAVE_AFASHstatic int flag_ash;#endifstatic struct aftrans_t { char *alias; char *name; int *flag;} aftrans[] = {#ifdef HAVE_AFX25 { "ax25", "ax25", &flag_ax25 },#endif { "ip", "inet", &flag_inet },#ifdef HAVE_AFINET6 { "ip6", "inet6", &flag_inet6 },#endif#ifdef HAVE_AFIPX { "ipx", "ipx", &flag_ipx },#endif#ifdef HAVE_AFATALK { "appletalk", "ddp", &flag_ddp },#endif#ifdef HAVE_AFNETROM { "netrom", "netrom", &flag_netrom },#endif { "inet", "inet", &flag_inet },#ifdef HAVE_AFINET6 { "inet6", "inet6", &flag_inet6 },#endif#ifdef HAVE_AFATALK { "ddp", "ddp", &flag_ddp },#endif { "unix", "unix", &flag_unx }, { "tcpip", "inet", &flag_inet },#ifdef HAVE_AFECONET { "econet", "ec", &flag_econet },#endif#ifdef HAVE_AFX25 { "x25", "x25", &flag_x25 },#endif#ifdef HAVE_AFASH { "ash", "ash", &flag_ash },#endif { 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#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; if ((slash = strchr(adr, '/')) == NULL) return 0; *slash++ = '\0'; prefix = strtoul(slash, &end, 0); if (*end != '\0') return -1; if (name) { sprintf(name, "/%d", prefix); } mask->sin_family = AF_INET; mask->sin_addr.s_addr = htonl(~(0xffffffffU >> prefix)); return 1;}#endif /* KEEP_UNUSED */static struct aftype inet_aftype ={ "inet", "DARPA Internet", AF_INET, sizeof(unsigned long), NULL /* UNUSED INET_print */, INET_sprint, NULL /* UNUSED INET_input */, NULL /* UNUSED INET_reserror */, NULL /*INET_rprint */ , NULL /*INET_rinput */ , NULL /* UNUSED INET_getnetmask */, -1, NULL};#endif /* HAVE_AFINET */#if HAVE_AFINET6#ifdef KEEP_UNUSEDstatic void INET6_reserror(char *text){ herror(text);}/* Display an Internet socket address. */static char *INET6_print(unsigned char *ptr){ static char name[80]; inet_ntop(AF_INET6, (struct in6_addr *) ptr, name, 80); return name;}#endif /* KEEP_UNUSED *//* Display an Internet socket address. *//* dirty! struct sockaddr usually doesn't suffer for inet6 addresses, fst. */static char *INET6_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 (INET6_rresolve(buff, sizeof(buff), (struct sockaddr_in6 *) sap, numeric) != 0) return safe_strncpy(buff, _("[UNKNOWN]"), sizeof(buff)); return (buff);}#ifdef KEEP_UNUSEDstatic int INET6_getsock(char *bufp, struct sockaddr *sap){ struct sockaddr_in6 *sin6; sin6 = (struct sockaddr_in6 *) sap; sin6->sin6_family = AF_INET6; sin6->sin6_port = 0; if (inet_pton(AF_INET6, bufp, sin6->sin6_addr.s6_addr) <= 0) return (-1); return 16; /* ?;) */}static int INET6_input(int type, char *bufp, struct sockaddr *sap){ switch (type) { case 1: return (INET6_getsock(bufp, sap)); default: return (INET6_resolve(bufp, (struct sockaddr_in6 *) sap)); }}#endif /* KEEP_UNUSED */static struct aftype inet6_aftype ={ "inet6", "IPv6", AF_INET6, sizeof(struct in6_addr), NULL /* UNUSED INET6_print */, INET6_sprint, NULL /* UNUSED INET6_input */, NULL /* UNUSED INET6_reserror */, NULL /*INET6_rprint */ , NULL /*INET6_rinput */ , NULL /* UNUSED INET6_getnetmask */, -1, NULL};#endif /* HAVE_AFINET6 *//* Display an UNSPEC address. */static char *UNSPEC_print(unsigned char *ptr){ static char buff[sizeof(struct sockaddr)*3+1]; char *pos; unsigned int i; pos = buff; for (i = 0; i < sizeof(struct sockaddr); i++) { /* careful -- not every libc's sprintf returns # bytes written */ sprintf(pos, "%02X-", (*ptr++ & 0377)); pos += 3; } /* Erase trailing "-". Works as long as sizeof(struct sockaddr) != 0 */ *--pos = '\0'; return (buff);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -