Deleted Added
full compact
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 = &ifr;
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 = &ifr;
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}