ifconfig.c (134609) | ifconfig.c (138593) |
---|---|
1/* 2 * Copyright (c) 1983, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 24 unchanged lines hidden (view full) --- 33 The Regents of the University of California. All rights reserved.\n"; 34#endif /* not lint */ 35 36#ifndef lint 37#if 0 38static char sccsid[] = "@(#)ifconfig.c 8.2 (Berkeley) 2/16/94"; 39#endif 40static const char rcsid[] = | 1/* 2 * Copyright (c) 1983, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 24 unchanged lines hidden (view full) --- 33 The Regents of the University of California. All rights reserved.\n"; 34#endif /* not lint */ 35 36#ifndef lint 37#if 0 38static char sccsid[] = "@(#)ifconfig.c 8.2 (Berkeley) 2/16/94"; 39#endif 40static const char rcsid[] = |
41 "$FreeBSD: head/sbin/ifconfig/ifconfig.c 134609 2004-09-01 18:22:14Z brooks $"; | 41 "$FreeBSD: head/sbin/ifconfig/ifconfig.c 138593 2004-12-08 19:18:07Z sam $"; |
42#endif /* not lint */ 43 44#include <sys/param.h> 45#include <sys/ioctl.h> 46#include <sys/socket.h> 47#include <sys/sysctl.h> 48#include <sys/time.h> 49#include <sys/module.h> --- 7 unchanged lines hidden (view full) --- 57#include <net/route.h> 58 59/* IP */ 60#include <netinet/in.h> 61#include <netinet/in_var.h> 62#include <arpa/inet.h> 63#include <netdb.h> 64 | 42#endif /* not lint */ 43 44#include <sys/param.h> 45#include <sys/ioctl.h> 46#include <sys/socket.h> 47#include <sys/sysctl.h> 48#include <sys/time.h> 49#include <sys/module.h> --- 7 unchanged lines hidden (view full) --- 57#include <net/route.h> 58 59/* IP */ 60#include <netinet/in.h> 61#include <netinet/in_var.h> 62#include <arpa/inet.h> 63#include <netdb.h> 64 |
65#ifdef INET6 66#include <netinet6/nd6.h> /* Define ND6_INFINITE_LIFETIME */ 67#endif 68 69#ifndef NO_IPX 70/* IPX */ 71#define IPXIP 72#define IPTUNNEL 73#include <netipx/ipx.h> 74#include <netipx/ipx_if.h> 75#endif 76 77/* Appletalk */ 78#include <netatalk/at.h> 79 | |
80#include <ctype.h> 81#include <err.h> 82#include <errno.h> 83#include <fcntl.h> 84#include <stdio.h> 85#include <stdlib.h> 86#include <string.h> 87#include <unistd.h> | 65#include <ctype.h> 66#include <err.h> 67#include <errno.h> 68#include <fcntl.h> 69#include <stdio.h> 70#include <stdlib.h> 71#include <string.h> 72#include <unistd.h> |
88#include <ifaddrs.h> | |
89 90#include "ifconfig.h" 91 | 73 74#include "ifconfig.h" 75 |
92/* wrapper for KAME-special getnameinfo() */ 93#ifndef NI_WITHSCOPEID 94#define NI_WITHSCOPEID 0 95#endif 96 | |
97/* 98 * Since "struct ifreq" is composed of various union members, callers 99 * should pay special attention to interprete the value. 100 * (.e.g. little/big endian difference in the structure.) 101 */ | 76/* 77 * Since "struct ifreq" is composed of various union members, callers 78 * should pay special attention to interprete the value. 79 * (.e.g. little/big endian difference in the structure.) 80 */ |
102struct ifreq ifr, ridreq; 103struct ifaliasreq addreq; 104#ifdef INET6 105struct in6_ifreq in6_ridreq; 106struct in6_aliasreq in6_addreq = 107 { { 0 }, 108 { 0 }, 109 { 0 }, 110 { 0 }, 111 0, 112 { 0, 0, ND6_INFINITE_LIFETIME, ND6_INFINITE_LIFETIME } }; 113#endif 114struct sockaddr_in netmask; 115struct netrange at_nr; /* AppleTalk net range */ | 81struct ifreq ifr; |
116 117char name[IFNAMSIZ]; 118int flags; 119int setaddr; 120int setipdst; 121int setmask; 122int doalias; 123int clearaddr; 124int newaddr = 1; | 82 83char name[IFNAMSIZ]; 84int flags; 85int setaddr; 86int setipdst; 87int setmask; 88int doalias; 89int clearaddr; 90int newaddr = 1; |
125#ifdef INET6 126static int ip6lifetime; 127#endif | 91int verbose; |
128 | 92 |
129struct afswtch; | 93int supmedia = 0; 94int printname = 0; /* Print the name of the created interface. */ |
130 | 95 |
131int supmedia = 0; 132int listcloners = 0; 133int printname = 0; /* Print the name of the created interface. */ 134 135#ifdef INET6 136char addr_buf[MAXHOSTNAMELEN *2 + 1]; /*for getnameinfo()*/ 137#endif 138 139void Perror(const char *cmd); 140void checkatrange(struct sockaddr_at *); 141int ifconfig(int argc, char *const *argv, const struct afswtch *afp); 142void notealias(const char *, int, int, const struct afswtch *afp); 143void list_cloners(void); 144void printb(const char *s, unsigned value, const char *bits); 145void rt_xaddrs(caddr_t, caddr_t, struct rt_addrinfo *); 146void status(const struct afswtch *afp, int addrcount, | 96static int ifconfig(int argc, char *const *argv, const struct afswtch *afp); 97static void status(const struct afswtch *afp, int addrcount, |
147 struct sockaddr_dl *sdl, struct if_msghdr *ifm, 148 struct ifa_msghdr *ifam); | 98 struct sockaddr_dl *sdl, struct if_msghdr *ifm, 99 struct ifa_msghdr *ifam); |
149void tunnel_status(int s); 150void usage(void); 151void ifmaybeload(char *name); | 100static void tunnel_status(int s); 101static void usage(void); |
152 | 102 |
153#ifdef INET6 154void in6_fillscopeid(struct sockaddr_in6 *sin6); 155int prefix(void *, int); 156static char *sec2str(time_t); 157int explicit_prefix = 0; 158#endif | 103static struct afswtch *af_getbyname(const char *name); 104static struct afswtch *af_getbyfamily(int af); 105static void af_all_status(int, const struct rt_addrinfo *sdl); |
159 | 106 |
160typedef void c_func(const char *cmd, int arg, int s, const struct afswtch *afp); 161typedef void c_func2(const char *arg, const char *arg2, int s, const struct afswtch *afp); 162c_func setatphase, setatrange; 163c_func setifaddr, setifbroadaddr, setifdstaddr, setifnetmask; 164c_func2 settunnel; 165c_func deletetunnel; 166#ifdef INET6 167c_func setifprefixlen; 168c_func setip6flags; 169c_func setip6pltime; 170c_func setip6vltime; 171c_func2 setip6lifetime; 172c_func setip6eui64; 173#endif 174c_func setifipdst; 175c_func setifflags, setifmetric, setifmtu, setifcap; 176c_func clone_destroy; 177c_func setifname; | 107static struct option *opts = NULL; |
178 | 108 |
179 180void clone_create(void); 181 182 183#define NEXTARG 0xffffff 184#define NEXTARG2 0xfffffe 185 186const 187struct cmd { 188 const char *c_name; 189 int c_parameter; /* NEXTARG means next argv */ 190 void (*c_func)(const char *, int, int, const struct afswtch *afp); 191 void (*c_func2)(const char *, const char *, int, const struct afswtch *afp); 192} cmds[] = { 193 { "up", IFF_UP, setifflags } , 194 { "down", -IFF_UP, setifflags }, 195 { "arp", -IFF_NOARP, setifflags }, 196 { "-arp", IFF_NOARP, setifflags }, 197 { "debug", IFF_DEBUG, setifflags }, 198 { "-debug", -IFF_DEBUG, setifflags }, 199 { "promisc", IFF_PPROMISC, setifflags }, 200 { "-promisc", -IFF_PPROMISC, setifflags }, 201 { "add", IFF_UP, notealias }, 202 { "alias", IFF_UP, notealias }, 203 { "-alias", -IFF_UP, notealias }, 204 { "delete", -IFF_UP, notealias }, 205 { "remove", -IFF_UP, notealias }, 206#ifdef notdef 207#define EN_SWABIPS 0x1000 208 { "swabips", EN_SWABIPS, setifflags }, 209 { "-swabips", -EN_SWABIPS, setifflags }, 210#endif 211 { "netmask", NEXTARG, setifnetmask }, 212#ifdef INET6 213 { "prefixlen", NEXTARG, setifprefixlen }, 214 { "anycast", IN6_IFF_ANYCAST, setip6flags }, 215 { "tentative", IN6_IFF_TENTATIVE, setip6flags }, 216 { "-tentative", -IN6_IFF_TENTATIVE, setip6flags }, 217 { "deprecated", IN6_IFF_DEPRECATED, setip6flags }, 218 { "-deprecated", -IN6_IFF_DEPRECATED, setip6flags }, 219 { "autoconf", IN6_IFF_AUTOCONF, setip6flags }, 220 { "-autoconf", -IN6_IFF_AUTOCONF, setip6flags }, 221 { "pltime", NEXTARG, setip6pltime }, 222 { "vltime", NEXTARG, setip6vltime }, 223 { "eui64", 0, setip6eui64 }, 224#endif 225 { "range", NEXTARG, setatrange }, 226 { "phase", NEXTARG, setatphase }, 227 { "metric", NEXTARG, setifmetric }, 228 { "broadcast", NEXTARG, setifbroadaddr }, 229 { "ipdst", NEXTARG, setifipdst }, 230 { "tunnel", NEXTARG2, NULL, settunnel }, 231 { "deletetunnel", 0, deletetunnel }, 232 { "link0", IFF_LINK0, setifflags }, 233 { "-link0", -IFF_LINK0, setifflags }, 234 { "link1", IFF_LINK1, setifflags }, 235 { "-link1", -IFF_LINK1, setifflags }, 236 { "link2", IFF_LINK2, setifflags }, 237 { "-link2", -IFF_LINK2, setifflags }, 238 { "monitor", IFF_MONITOR, setifflags }, 239 { "-monitor", -IFF_MONITOR, setifflags }, 240 { "staticarp", IFF_STATICARP, setifflags }, 241 { "-staticarp", -IFF_STATICARP, setifflags }, 242#ifdef USE_IF_MEDIA 243 { "media", NEXTARG, setmedia }, 244 { "mode", NEXTARG, setmediamode }, 245 { "mediaopt", NEXTARG, setmediaopt }, 246 { "-mediaopt", NEXTARG, unsetmediaopt }, 247#endif 248#ifdef USE_VLANS 249 { "vlan", NEXTARG, setvlantag }, 250 { "vlandev", NEXTARG, setvlandev }, 251 { "-vlandev", NEXTARG, unsetvlandev }, 252#endif 253#if 0 254 /* XXX `create' special-cased below */ 255 {"create", 0, clone_create }, 256 {"plumb", 0, clone_create }, 257#endif 258 {"destroy", 0, clone_destroy }, 259 {"unplumb", 0, clone_destroy }, 260#ifdef USE_IEEE80211 261 { "ssid", NEXTARG, set80211ssid }, 262 { "nwid", NEXTARG, set80211ssid }, 263 { "stationname", NEXTARG, set80211stationname }, 264 { "station", NEXTARG, set80211stationname }, /* BSD/OS */ 265 { "channel", NEXTARG, set80211channel }, 266 { "authmode", NEXTARG, set80211authmode }, 267 { "powersavemode", NEXTARG, set80211powersavemode }, 268 { "powersave", 1, set80211powersave }, 269 { "-powersave", 0, set80211powersave }, 270 { "powersavesleep", NEXTARG, set80211powersavesleep }, 271 { "wepmode", NEXTARG, set80211wepmode }, 272 { "wep", 1, set80211wep }, 273 { "-wep", 0, set80211wep }, 274 { "weptxkey", NEXTARG, set80211weptxkey }, 275 { "wepkey", NEXTARG, set80211wepkey }, 276 { "nwkey", NEXTARG, set80211nwkey }, /* NetBSD */ 277 { "-nwkey", 0, set80211wep }, /* NetBSD */ 278 { "rtsthreshold",NEXTARG, set80211rtsthreshold }, 279 { "protmode", NEXTARG, set80211protmode }, 280 { "txpower", NEXTARG, set80211txpower }, 281#endif 282#ifdef USE_MAC 283 { "maclabel", NEXTARG, setifmaclabel }, 284#endif 285 { "rxcsum", IFCAP_RXCSUM, setifcap }, 286 { "-rxcsum", -IFCAP_RXCSUM, setifcap }, 287 { "txcsum", IFCAP_TXCSUM, setifcap }, 288 { "-txcsum", -IFCAP_TXCSUM, setifcap }, 289 { "netcons", IFCAP_NETCONS, setifcap }, 290 { "-netcons", -IFCAP_NETCONS, setifcap }, 291 { "polling", IFCAP_POLLING, setifcap }, 292 { "-polling", -IFCAP_POLLING, setifcap }, 293 { "vlanmtu", IFCAP_VLAN_MTU, setifcap }, 294 { "-vlanmtu", -IFCAP_VLAN_MTU, setifcap }, 295 { "vlanhwtag", IFCAP_VLAN_HWTAGGING, setifcap }, 296 { "-vlanhwtag", -IFCAP_VLAN_HWTAGGING, setifcap }, 297 { "normal", -IFF_LINK0, setifflags }, 298 { "compress", IFF_LINK0, setifflags }, 299 { "noicmp", IFF_LINK1, setifflags }, 300 { "mtu", NEXTARG, setifmtu }, 301 { "name", NEXTARG, setifname }, 302 { 0, 0, setifaddr }, 303 { 0, 0, setifdstaddr }, 304}; 305 306/* 307 * XNS support liberally adapted from code written at the University of 308 * Maryland principally by James O'Toole and Chris Torek. 309 */ 310typedef void af_status(int, struct rt_addrinfo *); 311typedef void af_getaddr(const char *, int); 312typedef void af_getprefix(const char *, int); 313 314af_status in_status, at_status, link_status; 315af_getaddr in_getaddr, at_getaddr, link_getaddr; 316 317#ifndef NO_IPX 318af_status ipx_status; 319af_getaddr ipx_getaddr; 320#endif 321 322#ifdef INET6 323af_status in6_status; 324af_getaddr in6_getaddr; 325af_getprefix in6_getprefix; 326#endif /*INET6*/ 327 328/* Known address families */ 329const 330struct afswtch { 331 const char *af_name; 332 short af_af; 333 af_status *af_status; 334 af_getaddr *af_getaddr; 335 af_getprefix *af_getprefix; 336 u_long af_difaddr; 337 u_long af_aifaddr; 338 caddr_t af_ridreq; 339 caddr_t af_addreq; 340} afs[] = { 341#define C(x) ((caddr_t) &x) 342 { "inet", AF_INET, in_status, in_getaddr, NULL, 343 SIOCDIFADDR, SIOCAIFADDR, C(ridreq), C(addreq) }, 344#ifdef INET6 345 { "inet6", AF_INET6, in6_status, in6_getaddr, in6_getprefix, 346 SIOCDIFADDR_IN6, SIOCAIFADDR_IN6, 347 C(in6_ridreq), C(in6_addreq) }, 348#endif /*INET6*/ 349#ifndef NO_IPX 350 { "ipx", AF_IPX, ipx_status, ipx_getaddr, NULL, 351 SIOCDIFADDR, SIOCAIFADDR, C(ridreq), C(addreq) }, 352#endif 353 { "atalk", AF_APPLETALK, at_status, at_getaddr, NULL, 354 SIOCDIFADDR, SIOCAIFADDR, C(addreq), C(addreq) }, 355 { "link", AF_LINK, link_status, link_getaddr, NULL, 356 0, SIOCSIFLLADDR, NULL, C(ridreq) }, 357 { "ether", AF_LINK, link_status, link_getaddr, NULL, 358 0, SIOCSIFLLADDR, NULL, C(ridreq) }, 359 { "lladdr", AF_LINK, link_status, link_getaddr, NULL, 360 0, SIOCSIFLLADDR, NULL, C(ridreq) }, 361#if 0 /* XXX conflicts with the media command */ 362#ifdef USE_IF_MEDIA 363 { "media", AF_UNSPEC, media_status, NULL, NULL, }, /* XXX not real!! */ 364#endif 365#ifdef USE_VLANS 366 { "vlan", AF_UNSPEC, vlan_status, NULL, NULL, }, /* XXX not real!! */ 367#endif 368#ifdef USE_IEEE80211 369 { "ieee80211", AF_UNSPEC, ieee80211_status, NULL, NULL, }, /* XXX not real!! */ 370#endif 371#ifdef USE_MAC 372 { "maclabel", AF_UNSPEC, maclabel_status, NULL, NULL, }, 373#endif 374#endif 375 { 0, 0, 0, 0 } 376}; 377 378/* 379 * Expand the compacted form of addresses as returned via the 380 * configuration read via sysctl(). 381 */ 382 | |
383void | 109void |
384rt_xaddrs(caddr_t cp, caddr_t cplim, struct rt_addrinfo *rtinfo) | 110opt_register(struct option *p) |
385{ | 111{ |
386 struct sockaddr *sa; 387 int i; 388 389 memset(rtinfo->rti_info, 0, sizeof(rtinfo->rti_info)); 390 for (i = 0; (i < RTAX_MAX) && (cp < cplim); i++) { 391 if ((rtinfo->rti_addrs & (1 << i)) == 0) 392 continue; 393 rtinfo->rti_info[i] = sa = (struct sockaddr *)cp; 394 cp += SA_SIZE(sa); 395 } | 112 p->next = opts; 113 opts = p; |
396} 397 | 114} 115 |
398 399void | 116static void |
400usage(void) 401{ | 117usage(void) 118{ |
402#ifndef INET6 403 fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n", 404 "usage: ifconfig interface address_family [address [dest_address]]", 405 " [parameters]", 406 " ifconfig -C", 407 " ifconfig interface create", 408 " ifconfig -a [-d] [-m] [-u] [address_family]", 409 " ifconfig -l [-d] [-u] [address_family]", 410 " ifconfig [-d] [-m] [-u]"); 411#else 412 fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n", 413 "usage: ifconfig [-L] interface address_family [address [dest_address]]", 414 " [parameters]", 415 " ifconfig -C", 416 " ifconfig interface create", 417 " ifconfig -a [-L] [-d] [-m] [-u] [address_family]", 418 " ifconfig -l [-d] [-u] [address_family]", 419 " ifconfig [-L] [-d] [-m] [-u]"); 420#endif | 119 char options[1024]; 120 struct option *p; 121 122 /* XXX not right but close enough for now */ 123 options[0] = '\0'; 124 for (p = opts; p != NULL; p = p->next) { 125 strlcat(options, p->opt_usage, sizeof(options)); 126 strlcat(options, " ", sizeof(options)); 127 } 128 129 fprintf(stderr, 130 "usage: ifconfig %sinterface address_family [address [dest_address]]\n" 131 " [parameters]\n" 132 " ifconfig interface create\n" 133 " ifconfig -a %s[-d] [-m] [-u] [-v] [address_family]\n" 134 " ifconfig -l [-d] [-u] [address_family]\n" 135 " ifconfig %s[-d] [-m] [-u] [-v]\n", 136 options, options, options); |
421 exit(1); 422} 423 424int 425main(int argc, char *argv[]) 426{ | 137 exit(1); 138} 139 140int 141main(int argc, char *argv[]) 142{ |
427 int c; 428 int all, namesonly, downonly, uponly; | 143 int c, all, namesonly, downonly, uponly; |
429 int need_nl = 0, count = 0; | 144 int need_nl = 0, count = 0; |
430 const struct afswtch *afp = 0; | 145 const struct afswtch *afp = NULL; |
431 int addrcount, ifindex; | 146 int addrcount, ifindex; |
432 struct if_msghdr *ifm, *nextifm; 433 struct ifa_msghdr *ifam; 434 struct sockaddr_dl *sdl; 435 char *buf, *lim, *next; | 147 struct if_msghdr *ifm, *nextifm; 148 struct ifa_msghdr *ifam; 149 struct sockaddr_dl *sdl; 150 char *buf, *lim, *next; |
436 size_t needed; 437 int mib[6]; | 151 size_t needed; 152 int mib[6]; |
153 char options[1024]; 154 struct option *p; |
|
438 | 155 |
156 all = downonly = uponly = namesonly = verbose = 0; 157 |
|
439 /* Parse leading line options */ | 158 /* Parse leading line options */ |
440 all = downonly = uponly = namesonly = 0; 441 while ((c = getopt(argc, argv, "adlmuC" 442#ifdef INET6 443 "L" 444#endif 445 )) != -1) { | 159 strlcpy(options, "adlmuv", sizeof(options)); 160 for (p = opts; p != NULL; p = p->next) 161 strlcat(options, p->opt, sizeof(options)); 162 while ((c = getopt(argc, argv, options)) != -1) { |
446 switch (c) { 447 case 'a': /* scan all interfaces */ 448 all++; 449 break; 450 case 'd': /* restrict scan to "down" interfaces */ 451 downonly++; 452 break; 453 case 'l': /* scan interface names only */ 454 namesonly++; 455 break; 456 case 'm': /* show media choices in status */ 457 supmedia = 1; 458 break; 459 case 'u': /* restrict scan to "up" interfaces */ 460 uponly++; 461 break; | 163 switch (c) { 164 case 'a': /* scan all interfaces */ 165 all++; 166 break; 167 case 'd': /* restrict scan to "down" interfaces */ 168 downonly++; 169 break; 170 case 'l': /* scan interface names only */ 171 namesonly++; 172 break; 173 case 'm': /* show media choices in status */ 174 supmedia = 1; 175 break; 176 case 'u': /* restrict scan to "up" interfaces */ 177 uponly++; 178 break; |
462 case 'C': 463 listcloners = 1; | 179 case 'v': 180 verbose++; |
464 break; | 181 break; |
465#ifdef INET6 466 case 'L': 467 ip6lifetime++; /* print IPv6 address lifetime */ 468 break; 469#endif | |
470 default: | 182 default: |
471 usage(); | 183 for (p = opts; p != NULL; p = p->next) 184 if (p->opt[0] == c) { 185 p->cb(optarg); 186 break; 187 } 188 if (p == NULL) 189 usage(); |
472 break; 473 } 474 } 475 argc -= optind; 476 argv += optind; 477 | 190 break; 191 } 192 } 193 argc -= optind; 194 argv += optind; 195 |
478 if (listcloners) { 479 /* -C must be solitary */ 480 if (all || supmedia || uponly || downonly || namesonly || 481 argc > 0) 482 usage(); 483 484 list_cloners(); 485 exit(0); 486 } 487 | |
488 /* -l cannot be used with -a or -m */ 489 if (namesonly && (all || supmedia)) 490 usage(); 491 492 /* nonsense.. */ 493 if (uponly && downonly) 494 usage(); 495 496 /* no arguments is equivalent to '-a' */ 497 if (!namesonly && argc < 1) 498 all = 1; 499 500 /* -a and -l allow an address family arg to limit the output */ 501 if (all || namesonly) { 502 if (argc > 1) 503 usage(); 504 505 ifindex = 0; 506 if (argc == 1) { | 196 /* -l cannot be used with -a or -m */ 197 if (namesonly && (all || supmedia)) 198 usage(); 199 200 /* nonsense.. */ 201 if (uponly && downonly) 202 usage(); 203 204 /* no arguments is equivalent to '-a' */ 205 if (!namesonly && argc < 1) 206 all = 1; 207 208 /* -a and -l allow an address family arg to limit the output */ 209 if (all || namesonly) { 210 if (argc > 1) 211 usage(); 212 213 ifindex = 0; 214 if (argc == 1) { |
507 for (afp = afs; afp->af_name; afp++) 508 if (strcmp(afp->af_name, *argv) == 0) { 509 argc--, argv++; 510 break; 511 } 512 if (afp->af_name == NULL) | 215 afp = af_getbyname(*argv); 216 if (afp == NULL) |
513 usage(); | 217 usage(); |
218 if (afp->af_name != NULL) 219 argc--, argv++; |
|
514 /* leave with afp non-zero */ 515 } 516 } else { 517 /* not listing, need an argument */ 518 if (argc < 1) 519 usage(); 520 521 strncpy(name, *argv, sizeof(name)); --- 16 unchanged lines hidden (view full) --- 538 } 539 ifindex = if_nametoindex(name); 540 if (ifindex == 0) 541 errx(1, "interface %s does not exist", name); 542 } 543 544 /* Check for address family */ 545 if (argc > 0) { | 220 /* leave with afp non-zero */ 221 } 222 } else { 223 /* not listing, need an argument */ 224 if (argc < 1) 225 usage(); 226 227 strncpy(name, *argv, sizeof(name)); --- 16 unchanged lines hidden (view full) --- 244 } 245 ifindex = if_nametoindex(name); 246 if (ifindex == 0) 247 errx(1, "interface %s does not exist", name); 248 } 249 250 /* Check for address family */ 251 if (argc > 0) { |
546 for (afp = afs; afp->af_name; afp++) 547 if (strcmp(afp->af_name, *argv) == 0) { 548 argc--, argv++; 549 break; 550 } 551 if (afp->af_name == NULL) 552 afp = NULL; /* not a family, NULL */ | 252 afp = af_getbyname(*argv); 253 if (afp != NULL) 254 argc--, argv++; |
553 } 554 555retry: 556 mib[0] = CTL_NET; 557 mib[1] = PF_ROUTE; 558 mib[2] = 0; 559 mib[3] = 0; /* address family */ 560 mib[4] = NET_RT_IFLIST; 561 mib[5] = ifindex; /* interface index */ 562 563 /* if particular family specified, only ask about it */ | 255 } 256 257retry: 258 mib[0] = CTL_NET; 259 mib[1] = PF_ROUTE; 260 mib[2] = 0; 261 mib[3] = 0; /* address family */ 262 mib[4] = NET_RT_IFLIST; 263 mib[5] = ifindex; /* interface index */ 264 265 /* if particular family specified, only ask about it */ |
564 if (afp) | 266 if (afp != NULL) |
565 mib[3] = afp->af_af; 566 567 if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) 568 errx(1, "iflist-sysctl-estimate"); 569 if ((buf = malloc(needed)) == NULL) 570 errx(1, "malloc"); 571 if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) { 572 if (errno == ENOMEM && count++ < 10) { --- 52 unchanged lines hidden (view full) --- 625 if (all || namesonly) { 626 if (uponly) 627 if ((flags & IFF_UP) == 0) 628 continue; /* not up */ 629 if (downonly) 630 if (flags & IFF_UP) 631 continue; /* not down */ 632 if (namesonly) { | 267 mib[3] = afp->af_af; 268 269 if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) 270 errx(1, "iflist-sysctl-estimate"); 271 if ((buf = malloc(needed)) == NULL) 272 errx(1, "malloc"); 273 if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) { 274 if (errno == ENOMEM && count++ < 10) { --- 52 unchanged lines hidden (view full) --- 327 if (all || namesonly) { 328 if (uponly) 329 if ((flags & IFF_UP) == 0) 330 continue; /* not up */ 331 if (downonly) 332 if (flags & IFF_UP) 333 continue; /* not down */ 334 if (namesonly) { |
633 if (afp == NULL || 634 afp->af_status != link_status || 635 sdl->sdl_type == IFT_ETHER) { | 335 if (afp == NULL || afp->af_af != AF_LINK || 336 sdl->sdl_type == IFT_ETHER) { |
636 if (need_nl) 637 putchar(' '); 638 fputs(name, stdout); 639 need_nl++; 640 } 641 continue; 642 } 643 } --- 9 unchanged lines hidden (view full) --- 653 putchar('\n'); 654end: 655 if (printname) 656 printf("%s\n", name); 657 658 exit (0); 659} 660 | 337 if (need_nl) 338 putchar(' '); 339 fputs(name, stdout); 340 need_nl++; 341 } 342 continue; 343 } 344 } --- 9 unchanged lines hidden (view full) --- 354 putchar('\n'); 355end: 356 if (printname) 357 printf("%s\n", name); 358 359 exit (0); 360} 361 |
661int | 362static struct afswtch *afs = NULL; 363 364void 365af_register(struct afswtch *p) 366{ 367 p->af_next = afs; 368 afs = p; 369} 370 371static struct afswtch * 372af_getbyname(const char *name) 373{ 374 struct afswtch *afp; 375 376 for (afp = afs; afp != NULL; afp = afp->af_next) 377 if (strcmp(afp->af_name, name) == 0) 378 return afp; 379 return NULL; 380} 381 382static struct afswtch * 383af_getbyfamily(int af) 384{ 385 struct afswtch *afp; 386 387 for (afp = afs; afp != NULL; afp = afp->af_next) 388 if (afp->af_af == af) 389 return afp; 390 return NULL; 391} 392 393static void 394af_all_status(int s, const struct rt_addrinfo *sdl) 395{ 396 struct afswtch *afp; 397 uint8_t afmask[howmany(AF_MAX, NBBY)]; 398 399 memset(afmask, 0, sizeof(afmask)); 400 for (afp = afs; afp != NULL; afp = afp->af_next) { 401 if (afp->af_status == NULL) 402 continue; 403 if (afp->af_af != AF_UNSPEC && isset(afmask, afp->af_af)) 404 continue; 405 afp->af_status(s, sdl); 406 setbit(afmask, afp->af_af); 407 } 408} 409 410static void 411af_all_tunnel_status(int s) 412{ 413 struct afswtch *afp; 414 uint8_t afmask[howmany(AF_MAX, NBBY)]; 415 416 memset(afmask, 0, sizeof(afmask)); 417 for (afp = afs; afp != NULL; afp = afp->af_next) { 418 if (afp->af_status_tunnel == NULL) 419 continue; 420 if (afp->af_af != AF_UNSPEC && isset(afmask, afp->af_af)) 421 continue; 422 afp->af_status_tunnel(s); 423 setbit(afmask, afp->af_af); 424 } 425} 426 427static struct cmd *cmds = NULL; 428 429void 430cmd_register(struct cmd *p) 431{ 432 p->c_next = cmds; 433 cmds = p; 434} 435 436static const struct cmd * 437cmd_lookup(const char *name) 438{ 439#define N(a) (sizeof(a)/sizeof(a[0])) 440 const struct cmd *p; 441 442 for (p = cmds; p != NULL; p = p->c_next) 443 if (strcmp(name, p->c_name) == 0) 444 return p; 445 return NULL; 446#undef N 447} 448 449/* specially-handled comamnds */ 450static void setifaddr(const char *, int, int, const struct afswtch *); 451static const struct cmd setifaddr_cmd = DEF_CMD("ifaddr", 0, setifaddr); 452 453static void setifdstaddr(const char *, int, int, const struct afswtch *); 454static const struct cmd setifdstaddr_cmd = 455 DEF_CMD("ifdstaddr", 0, setifdstaddr); 456 457static int |
662ifconfig(int argc, char *const *argv, const struct afswtch *afp) 663{ | 458ifconfig(int argc, char *const *argv, const struct afswtch *afp) 459{ |
664 int af, s; | 460 int s; |
665 666 if (afp == NULL) | 461 462 if (afp == NULL) |
667 afp = &afs[0]; 668 af = afp->af_af == AF_LINK ? AF_INET : afp->af_af; 669 ifr.ifr_addr.sa_family = af; | 463 afp = af_getbyname("inet"); 464 ifr.ifr_addr.sa_family = 465 afp->af_af == AF_LINK || afp->af_af == AF_UNSPEC ? 466 AF_INET : afp->af_af; |
670 strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name); 671 | 467 strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name); 468 |
672 if ((s = socket(af, SOCK_DGRAM, 0)) < 0) 673 err(1, "socket"); | 469 if ((s = socket(ifr.ifr_addr.sa_family, SOCK_DGRAM, 0)) < 0) 470 err(1, "socket(family %u,SOCK_DGRAM", ifr.ifr_addr.sa_family); |
674 675 while (argc > 0) { 676 const struct cmd *p; 677 | 471 472 while (argc > 0) { 473 const struct cmd *p; 474 |
678 for (p = cmds; p->c_name; p++) 679 if (strcmp(*argv, p->c_name) == 0) 680 break; 681 if (p->c_name == 0 && setaddr) 682 p++; /* got src, do dst */ | 475 p = cmd_lookup(*argv); 476 if (p == NULL) { 477 /* 478 * Not a recognized command, choose between setting 479 * the interface address and the dst address. 480 */ 481 p = (setaddr ? &setifdstaddr_cmd : &setifaddr_cmd); 482 } |
683 if (p->c_func || p->c_func2) { 684 if (p->c_parameter == NEXTARG) { 685 if (argv[1] == NULL) 686 errx(1, "'%s' requires argument", 687 p->c_name); | 483 if (p->c_func || p->c_func2) { 484 if (p->c_parameter == NEXTARG) { 485 if (argv[1] == NULL) 486 errx(1, "'%s' requires argument", 487 p->c_name); |
688 (*p->c_func)(argv[1], 0, s, afp); | 488 p->c_func(argv[1], 0, s, afp); |
689 argc--, argv++; | 489 argc--, argv++; |
490 } else if (p->c_parameter == OPTARG) { 491 p->c_func(argv[1], 0, s, afp); 492 if (argv[1] != NULL) 493 argc--, argv++; |
|
690 } else if (p->c_parameter == NEXTARG2) { 691 if (argc < 3) 692 errx(1, "'%s' requires 2 arguments", 693 p->c_name); | 494 } else if (p->c_parameter == NEXTARG2) { 495 if (argc < 3) 496 errx(1, "'%s' requires 2 arguments", 497 p->c_name); |
694 (*p->c_func2)(argv[1], argv[2], s, afp); | 498 p->c_func2(argv[1], argv[2], s, afp); |
695 argc -= 2, argv += 2; 696 } else | 499 argc -= 2, argv += 2; 500 } else |
697 (*p->c_func)(*argv, p->c_parameter, s, afp); | 501 p->c_func(*argv, p->c_parameter, s, afp); |
698 } 699 argc--, argv++; 700 } | 502 } 503 argc--, argv++; 504 } |
701#ifdef INET6 702 if (af == AF_INET6 && explicit_prefix == 0) { 703 /* Aggregatable address architecture defines all prefixes 704 are 64. So, it is convenient to set prefixlen to 64 if 705 it is not specified. */ 706 setifprefixlen("64", 0, s, afp); 707 /* in6_getprefix("64", MASK) if MASK is available here... */ 708 } 709#endif 710#ifndef NO_IPX 711 if (setipdst && af == AF_IPX) { 712 struct ipxip_req rq; 713 int size = sizeof(rq); | |
714 | 505 |
715 rq.rq_ipx = addreq.ifra_addr; 716 rq.rq_ip = addreq.ifra_dstaddr; 717 718 if (setsockopt(s, 0, SO_IPXIP_ROUTE, &rq, size) < 0) 719 Perror("Encapsulation Routing"); 720 } 721#endif 722 if (af == AF_APPLETALK) 723 checkatrange((struct sockaddr_at *) &addreq.ifra_addr); | 506 /* 507 * Do any post argument processing required by the address family. 508 */ 509 if (afp->af_postproc != NULL) 510 afp->af_postproc(s, afp); 511 /* 512 * Do deferred operations. 513 */ |
724 if (clearaddr) { 725 if (afp->af_ridreq == NULL || afp->af_difaddr == 0) { 726 warnx("interface %s cannot change %s addresses!", 727 name, afp->af_name); 728 clearaddr = 0; 729 } 730 } 731 if (clearaddr) { 732 int ret; 733 strncpy(afp->af_ridreq, name, sizeof ifr.ifr_name); | 514 if (clearaddr) { 515 if (afp->af_ridreq == NULL || afp->af_difaddr == 0) { 516 warnx("interface %s cannot change %s addresses!", 517 name, afp->af_name); 518 clearaddr = 0; 519 } 520 } 521 if (clearaddr) { 522 int ret; 523 strncpy(afp->af_ridreq, name, sizeof ifr.ifr_name); |
734 if ((ret = ioctl(s, afp->af_difaddr, afp->af_ridreq)) < 0) { | 524 ret = ioctl(s, afp->af_difaddr, afp->af_ridreq); 525 if (ret < 0) { |
735 if (errno == EADDRNOTAVAIL && (doalias >= 0)) { 736 /* means no previous address for interface */ 737 } else 738 Perror("ioctl (SIOCDIFADDR)"); 739 } 740 } 741 if (newaddr) { 742 if (afp->af_addreq == NULL || afp->af_aifaddr == 0) { --- 5 unchanged lines hidden (view full) --- 748 if (newaddr && (setaddr || setmask)) { 749 strncpy(afp->af_addreq, name, sizeof ifr.ifr_name); 750 if (ioctl(s, afp->af_aifaddr, afp->af_addreq) < 0) 751 Perror("ioctl (SIOCAIFADDR)"); 752 } 753 close(s); 754 return(0); 755} | 526 if (errno == EADDRNOTAVAIL && (doalias >= 0)) { 527 /* means no previous address for interface */ 528 } else 529 Perror("ioctl (SIOCDIFADDR)"); 530 } 531 } 532 if (newaddr) { 533 if (afp->af_addreq == NULL || afp->af_aifaddr == 0) { --- 5 unchanged lines hidden (view full) --- 539 if (newaddr && (setaddr || setmask)) { 540 strncpy(afp->af_addreq, name, sizeof ifr.ifr_name); 541 if (ioctl(s, afp->af_aifaddr, afp->af_addreq) < 0) 542 Perror("ioctl (SIOCAIFADDR)"); 543 } 544 close(s); 545 return(0); 546} |
756#define RIDADDR 0 757#define ADDR 1 758#define MASK 2 759#define DSTADDR 3 | |
760 761/*ARGSUSED*/ | 547 548/*ARGSUSED*/ |
762void | 549static void |
763setifaddr(const char *addr, int param, int s, const struct afswtch *afp) 764{ | 550setifaddr(const char *addr, int param, int s, const struct afswtch *afp) 551{ |
765 if (*afp->af_getaddr == NULL) | 552 if (afp->af_getaddr == NULL) |
766 return; 767 /* 768 * Delay the ioctl to set the interface addr until flags are all set. 769 * The address interpretation may depend on the flags, 770 * and the flags may change when the address is set. 771 */ 772 setaddr++; 773 if (doalias == 0 && afp->af_af != AF_LINK) 774 clearaddr = 1; | 553 return; 554 /* 555 * Delay the ioctl to set the interface addr until flags are all set. 556 * The address interpretation may depend on the flags, 557 * and the flags may change when the address is set. 558 */ 559 setaddr++; 560 if (doalias == 0 && afp->af_af != AF_LINK) 561 clearaddr = 1; |
775 (*afp->af_getaddr)(addr, (doalias >= 0 ? ADDR : RIDADDR)); | 562 afp->af_getaddr(addr, (doalias >= 0 ? ADDR : RIDADDR)); |
776} 777 | 563} 564 |
778void | 565static void |
779settunnel(const char *src, const char *dst, int s, const struct afswtch *afp) 780{ | 566settunnel(const char *src, const char *dst, int s, const struct afswtch *afp) 567{ |
781 struct addrinfo hints, *srcres, *dstres; 782 struct ifaliasreq addreq; | 568 struct addrinfo *srcres, *dstres; |
783 int ecode; | 569 int ecode; |
784#ifdef INET6 785 struct in6_aliasreq in6_addreq; 786#endif | |
787 | 570 |
788 memset(&hints, 0, sizeof(hints)); 789 hints.ai_family = afp->af_af; | 571 if (afp->af_settunnel == NULL) { 572 warn("address family %s does not support tunnel setup", 573 afp->af_name); 574 return; 575 } |
790 791 if ((ecode = getaddrinfo(src, NULL, NULL, &srcres)) != 0) 792 errx(1, "error in parsing address string: %s", 793 gai_strerror(ecode)); 794 795 if ((ecode = getaddrinfo(dst, NULL, NULL, &dstres)) != 0) 796 errx(1, "error in parsing address string: %s", 797 gai_strerror(ecode)); 798 799 if (srcres->ai_addr->sa_family != dstres->ai_addr->sa_family) 800 errx(1, 801 "source and destination address families do not match"); 802 | 576 577 if ((ecode = getaddrinfo(src, NULL, NULL, &srcres)) != 0) 578 errx(1, "error in parsing address string: %s", 579 gai_strerror(ecode)); 580 581 if ((ecode = getaddrinfo(dst, NULL, NULL, &dstres)) != 0) 582 errx(1, "error in parsing address string: %s", 583 gai_strerror(ecode)); 584 585 if (srcres->ai_addr->sa_family != dstres->ai_addr->sa_family) 586 errx(1, 587 "source and destination address families do not match"); 588 |
803 switch (srcres->ai_addr->sa_family) { 804 case AF_INET: 805 memset(&addreq, 0, sizeof(addreq)); 806 strncpy(addreq.ifra_name, name, IFNAMSIZ); 807 memcpy(&addreq.ifra_addr, srcres->ai_addr, 808 srcres->ai_addr->sa_len); 809 memcpy(&addreq.ifra_dstaddr, dstres->ai_addr, 810 dstres->ai_addr->sa_len); | 589 afp->af_settunnel(s, srcres, dstres); |
811 | 590 |
812 if (ioctl(s, SIOCSIFPHYADDR, &addreq) < 0) 813 warn("SIOCSIFPHYADDR"); 814 break; 815 816#ifdef INET6 817 case AF_INET6: 818 memset(&in6_addreq, 0, sizeof(in6_addreq)); 819 strncpy(in6_addreq.ifra_name, name, IFNAMSIZ); 820 memcpy(&in6_addreq.ifra_addr, srcres->ai_addr, 821 srcres->ai_addr->sa_len); 822 memcpy(&in6_addreq.ifra_dstaddr, dstres->ai_addr, 823 dstres->ai_addr->sa_len); 824 825 if (ioctl(s, SIOCSIFPHYADDR_IN6, &in6_addreq) < 0) 826 warn("SIOCSIFPHYADDR_IN6"); 827 break; 828#endif /* INET6 */ 829 830 default: 831 warn("address family not supported"); 832 } 833 | |
834 freeaddrinfo(srcres); 835 freeaddrinfo(dstres); 836} 837 838/* ARGSUSED */ | 591 freeaddrinfo(srcres); 592 freeaddrinfo(dstres); 593} 594 595/* ARGSUSED */ |
839void | 596static void |
840deletetunnel(const char *vname, int param, int s, const struct afswtch *afp) 841{ 842 843 if (ioctl(s, SIOCDIFPHYADDR, &ifr) < 0) 844 err(1, "SIOCDIFPHYADDR"); 845} 846 | 597deletetunnel(const char *vname, int param, int s, const struct afswtch *afp) 598{ 599 600 if (ioctl(s, SIOCDIFPHYADDR, &ifr) < 0) 601 err(1, "SIOCDIFPHYADDR"); 602} 603 |
847void | 604static void |
848setifnetmask(const char *addr, int dummy __unused, int s, 849 const struct afswtch *afp) 850{ | 605setifnetmask(const char *addr, int dummy __unused, int s, 606 const struct afswtch *afp) 607{ |
851 if (*afp->af_getaddr == NULL) 852 return; 853 setmask++; 854 (*afp->af_getaddr)(addr, MASK); 855} 856 857#ifdef INET6 858void 859setifprefixlen(const char *addr, int dummy __unused, int s, 860 const struct afswtch *afp) 861{ 862 if (*afp->af_getprefix) 863 (*afp->af_getprefix)(addr, MASK); 864 explicit_prefix = 1; 865} 866 867void 868setip6flags(const char *dummyaddr __unused, int flag, int dummysoc __unused, 869 const struct afswtch *afp) 870{ 871 if (afp->af_af != AF_INET6) 872 err(1, "address flags can be set only for inet6 addresses"); 873 874 if (flag < 0) 875 in6_addreq.ifra_flags &= ~(-flag); 876 else 877 in6_addreq.ifra_flags |= flag; 878} 879 880void 881setip6pltime(const char *seconds, int dummy __unused, int s, 882 const struct afswtch *afp) 883{ 884 setip6lifetime("pltime", seconds, s, afp); 885} 886 887void 888setip6vltime(const char *seconds, int dummy __unused, int s, 889 const struct afswtch *afp) 890{ 891 setip6lifetime("vltime", seconds, s, afp); 892} 893 894void 895setip6lifetime(const char *cmd, const char *val, int s, 896 const struct afswtch *afp) 897{ 898 time_t newval, t; 899 char *ep; 900 901 t = time(NULL); 902 newval = (time_t)strtoul(val, &ep, 0); 903 if (val == ep) 904 errx(1, "invalid %s", cmd); 905 if (afp->af_af != AF_INET6) 906 errx(1, "%s not allowed for the AF", cmd); 907 if (strcmp(cmd, "vltime") == 0) { 908 in6_addreq.ifra_lifetime.ia6t_expire = t + newval; 909 in6_addreq.ifra_lifetime.ia6t_vltime = newval; 910 } else if (strcmp(cmd, "pltime") == 0) { 911 in6_addreq.ifra_lifetime.ia6t_preferred = t + newval; 912 in6_addreq.ifra_lifetime.ia6t_pltime = newval; | 608 if (afp->af_getaddr != NULL) { 609 setmask++; 610 afp->af_getaddr(addr, MASK); |
913 } 914} 915 | 611 } 612} 613 |
916void 917setip6eui64(const char *cmd, int dummy __unused, int s, 918 const struct afswtch *afp) 919{ 920 struct ifaddrs *ifap, *ifa; 921 const struct sockaddr_in6 *sin6 = NULL; 922 const struct in6_addr *lladdr = NULL; 923 struct in6_addr *in6; 924 925 if (afp->af_af != AF_INET6) 926 errx(EXIT_FAILURE, "%s not allowed for the AF", cmd); 927 in6 = (struct in6_addr *)&in6_addreq.ifra_addr.sin6_addr; 928 if (memcmp(&in6addr_any.s6_addr[8], &in6->s6_addr[8], 8) != 0) 929 errx(EXIT_FAILURE, "interface index is already filled"); 930 if (getifaddrs(&ifap) != 0) 931 err(EXIT_FAILURE, "getifaddrs"); 932 for (ifa = ifap; ifa; ifa = ifa->ifa_next) { 933 if (ifa->ifa_addr->sa_family == AF_INET6 && 934 strcmp(ifa->ifa_name, name) == 0) { 935 sin6 = (const struct sockaddr_in6 *)ifa->ifa_addr; 936 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { 937 lladdr = &sin6->sin6_addr; 938 break; 939 } 940 } 941 } 942 if (!lladdr) 943 errx(EXIT_FAILURE, "could not determine link local address"); 944 945 memcpy(&in6->s6_addr[8], &lladdr->s6_addr[8], 8); 946 947 freeifaddrs(ifap); 948} 949#endif 950 951void | 614static void |
952setifbroadaddr(const char *addr, int dummy __unused, int s, 953 const struct afswtch *afp) 954{ | 615setifbroadaddr(const char *addr, int dummy __unused, int s, 616 const struct afswtch *afp) 617{ |
955 if (*afp->af_getaddr == NULL) 956 return; 957 (*afp->af_getaddr)(addr, DSTADDR); | 618 if (afp->af_getaddr != NULL) 619 afp->af_getaddr(addr, DSTADDR); |
958} 959 | 620} 621 |
960void | 622static void |
961setifipdst(const char *addr, int dummy __unused, int s, 962 const struct afswtch *afp) 963{ | 623setifipdst(const char *addr, int dummy __unused, int s, 624 const struct afswtch *afp) 625{ |
964 in_getaddr(addr, DSTADDR); | 626 const struct afswtch *inet; 627 628 inet = af_getbyname("inet"); 629 if (inet == NULL) 630 return; 631 inet->af_getaddr(addr, DSTADDR); |
965 setipdst++; 966 clearaddr = 0; 967 newaddr = 0; 968} | 632 setipdst++; 633 clearaddr = 0; 634 newaddr = 0; 635} |
969#define rqtosa(x) (&(((struct ifreq *)(afp->x))->ifr_addr)) | |
970 | 636 |
971void | 637static void |
972notealias(const char *addr, int param, int s, const struct afswtch *afp) 973{ | 638notealias(const char *addr, int param, int s, const struct afswtch *afp) 639{ |
640#define rqtosa(x) (&(((struct ifreq *)(afp->x))->ifr_addr)) |
|
974 if (setaddr && doalias == 0 && param < 0) 975 if (afp->af_addreq != NULL && afp->af_ridreq != NULL) 976 bcopy((caddr_t)rqtosa(af_addreq), 977 (caddr_t)rqtosa(af_ridreq), 978 rqtosa(af_addreq)->sa_len); 979 doalias = param; 980 if (param < 0) { 981 clearaddr = 1; 982 newaddr = 0; 983 } else 984 clearaddr = 0; | 641 if (setaddr && doalias == 0 && param < 0) 642 if (afp->af_addreq != NULL && afp->af_ridreq != NULL) 643 bcopy((caddr_t)rqtosa(af_addreq), 644 (caddr_t)rqtosa(af_ridreq), 645 rqtosa(af_addreq)->sa_len); 646 doalias = param; 647 if (param < 0) { 648 clearaddr = 1; 649 newaddr = 0; 650 } else 651 clearaddr = 0; |
652#undef rqtosa |
|
985} 986 987/*ARGSUSED*/ | 653} 654 655/*ARGSUSED*/ |
988void | 656static void |
989setifdstaddr(const char *addr, int param __unused, int s, 990 const struct afswtch *afp) 991{ | 657setifdstaddr(const char *addr, int param __unused, int s, 658 const struct afswtch *afp) 659{ |
992 if (*afp->af_getaddr == NULL) 993 return; 994 (*afp->af_getaddr)(addr, DSTADDR); | 660 if (afp->af_getaddr != NULL) 661 afp->af_getaddr(addr, DSTADDR); |
995} 996 997/* 998 * Note: doing an SIOCIGIFFLAGS scribbles on the union portion 999 * of the ifreq structure, which may confuse other parts of ifconfig. 1000 * Make a private copy so we can avoid that. 1001 */ | 662} 663 664/* 665 * Note: doing an SIOCIGIFFLAGS scribbles on the union portion 666 * of the ifreq structure, which may confuse other parts of ifconfig. 667 * Make a private copy so we can avoid that. 668 */ |
1002void | 669static void |
1003setifflags(const char *vname, int value, int s, const struct afswtch *afp) 1004{ 1005 struct ifreq my_ifr; 1006 1007 bcopy((char *)&ifr, (char *)&my_ifr, sizeof(struct ifreq)); 1008 1009 if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&my_ifr) < 0) { 1010 Perror("ioctl (SIOCGIFFLAGS)"); --- 27 unchanged lines hidden (view full) --- 1038 flags &= ~value; 1039 } else 1040 flags |= value; 1041 ifr.ifr_reqcap = flags; 1042 if (ioctl(s, SIOCSIFCAP, (caddr_t)&ifr) < 0) 1043 Perror(vname); 1044} 1045 | 670setifflags(const char *vname, int value, int s, const struct afswtch *afp) 671{ 672 struct ifreq my_ifr; 673 674 bcopy((char *)&ifr, (char *)&my_ifr, sizeof(struct ifreq)); 675 676 if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&my_ifr) < 0) { 677 Perror("ioctl (SIOCGIFFLAGS)"); --- 27 unchanged lines hidden (view full) --- 705 flags &= ~value; 706 } else 707 flags |= value; 708 ifr.ifr_reqcap = flags; 709 if (ioctl(s, SIOCSIFCAP, (caddr_t)&ifr) < 0) 710 Perror(vname); 711} 712 |
1046void | 713static void |
1047setifmetric(const char *val, int dummy __unused, int s, 1048 const struct afswtch *afp) 1049{ 1050 strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); 1051 ifr.ifr_metric = atoi(val); 1052 if (ioctl(s, SIOCSIFMETRIC, (caddr_t)&ifr) < 0) 1053 warn("ioctl (set metric)"); 1054} 1055 | 714setifmetric(const char *val, int dummy __unused, int s, 715 const struct afswtch *afp) 716{ 717 strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); 718 ifr.ifr_metric = atoi(val); 719 if (ioctl(s, SIOCSIFMETRIC, (caddr_t)&ifr) < 0) 720 warn("ioctl (set metric)"); 721} 722 |
1056void | 723static void |
1057setifmtu(const char *val, int dummy __unused, int s, 1058 const struct afswtch *afp) 1059{ 1060 strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); 1061 ifr.ifr_mtu = atoi(val); 1062 if (ioctl(s, SIOCSIFMTU, (caddr_t)&ifr) < 0) 1063 warn("ioctl (set mtu)"); 1064} 1065 | 724setifmtu(const char *val, int dummy __unused, int s, 725 const struct afswtch *afp) 726{ 727 strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); 728 ifr.ifr_mtu = atoi(val); 729 if (ioctl(s, SIOCSIFMTU, (caddr_t)&ifr) < 0) 730 warn("ioctl (set mtu)"); 731} 732 |
1066void | 733static void |
1067setifname(const char *val, int dummy __unused, int s, 1068 const struct afswtch *afp) 1069{ | 734setifname(const char *val, int dummy __unused, int s, 735 const struct afswtch *afp) 736{ |
1070 char *newname; | 737 char *newname; |
1071 1072 newname = strdup(val); | 738 739 newname = strdup(val); |
1073 | 740 if (newname == NULL) { 741 warn("no memory to set ifname"); 742 return; 743 } |
1074 ifr.ifr_data = newname; 1075 if (ioctl(s, SIOCSIFNAME, (caddr_t)&ifr) < 0) { 1076 warn("ioctl (set name)"); 1077 free(newname); 1078 return; 1079 } 1080 strlcpy(name, newname, sizeof(name)); 1081 free(newname); 1082 1083 /* 1084 * Even if we just created the interface, we don't need to print 1085 * its name because we just nailed it down separately. 1086 */ 1087 printname = 0; 1088} 1089 | 744 ifr.ifr_data = newname; 745 if (ioctl(s, SIOCSIFNAME, (caddr_t)&ifr) < 0) { 746 warn("ioctl (set name)"); 747 free(newname); 748 return; 749 } 750 strlcpy(name, newname, sizeof(name)); 751 free(newname); 752 753 /* 754 * Even if we just created the interface, we don't need to print 755 * its name because we just nailed it down separately. 756 */ 757 printname = 0; 758} 759 |
760/* 761 * Expand the compacted form of addresses as returned via the 762 * configuration read via sysctl(). 763 */ 764static void 765rt_xaddrs(caddr_t cp, caddr_t cplim, struct rt_addrinfo *rtinfo) 766{ 767 struct sockaddr *sa; 768 int i; 769 770 memset(rtinfo->rti_info, 0, sizeof(rtinfo->rti_info)); 771 for (i = 0; (i < RTAX_MAX) && (cp < cplim); i++) { 772 if ((rtinfo->rti_addrs & (1 << i)) == 0) 773 continue; 774 rtinfo->rti_info[i] = sa = (struct sockaddr *)cp; 775 cp += SA_SIZE(sa); 776 } 777} 778 |
|
1090#define IFFBITS \ 1091"\020\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\6SMART\7RUNNING" \ 1092"\10NOARP\11PROMISC\12ALLMULTI\13OACTIVE\14SIMPLEX\15LINK0\16LINK1\17LINK2" \ 1093"\20MULTICAST\21POLLING\23MONITOR\24STATICARP" 1094 1095#define IFCAPBITS \ 1096"\020\1RXCSUM\2TXCSUM\3NETCONS\4VLAN_MTU\5VLAN_HWTAGGING\6JUMBO_MTU\7POLLING" 1097 1098/* 1099 * Print the status of the interface. If an address family was | 779#define IFFBITS \ 780"\020\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\6SMART\7RUNNING" \ 781"\10NOARP\11PROMISC\12ALLMULTI\13OACTIVE\14SIMPLEX\15LINK0\16LINK1\17LINK2" \ 782"\20MULTICAST\21POLLING\23MONITOR\24STATICARP" 783 784#define IFCAPBITS \ 785"\020\1RXCSUM\2TXCSUM\3NETCONS\4VLAN_MTU\5VLAN_HWTAGGING\6JUMBO_MTU\7POLLING" 786 787/* 788 * Print the status of the interface. If an address family was |
1100 * specified, show it and it only; otherwise, show them all. | 789 * specified, show only it; otherwise, show them all. |
1101 */ | 790 */ |
1102void | 791static void |
1103status(const struct afswtch *afp, int addrcount, struct sockaddr_dl *sdl, 1104 struct if_msghdr *ifm, struct ifa_msghdr *ifam) 1105{ | 792status(const struct afswtch *afp, int addrcount, struct sockaddr_dl *sdl, 793 struct if_msghdr *ifm, struct ifa_msghdr *ifam) 794{ |
1106 const struct afswtch *p = NULL; | |
1107 struct rt_addrinfo info; 1108 int allfamilies, s; 1109 struct ifstat ifs; 1110 1111 if (afp == NULL) { 1112 allfamilies = 1; | 795 struct rt_addrinfo info; 796 int allfamilies, s; 797 struct ifstat ifs; 798 799 if (afp == NULL) { 800 allfamilies = 1; |
1113 afp = &afs[0]; | 801 afp = af_getbyname("inet"); |
1114 } else 1115 allfamilies = 0; 1116 1117 ifr.ifr_addr.sa_family = afp->af_af == AF_LINK ? AF_INET : afp->af_af; 1118 strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); 1119 | 802 } else 803 allfamilies = 0; 804 805 ifr.ifr_addr.sa_family = afp->af_af == AF_LINK ? AF_INET : afp->af_af; 806 strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); 807 |
1120 if ((s = socket(ifr.ifr_addr.sa_family, SOCK_DGRAM, 0)) < 0) 1121 err(1, "socket"); | 808 s = socket(ifr.ifr_addr.sa_family, SOCK_DGRAM, 0); 809 if (s < 0) 810 err(1, "socket(family %u,SOCK_DGRAM)", ifr.ifr_addr.sa_family); |
1122 1123 printf("%s: ", name); 1124 printb("flags", flags, IFFBITS); 1125 if (ifm->ifm_data.ifi_metric) 1126 printf(" metric %ld", ifm->ifm_data.ifi_metric); 1127 if (ifm->ifm_data.ifi_mtu) 1128 printf(" mtu %ld", ifm->ifm_data.ifi_mtu); 1129 putchar('\n'); 1130 1131 if (ioctl(s, SIOCGIFCAP, (caddr_t)&ifr) == 0) { 1132 if (ifr.ifr_curcap != 0) { 1133 printb("\toptions", ifr.ifr_curcap, IFCAPBITS); 1134 putchar('\n'); 1135 } 1136 if (supmedia && ifr.ifr_reqcap != 0) { | 811 812 printf("%s: ", name); 813 printb("flags", flags, IFFBITS); 814 if (ifm->ifm_data.ifi_metric) 815 printf(" metric %ld", ifm->ifm_data.ifi_metric); 816 if (ifm->ifm_data.ifi_mtu) 817 printf(" mtu %ld", ifm->ifm_data.ifi_mtu); 818 putchar('\n'); 819 820 if (ioctl(s, SIOCGIFCAP, (caddr_t)&ifr) == 0) { 821 if (ifr.ifr_curcap != 0) { 822 printb("\toptions", ifr.ifr_curcap, IFCAPBITS); 823 putchar('\n'); 824 } 825 if (supmedia && ifr.ifr_reqcap != 0) { |
1137 printf("\tcapability list:\n"); 1138 printb("\t\t", ifr.ifr_reqcap, IFCAPBITS); | 826 printb("\tcapabilities", ifr.ifr_reqcap, IFCAPBITS); |
1139 putchar('\n'); 1140 } 1141 } 1142 1143 tunnel_status(s); 1144 1145 while (addrcount > 0) { | 827 putchar('\n'); 828 } 829 } 830 831 tunnel_status(s); 832 833 while (addrcount > 0) { |
1146 | |
1147 info.rti_addrs = ifam->ifam_addrs; | 834 info.rti_addrs = ifam->ifam_addrs; |
1148 | |
1149 /* Expand the compacted addresses */ 1150 rt_xaddrs((char *)(ifam + 1), ifam->ifam_msglen + (char *)ifam, 1151 &info); 1152 | 835 /* Expand the compacted addresses */ 836 rt_xaddrs((char *)(ifam + 1), ifam->ifam_msglen + (char *)ifam, 837 &info); 838 |
1153 if (!allfamilies) { 1154 if (afp->af_af == info.rti_info[RTAX_IFA]->sa_family) { 1155 p = afp; 1156 (*p->af_status)(s, &info); 1157 } 1158 } else for (p = afs; p->af_name; p++) { 1159 if (p->af_af == info.rti_info[RTAX_IFA]->sa_family) 1160 (*p->af_status)(s, &info); 1161 } | 839 if (allfamilies) { 840 const struct afswtch *p; 841 p = af_getbyfamily(info.rti_info[RTAX_IFA]->sa_family); 842 if (p != NULL) 843 p->af_status(s, &info); 844 } else if (afp->af_af == info.rti_info[RTAX_IFA]->sa_family) 845 afp->af_status(s, &info); |
1162 addrcount--; 1163 ifam = (struct ifa_msghdr *)((char *)ifam + ifam->ifam_msglen); 1164 } | 846 addrcount--; 847 ifam = (struct ifa_msghdr *)((char *)ifam + ifam->ifam_msglen); 848 } |
1165 if (allfamilies || afp->af_status == link_status) 1166 link_status(s, (struct rt_addrinfo *)sdl); 1167#ifdef USE_IF_MEDIA 1168 if (allfamilies || afp->af_status == media_status) 1169 media_status(s, NULL); 1170#endif 1171#ifdef USE_VLANS 1172 if (allfamilies || afp->af_status == vlan_status) 1173 vlan_status(s, NULL); 1174#endif 1175#ifdef USE_IEEE80211 1176 if (allfamilies || afp->af_status == ieee80211_status) 1177 ieee80211_status(s, NULL); 1178#endif 1179#ifdef USE_MAC 1180 if (allfamilies || afp->af_status == maclabel_status) 1181 maclabel_status(s, NULL); 1182#endif | 849 if (allfamilies) 850 af_all_status(s, (const struct rt_addrinfo *) sdl); 851 else if (afp->af_status != NULL) 852 afp->af_status(s, (const struct rt_addrinfo *) sdl); 853 |
1183 strncpy(ifs.ifs_name, name, sizeof ifs.ifs_name); 1184 if (ioctl(s, SIOCGIFSTATUS, &ifs) == 0) 1185 printf("%s", ifs.ascii); 1186 | 854 strncpy(ifs.ifs_name, name, sizeof ifs.ifs_name); 855 if (ioctl(s, SIOCGIFSTATUS, &ifs) == 0) 856 printf("%s", ifs.ascii); 857 |
1187 if (!allfamilies && !p && 1188#ifdef USE_IF_MEDIA 1189 afp->af_status != media_status && 1190#endif 1191 afp->af_status != link_status 1192#ifdef USE_VLANS 1193 && afp->af_status != vlan_status 1194#endif 1195 ) 1196 warnx("%s has no %s interface address!", name, afp->af_name); 1197 | |
1198 close(s); 1199 return; 1200} 1201 | 858 close(s); 859 return; 860} 861 |
1202void | 862static void |
1203tunnel_status(int s) 1204{ | 863tunnel_status(int s) 864{ |
1205 char psrcaddr[NI_MAXHOST]; 1206 char pdstaddr[NI_MAXHOST]; 1207 u_long srccmd, dstcmd; 1208 struct ifreq *ifrp; 1209 const char *ver = ""; 1210#ifdef NI_WITHSCOPEID 1211 const int niflag = NI_NUMERICHOST | NI_WITHSCOPEID; 1212#else 1213 const int niflag = NI_NUMERICHOST; 1214#endif 1215#ifdef INET6 1216 struct in6_ifreq in6_ifr; 1217 int s6; 1218#endif /* INET6 */ 1219 1220 psrcaddr[0] = pdstaddr[0] = '\0'; 1221 1222#ifdef INET6 1223 memset(&in6_ifr, 0, sizeof(in6_ifr)); 1224 strncpy(in6_ifr.ifr_name, name, IFNAMSIZ); 1225 s6 = socket(AF_INET6, SOCK_DGRAM, 0); 1226 if (s6 < 0) { 1227 srccmd = SIOCGIFPSRCADDR; 1228 dstcmd = SIOCGIFPDSTADDR; 1229 ifrp = 𝔦 1230 } else { 1231 close(s6); 1232 srccmd = SIOCGIFPSRCADDR_IN6; 1233 dstcmd = SIOCGIFPDSTADDR_IN6; 1234 ifrp = (struct ifreq *)&in6_ifr; 1235 } 1236#else /* INET6 */ 1237 srccmd = SIOCGIFPSRCADDR; 1238 dstcmd = SIOCGIFPDSTADDR; 1239 ifrp = 𝔦 1240#endif /* INET6 */ 1241 1242 if (ioctl(s, srccmd, (caddr_t)ifrp) < 0) 1243 return; 1244#ifdef INET6 1245 if (ifrp->ifr_addr.sa_family == AF_INET6) 1246 in6_fillscopeid((struct sockaddr_in6 *)&ifrp->ifr_addr); 1247#endif 1248 getnameinfo(&ifrp->ifr_addr, ifrp->ifr_addr.sa_len, 1249 psrcaddr, sizeof(psrcaddr), 0, 0, niflag); 1250#ifdef INET6 1251 if (ifrp->ifr_addr.sa_family == AF_INET6) 1252 ver = "6"; 1253#endif 1254 1255 if (ioctl(s, dstcmd, (caddr_t)ifrp) < 0) 1256 return; 1257#ifdef INET6 1258 if (ifrp->ifr_addr.sa_family == AF_INET6) 1259 in6_fillscopeid((struct sockaddr_in6 *)&ifrp->ifr_addr); 1260#endif 1261 getnameinfo(&ifrp->ifr_addr, ifrp->ifr_addr.sa_len, 1262 pdstaddr, sizeof(pdstaddr), 0, 0, niflag); 1263 1264 printf("\ttunnel inet%s %s --> %s\n", ver, 1265 psrcaddr, pdstaddr); | 865 af_all_tunnel_status(s); |
1266} 1267 1268void | 866} 867 868void |
1269in_status(int s __unused, struct rt_addrinfo * info) 1270{ 1271 struct sockaddr_in *sin, null_sin; 1272 1273 memset(&null_sin, 0, sizeof(null_sin)); 1274 1275 sin = (struct sockaddr_in *)info->rti_info[RTAX_IFA]; 1276 printf("\tinet %s ", inet_ntoa(sin->sin_addr)); 1277 1278 if (flags & IFF_POINTOPOINT) { 1279 /* note RTAX_BRD overlap with IFF_BROADCAST */ 1280 sin = (struct sockaddr_in *)info->rti_info[RTAX_BRD]; 1281 if (!sin) 1282 sin = &null_sin; 1283 printf("--> %s ", inet_ntoa(sin->sin_addr)); 1284 } 1285 1286 sin = (struct sockaddr_in *)info->rti_info[RTAX_NETMASK]; 1287 if (!sin) 1288 sin = &null_sin; 1289 printf("netmask 0x%lx ", (unsigned long)ntohl(sin->sin_addr.s_addr)); 1290 1291 if (flags & IFF_BROADCAST) { 1292 /* note RTAX_BRD overlap with IFF_POINTOPOINT */ 1293 sin = (struct sockaddr_in *)info->rti_info[RTAX_BRD]; 1294 if (sin && sin->sin_addr.s_addr != 0) 1295 printf("broadcast %s", inet_ntoa(sin->sin_addr)); 1296 } 1297 putchar('\n'); 1298} 1299 1300#ifdef INET6 1301void 1302in6_fillscopeid(struct sockaddr_in6 *sin6) 1303{ 1304#if defined(__KAME__) && defined(KAME_SCOPEID) 1305 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { 1306 sin6->sin6_scope_id = 1307 ntohs(*(u_int16_t *)&sin6->sin6_addr.s6_addr[2]); 1308 sin6->sin6_addr.s6_addr[2] = sin6->sin6_addr.s6_addr[3] = 0; 1309 } 1310#endif 1311} 1312 1313void 1314in6_status(int s __unused, struct rt_addrinfo * info) 1315{ 1316 struct sockaddr_in6 *sin, null_sin; 1317 struct in6_ifreq ifr6; 1318 int s6; 1319 u_int32_t flags6; 1320 struct in6_addrlifetime lifetime; 1321 time_t t = time(NULL); 1322 int error; 1323 u_int32_t scopeid; 1324 1325 memset(&null_sin, 0, sizeof(null_sin)); 1326 1327 sin = (struct sockaddr_in6 *)info->rti_info[RTAX_IFA]; 1328 strncpy(ifr6.ifr_name, ifr.ifr_name, sizeof(ifr.ifr_name)); 1329 if ((s6 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { 1330 perror("ifconfig: socket"); 1331 return; 1332 } 1333 ifr6.ifr_addr = *sin; 1334 if (ioctl(s6, SIOCGIFAFLAG_IN6, &ifr6) < 0) { 1335 perror("ifconfig: ioctl(SIOCGIFAFLAG_IN6)"); 1336 close(s6); 1337 return; 1338 } 1339 flags6 = ifr6.ifr_ifru.ifru_flags6; 1340 memset(&lifetime, 0, sizeof(lifetime)); 1341 ifr6.ifr_addr = *sin; 1342 if (ioctl(s6, SIOCGIFALIFETIME_IN6, &ifr6) < 0) { 1343 perror("ifconfig: ioctl(SIOCGIFALIFETIME_IN6)"); 1344 close(s6); 1345 return; 1346 } 1347 lifetime = ifr6.ifr_ifru.ifru_lifetime; 1348 close(s6); 1349 1350 /* XXX: embedded link local addr check */ 1351 if (IN6_IS_ADDR_LINKLOCAL(&sin->sin6_addr) && 1352 *(u_short *)&sin->sin6_addr.s6_addr[2] != 0) { 1353 u_short index; 1354 1355 index = *(u_short *)&sin->sin6_addr.s6_addr[2]; 1356 *(u_short *)&sin->sin6_addr.s6_addr[2] = 0; 1357 if (sin->sin6_scope_id == 0) 1358 sin->sin6_scope_id = ntohs(index); 1359 } 1360 scopeid = sin->sin6_scope_id; 1361 1362 error = getnameinfo((struct sockaddr *)sin, sin->sin6_len, addr_buf, 1363 sizeof(addr_buf), NULL, 0, 1364 NI_NUMERICHOST|NI_WITHSCOPEID); 1365 if (error != 0) 1366 inet_ntop(AF_INET6, &sin->sin6_addr, addr_buf, 1367 sizeof(addr_buf)); 1368 printf("\tinet6 %s ", addr_buf); 1369 1370 if (flags & IFF_POINTOPOINT) { 1371 /* note RTAX_BRD overlap with IFF_BROADCAST */ 1372 sin = (struct sockaddr_in6 *)info->rti_info[RTAX_BRD]; 1373 /* 1374 * some of the interfaces do not have valid destination 1375 * address. 1376 */ 1377 if (sin && sin->sin6_family == AF_INET6) { 1378 int error; 1379 1380 /* XXX: embedded link local addr check */ 1381 if (IN6_IS_ADDR_LINKLOCAL(&sin->sin6_addr) && 1382 *(u_short *)&sin->sin6_addr.s6_addr[2] != 0) { 1383 u_short index; 1384 1385 index = *(u_short *)&sin->sin6_addr.s6_addr[2]; 1386 *(u_short *)&sin->sin6_addr.s6_addr[2] = 0; 1387 if (sin->sin6_scope_id == 0) 1388 sin->sin6_scope_id = ntohs(index); 1389 } 1390 1391 error = getnameinfo((struct sockaddr *)sin, 1392 sin->sin6_len, addr_buf, 1393 sizeof(addr_buf), NULL, 0, 1394 NI_NUMERICHOST|NI_WITHSCOPEID); 1395 if (error != 0) 1396 inet_ntop(AF_INET6, &sin->sin6_addr, addr_buf, 1397 sizeof(addr_buf)); 1398 printf("--> %s ", addr_buf); 1399 } 1400 } 1401 1402 sin = (struct sockaddr_in6 *)info->rti_info[RTAX_NETMASK]; 1403 if (!sin) 1404 sin = &null_sin; 1405 printf("prefixlen %d ", prefix(&sin->sin6_addr, 1406 sizeof(struct in6_addr))); 1407 1408 if ((flags6 & IN6_IFF_ANYCAST) != 0) 1409 printf("anycast "); 1410 if ((flags6 & IN6_IFF_TENTATIVE) != 0) 1411 printf("tentative "); 1412 if ((flags6 & IN6_IFF_DUPLICATED) != 0) 1413 printf("duplicated "); 1414 if ((flags6 & IN6_IFF_DETACHED) != 0) 1415 printf("detached "); 1416 if ((flags6 & IN6_IFF_DEPRECATED) != 0) 1417 printf("deprecated "); 1418 if ((flags6 & IN6_IFF_AUTOCONF) != 0) 1419 printf("autoconf "); 1420 if ((flags6 & IN6_IFF_TEMPORARY) != 0) 1421 printf("temporary "); 1422 1423 if (scopeid) 1424 printf("scopeid 0x%x ", scopeid); 1425 1426 if (ip6lifetime && (lifetime.ia6t_preferred || lifetime.ia6t_expire)) { 1427 printf("pltime "); 1428 if (lifetime.ia6t_preferred) { 1429 printf("%s ", lifetime.ia6t_preferred < t 1430 ? "0" : sec2str(lifetime.ia6t_preferred - t)); 1431 } else 1432 printf("infty "); 1433 1434 printf("vltime "); 1435 if (lifetime.ia6t_expire) { 1436 printf("%s ", lifetime.ia6t_expire < t 1437 ? "0" : sec2str(lifetime.ia6t_expire - t)); 1438 } else 1439 printf("infty "); 1440 } 1441 1442 putchar('\n'); 1443} 1444#endif /*INET6*/ 1445 1446#ifndef NO_IPX 1447void 1448ipx_status(int s __unused, struct rt_addrinfo * info) 1449{ 1450 struct sockaddr_ipx *sipx, null_sipx; 1451 1452 memset(&null_sipx, 0, sizeof(null_sipx)); 1453 1454 sipx = (struct sockaddr_ipx *)info->rti_info[RTAX_IFA]; 1455 printf("\tipx %s ", ipx_ntoa(sipx->sipx_addr)); 1456 1457 if (flags & IFF_POINTOPOINT) { 1458 sipx = (struct sockaddr_ipx *)info->rti_info[RTAX_BRD]; 1459 if (!sipx) 1460 sipx = &null_sipx; 1461 printf("--> %s ", ipx_ntoa(sipx->sipx_addr)); 1462 } 1463 putchar('\n'); 1464} 1465#endif 1466 1467void 1468at_status(int s __unused, struct rt_addrinfo * info) 1469{ 1470 struct sockaddr_at *sat, null_sat; 1471 struct netrange *nr; 1472 1473 memset(&null_sat, 0, sizeof(null_sat)); 1474 1475 sat = (struct sockaddr_at *)info->rti_info[RTAX_IFA]; 1476 nr = &sat->sat_range.r_netrange; 1477 printf("\tatalk %d.%d range %d-%d phase %d", 1478 ntohs(sat->sat_addr.s_net), sat->sat_addr.s_node, 1479 ntohs(nr->nr_firstnet), ntohs(nr->nr_lastnet), nr->nr_phase); 1480 if (flags & IFF_POINTOPOINT) { 1481 /* note RTAX_BRD overlap with IFF_BROADCAST */ 1482 sat = (struct sockaddr_at *)info->rti_info[RTAX_BRD]; 1483 if (!sat) 1484 sat = &null_sat; 1485 printf("--> %d.%d", 1486 ntohs(sat->sat_addr.s_net), sat->sat_addr.s_node); 1487 } 1488 if (flags & IFF_BROADCAST) { 1489 /* note RTAX_BRD overlap with IFF_POINTOPOINT */ 1490 sat = (struct sockaddr_at *)info->rti_info[RTAX_BRD]; 1491 if (sat) 1492 printf(" broadcast %d.%d", 1493 ntohs(sat->sat_addr.s_net), 1494 sat->sat_addr.s_node); 1495 } 1496 1497 putchar('\n'); 1498} 1499 1500void 1501link_status(int s __unused, struct rt_addrinfo *info) 1502{ 1503 struct sockaddr_dl *sdl = (struct sockaddr_dl *)info; 1504 1505 if (sdl->sdl_alen > 0) { 1506 if (sdl->sdl_type == IFT_ETHER && 1507 sdl->sdl_alen == ETHER_ADDR_LEN) 1508 printf("\tether %s\n", 1509 ether_ntoa((struct ether_addr *)LLADDR(sdl))); 1510 else { 1511 int n = sdl->sdl_nlen > 0 ? sdl->sdl_nlen + 1 : 0; 1512 1513 printf("\tlladdr %s\n", link_ntoa(sdl) + n); 1514 } 1515 } 1516} 1517 1518void | |
1519Perror(const char *cmd) 1520{ 1521 switch (errno) { 1522 1523 case ENXIO: 1524 errx(1, "%s: no such interface", cmd); 1525 break; 1526 1527 case EPERM: 1528 errx(1, "%s: permission denied", cmd); 1529 break; 1530 1531 default: 1532 err(1, "%s", cmd); 1533 } 1534} 1535 | 869Perror(const char *cmd) 870{ 871 switch (errno) { 872 873 case ENXIO: 874 errx(1, "%s: no such interface", cmd); 875 break; 876 877 case EPERM: 878 errx(1, "%s: permission denied", cmd); 879 break; 880 881 default: 882 err(1, "%s", cmd); 883 } 884} 885 |
1536#define SIN(x) ((struct sockaddr_in *) &(x)) 1537struct sockaddr_in *sintab[] = { 1538SIN(ridreq.ifr_addr), SIN(addreq.ifra_addr), 1539SIN(addreq.ifra_mask), SIN(addreq.ifra_broadaddr)}; 1540 1541void 1542in_getaddr(const char *s, int which) 1543{ 1544 struct sockaddr_in *sin = sintab[which]; 1545 struct hostent *hp; 1546 struct netent *np; 1547 1548 sin->sin_len = sizeof(*sin); 1549 if (which != MASK) 1550 sin->sin_family = AF_INET; 1551 1552 if (which == ADDR) { 1553 char *p = NULL; 1554 1555 if((p = strrchr(s, '/')) != NULL) { 1556 /* address is `name/masklen' */ 1557 int masklen; 1558 int ret; 1559 struct sockaddr_in *min = sintab[MASK]; 1560 *p = '\0'; 1561 ret = sscanf(p+1, "%u", &masklen); 1562 if(ret != 1 || (masklen < 0 || masklen > 32)) { 1563 *p = '/'; 1564 errx(1, "%s: bad value", s); 1565 } 1566 min->sin_len = sizeof(*min); 1567 min->sin_addr.s_addr = htonl(~((1LL << (32 - masklen)) - 1) & 1568 0xffffffff); 1569 } 1570 } 1571 1572 if (inet_aton(s, &sin->sin_addr)) 1573 return; 1574 if ((hp = gethostbyname(s)) != 0) 1575 bcopy(hp->h_addr, (char *)&sin->sin_addr, 1576 MIN(hp->h_length, sizeof(sin->sin_addr))); 1577 else if ((np = getnetbyname(s)) != 0) 1578 sin->sin_addr = inet_makeaddr(np->n_net, INADDR_ANY); 1579 else 1580 errx(1, "%s: bad value", s); 1581} 1582 1583#ifdef INET6 1584#define SIN6(x) ((struct sockaddr_in6 *) &(x)) 1585struct sockaddr_in6 *sin6tab[] = { 1586SIN6(in6_ridreq.ifr_addr), SIN6(in6_addreq.ifra_addr), 1587SIN6(in6_addreq.ifra_prefixmask), SIN6(in6_addreq.ifra_dstaddr)}; 1588 1589void 1590in6_getaddr(const char *s, int which) 1591{ 1592 struct sockaddr_in6 *sin = sin6tab[which]; 1593 struct addrinfo hints, *res; 1594 int error = -1; 1595 1596 newaddr &= 1; 1597 1598 sin->sin6_len = sizeof(*sin); 1599 if (which != MASK) 1600 sin->sin6_family = AF_INET6; 1601 1602 if (which == ADDR) { 1603 char *p = NULL; 1604 if((p = strrchr(s, '/')) != NULL) { 1605 *p = '\0'; 1606 in6_getprefix(p + 1, MASK); 1607 explicit_prefix = 1; 1608 } 1609 } 1610 1611 if (sin->sin6_family == AF_INET6) { 1612 bzero(&hints, sizeof(struct addrinfo)); 1613 hints.ai_family = AF_INET6; 1614 error = getaddrinfo(s, NULL, &hints, &res); 1615 } 1616 if (error != 0) { 1617 if (inet_pton(AF_INET6, s, &sin->sin6_addr) != 1) 1618 errx(1, "%s: bad value", s); 1619 } else 1620 bcopy(res->ai_addr, sin, res->ai_addrlen); 1621} 1622 1623void 1624in6_getprefix(const char *plen, int which) 1625{ 1626 struct sockaddr_in6 *sin = sin6tab[which]; 1627 u_char *cp; 1628 int len = atoi(plen); 1629 1630 if ((len < 0) || (len > 128)) 1631 errx(1, "%s: bad value", plen); 1632 sin->sin6_len = sizeof(*sin); 1633 if (which != MASK) 1634 sin->sin6_family = AF_INET6; 1635 if ((len == 0) || (len == 128)) { 1636 memset(&sin->sin6_addr, 0xff, sizeof(struct in6_addr)); 1637 return; 1638 } 1639 memset((void *)&sin->sin6_addr, 0x00, sizeof(sin->sin6_addr)); 1640 for (cp = (u_char *)&sin->sin6_addr; len > 7; len -= 8) 1641 *cp++ = 0xff; 1642 *cp = 0xff << (8 - len); 1643} 1644#endif 1645 | |
1646/* 1647 * Print a value a la the %b format of the kernel's printf 1648 */ 1649void 1650printb(const char *s, unsigned v, const char *bits) 1651{ 1652 int i, any = 0; 1653 char c; --- 15 unchanged lines hidden (view full) --- 1669 } else 1670 for (; *bits > 32; bits++) 1671 ; 1672 } 1673 putchar('>'); 1674 } 1675} 1676 | 886/* 887 * Print a value a la the %b format of the kernel's printf 888 */ 889void 890printb(const char *s, unsigned v, const char *bits) 891{ 892 int i, any = 0; 893 char c; --- 15 unchanged lines hidden (view full) --- 909 } else 910 for (; *bits > 32; bits++) 911 ; 912 } 913 putchar('>'); 914 } 915} 916 |
1677#ifndef NO_IPX 1678#define SIPX(x) ((struct sockaddr_ipx *) &(x)) 1679struct sockaddr_ipx *sipxtab[] = { 1680SIPX(ridreq.ifr_addr), SIPX(addreq.ifra_addr), 1681SIPX(addreq.ifra_mask), SIPX(addreq.ifra_broadaddr)}; 1682 | |
1683void | 917void |
1684ipx_getaddr(const char *addr, int which) 1685{ 1686 struct sockaddr_ipx *sipx = sipxtab[which]; 1687 1688 sipx->sipx_family = AF_IPX; 1689 sipx->sipx_len = sizeof(*sipx); 1690 sipx->sipx_addr = ipx_addr(addr); 1691 if (which == MASK) 1692 printf("Attempt to set IPX netmask will be ineffectual\n"); 1693} 1694#endif 1695 1696void 1697at_getaddr(const char *addr, int which) 1698{ 1699 struct sockaddr_at *sat = (struct sockaddr_at *) &addreq.ifra_addr; 1700 u_int net, node; 1701 1702 sat->sat_family = AF_APPLETALK; 1703 sat->sat_len = sizeof(*sat); 1704 if (which == MASK) 1705 errx(1, "AppleTalk does not use netmasks"); 1706 if (sscanf(addr, "%u.%u", &net, &node) != 2 1707 || net > 0xffff || node > 0xfe) 1708 errx(1, "%s: illegal address", addr); 1709 sat->sat_addr.s_net = htons(net); 1710 sat->sat_addr.s_node = node; 1711} 1712 1713void 1714link_getaddr(const char *addr, int which) 1715{ 1716 char *temp; 1717 struct sockaddr_dl sdl; 1718 struct sockaddr *sa = &ridreq.ifr_addr; 1719 1720 if (which != ADDR) 1721 errx(1, "can't set link-level netmask or broadcast"); 1722 if ((temp = malloc(strlen(addr) + 1)) == NULL) 1723 errx(1, "malloc failed"); 1724 temp[0] = ':'; 1725 strcpy(temp + 1, addr); 1726 sdl.sdl_len = sizeof(sdl); 1727 link_addr(temp, &sdl); 1728 free(temp); 1729 if (sdl.sdl_alen > sizeof(sa->sa_data)) 1730 errx(1, "malformed link-level address"); 1731 sa->sa_family = AF_LINK; 1732 sa->sa_len = sdl.sdl_alen; 1733 bcopy(LLADDR(&sdl), sa->sa_data, sdl.sdl_alen); 1734} 1735 1736/* XXX FIXME -- should use strtoul for better parsing. */ 1737void 1738setatrange(const char *range, int dummy __unused, int s, 1739 const struct afswtch *afp) 1740{ 1741 u_int first = 123, last = 123; 1742 1743 if (sscanf(range, "%u-%u", &first, &last) != 2 1744 || first == 0 || first > 0xffff 1745 || last == 0 || last > 0xffff || first > last) 1746 errx(1, "%s: illegal net range: %u-%u", range, first, last); 1747 at_nr.nr_firstnet = htons(first); 1748 at_nr.nr_lastnet = htons(last); 1749} 1750 1751void 1752setatphase(const char *phase, int dummy __unused, int s, 1753 const struct afswtch *afp) 1754{ 1755 if (!strcmp(phase, "1")) 1756 at_nr.nr_phase = 1; 1757 else if (!strcmp(phase, "2")) 1758 at_nr.nr_phase = 2; 1759 else 1760 errx(1, "%s: illegal phase", phase); 1761} 1762 1763void 1764checkatrange(struct sockaddr_at *sat) 1765{ 1766 if (at_nr.nr_phase == 0) 1767 at_nr.nr_phase = 2; /* Default phase 2 */ 1768 if (at_nr.nr_firstnet == 0) 1769 at_nr.nr_firstnet = /* Default range of one */ 1770 at_nr.nr_lastnet = sat->sat_addr.s_net; 1771printf("\tatalk %d.%d range %d-%d phase %d\n", 1772 ntohs(sat->sat_addr.s_net), sat->sat_addr.s_node, 1773 ntohs(at_nr.nr_firstnet), ntohs(at_nr.nr_lastnet), at_nr.nr_phase); 1774 if ((u_short) ntohs(at_nr.nr_firstnet) > 1775 (u_short) ntohs(sat->sat_addr.s_net) 1776 || (u_short) ntohs(at_nr.nr_lastnet) < 1777 (u_short) ntohs(sat->sat_addr.s_net)) 1778 errx(1, "AppleTalk address is not in range"); 1779 sat->sat_range.r_netrange = at_nr; 1780} 1781 1782#ifdef INET6 1783int 1784prefix(void *val, int size) 1785{ 1786 u_char *name = (u_char *)val; 1787 int byte, bit, plen = 0; 1788 1789 for (byte = 0; byte < size; byte++, plen += 8) 1790 if (name[byte] != 0xff) 1791 break; 1792 if (byte == size) 1793 return (plen); 1794 for (bit = 7; bit != 0; bit--, plen++) 1795 if (!(name[byte] & (1 << bit))) 1796 break; 1797 for (; bit != 0; bit--) 1798 if (name[byte] & (1 << bit)) 1799 return(0); 1800 byte++; 1801 for (; byte < size; byte++) 1802 if (name[byte]) 1803 return(0); 1804 return (plen); 1805} 1806 1807static char * 1808sec2str(time_t total) 1809{ 1810 static char result[256]; 1811 int days, hours, mins, secs; 1812 int first = 1; 1813 char *p = result; 1814 1815 if (0) { 1816 days = total / 3600 / 24; 1817 hours = (total / 3600) % 24; 1818 mins = (total / 60) % 60; 1819 secs = total % 60; 1820 1821 if (days) { 1822 first = 0; 1823 p += sprintf(p, "%dd", days); 1824 } 1825 if (!first || hours) { 1826 first = 0; 1827 p += sprintf(p, "%dh", hours); 1828 } 1829 if (!first || mins) { 1830 first = 0; 1831 p += sprintf(p, "%dm", mins); 1832 } 1833 sprintf(p, "%ds", secs); 1834 } else 1835 sprintf(result, "%lu", (unsigned long)total); 1836 1837 return(result); 1838} 1839#endif /*INET6*/ 1840 1841void | |
1842ifmaybeload(char *name) 1843{ 1844 struct module_stat mstat; 1845 int fileid, modid; 1846 char ifkind[35], *cp, *dp; 1847 1848 /* turn interface and unit into module name */ 1849 strcpy(ifkind, "if_"); --- 22 unchanged lines hidden (view full) --- 1872 return; 1873 } 1874 } 1875 1876 /* not present, we should try to load it */ 1877 kldload(ifkind); 1878} 1879 | 918ifmaybeload(char *name) 919{ 920 struct module_stat mstat; 921 int fileid, modid; 922 char ifkind[35], *cp, *dp; 923 924 /* turn interface and unit into module name */ 925 strcpy(ifkind, "if_"); --- 22 unchanged lines hidden (view full) --- 948 return; 949 } 950 } 951 952 /* not present, we should try to load it */ 953 kldload(ifkind); 954} 955 |
1880void 1881list_cloners(void) 1882{ 1883 struct if_clonereq ifcr; 1884 char *cp, *buf; 1885 int idx; 1886 int s; | 956static struct cmd basic_cmds[] = { 957 DEF_CMD("up", IFF_UP, setifflags), 958 DEF_CMD("down", -IFF_UP, setifflags), 959 DEF_CMD("arp", -IFF_NOARP, setifflags), 960 DEF_CMD("-arp", IFF_NOARP, setifflags), 961 DEF_CMD("debug", IFF_DEBUG, setifflags), 962 DEF_CMD("-debug", -IFF_DEBUG, setifflags), 963 DEF_CMD("promisc", IFF_PPROMISC, setifflags), 964 DEF_CMD("-promisc", -IFF_PPROMISC, setifflags), 965 DEF_CMD("add", IFF_UP, notealias), 966 DEF_CMD("alias", IFF_UP, notealias), 967 DEF_CMD("-alias", -IFF_UP, notealias), 968 DEF_CMD("delete", -IFF_UP, notealias), 969 DEF_CMD("remove", -IFF_UP, notealias), 970#ifdef notdef 971#define EN_SWABIPS 0x1000 972 DEF_CMD("swabips", EN_SWABIPS, setifflags), 973 DEF_CMD("-swabips", -EN_SWABIPS, setifflags), 974#endif 975 DEF_CMD_ARG("netmask", setifnetmask), 976 DEF_CMD_ARG("metric", setifmetric), 977 DEF_CMD_ARG("broadcast", setifbroadaddr), 978 DEF_CMD_ARG("ipdst", setifipdst), 979 DEF_CMD_ARG2("tunnel", settunnel), 980 DEF_CMD("deletetunnel", 0, deletetunnel), 981 DEF_CMD("link0", IFF_LINK0, setifflags), 982 DEF_CMD("-link0", -IFF_LINK0, setifflags), 983 DEF_CMD("link1", IFF_LINK1, setifflags), 984 DEF_CMD("-link1", -IFF_LINK1, setifflags), 985 DEF_CMD("link2", IFF_LINK2, setifflags), 986 DEF_CMD("-link2", -IFF_LINK2, setifflags), 987 DEF_CMD("monitor", IFF_MONITOR, setifflags), 988 DEF_CMD("-monitor", -IFF_MONITOR, setifflags), 989 DEF_CMD("staticarp", IFF_STATICARP, setifflags), 990 DEF_CMD("-staticarp", -IFF_STATICARP, setifflags), 991 DEF_CMD("rxcsum", IFCAP_RXCSUM, setifcap), 992 DEF_CMD("-rxcsum", -IFCAP_RXCSUM, setifcap), 993 DEF_CMD("txcsum", IFCAP_TXCSUM, setifcap), 994 DEF_CMD("-txcsum", -IFCAP_TXCSUM, setifcap), 995 DEF_CMD("netcons", IFCAP_NETCONS, setifcap), 996 DEF_CMD("-netcons", -IFCAP_NETCONS, setifcap), 997 DEF_CMD("polling", IFCAP_POLLING, setifcap), 998 DEF_CMD("-polling", -IFCAP_POLLING, setifcap), 999 DEF_CMD("normal", -IFF_LINK0, setifflags), 1000 DEF_CMD("compress", IFF_LINK0, setifflags), 1001 DEF_CMD("noicmp", IFF_LINK1, setifflags), 1002 DEF_CMD_ARG("mtu", setifmtu), 1003 DEF_CMD_ARG("name", setifname), 1004}; |
1887 | 1005 |
1888 s = socket(AF_INET, SOCK_DGRAM, 0); 1889 if (s == -1) 1890 err(1, "socket"); 1891 1892 memset(&ifcr, 0, sizeof(ifcr)); 1893 1894 if (ioctl(s, SIOCIFGCLONERS, &ifcr) < 0) 1895 err(1, "SIOCIFGCLONERS for count"); 1896 1897 buf = malloc(ifcr.ifcr_total * IFNAMSIZ); 1898 if (buf == NULL) 1899 err(1, "unable to allocate cloner name buffer"); 1900 1901 ifcr.ifcr_count = ifcr.ifcr_total; 1902 ifcr.ifcr_buffer = buf; 1903 1904 if (ioctl(s, SIOCIFGCLONERS, &ifcr) < 0) 1905 err(1, "SIOCIFGCLONERS for names"); 1906 1907 /* 1908 * In case some disappeared in the mean time, clamp it down. 1909 */ 1910 if (ifcr.ifcr_count > ifcr.ifcr_total) 1911 ifcr.ifcr_count = ifcr.ifcr_total; 1912 1913 for (cp = buf, idx = 0; idx < ifcr.ifcr_count; idx++, cp += IFNAMSIZ) { 1914 if (idx > 0) 1915 putchar(' '); 1916 printf("%s", cp); 1917 } 1918 1919 putchar('\n'); 1920 free(buf); 1921} 1922 1923void 1924clone_create(void) | 1006static __constructor void 1007ifconfig_ctor(void) |
1925{ | 1008{ |
1926 int s; | 1009#define N(a) (sizeof(a) / sizeof(a[0])) 1010 int i; |
1927 | 1011 |
1928 s = socket(AF_INET, SOCK_DGRAM, 0); 1929 if (s == -1) 1930 err(1, "socket"); 1931 1932 memset(&ifr, 0, sizeof(ifr)); 1933 (void) strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); 1934 if (ioctl(s, SIOCIFCREATE, &ifr) < 0) 1935 err(1, "SIOCIFCREATE"); 1936 1937 /* 1938 * If we get a different name back then we put in, we probably 1939 * want to print it out, but we might change our mind later so 1940 * we just signal our intrest and leave the printout for later. 1941 */ 1942 if (strcmp(name, ifr.ifr_name) != 0) { 1943 printname = 1; 1944 strlcpy(name, ifr.ifr_name, sizeof(name)); 1945 } 1946 1947 close(s); | 1012 for (i = 0; i < N(basic_cmds); i++) 1013 cmd_register(&basic_cmds[i]); 1014#undef N |
1948} | 1015} |
1949 1950void 1951clone_destroy(const char *val, int d, int s, const struct afswtch *rafp) 1952{ 1953 1954 (void) strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); 1955 if (ioctl(s, SIOCIFDESTROY, &ifr) < 0) 1956 err(1, "SIOCIFDESTROY"); 1957 /* 1958 * If we create and destroy an interface in the same command, 1959 * there isn't any reason to print it's name. 1960 */ 1961 printname = 0; 1962} | |