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

📄 gifconfig.c

📁 支持IPv4和IPv6的网卡管理程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/*	$KAME: gifconfig.c,v 1.19 2001/11/13 12:38:45 jinmei Exp $	*//* * Copyright (c) 1983, 1993 *	The Regents of the University of California.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. *//* * gifconfig, derived from ifconfig * * @(#) Copyright (c) 1983, 1993\n\ *	The Regents of the University of California.  All rights reserved.\n * * @(#)ifconfig.c	8.2 (Berkeley) 2/16/94 *//* *  951109 - Andrew@pubnix.net - Changed to iterative buffer growing mechanism *				 for ifconfig -a so all interfaces are queried. * *  960101 - peter@freebsd.org - Blow away the SIOCGIFCONF code and use *				 sysctl() to get the structured interface conf *				 and parse the messages in there. REALLY UGLY! */#include <sys/param.h>#include <sys/socket.h>#include <sys/ioctl.h>#include <sys/sysctl.h>#include <net/if.h>#if defined(__FreeBSD__) && __FreeBSD__ >= 3#include <net/if_var.h>#endif /* __FreeBSD__ >= 3 */#include <net/if_dl.h>#include <net/if_types.h>#include <net/route.h>#include <netinet/in.h>#include <netinet/in_var.h>#include <arpa/inet.h>#include <netdb.h>#include <sys/protosw.h>#include <ctype.h>#include <err.h>#include <errno.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <nlist.h>#include <kvm.h>#include <fcntl.h>struct	ifreq		ifr;struct	ifaliasreq	addreq;#ifdef INET6struct	in6_ifreq	in6_ifr;struct	in6_aliasreq	in6_addreq;#endifchar	name[32];int	flags;int	metric;int	mtu;int	setpsrc = 0;int	newaddr = 0;int	s;kvm_t	*kvmd;void setifpsrc __P((char *, int));void setifpdst __P((char *, int));void setifflags __P((char *, int));#ifdef SIOCDIFPHYADDRvoid delifaddrs __P((char *, int));#endif#define	NEXTARG		0xffffffstatic struct	cmd {	char	*c_name;	int	c_parameter;		/* NEXTARG means next argv */	void	(*c_func) __P((char *, int));} cmds[] = {	{ "up",		IFF_UP,		setifflags } ,	{ "down",	-IFF_UP,	setifflags },#ifdef SIOCDIFPHYADDR	{ "delete",	0,		delifaddrs },#endif	{ 0,		0,		setifpsrc },	{ 0,		0,		setifpdst },};/* * XNS support liberally adapted from code written at the University of * Maryland principally by James O'Toole and Chris Torek. */int main __P((int, char *[]));void status __P((void));void phys_status __P((int));void in_status __P((int));#ifdef INET6void in6_status __P((int));#endifvoid ether_status __P((int));void Perror __P((char *));void in_getaddr __P((char *, int));#ifdef INET6void in6_getaddr __P((char *, int));void in6_getprefix __P((char *, int));#endifvoid printb __P((char *, unsigned int, char *));int prefix __P((void *, int));/* Known address families */struct afswtch {	char *af_name;	short af_af;	void (*af_status) __P((int));	void (*af_getaddr) __P((char *, int));	void (*af_getprefix) __P((char *, int));	u_long af_pifaddr;	caddr_t af_addreq;	caddr_t af_req;} afs[] = {#define C(x) ((caddr_t) &x)	{ "inet", AF_INET, in_status, in_getaddr, 0,	     SIOCSIFPHYADDR, C(addreq), C(ifr) },#ifdef INET6	{ "inet6", AF_INET6, in6_status, in6_getaddr, in6_getprefix,	     SIOCSIFPHYADDR_IN6, C(in6_addreq), C(in6_ifr) },#endif	{ "ether", AF_INET, ether_status, NULL, NULL },	/* XXX not real!! */	{ 0,	0,	    0,		0,	0 }};struct afswtch *afp = NULL;	/*the address family being set or asked about*/void	rt_xaddrs __P((caddr_t, caddr_t, struct rt_addrinfo *));int	ifconfig __P((int argc, char *argv[], int af, struct afswtch *rafp));/* * Expand the compacted form of addresses as returned via the * configuration read via sysctl(). */#define ROUNDUP(a) \	((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))voidrt_xaddrs(cp, cplim, rtinfo)	caddr_t cp, cplim;	struct rt_addrinfo *rtinfo;{	struct sockaddr *sa;	int i;	memset(rtinfo->rti_info, 0, sizeof(rtinfo->rti_info));	for (i = 0; (i < RTAX_MAX) && (cp < cplim); i++) {		if ((rtinfo->rti_addrs & (1 << i)) == 0)			continue;		rtinfo->rti_info[i] = sa = (struct sockaddr *)cp;		ADVANCE(cp, sa);	}}/* * Grunge for new-style sysctl() decoding.. :-( * Apologies to the world for committing gross things like this in 1996.. */struct if_msghdr *ifm;struct ifa_msghdr *ifam;struct sockaddr_dl *sdl;struct rt_addrinfo info;char *buf, *lim, *next;intmain(argc, argv)	int argc;	char *argv[];{	int af = AF_INET;	struct afswtch *rafp = NULL;	size_t needed;	int mib[6];	int all;	if (argc < 2) {		fprintf(stderr,		    "usage: gifconfig interface [af] [physsrc physdst]\n");#ifdef SIOCDIFPHYADDR		fprintf(stderr,		    "       gifconfig interface delete\n");#endif		fprintf(stderr,		    "       gifconfig -a\n");		exit(1);	}	argc--, argv++;	strncpy(name, *argv, sizeof(name));	strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));	argc--, argv++;	if (argc > 0) {		for (afp = rafp = afs; rafp->af_name; rafp++)			if (strcmp(rafp->af_name, *argv) == 0) {				afp = rafp; argc--; argv++;				break;			}		rafp = afp;		af = ifr.ifr_addr.sa_family = rafp->af_af;	}	mib[0] = CTL_NET;	mib[1] = PF_ROUTE;	mib[2] = 0;	mib[3] = 0;	/* address family */	mib[4] = NET_RT_IFLIST;	mib[5] = 0;	/* if particular family specified, only ask about it */	if (afp) {		mib[3] = afp->af_af;	}	if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)		errx(1, "iflist-sysctl-estimate");	if ((buf = malloc(needed)) == NULL)		errx(1, "malloc");	if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0)		errx(1, "actual retrieval of interface table");	lim = buf + needed;	all = 0;	if (strcmp(name, "-a") == 0)		all = 1;	/* All interfaces */	else if (strcmp(name, "-au") == 0)		all = 2;	/* All IFF_UPinterfaces */	else if (strcmp(name, "-ad") == 0)		all = 3;	/* All !IFF_UP interfaces */	for (next = buf; next < lim; next += ifm->ifm_msglen) {		ifm = (struct if_msghdr *)next;		/* XXX: Swallow up leftover NEWADDR messages */		if (ifm->ifm_type == RTM_NEWADDR)			continue;		if (ifm->ifm_type == RTM_IFINFO) {			sdl = (struct sockaddr_dl *)(ifm + 1);			flags = ifm->ifm_flags;		} else {			errx(1, "out of sync parsing NET_RT_IFLIST");		}		switch(all) {		case -1:		case 0:			if (strlen(name) != sdl->sdl_nlen)				continue; /* not same len */			if (strncmp(name, sdl->sdl_data, sdl->sdl_nlen) != 0)				continue; /* not same name */			break;		case 1:			break;	/* always do it */		case 2:			if ((flags & IFF_UP) == 0)				continue; /* not up */			break;		case 3:			if (flags & IFF_UP)				continue; /* not down */			break;		}		/*		 * Let's just do it for gif only		 */		if (sdl->sdl_type != IFT_GIF) {			if (all != 0)				continue;			fprintf(stderr, "gifconfig: %s is not gif.\n",				ifr.ifr_name);			exit(1);		}		if (all > 0) {			strncpy(name, sdl->sdl_data, sdl->sdl_nlen);			name[sdl->sdl_nlen] = '\0';		}		if ((s = socket(af, SOCK_DGRAM, 0)) < 0) {			perror("gifconfig: socket");			exit(1);		}		ifconfig(argc,argv,af,rafp);		close(s);		if (all == 0) {			all = -1; /* flag it as 'done' */			break;		}	}	free(buf);	if (all == 0)		errx(1, "interface %s does not exist", name);		exit (0);}intifconfig(argc, argv, af, rafp)	int argc;	char *argv[];	int af;	struct afswtch *rafp;{	af = 0;		/*fool gcc*/	strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);#ifdef INET6	strncpy(in6_ifr.ifr_name, name, sizeof in6_ifr.ifr_name);#endif /* INET6 */	if (ioctl(s, SIOCGIFMETRIC, (caddr_t)&ifr) < 0)		perror("ioctl (SIOCGIFMETRIC)");	else		metric = ifr.ifr_metric;#if defined(SIOCGIFMTU) && !defined(__OpenBSD__)	if (ioctl(s, SIOCGIFMTU, (caddr_t)&ifr) < 0)		perror("ioctl (SIOCGIFMTU)");	else		mtu = ifr.ifr_mtu;#else	mtu = 0;#endif	if (argc == 0) {		status();		return(0);	}	while (argc > 0) {		register struct cmd *p;		for (p = cmds; p->c_name; p++)			if (strcmp(*argv, p->c_name) == 0)				break;		if (p->c_name == 0 && setpsrc)			p++;	/* got src, do dst */		if (p->c_func) {			if (p->c_parameter == NEXTARG) {				if (argv[1] == NULL)					errx(1, "'%s' requires argument",					    p->c_name);				(*p->c_func)(argv[1], 0);				argc--, argv++;			} else				(*p->c_func)(*argv, p->c_parameter);		}		argc--, argv++;	}	if (newaddr) {		strncpy(rafp->af_addreq, name, sizeof ifr.ifr_name);		if (ioctl(s, rafp->af_pifaddr, rafp->af_addreq) < 0)			Perror("ioctl (SIOCSIFPHYADDR)");	}	else if (setpsrc) {		errx(1, "destination is not specified");	}	return(0);}#define PSRC	0#define PDST	1/*ARGSUSED*/voidsetifpsrc(addr, param)	char *addr;	int param;{	param = 0;	/*fool gcc*/	(*afp->af_getaddr)(addr, PSRC);	setpsrc = 1;}/*ARGSUSED*/voidsetifpdst(addr, param)	char *addr;	int param;{	param = 0;	/*fool gcc*/	(*afp->af_getaddr)(addr, PDST);	newaddr = 1;}voidsetifflags(vname, value)	char *vname;	int value;{ 	if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) { 		Perror("ioctl (SIOCGIFFLAGS)"); 		exit(1); 	}	strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); 	flags = ifr.ifr_flags;	if (value < 0) {		value = -value;		flags &= ~value;	} else		flags |= value;	ifr.ifr_flags = flags;	if (ioctl(s, SIOCSIFFLAGS, (caddr_t)&ifr) < 0)		Perror(vname);}#ifdef SIOCDIFPHYADDR/* ARGSUSED */voiddelifaddrs(vname, param)	char *vname;	int param;{	param = 0;		/* fool gcc */	vname = NULL;		/* ditto */	if (ioctl(s, SIOCDIFPHYADDR, (caddr_t)&ifr) < 0)		err(1, "ioctl(SIOCDIFPHYADDR)");

⌨️ 快捷键说明

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