121811Skarels /* 221811Skarels * Copyright (c) 1983 Regents of the University of California. 334941Sbostic * All rights reserved. 434941Sbostic * 5*51366Swilliam * Redistribution and use in source and binary forms, with or without 6*51366Swilliam * modification, are permitted provided that the following conditions 7*51366Swilliam * are met: 8*51366Swilliam * 1. Redistributions of source code must retain the above copyright 9*51366Swilliam * notice, this list of conditions and the following disclaimer. 10*51366Swilliam * 2. Redistributions in binary form must reproduce the above copyright 11*51366Swilliam * notice, this list of conditions and the following disclaimer in the 12*51366Swilliam * documentation and/or other materials provided with the distribution. 13*51366Swilliam * 3. All advertising materials mentioning features or use of this software 14*51366Swilliam * must display the following acknowledgement: 15*51366Swilliam * This product includes software developed by the University of 16*51366Swilliam * California, Berkeley and its contributors. 17*51366Swilliam * 4. Neither the name of the University nor the names of its contributors 18*51366Swilliam * may be used to endorse or promote products derived from this software 19*51366Swilliam * without specific prior written permission. 20*51366Swilliam * 21*51366Swilliam * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22*51366Swilliam * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23*51366Swilliam * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24*51366Swilliam * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25*51366Swilliam * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26*51366Swilliam * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27*51366Swilliam * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28*51366Swilliam * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29*51366Swilliam * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30*51366Swilliam * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31*51366Swilliam * SUCH DAMAGE. 3221811Skarels */ 3321811Skarels 3414869Ssam #ifndef lint 3521811Skarels char copyright[] = 3621811Skarels "@(#) Copyright (c) 1983 Regents of the University of California.\n\ 3721811Skarels All rights reserved.\n"; 3834941Sbostic #endif /* not lint */ 3914869Ssam 4021811Skarels #ifndef lint 41*51366Swilliam static char sccsid[] = "@(#)ifconfig.c 5.1 (Berkeley) 2/28/91"; 4234941Sbostic #endif /* not lint */ 4321811Skarels 4446782Sbostic #include <sys/param.h> 4514869Ssam #include <sys/socket.h> 4614869Ssam #include <sys/ioctl.h> 4714869Ssam 4822485Ssklower #include <net/if.h> 4914869Ssam #include <netinet/in.h> 5046782Sbostic #include <arpa/inet.h> 5114869Ssam 5222485Ssklower #define NSIP 5322485Ssklower #include <netns/ns.h> 5422485Ssklower #include <netns/ns_if.h> 5546782Sbostic #include <netdb.h> 5622485Ssklower 5737479Ssklower #define EON 5837315Ssklower #include <netiso/iso.h> 5937315Ssklower #include <netiso/iso_var.h> 6037479Ssklower #include <sys/protosw.h> 6137315Ssklower 6246782Sbostic #include <unistd.h> 6314869Ssam #include <stdio.h> 6414869Ssam #include <errno.h> 6514869Ssam #include <ctype.h> 6646782Sbostic #include <stdlib.h> 6746782Sbostic #include <string.h> 6814869Ssam 6937315Ssklower struct ifreq ifr, ridreq; 7037315Ssklower struct ifaliasreq addreq; 7137315Ssklower struct iso_ifreq iso_ridreq; 7243089Ssklower struct iso_aliasreq iso_addreq; 7337315Ssklower struct sockaddr_in netmask; 7437315Ssklower 7514869Ssam char name[30]; 7621811Skarels int flags; 7726185Skarels int metric; 7843089Ssklower int nsellength = 1; 7916329Skarels int setaddr; 8022485Ssklower int setipdst; 8137315Ssklower int doalias; 8237479Ssklower int clearaddr; 8337315Ssklower int newaddr = 1; 8414869Ssam int s; 8521811Skarels extern int errno; 8614869Ssam 8721811Skarels int setifflags(), setifaddr(), setifdstaddr(), setifnetmask(); 8826185Skarels int setifmetric(), setifbroadaddr(), setifipdst(); 8942965Ssklower int notealias(), setsnpaoffset(), setnsellength(); 9014869Ssam 9121811Skarels #define NEXTARG 0xffffff 9221811Skarels 9314869Ssam struct cmd { 9414869Ssam char *c_name; 9521811Skarels int c_parameter; /* NEXTARG means next argv */ 9614869Ssam int (*c_func)(); 9714869Ssam } cmds[] = { 9814869Ssam { "up", IFF_UP, setifflags } , 9914869Ssam { "down", -IFF_UP, setifflags }, 10014869Ssam { "trailers", -IFF_NOTRAILERS,setifflags }, 10114869Ssam { "-trailers", IFF_NOTRAILERS, setifflags }, 10215359Skarels { "arp", -IFF_NOARP, setifflags }, 10315359Skarels { "-arp", IFF_NOARP, setifflags }, 10415286Sleres { "debug", IFF_DEBUG, setifflags }, 10515286Sleres { "-debug", -IFF_DEBUG, setifflags }, 10637315Ssklower { "alias", IFF_UP, notealias }, 10737315Ssklower { "-alias", -IFF_UP, notealias }, 10837315Ssklower { "delete", -IFF_UP, notealias }, 10915004Ssam #ifdef notdef 11021811Skarels #define EN_SWABIPS 0x1000 11115004Ssam { "swabips", EN_SWABIPS, setifflags }, 11215004Ssam { "-swabips", -EN_SWABIPS, setifflags }, 11315004Ssam #endif 11421811Skarels { "netmask", NEXTARG, setifnetmask }, 11526185Skarels { "metric", NEXTARG, setifmetric }, 11621811Skarels { "broadcast", NEXTARG, setifbroadaddr }, 11722485Ssklower { "ipdst", NEXTARG, setifipdst }, 11842965Ssklower { "snpaoffset", NEXTARG, setsnpaoffset }, 11942965Ssklower { "nsellength", NEXTARG, setnsellength }, 120*51366Swilliam { "llc0", IFF_LLC0, setifflags } , 121*51366Swilliam { "-llc0", -IFF_LLC0, setifflags } , 122*51366Swilliam { "llc1", IFF_LLC1, setifflags } , 123*51366Swilliam { "-llc1", -IFF_LLC1, setifflags } , 124*51366Swilliam { "llc2", IFF_LLC2, setifflags } , 125*51366Swilliam { "-llc2", -IFF_LLC2, setifflags } , 12614869Ssam { 0, 0, setifaddr }, 12717218Stef { 0, 0, setifdstaddr }, 12814869Ssam }; 12914869Ssam 13022485Ssklower /* 13122485Ssklower * XNS support liberally adapted from 13222485Ssklower * code written at the University of Maryland 13322485Ssklower * principally by James O'Toole and Chris Torek. 13422485Ssklower */ 13522485Ssklower int in_status(), in_getaddr(); 13622485Ssklower int xns_status(), xns_getaddr(); 13737315Ssklower int iso_status(), iso_getaddr(); 13822485Ssklower 13922485Ssklower /* Known address families */ 14022485Ssklower struct afswtch { 14122485Ssklower char *af_name; 14222485Ssklower short af_af; 14322485Ssklower int (*af_status)(); 14422485Ssklower int (*af_getaddr)(); 14537315Ssklower int af_difaddr; 14637315Ssklower int af_aifaddr; 14737315Ssklower caddr_t af_ridreq; 14837315Ssklower caddr_t af_addreq; 14922485Ssklower } afs[] = { 15037315Ssklower #define C(x) ((caddr_t) &x) 15137315Ssklower { "inet", AF_INET, in_status, in_getaddr, 15237315Ssklower SIOCDIFADDR, SIOCAIFADDR, C(ridreq), C(addreq) }, 15337315Ssklower { "ns", AF_NS, xns_status, xns_getaddr, 15437315Ssklower SIOCDIFADDR, SIOCAIFADDR, C(ridreq), C(addreq) }, 15537315Ssklower { "iso", AF_ISO, iso_status, iso_getaddr, 15637315Ssklower SIOCDIFADDR_ISO, SIOCAIFADDR_ISO, C(iso_ridreq), C(iso_addreq) }, 15737315Ssklower { 0, 0, 0, 0 } 15822485Ssklower }; 15922485Ssklower 16022485Ssklower struct afswtch *afp; /*the address family being set or asked about*/ 16122485Ssklower 16214869Ssam main(argc, argv) 16314869Ssam int argc; 16414869Ssam char *argv[]; 16514869Ssam { 16622485Ssklower int af = AF_INET; 16737315Ssklower register struct afswtch *rafp; 16827061Skarels 16914869Ssam if (argc < 2) { 170*51366Swilliam fprintf(stderr, "usage: ifconfig interface\n%s%s%s%s%s%s", 17126185Skarels "\t[ af [ address [ dest_addr ] ] [ up ] [ down ]", 17226185Skarels "[ netmask mask ] ]\n", 17326185Skarels "\t[ metric n ]\n", 17426185Skarels "\t[ trailers | -trailers ]\n", 175*51366Swilliam "\t[ arp | -arp ]\n", 176*51366Swilliam "\t[ llc0 | -llc0 ] [ llc1 | -llc1 ] [ llc2 | -llc2 ] \n"); 17714869Ssam exit(1); 17814869Ssam } 17922485Ssklower argc--, argv++; 18024248Ssklower strncpy(name, *argv, sizeof(name)); 18122485Ssklower strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); 18222485Ssklower argc--, argv++; 18322485Ssklower if (argc > 0) { 18437315Ssklower for (afp = rafp = afs; rafp->af_name; rafp++) 18537315Ssklower if (strcmp(rafp->af_name, *argv) == 0) { 18637315Ssklower afp = rafp; argc--; argv++; 18722485Ssklower break; 18822485Ssklower } 18937315Ssklower rafp = afp; 19037315Ssklower af = ifr.ifr_addr.sa_family = rafp->af_af; 19122485Ssklower } 19222485Ssklower s = socket(af, SOCK_DGRAM, 0); 19314869Ssam if (s < 0) { 19414869Ssam perror("ifconfig: socket"); 19514869Ssam exit(1); 19614869Ssam } 19714869Ssam if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) { 19814869Ssam Perror("ioctl (SIOCGIFFLAGS)"); 19914869Ssam exit(1); 20014869Ssam } 20122485Ssklower strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name); 20221811Skarels flags = ifr.ifr_flags; 20326185Skarels if (ioctl(s, SIOCGIFMETRIC, (caddr_t)&ifr) < 0) 20426185Skarels perror("ioctl (SIOCGIFMETRIC)"); 20526185Skarels else 20626185Skarels metric = ifr.ifr_metric; 20714869Ssam if (argc == 0) { 20814869Ssam status(); 20914869Ssam exit(0); 21014869Ssam } 21114869Ssam while (argc > 0) { 21214869Ssam register struct cmd *p; 21314869Ssam 21414869Ssam for (p = cmds; p->c_name; p++) 21514869Ssam if (strcmp(*argv, p->c_name) == 0) 21614869Ssam break; 21717218Stef if (p->c_name == 0 && setaddr) 21817218Stef p++; /* got src, do dst */ 21921811Skarels if (p->c_func) { 22021811Skarels if (p->c_parameter == NEXTARG) { 22121811Skarels (*p->c_func)(argv[1]); 22221811Skarels argc--, argv++; 22321811Skarels } else 22421811Skarels (*p->c_func)(*argv, p->c_parameter); 22521811Skarels } 22614869Ssam argc--, argv++; 22714869Ssam } 22843089Ssklower if (af == AF_ISO) 22943089Ssklower adjust_nsellength(); 23037479Ssklower if (setipdst && af==AF_NS) { 23137479Ssklower struct nsip_req rq; 23237479Ssklower int size = sizeof(rq); 23337479Ssklower 23437479Ssklower rq.rq_ns = addreq.ifra_addr; 23537479Ssklower rq.rq_ip = addreq.ifra_dstaddr; 23637479Ssklower 23737479Ssklower if (setsockopt(s, 0, SO_NSIP_ROUTE, &rq, size) < 0) 23837479Ssklower Perror("Encapsulation Routing"); 23937479Ssklower } 24037315Ssklower if (clearaddr) { 24137315Ssklower int ret; 24237315Ssklower strncpy(rafp->af_ridreq, name, sizeof ifr.ifr_name); 24337315Ssklower if ((ret = ioctl(s, rafp->af_difaddr, rafp->af_ridreq)) < 0) { 24437315Ssklower if (errno == EADDRNOTAVAIL && (doalias >= 0)) { 24537315Ssklower /* means no previous address for interface */ 24637315Ssklower } else 24737315Ssklower Perror("ioctl (SIOCDIFADDR)"); 24837315Ssklower } 24921811Skarels } 25037315Ssklower if (newaddr) { 25137315Ssklower strncpy(rafp->af_addreq, name, sizeof ifr.ifr_name); 25237315Ssklower if (ioctl(s, rafp->af_aifaddr, rafp->af_addreq) < 0) 25337315Ssklower Perror("ioctl (SIOCAIFADDR)"); 25416329Skarels } 25514869Ssam exit(0); 25614869Ssam } 25737315Ssklower #define RIDADDR 0 25837315Ssklower #define ADDR 1 25937315Ssklower #define MASK 2 26037315Ssklower #define DSTADDR 3 26114869Ssam 26214869Ssam /*ARGSUSED*/ 26314869Ssam setifaddr(addr, param) 26414869Ssam char *addr; 26522485Ssklower short param; 26614869Ssam { 26716329Skarels /* 26816329Skarels * Delay the ioctl to set the interface addr until flags are all set. 26916329Skarels * The address interpretation may depend on the flags, 27016329Skarels * and the flags may change when the address is set. 27115390Skarels */ 27216329Skarels setaddr++; 27340830Ssklower if (doalias == 0) 27437479Ssklower clearaddr = 1; 27537315Ssklower (*afp->af_getaddr)(addr, (doalias >= 0 ? ADDR : RIDADDR)); 27614869Ssam } 27714869Ssam 27821811Skarels setifnetmask(addr) 27921811Skarels char *addr; 28021811Skarels { 28137315Ssklower (*afp->af_getaddr)(addr, MASK); 28221811Skarels } 28321811Skarels 28421811Skarels setifbroadaddr(addr) 28521811Skarels char *addr; 28621811Skarels { 28737315Ssklower (*afp->af_getaddr)(addr, DSTADDR); 28821811Skarels } 28921811Skarels 29022485Ssklower setifipdst(addr) 29122485Ssklower char *addr; 29222485Ssklower { 29337315Ssklower in_getaddr(addr, DSTADDR); 29422485Ssklower setipdst++; 29537479Ssklower clearaddr = 0; 29637479Ssklower newaddr = 0; 29722485Ssklower } 29837479Ssklower #define rqtosa(x) (&(((struct ifreq *)(afp->x))->ifr_addr)) 29917218Stef /*ARGSUSED*/ 30037315Ssklower notealias(addr, param) 30137315Ssklower char *addr; 30237315Ssklower { 30337479Ssklower if (setaddr && doalias == 0 && param < 0) 30437479Ssklower bcopy((caddr_t)rqtosa(af_addreq), 30537479Ssklower (caddr_t)rqtosa(af_ridreq), 30637479Ssklower rqtosa(af_addreq)->sa_len); 30737315Ssklower doalias = param; 30837479Ssklower if (param < 0) { 30937479Ssklower clearaddr = 1; 31037479Ssklower newaddr = 0; 31137479Ssklower } else 31237315Ssklower clearaddr = 0; 31337315Ssklower } 31437315Ssklower 31537315Ssklower /*ARGSUSED*/ 31617218Stef setifdstaddr(addr, param) 31717218Stef char *addr; 31817218Stef int param; 31917218Stef { 32037315Ssklower (*afp->af_getaddr)(addr, DSTADDR); 32117218Stef } 32217218Stef 32314870Ssam setifflags(vname, value) 32414870Ssam char *vname; 32522485Ssklower short value; 32614869Ssam { 32722485Ssklower if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) { 32822485Ssklower Perror("ioctl (SIOCGIFFLAGS)"); 32922485Ssklower exit(1); 33022485Ssklower } 33122485Ssklower strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); 33222485Ssklower flags = ifr.ifr_flags; 33314869Ssam 33414869Ssam if (value < 0) { 33514869Ssam value = -value; 33621811Skarels flags &= ~value; 33714869Ssam } else 33821811Skarels flags |= value; 33921811Skarels ifr.ifr_flags = flags; 34014869Ssam if (ioctl(s, SIOCSIFFLAGS, (caddr_t)&ifr) < 0) 34114870Ssam Perror(vname); 34214869Ssam } 34314869Ssam 34426185Skarels setifmetric(val) 34526185Skarels char *val; 34626185Skarels { 34726185Skarels strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); 34826185Skarels ifr.ifr_metric = atoi(val); 34926185Skarels if (ioctl(s, SIOCSIFMETRIC, (caddr_t)&ifr) < 0) 35026185Skarels perror("ioctl (set metric)"); 35126185Skarels } 35226185Skarels 35337315Ssklower setsnpaoffset(val) 35437315Ssklower char *val; 35537315Ssklower { 35637315Ssklower iso_addreq.ifra_snpaoffset = atoi(val); 35737315Ssklower } 35837315Ssklower 35926185Skarels #define IFFBITS \ 360*51366Swilliam "\020\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\6NOTRAILERS\7RUNNING\10NOARP\ 361*51366Swilliam \11PROMISC\12ALLMULTI\13OACTIVE\14SIMPLEX\15LLC0\16LLC1\16LLC2" 36226185Skarels 36322485Ssklower /* 36422485Ssklower * Print the status of the interface. If an address family was 36522485Ssklower * specified, show it and it only; otherwise, show them all. 36622485Ssklower */ 36714869Ssam status() 36814869Ssam { 36922485Ssklower register struct afswtch *p = afp; 37022485Ssklower short af = ifr.ifr_addr.sa_family; 37122485Ssklower 37226185Skarels printf("%s: ", name); 37326185Skarels printb("flags", flags, IFFBITS); 37426185Skarels if (metric) 37526185Skarels printf(" metric %d", metric); 37626185Skarels putchar('\n'); 37722485Ssklower if ((p = afp) != NULL) { 37828468Skarels (*p->af_status)(1); 37928468Skarels } else for (p = afs; p->af_name; p++) { 38022485Ssklower ifr.ifr_addr.sa_family = p->af_af; 38128468Skarels (*p->af_status)(0); 38222485Ssklower } 38322485Ssklower } 38422485Ssklower 38528468Skarels in_status(force) 38628468Skarels int force; 38722485Ssklower { 38814869Ssam struct sockaddr_in *sin; 38922485Ssklower char *inet_ntoa(); 39014869Ssam 39127061Skarels strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); 39221811Skarels if (ioctl(s, SIOCGIFADDR, (caddr_t)&ifr) < 0) { 39328468Skarels if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT) { 39428468Skarels if (!force) 39528468Skarels return; 39621811Skarels bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr)); 39728468Skarels } else 39828468Skarels perror("ioctl (SIOCGIFADDR)"); 39921811Skarels } 40014869Ssam sin = (struct sockaddr_in *)&ifr.ifr_addr; 40126429Skarels printf("\tinet %s ", inet_ntoa(sin->sin_addr)); 40228468Skarels strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); 40328468Skarels if (ioctl(s, SIOCGIFNETMASK, (caddr_t)&ifr) < 0) { 40428468Skarels if (errno != EADDRNOTAVAIL) 40528468Skarels perror("ioctl (SIOCGIFNETMASK)"); 40628468Skarels bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr)); 40728468Skarels } else 40828468Skarels netmask.sin_addr = 40928468Skarels ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr; 41017218Stef if (flags & IFF_POINTOPOINT) { 41121811Skarels if (ioctl(s, SIOCGIFDSTADDR, (caddr_t)&ifr) < 0) { 41221811Skarels if (errno == EADDRNOTAVAIL) 41321811Skarels bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr)); 41421811Skarels else 41528468Skarels perror("ioctl (SIOCGIFDSTADDR)"); 41621811Skarels } 41722485Ssklower strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); 41817218Stef sin = (struct sockaddr_in *)&ifr.ifr_dstaddr; 41917218Stef printf("--> %s ", inet_ntoa(sin->sin_addr)); 42017218Stef } 42121811Skarels printf("netmask %x ", ntohl(netmask.sin_addr.s_addr)); 42221811Skarels if (flags & IFF_BROADCAST) { 42321811Skarels if (ioctl(s, SIOCGIFBRDADDR, (caddr_t)&ifr) < 0) { 42421811Skarels if (errno == EADDRNOTAVAIL) 42528468Skarels bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr)); 42628468Skarels else 42728468Skarels perror("ioctl (SIOCGIFADDR)"); 42821811Skarels } 42922485Ssklower strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); 43021811Skarels sin = (struct sockaddr_in *)&ifr.ifr_addr; 43128468Skarels if (sin->sin_addr.s_addr != 0) 43228468Skarels printf("broadcast %s", inet_ntoa(sin->sin_addr)); 43321811Skarels } 43426185Skarels putchar('\n'); 43514869Ssam } 43614869Ssam 43722485Ssklower 43828468Skarels xns_status(force) 43928468Skarels int force; 44022485Ssklower { 44122485Ssklower struct sockaddr_ns *sns; 44222485Ssklower 44322485Ssklower close(s); 44422485Ssklower s = socket(AF_NS, SOCK_DGRAM, 0); 44522485Ssklower if (s < 0) { 44630692Smckusick if (errno == EPROTONOSUPPORT) 44724248Ssklower return; 44822485Ssklower perror("ifconfig: socket"); 44922485Ssklower exit(1); 45022485Ssklower } 45122485Ssklower if (ioctl(s, SIOCGIFADDR, (caddr_t)&ifr) < 0) { 45228468Skarels if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT) { 45328468Skarels if (!force) 45428468Skarels return; 45528468Skarels bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr)); 45628468Skarels } else 45728468Skarels perror("ioctl (SIOCGIFADDR)"); 45822485Ssklower } 45922485Ssklower strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name); 46022485Ssklower sns = (struct sockaddr_ns *)&ifr.ifr_addr; 46126185Skarels printf("\tns %s ", ns_ntoa(sns->sns_addr)); 46226101Ssklower if (flags & IFF_POINTOPOINT) { /* by W. Nesheim@Cornell */ 46326101Ssklower if (ioctl(s, SIOCGIFDSTADDR, (caddr_t)&ifr) < 0) { 46426101Ssklower if (errno == EADDRNOTAVAIL) 46526101Ssklower bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr)); 46626101Ssklower else 46726101Ssklower Perror("ioctl (SIOCGIFDSTADDR)"); 46826101Ssklower } 46926101Ssklower strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); 47026101Ssklower sns = (struct sockaddr_ns *)&ifr.ifr_dstaddr; 47126101Ssklower printf("--> %s ", ns_ntoa(sns->sns_addr)); 47226101Ssklower } 47322485Ssklower putchar('\n'); 47422485Ssklower } 47522485Ssklower 47637315Ssklower iso_status(force) 47737315Ssklower int force; 47837315Ssklower { 47937315Ssklower struct sockaddr_iso *siso; 48037315Ssklower struct iso_ifreq ifr; 48137315Ssklower 48237315Ssklower close(s); 48337315Ssklower s = socket(AF_ISO, SOCK_DGRAM, 0); 48437315Ssklower if (s < 0) { 48537315Ssklower if (errno == EPROTONOSUPPORT) 48637315Ssklower return; 48737315Ssklower perror("ifconfig: socket"); 48837315Ssklower exit(1); 48937315Ssklower } 49042965Ssklower bzero((caddr_t)&ifr, sizeof(ifr)); 49142965Ssklower strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); 49242965Ssklower if (ioctl(s, SIOCGIFADDR_ISO, (caddr_t)&ifr) < 0) { 49337315Ssklower if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT) { 49437315Ssklower if (!force) 49537315Ssklower return; 49637315Ssklower bzero((char *)&ifr.ifr_Addr, sizeof(ifr.ifr_Addr)); 49742965Ssklower } else { 49842965Ssklower perror("ioctl (SIOCGIFADDR_ISO)"); 49942965Ssklower exit(1); 50042965Ssklower } 50137315Ssklower } 50237315Ssklower strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name); 50337315Ssklower siso = &ifr.ifr_Addr; 50442965Ssklower printf("\tiso %s ", iso_ntoa(&siso->siso_addr)); 50542965Ssklower if (ioctl(s, SIOCGIFNETMASK_ISO, (caddr_t)&ifr) < 0) { 50637315Ssklower if (errno != EADDRNOTAVAIL) 50742965Ssklower perror("ioctl (SIOCGIFNETMASK_ISO)"); 50837315Ssklower } else { 50942965Ssklower printf(" netmask %s ", iso_ntoa(&siso->siso_addr)); 51037315Ssklower } 51137315Ssklower if (flags & IFF_POINTOPOINT) { 51242965Ssklower if (ioctl(s, SIOCGIFDSTADDR_ISO, (caddr_t)&ifr) < 0) { 51337315Ssklower if (errno == EADDRNOTAVAIL) 51437315Ssklower bzero((char *)&ifr.ifr_Addr, sizeof(ifr.ifr_Addr)); 51537315Ssklower else 51642965Ssklower Perror("ioctl (SIOCGIFDSTADDR_ISO)"); 51737315Ssklower } 51837315Ssklower strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); 51937315Ssklower siso = &ifr.ifr_Addr; 52042965Ssklower printf("--> %s ", iso_ntoa(&siso->siso_addr)); 52137315Ssklower } 52237315Ssklower putchar('\n'); 52337315Ssklower } 52437315Ssklower 52514869Ssam Perror(cmd) 52614869Ssam char *cmd; 52714869Ssam { 52814869Ssam extern int errno; 52914869Ssam 53014869Ssam fprintf(stderr, "ifconfig: "); 53114869Ssam switch (errno) { 53214869Ssam 53314869Ssam case ENXIO: 53422485Ssklower fprintf(stderr, "%s: no such interface\n", cmd); 53514869Ssam break; 53614869Ssam 53714869Ssam case EPERM: 53816822Slepreau fprintf(stderr, "%s: permission denied\n", cmd); 53914869Ssam break; 54014869Ssam 54114869Ssam default: 54214869Ssam perror(cmd); 54314869Ssam } 54414869Ssam exit(1); 54514869Ssam } 54614869Ssam 54714869Ssam struct in_addr inet_makeaddr(); 54814869Ssam 54937315Ssklower #define SIN(x) ((struct sockaddr_in *) &(x)) 55037315Ssklower struct sockaddr_in *sintab[] = { 55137315Ssklower SIN(ridreq.ifr_addr), SIN(addreq.ifra_addr), 55237315Ssklower SIN(addreq.ifra_mask), SIN(addreq.ifra_broadaddr)}; 55337315Ssklower 55437315Ssklower in_getaddr(s, which) 55514869Ssam char *s; 55614869Ssam { 55737315Ssklower register struct sockaddr_in *sin = sintab[which]; 55814869Ssam struct hostent *hp; 55914869Ssam struct netent *np; 56014869Ssam int val; 56114869Ssam 56239210Ssklower sin->sin_len = sizeof(*sin); 56339210Ssklower if (which != MASK) 56437315Ssklower sin->sin_family = AF_INET; 56539210Ssklower 56639210Ssklower if ((val = inet_addr(s)) != -1) 56721811Skarels sin->sin_addr.s_addr = val; 56839210Ssklower else if (hp = gethostbyname(s)) 56914869Ssam bcopy(hp->h_addr, (char *)&sin->sin_addr, hp->h_length); 57039210Ssklower else if (np = getnetbyname(s)) 57114869Ssam sin->sin_addr = inet_makeaddr(np->n_net, INADDR_ANY); 57239210Ssklower else { 57339210Ssklower fprintf(stderr, "%s: bad value\n", s); 57439210Ssklower exit(1); 57514869Ssam } 57614869Ssam } 57714869Ssam 57814869Ssam /* 57914869Ssam * Print a value a la the %b format of the kernel's printf 58014869Ssam */ 58114869Ssam printb(s, v, bits) 58214869Ssam char *s; 58314869Ssam register char *bits; 58414869Ssam register unsigned short v; 58514869Ssam { 58614869Ssam register int i, any = 0; 58714869Ssam register char c; 58814869Ssam 58914869Ssam if (bits && *bits == 8) 59014869Ssam printf("%s=%o", s, v); 59114869Ssam else 59214869Ssam printf("%s=%x", s, v); 59314869Ssam bits++; 59414869Ssam if (bits) { 59514869Ssam putchar('<'); 59614869Ssam while (i = *bits++) { 59714869Ssam if (v & (1 << (i-1))) { 59814869Ssam if (any) 59914869Ssam putchar(','); 60014869Ssam any = 1; 60114869Ssam for (; (c = *bits) > 32; bits++) 60214869Ssam putchar(c); 60314869Ssam } else 60414869Ssam for (; *bits > 32; bits++) 60514869Ssam ; 60614869Ssam } 60714869Ssam putchar('>'); 60814869Ssam } 60914869Ssam } 61022485Ssklower 61137315Ssklower #define SNS(x) ((struct sockaddr_ns *) &(x)) 61237315Ssklower struct sockaddr_ns *snstab[] = { 61337315Ssklower SNS(ridreq.ifr_addr), SNS(addreq.ifra_addr), 61437315Ssklower SNS(addreq.ifra_mask), SNS(addreq.ifra_broadaddr)}; 61537315Ssklower 61637315Ssklower xns_getaddr(addr, which) 61722485Ssklower char *addr; 61822485Ssklower { 61937315Ssklower struct sockaddr_ns *sns = snstab[which]; 62026101Ssklower struct ns_addr ns_addr(); 62137315Ssklower 62222485Ssklower sns->sns_family = AF_NS; 62337227Ssklower sns->sns_len = sizeof(*sns); 62426101Ssklower sns->sns_addr = ns_addr(addr); 62537315Ssklower if (which == MASK) 62637315Ssklower printf("Attempt to set XNS netmask will be ineffectual\n"); 62722485Ssklower } 62837315Ssklower 62937315Ssklower #define SISO(x) ((struct sockaddr_iso *) &(x)) 63037315Ssklower struct sockaddr_iso *sisotab[] = { 63137315Ssklower SISO(iso_ridreq.ifr_Addr), SISO(iso_addreq.ifra_addr), 63237315Ssklower SISO(iso_addreq.ifra_mask), SISO(iso_addreq.ifra_dstaddr)}; 63337315Ssklower 63437315Ssklower iso_getaddr(addr, which) 63537315Ssklower char *addr; 63637315Ssklower { 63743089Ssklower register struct sockaddr_iso *siso = sisotab[which]; 63837315Ssklower struct iso_addr *iso_addr(); 63937315Ssklower siso->siso_addr = *iso_addr(addr); 64043089Ssklower 64137315Ssklower if (which == MASK) { 64239210Ssklower siso->siso_len = TSEL(siso) - (caddr_t)(siso); 64337315Ssklower siso->siso_nlen = 0; 64437315Ssklower } else { 64543089Ssklower siso->siso_len = sizeof(*siso); 64643089Ssklower siso->siso_family = AF_ISO; 64737315Ssklower } 64837315Ssklower } 64942965Ssklower 65042965Ssklower setnsellength(val) 65142965Ssklower char *val; 65242965Ssklower { 65343089Ssklower nsellength = atoi(val); 65443089Ssklower if (nsellength < 0) { 65543089Ssklower fprintf(stderr, "Negative NSEL length is absurd\n"); 65643089Ssklower exit (1); 65743089Ssklower } 65842965Ssklower if (afp == 0 || afp->af_af != AF_ISO) { 65942965Ssklower fprintf(stderr, "Setting NSEL length valid only for iso\n"); 66042965Ssklower exit (1); 66142965Ssklower } 66242965Ssklower } 66343089Ssklower 66443089Ssklower fixnsel(s) 66543089Ssklower register struct sockaddr_iso *s; 66643089Ssklower { 66743089Ssklower if (s->siso_family == 0) 66843089Ssklower return; 66943089Ssklower s->siso_tlen = nsellength; 67043089Ssklower } 67143089Ssklower 67243089Ssklower adjust_nsellength() 67343089Ssklower { 67443089Ssklower fixnsel(sisotab[RIDADDR]); 67543089Ssklower fixnsel(sisotab[ADDR]); 67643089Ssklower fixnsel(sisotab[DSTADDR]); 67743089Ssklower } 678