ifconfig.c revision 25448
1219089Spjd/* 2219089Spjd * Copyright (c) 1983, 1993 3219089Spjd * The Regents of the University of California. All rights reserved. 4219089Spjd * 5219089Spjd * Redistribution and use in source and binary forms, with or without 6219089Spjd * modification, are permitted provided that the following conditions 7219089Spjd * are met: 8219089Spjd * 1. Redistributions of source code must retain the above copyright 9219089Spjd * notice, this list of conditions and the following disclaimer. 10219089Spjd * 2. Redistributions in binary form must reproduce the above copyright 11219089Spjd * notice, this list of conditions and the following disclaimer in the 12219089Spjd * documentation and/or other materials provided with the distribution. 13219089Spjd * 3. All advertising materials mentioning features or use of this software 14219089Spjd * must display the following acknowledgement: 15219089Spjd * This product includes software developed by the University of 16219089Spjd * California, Berkeley and its contributors. 17219089Spjd * 4. Neither the name of the University nor the names of its contributors 18219089Spjd * may be used to endorse or promote products derived from this software 19219089Spjd * without specific prior written permission. 20219089Spjd * 21219089Spjd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22219089Spjd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23249195Smm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24219089Spjd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25219089Spjd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26219089Spjd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27219089Spjd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28219089Spjd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29219089Spjd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30219089Spjd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31219089Spjd * SUCH DAMAGE. 32219089Spjd */ 33219089Spjd 34219089Spjd#ifndef lint 35219089Spjdstatic const char copyright[] = 36219089Spjd"@(#) Copyright (c) 1983, 1993\n\ 37219089Spjd The Regents of the University of California. All rights reserved.\n"; 38219089Spjd#endif /* not lint */ 39219089Spjd 40219089Spjd#ifndef lint 41219089Spjd/* 42219089Spjdstatic char sccsid[] = "@(#)ifconfig.c 8.2 (Berkeley) 2/16/94"; 43219089Spjd*/ 44219089Spjdstatic const char rcsid[] = 45219089Spjd "$Id: ifconfig.c,v 1.24 1997/02/22 14:32:33 peter Exp $"; 46219089Spjd#endif /* not lint */ 47219089Spjd 48236884Smm#include <sys/param.h> 49219089Spjd#include <sys/ioctl.h> 50219089Spjd#include <sys/socket.h> 51219089Spjd#include <sys/sysctl.h> 52219089Spjd#include <sys/time.h> 53219089Spjd 54219089Spjd#include <net/if.h> 55219089Spjd#include <net/if_var.h> 56248571Smm#include <net/if_dl.h> 57219089Spjd#include <net/if_types.h> 58219089Spjd#include <net/route.h> 59237972Smm 60237972Smm/* IP */ 61237972Smm#include <netinet/in.h> 62237972Smm#include <netinet/in_var.h> 63219089Spjd#include <arpa/inet.h> 64237972Smm#include <netdb.h> 65237972Smm 66237972Smm/* IPX */ 67237972Smm#define IPXIP 68219089Spjd#define IPTUNNEL 69268650Sdelphij#include <netipx/ipx.h> 70237972Smm#include <netipx/ipx_if.h> 71237972Smm 72237972Smm/* Appletalk */ 73237972Smm#include <netatalk/at.h> 74237972Smm 75237972Smm/* XNS */ 76237972Smm#ifdef NS 77237972Smm#define NSIP 78237972Smm#include <netns/ns.h> 79237972Smm#include <netns/ns_if.h> 80237972Smm#endif 81237972Smm 82237972Smm/* OSI */ 83237972Smm#ifdef ISO 84237972Smm#define EON 85237972Smm#include <netiso/iso.h> 86237972Smm#include <netiso/iso_var.h> 87237972Smm#endif 88237972Smm 89237972Smm#include <ctype.h> 90237972Smm#include <err.h> 91237972Smm#include <errno.h> 92237972Smm#include <fcntl.h> 93237972Smm#include <stdio.h> 94237972Smm#include <stdlib.h> 95237972Smm#include <string.h> 96237972Smm#include <unistd.h> 97237972Smm 98237972Smmstruct ifreq ifr, ridreq; 99237972Smmstruct ifaliasreq addreq; 100219089Spjd#ifdef ISO 101219089Spjdstruct iso_ifreq iso_ridreq; 102219089Spjdstruct iso_aliasreq iso_addreq; 103219089Spjd#endif 104219089Spjdstruct sockaddr_in netmask; 105219089Spjdstruct netrange at_nr; /* AppleTalk net range */ 106219089Spjd 107219089Spjdchar name[32]; 108219089Spjdint flags; 109219089Spjdint metric; 110219089Spjdint mtu; 111219089Spjd#ifdef ISO 112219089Spjdint nsellength = 1; 113219089Spjd#endif 114219089Spjdint setaddr; 115219089Spjdint setipdst; 116219089Spjdint doalias; 117219089Spjdint clearaddr; 118219089Spjdint newaddr = 1; 119219089Spjdint s; 120219089Spjd 121219089Spjdstruct afswtch; 122219089Spjd 123219089Spjdvoid Perror __P((const char *cmd)); 124219089Spjdvoid checkatrange __P((struct sockaddr_at *)); 125219089Spjdint ifconfig __P((int argc, char *const *argv, int af, 126249858Smm const struct afswtch *rafp)); 127249858Smmvoid notealias __P((const char *, int)); 128249858Smmvoid printb __P((const char *s, unsigned value, const char *bits)); 129249858Smmvoid rt_xaddrs __P((caddr_t, caddr_t, struct rt_addrinfo *)); 130249858Smmvoid status __P((void)); 131249858Smm 132249858Smmtypedef void c_func __P((const char *cmd, int arg)); 133263390Sdelphijc_func setatphase, setatrange; 134249858Smmc_func setifaddr, setifbroadaddr, setifdstaddr, setifnetmask; 135219089Spjdc_func setifipdst; 136219089Spjdc_func setifflags, setifmetric, setifmtu; 137219089Spjd 138219089Spjd#ifdef ISO 139219089Spjdc_func setsnpaoffset, setnsellength; 140219089Spjd#endif 141219089Spjd 142219089Spjd#define NEXTARG 0xffffff 143219089Spjd 144219089Spjdconst 145219089Spjdstruct cmd { 146219089Spjd const char *c_name; 147219089Spjd int c_parameter; /* NEXTARG means next argv */ 148219089Spjd void (*c_func) __P((const char *, int)); 149219089Spjd} cmds[] = { 150219089Spjd { "up", IFF_UP, setifflags } , 151219089Spjd { "down", -IFF_UP, setifflags }, 152219089Spjd { "arp", -IFF_NOARP, setifflags }, 153219089Spjd { "-arp", IFF_NOARP, setifflags }, 154219089Spjd { "debug", IFF_DEBUG, setifflags }, 155219089Spjd { "-debug", -IFF_DEBUG, setifflags }, 156219089Spjd { "alias", IFF_UP, notealias }, 157219089Spjd { "-alias", -IFF_UP, notealias }, 158219089Spjd { "delete", -IFF_UP, notealias }, 159219089Spjd#ifdef notdef 160219089Spjd#define EN_SWABIPS 0x1000 161219089Spjd { "swabips", EN_SWABIPS, setifflags }, 162219089Spjd { "-swabips", -EN_SWABIPS, setifflags }, 163219089Spjd#endif 164219089Spjd { "netmask", NEXTARG, setifnetmask }, 165219089Spjd { "range", NEXTARG, setatrange }, 166219089Spjd { "phase", NEXTARG, setatphase }, 167219089Spjd { "metric", NEXTARG, setifmetric }, 168219089Spjd { "broadcast", NEXTARG, setifbroadaddr }, 169219089Spjd { "ipdst", NEXTARG, setifipdst }, 170219089Spjd#ifdef ISO 171219089Spjd { "snpaoffset", NEXTARG, setsnpaoffset }, 172219089Spjd { "nsellength", NEXTARG, setnsellength }, 173219089Spjd#endif 174219089Spjd { "link0", IFF_LINK0, setifflags }, 175219089Spjd { "-link0", -IFF_LINK0, setifflags }, 176219089Spjd { "link1", IFF_LINK1, setifflags }, 177219089Spjd { "-link1", -IFF_LINK1, setifflags }, 178219089Spjd { "link2", IFF_LINK2, setifflags }, 179219089Spjd { "-link2", -IFF_LINK2, setifflags }, 180219089Spjd { "normal", -IFF_LINK0, setifflags }, 181219089Spjd { "compress", IFF_LINK0, setifflags }, 182219089Spjd { "noicmp", IFF_LINK1, setifflags }, 183219089Spjd { "mtu", NEXTARG, setifmtu }, 184219089Spjd { 0, 0, setifaddr }, 185219089Spjd { 0, 0, setifdstaddr }, 186219089Spjd}; 187219089Spjd 188219089Spjd/* 189219089Spjd * XNS support liberally adapted from code written at the University of 190219089Spjd * Maryland principally by James O'Toole and Chris Torek. 191219089Spjd */ 192219089Spjdtypedef void af_status __P((int)); 193219089Spjdtypedef void af_getaddr __P((const char *, int)); 194248571Smm 195219089Spjdaf_status in_status, ipx_status, at_status, ether_status; 196248571Smmaf_getaddr in_getaddr, ipx_getaddr, at_getaddr; 197219089Spjd 198219089Spjd#ifdef NS 199249195Smmaf_status xns_status; 200219089Spjdaf_getaddr xns_getaddr; 201219089Spjd#endif 202219089Spjd#ifdef ISO 203219089Spjdaf_status iso_status; 204219089Spjdaf_getaddr iso_getaddr; 205248571Smm#endif 206219089Spjd 207248571Smm/* Known address families */ 208248571Smmconst 209219089Spjdstruct afswtch { 210219089Spjd const char *af_name; 211219089Spjd short af_af; 212219089Spjd af_status *af_status; 213219089Spjd af_getaddr *af_getaddr; 214219089Spjd int af_difaddr; 215219089Spjd int af_aifaddr; 216219089Spjd caddr_t af_ridreq; 217219089Spjd caddr_t af_addreq; 218219089Spjd} afs[] = { 219219089Spjd#define C(x) ((caddr_t) &x) 220219089Spjd { "inet", AF_INET, in_status, in_getaddr, 221219089Spjd SIOCDIFADDR, SIOCAIFADDR, C(ridreq), C(addreq) }, 222219089Spjd { "ipx", AF_IPX, ipx_status, ipx_getaddr, 223219089Spjd SIOCDIFADDR, SIOCAIFADDR, C(ridreq), C(addreq) }, 224219089Spjd { "atalk", AF_APPLETALK, at_status, at_getaddr, 225254112Sdelphij SIOCDIFADDR, SIOCAIFADDR, C(addreq), C(addreq) }, 226219089Spjd#ifdef NS 227219089Spjd { "ns", AF_NS, xns_status, xns_getaddr, 228219089Spjd SIOCDIFADDR, SIOCAIFADDR, C(ridreq), C(addreq) }, 229219089Spjd#endif 230219089Spjd#ifdef ISO 231219089Spjd { "iso", AF_ISO, iso_status, iso_getaddr, 232219089Spjd SIOCDIFADDR_ISO, SIOCAIFADDR_ISO, C(iso_ridreq), C(iso_addreq) }, 233219089Spjd#endif 234219089Spjd { "ether", AF_INET, ether_status, NULL }, /* XXX not real!! */ 235219089Spjd { 0, 0, 0, 0 } 236219089Spjd}; 237219089Spjd 238219089Spjdconst struct afswtch *afp; /*the address family being set or asked about*/ 239219089Spjd 240219089Spjd/* 241219089Spjd * Expand the compacted form of addresses as returned via the 242219089Spjd * configuration read via sysctl(). 243219089Spjd */ 244219089Spjd 245219089Spjd#define ROUNDUP(a) \ 246219089Spjd ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) 247219089Spjd#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len)) 248219089Spjd 249219089Spjdvoid 250219089Spjdrt_xaddrs(cp, cplim, rtinfo) 251219089Spjd caddr_t cp, cplim; 252219089Spjd struct rt_addrinfo *rtinfo; 253219089Spjd{ 254219089Spjd struct sockaddr *sa; 255219089Spjd int i; 256219089Spjd 257219089Spjd memset(rtinfo->rti_info, 0, sizeof(rtinfo->rti_info)); 258219089Spjd for (i = 0; (i < RTAX_MAX) && (cp < cplim); i++) { 259219089Spjd if ((rtinfo->rti_addrs & (1 << i)) == 0) 260219089Spjd continue; 261219089Spjd rtinfo->rti_info[i] = sa = (struct sockaddr *)cp; 262219089Spjd ADVANCE(cp, sa); 263219089Spjd } 264219089Spjd} 265219089Spjd 266219089Spjd 267219089Spjd/* 268248571Smm * Grunge for new-style sysctl() decoding.. :-( 269219089Spjd * Apologies to the world for committing gross things like this in 1996.. 270219089Spjd */ 271219089Spjdstruct if_msghdr *ifm; 272219089Spjdstruct ifa_msghdr *ifam; 273219089Spjdstruct sockaddr_dl *sdl; 274219089Spjdstruct rt_addrinfo info; 275219089Spjdchar *buf, *lim, *next; 276219089Spjd 277219089Spjdint 278219089Spjdmain(argc, argv) 279219089Spjd int argc; 280219089Spjd char *const *argv; 281219089Spjd{ 282219089Spjd int af = AF_INET; 283219089Spjd const struct afswtch *rafp; 284219089Spjd 285219089Spjd size_t needed; 286219089Spjd int mib[6]; 287219089Spjd int all; 288219089Spjd 289219089Spjd rafp = 0; 290219089Spjd 291219089Spjd if (argc < 2) { 292219089Spjd fprintf(stderr, "usage: ifconfig interface\n%s%s%s%s%s%s%s", 293219089Spjd "\t[ af [ address [ dest_addr ] ] [ up ] [ down ]", 294219089Spjd "[ netmask mask ] ]\n", 295219089Spjd "\t[ metric n ]\n", 296219089Spjd "\t[ mtu n ]\n", 297219089Spjd "\t[ arp | -arp ]\n", 298219089Spjd "\t[ link0 | -link0 ] [ link1 | -link1 ] [ link2 | -link2 ] \n", 299219089Spjd "\t[ -a ] [ -ad ] [ -au ]\n"); 300219089Spjd exit(1); 301219089Spjd } 302219089Spjd argc--, argv++; 303219089Spjd strncpy(name, *argv, sizeof(name)); 304219089Spjd strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); 305219089Spjd argc--, argv++; 306219089Spjd if (argc > 0) { 307219089Spjd for (afp = rafp = afs; rafp->af_name; rafp++) 308219089Spjd if (strcmp(rafp->af_name, *argv) == 0) { 309219089Spjd afp = rafp; argc--; argv++; 310219089Spjd break; 311219089Spjd } 312219089Spjd rafp = afp; 313219089Spjd af = ifr.ifr_addr.sa_family = rafp->af_af; 314219089Spjd } 315219089Spjd 316219089Spjd mib[0] = CTL_NET; 317248571Smm mib[1] = PF_ROUTE; 318219089Spjd mib[2] = 0; 319219089Spjd mib[3] = 0; /* address family */ 320219089Spjd mib[4] = NET_RT_IFLIST; 321219089Spjd mib[5] = 0; 322219089Spjd 323219089Spjd /* if particular family specified, only ask about it */ 324219089Spjd if (afp) { 325219089Spjd mib[3] = afp->af_af; 326219089Spjd } 327219089Spjd 328219089Spjd if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) 329219089Spjd errx(1, "iflist-sysctl-estimate"); 330219089Spjd if ((buf = malloc(needed)) == NULL) 331219089Spjd errx(1, "malloc"); 332219089Spjd if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) 333219089Spjd errx(1, "actual retrieval of interface table"); 334219089Spjd lim = buf + needed; 335219089Spjd 336219089Spjd all = 0; 337219089Spjd if (strcmp(name, "-a") == 0) 338219089Spjd all = 1; /* All interfaces */ 339219089Spjd else if (strcmp(name, "-au") == 0) 340219089Spjd all = 2; /* All IFF_UPinterfaces */ 341219089Spjd else if (strcmp(name, "-ad") == 0) 342219089Spjd all = 3; /* All !IFF_UP interfaces */ 343219089Spjd 344219089Spjd for (next = buf; next < lim; next += ifm->ifm_msglen) { 345219089Spjd 346219089Spjd ifm = (struct if_msghdr *)next; 347219089Spjd 348219089Spjd /* XXX: Swallow up leftover NEWADDR messages */ 349219089Spjd if (ifm->ifm_type == RTM_NEWADDR) 350219089Spjd continue; 351219089Spjd 352219089Spjd if (ifm->ifm_type == RTM_IFINFO) { 353219089Spjd sdl = (struct sockaddr_dl *)(ifm + 1); 354219089Spjd flags = ifm->ifm_flags; 355248571Smm } else { 356219089Spjd errx(1, "out of sync parsing NET_RT_IFLIST"); 357248571Smm } 358219089Spjd 359219089Spjd switch(all) { 360249195Smm case -1: 361219089Spjd case 0: 362219089Spjd if (strlen(name) != sdl->sdl_nlen) 363219089Spjd continue; /* not same len */ 364219089Spjd if (strncmp(name, sdl->sdl_data, sdl->sdl_nlen) != 0) 365219089Spjd continue; /* not same name */ 366248571Smm break; 367219089Spjd case 1: 368248571Smm break; /* always do it */ 369219089Spjd case 2: 370219089Spjd if ((flags & IFF_UP) == 0) 371219089Spjd continue; /* not up */ 372219089Spjd break; 373219089Spjd case 3: 374219089Spjd if (flags & IFF_UP) 375219089Spjd continue; /* not down */ 376219089Spjd break; 377248571Smm } 378248571Smm 379219089Spjd if (all > 0) { 380219089Spjd strncpy(name, sdl->sdl_data, sdl->sdl_nlen); 381219089Spjd name[sdl->sdl_nlen] = '\0'; 382219089Spjd } 383219089Spjd 384219089Spjd if ((s = socket(af, SOCK_DGRAM, 0)) < 0) { 385219089Spjd perror("ifconfig: socket"); 386219089Spjd exit(1); 387219089Spjd } 388219089Spjd 389219089Spjd ifconfig(argc, argv, af, rafp); 390219089Spjd 391219089Spjd close(s); 392219089Spjd 393219089Spjd if (all == 0) { 394219089Spjd all = -1; /* flag it as 'done' */ 395219089Spjd break; 396219089Spjd } 397219089Spjd } 398219089Spjd free(buf); 399240868Spjd 400240868Spjd if (all == 0) 401219089Spjd errx(1, "interface %s does not exist", name); 402219089Spjd 403219089Spjd 404219089Spjd exit (0); 405219089Spjd} 406219089Spjd 407219089Spjd 408219089Spjd 409219089Spjdint 410219089Spjdifconfig(argc,argv,af,rafp) 411219089Spjd int argc; 412219089Spjd char *const *argv; 413219089Spjd int af; 414219089Spjd const struct afswtch *rafp; 415248571Smm{ 416219089Spjd 417219089Spjd strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name); 418219089Spjd 419219089Spjd if (ioctl(s, SIOCGIFMETRIC, (caddr_t)&ifr) < 0) 420219089Spjd perror("ioctl (SIOCGIFMETRIC)"); 421219089Spjd else 422219089Spjd metric = ifr.ifr_metric; 423219089Spjd 424219089Spjd if (ioctl(s, SIOCGIFMTU, (caddr_t)&ifr) < 0) 425237972Smm perror("ioctl (SIOCGIFMTU)"); 426219089Spjd else 427219089Spjd mtu = ifr.ifr_mtu; 428219089Spjd 429219089Spjd if (argc == 0) { 430219089Spjd status(); 431219089Spjd return(0); 432219089Spjd } 433219089Spjd 434236884Smm while (argc > 0) { 435219089Spjd register const struct cmd *p; 436219089Spjd 437219089Spjd for (p = cmds; p->c_name; p++) 438219089Spjd if (strcmp(*argv, p->c_name) == 0) 439219089Spjd break; 440219089Spjd if (p->c_name == 0 && setaddr) 441219089Spjd p++; /* got src, do dst */ 442219089Spjd if (p->c_func) { 443219089Spjd if (p->c_parameter == NEXTARG) { 444219089Spjd if (argv[1] == NULL) 445255437Sdelphij errx(1, "'%s' requires argument", 446219089Spjd p->c_name); 447219089Spjd (*p->c_func)(argv[1], 0); 448219089Spjd argc--, argv++; 449219089Spjd } else 450219089Spjd (*p->c_func)(*argv, p->c_parameter); 451219089Spjd } 452219089Spjd argc--, argv++; 453219089Spjd } 454219089Spjd#ifdef ISO 455219089Spjd if (af == AF_ISO) 456219089Spjd adjust_nsellength(); 457219089Spjd#endif 458219089Spjd if (setipdst && af==AF_IPX) { 459219089Spjd struct ipxip_req rq; 460219089Spjd int size = sizeof(rq); 461219089Spjd 462219089Spjd rq.rq_ipx = addreq.ifra_addr; 463219089Spjd rq.rq_ip = addreq.ifra_dstaddr; 464219089Spjd 465219089Spjd if (setsockopt(s, 0, SO_IPXIP_ROUTE, &rq, size) < 0) 466219089Spjd Perror("Encapsulation Routing"); 467219089Spjd } 468219089Spjd if (af == AF_APPLETALK) 469219089Spjd checkatrange((struct sockaddr_at *) &addreq.ifra_addr); 470219089Spjd#ifdef NS 471219089Spjd if (setipdst && af==AF_NS) { 472219089Spjd struct nsip_req rq; 473219089Spjd int size = sizeof(rq); 474219089Spjd 475219089Spjd rq.rq_ns = addreq.ifra_addr; 476219089Spjd rq.rq_ip = addreq.ifra_dstaddr; 477219089Spjd 478219089Spjd if (setsockopt(s, 0, SO_NSIP_ROUTE, &rq, size) < 0) 479219089Spjd Perror("Encapsulation Routing"); 480219089Spjd } 481219089Spjd#endif 482263397Sdelphij if (clearaddr) { 483219089Spjd if (rafp->af_ridreq == NULL || rafp->af_difaddr == 0) { 484219089Spjd warnx("interface %s cannot change %s addresses!", 485219089Spjd name, rafp->af_name); 486219089Spjd clearaddr = NULL; 487219089Spjd } 488219089Spjd } 489219089Spjd if (clearaddr) { 490219089Spjd int ret; 491219089Spjd strncpy(rafp->af_ridreq, name, sizeof ifr.ifr_name); 492219089Spjd if ((ret = ioctl(s, rafp->af_difaddr, rafp->af_ridreq)) < 0) { 493219089Spjd if (errno == EADDRNOTAVAIL && (doalias >= 0)) { 494219089Spjd /* means no previous address for interface */ 495219089Spjd } else 496219089Spjd Perror("ioctl (SIOCDIFADDR)"); 497219089Spjd } 498219089Spjd } 499219089Spjd if (newaddr) { 500219089Spjd if (rafp->af_ridreq == NULL || rafp->af_difaddr == 0) { 501219089Spjd warnx("interface %s cannot change %s addresses!", 502219089Spjd name, rafp->af_name); 503219089Spjd newaddr = NULL; 504219089Spjd } 505219089Spjd } 506219089Spjd if (newaddr) { 507219089Spjd strncpy(rafp->af_addreq, name, sizeof ifr.ifr_name); 508219089Spjd if (ioctl(s, rafp->af_aifaddr, rafp->af_addreq) < 0) 509219089Spjd Perror("ioctl (SIOCAIFADDR)"); 510219089Spjd } 511219089Spjd return(0); 512219089Spjd} 513219089Spjd#define RIDADDR 0 514263397Sdelphij#define ADDR 1 515263397Sdelphij#define MASK 2 516219089Spjd#define DSTADDR 3 517219089Spjd 518219089Spjd/*ARGSUSED*/ 519219089Spjdvoid 520219089Spjdsetifaddr(addr, param) 521219089Spjd const char *addr; 522219089Spjd int param; 523219089Spjd{ 524219089Spjd /* 525219089Spjd * Delay the ioctl to set the interface addr until flags are all set. 526219089Spjd * The address interpretation may depend on the flags, 527219089Spjd * and the flags may change when the address is set. 528219089Spjd */ 529219089Spjd setaddr++; 530219089Spjd if (doalias == 0) 531219089Spjd clearaddr = 1; 532219089Spjd (*afp->af_getaddr)(addr, (doalias >= 0 ? ADDR : RIDADDR)); 533219089Spjd} 534219089Spjd 535219089Spjdvoid 536219089Spjdsetifnetmask(addr, dummy) 537219089Spjd const char *addr; 538219089Spjd int dummy __unused; 539219089Spjd{ 540219089Spjd (*afp->af_getaddr)(addr, MASK); 541219089Spjd} 542219089Spjd 543219089Spjdvoid 544219089Spjdsetifbroadaddr(addr, dummy) 545219089Spjd const char *addr; 546219089Spjd int dummy __unused; 547219089Spjd{ 548219089Spjd (*afp->af_getaddr)(addr, DSTADDR); 549219089Spjd} 550219089Spjd 551219089Spjdvoid 552219089Spjdsetifipdst(addr, dummy) 553219089Spjd const char *addr; 554219089Spjd int dummy __unused; 555219089Spjd{ 556219089Spjd in_getaddr(addr, DSTADDR); 557219089Spjd setipdst++; 558219089Spjd clearaddr = 0; 559219089Spjd newaddr = 0; 560219089Spjd} 561219089Spjd#define rqtosa(x) (&(((struct ifreq *)(afp->x))->ifr_addr)) 562219089Spjd 563219089Spjdvoid 564219089Spjdnotealias(addr, param) 565219089Spjd const char *addr; 566219089Spjd int param; 567219089Spjd{ 568219089Spjd if (setaddr && doalias == 0 && param < 0) 569219089Spjd bcopy((caddr_t)rqtosa(af_addreq), 570219089Spjd (caddr_t)rqtosa(af_ridreq), 571219089Spjd rqtosa(af_addreq)->sa_len); 572219089Spjd doalias = param; 573219089Spjd if (param < 0) { 574219089Spjd clearaddr = 1; 575246666Smm newaddr = 0; 576219089Spjd } else 577219089Spjd clearaddr = 0; 578219089Spjd} 579219089Spjd 580219089Spjd/*ARGSUSED*/ 581219089Spjdvoid 582219089Spjdsetifdstaddr(addr, param) 583219089Spjd const char *addr; 584219089Spjd int param __unused; 585219089Spjd{ 586236884Smm (*afp->af_getaddr)(addr, DSTADDR); 587219089Spjd} 588219089Spjd 589219089Spjdvoid 590219089Spjdsetifflags(vname, value) 591219089Spjd const char *vname; 592236884Smm int value; 593219089Spjd{ 594219089Spjd if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) { 595219089Spjd Perror("ioctl (SIOCGIFFLAGS)"); 596219089Spjd exit(1); 597219089Spjd } 598219089Spjd strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); 599219089Spjd flags = ifr.ifr_flags; 600219089Spjd 601219089Spjd if (value < 0) { 602219089Spjd value = -value; 603219089Spjd flags &= ~value; 604219089Spjd } else 605219089Spjd flags |= value; 606219089Spjd ifr.ifr_flags = flags; 607219089Spjd if (ioctl(s, SIOCSIFFLAGS, (caddr_t)&ifr) < 0) 608219089Spjd Perror(vname); 609219089Spjd} 610219089Spjd 611219089Spjdvoid 612219089Spjdsetifmetric(val, dummy) 613219089Spjd const char *val; 614219089Spjd int dummy __unused; 615219089Spjd{ 616219089Spjd strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); 617219089Spjd ifr.ifr_metric = atoi(val); 618219089Spjd if (ioctl(s, SIOCSIFMETRIC, (caddr_t)&ifr) < 0) 619219089Spjd perror("ioctl (set metric)"); 620219089Spjd} 621219089Spjd 622219089Spjdvoid 623219089Spjdsetifmtu(val, dummy) 624219089Spjd const char *val; 625219089Spjd int dummy __unused; 626219089Spjd{ 627219089Spjd strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); 628219089Spjd ifr.ifr_mtu = atoi(val); 629219089Spjd if (ioctl(s, SIOCSIFMTU, (caddr_t)&ifr) < 0) 630219089Spjd perror("ioctl (set mtu)"); 631219089Spjd} 632219089Spjd 633246666Smm#ifdef ISO 634219089Spjdvoid 635219089Spjdsetsnpaoffset(val, dummy) 636219089Spjd char *val; 637219089Spjd int dummy __unused; 638219089Spjd{ 639219089Spjd iso_addreq.ifra_snpaoffset = atoi(val); 640219089Spjd} 641219089Spjd#endif 642219089Spjd 643219089Spjd#define IFFBITS \ 644219089Spjd"\020\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\6b6\7RUNNING" \ 645219089Spjd"\10NOARP\11PROMISC\12ALLMULTI\13OACTIVE\14SIMPLEX\15LINK0\16LINK1\17LINK2" \ 646219089Spjd"\20MULTICAST" 647219089Spjd 648219089Spjd/* 649219089Spjd * Print the status of the interface. If an address family was 650219089Spjd * specified, show it and it only; otherwise, show them all. 651219089Spjd */ 652219089Spjdvoid 653219089Spjdstatus() 654219089Spjd{ 655246666Smm const struct afswtch *p = NULL; 656219089Spjd char *mynext; 657219089Spjd struct if_msghdr *myifm; 658219089Spjd 659219089Spjd printf("%s: ", name); 660219089Spjd printb("flags", flags, IFFBITS); 661219089Spjd if (metric) 662219089Spjd printf(" metric %d", metric); 663219089Spjd if (mtu) 664219089Spjd printf(" mtu %d", mtu); 665219089Spjd putchar('\n'); 666219089Spjd 667246666Smm /* 668219089Spjd * XXX: Sigh. This is bad, I know. At this point, we may have 669219089Spjd * *zero* RTM_NEWADDR's, so we have to "feel the water" before 670219089Spjd * incrementing the loop. One day, I might feel inspired enough 671219089Spjd * to get the top level loop to pass a count down here so we 672219089Spjd * dont have to mess with this. -Peter 673219089Spjd */ 674219089Spjd myifm = ifm; 675219089Spjd 676219089Spjd while (1) { 677219089Spjd 678219089Spjd mynext = next + ifm->ifm_msglen; 679219089Spjd 680219089Spjd if (mynext >= lim) 681219089Spjd break; 682219089Spjd 683219089Spjd myifm = (struct if_msghdr *)mynext; 684219089Spjd 685219089Spjd if (myifm->ifm_type != RTM_NEWADDR) 686219089Spjd break; 687219089Spjd 688219089Spjd next = mynext; 689246666Smm 690219089Spjd ifm = (struct if_msghdr *)next; 691219089Spjd 692219089Spjd ifam = (struct ifa_msghdr *)myifm; 693219089Spjd info.rti_addrs = ifam->ifam_addrs; 694219089Spjd 695219089Spjd /* Expand the compacted addresses */ 696219089Spjd rt_xaddrs((char *)(ifam + 1), ifam->ifam_msglen + (char *)ifam, 697219089Spjd &info); 698219089Spjd 699219089Spjd if (afp) { 700219089Spjd if (afp->af_af == info.rti_info[RTAX_IFA]->sa_family && 701219089Spjd afp->af_status != ether_status) { 702219089Spjd p = afp; 703219089Spjd if (p->af_status != ether_status) 704219089Spjd (*p->af_status)(1); 705219089Spjd } 706219089Spjd } else for (p = afs; p->af_name; p++) { 707219089Spjd if (p->af_af == info.rti_info[RTAX_IFA]->sa_family && 708219089Spjd p->af_status != ether_status) 709219089Spjd (*p->af_status)(0); 710219089Spjd } 711219089Spjd } 712219089Spjd if (afp == NULL || afp->af_status == ether_status) 713219089Spjd ether_status(0); 714219089Spjd else if (afp && !p) { 715219089Spjd warnx("%s has no %s IFA address!", name, afp->af_name); 716219089Spjd } 717219089Spjd} 718219089Spjd 719219089Spjdvoid 720219089Spjdin_status(force) 721219089Spjd int force; 722219089Spjd{ 723219089Spjd struct sockaddr_in *sin, null_sin; 724219089Spjd 725219089Spjd memset(&null_sin, 0, sizeof(null_sin)); 726219089Spjd 727219089Spjd sin = (struct sockaddr_in *)info.rti_info[RTAX_IFA]; 728219089Spjd if (!sin || sin->sin_family != AF_INET) { 729219089Spjd if (!force) 730219089Spjd return; 731219089Spjd /* warnx("%s has no AF_INET IFA address!", name); */ 732219089Spjd sin = &null_sin; 733219089Spjd } 734219089Spjd printf("\tinet %s ", inet_ntoa(sin->sin_addr)); 735219089Spjd 736219089Spjd if (flags & IFF_POINTOPOINT) { 737219089Spjd /* note RTAX_BRD overlap with IFF_BROADCAST */ 738219089Spjd sin = (struct sockaddr_in *)info.rti_info[RTAX_BRD]; 739219089Spjd if (!sin) 740219089Spjd sin = &null_sin; 741219089Spjd printf("--> %s ", inet_ntoa(sin->sin_addr)); 742219089Spjd } 743219089Spjd 744219089Spjd sin = (struct sockaddr_in *)info.rti_info[RTAX_NETMASK]; 745219089Spjd if (!sin) 746219089Spjd sin = &null_sin; 747219089Spjd printf("netmask 0x%lx ", (unsigned long)ntohl(sin->sin_addr.s_addr)); 748219089Spjd 749219089Spjd if (flags & IFF_BROADCAST) { 750219089Spjd /* note RTAX_BRD overlap with IFF_POINTOPOINT */ 751219089Spjd sin = (struct sockaddr_in *)info.rti_info[RTAX_BRD]; 752219089Spjd if (sin && sin->sin_addr.s_addr != 0) 753219089Spjd printf("broadcast %s", inet_ntoa(sin->sin_addr)); 754219089Spjd } 755219089Spjd putchar('\n'); 756219089Spjd} 757219089Spjd 758219089Spjdvoid 759219089Spjdipx_status(force) 760219089Spjd int force; 761219089Spjd{ 762219089Spjd struct sockaddr_ipx *sipx, null_sipx; 763219089Spjd 764219089Spjd close(s); 765219089Spjd s = socket(AF_IPX, SOCK_DGRAM, 0); 766219089Spjd if (s < 0) { 767263397Sdelphij if (errno == EPROTONOSUPPORT) 768219089Spjd return; 769219089Spjd perror("ifconfig: socket"); 770219089Spjd exit(1); 771219089Spjd } 772219089Spjd 773219089Spjd memset(&null_sipx, 0, sizeof(null_sipx)); 774219089Spjd 775219089Spjd sipx = (struct sockaddr_ipx *)info.rti_info[RTAX_IFA]; 776219089Spjd if (!sipx || sipx->sipx_family != AF_IPX) { 777219089Spjd if (!force) 778219089Spjd return; 779219089Spjd warnx("%s has no AF_IPX IFA address!", name); 780219089Spjd sipx = &null_sipx; 781219089Spjd } 782219089Spjd printf("\tipx %s ", ipx_ntoa(sipx->sipx_addr)); 783219089Spjd 784219089Spjd if (flags & IFF_POINTOPOINT) { 785219089Spjd sipx = (struct sockaddr_ipx *)info.rti_info[RTAX_BRD]; 786219089Spjd if (!sipx) 787219089Spjd sipx = &null_sipx; 788219089Spjd printf("--> %s ", ipx_ntoa(sipx->sipx_addr)); 789219089Spjd } 790219089Spjd putchar('\n'); 791219089Spjd 792219089Spjd} 793219089Spjd 794219089Spjdvoid 795219089Spjdat_status(force) 796219089Spjd int force; 797219089Spjd{ 798219089Spjd struct sockaddr_at *sat, null_sat; 799219089Spjd struct netrange *nr; 800219089Spjd 801219089Spjd memset(&null_sat, 0, sizeof(null_sat)); 802219089Spjd 803254112Sdelphij sat = (struct sockaddr_at *)info.rti_info[RTAX_IFA]; 804219089Spjd if (!sat || sat->sat_family != AF_APPLETALK) { 805219089Spjd if (!force) 806219089Spjd return; 807219089Spjd sat = &null_sat; 808219089Spjd } 809219089Spjd nr = &sat->sat_range.r_netrange; 810219089Spjd printf("\tatalk %d.%d range %d-%d phase %d", 811219089Spjd ntohs(sat->sat_addr.s_net), sat->sat_addr.s_node, 812219089Spjd ntohs(nr->nr_firstnet), ntohs(nr->nr_lastnet), nr->nr_phase); 813219089Spjd if (flags & IFF_POINTOPOINT) { 814219089Spjd /* note RTAX_BRD overlap with IFF_BROADCAST */ 815219089Spjd sat = (struct sockaddr_at *)info.rti_info[RTAX_BRD]; 816219089Spjd if (!sat) 817219089Spjd sat = &null_sat; 818219089Spjd printf("--> %d.%d", 819219089Spjd ntohs(sat->sat_addr.s_net), sat->sat_addr.s_node); 820219089Spjd } 821219089Spjd if (flags & IFF_BROADCAST) { 822219089Spjd /* note RTAX_BRD overlap with IFF_POINTOPOINT */ 823219089Spjd sat = (struct sockaddr_at *)info.rti_info[RTAX_BRD]; 824219089Spjd if (sat) 825219089Spjd printf(" broadcast %d.%d", 826219089Spjd ntohs(sat->sat_addr.s_net), 827219089Spjd sat->sat_addr.s_node); 828219089Spjd } 829219089Spjd 830219089Spjd putchar('\n'); 831219089Spjd} 832219089Spjd 833219089Spjd#ifdef NS 834219089Spjdvoid 835219089Spjdxns_status(force) 836219089Spjd int force; 837219089Spjd{ 838219089Spjd struct sockaddr_ns *sns, null_sns; 839219089Spjd 840219089Spjd close(s); 841219089Spjd s = socket(AF_NS, SOCK_DGRAM, 0); 842219089Spjd if (s < 0) { 843219089Spjd if (errno == EPROTONOSUPPORT) 844219089Spjd return; 845219089Spjd perror("ifconfig: socket"); 846219089Spjd exit(1); 847219089Spjd } 848219089Spjd memset(&null_sns, 0, sizeof(null_sns)); 849219089Spjd 850219089Spjd sns = (struct sockaddr_ns *)info.rti_info[RTAX_IFA]; 851219089Spjd if (!sns || sns->sns_family != AF_NS) { 852219089Spjd if (!force) 853219089Spjd return; 854219089Spjd /* warnx("%s has no AF_NS IFA address!", name); */ 855219089Spjd sns = &null_sns; 856219089Spjd } 857219089Spjd printf("\tns %s ", ns_ntoa(sns->sns_addr)); 858219089Spjd 859219089Spjd if (flags & IFF_POINTOPOINT) { 860219089Spjd sns = (struct sockaddr_ns *)info.rti_info[RTAX_BRD]; 861219089Spjd if (!sns) 862219089Spjd sns = &null_sns; 863219089Spjd printf("--> %s ", ns_ntoa(sns->sns_addr)); 864219089Spjd } 865219089Spjd 866219089Spjd putchar('\n'); 867219089Spjd} 868219089Spjd#endif 869219089Spjd 870219089Spjd#ifdef ISO 871219089Spjdvoid 872219089Spjdiso_status(force) 873219089Spjd int force; 874219089Spjd{ 875219089Spjd struct sockaddr_iso *siso, null_siso; 876219089Spjd 877219089Spjd close(s); 878219089Spjd s = socket(AF_ISO, SOCK_DGRAM, 0); 879219089Spjd if (s < 0) { 880219089Spjd if (errno == EPROTONOSUPPORT) 881219089Spjd return; 882219089Spjd perror("ifconfig: socket"); 883219089Spjd exit(1); 884219089Spjd } 885219089Spjd 886219089Spjd memset(&null_siso, 0, sizeof(null_siso)); 887219089Spjd 888219089Spjd siso = (struct sockaddr_iso *)info.rti_info[RTAX_IFA]; 889219089Spjd if (!siso || siso->siso_family != AF_ISO) { 890219089Spjd if (!force) 891219089Spjd return; 892219089Spjd /* warnx("%s has no AF_ISO IFA address!", name); */ 893219089Spjd siso = &null_siso; 894219089Spjd } 895219089Spjd printf("\tiso %s ", iso_ntoa(&siso->siso_addr)); 896219089Spjd 897219089Spjd /* XXX: is this right? is the ISO netmask meant to be before P2P? */ 898219089Spjd siso = (struct sockaddr_iso *)info.rti_info[RTAX_NETMASK]; 899219089Spjd if (siso) 900219089Spjd printf(" netmask %s ", iso_ntoa(&siso->siso_addr)); 901219089Spjd 902219089Spjd if (flags & IFF_POINTOPOINT) { 903219089Spjd siso = (struct sockaddr_iso *)info.rti_info[RTAX_BRD]; 904219089Spjd if (!siso) 905219089Spjd siso = &null_siso; 906219089Spjd printf("--> %s ", iso_ntoa(&siso->siso_addr)); 907219089Spjd } 908219089Spjd 909219089Spjd putchar('\n'); 910219089Spjd} 911219089Spjd#endif 912219089Spjd 913219089Spjdvoid 914219089Spjdether_status(force) 915219089Spjd int force __unused; 916219089Spjd{ 917219089Spjd char *cp; 918219089Spjd int n; 919219089Spjd 920219089Spjd cp = (char *)LLADDR(sdl); 921219089Spjd if ((n = sdl->sdl_alen) > 0) { 922219089Spjd if (sdl->sdl_type == IFT_ETHER) 923219089Spjd printf ("\tether "); 924219089Spjd else 925219089Spjd printf ("\tlladdr "); 926219089Spjd while (--n >= 0) 927219089Spjd printf("%02x%c",*cp++ & 0xff, n>0? ':' : ' '); 928219089Spjd putchar('\n'); 929219089Spjd } 930219089Spjd} 931219089Spjd 932219089Spjdvoid 933219089SpjdPerror(cmd) 934219089Spjd const char *cmd; 935219089Spjd{ 936219089Spjd switch (errno) { 937219089Spjd 938219089Spjd case ENXIO: 939219089Spjd errx(1, "%s: no such interface", cmd); 940219089Spjd break; 941219089Spjd 942219089Spjd case EPERM: 943219089Spjd errx(1, "%s: permission denied", cmd); 944219089Spjd break; 945219089Spjd 946219089Spjd default: 947219089Spjd err(1, "%s", cmd); 948219089Spjd } 949219089Spjd} 950219089Spjd 951219089Spjd#define SIN(x) ((struct sockaddr_in *) &(x)) 952219089Spjdstruct sockaddr_in *sintab[] = { 953219089SpjdSIN(ridreq.ifr_addr), SIN(addreq.ifra_addr), 954219089SpjdSIN(addreq.ifra_mask), SIN(addreq.ifra_broadaddr)}; 955219089Spjd 956219089Spjdvoid 957219089Spjdin_getaddr(s, which) 958219089Spjd const char *s; 959219089Spjd int which; 960219089Spjd{ 961219089Spjd register struct sockaddr_in *sin = sintab[which]; 962219089Spjd struct hostent *hp; 963219089Spjd struct netent *np; 964219089Spjd 965219089Spjd sin->sin_len = sizeof(*sin); 966219089Spjd if (which != MASK) 967219089Spjd sin->sin_family = AF_INET; 968219089Spjd 969219089Spjd if (inet_aton(s, &sin->sin_addr)) 970219089Spjd return; 971219089Spjd if ((hp = gethostbyname(s)) != 0) 972219089Spjd bcopy(hp->h_addr, (char *)&sin->sin_addr, hp->h_length); 973219089Spjd else if ((np = getnetbyname(s)) != 0) 974219089Spjd sin->sin_addr = inet_makeaddr(np->n_net, INADDR_ANY); 975219089Spjd else 976219089Spjd errx(1, "%s: bad value", s); 977219089Spjd} 978219089Spjd 979219089Spjd/* 980219089Spjd * Print a value a la the %b format of the kernel's printf 981219089Spjd */ 982219089Spjdvoid 983219089Spjdprintb(s, v, bits) 984219089Spjd const char *s; 985219089Spjd register unsigned v; 986219089Spjd register const char *bits; 987219089Spjd{ 988248571Smm register int i, any = 0; 989219089Spjd register char c; 990219089Spjd 991219089Spjd if (bits && *bits == 8) 992219089Spjd printf("%s=%o", s, v); 993219089Spjd else 994219089Spjd printf("%s=%x", s, v); 995248571Smm bits++; 996248571Smm if (bits) { 997248571Smm putchar('<'); 998248571Smm while ((i = *bits++) != '\0') { 999219089Spjd if (v & (1 << (i-1))) { 1000219089Spjd if (any) 1001219089Spjd putchar(','); 1002248571Smm any = 1; 1003248571Smm for (; (c = *bits) > 32; bits++) 1004248571Smm putchar(c); 1005248571Smm } else 1006219089Spjd for (; *bits > 32; bits++) 1007248571Smm ; 1008248571Smm } 1009248571Smm putchar('>'); 1010248571Smm } 1011219089Spjd} 1012248571Smm 1013248571Smm#define SIPX(x) ((struct sockaddr_ipx *) &(x)) 1014248571Smmstruct sockaddr_ipx *sipxtab[] = { 1015219089SpjdSIPX(ridreq.ifr_addr), SIPX(addreq.ifra_addr), 1016219089SpjdSIPX(addreq.ifra_mask), SIPX(addreq.ifra_broadaddr)}; 1017219089Spjd 1018219089Spjdvoid 1019219089Spjdipx_getaddr(addr, which) 1020219089Spjd const char *addr; 1021219089Spjd int which; 1022219089Spjd{ 1023219089Spjd struct sockaddr_ipx *sipx = sipxtab[which]; 1024219089Spjd 1025219089Spjd sipx->sipx_family = AF_IPX; 1026219089Spjd sipx->sipx_len = sizeof(*sipx); 1027219089Spjd sipx->sipx_addr = ipx_addr(addr); 1028219089Spjd if (which == MASK) 1029219089Spjd printf("Attempt to set IPX netmask will be ineffectual\n"); 1030219089Spjd} 1031219089Spjd 1032219089Spjdvoid 1033219089Spjdat_getaddr(addr, which) 1034219089Spjd const char *addr; 1035219089Spjd int which; 1036219089Spjd{ 1037219089Spjd struct sockaddr_at *sat = (struct sockaddr_at *) &addreq.ifra_addr; 1038219089Spjd u_int net, node; 1039219089Spjd 1040219089Spjd sat->sat_family = AF_APPLETALK; 1041219089Spjd sat->sat_len = sizeof(*sat); 1042219089Spjd if (which == MASK) 1043219089Spjd errx(1, "AppleTalk does not use netmasks\n"); 1044219089Spjd if (sscanf(addr, "%u.%u", &net, &node) != 2 1045219089Spjd || net > 0xffff || node > 0xfe) 1046219089Spjd errx(1, "%s: illegal address", addr); 1047219089Spjd sat->sat_addr.s_net = htons(net); 1048219089Spjd sat->sat_addr.s_node = node; 1049219089Spjd} 1050219089Spjd 1051219089Spjd/* XXX FIXME -- should use strtoul for better parsing. */ 1052219089Spjdvoid 1053219089Spjdsetatrange(range, dummy) 1054219089Spjd const char *range; 1055219089Spjd int dummy __unused; 1056219089Spjd{ 1057219089Spjd u_short first = 123, last = 123; 1058219089Spjd 1059219089Spjd if (sscanf(range, "%hu-%hu", &first, &last) != 2 1060219089Spjd || first == 0 || first > 0xffff 1061219089Spjd || last == 0 || last > 0xffff || first > last) 1062219089Spjd errx(1, "%s: illegal net range: %u-%u", range, first, last); 1063219089Spjd at_nr.nr_firstnet = htons(first); 1064219089Spjd at_nr.nr_lastnet = htons(last); 1065219089Spjd} 1066219089Spjd 1067219089Spjdvoid 1068219089Spjdsetatphase(phase, dummy) 1069219089Spjd const char *phase; 1070219089Spjd int dummy __unused; 1071219089Spjd{ 1072219089Spjd if (!strcmp(phase, "1")) 1073219089Spjd at_nr.nr_phase = 1; 1074219089Spjd else if (!strcmp(phase, "2")) 1075219089Spjd at_nr.nr_phase = 2; 1076219089Spjd else 1077219089Spjd errx(1, "%s: illegal phase", phase); 1078219089Spjd} 1079219089Spjd 1080219089Spjdvoid 1081219089Spjdcheckatrange(struct sockaddr_at *sat) 1082219089Spjd{ 1083219089Spjd if (at_nr.nr_phase == 0) 1084219089Spjd at_nr.nr_phase = 2; /* Default phase 2 */ 1085219089Spjd if (at_nr.nr_firstnet == 0) 1086219089Spjd at_nr.nr_firstnet = /* Default range of one */ 1087219089Spjd at_nr.nr_lastnet = sat->sat_addr.s_net; 1088219089Spjdprintf("\tatalk %d.%d range %d-%d phase %d\n", 1089219089Spjd ntohs(sat->sat_addr.s_net), sat->sat_addr.s_node, 1090219089Spjd ntohs(at_nr.nr_firstnet), ntohs(at_nr.nr_lastnet), at_nr.nr_phase); 1091219089Spjd if ((u_short) ntohs(at_nr.nr_firstnet) > 1092219089Spjd (u_short) ntohs(sat->sat_addr.s_net) 1093219089Spjd || (u_short) ntohs(at_nr.nr_lastnet) < 1094219089Spjd (u_short) ntohs(sat->sat_addr.s_net)) 1095219089Spjd errx(1, "AppleTalk address is not in range"); 1096219089Spjd sat->sat_range.r_netrange = at_nr; 1097219089Spjd} 1098219089Spjd 1099219089Spjd#ifdef NS 1100219089Spjd#define SNS(x) ((struct sockaddr_ns *) &(x)) 1101219089Spjdstruct sockaddr_ns *snstab[] = { 1102219089SpjdSNS(ridreq.ifr_addr), SNS(addreq.ifra_addr), 1103248571SmmSNS(addreq.ifra_mask), SNS(addreq.ifra_broadaddr)}; 1104219089Spjd 1105219089Spjdvoid 1106248571Smmxns_getaddr(addr, which) 1107219089Spjd const char *addr; 1108219089Spjd int which; 1109219089Spjd{ 1110219089Spjd struct sockaddr_ns *sns = snstab[which]; 1111219089Spjd 1112248571Smm sns->sns_family = AF_NS; 1113248571Smm sns->sns_len = sizeof(*sns); 1114219089Spjd sns->sns_addr = ns_addr(addr); 1115219089Spjd if (which == MASK) 1116219089Spjd printf("Attempt to set XNS netmask will be ineffectual\n"); 1117219089Spjd} 1118219089Spjd#endif 1119219089Spjd 1120219089Spjd#ifdef ISO 1121219089Spjd#define SISO(x) ((struct sockaddr_iso *) &(x)) 1122219089Spjdstruct sockaddr_iso *sisotab[] = { 1123248571SmmSISO(iso_ridreq.ifr_Addr), SISO(iso_addreq.ifra_addr), 1124219089SpjdSISO(iso_addreq.ifra_mask), SISO(iso_addreq.ifra_dstaddr)}; 1125219089Spjd 1126219089Spjdvoid 1127219089Spjdiso_getaddr(addr, which) 1128219089Spjdchar *addr; 1129219089Spjd{ 1130248571Smm register struct sockaddr_iso *siso = sisotab[which]; 1131219089Spjd struct iso_addr *iso_addr(); 1132219089Spjd siso->siso_addr = *iso_addr(addr); 1133219089Spjd 1134219089Spjd if (which == MASK) { 1135219089Spjd siso->siso_len = TSEL(siso) - (caddr_t)(siso); 1136219089Spjd siso->siso_nlen = 0; 1137219089Spjd } else { 1138219089Spjd siso->siso_len = sizeof(*siso); 1139219089Spjd siso->siso_family = AF_ISO; 1140219089Spjd } 1141219089Spjd} 1142219089Spjd 1143219089Spjdvoid 1144219089Spjdsetnsellength(val) 1145219089Spjd char *val; 1146219089Spjd{ 1147219089Spjd nsellength = atoi(val); 1148219089Spjd if (nsellength < 0) 1149219089Spjd errx(1, "Negative NSEL length is absurd"); 1150219089Spjd if (afp == 0 || afp->af_af != AF_ISO) 1151219089Spjd errx(1, "Setting NSEL length valid only for iso"); 1152219089Spjd} 1153219089Spjd 1154219089Spjdvoid 1155219089Spjdfixnsel(s) 1156219089Spjdregister struct sockaddr_iso *s; 1157219089Spjd{ 1158219089Spjd if (s->siso_family == 0) 1159219089Spjd return; 1160219089Spjd s->siso_tlen = nsellength; 1161219089Spjd} 1162219089Spjd 1163219089Spjdvoid 1164219089Spjdadjust_nsellength() 1165219089Spjd{ 1166219089Spjd fixnsel(sisotab[RIDADDR]); 1167219089Spjd fixnsel(sisotab[ADDR]); 1168219089Spjd fixnsel(sisotab[DSTADDR]); 1169219089Spjd} 1170219089Spjd#endif 1171219089Spjd