?? gifconfig.c
字號:
/* $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 + -