Bug Summary

File:src/sbin/ifconfig/ifconfig.c
Warning:line 920, column 5
Called function pointer is null (null dereference)

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name ifconfig.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/sbin/ifconfig/obj -resource-dir /usr/local/lib/clang/13.0.0 -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/sbin/ifconfig/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/sbin/ifconfig/ifconfig.c
1/* $OpenBSD: ifconfig.c,v 1.451 2021/11/23 19:13:45 kn Exp $ */
2/* $NetBSD: ifconfig.c,v 1.40 1997/10/01 02:19:43 enami Exp $ */
3
4/*
5 * Copyright (c) 1983, 1993
6 * The Regents of the University of California. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the University nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32
33/*-
34 * Copyright (c) 1997, 1998, 2000 The NetBSD Foundation, Inc.
35 * All rights reserved.
36 *
37 * This code is derived from software contributed to The NetBSD Foundation
38 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
39 * NASA Ames Research Center.
40 *
41 * Redistribution and use in source and binary forms, with or without
42 * modification, are permitted provided that the following conditions
43 * are met:
44 * 1. Redistributions of source code must retain the above copyright
45 * notice, this list of conditions and the following disclaimer.
46 * 2. Redistributions in binary form must reproduce the above copyright
47 * notice, this list of conditions and the following disclaimer in the
48 * documentation and/or other materials provided with the distribution.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
51 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
52 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
53 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
54 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
55 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
56 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
57 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
58 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
59 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
60 * POSSIBILITY OF SUCH DAMAGE.
61 */
62
63#include <sys/socket.h>
64#include <sys/ioctl.h>
65#include <sys/time.h>
66
67#include <net/if.h>
68#include <net/if_dl.h>
69#include <net/if_media.h>
70#include <net/if_types.h>
71#include <netinet/in.h>
72#include <netinet/in_var.h>
73#include <netinet6/in6_var.h>
74#include <netinet6/nd6.h>
75#include <arpa/inet.h>
76#include <netinet/ip_ipsp.h>
77#include <netinet/if_ether.h>
78#include <net80211/ieee80211.h>
79#include <net80211/ieee80211_ioctl.h>
80#include <net/pfvar.h>
81#include <net/if_pfsync.h>
82#include <net/if_pflow.h>
83#include <net/if_pppoe.h>
84#include <net/if_trunk.h>
85#include <net/if_wg.h>
86#include <net/trunklacp.h>
87#include <net/if_sppp.h>
88#include <net/ppp_defs.h>
89
90#include <netinet/ip_carp.h>
91
92#include <netdb.h>
93
94#include <net/if_vlan_var.h>
95
96#include <netmpls/mpls.h>
97
98#include <ctype.h>
99#include <err.h>
100#include <errno(*__errno()).h>
101#include <stdio.h>
102#include <stdint.h>
103#include <stdlib.h>
104#include <stddef.h>
105#include <string.h>
106#include <unistd.h>
107#include <limits.h>
108#include <resolv.h>
109#include <util.h>
110#include <ifaddrs.h>
111
112#ifndef SMALL
113#include <dev/usb/mbim.h>
114#include <dev/usb/if_umb.h>
115#endif /* SMALL */
116
117#include "ifconfig.h"
118
119#define MINIMUM(a, b)(((a) < (b)) ? (a) : (b)) (((a) < (b)) ? (a) : (b))
120#define MAXIMUM(a, b)(((a) > (b)) ? (a) : (b)) (((a) > (b)) ? (a) : (b))
121
122#define HWFEATURESBITS"\024\1CSUM_IPv4\2CSUM_TCPv4\3CSUM_UDPv4" "\5VLAN_MTU\6VLAN_HWTAGGING\10CSUM_TCPv6"
"\11CSUM_UDPv6\20WOL"
\
123 "\024\1CSUM_IPv4\2CSUM_TCPv4\3CSUM_UDPv4" \
124 "\5VLAN_MTU\6VLAN_HWTAGGING\10CSUM_TCPv6" \
125 "\11CSUM_UDPv6\20WOL"
126
127struct ifencap {
128 unsigned int ife_flags;
129#define IFE_VNETID_MASK0xf 0xf
130#define IFE_VNETID_NOPE0x0 0x0
131#define IFE_VNETID_NONE0x1 0x1
132#define IFE_VNETID_ANY0x2 0x2
133#define IFE_VNETID_SET0x3 0x3
134 int64_t ife_vnetid;
135#define IFE_VNETFLOWID0x10 0x10
136
137#define IFE_PARENT_MASK0xf00 0xf00
138#define IFE_PARENT_NOPE0x000 0x000
139#define IFE_PARENT_NONE0x100 0x100
140#define IFE_PARENT_SET0x200 0x200
141 char ife_parent[IFNAMSIZ16];
142
143#define IFE_TXHPRIO_SET0x1000 0x1000
144 int ife_txhprio;
145#define IFE_RXHPRIO_SET0x2000 0x2000
146 int ife_rxhprio;
147};
148
149struct ifreq ifr, ridreq;
150struct in_aliasreq in_addreq;
151struct in6_ifreq ifr6;
152struct in6_ifreq in6_ridreq;
153struct in6_aliasreq in6_addreq;
154struct sockaddr_in netmask;
155
156#ifndef SMALL
157struct ifaliasreq addreq;
158
159int wconfig = 0;
160int wcwconfig = 0;
161int rdomainid;
162#endif /* SMALL */
163
164char ifname[IFNAMSIZ16];
165int flags, xflags, setaddr, setipdst, doalias;
166u_long metric, mtu;
167int llprio;
168int clearaddr, sock;
169int newaddr = 0;
170int af = AF_INET2;
171int explicit_prefix = 0;
172int Lflag = 1;
173int show_join = 0;
174
175int showmediaflag;
176int showcapsflag;
177int shownet80211chans;
178int shownet80211nodes;
179int showclasses;
180int showtransceiver;
181
182struct ifencap;
183
184struct ieee80211_join join;
185
186const char *lacpmodeactive = "active";
187const char *lacpmodepassive = "passive";
188const char *lacptimeoutfast = "fast";
189const char *lacptimeoutslow = "slow";
190
191void notealias(const char *, int);
192void setifaddr(const char *, int);
193void setiflladdr(const char *, int);
194void setifdstaddr(const char *, int);
195void setifflags(const char *, int);
196void setifxflags(const char *, int);
197void addaf(const char *, int);
198void removeaf(const char *, int);
199void setifbroadaddr(const char *, int);
200void setifmtu(const char *, int);
201void setifllprio(const char *, int);
202void setifnwid(const char *, int);
203void setifjoin(const char *, int);
204void delifjoin(const char *, int);
205void delifjoinlist(const char *, int);
206void showjoin(const char *, int);
207void setifbssid(const char *, int);
208void setifnwkey(const char *, int);
209void setifwpa(const char *, int);
210void setifwpaprotos(const char *, int);
211void setifwpaakms(const char *, int);
212void setifwpaciphers(const char *, int);
213void setifwpagroupcipher(const char *, int);
214void setifwpakey(const char *, int);
215void setifchan(const char *, int);
216void setifscan(const char *, int);
217void setifnwflag(const char *, int);
218void unsetifnwflag(const char *, int);
219void setifnetmask(const char *, int);
220void setifprefixlen(const char *, int);
221void setvnetid(const char *, int);
222void delvnetid(const char *, int);
223void getvnetid(struct ifencap *);
224void setifparent(const char *, int);
225void delifparent(const char *, int);
226void getifparent(struct ifencap *);
227void getencap(void);
228void setia6flags(const char *, int);
229void setia6pltime(const char *, int);
230void setia6vltime(const char *, int);
231void setia6lifetime(const char *, const char *);
232void setia6eui64(const char *, int);
233void setmedia(const char *, int);
234void setmediaopt(const char *, int);
235void setmediamode(const char *, int);
236void unsetmediamode(const char *, int);
237void clone_create(const char *, int);
238void clone_destroy(const char *, int);
239void unsetmediaopt(const char *, int);
240void setmediainst(const char *, int);
241int prefix(void *val, int);
242void getifgroups(void);
243void setifgroup(const char *, int);
244void unsetifgroup(const char *, int);
245void setgroupattribs(char *, int, char *[]);
246int printgroup(char *, int);
247void setautoconf(const char *, int);
248void settemporary(const char *, int);
249void settrunkport(const char *, int);
250void unsettrunkport(const char *, int);
251void settrunkproto(const char *, int);
252void settrunklacpmode(const char *, int);
253void settrunklacptimeout(const char *, int);
254void trunk_status(void);
255void list_cloners(void);
256
257#ifndef SMALL
258void setifrtlabel(const char *, int);
259void setrdomain(const char *, int);
260void unsetrdomain(const char *, int);
261void setkeepalive(const char *, const char *);
262void unsetkeepalive(const char *, int);
263void carp_status(void);
264void setcarp_advbase(const char *,int);
265void setcarp_advskew(const char *, int);
266void setcarppeer(const char *, int);
267void unsetcarppeer(const char *, int);
268void setcarp_passwd(const char *, int);
269void setcarp_vhid(const char *, int);
270void setcarp_state(const char *, int);
271void setcarpdev(const char *, int);
272void setcarp_nodes(const char *, int);
273void setcarp_balancing(const char *, int);
274void setpfsync_syncdev(const char *, int);
275void setpfsync_maxupd(const char *, int);
276void unsetpfsync_syncdev(const char *, int);
277void setpfsync_syncpeer(const char *, int);
278void unsetpfsync_syncpeer(const char *, int);
279void setpfsync_defer(const char *, int);
280void pfsync_status(void);
281void setvnetflowid(const char *, int);
282void delvnetflowid(const char *, int);
283void getvnetflowid(struct ifencap *);
284void gettxprio(struct ifencap *);
285void settxprio(const char *, int);
286void getrxprio(struct ifencap *);
287void setrxprio(const char *, int);
288void setmplslabel(const char *, int);
289void unsetmplslabel(const char *, int);
290void setpwe3cw(const char *, int);
291void unsetpwe3cw(const char *, int);
292void setpwe3fat(const char *, int);
293void unsetpwe3fat(const char *, int);
294void setpwe3neighbor(const char *, const char *);
295void unsetpwe3neighbor(const char *, int);
296void mpls_status(void);
297void settunnel(const char *, const char *);
298void settunneladdr(const char *, int);
299void deletetunnel(const char *, int);
300void settunnelinst(const char *, int);
301void unsettunnelinst(const char *, int);
302void settunnelttl(const char *, int);
303void settunneldf(const char *, int);
304void settunnelnodf(const char *, int);
305void settunnelecn(const char *, int);
306void settunnelnoecn(const char *, int);
307void setpppoe_dev(const char *,int);
308void setpppoe_svc(const char *,int);
309void setpppoe_ac(const char *,int);
310void pppoe_status(void);
311void setspppproto(const char *, int);
312void setspppname(const char *, int);
313void setspppkey(const char *, int);
314void setsppppeerproto(const char *, int);
315void setsppppeername(const char *, int);
316void setsppppeerkey(const char *, int);
317void setsppppeerflag(const char *, int);
318void unsetsppppeerflag(const char *, int);
319void sppp_status(void);
320void sppp_printproto(const char *, struct sauthreq *);
321void setifpriority(const char *, int);
322void setifpowersave(const char *, int);
323void setifmetric(const char *, int);
324void pflow_status(void);
325void pflow_addr(const char*, struct sockaddr_storage *);
326void setpflow_sender(const char *, int);
327void unsetpflow_sender(const char *, int);
328void setpflow_receiver(const char *, int);
329void unsetpflow_receiver(const char *, int);
330void setpflowproto(const char *, int);
331void setifipdst(const char *, int);
332void setifdesc(const char *, int);
333void unsetifdesc(const char *, int);
334void printifhwfeatures(const char *, int);
335void setpair(const char *, int);
336void unsetpair(const char *, int);
337void umb_status(void);
338void umb_printclasses(char *, int);
339int umb_parse_classes(const char *);
340void umb_setpin(const char *, int);
341void umb_chgpin(const char *, const char *);
342void umb_puk(const char *, const char *);
343void umb_pinop(int, int, const char *, const char *);
344void umb_apn(const char *, int);
345void umb_setclass(const char *, int);
346void umb_roaming(const char *, int);
347void utf16_to_char(uint16_t *, int, char *, size_t);
348int char_to_utf16(const char *, uint16_t *, size_t);
349void transceiver(const char *, int);
350void transceiverdump(const char *, int);
351
352/* WG */
353void setwgpeer(const char *, int);
354void setwgpeerep(const char *, const char *);
355void setwgpeeraip(const char *, int);
356void setwgpeerpsk(const char *, int);
357void setwgpeerpka(const char *, int);
358void setwgport(const char *, int);
359void setwgkey(const char *, int);
360void setwgrtable(const char *, int);
361
362void unsetwgpeer(const char *, int);
363void unsetwgpeerpsk(const char *, int);
364void unsetwgpeerall(const char *, int);
365
366void wg_status();
367#else
368void setignore(const char *, int);
369#endif
370
371/*
372 * Media stuff. Whenever a media command is first performed, the
373 * currently select media is grabbed for this interface. If `media'
374 * is given, the current media word is modified. `mediaopt' commands
375 * only modify the set and clear words. They then operate on the
376 * current media word later.
377 */
378uint64_t media_current;
379uint64_t mediaopt_set;
380uint64_t mediaopt_clear;
381
382int actions; /* Actions performed */
383
384#define A_MEDIA0x0001 0x0001 /* media command */
385#define A_MEDIAOPTSET0x0002 0x0002 /* mediaopt command */
386#define A_MEDIAOPTCLR0x0004 0x0004 /* -mediaopt command */
387#define A_MEDIAOPT(0x0002|0x0004) (A_MEDIAOPTSET0x0002|A_MEDIAOPTCLR0x0004)
388#define A_MEDIAINST0x0008 0x0008 /* instance or inst command */
389#define A_MEDIAMODE0x0010 0x0010 /* mode command */
390#define A_JOIN0x0020 0x0020 /* join */
391#define A_WIREGUARD0x0040 0x0040 /* any WireGuard command */
392#define A_SILENT0x8000000 0x8000000 /* doing operation, do not print */
393
394#define NEXTARG00xffffff 0xffffff
395#define NEXTARG0xfffffe 0xfffffe
396#define NEXTARG20xfffffd 0xfffffd
397
398const struct cmd {
399 char *c_name;
400 int c_parameter; /* NEXTARG means next argv */
401 int c_action; /* defered action */
402 void (*c_func)(const char *, int);
403 void (*c_func2)(const char *, const char *);
404} cmds[] = {
405 { "up", IFF_UP0x1, 0, setifflags } ,
406 { "down", -IFF_UP0x1, 0, setifflags },
407 { "arp", -IFF_NOARP0x80, 0, setifflags },
408 { "-arp", IFF_NOARP0x80, 0, setifflags },
409 { "debug", IFF_DEBUG0x4, 0, setifflags },
410 { "-debug", -IFF_DEBUG0x4, 0, setifflags },
411 { "alias", IFF_UP0x1, 0, notealias },
412 { "-alias", -IFF_UP0x1, 0, notealias },
413 { "delete", -IFF_UP0x1, 0, notealias },
414 { "netmask", NEXTARG0xfffffe, 0, setifnetmask },
415 { "mtu", NEXTARG0xfffffe, 0, setifmtu },
416 { "nwid", NEXTARG0xfffffe, 0, setifnwid },
417 { "-nwid", -1, 0, setifnwid },
418 { "join", NEXTARG0xfffffe, 0, setifjoin },
419 { "-join", NEXTARG0xfffffe, 0, delifjoin },
420 { "joinlist", NEXTARG00xffffff, 0, showjoin },
421 { "-joinlist", -1, 0, delifjoinlist },
422 { "bssid", NEXTARG0xfffffe, 0, setifbssid },
423 { "-bssid", -1, 0, setifbssid },
424 { "nwkey", NEXTARG0xfffffe, 0, setifnwkey },
425 { "-nwkey", -1, 0, setifnwkey },
426 { "wpa", 1, 0, setifwpa },
427 { "-wpa", 0, 0, setifwpa },
428 { "wpaakms", NEXTARG0xfffffe, 0, setifwpaakms },
429 { "wpaciphers", NEXTARG0xfffffe, 0, setifwpaciphers },
430 { "wpagroupcipher", NEXTARG0xfffffe, 0, setifwpagroupcipher },
431 { "wpaprotos", NEXTARG0xfffffe, 0, setifwpaprotos },
432 { "wpakey", NEXTARG0xfffffe, 0, setifwpakey },
433 { "-wpakey", -1, 0, setifwpakey },
434 { "chan", NEXTARG00xffffff, 0, setifchan },
435 { "-chan", -1, 0, setifchan },
436 { "scan", NEXTARG00xffffff, 0, setifscan },
437 { "broadcast", NEXTARG0xfffffe, 0, setifbroadaddr },
438 { "prefixlen", NEXTARG0xfffffe, 0, setifprefixlen},
439 { "vnetid", NEXTARG0xfffffe, 0, setvnetid },
440 { "-vnetid", 0, 0, delvnetid },
441 { "parent", NEXTARG0xfffffe, 0, setifparent },
442 { "-parent", 1, 0, delifparent },
443 { "vlan", NEXTARG0xfffffe, 0, setvnetid },
444 { "-vlan", 0, 0, delvnetid },
445 { "vlandev", NEXTARG0xfffffe, 0, setifparent },
446 { "-vlandev", 1, 0, delifparent },
447 { "group", NEXTARG0xfffffe, 0, setifgroup },
448 { "-group", NEXTARG0xfffffe, 0, unsetifgroup },
449 { "autoconf", 1, 0, setautoconf },
450 { "-autoconf", -1, 0, setautoconf },
451 { "trunkport", NEXTARG0xfffffe, 0, settrunkport },
452 { "-trunkport", NEXTARG0xfffffe, 0, unsettrunkport },
453 { "trunkproto", NEXTARG0xfffffe, 0, settrunkproto },
454 { "lacpmode", NEXTARG0xfffffe, 0, settrunklacpmode },
455 { "lacptimeout", NEXTARG0xfffffe, 0, settrunklacptimeout },
456 { "anycast", IN6_IFF_ANYCAST0x01, 0, setia6flags },
457 { "-anycast", -IN6_IFF_ANYCAST0x01, 0, setia6flags },
458 { "tentative", IN6_IFF_TENTATIVE0x02, 0, setia6flags },
459 { "-tentative", -IN6_IFF_TENTATIVE0x02, 0, setia6flags },
460 { "pltime", NEXTARG0xfffffe, 0, setia6pltime },
461 { "vltime", NEXTARG0xfffffe, 0, setia6vltime },
462 { "eui64", 0, 0, setia6eui64 },
463 { "temporary", 1, 0, settemporary },
464 { "-temporary", -1, 0, settemporary },
465 { "soii", -IFXF_INET6_NOSOII0x40, 0, setifxflags },
466 { "-soii", IFXF_INET6_NOSOII0x40, 0, setifxflags },
467 { "monitor", IFXF_MONITOR0x100, 0, setifxflags },
468 { "-monitor", -IFXF_MONITOR0x100, 0, setifxflags },
469#ifndef SMALL
470 { "hwfeatures", NEXTARG00xffffff, 0, printifhwfeatures },
471 { "metric", NEXTARG0xfffffe, 0, setifmetric },
472 { "powersave", NEXTARG00xffffff, 0, setifpowersave },
473 { "-powersave", -1, 0, setifpowersave },
474 { "priority", NEXTARG0xfffffe, 0, setifpriority },
475 { "rtlabel", NEXTARG0xfffffe, 0, setifrtlabel },
476 { "-rtlabel", -1, 0, setifrtlabel },
477 { "rdomain", NEXTARG0xfffffe, 0, setrdomain },
478 { "-rdomain", 0, 0, unsetrdomain },
479 { "staticarp", IFF_STATICARP0x20, 0, setifflags },
480 { "-staticarp", -IFF_STATICARP0x20, 0, setifflags },
481 { "mpls", IFXF_MPLS0x8, 0, setifxflags },
482 { "-mpls", -IFXF_MPLS0x8, 0, setifxflags },
483 { "mplslabel", NEXTARG0xfffffe, 0, setmplslabel },
484 { "-mplslabel", 0, 0, unsetmplslabel },
485 { "pwecw", 0, 0, setpwe3cw },
486 { "-pwecw", 0, 0, unsetpwe3cw },
487 { "pwefat", 0, 0, setpwe3fat },
488 { "-pwefat", 0, 0, unsetpwe3fat },
489 { "pweneighbor", NEXTARG20xfffffd, 0, NULL((void*)0), setpwe3neighbor },
490 { "-pweneighbor", 0, 0, unsetpwe3neighbor },
491 { "advbase", NEXTARG0xfffffe, 0, setcarp_advbase },
492 { "advskew", NEXTARG0xfffffe, 0, setcarp_advskew },
493 { "carppeer", NEXTARG0xfffffe, 0, setcarppeer },
494 { "-carppeer", 1, 0, unsetcarppeer },
495 { "pass", NEXTARG0xfffffe, 0, setcarp_passwd },
496 { "vhid", NEXTARG0xfffffe, 0, setcarp_vhid },
497 { "state", NEXTARG0xfffffe, 0, setcarp_state },
498 { "carpdev", NEXTARG0xfffffe, 0, setcarpdev },
499 { "carpnodes", NEXTARG0xfffffe, 0, setcarp_nodes },
500 { "balancing", NEXTARG0xfffffe, 0, setcarp_balancing },
501 { "syncdev", NEXTARG0xfffffe, 0, setpfsync_syncdev },
502 { "-syncdev", 1, 0, unsetpfsync_syncdev },
503 { "syncif", NEXTARG0xfffffe, 0, setpfsync_syncdev },
504 { "-syncif", 1, 0, unsetpfsync_syncdev },
505 { "syncpeer", NEXTARG0xfffffe, 0, setpfsync_syncpeer },
506 { "-syncpeer", 1, 0, unsetpfsync_syncpeer },
507 { "maxupd", NEXTARG0xfffffe, 0, setpfsync_maxupd },
508 { "defer", 1, 0, setpfsync_defer },
509 { "-defer", 0, 0, setpfsync_defer },
510 { "tunnel", NEXTARG20xfffffd, 0, NULL((void*)0), settunnel },
511 { "tunneladdr", NEXTARG0xfffffe, 0, settunneladdr },
512 { "-tunnel", 0, 0, deletetunnel },
513 { "tunneldomain", NEXTARG0xfffffe, 0, settunnelinst },
514 { "-tunneldomain", 0, 0, unsettunnelinst },
515 { "tunnelttl", NEXTARG0xfffffe, 0, settunnelttl },
516 { "tunneldf", 0, 0, settunneldf },
517 { "-tunneldf", 0, 0, settunnelnodf },
518 { "tunnelecn", 0, 0, settunnelecn },
519 { "-tunnelecn", 0, 0, settunnelnoecn },
520 { "vnetflowid", 0, 0, setvnetflowid },
521 { "-vnetflowid", 0, 0, delvnetflowid },
522 { "txprio", NEXTARG0xfffffe, 0, settxprio },
523 { "rxprio", NEXTARG0xfffffe, 0, setrxprio },
524 { "pppoedev", NEXTARG0xfffffe, 0, setpppoe_dev },
525 { "pppoesvc", NEXTARG0xfffffe, 0, setpppoe_svc },
526 { "-pppoesvc", 1, 0, setpppoe_svc },
527 { "pppoeac", NEXTARG0xfffffe, 0, setpppoe_ac },
528 { "-pppoeac", 1, 0, setpppoe_ac },
529 { "authproto", NEXTARG0xfffffe, 0, setspppproto },
530 { "authname", NEXTARG0xfffffe, 0, setspppname },
531 { "authkey", NEXTARG0xfffffe, 0, setspppkey },
532 { "peerproto", NEXTARG0xfffffe, 0, setsppppeerproto },
533 { "peername", NEXTARG0xfffffe, 0, setsppppeername },
534 { "peerkey", NEXTARG0xfffffe, 0, setsppppeerkey },
535 { "peerflag", NEXTARG0xfffffe, 0, setsppppeerflag },
536 { "-peerflag", NEXTARG0xfffffe, 0, unsetsppppeerflag },
537 { "nwflag", NEXTARG0xfffffe, 0, setifnwflag },
538 { "-nwflag", NEXTARG0xfffffe, 0, unsetifnwflag },
539 { "flowsrc", NEXTARG0xfffffe, 0, setpflow_sender },
540 { "-flowsrc", 1, 0, unsetpflow_sender },
541 { "flowdst", NEXTARG0xfffffe, 0, setpflow_receiver },
542 { "-flowdst", 1, 0, unsetpflow_receiver },
543 { "pflowproto", NEXTARG0xfffffe, 0, setpflowproto },
544 { "-inet", AF_INET2, 0, removeaf },
545 { "-inet6", AF_INET624, 0, removeaf },
546 { "keepalive", NEXTARG20xfffffd, 0, NULL((void*)0), setkeepalive },
547 { "-keepalive", 1, 0, unsetkeepalive },
548 { "add", NEXTARG0xfffffe, 0, bridge_add },
549 { "del", NEXTARG0xfffffe, 0, bridge_delete },
550 { "addspan", NEXTARG0xfffffe, 0, bridge_addspan },
551 { "delspan", NEXTARG0xfffffe, 0, bridge_delspan },
552 { "discover", NEXTARG0xfffffe, 0, setdiscover },
553 { "-discover", NEXTARG0xfffffe, 0, unsetdiscover },
554 { "blocknonip", NEXTARG0xfffffe, 0, setblocknonip },
555 { "-blocknonip",NEXTARG0xfffffe, 0, unsetblocknonip },
556 { "learn", NEXTARG0xfffffe, 0, setlearn },
557 { "-learn", NEXTARG0xfffffe, 0, unsetlearn },
558 { "stp", NEXTARG0xfffffe, 0, setstp },
559 { "-stp", NEXTARG0xfffffe, 0, unsetstp },
560 { "edge", NEXTARG0xfffffe, 0, setedge },
561 { "-edge", NEXTARG0xfffffe, 0, unsetedge },
562 { "autoedge", NEXTARG0xfffffe, 0, setautoedge },
563 { "-autoedge", NEXTARG0xfffffe, 0, unsetautoedge },
564 { "protected", NEXTARG20xfffffd, 0, NULL((void*)0), bridge_protect },
565 { "-protected", NEXTARG0xfffffe, 0, bridge_unprotect },
566 { "ptp", NEXTARG0xfffffe, 0, setptp },
567 { "-ptp", NEXTARG0xfffffe, 0, unsetptp },
568 { "autoptp", NEXTARG0xfffffe, 0, setautoptp },
569 { "-autoptp", NEXTARG0xfffffe, 0, unsetautoptp },
570 { "flush", 0, 0, bridge_flush },
571 { "flushall", 0, 0, bridge_flushall },
572 { "static", NEXTARG20xfffffd, 0, NULL((void*)0), bridge_addaddr },
573 { "deladdr", NEXTARG0xfffffe, 0, bridge_deladdr },
574 { "maxaddr", NEXTARG0xfffffe, 0, bridge_maxaddr },
575 { "addr", 0, 0, bridge_addrs },
576 { "hellotime", NEXTARG0xfffffe, 0, bridge_hellotime },
577 { "fwddelay", NEXTARG0xfffffe, 0, bridge_fwddelay },
578 { "maxage", NEXTARG0xfffffe, 0, bridge_maxage },
579 { "proto", NEXTARG0xfffffe, 0, bridge_proto },
580 { "ifpriority", NEXTARG20xfffffd, 0, NULL((void*)0), bridge_ifprio },
581 { "ifcost", NEXTARG20xfffffd, 0, NULL((void*)0), bridge_ifcost },
582 { "-ifcost", NEXTARG0xfffffe, 0, bridge_noifcost },
583 { "timeout", NEXTARG0xfffffe, 0, bridge_timeout },
584 { "holdcnt", NEXTARG0xfffffe, 0, bridge_holdcnt },
585 { "spanpriority", NEXTARG0xfffffe, 0, bridge_priority },
586 { "ipdst", NEXTARG0xfffffe, 0, setifipdst },
587#if 0
588 /* XXX `rule` special-cased below */
589 { "rule", 0, 0, bridge_rule },
590#endif
591 { "rules", NEXTARG0xfffffe, 0, bridge_rules },
592 { "rulefile", NEXTARG0xfffffe, 0, bridge_rulefile },
593 { "flushrule", NEXTARG0xfffffe, 0, bridge_flushrule },
594 { "description", NEXTARG0xfffffe, 0, setifdesc },
595 { "descr", NEXTARG0xfffffe, 0, setifdesc },
596 { "-description", 1, 0, unsetifdesc },
597 { "-descr", 1, 0, unsetifdesc },
598 { "wol", IFXF_WOL0x10, 0, setifxflags },
599 { "-wol", -IFXF_WOL0x10, 0, setifxflags },
600 { "pin", NEXTARG0xfffffe, 0, umb_setpin },
601 { "chgpin", NEXTARG20xfffffd, 0, NULL((void*)0), umb_chgpin },
602 { "puk", NEXTARG20xfffffd, 0, NULL((void*)0), umb_puk },
603 { "apn", NEXTARG0xfffffe, 0, umb_apn },
604 { "-apn", -1, 0, umb_apn },
605 { "class", NEXTARG00xffffff, 0, umb_setclass },
606 { "-class", -1, 0, umb_setclass },
607 { "roaming", 1, 0, umb_roaming },
608 { "-roaming", 0, 0, umb_roaming },
609 { "patch", NEXTARG0xfffffe, 0, setpair },
610 { "-patch", 1, 0, unsetpair },
611 { "addlocal", NEXTARG0xfffffe, 0, addlocal },
612 { "transceiver", NEXTARG00xffffff, 0, transceiver },
613 { "sff", NEXTARG00xffffff, 0, transceiver },
614 { "sffdump", 0, 0, transceiverdump },
615
616 { "wgpeer", NEXTARG0xfffffe, A_WIREGUARD0x0040, setwgpeer},
617 { "wgendpoint", NEXTARG20xfffffd, A_WIREGUARD0x0040, NULL((void*)0), setwgpeerep},
618 { "wgaip", NEXTARG0xfffffe, A_WIREGUARD0x0040, setwgpeeraip},
619 { "wgpsk", NEXTARG0xfffffe, A_WIREGUARD0x0040, setwgpeerpsk},
620 { "wgpka", NEXTARG0xfffffe, A_WIREGUARD0x0040, setwgpeerpka},
621 { "wgport", NEXTARG0xfffffe, A_WIREGUARD0x0040, setwgport},
622 { "wgkey", NEXTARG0xfffffe, A_WIREGUARD0x0040, setwgkey},
623 { "wgrtable", NEXTARG0xfffffe, A_WIREGUARD0x0040, setwgrtable},
624 { "-wgpeer", NEXTARG0xfffffe, A_WIREGUARD0x0040, unsetwgpeer},
625 { "-wgpsk", 0, A_WIREGUARD0x0040, unsetwgpeerpsk},
626 { "-wgpeerall", 0, A_WIREGUARD0x0040, unsetwgpeerall},
627
628#else /* SMALL */
629 { "powersave", NEXTARG00xffffff, 0, setignore },
630 { "priority", NEXTARG0xfffffe, 0, setignore },
631 { "rtlabel", NEXTARG0xfffffe, 0, setignore },
632 { "mpls", IFXF_MPLS0x8, 0, setignore },
633 { "nwflag", NEXTARG0xfffffe, 0, setignore },
634 { "rdomain", NEXTARG0xfffffe, 0, setignore },
635 { "-inet", AF_INET2, 0, removeaf },
636 { "-inet6", AF_INET624, 0, removeaf },
637 { "description", NEXTARG0xfffffe, 0, setignore },
638 { "descr", NEXTARG0xfffffe, 0, setignore },
639 { "wol", IFXF_WOL0x10, 0, setignore },
640 { "-wol", -IFXF_WOL0x10, 0, setignore },
641#endif /* SMALL */
642#if 0
643 /* XXX `create' special-cased below */
644 { "create", 0, 0, clone_create } ,
645#endif
646 { "destroy", 0, 0, clone_destroy } ,
647 { "link0", IFF_LINK00x1000, 0, setifflags } ,
648 { "-link0", -IFF_LINK00x1000, 0, setifflags } ,
649 { "link1", IFF_LINK10x2000, 0, setifflags } ,
650 { "-link1", -IFF_LINK10x2000, 0, setifflags } ,
651 { "link2", IFF_LINK20x4000, 0, setifflags } ,
652 { "-link2", -IFF_LINK20x4000, 0, setifflags } ,
653 { "media", NEXTARG00xffffff, A_MEDIA0x0001, setmedia },
654 { "mediaopt", NEXTARG0xfffffe, A_MEDIAOPTSET0x0002, setmediaopt },
655 { "-mediaopt", NEXTARG0xfffffe, A_MEDIAOPTCLR0x0004, unsetmediaopt },
656 { "mode", NEXTARG0xfffffe, A_MEDIAMODE0x0010, setmediamode },
657 { "-mode", 0, A_MEDIAMODE0x0010, unsetmediamode },
658 { "instance", NEXTARG0xfffffe, A_MEDIAINST0x0008, setmediainst },
659 { "inst", NEXTARG0xfffffe, A_MEDIAINST0x0008, setmediainst },
660 { "lladdr", NEXTARG0xfffffe, 0, setiflladdr },
661 { "llprio", NEXTARG0xfffffe, 0, setifllprio },
662 { NULL((void*)0), /*src*/ 0, 0, setifaddr },
663 { NULL((void*)0), /*dst*/ 0, 0, setifdstaddr },
664 { NULL((void*)0), /*illegal*/0, 0, NULL((void*)0) },
665};
666
667#define IFFBITS"\024\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\6STATICARP"
"\7RUNNING\10NOARP\11PROMISC\12ALLMULTI\13OACTIVE\14SIMPLEX"
"\15LINK0\16LINK1\17LINK2\20MULTICAST" "\23AUTOCONF6TEMP\24MPLS\25WOL\26AUTOCONF6\27INET6_NOSOII"
"\30AUTOCONF4" "\31MONITOR"
\
668 "\024\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\6STATICARP" \
669 "\7RUNNING\10NOARP\11PROMISC\12ALLMULTI\13OACTIVE\14SIMPLEX" \
670 "\15LINK0\16LINK1\17LINK2\20MULTICAST" \
671 "\23AUTOCONF6TEMP\24MPLS\25WOL\26AUTOCONF6\27INET6_NOSOII" \
672 "\30AUTOCONF4" "\31MONITOR"
673
674int getinfo(struct ifreq *, int);
675void getsock(int);
676void printgroupattribs(char *);
677void printif(char *, int);
678void printb_status(unsigned short, unsigned char *);
679const char *get_linkstate(int, int);
680void status(int, struct sockaddr_dl *, int);
681__dead__attribute__((__noreturn__)) void usage(void);
682const char *get_string(const char *, const char *, u_int8_t *, int *);
683int len_string(const u_int8_t *, int);
684int print_string(const u_int8_t *, int);
685char *sec2str(time_t);
686
687const char *get_media_type_string(uint64_t);
688const char *get_media_subtype_string(uint64_t);
689uint64_t get_media_mode(uint64_t, const char *);
690uint64_t get_media_subtype(uint64_t, const char *);
691uint64_t get_media_options(uint64_t, const char *);
692uint64_t lookup_media_word(const struct ifmedia_description *, uint64_t,
693 const char *);
694void print_media_word(uint64_t, int, int);
695void process_media_commands(void);
696void init_current_media(void);
697
698void process_join_commands(void);
699
700void process_wg_commands(void);
701
702unsigned long get_ts_map(int, int, int);
703
704void in_status(int);
705void in_getaddr(const char *, int);
706void in_getprefix(const char *, int);
707void in6_fillscopeid(struct sockaddr_in6 *);
708void in6_alias(struct in6_ifreq *);
709void in6_status(int);
710void in6_getaddr(const char *, int);
711void in6_getprefix(const char *, int);
712void ieee80211_status(void);
713void join_status(void);
714void ieee80211_listchans(void);
715void ieee80211_listnodes(void);
716void ieee80211_printnode(struct ieee80211_nodereq *);
717u_int getwpacipher(const char *);
718void print_cipherset(u_int32_t);
719
720void spppauthinfo(struct sauthreq *, int);
721void spppdnsinfo(struct sdnsreq *);
722
723/* Known address families */
724const struct afswtch {
725 char *af_name;
726 short af_af;
727 void (*af_status)(int);
728 void (*af_getaddr)(const char *, int);
729 void (*af_getprefix)(const char *, int);
730 u_long af_difaddr;
731 u_long af_aifaddr;
732 caddr_t af_ridreq;
733 caddr_t af_addreq;
734} afs[] = {
735#define C(x)((caddr_t) &x) ((caddr_t) &x)
736 { "inet", AF_INET2, in_status, in_getaddr, in_getprefix,
737 SIOCDIFADDR((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((25)))
, SIOCAIFADDR((unsigned long)0x80000000 | ((sizeof(struct ifaliasreq) &
0x1fff) << 16) | ((('i')) << 8) | ((26)))
, C(ridreq)((caddr_t) &ridreq), C(in_addreq)((caddr_t) &in_addreq) },
738 { "inet6", AF_INET624, in6_status, in6_getaddr, in6_getprefix,
739 SIOCDIFADDR_IN6((unsigned long)0x80000000 | ((sizeof(struct in6_ifreq) &
0x1fff) << 16) | ((('i')) << 8) | ((25)))
, SIOCAIFADDR_IN6((unsigned long)0x80000000 | ((sizeof(struct in6_aliasreq) &
0x1fff) << 16) | ((('i')) << 8) | ((26)))
, C(in6_ridreq)((caddr_t) &in6_ridreq), C(in6_addreq)((caddr_t) &in6_addreq) },
740 { 0, 0, 0, 0 }
741};
742
743const struct afswtch *afp; /*the address family being set or asked about*/
744
745char joinname[IEEE80211_NWID_LEN32];
746size_t joinlen;
747char nwidname[IEEE80211_NWID_LEN32];
748size_t nwidlen;
749
750int ifaliases = 0;
751int aflag = 0;
752
753int
754main(int argc, char *argv[])
755{
756 const struct afswtch *rafp = NULL((void*)0);
757 int create = 0;
758 int Cflag = 0;
759 int gflag = 0;
760 int found_rulefile = 0;
761 int i;
762
763 /* If no args at all, print all interfaces. */
764 if (argc < 2) {
1
Assuming 'argc' is >= 2
2
Taking false branch
765 /* no filesystem visibility */
766 if (unveil("/", "") == -1)
767 err(1, "unveil /");
768 if (unveil(NULL((void*)0), NULL((void*)0)) == -1)
769 err(1, "unveil");
770 aflag = 1;
771 printif(NULL((void*)0), 0);
772 return (0);
773 }
774 argc--, argv++;
775 if (*argv[0] == '-') {
3
Assuming the condition is false
4
Taking false branch
776 int nomore = 0;
777
778 for (i = 1; argv[0][i]; i++) {
779 switch (argv[0][i]) {
780 case 'a':
781 aflag = 1;
782 nomore = 1;
783 break;
784 case 'A':
785 aflag = 1;
786 ifaliases = 1;
787 nomore = 1;
788 break;
789 case 'g':
790 gflag = 1;
791 break;
792 case 'C':
793 Cflag = 1;
794 nomore = 1;
795 break;
796 default:
797 usage();
798 break;
799 }
800 }
801 if (nomore == 0) {
802 argc--, argv++;
803 if (argc < 1)
804 usage();
805 if (strlcpy(ifname, *argv, sizeof(ifname)) >= IFNAMSIZ16)
806 errx(1, "interface name '%s' too long", *argv);
807 }
808 } else if (strlcpy(ifname, *argv, sizeof(ifname)) >= IFNAMSIZ16)
5
Assuming the condition is false
6
Taking false branch
809 errx(1, "interface name '%s' too long", *argv);
810 argc--, argv++;
811
812 for (i = 0; i < argc; i++) {
7
Assuming 'i' is < 'argc'
8
Loop condition is true. Entering loop body
813 if (strcmp(argv[i], "rulefile") == 0) {
9
Taking true branch
814 found_rulefile = 1;
815 break;
10
Execution continues on line 819
816 }
817 }
818
819 if (!found_rulefile
10.1
'found_rulefile' is 1
) {
11
Taking false branch
820 if (unveil(_PATH_RESCONF"/etc/resolv.conf", "r") == -1)
821 err(1, "unveil %s", _PATH_RESCONF"/etc/resolv.conf");
822 if (unveil(_PATH_HOSTS"/etc/hosts", "r") == -1)
823 err(1, "unveil %s", _PATH_HOSTS"/etc/hosts");
824 if (unveil(_PATH_SERVICES"/etc/services", "r") == -1)
825 err(1, "unveil %s", _PATH_SERVICES"/etc/services");
826 if (unveil(NULL((void*)0), NULL((void*)0)) == -1)
827 err(1, "unveil");
828 }
829
830 if (argc
11.1
'argc' is > 0
> 0) {
12
Taking true branch
831 for (afp = rafp = afs; rafp->af_name; rafp++)
13
Loop condition is false. Execution continues on line 838
832 if (strcmp(rafp->af_name, *argv) == 0) {
833 afp = rafp;
834 argc--;
835 argv++;
836 break;
837 }
838 rafp = afp;
839 af = ifr.ifr_addrifr_ifru.ifru_addr.sa_family = rafp->af_af;
840 }
841 if (Cflag
13.1
'Cflag' is 0
) {
14
Taking false branch
842 if (argc > 0 || aflag)
843 usage();
844 list_cloners();
845 return (0);
846 }
847 if (gflag
14.1
'gflag' is 0
) {
15
Taking false branch
848 if (argc == 0)
849 printgroupattribs(ifname);
850 else
851 setgroupattribs(ifname, argc, argv);
852 return (0);
853 }
854 (void) strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
855
856 /* initialization */
857 in6_addreq.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME0xffffffff;
858 in6_addreq.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME0xffffffff;
859
860 /*
861 * NOTE: We must special-case the `create' command right
862 * here as we would otherwise fail in getinfo().
863 */
864 if (argc
15.1
'argc' is > 0
> 0 && strcmp(argv[0], "create") == 0) {
16
Assuming the condition is false
17
Taking false branch
865 clone_create(argv[0], 0);
866 argc--, argv++;
867 if (argc == 0)
868 return (0);
869 }
870 if (aflag
17.1
'aflag' is equal to 0
== 0) {
18
Taking true branch
871 create = (argc
18.1
'argc' is > 0
> 0) && strcmp(argv[0], "destroy") != 0;
872 (void)getinfo(&ifr, create);
873 }
874
875 if (argc
18.2
'argc' is not equal to 0
!= 0 && af
18.3
'af' is not equal to AF_INET6
== AF_INET624)
19
Taking false branch
876 addaf(ifname, AF_INET624);
877
878 while (argc
19.1
'argc' is > 0
> 0) {
20
Loop condition is true. Entering loop body
879 const struct cmd *p;
880
881 for (p = cmds; p->c_name; p++)
21
Loop condition is false. Execution continues on line 885
882 if (strcmp(*argv, p->c_name) == 0)
883 break;
884#ifndef SMALL
885 if (strcmp(*argv, "rule") == 0) {
22
Assuming the condition is false
23
Taking false branch
886 argc--, argv++;
887 return bridge_rule(argc, argv, -1);
888 }
889#endif
890 if (p->c_name
23.1
Field 'c_name' is equal to null
== 0 && setaddr)
24
Assuming 'setaddr' is 0
25
Taking false branch
891 for (i = setaddr; i > 0; i--) {
892 p++;
893 if (p->c_func == NULL((void*)0))
894 errx(1, "%s: bad value", *argv);
895 }
896 if (p->c_func || p->c_func2) {
26
Assuming field 'c_func' is null
27
Assuming field 'c_func2' is non-null
28
Taking true branch
897 if (p->c_parameter == NEXTARG00xffffff) {
29
Assuming field 'c_parameter' is not equal to NEXTARG0
30
Taking false branch
898 const struct cmd *p0;
899 int noarg = 1;
900
901 if (argv[1]) {
902 for (p0 = cmds; p0->c_name; p0++)
903 if (strcmp(argv[1],
904 p0->c_name) == 0) {
905 noarg = 0;
906 break;
907 }
908 } else
909 noarg = 0;
910
911 if (noarg == 0)
912 (*p->c_func)(NULL((void*)0), 0);
913 else
914 goto nextarg;
915 } else if (p->c_parameter == NEXTARG0xfffffe) {
31
Assuming field 'c_parameter' is equal to NEXTARG
32
Taking true branch
916nextarg:
917 if (argv[1] == NULL((void*)0))
33
Assuming the condition is false
34
Taking false branch
918 errx(1, "'%s' requires argument",
919 p->c_name);
920 (*p->c_func)(argv[1], 0);
35
Called function pointer is null (null dereference)
921 argc--, argv++;
922 actions = actions | A_SILENT0x8000000 | p->c_action;
923 } else if (p->c_parameter == NEXTARG20xfffffd) {
924 if ((argv[1] == NULL((void*)0)) ||
925 (argv[2] == NULL((void*)0)))
926 errx(1, "'%s' requires 2 arguments",
927 p->c_name);
928 (*p->c_func2)(argv[1], argv[2]);
929 argc -= 2;
930 argv += 2;
931 actions = actions | A_SILENT0x8000000 | p->c_action;
932 } else {
933 (*p->c_func)(*argv, p->c_parameter);
934 actions = actions | A_SILENT0x8000000 | p->c_action;
935 }
936 }
937 argc--, argv++;
938 }
939
940 if (argc == 0 && actions == 0) {
941 printif(ifr.ifr_name, aflag ? ifaliases : 1);
942 return (0);
943 }
944
945#ifndef SMALL
946 process_wg_commands();
947#endif
948
949 process_join_commands();
950
951 /* Process any media commands that may have been issued. */
952 process_media_commands();
953
954 if (af == AF_INET624 && explicit_prefix == 0) {
955 /*
956 * Aggregatable address architecture defines all prefixes
957 * are 64. So, it is convenient to set prefixlen to 64 if
958 * it is not specified. If we are setting a destination
959 * address on a point-to-point interface, 128 is required.
960 */
961 if (setipdst && (flags & IFF_POINTOPOINT0x10))
962 setifprefixlen("128", 0);
963 else
964 setifprefixlen("64", 0);
965 /* in6_getprefix("64", MASK) if MASK is available here... */
966 }
967
968 if (clearaddr) {
969 (void) strlcpy(rafp->af_ridreq, ifname, sizeof(ifr.ifr_name));
970 if (ioctl(sock, rafp->af_difaddr, rafp->af_ridreq) == -1) {
971 if (errno(*__errno()) == EADDRNOTAVAIL49 && (doalias >= 0)) {
972 /* means no previous address for interface */
973 } else
974 err(1, "SIOCDIFADDR");
975 }
976 }
977 if (newaddr) {
978 (void) strlcpy(rafp->af_addreq, ifname, sizeof(ifr.ifr_name));
979 if (ioctl(sock, rafp->af_aifaddr, rafp->af_addreq) == -1)
980 err(1, "SIOCAIFADDR");
981 }
982 return (0);
983}
984
985void
986getsock(int naf)
987{
988 static int oaf = -1;
989
990 if (oaf == naf)
991 return;
992 if (oaf != -1)
993 close(sock);
994 sock = socket(naf, SOCK_DGRAM2, 0);
995 if (sock == -1)
996 oaf = -1;
997 else
998 oaf = naf;
999}
1000
1001int
1002getinfo(struct ifreq *ifr, int create)
1003{
1004
1005 getsock(af);
1006 if (sock == -1)
1007 err(1, "socket");
1008 if (!isdigit((unsigned char)ifname[strlen(ifname) - 1]))
1009 return (-1); /* ignore groups here */
1010 if (ioctl(sock, SIOCGIFFLAGS(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((17)))
, (caddr_t)ifr) == -1) {
1011 int oerrno = errno(*__errno());
1012
1013 if (!create)
1014 return (-1);
1015 if (ioctl(sock, SIOCIFCREATE((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((122)))
, (caddr_t)ifr) == -1) {
1016 errno(*__errno()) = oerrno;
1017 return (-1);
1018 }
1019 if (ioctl(sock, SIOCGIFFLAGS(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((17)))
, (caddr_t)ifr) == -1)
1020 return (-1);
1021 }
1022 flags = ifr->ifr_flagsifr_ifru.ifru_flags & 0xffff;
1023 if (ioctl(sock, SIOCGIFXFLAGS(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((158)))
, (caddr_t)ifr) == -1)
1024 ifr->ifr_flagsifr_ifru.ifru_flags = 0;
1025 xflags = ifr->ifr_flagsifr_ifru.ifru_flags;
1026 if (ioctl(sock, SIOCGIFMETRIC(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((23)))
, (caddr_t)ifr) == -1)
1027 metric = 0;
1028 else
1029 metric = ifr->ifr_metricifr_ifru.ifru_metric;
1030#ifdef SMALL
1031 if (ioctl(sock, SIOCGIFMTU(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((126)))
, (caddr_t)ifr) == -1)
1032#else
1033 if (is_bridge() || ioctl(sock, SIOCGIFMTU(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((126)))
, (caddr_t)ifr) == -1)
1034#endif
1035 mtu = 0;
1036 else
1037 mtu = ifr->ifr_mtuifr_ifru.ifru_metric;
1038#ifndef SMALL
1039 if (ioctl(sock, SIOCGIFRDOMAIN(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((160)))
, (caddr_t)ifr) == -1)
1040 rdomainid = 0;
1041 else
1042 rdomainid = ifr->ifr_rdomainidifr_ifru.ifru_metric;
1043#endif
1044 if (ioctl(sock, SIOCGIFLLPRIO(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((182)))
, (caddr_t)ifr) == -1)
1045 llprio = 0;
1046 else
1047 llprio = ifr->ifr_llprioifr_ifru.ifru_metric;
1048
1049 return (0);
1050}
1051
1052int
1053printgroup(char *groupname, int ifaliases)
1054{
1055 struct ifgroupreq ifgr;
1056 struct ifg_req *ifg;
1057 int len, cnt = 0;
1058
1059 getsock(AF_INET2);
1060 bzero(&ifgr, sizeof(ifgr));
1061 strlcpy(ifgr.ifgr_name, groupname, sizeof(ifgr.ifgr_name));
1062 if (ioctl(sock, SIOCGIFGMEMB(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifgroupreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((138)))
, (caddr_t)&ifgr) == -1) {
1063 if (errno(*__errno()) == EINVAL22 || errno(*__errno()) == ENOTTY25 ||
1064 errno(*__errno()) == ENOENT2)
1065 return (-1);
1066 else
1067 err(1, "SIOCGIFGMEMB");
1068 }
1069
1070 len = ifgr.ifgr_len;
1071 if ((ifgr.ifgr_groupsifgr_ifgru.ifgru_groups = calloc(1, len)) == NULL((void*)0))
1072 err(1, "printgroup");
1073 if (ioctl(sock, SIOCGIFGMEMB(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifgroupreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((138)))
, (caddr_t)&ifgr) == -1)
1074 err(1, "SIOCGIFGMEMB");
1075
1076 for (ifg = ifgr.ifgr_groupsifgr_ifgru.ifgru_groups; ifg && len >= sizeof(struct ifg_req);
1077 ifg++) {
1078 len -= sizeof(struct ifg_req);
1079 printif(ifg->ifgrq_memberifgrq_ifgrqu.ifgrqu_member, ifaliases);
1080 cnt++;
1081 }
1082 free(ifgr.ifgr_groupsifgr_ifgru.ifgru_groups);
1083
1084 return (cnt);
1085}
1086
1087void
1088printgroupattribs(char *groupname)
1089{
1090 struct ifgroupreq ifgr;
1091
1092 getsock(AF_INET2);
1093 bzero(&ifgr, sizeof(ifgr));
1094 strlcpy(ifgr.ifgr_name, groupname, sizeof(ifgr.ifgr_name));
1095 if (ioctl(sock, SIOCGIFGATTR(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifgroupreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((139)))
, (caddr_t)&ifgr) == -1)
1096 err(1, "SIOCGIFGATTR");
1097
1098 printf("%s:", groupname);
1099 printf(" carp demote count %d", ifgr.ifgr_attribifgr_ifgru.ifgru_attrib.ifg_carp_demoted);
1100 printf("\n");
1101}
1102
1103void
1104setgroupattribs(char *groupname, int argc, char *argv[])
1105{
1106 const char *errstr;
1107 char *p = argv[0];
1108 int neg = 1;
1109
1110 struct ifgroupreq ifgr;
1111
1112 getsock(AF_INET2);
1113 bzero(&ifgr, sizeof(ifgr));
1114 strlcpy(ifgr.ifgr_name, groupname, sizeof(ifgr.ifgr_name));
1115
1116 if (argc > 1) {
1117 neg = strtonum(argv[1], 0, 128, &errstr);
1118 if (errstr)
1119 errx(1, "invalid carp demotion: %s", errstr);
1120 }
1121
1122 if (p[0] == '-') {
1123 neg = neg * -1;
1124 p++;
1125 }
1126 if (!strcmp(p, "carpdemote"))
1127 ifgr.ifgr_attribifgr_ifgru.ifgru_attrib.ifg_carp_demoted = neg;
1128 else
1129 usage();
1130
1131 if (ioctl(sock, SIOCSIFGATTR((unsigned long)0x80000000 | ((sizeof(struct ifgroupreq) &
0x1fff) << 16) | ((('i')) << 8) | ((140)))
, (caddr_t)&ifgr) == -1)
1132 err(1, "SIOCSIFGATTR");
1133}
1134
1135void
1136printif(char *name, int ifaliases)
1137{
1138 struct ifaddrs *ifap, *ifa;
1139 struct if_data *ifdata;
1140 const char *namep;
1141 char *oname = NULL((void*)0);
1142 struct ifreq *ifrp;
1143 int count = 0, noinet = 1;
1144 size_t nlen = 0;
1145
1146 if (aflag)
1147 name = NULL((void*)0);
1148 if (name) {
1149 if ((oname = strdup(name)) == NULL((void*)0))
1150 err(1, "strdup");
1151 nlen = strlen(oname);
1152 /* is it a group? */
1153 if (nlen && !isdigit((unsigned char)oname[nlen - 1]))
1154 if (printgroup(oname, ifaliases) != -1) {
1155 free(oname);
1156 return;
1157 }
1158 }
1159
1160 if (getifaddrs(&ifap) != 0)
1161 err(1, "getifaddrs");
1162
1163 namep = NULL((void*)0);
1164 for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
1165 if (oname) {
1166 if (nlen && isdigit((unsigned char)oname[nlen - 1])) {
1167 /* must have exact match */
1168 if (strcmp(oname, ifa->ifa_name) != 0)
1169 continue;
1170 } else {
1171 /* partial match OK if it ends w/ digit */
1172 if (strncmp(oname, ifa->ifa_name, nlen) != 0 ||
1173 !isdigit((unsigned char)ifa->ifa_name[nlen]))
1174 continue;
1175 }
1176 }
1177 /* quickhack: sizeof(ifr) < sizeof(ifr6) */
1178 if (ifa->ifa_addr != NULL((void*)0) &&
1179 ifa->ifa_addr->sa_family == AF_INET624) {
1180 memset(&ifr6, 0, sizeof(ifr6));
1181 memcpy(&ifr6.ifr_addrifr_ifru.ifru_addr, ifa->ifa_addr,
1182 MINIMUM(sizeof(ifr6.ifr_addr), ifa->ifa_addr->sa_len)(((sizeof(ifr6.ifr_ifru.ifru_addr)) < (ifa->ifa_addr->
sa_len)) ? (sizeof(ifr6.ifr_ifru.ifru_addr)) : (ifa->ifa_addr
->sa_len))
);
1183 ifrp = (struct ifreq *)&ifr6;
1184 } else if (ifa->ifa_addr != NULL((void*)0)) {
1185 memset(&ifr, 0, sizeof(ifr));
1186 memcpy(&ifr.ifr_addrifr_ifru.ifru_addr, ifa->ifa_addr,
1187 MINIMUM(sizeof(ifr.ifr_addr), ifa->ifa_addr->sa_len)(((sizeof(ifr.ifr_ifru.ifru_addr)) < (ifa->ifa_addr->
sa_len)) ? (sizeof(ifr.ifr_ifru.ifru_addr)) : (ifa->ifa_addr
->sa_len))
);
1188 ifrp = &ifr;
1189 }
1190 strlcpy(ifname, ifa->ifa_name, sizeof(ifname));
1191 strlcpy(ifrp->ifr_name, ifa->ifa_name, sizeof(ifrp->ifr_name));
1192
1193 if (ifa->ifa_addr != NULL((void*)0) &&
1194 ifa->ifa_addr->sa_family == AF_LINK18) {
1195 namep = ifa->ifa_name;
1196 if (getinfo(ifrp, 0) < 0)
1197 continue;
1198 ifdata = ifa->ifa_data;
1199 status(1, (struct sockaddr_dl *)ifa->ifa_addr,
1200 ifdata->ifi_link_state);
1201 count++;
1202 noinet = 1;
1203 continue;
1204 }
1205
1206 if (!namep || !strcmp(namep, ifa->ifa_name)) {
1207 const struct afswtch *p;
1208
1209 if (ifa->ifa_addr == NULL((void*)0) ||
1210 (ifa->ifa_addr->sa_family == AF_INET2 &&
1211 ifaliases == 0 && noinet == 0))
1212 continue;
1213 if ((p = afp) != NULL((void*)0)) {
1214 if (ifa->ifa_addr->sa_family == p->af_af)
1215 p->af_status(1);
1216 } else {
1217 for (p = afs; p->af_name; p++) {
1218 if (ifa->ifa_addr->sa_family ==
1219 p->af_af)
1220 p->af_status(0);
1221 }
1222 }
1223 count++;
1224 if (ifa->ifa_addr->sa_family == AF_INET2)
1225 noinet = 0;
1226 continue;
1227 }
1228 }
1229 freeifaddrs(ifap);
1230 free(oname);
1231 if (count == 0) {
1232 fprintf(stderr(&__sF[2]), "%s: no such interface\n", ifname);
1233 exit(1);
1234 }
1235}
1236
1237/*ARGSUSED*/
1238void
1239clone_create(const char *addr, int param)
1240{
1241
1242 /* We're called early... */
1243 getsock(AF_INET2);
1244
1245 (void) strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
1246 if (ioctl(sock, SIOCIFCREATE((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((122)))
, &ifr) == -1)
1247 err(1, "SIOCIFCREATE");
1248}
1249
1250/*ARGSUSED*/
1251void
1252clone_destroy(const char *addr, int param)
1253{
1254
1255 (void) strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
1256 if (ioctl(sock, SIOCIFDESTROY((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((121)))
, &ifr) == -1)
1257 err(1, "SIOCIFDESTROY");
1258}
1259
1260void
1261list_cloners(void)
1262{
1263 struct if_clonereq ifcr;
1264 char *cp, *buf;
1265 int idx;
1266
1267 memset(&ifcr, 0, sizeof(ifcr));
1268
1269 getsock(AF_INET2);
1270
1271 if (ioctl(sock, SIOCIFGCLONERS(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct if_clonereq) & 0x1fff) << 16) | ((('i')) <<
8) | ((120)))
, &ifcr) == -1)
1272 err(1, "SIOCIFGCLONERS for count");
1273
1274 buf = calloc(ifcr.ifcr_total, IFNAMSIZ16);
1275 if (buf == NULL((void*)0))
1276 err(1, "unable to allocate cloner name buffer");
1277
1278 ifcr.ifcr_count = ifcr.ifcr_total;
1279 ifcr.ifcr_buffer = buf;
1280
1281 if (ioctl(sock, SIOCIFGCLONERS(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct if_clonereq) & 0x1fff) << 16) | ((('i')) <<
8) | ((120)))
, &ifcr) == -1)
1282 err(1, "SIOCIFGCLONERS for names");
1283
1284 /*
1285 * In case some disappeared in the mean time, clamp it down.
1286 */
1287 if (ifcr.ifcr_count > ifcr.ifcr_total)
1288 ifcr.ifcr_count = ifcr.ifcr_total;
1289
1290 qsort(buf, ifcr.ifcr_count, IFNAMSIZ16,
1291 (int(*)(const void *, const void *))strcmp);
1292
1293 for (cp = buf, idx = 0; idx < ifcr.ifcr_count; idx++, cp += IFNAMSIZ16) {
1294 if (idx > 0)
1295 putchar(' ')(!__isthreaded ? __sputc(' ', (&__sF[1])) : (putc)(' ', (
&__sF[1])))
;
1296 printf("%s", cp);
1297 }
1298
1299 putchar('\n')(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n',
(&__sF[1])))
;
1300 free(buf);
1301}
1302
1303#define RIDADDR0 0
1304#define ADDR1 1
1305#define MASK2 2
1306#define DSTADDR3 3
1307
1308/*ARGSUSED*/
1309void
1310setifaddr(const char *addr, int param)
1311{
1312 /*
1313 * Delay the ioctl to set the interface addr until flags are all set.
1314 * The address interpretation may depend on the flags,
1315 * and the flags may change when the address is set.
1316 */
1317 setaddr++;
1318 if (doalias >= 0)
1319 newaddr = 1;
1320 if (doalias == 0)
1321 clearaddr = 1;
1322 afp->af_getaddr(addr, (doalias >= 0 ? ADDR1 : RIDADDR0));
1323}
1324
1325#ifndef SMALL
1326void
1327setifrtlabel(const char *label, int d)
1328{
1329 if (d != 0)
1330 ifr.ifr_dataifr_ifru.ifru_data = (caddr_t)(const char *)"";
1331 else
1332 ifr.ifr_dataifr_ifru.ifru_data = (caddr_t)label;
1333 if (ioctl(sock, SIOCSIFRTLABEL((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((130)))
, &ifr) == -1)
1334 warn("SIOCSIFRTLABEL");
1335}
1336#endif
1337
1338/* ARGSUSED */
1339void
1340setifnetmask(const char *addr, int ignored)
1341{
1342 afp->af_getaddr(addr, MASK2);
1343 explicit_prefix = 1;
1344}
1345
1346/* ARGSUSED */
1347void
1348setifbroadaddr(const char *addr, int ignored)
1349{
1350 afp->af_getaddr(addr, DSTADDR3);
1351}
1352
1353#ifndef SMALL
1354/* ARGSUSED */
1355void
1356setifdesc(const char *val, int ignored)
1357{
1358 ifr.ifr_dataifr_ifru.ifru_data = (caddr_t)val;
1359 if (ioctl(sock, SIOCSIFDESCR((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((128)))
, &ifr) == -1)
1360 warn("SIOCSIFDESCR");
1361}
1362
1363/* ARGSUSED */
1364void
1365unsetifdesc(const char *noval, int ignored)
1366{
1367 ifr.ifr_dataifr_ifru.ifru_data = (caddr_t)(const char *)"";
1368 if (ioctl(sock, SIOCSIFDESCR((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((128)))
, &ifr) == -1)
1369 warn("SIOCSIFDESCR");
1370}
1371
1372/* ARGSUSED */
1373void
1374setifipdst(const char *addr, int ignored)
1375{
1376 in_getaddr(addr, DSTADDR3);
1377 setipdst++;
1378 clearaddr = 0;
1379 newaddr = 0;
1380}
1381#endif
1382
1383#define rqtosa(x)(&(((struct ifreq *)(afp->x))->ifr_ifru.ifru_addr)) (&(((struct ifreq *)(afp->x))->ifr_addrifr_ifru.ifru_addr))
1384/*ARGSUSED*/
1385void
1386notealias(const char *addr, int param)
1387{
1388 if (setaddr && doalias == 0 && param < 0)
1389 memcpy(rqtosa(af_ridreq)(&(((struct ifreq *)(afp->af_ridreq))->ifr_ifru.ifru_addr
))
, rqtosa(af_addreq)(&(((struct ifreq *)(afp->af_addreq))->ifr_ifru.ifru_addr
))
,
1390 rqtosa(af_addreq)(&(((struct ifreq *)(afp->af_addreq))->ifr_ifru.ifru_addr
))
->sa_len);
1391 doalias = param;
1392 if (param < 0) {
1393 clearaddr = 1;
1394 newaddr = 0;
1395 } else
1396 clearaddr = 0;
1397}
1398
1399/*ARGSUSED*/
1400void
1401setifdstaddr(const char *addr, int param)
1402{
1403 setaddr++;
1404 setipdst++;
1405 afp->af_getaddr(addr, DSTADDR3);
1406}
1407
1408/*
1409 * Note: doing an SIOCGIFFLAGS scribbles on the union portion
1410 * of the ifreq structure, which may confuse other parts of ifconfig.
1411 * Make a private copy so we can avoid that.
1412 */
1413/* ARGSUSED */
1414void
1415setifflags(const char *vname, int value)
1416{
1417 struct ifreq my_ifr;
1418
1419 bcopy((char *)&ifr, (char *)&my_ifr, sizeof(struct ifreq));
1420
1421 if (ioctl(sock, SIOCGIFFLAGS(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((17)))
, (caddr_t)&my_ifr) == -1)
1422 err(1, "SIOCGIFFLAGS");
1423 (void) strlcpy(my_ifr.ifr_name, ifname, sizeof(my_ifr.ifr_name));
1424 flags = my_ifr.ifr_flagsifr_ifru.ifru_flags;
1425
1426 if (value < 0) {
1427 value = -value;
1428 flags &= ~value;
1429 } else
1430 flags |= value;
1431 my_ifr.ifr_flagsifr_ifru.ifru_flags = flags;
1432 if (ioctl(sock, SIOCSIFFLAGS((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((16)))
, (caddr_t)&my_ifr) == -1)
1433 err(1, "SIOCSIFFLAGS");
1434}
1435
1436/* ARGSUSED */
1437void
1438setifxflags(const char *vname, int value)
1439{
1440 struct ifreq my_ifr;
1441
1442 bcopy((char *)&ifr, (char *)&my_ifr, sizeof(struct ifreq));
1443
1444 if (ioctl(sock, SIOCGIFXFLAGS(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((158)))
, (caddr_t)&my_ifr) == -1)
1445 warn("SIOCGIFXFLAGS");
1446 (void) strlcpy(my_ifr.ifr_name, ifname, sizeof(my_ifr.ifr_name));
1447 xflags = my_ifr.ifr_flagsifr_ifru.ifru_flags;
1448
1449 if (value < 0) {
1450 value = -value;
1451 xflags &= ~value;
1452 } else
1453 xflags |= value;
1454 my_ifr.ifr_flagsifr_ifru.ifru_flags = xflags;
1455 if (ioctl(sock, SIOCSIFXFLAGS((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((157)))
, (caddr_t)&my_ifr) == -1)
1456 warn("SIOCSIFXFLAGS");
1457}
1458
1459void
1460addaf(const char *vname, int value)
1461{
1462 struct if_afreq ifar;
1463
1464 strlcpy(ifar.ifar_name, ifname, sizeof(ifar.ifar_name));
1465 ifar.ifar_af = value;
1466 if (ioctl(sock, SIOCIFAFATTACH((unsigned long)0x80000000 | ((sizeof(struct if_afreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((171)))
, (caddr_t)&ifar) == -1)
1467 warn("SIOCIFAFATTACH");
1468}
1469
1470void
1471removeaf(const char *vname, int value)
1472{
1473 struct if_afreq ifar;
1474
1475 strlcpy(ifar.ifar_name, ifname, sizeof(ifar.ifar_name));
1476 ifar.ifar_af = value;
1477 if (ioctl(sock, SIOCIFAFDETACH((unsigned long)0x80000000 | ((sizeof(struct if_afreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((172)))
, (caddr_t)&ifar) == -1)
1478 warn("SIOCIFAFDETACH");
1479}
1480
1481void
1482setia6flags(const char *vname, int value)
1483{
1484
1485 if (value < 0) {
1486 value = -value;
1487 in6_addreq.ifra_flags &= ~value;
1488 } else
1489 in6_addreq.ifra_flags |= value;
1490}
1491
1492void
1493setia6pltime(const char *val, int d)
1494{
1495
1496 setia6lifetime("pltime", val);
1497}
1498
1499void
1500setia6vltime(const char *val, int d)
1501{
1502
1503 setia6lifetime("vltime", val);
1504}
1505
1506void
1507setia6lifetime(const char *cmd, const char *val)
1508{
1509 const char *errmsg = NULL((void*)0);
1510 time_t newval, t;
1511
1512 newval = strtonum(val, 0, 1000000, &errmsg);
1513 if (errmsg)
1514 errx(1, "invalid %s %s: %s", cmd, val, errmsg);
1515
1516 t = time(NULL((void*)0));
1517
1518 if (afp->af_af != AF_INET624)
1519 errx(1, "%s not allowed for this address family", cmd);
1520 if (strcmp(cmd, "vltime") == 0) {
1521 in6_addreq.ifra_lifetime.ia6t_expire = t + newval;
1522 in6_addreq.ifra_lifetime.ia6t_vltime = newval;
1523 } else if (strcmp(cmd, "pltime") == 0) {
1524 in6_addreq.ifra_lifetime.ia6t_preferred = t + newval;
1525 in6_addreq.ifra_lifetime.ia6t_pltime = newval;
1526 }
1527}
1528
1529void
1530setia6eui64(const char *cmd, int val)
1531{
1532 struct ifaddrs *ifap, *ifa;
1533 const struct sockaddr_in6 *sin6 = NULL((void*)0);
1534 const struct in6_addr *lladdr = NULL((void*)0);
1535 struct in6_addr *in6;
1536
1537 if (afp->af_af != AF_INET624)
1538 errx(1, "%s not allowed for this address family", cmd);
1539
1540 addaf(ifname, AF_INET624);
1541
1542 in6 = (struct in6_addr *)&in6_addreq.ifra_addrifra_ifrau.ifrau_addr.sin6_addr;
1543 if (memcmp(&in6addr_any.s6_addr__u6_addr.__u6_addr8[8], &in6->s6_addr__u6_addr.__u6_addr8[8], 8) != 0)
1544 errx(1, "interface index is already filled");
1545 if (getifaddrs(&ifap) != 0)
1546 err(1, "getifaddrs");
1547 for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
1548 if (ifa->ifa_addr->sa_family == AF_INET624 &&
1549 strcmp(ifa->ifa_name, ifname) == 0) {
1550 sin6 = (const struct sockaddr_in6 *)ifa->ifa_addr;
1551 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)(((&sin6->sin6_addr)->__u6_addr.__u6_addr8[0] == 0xfe
) && (((&sin6->sin6_addr)->__u6_addr.__u6_addr8
[1] & 0xc0) == 0x80))
) {
1552 lladdr = &sin6->sin6_addr;
1553 break;
1554 }
1555 }
1556 }
1557 if (!lladdr)
1558 errx(1, "could not determine link local address");
1559
1560 memcpy(&in6->s6_addr__u6_addr.__u6_addr8[8], &lladdr->s6_addr__u6_addr.__u6_addr8[8], 8);
1561
1562 freeifaddrs(ifap);
1563}
1564
1565void
1566setautoconf(const char *cmd, int val)
1567{
1568 switch (afp->af_af) {
1569 case AF_INET2:
1570 setifxflags("inet", val * IFXF_AUTOCONF40x80);
1571 break;
1572 case AF_INET624:
1573 if (val > 0)
1574 setifxflags("inet6", (IFXF_AUTOCONF60x20 |
1575 IFXF_AUTOCONF6TEMP0x4));
1576 else
1577 setifxflags("inet6", -IFXF_AUTOCONF60x20);
1578 break;
1579 default:
1580 errx(1, "autoconf not allowed for this address family");
1581 }
1582}
1583
1584void
1585settemporary(const char *cmd, int val)
1586{
1587 switch (afp->af_af) {
1588 case AF_INET624:
1589 setifxflags("inet6", val * IFXF_AUTOCONF6TEMP0x4);
1590 break;
1591 default:
1592 errx(1, "temporary not allowed for this address family");
1593 }
1594}
1595
1596#ifndef SMALL
1597/* ARGSUSED */
1598void
1599setifmetric(const char *val, int ignored)
1600{
1601 const char *errmsg = NULL((void*)0);
1602
1603 (void) strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
1604
1605 ifr.ifr_metricifr_ifru.ifru_metric = strtonum(val, 0, INT_MAX2147483647, &errmsg);
1606 if (errmsg)
1607 errx(1, "metric %s: %s", val, errmsg);
1608 if (ioctl(sock, SIOCSIFMETRIC((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((24)))
, (caddr_t)&ifr) == -1)
1609 warn("SIOCSIFMETRIC");
1610}
1611#endif
1612
1613/* ARGSUSED */
1614void
1615setifmtu(const char *val, int d)
1616{
1617 const char *errmsg = NULL((void*)0);
1618
1619 (void) strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
1620
1621 ifr.ifr_mtuifr_ifru.ifru_metric = strtonum(val, 0, INT_MAX2147483647, &errmsg);
1622 if (errmsg)
1623 errx(1, "mtu %s: %s", val, errmsg);
1624 if (ioctl(sock, SIOCSIFMTU((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((127)))
, (caddr_t)&ifr) == -1)
1625 warn("SIOCSIFMTU");
1626}
1627
1628/* ARGSUSED */
1629void
1630setifllprio(const char *val, int d)
1631{
1632 const char *errmsg = NULL((void*)0);
1633
1634 (void) strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
1635
1636 ifr.ifr_llprioifr_ifru.ifru_metric = strtonum(val, 0, UCHAR_MAX(127*2 +1), &errmsg);
1637 if (errmsg)
1638 errx(1, "llprio %s: %s", val, errmsg);
1639 if (ioctl(sock, SIOCSIFLLPRIO((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((181)))
, (caddr_t)&ifr) == -1)
1640 warn("SIOCSIFLLPRIO");
1641}
1642
1643/* ARGSUSED */
1644void
1645setifgroup(const char *group_name, int dummy)
1646{
1647 struct ifgroupreq ifgr;
1648 size_t namelen;
1649
1650 memset(&ifgr, 0, sizeof(ifgr));
1651 strlcpy(ifgr.ifgr_name, ifname, IFNAMSIZ16);
1652
1653 namelen = strlen(group_name);
1654 if (namelen == 0)
1655 errx(1, "setifgroup: group name empty");
1656 if (namelen >= IFNAMSIZ16)
1657 errx(1, "setifgroup: group name too long");
1658 if (isdigit((unsigned char)group_name[namelen - 1]))
1659 errx(1, "setifgroup: group names may not end in a digit");
1660
1661 strlcpy(ifgr.ifgr_groupifgr_ifgru.ifgru_group, group_name, IFNAMSIZ16);
1662 if (ioctl(sock, SIOCAIFGROUP((unsigned long)0x80000000 | ((sizeof(struct ifgroupreq) &
0x1fff) << 16) | ((('i')) << 8) | ((135)))
, (caddr_t)&ifgr) == -1) {
1663 if (errno(*__errno()) != EEXIST17)
1664 err(1," SIOCAIFGROUP");
1665 }
1666}
1667
1668/* ARGSUSED */
1669void
1670unsetifgroup(const char *group_name, int dummy)
1671{
1672 struct ifgroupreq ifgr;
1673
1674 memset(&ifgr, 0, sizeof(ifgr));
1675 strlcpy(ifgr.ifgr_name, ifname, IFNAMSIZ16);
1676
1677 if (strlcpy(ifgr.ifgr_groupifgr_ifgru.ifgru_group, group_name, IFNAMSIZ16) >= IFNAMSIZ16)
1678 errx(1, "unsetifgroup: group name too long");
1679 if (ioctl(sock, SIOCDIFGROUP((unsigned long)0x80000000 | ((sizeof(struct ifgroupreq) &
0x1fff) << 16) | ((('i')) << 8) | ((137)))
, (caddr_t)&ifgr) == -1)
1680 err(1, "SIOCDIFGROUP");
1681}
1682
1683const char *
1684get_string(const char *val, const char *sep, u_int8_t *buf, int *lenp)
1685{
1686 int len = *lenp, hexstr;
1687 u_int8_t *p = buf;
1688
1689 hexstr = (val[0] == '0' && tolower((u_char)val[1]) == 'x');
1690 if (hexstr)
1691 val += 2;
1692 for (;;) {
1693 if (*val == '\0')
1694 break;
1695 if (sep != NULL((void*)0) && strchr(sep, *val) != NULL((void*)0)) {
1696 val++;
1697 break;
1698 }
1699 if (hexstr) {
1700 if (!isxdigit((u_char)val[0]) ||
1701 !isxdigit((u_char)val[1])) {
1702 warnx("bad hexadecimal digits");
1703 return NULL((void*)0);
1704 }
1705 }
1706 if (p > buf + len) {
1707 if (hexstr)
1708 warnx("hexadecimal digits too long");
1709 else
1710 warnx("strings too long");
1711 return NULL((void*)0);
1712 }
1713 if (hexstr) {
1714#define tohex(x) (isdigit(x) ? (x) - '0' : tolower(x) - 'a' + 10)
1715 *p++ = (tohex((u_char)val[0]) << 4) |
1716 tohex((u_char)val[1]);
1717#undef tohex
1718 val += 2;
1719 } else {
1720 if (*val == '\\' &&
1721 sep != NULL((void*)0) && strchr(sep, *(val + 1)) != NULL((void*)0))
1722 val++;
1723 *p++ = *val++;
1724 }
1725 }
1726 len = p - buf;
1727 if (len < *lenp)
1728 memset(p, 0, *lenp - len);
1729 *lenp = len;
1730 return val;
1731}
1732
1733int
1734len_string(const u_int8_t *buf, int len)
1735{
1736 int i = 0, hasspc = 0;
1737
1738 if (len < 2 || buf[0] != '0' || tolower(buf[1]) != 'x') {
1739 for (; i < len; i++) {
1740 /* Only print 7-bit ASCII keys */
1741 if (buf[i] & 0x80 || !isprint(buf[i]))
1742 break;
1743 if (isspace(buf[i]))
1744 hasspc++;
1745 }
1746 }
1747 if (i == len) {
1748 if (hasspc || len == 0)
1749 return len + 2;
1750 else
1751 return len;
1752 } else
1753 return (len * 2) + 2;
1754}
1755
1756int
1757print_string(const u_int8_t *buf, int len)
1758{
1759 int i = 0, hasspc = 0;
1760
1761 if (len < 2 || buf[0] != '0' || tolower(buf[1]) != 'x') {
1762 for (; i < len; i++) {
1763 /* Only print 7-bit ASCII keys */
1764 if (buf[i] & 0x80 || !isprint(buf[i]))
1765 break;
1766 if (isspace(buf[i]))
1767 hasspc++;
1768 }
1769 }
1770 if (i == len) {
1771 if (hasspc || len == 0) {
1772 printf("\"%.*s\"", len, buf);
1773 return len + 2;
1774 } else {
1775 printf("%.*s", len, buf);
1776 return len;
1777 }
1778 } else {
1779 printf("0x");
1780 for (i = 0; i < len; i++)
1781 printf("%02x", buf[i]);
1782 return (len * 2) + 2;
1783 }
1784}
1785
1786void
1787setifnwid(const char *val, int d)
1788{
1789 struct ieee80211_nwid nwid;
1790 int len;
1791
1792 if (joinlen != 0) {
1793 errx(1, "nwid and join may not be used at the same time");
1794 }
1795
1796 if (nwidlen != 0) {
1797 errx(1, "nwid may not be specified twice");
1798 }
1799
1800 if (d != 0) {
1801 /* no network id is especially desired */
1802 memset(&nwid, 0, sizeof(nwid));
1803 len = 0;
1804 } else {
1805 len = sizeof(nwid.i_nwid);
1806 if (get_string(val, NULL((void*)0), nwid.i_nwid, &len) == NULL((void*)0))
1807 return;
1808 }
1809 nwidlen = nwid.i_len = len;
1810 (void)strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
1811 memcpy(nwidname, nwid.i_nwid, len);
1812 ifr.ifr_dataifr_ifru.ifru_data = (caddr_t)&nwid;
1813 if (ioctl(sock, SIOCS80211NWID(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((230)))
, (caddr_t)&ifr) == -1)
1814 warn("SIOCS80211NWID");
1815}
1816
1817
1818void
1819process_join_commands(void)
1820{
1821 if (!(actions & A_JOIN0x0020))
1822 return;
1823
1824 ifr.ifr_dataifr_ifru.ifru_data = (caddr_t)&join;
1825 if (ioctl(sock, SIOCS80211JOIN(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((255)))
, (caddr_t)&ifr) == -1)
1826 err(1, "SIOCS80211JOIN");
1827}
1828
1829void
1830setifjoin(const char *val, int d)
1831{
1832 int len;
1833
1834 if (nwidlen != 0) {
1835 errx(1, "nwid and join may not be used at the same time");
1836 }
1837
1838 if (joinlen != 0) {
1839 errx(1, "join may not be specified twice");
1840 }
1841
1842 if (d != 0) {
1843 /* no network id is especially desired */
1844 memset(&join, 0, sizeof(join));
1845 len = 0;
1846 } else {
1847 len = sizeof(join.i_nwid);
1848 if (get_string(val, NULL((void*)0), join.i_nwid, &len) == NULL((void*)0))
1849 return;
1850 if (len == 0)
1851 join.i_flags |= IEEE80211_JOIN_ANY0x80;
1852 }
1853 joinlen = join.i_len = len;
1854 (void)strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
1855 memcpy(joinname, join.i_nwid, len);
1856
1857 actions |= A_JOIN0x0020;
1858}
1859
1860void
1861delifjoin(const char *val, int d)
1862{
1863 struct ieee80211_join join;
1864 int len;
1865
1866 memset(&join, 0, sizeof(join));
1867 len = 0;
1868 join.i_flags |= IEEE80211_JOIN_DEL0x04;
1869
1870 if (d == -1) {
1871 ifr.ifr_dataifr_ifru.ifru_data = (caddr_t)&join;
1872 if (ioctl(sock, SIOCS80211JOIN(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((255)))
, (caddr_t)&ifr) == -1)
1873 err(1, "SIOCS80211JOIN");
1874 }
1875
1876 len = sizeof(join.i_nwid);
1877 if (get_string(val, NULL((void*)0), join.i_nwid, &len) == NULL((void*)0))
1878 return;
1879 join.i_len = len;
1880 if (len == 0)
1881 join.i_flags |= IEEE80211_JOIN_ANY0x80;
1882 (void)strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
1883 ifr.ifr_dataifr_ifru.ifru_data = (caddr_t)&join;
1884 if (ioctl(sock, SIOCS80211JOIN(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((255)))
, (caddr_t)&ifr) == -1)
1885 err(1, "SIOCS80211JOIN");
1886}
1887
1888void
1889delifjoinlist(const char *val, int d)
1890{
1891 struct ieee80211_join join;
1892 int len;
1893
1894 memset(&join, 0, sizeof(join));
1895 len = 0;
1896 join.i_flags |= (IEEE80211_JOIN_DEL0x04 | IEEE80211_JOIN_DEL_ALL0x100);
1897
1898 if (d == -1) {
1899 ifr.ifr_dataifr_ifru.ifru_data = (caddr_t)&join;
1900 if (ioctl(sock, SIOCS80211JOIN(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((255)))
, (caddr_t)&ifr) == -1)
1901 err(1, "SIOCS80211JOIN");
1902 return;
1903 }
1904
1905 ifr.ifr_dataifr_ifru.ifru_data = (caddr_t)&join;
1906 if (ioctl(sock, SIOCS80211JOIN(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((255)))
, (caddr_t)&ifr) == -1)
1907 err(1, "SIOCS80211JOIN");
1908}
1909
1910void
1911setifbssid(const char *val, int d)
1912{
1913
1914 struct ieee80211_bssid bssid;
1915 struct ether_addr *ea;
1916
1917 if (d != 0) {
1918 /* no BSSID is especially desired */
1919 memset(&bssid.i_bssid, 0, sizeof(bssid.i_bssid));
1920 } else {
1921 ea = ether_aton((char*)val);
1922 if (ea == NULL((void*)0)) {
1923 warnx("malformed BSSID: %s", val);
1924 return;
1925 }
1926 memcpy(&bssid.i_bssid, ea->ether_addr_octet,
1927 sizeof(bssid.i_bssid));
1928 }
1929 strlcpy(bssid.i_name, ifname, sizeof(bssid.i_name));
1930 if (ioctl(sock, SIOCS80211BSSID((unsigned long)0x80000000 | ((sizeof(struct ieee80211_bssid)
& 0x1fff) << 16) | ((('i')) << 8) | ((240)))
, &bssid) == -1)
1931 warn("SIOCS80211BSSID");
1932}
1933
1934void
1935setifnwkey(const char *val, int d)
1936{
1937 int i, len;
1938 struct ieee80211_nwkey nwkey;
1939 u_int8_t keybuf[IEEE80211_WEP_NKID4][16];
1940
1941 bzero(&nwkey, sizeof(nwkey));
1942 bzero(&keybuf, sizeof(keybuf));
1943
1944 nwkey.i_wepon = IEEE80211_NWKEY_WEP1;
1945 nwkey.i_defkid = 1;
1946 if (d == -1) {
1947 /* disable WEP encryption */
1948 nwkey.i_wepon = IEEE80211_NWKEY_OPEN0;
1949 i = 0;
1950 } else if (strcasecmp("persist", val) == 0) {
1951 /* use all values from persistent memory */
1952 nwkey.i_wepon |= IEEE80211_NWKEY_PERSIST0x100;
1953 nwkey.i_defkid = 0;
1954 for (i = 0; i < IEEE80211_WEP_NKID4; i++)
1955 nwkey.i_key[i].i_keylen = -1;
1956 } else if (strncasecmp("persist:", val, 8) == 0) {
1957 val += 8;
1958 /* program keys in persistent memory */
1959 nwkey.i_wepon |= IEEE80211_NWKEY_PERSIST0x100;
1960 goto set_nwkey;
1961 } else {
1962 set_nwkey:
1963 if (isdigit((unsigned char)val[0]) && val[1] == ':') {
1964 /* specifying a full set of four keys */
1965 nwkey.i_defkid = val[0] - '0';
1966 val += 2;
1967 for (i = 0; i < IEEE80211_WEP_NKID4; i++) {
1968 len = sizeof(keybuf[i]);
1969 val = get_string(val, ",", keybuf[i], &len);
1970 if (val == NULL((void*)0))
1971 return;
1972 nwkey.i_key[i].i_keylen = len;
1973 nwkey.i_key[i].i_keydat = keybuf[i];
1974 }
1975 if (*val != '\0') {
1976 warnx("SIOCS80211NWKEY: too many keys.");
1977 return;
1978 }
1979 } else {
1980 /*
1981 * length of each key must be either a 5
1982 * character ASCII string or 10 hex digits for
1983 * 40 bit encryption, or 13 character ASCII
1984 * string or 26 hex digits for 128 bit
1985 * encryption.
1986 */
1987 int j;
1988 char *tmp = NULL((void*)0);
1989 size_t vlen = strlen(val);
1990 switch(vlen) {
1991 case 10:
1992 case 26:
1993 /* 0x must be missing for these lengths */
1994 j = asprintf(&tmp, "0x%s", val);
1995 if (j == -1) {
1996 warnx("malloc failed");
1997 return;
1998 }
1999 val = tmp;
2000 break;
2001 case 12:
2002 case 28:
2003 case 5:
2004 case 13:
2005 /* 0xkey or string case - all is ok */
2006 break;
2007 default:
2008 warnx("Invalid WEP key length");
2009 return;
2010 }
2011 len = sizeof(keybuf[0]);
2012 val = get_string(val, NULL((void*)0), keybuf[0], &len);
2013 free(tmp);
2014 if (val == NULL((void*)0))
2015 return;
2016 nwkey.i_key[0].i_keylen = len;
2017 nwkey.i_key[0].i_keydat = keybuf[0];
2018 i = 1;
2019 }
2020 }
2021 (void)strlcpy(nwkey.i_name, ifname, sizeof(nwkey.i_name));
2022
2023 if (actions & A_JOIN0x0020) {
2024 memcpy(&join.i_nwkey, &nwkey, sizeof(join.i_nwkey));
2025 join.i_flags |= IEEE80211_JOIN_NWKEY0x08;
2026 return;
2027 }
2028
2029 if (ioctl(sock, SIOCS80211NWKEY((unsigned long)0x80000000 | ((sizeof(struct ieee80211_nwkey)
& 0x1fff) << 16) | ((('i')) << 8) | ((232)))
, (caddr_t)&nwkey) == -1)
2030 err(1, "SIOCS80211NWKEY");
2031}
2032
2033/* ARGSUSED */
2034void
2035setifwpa(const char *val, int d)
2036{
2037 struct ieee80211_wpaparams wpa;
2038
2039 memset(&wpa, 0, sizeof(wpa));
2040 (void)strlcpy(wpa.i_name, ifname, sizeof(wpa.i_name));
2041 /* Don't read current values. The kernel will set defaults. */
2042 wpa.i_enabled = d;
2043
2044 if (actions & A_JOIN0x0020) {
2045 join.i_wpaparams.i_enabled = d;
2046 join.i_flags |= IEEE80211_JOIN_WPA0x10;
2047 return;
2048 }
2049
2050 if (ioctl(sock, SIOCS80211WPAPARMS((unsigned long)0x80000000 | ((sizeof(struct ieee80211_wpaparams
) & 0x1fff) << 16) | ((('i')) << 8) | ((247))
)
, (caddr_t)&wpa) == -1)
2051 err(1, "SIOCS80211WPAPARMS");
2052}
2053
2054/* ARGSUSED */
2055void
2056setifwpaprotos(const char *val, int d)
2057{
2058 struct ieee80211_wpaparams wpa;
2059 char *optlist, *str;
2060 u_int rval = 0;
2061
2062 if ((optlist = strdup(val)) == NULL((void*)0))
2063 err(1, "strdup");
2064 str = strtok(optlist, ",");
2065 while (str != NULL((void*)0)) {
2066 if (strcasecmp(str, "wpa1") == 0)
2067 rval |= IEEE80211_WPA_PROTO_WPA10x01;
2068 else if (strcasecmp(str, "wpa2") == 0)
2069 rval |= IEEE80211_WPA_PROTO_WPA20x02;
2070 else
2071 errx(1, "wpaprotos: unknown protocol: %s", str);
2072 str = strtok(NULL((void*)0), ",");
2073 }
2074 free(optlist);
2075
2076 if (actions & A_JOIN0x0020) {
2077 join.i_wpaparams.i_protos = rval;
2078 join.i_flags |= IEEE80211_JOIN_WPA0x10;
2079 return;
2080 }
2081
2082 memset(&wpa, 0, sizeof(wpa));
2083 (void)strlcpy(wpa.i_name, ifname, sizeof(wpa.i_name));
2084 if (ioctl(sock, SIOCG80211WPAPARMS(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ieee80211_wpaparams) & 0x1fff) << 16) | (((
'i')) << 8) | ((248)))
, (caddr_t)&wpa) == -1)
2085 err(1, "SIOCG80211WPAPARMS");
2086 wpa.i_protos = rval;
2087 /* Let the kernel set up the appropriate default ciphers. */
2088 wpa.i_ciphers = 0;
2089 wpa.i_groupcipher = 0;
2090
2091 if (ioctl(sock, SIOCS80211WPAPARMS((unsigned long)0x80000000 | ((sizeof(struct ieee80211_wpaparams
) & 0x1fff) << 16) | ((('i')) << 8) | ((247))
)
, (caddr_t)&wpa) == -1)
2092 err(1, "SIOCS80211WPAPARMS");
2093}
2094
2095/* ARGSUSED */
2096void
2097setifwpaakms(const char *val, int d)
2098{
2099 struct ieee80211_wpaparams wpa;
2100 char *optlist, *str;
2101 u_int rval = 0;
2102
2103 if ((optlist = strdup(val)) == NULL((void*)0))
2104 err(1, "strdup");
2105 str = strtok(optlist, ",");
2106 while (str != NULL((void*)0)) {
2107 if (strcasecmp(str, "psk") == 0)
2108 rval |= IEEE80211_WPA_AKM_PSK0x01;
2109 else if (strcasecmp(str, "802.1x") == 0)
2110 rval |= IEEE80211_WPA_AKM_8021X0x02;
2111 else
2112 errx(1, "wpaakms: unknown akm: %s", str);
2113 str = strtok(NULL((void*)0), ",");
2114 }
2115 free(optlist);
2116
2117 if (actions & A_JOIN0x0020) {
2118 join.i_wpaparams.i_akms = rval;
2119 join.i_wpaparams.i_enabled =
2120 ((rval & IEEE80211_WPA_AKM_8021X0x02) != 0);
2121 join.i_flags |= IEEE80211_JOIN_WPA0x10;
2122 return;
2123 }
2124
2125 memset(&wpa, 0, sizeof(wpa));
2126 (void)strlcpy(wpa.i_name, ifname, sizeof(wpa.i_name));
2127 if (ioctl(sock, SIOCG80211WPAPARMS(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ieee80211_wpaparams) & 0x1fff) << 16) | (((
'i')) << 8) | ((248)))
, (caddr_t)&wpa) == -1)
2128 err(1, "SIOCG80211WPAPARMS");
2129 wpa.i_akms = rval;
2130 /* Enable WPA for 802.1x here. PSK case is handled in setifwpakey(). */
2131 wpa.i_enabled = ((rval & IEEE80211_WPA_AKM_8021X0x02) != 0);
2132
2133 if (ioctl(sock, SIOCS80211WPAPARMS((unsigned long)0x80000000 | ((sizeof(struct ieee80211_wpaparams
) & 0x1fff) << 16) | ((('i')) << 8) | ((247))
)
, (caddr_t)&wpa) == -1)
2134 err(1, "SIOCS80211WPAPARMS");
2135}
2136
2137static const struct {
2138 const char *name;
2139 u_int cipher;
2140} ciphers[] = {
2141 { "usegroup", IEEE80211_WPA_CIPHER_USEGROUP0x01 },
2142 { "wep40", IEEE80211_WPA_CIPHER_WEP400x02 },
2143 { "tkip", IEEE80211_WPA_CIPHER_TKIP0x04 },
2144 { "ccmp", IEEE80211_WPA_CIPHER_CCMP0x08 },
2145 { "wep104", IEEE80211_WPA_CIPHER_WEP1040x10 }
2146};
2147
2148u_int
2149getwpacipher(const char *name)
2150{
2151 int i;
2152
2153 for (i = 0; i < sizeof(ciphers) / sizeof(ciphers[0]); i++)
2154 if (strcasecmp(name, ciphers[i].name) == 0)
2155 return ciphers[i].cipher;
2156 return IEEE80211_WPA_CIPHER_NONE0x00;
2157}
2158
2159/* ARGSUSED */
2160void
2161setifwpaciphers(const char *val, int d)
2162{
2163 struct ieee80211_wpaparams wpa;
2164 char *optlist, *str;
2165 u_int rval = 0;
2166
2167 if ((optlist = strdup(val)) == NULL((void*)0))
2168 err(1, "strdup");
2169 str = strtok(optlist, ",");
2170 while (str != NULL((void*)0)) {
2171 u_int cipher = getwpacipher(str);
2172 if (cipher == IEEE80211_WPA_CIPHER_NONE0x00)
2173 errx(1, "wpaciphers: unknown cipher: %s", str);
2174
2175 rval |= cipher;
2176 str = strtok(NULL((void*)0), ",");
2177 }
2178 free(optlist);
2179
2180 if (actions & A_JOIN0x0020) {
2181 join.i_wpaparams.i_ciphers = rval;
2182 join.i_flags |= IEEE80211_JOIN_WPA0x10;
2183 return;
2184 }
2185
2186 memset(&wpa, 0, sizeof(wpa));
2187 (void)strlcpy(wpa.i_name, ifname, sizeof(wpa.i_name));
2188 if (ioctl(sock, SIOCG80211WPAPARMS(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ieee80211_wpaparams) & 0x1fff) << 16) | (((
'i')) << 8) | ((248)))
, (caddr_t)&wpa) == -1)
2189 err(1, "SIOCG80211WPAPARMS");
2190 wpa.i_ciphers = rval;
2191
2192 if (ioctl(sock, SIOCS80211WPAPARMS((unsigned long)0x80000000 | ((sizeof(struct ieee80211_wpaparams
) & 0x1fff) << 16) | ((('i')) << 8) | ((247))
)
, (caddr_t)&wpa) == -1)
2193 err(1, "SIOCS80211WPAPARMS");
2194}
2195
2196/* ARGSUSED */
2197void
2198setifwpagroupcipher(const char *val, int d)
2199{
2200 struct ieee80211_wpaparams wpa;
2201 u_int cipher;
2202
2203 cipher = getwpacipher(val);
2204 if (cipher == IEEE80211_WPA_CIPHER_NONE0x00)
2205 errx(1, "wpagroupcipher: unknown cipher: %s", val);
2206
2207 memset(&wpa, 0, sizeof(wpa));
2208 (void)strlcpy(wpa.i_name, ifname, sizeof(wpa.i_name));
2209 if (ioctl(sock, SIOCG80211WPAPARMS(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ieee80211_wpaparams) & 0x1fff) << 16) | (((
'i')) << 8) | ((248)))
, (caddr_t)&wpa) == -1)
2210 err(1, "SIOCG80211WPAPARMS");
2211 wpa.i_groupcipher = cipher;
2212
2213 if (actions & A_JOIN0x0020) {
2214 join.i_wpaparams.i_groupcipher = cipher;
2215 join.i_flags |= IEEE80211_JOIN_WPA0x10;
2216 return;
2217 }
2218
2219 if (ioctl(sock, SIOCS80211WPAPARMS((unsigned long)0x80000000 | ((sizeof(struct ieee80211_wpaparams
) & 0x1fff) << 16) | ((('i')) << 8) | ((247))
)
, (caddr_t)&wpa) == -1)
2220 err(1, "SIOCS80211WPAPARMS");
2221}
2222
2223void
2224setifwpakey(const char *val, int d)
2225{
2226 struct ieee80211_wpaparams wpa;
2227 struct ieee80211_wpapsk psk;
2228 struct ieee80211_nwid nwid;
2229 int passlen;
2230
2231 memset(&psk, 0, sizeof(psk));
2232 if (d != -1) {
2233 memset(&ifr, 0, sizeof(ifr));
2234 ifr.ifr_dataifr_ifru.ifru_data = (caddr_t)&nwid;
2235 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2236
2237 /* Use the value specified in 'join' or 'nwid' */
2238 if (joinlen != 0) {
2239 memcpy(nwid.i_nwid, joinname, joinlen);
2240 nwid.i_len = joinlen;
2241 } else if (nwidlen != 0) {
2242 memcpy(nwid.i_nwid, nwidname, nwidlen);
2243 nwid.i_len = nwidlen;
2244 } else {
2245 warnx("no nwid or join command, guessing nwid to use");
2246
2247 if (ioctl(sock, SIOCG80211NWID(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((231)))
, (caddr_t)&ifr) == -1)
2248 err(1, "SIOCG80211NWID");
2249 }
2250
2251 passlen = strlen(val);
2252 if (passlen == 2 + 2 * sizeof(psk.i_psk) &&
2253 val[0] == '0' && val[1] == 'x') {
2254 /* Parse a WPA hex key (must be full-length) */
2255 passlen = sizeof(psk.i_psk);
2256 val = get_string(val, NULL((void*)0), psk.i_psk, &passlen);
2257 if (val == NULL((void*)0) || passlen != sizeof(psk.i_psk))
2258 errx(1, "wpakey: invalid pre-shared key");
2259 } else {
2260 /* Parse a WPA passphrase */
2261 if (passlen < 8 || passlen > 63)
2262 errx(1, "wpakey: passphrase must be between "
2263 "8 and 63 characters");
2264 if (nwid.i_len == 0)
2265 errx(1, "wpakey: nwid not set");
2266 if (pkcs5_pbkdf2(val, passlen, nwid.i_nwid, nwid.i_len,
2267 psk.i_psk, sizeof(psk.i_psk), 4096) != 0)
2268 errx(1, "wpakey: passphrase hashing failed");
2269 }
2270 psk.i_enabled = 1;
2271 } else
2272 psk.i_enabled = 0;
2273
2274 (void)strlcpy(psk.i_name, ifname, sizeof(psk.i_name));
2275
2276 if (actions & A_JOIN0x0020) {
2277 memcpy(&join.i_wpapsk, &psk, sizeof(join.i_wpapsk));
2278 join.i_flags |= IEEE80211_JOIN_WPAPSK0x20;
2279 if (!join.i_wpaparams.i_enabled)
2280 setifwpa(NULL((void*)0), join.i_wpapsk.i_enabled);
2281 return;
2282 }
2283
2284 if (ioctl(sock, SIOCS80211WPAPSK((unsigned long)0x80000000 | ((sizeof(struct ieee80211_wpapsk
) & 0x1fff) << 16) | ((('i')) << 8) | ((245))
)
, (caddr_t)&psk) == -1)
2285 err(1, "SIOCS80211WPAPSK");
2286
2287 /* And ... automatically enable or disable WPA */
2288 memset(&wpa, 0, sizeof(wpa));
2289 (void)strlcpy(wpa.i_name, ifname, sizeof(wpa.i_name));
2290 if (ioctl(sock, SIOCG80211WPAPARMS(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ieee80211_wpaparams) & 0x1fff) << 16) | (((
'i')) << 8) | ((248)))
, (caddr_t)&wpa) == -1)
2291 err(1, "SIOCG80211WPAPARMS");
2292 wpa.i_enabled = psk.i_enabled;
2293 if (ioctl(sock, SIOCS80211WPAPARMS((unsigned long)0x80000000 | ((sizeof(struct ieee80211_wpaparams
) & 0x1fff) << 16) | ((('i')) << 8) | ((247))
)
, (caddr_t)&wpa) == -1)
2294 err(1, "SIOCS80211WPAPARMS");
2295}
2296
2297void
2298setifchan(const char *val, int d)
2299{
2300 struct ieee80211chanreq channel;
2301 const char *errstr;
2302 int chan;
2303
2304 if (val == NULL((void*)0)) {
2305 if (shownet80211chans || shownet80211nodes)
2306 usage();
2307 shownet80211chans = 1;
2308 return;
2309 }
2310 if (d != 0)
2311 chan = IEEE80211_CHAN_ANY0xffff;
2312 else {
2313 chan = strtonum(val, 1, 256, &errstr);
2314 if (errstr) {
2315 warnx("invalid channel %s: %s", val, errstr);
2316 return;
2317 }
2318 }
2319
2320 strlcpy(channel.i_name, ifname, sizeof(channel.i_name));
2321 channel.i_channel = (u_int16_t)chan;
2322 if (ioctl(sock, SIOCS80211CHANNEL((unsigned long)0x80000000 | ((sizeof(struct ieee80211chanreq
) & 0x1fff) << 16) | ((('i')) << 8) | ((238))
)
, (caddr_t)&channel) == -1)
2323 warn("SIOCS80211CHANNEL");
2324}
2325
2326/* ARGSUSED */
2327void
2328setifscan(const char *val, int d)
2329{
2330 if (shownet80211chans || shownet80211nodes)
2331 usage();
2332 shownet80211nodes = 1;
2333}
2334
2335#ifndef SMALL
2336
2337void
2338setifnwflag(const char *val, int d)
2339{
2340 static const struct ieee80211_flags nwflags[] = IEEE80211_FLAGS{ { "hidenwid", 0x00000001 }, { "nobridge", 0x00000002 }, { "stayauth"
, 0x00000004 }, { "nomimo", 0x00000008 } }
;
2341 u_int i, flag = 0;
2342
2343 for (i = 0; i < (sizeof(nwflags) / sizeof(nwflags[0])); i++) {
2344 if (strcmp(val, nwflags[i].f_name) == 0) {
2345 flag = nwflags[i].f_flag;
2346 break;
2347 }
2348 }
2349 if (flag == 0)
2350 errx(1, "Invalid nwflag: %s", val);
2351
2352 if (ioctl(sock, SIOCG80211FLAGS(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((216)))
, (caddr_t)&ifr) != 0)
2353 err(1, "SIOCG80211FLAGS");
2354
2355 if (d)
2356 ifr.ifr_flagsifr_ifru.ifru_flags &= ~flag;
2357 else
2358 ifr.ifr_flagsifr_ifru.ifru_flags |= flag;
2359
2360 if (ioctl(sock, SIOCS80211FLAGS((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((217)))
, (caddr_t)&ifr) != 0)
2361 err(1, "SIOCS80211FLAGS");
2362}
2363
2364void
2365unsetifnwflag(const char *val, int d)
2366{
2367 setifnwflag(val, 1);
2368}
2369
2370/* ARGSUSED */
2371void
2372setifpowersave(const char *val, int d)
2373{
2374 struct ieee80211_power power;
2375 const char *errmsg = NULL((void*)0);
2376
2377 (void)strlcpy(power.i_name, ifname, sizeof(power.i_name));
2378 if (ioctl(sock, SIOCG80211POWER(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ieee80211_power) & 0x1fff) << 16) | ((('i')
) << 8) | ((235)))
, (caddr_t)&power) == -1) {
2379 warn("SIOCG80211POWER");
2380 return;
2381 }
2382
2383 if (d != -1 && val != NULL((void*)0)) {
2384 power.i_maxsleep = strtonum(val, 0, INT_MAX2147483647, &errmsg);
2385 if (errmsg)
2386 errx(1, "powersave %s: %s", val, errmsg);
2387 }
2388
2389 power.i_enabled = d == -1 ? 0 : 1;
2390 if (ioctl(sock, SIOCS80211POWER((unsigned long)0x80000000 | ((sizeof(struct ieee80211_power)
& 0x1fff) << 16) | ((('i')) << 8) | ((234)))
, (caddr_t)&power) == -1)
2391 warn("SIOCS80211POWER");
2392}
2393#endif
2394
2395void
2396print_cipherset(u_int32_t cipherset)
2397{
2398 const char *sep = "";
2399 int i;
2400
2401 if (cipherset == IEEE80211_WPA_CIPHER_NONE0x00) {
2402 printf("none");
2403 return;
2404 }
2405 for (i = 0; i < sizeof(ciphers) / sizeof(ciphers[0]); i++) {
2406 if (cipherset & ciphers[i].cipher) {
2407 printf("%s%s", sep, ciphers[i].name);
2408 sep = ",";
2409 }
2410 }
2411}
2412
2413static void
2414print_assoc_failures(uint32_t assoc_fail)
2415{
2416 /* Filter out the most obvious failure cases. */
2417 assoc_fail &= ~IEEE80211_NODEREQ_ASSOCFAIL_ESSID0x10;
2418 if (assoc_fail & IEEE80211_NODEREQ_ASSOCFAIL_PRIVACY0x04)
2419 assoc_fail &= ~IEEE80211_NODEREQ_ASSOCFAIL_WPA_PROTO0x40;
2420 assoc_fail &= ~IEEE80211_NODEREQ_ASSOCFAIL_PRIVACY0x04;
2421
2422 if (assoc_fail == 0)
2423 return;
2424
2425 printb_status(assoc_fail, IEEE80211_NODEREQ_ASSOCFAIL_BITS"\20\1!CHAN\2!IBSS\3!PRIVACY\4!BASICRATE\5!ESSID\6!BSSID\7!WPAPROTO"
"\10!WPAKEY"
);
2426}
2427
2428void
2429ieee80211_status(void)
2430{
2431 int len, inwid, ijoin, inwkey, ipsk, ichan, ipwr;
2432 int ibssid, iwpa, assocfail = 0;
2433 struct ieee80211_nwid nwid;
2434 struct ieee80211_join join;
2435 struct ieee80211_nwkey nwkey;
2436 struct ieee80211_wpapsk psk;
2437 struct ieee80211_power power;
2438 struct ieee80211chanreq channel;
2439 struct ieee80211_bssid bssid;
2440 struct ieee80211_wpaparams wpa;
2441 struct ieee80211_nodereq nr;
2442 u_int8_t zero_bssid[IEEE80211_ADDR_LEN6];
2443 struct ether_addr ea;
2444
2445 /* get current status via ioctls */
2446 memset(&ifr, 0, sizeof(ifr));
2447 ifr.ifr_dataifr_ifru.ifru_data = (caddr_t)&nwid;
2448 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2449 inwid = ioctl(sock, SIOCG80211NWID(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((231)))
, (caddr_t)&ifr);
2450
2451 ifr.ifr_dataifr_ifru.ifru_data = (caddr_t)&join;
2452 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2453 ijoin = ioctl(sock, SIOCG80211JOIN(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((0)))
, (caddr_t)&ifr);
2454
2455 memset(&nwkey, 0, sizeof(nwkey));
2456 strlcpy(nwkey.i_name, ifname, sizeof(nwkey.i_name));
2457 inwkey = ioctl(sock, SIOCG80211NWKEY(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ieee80211_nwkey) & 0x1fff) << 16) | ((('i')
) << 8) | ((233)))
, (caddr_t)&nwkey);
2458
2459 memset(&psk, 0, sizeof(psk));
2460 strlcpy(psk.i_name, ifname, sizeof(psk.i_name));
2461 ipsk = ioctl(sock, SIOCG80211WPAPSK(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ieee80211_wpapsk) & 0x1fff) << 16) | ((('i'
)) << 8) | ((246)))
, (caddr_t)&psk);
2462
2463 memset(&power, 0, sizeof(power));
2464 strlcpy(power.i_name, ifname, sizeof(power.i_name));
2465 ipwr = ioctl(sock, SIOCG80211POWER(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ieee80211_power) & 0x1fff) << 16) | ((('i')
) << 8) | ((235)))
, &power);
2466
2467 memset(&channel, 0, sizeof(channel));
2468 strlcpy(channel.i_name, ifname, sizeof(channel.i_name));
2469 ichan = ioctl(sock, SIOCG80211CHANNEL(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ieee80211chanreq) & 0x1fff) << 16) | ((('i'
)) << 8) | ((239)))
, (caddr_t)&channel);
2470
2471 memset(&bssid, 0, sizeof(bssid));
2472 strlcpy(bssid.i_name, ifname, sizeof(bssid.i_name));
2473 ibssid = ioctl(sock, SIOCG80211BSSID(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ieee80211_bssid) & 0x1fff) << 16) | ((('i')
) << 8) | ((241)))
, &bssid);
2474
2475 memset(&wpa, 0, sizeof(wpa));
2476 strlcpy(wpa.i_name, ifname, sizeof(wpa.i_name));
2477 iwpa = ioctl(sock, SIOCG80211WPAPARMS(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ieee80211_wpaparams) & 0x1fff) << 16) | (((
'i')) << 8) | ((248)))
, &wpa);
2478
2479 /* check if any ieee80211 option is active */
2480 if (inwid == 0 || ijoin == 0 || inwkey == 0 || ipsk == 0 ||
2481 ipwr == 0 || ichan == 0 || ibssid == 0 || iwpa == 0)
2482 fputs("\tieee80211:", stdout(&__sF[1]));
2483 else
2484 return;
2485
2486 if (inwid == 0) {
2487 /* nwid.i_nwid is not NUL terminated. */
2488 len = nwid.i_len;
2489 if (len > IEEE80211_NWID_LEN32)
2490 len = IEEE80211_NWID_LEN32;
2491 if (ijoin == 0 && join.i_flags & IEEE80211_JOIN_FOUND0x02)
2492 fputs(" join ", stdout(&__sF[1]));
2493 else
2494 fputs(" nwid ", stdout(&__sF[1]));
2495 print_string(nwid.i_nwid, len);
2496 }
2497
2498 if (ichan == 0 && channel.i_channel != 0 &&
2499 channel.i_channel != IEEE80211_CHAN_ANY0xffff)
2500 printf(" chan %u", channel.i_channel);
2501
2502 memset(&zero_bssid, 0, sizeof(zero_bssid));
2503 if (ibssid == 0 &&
2504 memcmp(bssid.i_bssid, zero_bssid, IEEE80211_ADDR_LEN6) != 0) {
2505 memcpy(&ea.ether_addr_octet, bssid.i_bssid,
2506 sizeof(ea.ether_addr_octet));
2507 printf(" bssid %s", ether_ntoa(&ea));
2508
2509 bzero(&nr, sizeof(nr));
2510 bcopy(bssid.i_bssid, &nr.nr_macaddr, sizeof(nr.nr_macaddr));
2511 strlcpy(nr.nr_ifname, ifname, sizeof(nr.nr_ifname));
2512 if (ioctl(sock, SIOCG80211NODE(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ieee80211_nodereq) & 0x1fff) << 16) | ((('i'
)) << 8) | ((211)))
, &nr) == 0) {
2513 if (nr.nr_rssi) {
2514 if (nr.nr_max_rssi)
2515 printf(" %u%%",
2516 IEEE80211_NODEREQ_RSSI(&nr)((u_int)(((float)(&nr)->nr_rssi / (&nr)->nr_max_rssi
) * 100))
);
2517 else
2518 printf(" %ddBm", nr.nr_rssi);
2519 }
2520 assocfail = nr.nr_assoc_fail;
2521 }
2522 }
2523
2524 if (inwkey == 0 && nwkey.i_wepon > IEEE80211_NWKEY_OPEN0)
2525 fputs(" nwkey", stdout(&__sF[1]));
2526
2527 if (ipsk == 0 && psk.i_enabled)
2528 fputs(" wpakey", stdout(&__sF[1]));
2529 if (iwpa == 0 && wpa.i_enabled) {
2530 const char *sep;
2531
2532 fputs(" wpaprotos ", stdout(&__sF[1])); sep = "";
2533 if (wpa.i_protos & IEEE80211_WPA_PROTO_WPA10x01) {
2534 fputs("wpa1", stdout(&__sF[1]));
2535 sep = ",";
2536 }
2537 if (wpa.i_protos & IEEE80211_WPA_PROTO_WPA20x02)
2538 printf("%swpa2", sep);
2539
2540 fputs(" wpaakms ", stdout(&__sF[1])); sep = "";
2541 if (wpa.i_akms & IEEE80211_WPA_AKM_PSK0x01) {
2542 fputs("psk", stdout(&__sF[1]));
2543 sep = ",";
2544 }
2545 if (wpa.i_akms & IEEE80211_WPA_AKM_8021X0x02)
2546 printf("%s802.1x", sep);
2547
2548 fputs(" wpaciphers ", stdout(&__sF[1]));
2549 print_cipherset(wpa.i_ciphers);
2550
2551 fputs(" wpagroupcipher ", stdout(&__sF[1]));
2552 print_cipherset(wpa.i_groupcipher);
2553 }
2554
2555 if (ipwr == 0 && power.i_enabled)
2556 printf(" powersave on (%dms sleep)", power.i_maxsleep);
2557
2558 if (ioctl(sock, SIOCG80211FLAGS(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((216)))
, (caddr_t)&ifr) == 0 &&
2559 ifr.ifr_flagsifr_ifru.ifru_flags) {
2560 putchar(' ')(!__isthreaded ? __sputc(' ', (&__sF[1])) : (putc)(' ', (
&__sF[1])))
;
2561 printb_status(ifr.ifr_flagsifr_ifru.ifru_flags, IEEE80211_F_USERBITS"\20\01HIDENWID\02NOBRIDGE\03STAYAUTH\04NOMIMO");
2562 }
2563
2564 if (assocfail) {
2565 putchar(' ')(!__isthreaded ? __sputc(' ', (&__sF[1])) : (putc)(' ', (
&__sF[1])))
;
2566 print_assoc_failures(assocfail);
2567 }
2568 putchar('\n')(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n',
(&__sF[1])))
;
2569 if (show_join)
2570 join_status();
2571 if (shownet80211chans)
2572 ieee80211_listchans();
2573 else if (shownet80211nodes)
2574 ieee80211_listnodes();
2575}
2576
2577void
2578showjoin(const char *cmd, int val)
2579{
2580 show_join = 1;
2581 return;
2582}
2583
2584void
2585join_status(void)
2586{
2587 struct ieee80211_joinreq_all ja;
2588 struct ieee80211_join *jn = NULL((void*)0);
2589 struct ieee80211_wpaparams *wpa;
2590 int jsz = 100;
2591 int ojsz;
2592 int i;
2593 int r;
2594 int maxlen, len;
2595
2596 bzero(&ja, sizeof(ja));
2597 jn = recallocarray(NULL((void*)0), 0, jsz, sizeof(*jn));
2598 if (jn == NULL((void*)0))
2599 err(1, "recallocarray");
2600 ojsz = jsz;
2601 while (1) {
2602 ja.ja_node = jn;
2603 ja.ja_size = jsz * sizeof(*jn);
2604 strlcpy(ja.ja_ifname, ifname, sizeof(ja.ja_ifname));
2605
2606 if ((r = ioctl(sock, SIOCG80211JOINALL(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ieee80211_joinreq_all) & 0x1fff) << 16) | (
(('i')) << 8) | ((218)))
, &ja)) != 0) {
2607 if (errno(*__errno()) == E2BIG7) {
2608 jsz += 100;
2609 jn = recallocarray(jn, ojsz, jsz, sizeof(*jn));
2610 if (jn == NULL((void*)0))
2611 err(1, "recallocarray");
2612 ojsz = jsz;
2613 continue;
2614 } else if (errno(*__errno()) != ENOENT2)
2615 warn("SIOCG80211JOINALL");
2616 return;
2617 }
2618 break;
2619 }
2620
2621 if (!ja.ja_nodes)
2622 return;
2623
2624 maxlen = 0;
2625 for (i = 0; i < ja.ja_nodes; i++) {
2626 len = len_string(jn[i].i_nwid, jn[i].i_len);
2627 if (len > maxlen)
2628 maxlen = len;
2629 }
2630
2631 for (i = 0; i < ja.ja_nodes; i++) {
2632 printf("\t ");
2633 if (jn[i].i_len > IEEE80211_NWID_LEN32)
2634 jn[i].i_len = IEEE80211_NWID_LEN32;
2635 len = print_string(jn[i].i_nwid, jn[i].i_len);
2636 printf("%-*s", maxlen - len, "");
2637 if (jn[i].i_flags) {
2638 const char *sep;
2639 printf(" ");
2640
2641 if (jn[i].i_flags & IEEE80211_JOIN_NWKEY0x08)
2642 printf("nwkey");
2643
2644 if (jn[i].i_flags & IEEE80211_JOIN_WPA0x10) {
2645 wpa = &jn[i].i_wpaparams;
2646
2647 printf("wpaprotos "); sep = "";
2648 if (wpa->i_protos & IEEE80211_WPA_PROTO_WPA10x01) {
2649 printf("wpa1");
2650 sep = ",";
2651 }
2652 if (wpa->i_protos & IEEE80211_WPA_PROTO_WPA20x02)
2653 printf("%swpa2", sep);
2654
2655 printf(" wpaakms "); sep = "";
2656 if (wpa->i_akms & IEEE80211_WPA_AKM_PSK0x01) {
2657 printf("psk");
2658 sep = ",";
2659 }
2660 if (wpa->i_akms & IEEE80211_WPA_AKM_8021X0x02)
2661 printf("%s802.1x", sep);
2662
2663 printf(" wpaciphers ");
2664 print_cipherset(wpa->i_ciphers);
2665
2666 printf(" wpagroupcipher ");
2667 print_cipherset(wpa->i_groupcipher);
2668 }
2669 }
2670 putchar('\n')(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n',
(&__sF[1])))
;
2671 }
2672}
2673
2674void
2675ieee80211_listchans(void)
2676{
2677 static struct ieee80211_channel chans[256+1];
2678 struct ieee80211_chanreq_all ca;
2679 int i;
2680
2681 bzero(&ca, sizeof(ca));
2682 bzero(chans, sizeof(chans));
2683 ca.i_chans = chans;
2684 strlcpy(ca.i_name, ifname, sizeof(ca.i_name));
2685
2686 if (ioctl(sock, SIOCG80211ALLCHANS(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ieee80211_chanreq_all) & 0x1fff) << 16) | (
(('i')) << 8) | ((215)))
, &ca) != 0) {
2687 warn("SIOCG80211ALLCHANS");
2688 return;
2689 }
2690 printf("\t\t%4s %-8s %s\n", "chan", "freq", "properties");
2691 for (i = 1; i <= 256; i++) {
2692 if (chans[i].ic_flags == 0)
2693 continue;
2694 printf("\t\t%4d %4d MHz ", i, chans[i].ic_freq);
2695 if (chans[i].ic_flags & IEEE80211_CHAN_PASSIVE0x0200)
2696 printf("passive scan");
2697 else
2698 putchar('-')(!__isthreaded ? __sputc('-', (&__sF[1])) : (putc)('-', (
&__sF[1])))
;
2699 putchar('\n')(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n',
(&__sF[1])))
;
2700 }
2701}
2702
2703/*
2704 * Returns an integer less than, equal to, or greater than zero if nr1's
2705 * RSSI is respectively greater than, equal to, or less than nr2's RSSI.
2706 */
2707static int
2708rssicmp(const void *nr1, const void *nr2)
2709{
2710 const struct ieee80211_nodereq *x = nr1, *y = nr2;
2711 return y->nr_rssi < x->nr_rssi ? -1 : y->nr_rssi > x->nr_rssi;
2712}
2713
2714void
2715ieee80211_listnodes(void)
2716{
2717 struct ieee80211_nodereq_all na;
2718 struct ieee80211_nodereq nr[512];
2719 struct ifreq ifr;
2720 int i;
2721
2722 if ((flags & IFF_UP0x1) == 0) {
2723 printf("\t\tcannot scan, interface is down\n");
2724 return;
2725 }
2726
2727 bzero(&ifr, sizeof(ifr));
2728 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2729
2730 if (ioctl(sock, SIOCS80211SCAN((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((210)))
, (caddr_t)&ifr) != 0) {
2731 if (errno(*__errno()) == EPERM1)
2732 printf("\t\tno permission to scan\n");
2733 return;
2734 }
2735
2736 bzero(&na, sizeof(na));
2737 bzero(&nr, sizeof(nr));
2738 na.na_node = nr;
2739 na.na_size = sizeof(nr);
2740 strlcpy(na.na_ifname, ifname, sizeof(na.na_ifname));
2741
2742 if (ioctl(sock, SIOCG80211ALLNODES(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ieee80211_nodereq_all) & 0x1fff) << 16) | (
(('i')) << 8) | ((214)))
, &na) != 0) {
2743 warn("SIOCG80211ALLNODES");
2744 return;
2745 }
2746
2747 if (!na.na_nodes)
2748 printf("\t\tnone\n");
2749 else
2750 qsort(nr, na.na_nodes, sizeof(*nr), rssicmp);
2751
2752 for (i = 0; i < na.na_nodes; i++) {
2753 printf("\t\t");
2754 ieee80211_printnode(&nr[i]);
2755 putchar('\n')(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n',
(&__sF[1])))
;
2756 }
2757}
2758
2759void
2760ieee80211_printnode(struct ieee80211_nodereq *nr)
2761{
2762 int len, i;
2763
2764 if (nr->nr_flags & IEEE80211_NODEREQ_AP0x01 ||
2765 nr->nr_capinfo & IEEE80211_CAPINFO_IBSS0x0002) {
2766 len = nr->nr_nwid_len;
2767 if (len > IEEE80211_NWID_LEN32)
2768 len = IEEE80211_NWID_LEN32;
2769 printf("nwid ");
2770 print_string(nr->nr_nwid, len);
2771 putchar(' ')(!__isthreaded ? __sputc(' ', (&__sF[1])) : (putc)(' ', (
&__sF[1])))
;
2772
2773 printf("chan %u ", nr->nr_channel);
2774
2775 printf("bssid %s ",
2776 ether_ntoa((struct ether_addr*)nr->nr_bssid));
2777 }
2778
2779 if ((nr->nr_flags & IEEE80211_NODEREQ_AP0x01) == 0)
2780 printf("lladdr %s ",
2781 ether_ntoa((struct ether_addr*)nr->nr_macaddr));
2782
2783 if (nr->nr_max_rssi)
2784 printf("%u%% ", IEEE80211_NODEREQ_RSSI(nr)((u_int)(((float)(nr)->nr_rssi / (nr)->nr_max_rssi) * 100
))
);
2785 else
2786 printf("%ddBm ", nr->nr_rssi);
2787
2788 if (nr->nr_pwrsave)
2789 printf("powersave ");
2790 /*
2791 * Print our current Tx rate for associated nodes.
2792 * Print the fastest supported rate for APs.
2793 */
2794 if ((nr->nr_flags & (IEEE80211_NODEREQ_AP0x01)) == 0) {
2795 if (nr->nr_flags & IEEE80211_NODEREQ_VHT0x10) {
2796 printf("VHT-MCS%d/%dSS", nr->nr_txmcs, nr->nr_vht_ss);
2797 } else if (nr->nr_flags & IEEE80211_NODEREQ_HT0x08) {
2798 printf("HT-MCS%d ", nr->nr_txmcs);
2799 } else if (nr->nr_nrates) {
2800 printf("%uM ",
2801 (nr->nr_rates[nr->nr_txrate] & IEEE80211_RATE_VAL0x7f)
2802 / 2);
2803 }
2804 } else if (nr->nr_max_rxrate) {
2805 printf("%uM HT ", nr->nr_max_rxrate);
2806 } else if (nr->nr_rxmcs[0] != 0) {
2807 for (i = IEEE80211_HT_NUM_MCS77 - 1; i >= 0; i--) {
2808 if (nr->nr_rxmcs[i / 8] & (1 << (i / 10)))
2809 break;
2810 }
2811 printf("HT-MCS%d ", i);
2812 } else if (nr->nr_nrates) {
2813 printf("%uM ",
2814 (nr->nr_rates[nr->nr_nrates - 1] & IEEE80211_RATE_VAL0x7f) / 2);
2815 }
2816 /* ESS is the default, skip it */
2817 nr->nr_capinfo &= ~IEEE80211_CAPINFO_ESS0x0001;
2818 if (nr->nr_capinfo) {
2819 printb_status(nr->nr_capinfo, IEEE80211_CAPINFO_BITS"\10\01ESS\02IBSS\03CF_POLLABLE\04CF_POLLREQ" "\05PRIVACY\06SHORT_PREAMBLE\07PBCC\10CHNL_AGILITY"
"\11SPECTRUM_MGMT\12QOS\13SHORT_SLOTTIME\14APSD" "\15RADIO_MEASUREMENT\16DSSSOFDM\17DELAYED_B_ACK\20IMMEDIATE_B_ACK"
);
2820 if (nr->nr_capinfo & IEEE80211_CAPINFO_PRIVACY0x0010) {
2821 if (nr->nr_rsnprotos) {
2822 if (nr->nr_rsnprotos & IEEE80211_WPA_PROTO_WPA20x02)
2823 fputs(",wpa2", stdout(&__sF[1]));
2824 if (nr->nr_rsnprotos & IEEE80211_WPA_PROTO_WPA10x01)
2825 fputs(",wpa1", stdout(&__sF[1]));
2826 } else
2827 fputs(",wep", stdout(&__sF[1]));
2828
2829 if (nr->nr_rsnakms & IEEE80211_WPA_AKM_8021X0x02 ||
2830 nr->nr_rsnakms & IEEE80211_WPA_AKM_SHA256_8021X0x08)
2831 fputs(",802.1x", stdout(&__sF[1]));
2832 }
2833 putchar(' ')(!__isthreaded ? __sputc(' ', (&__sF[1])) : (putc)(' ', (
&__sF[1])))
;
2834 }
2835
2836 if ((nr->nr_flags & IEEE80211_NODEREQ_AP0x01) == 0)
2837 printb_status(IEEE80211_NODEREQ_STATE(nr->nr_state)(1 << nr->nr_state),
2838 IEEE80211_NODEREQ_STATE_BITS"\20\01CACHE\02BSS\03AUTH\04ASSOC\05COLLECT");
2839 else if (nr->nr_assoc_fail)
2840 print_assoc_failures(nr->nr_assoc_fail);
2841}
2842
2843void
2844init_current_media(void)
2845{
2846 struct ifmediareq ifmr;
2847
2848 /*
2849 * If we have not yet done so, grab the currently-selected
2850 * media.
2851 */
2852 if ((actions & (A_MEDIA0x0001|A_MEDIAOPT(0x0002|0x0004)|A_MEDIAMODE0x0010)) == 0) {
2853 (void) memset(&ifmr, 0, sizeof(ifmr));
2854 (void) strlcpy(ifmr.ifm_name, ifname, sizeof(ifmr.ifm_name));
2855
2856 if (ioctl(sock, SIOCGIFMEDIA(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifmediareq) & 0x1fff) << 16) | ((('i')) <<
8) | ((56)))
, (caddr_t)&ifmr) == -1) {
2857 /*
2858 * If we get E2BIG, the kernel is telling us
2859 * that there are more, so we can ignore it.
2860 */
2861 if (errno(*__errno()) != E2BIG7)
2862 err(1, "SIOCGIFMEDIA");
2863 }
2864
2865 media_current = ifmr.ifm_current;
2866 }
2867
2868 /* Sanity. */
2869 if (IFM_TYPE(media_current)((media_current) & 0x000000000000ff00ULL) == 0)
2870 errx(1, "%s: no link type?", ifname);
2871}
2872
2873void
2874process_media_commands(void)
2875{
2876
2877 if ((actions & (A_MEDIA0x0001|A_MEDIAOPT(0x0002|0x0004)|A_MEDIAMODE0x0010)) == 0) {
2878 /* Nothing to do. */
2879 return;
2880 }
2881
2882 /*
2883 * Media already set up, and commands sanity-checked. Set/clear
2884 * any options, and we're ready to go.
2885 */
2886 media_current |= mediaopt_set;
2887 media_current &= ~mediaopt_clear;
2888
2889 (void) strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2890 ifr.ifr_mediaifr_ifru.ifru_media = media_current;
2891
2892 if (ioctl(sock, SIOCSIFMEDIA(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((55)))
, (caddr_t)&ifr) == -1)
2893 err(1, "SIOCSIFMEDIA");
2894}
2895
2896/* ARGSUSED */
2897void
2898setmedia(const char *val, int d)
2899{
2900 uint64_t type, subtype, inst;
2901
2902 if (val == NULL((void*)0)) {
2903 if (showmediaflag)
2904 usage();
2905 showmediaflag = 1;
2906 return;
2907 }
2908
2909 init_current_media();
2910
2911 /* Only one media command may be given. */
2912 if (actions & A_MEDIA0x0001)
2913 errx(1, "only one `media' command may be issued");
2914
2915 /* Must not come after mode commands */
2916 if (actions & A_MEDIAMODE0x0010)
2917 errx(1, "may not issue `media' after `mode' commands");
2918
2919 /* Must not come after mediaopt commands */
2920 if (actions & A_MEDIAOPT(0x0002|0x0004))
2921 errx(1, "may not issue `media' after `mediaopt' commands");
2922
2923 /*
2924 * No need to check if `instance' has been issued; setmediainst()
2925 * craps out if `media' has not been specified.
2926 */
2927
2928 type = IFM_TYPE(media_current)((media_current) & 0x000000000000ff00ULL);
2929 inst = IFM_INST(media_current)(((media_current) & 0xff00000000000000ULL) >> 56);
2930
2931 /* Look up the subtype. */
2932 subtype = get_media_subtype(type, val);
2933
2934 /* Build the new current media word. */
2935 media_current = IFM_MAKEWORD(type, subtype, 0, inst)((type) | (subtype) | (0) | ((uint64_t)(inst) << 56));
2936
2937 /* Media will be set after other processing is complete. */
2938}
2939
2940/* ARGSUSED */
2941void
2942setmediamode(const char *val, int d)
2943{
2944 uint64_t type, subtype, options, inst, mode;
2945
2946 init_current_media();
2947
2948 /* Can only issue `mode' once. */
2949 if (actions & A_MEDIAMODE0x0010)
2950 errx(1, "only one `mode' command may be issued");
2951
2952 type = IFM_TYPE(media_current)((media_current) & 0x000000000000ff00ULL);
2953 subtype = IFM_SUBTYPE(media_current)((media_current) & 0x00000000000000ffULL);
2954 options = IFM_OPTIONS(media_current)((media_current) & (0x00000000ffff0000ULL|0x00ffff0000000000ULL
))
;
2955 inst = IFM_INST(media_current)(((media_current) & 0xff00000000000000ULL) >> 56);
2956
2957 if ((mode = get_media_mode(type, val)) == -1)
2958 errx(1, "invalid media mode: %s", val);
2959 media_current = IFM_MAKEWORD(type, subtype, options, inst)((type) | (subtype) | (options) | ((uint64_t)(inst) << 56
))
| mode;
2960 /* Media will be set after other processing is complete. */
2961}
2962
2963void
2964unsetmediamode(const char *val, int d)
2965{
2966 uint64_t type, subtype, options, inst;
2967
2968 init_current_media();
2969
2970 /* Can only issue `mode' once. */
2971 if (actions & A_MEDIAMODE0x0010)
2972 errx(1, "only one `mode' command may be issued");
2973
2974 type = IFM_TYPE(media_current)((media_current) & 0x000000000000ff00ULL);
2975 subtype = IFM_SUBTYPE(media_current)((media_current) & 0x00000000000000ffULL);
2976 options = IFM_OPTIONS(media_current)((media_current) & (0x00000000ffff0000ULL|0x00ffff0000000000ULL
))
;
2977 inst = IFM_INST(media_current)(((media_current) & 0xff00000000000000ULL) >> 56);
2978
2979 media_current = IFM_MAKEWORD(type, subtype, options, inst)((type) | (subtype) | (options) | ((uint64_t)(inst) << 56
))
|
2980 (IFM_AUTO0ULL << IFM_MSHIFT32);
2981 /* Media will be set after other processing is complete. */
2982}
2983
2984void
2985setmediaopt(const char *val, int d)
2986{
2987
2988 init_current_media();
2989
2990 /* Can only issue `mediaopt' once. */
2991 if (actions & A_MEDIAOPTSET0x0002)
2992 errx(1, "only one `mediaopt' command may be issued");
2993
2994 /* Can't issue `mediaopt' if `instance' has already been issued. */
2995 if (actions & A_MEDIAINST0x0008)
2996 errx(1, "may not issue `mediaopt' after `instance'");
2997
2998 mediaopt_set = get_media_options(IFM_TYPE(media_current)((media_current) & 0x000000000000ff00ULL), val);
2999
3000 /* Media will be set after other processing is complete. */
3001}
3002
3003/* ARGSUSED */
3004void
3005unsetmediaopt(const char *val, int d)
3006{
3007
3008 init_current_media();
3009
3010 /* Can only issue `-mediaopt' once. */
3011 if (actions & A_MEDIAOPTCLR0x0004)
3012 errx(1, "only one `-mediaopt' command may be issued");
3013
3014 /* May not issue `media' and `-mediaopt'. */
3015 if (actions & A_MEDIA0x0001)
3016 errx(1, "may not issue both `media' and `-mediaopt'");
3017
3018 /*
3019 * No need to check for A_MEDIAINST, since the test for A_MEDIA
3020 * implicitly checks for A_MEDIAINST.
3021 */
3022
3023 mediaopt_clear = get_media_options(IFM_TYPE(media_current)((media_current) & 0x000000000000ff00ULL), val);
3024
3025 /* Media will be set after other processing is complete. */
3026}
3027
3028/* ARGSUSED */
3029void
3030setmediainst(const char *val, int d)
3031{
3032 uint64_t type, subtype, options, inst;
3033 const char *errmsg = NULL((void*)0);
3034
3035 init_current_media();
3036
3037 /* Can only issue `instance' once. */
3038 if (actions & A_MEDIAINST0x0008)
3039 errx(1, "only one `instance' command may be issued");
3040
3041 /* Must have already specified `media' */
3042 if ((actions & A_MEDIA0x0001) == 0)
3043 errx(1, "must specify `media' before `instance'");
3044
3045 type = IFM_TYPE(media_current)((media_current) & 0x000000000000ff00ULL);
3046 subtype = IFM_SUBTYPE(media_current)((media_current) & 0x00000000000000ffULL);
3047 options = IFM_OPTIONS(media_current)((media_current) & (0x00000000ffff0000ULL|0x00ffff0000000000ULL
))
;
3048
3049 inst = strtonum(val, 0, IFM_INST_MAX(((0xff00000000000000ULL) & 0xff00000000000000ULL) >>
56)
, &errmsg);
3050 if (errmsg)
3051 errx(1, "media instance %s: %s", val, errmsg);
3052
3053 media_current = IFM_MAKEWORD(type, subtype, options, inst)((type) | (subtype) | (options) | ((uint64_t)(inst) << 56
))
;
3054
3055 /* Media will be set after other processing is complete. */
3056}
3057
3058
3059const struct ifmedia_description ifm_type_descriptions[] =
3060 IFM_TYPE_DESCRIPTIONS{ { 0x0000000000000100ULL, "Ethernet" }, { 0x0000000000000100ULL
, "ether" }, { 0x0000000000000300ULL, "FDDI" }, { 0x0000000000000400ULL
, "IEEE802.11" }, { 0x0000000000000500ULL, "TDM" }, { 0x0000000000000600ULL
, "CARP" }, { 0, ((void*)0) }, }
;
3061
3062const struct ifmedia_description ifm_subtype_descriptions[] =
3063 IFM_SUBTYPE_DESCRIPTIONS{ { 0ULL, "autoselect" }, { 0ULL, "auto" }, { 1ULL, "manual" }
, { 2ULL, "none" }, { 0x0000000000000100ULL|3, "10baseT" }, {
0x0000000000000100ULL|3, "10baseT/UTP" }, { 0x0000000000000100ULL
|3, "UTP" }, { 0x0000000000000100ULL|3, "10UTP" }, { 0x0000000000000100ULL
|4, "10base2" }, { 0x0000000000000100ULL|4, "10base2/BNC" }, {
0x0000000000000100ULL|4, "BNC" }, { 0x0000000000000100ULL|4,
"10BNC" }, { 0x0000000000000100ULL|5, "10base5" }, { 0x0000000000000100ULL
|5, "10base5/AUI" }, { 0x0000000000000100ULL|5, "AUI" }, { 0x0000000000000100ULL
|5, "10AUI" }, { 0x0000000000000100ULL|6, "100baseTX" }, { 0x0000000000000100ULL
|6, "100TX" }, { 0x0000000000000100ULL|7, "100baseFX" }, { 0x0000000000000100ULL
|7, "100FX" }, { 0x0000000000000100ULL|8, "100baseT4" }, { 0x0000000000000100ULL
|8, "100T4" }, { 0x0000000000000100ULL|9, "100baseVG" }, { 0x0000000000000100ULL
|9, "100VG" }, { 0x0000000000000100ULL|10, "100baseT2" }, { 0x0000000000000100ULL
|10, "100T2" }, { 0x0000000000000100ULL|11, "1000baseSX" }, {
0x0000000000000100ULL|11, "1000SX" }, { 0x0000000000000100ULL
|12, "10baseSTP" }, { 0x0000000000000100ULL|12, "STP" }, { 0x0000000000000100ULL
|12, "10STP" }, { 0x0000000000000100ULL|13, "10baseFL" }, { 0x0000000000000100ULL
|13, "FL" }, { 0x0000000000000100ULL|13, "10FL" }, { 0x0000000000000100ULL
|14, "1000baseLX" }, { 0x0000000000000100ULL|14, "1000LX" }, {
0x0000000000000100ULL|15, "1000baseCX" }, { 0x0000000000000100ULL
|15, "1000CX" }, { 0x0000000000000100ULL|16, "1000baseT" }, {
0x0000000000000100ULL|16, "1000T" }, { 0x0000000000000100ULL
|16, "1000baseTX" }, { 0x0000000000000100ULL|16, "1000TX" }, {
0x0000000000000100ULL|17, "HomePNA1" }, { 0x0000000000000100ULL
|17, "HPNA1" }, { 0x0000000000000100ULL|18, "10GbaseLR" }, { 0x0000000000000100ULL
|18, "10GLR" }, { 0x0000000000000100ULL|18, "10GBASE-LR" }, {
0x0000000000000100ULL|19, "10GbaseSR" }, { 0x0000000000000100ULL
|19, "10GSR" }, { 0x0000000000000100ULL|19, "10GBASE-SR" }, {
0x0000000000000100ULL|20, "10GbaseCX4" }, { 0x0000000000000100ULL
|20, "10GCX4" }, { 0x0000000000000100ULL|20, "10GBASE-CX4" },
{ 0x0000000000000100ULL|21, "2500baseSX" }, { 0x0000000000000100ULL
|21, "2500SX" }, { 0x0000000000000100ULL|22, "10GbaseT" }, { 0x0000000000000100ULL
|22, "10GT" }, { 0x0000000000000100ULL|22, "10GBASE-T" }, { 0x0000000000000100ULL
|23, "10GSFP+Cu" }, { 0x0000000000000100ULL|23, "10GCu" }, { 0x0000000000000100ULL
|24, "10GbaseLRM" }, { 0x0000000000000100ULL|24, "10GBASE-LRM"
}, { 0x0000000000000100ULL|25, "40GbaseCR4" }, { 0x0000000000000100ULL
|25, "40GBASE-CR4" }, { 0x0000000000000100ULL|26, "40GbaseSR4"
}, { 0x0000000000000100ULL|26, "40GBASE-SR4" }, { 0x0000000000000100ULL
|27, "40GbaseLR4" }, { 0x0000000000000100ULL|27, "40GBASE-LR4"
}, { 0x0000000000000100ULL|28, "1000base-KX" }, { 0x0000000000000100ULL
|28, "1000BASE-KX" }, { 0x0000000000000100ULL|29, "10GbaseKX4"
}, { 0x0000000000000100ULL|29, "10GBASE-KX4" }, { 0x0000000000000100ULL
|30, "10GbaseKR" }, { 0x0000000000000100ULL|30, "10GBASE-KR" }
, { 0x0000000000000100ULL|31, "10GbaseCR1" }, { 0x0000000000000100ULL
|31, "10GBASE-CR1" }, { 0x0000000000000100ULL|54, "10G-AOC" }
, { 0x0000000000000100ULL|32, "20GbaseKR2" }, { 0x0000000000000100ULL
|32, "20GBASE-KR2" }, { 0x0000000000000100ULL|33, "2500baseKX"
}, { 0x0000000000000100ULL|33, "2500BASE-KX" }, { 0x0000000000000100ULL
|34, "2500baseT" }, { 0x0000000000000100ULL|34, "2500BASE-T" }
, { 0x0000000000000100ULL|35, "5000baseT" }, { 0x0000000000000100ULL
|35, "5000BASE-T" }, { 0x0000000000000100ULL|36, "1000base-SGMII"
}, { 0x0000000000000100ULL|36, "1000BASE-SGMII" }, { 0x0000000000000100ULL
|37, "10GbaseSFI" }, { 0x0000000000000100ULL|37, "10GBASE-SFI"
}, { 0x0000000000000100ULL|38, "40GbaseXLPPI" }, { 0x0000000000000100ULL
|38, "40GBASE-XLPPI" }, { 0x0000000000000100ULL|39, "1000baseCX-SGMII"
}, { 0x0000000000000100ULL|39, "1000BASE-CX-SGMII" }, { 0x0000000000000100ULL
|40, "40GbaseKR4" }, { 0x0000000000000100ULL|40, "40GBASE-KR4"
}, { 0x0000000000000100ULL|56, "40G-AOC" }, { 0x0000000000000100ULL
|41, "10GbaseER" }, { 0x0000000000000100ULL|41, "10GBASE-ER" }
, { 0x0000000000000100ULL|42, "100GbaseCR4" }, { 0x0000000000000100ULL
|42, "100GBASE-CR4" }, { 0x0000000000000100ULL|43, "100GbaseSR4"
}, { 0x0000000000000100ULL|43, "100GBASE-SR4" }, { 0x0000000000000100ULL
|44, "100GbaseKR4" }, { 0x0000000000000100ULL|44, "100GBASE-KR4"
}, { 0x0000000000000100ULL|45, "100GbaseLR4" }, { 0x0000000000000100ULL
|45, "100GBASE-LR4" }, { 0x0000000000000100ULL|57, "100G-AOC"
}, { 0x0000000000000100ULL|46, "56GbaseR4" }, { 0x0000000000000100ULL
|46, "56GBASE-R4" }, { 0x0000000000000100ULL|47, "25GbaseCR" }
, { 0x0000000000000100ULL|47, "25GBASE-CR" }, { 0x0000000000000100ULL
|48, "25GbaseKR" }, { 0x0000000000000100ULL|48, "25GBASE-KR" }
, { 0x0000000000000100ULL|49, "25GbaseSR" }, { 0x0000000000000100ULL
|49, "25GBASE-SR" }, { 0x0000000000000100ULL|52, "25GbaseLR" }
, { 0x0000000000000100ULL|52, "25GBASE-LR" }, { 0x0000000000000100ULL
|53, "25GbaseER" }, { 0x0000000000000100ULL|53, "25GBASE-ER" }
, { 0x0000000000000100ULL|55, "25G-AOC" }, { 0x0000000000000100ULL
|50, "50GbaseCR2" }, { 0x0000000000000100ULL|50, "50GBASE-CR2"
}, { 0x0000000000000100ULL|51, "50GbaseKR2" }, { 0x0000000000000100ULL
|51, "50GBASE-KR2" }, { 0x0000000000000300ULL|3, "Single-mode"
}, { 0x0000000000000300ULL|3, "SMF" }, { 0x0000000000000300ULL
|4, "Multi-mode" }, { 0x0000000000000300ULL|4, "MMF" }, { 0x0000000000000300ULL
|5, "UTP" }, { 0x0000000000000300ULL|5, "CDDI" }, { 0x0000000000000400ULL
|3, "FH1" }, { 0x0000000000000400ULL|4, "FH2" }, { 0x0000000000000400ULL
|5, "DS2" }, { 0x0000000000000400ULL|6, "DS5" }, { 0x0000000000000400ULL
|7, "DS11" }, { 0x0000000000000400ULL|8, "DS1" }, { 0x0000000000000400ULL
|9, "DS22" }, { 0x0000000000000400ULL|10, "OFDM6" }, { 0x0000000000000400ULL
|11, "OFDM9" }, { 0x0000000000000400ULL|12, "OFDM12" }, { 0x0000000000000400ULL
|13, "OFDM18" }, { 0x0000000000000400ULL|14, "OFDM24" }, { 0x0000000000000400ULL
|15, "OFDM36" }, { 0x0000000000000400ULL|16, "OFDM48" }, { 0x0000000000000400ULL
|17, "OFDM54" }, { 0x0000000000000400ULL|18, "OFDM72" }, { 0x0000000000000400ULL
|19, "HT-MCS0" }, { 0x0000000000000400ULL|20, "HT-MCS1" }, { 0x0000000000000400ULL
|21, "HT-MCS2" }, { 0x0000000000000400ULL|22, "HT-MCS3" }, { 0x0000000000000400ULL
|23, "HT-MCS4" }, { 0x0000000000000400ULL|24, "HT-MCS5" }, { 0x0000000000000400ULL
|25, "HT-MCS6" }, { 0x0000000000000400ULL|26, "HT-MCS7" }, { 0x0000000000000400ULL
|27, "HT-MCS8" }, { 0x0000000000000400ULL|28, "HT-MCS9" }, { 0x0000000000000400ULL
|29, "HT-MCS10" }, { 0x0000000000000400ULL|30, "HT-MCS11" }, {
0x0000000000000400ULL|31, "HT-MCS12" }, { 0x0000000000000400ULL
|32, "HT-MCS13" }, { 0x0000000000000400ULL|33, "HT-MCS14" }, {
0x0000000000000400ULL|34, "HT-MCS15" }, { 0x0000000000000400ULL
|35, "HT-MCS16" }, { 0x0000000000000400ULL|36, "HT-MCS17" }, {
0x0000000000000400ULL|37, "HT-MCS18" }, { 0x0000000000000400ULL
|38, "HT-MCS19" }, { 0x0000000000000400ULL|39, "HT-MCS20" }, {
0x0000000000000400ULL|40, "HT-MCS21" }, { 0x0000000000000400ULL
|41, "HT-MCS22" }, { 0x0000000000000400ULL|42, "HT-MCS23" }, {
0x0000000000000400ULL|43, "HT-MCS24" }, { 0x0000000000000400ULL
|44, "HT-MCS25" }, { 0x0000000000000400ULL|45, "HT-MCS26" }, {
0x0000000000000400ULL|46, "HT-MCS27" }, { 0x0000000000000400ULL
|47, "HT-MCS28" }, { 0x0000000000000400ULL|48, "HT-MCS29" }, {
0x0000000000000400ULL|49, "HT-MCS30" }, { 0x0000000000000400ULL
|50, "HT-MCS31" }, { 0x0000000000000400ULL|51, "HT-MCS32" }, {
0x0000000000000400ULL|52, "HT-MCS33" }, { 0x0000000000000400ULL
|53, "HT-MCS34" }, { 0x0000000000000400ULL|54, "HT-MCS35" }, {
0x0000000000000400ULL|55, "HT-MCS36" }, { 0x0000000000000400ULL
|56, "HT-MCS37" }, { 0x0000000000000400ULL|57, "HT-MCS38" }, {
0x0000000000000400ULL|58, "HT-MCS39" }, { 0x0000000000000400ULL
|59, "HT-MCS40" }, { 0x0000000000000400ULL|60, "HT-MCS41" }, {
0x0000000000000400ULL|61, "HT-MCS42" }, { 0x0000000000000400ULL
|62, "HT-MCS43" }, { 0x0000000000000400ULL|63, "HT-MCS44" }, {
0x0000000000000400ULL|64, "HT-MCS45" }, { 0x0000000000000400ULL
|65, "HT-MCS46" }, { 0x0000000000000400ULL|66, "HT-MCS47" }, {
0x0000000000000400ULL|67, "HT-MCS48" }, { 0x0000000000000400ULL
|68, "HT-MCS49" }, { 0x0000000000000400ULL|69, "HT-MCS50" }, {
0x0000000000000400ULL|70, "HT-MCS51" }, { 0x0000000000000400ULL
|71, "HT-MCS52" }, { 0x0000000000000400ULL|72, "HT-MCS53" }, {
0x0000000000000400ULL|73, "HT-MCS54" }, { 0x0000000000000400ULL
|74, "HT-MCS55" }, { 0x0000000000000400ULL|75, "HT-MCS56" }, {
0x0000000000000400ULL|76, "HT-MCS57" }, { 0x0000000000000400ULL
|77, "HT-MCS58" }, { 0x0000000000000400ULL|78, "HT-MCS59" }, {
0x0000000000000400ULL|79, "HT-MCS60" }, { 0x0000000000000400ULL
|80, "HT-MCS61" }, { 0x0000000000000400ULL|81, "HT-MCS62" }, {
0x0000000000000400ULL|82, "HT-MCS63" }, { 0x0000000000000400ULL
|83, "HT-MCS64" }, { 0x0000000000000400ULL|84, "HT-MCS65" }, {
0x0000000000000400ULL|85, "HT-MCS66" }, { 0x0000000000000400ULL
|86, "HT-MCS67" }, { 0x0000000000000400ULL|87, "HT-MCS68" }, {
0x0000000000000400ULL|88, "HT-MCS69" }, { 0x0000000000000400ULL
|89, "HT-MCS70" }, { 0x0000000000000400ULL|90, "HT-MCS71" }, {
0x0000000000000400ULL|91, "HT-MCS72" }, { 0x0000000000000400ULL
|92, "HT-MCS73" }, { 0x0000000000000400ULL|93, "HT-MCS74" }, {
0x0000000000000400ULL|94, "HT-MCS75" }, { 0x0000000000000400ULL
|95, "HT-MCS76" }, { 0x0000000000000400ULL|96, "VHT-MCS0" }, {
0x0000000000000400ULL|97, "VHT-MCS1" }, { 0x0000000000000400ULL
|98, "VHT-MCS2" }, { 0x0000000000000400ULL|99, "VHT-MCS3" }, {
0x0000000000000400ULL|100, "VHT-MCS4" }, { 0x0000000000000400ULL
|101, "VHT-MCS5" }, { 0x0000000000000400ULL|102, "VHT-MCS6" }
, { 0x0000000000000400ULL|103, "VHT-MCS7" }, { 0x0000000000000400ULL
|104, "VHT-MCS8" }, { 0x0000000000000400ULL|105, "VHT-MCS9" }
, { 0x0000000000000500ULL|3, "t1" }, { 0x0000000000000500ULL|
4, "t1-ami" }, { 0x0000000000000500ULL|5, "e1" }, { 0x0000000000000500ULL
|6, "e1-g.704" }, { 0x0000000000000500ULL|7, "e1-ami" }, { 0x0000000000000500ULL
|8, "e1-ami-g.704" }, { 0x0000000000000500ULL|9, "t3" }, { 0x0000000000000500ULL
|10, "t3-m13" }, { 0x0000000000000500ULL|11, "e3" }, { 0x0000000000000500ULL
|12, "e3-g.751" }, { 0x0000000000000500ULL|13, "e3-g.832" }, {
0x0000000000000500ULL|14, "e1-g.704-crc4" }, { 0, ((void*)0)
}, }
;
3064
3065struct ifmedia_description ifm_mode_descriptions[] =
3066 IFM_MODE_DESCRIPTIONS{ { 0ULL, "autoselect" }, { 0ULL, "auto" }, { 0x0000000000000400ULL
|0x0000000100000000ULL, "11a" }, { 0x0000000000000400ULL|0x0000000200000000ULL
, "11b" }, { 0x0000000000000400ULL|0x0000000300000000ULL, "11g"
}, { 0x0000000000000400ULL|0x0000000400000000ULL, "fh" }, { 0x0000000000000400ULL
|0x0000000800000000ULL, "11n" }, { 0x0000000000000400ULL|0x0000001000000000ULL
, "11ac" }, { 0x0000000000000500ULL|0x0000000100000000ULL, "master"
}, { 0, ((void*)0) }, }
;
3067
3068const struct ifmedia_description ifm_option_descriptions[] =
3069 IFM_OPTION_DESCRIPTIONS{ { 0x0000010000000000ULL, "full-duplex" }, { 0x0000010000000000ULL
, "fdx" }, { 0x0000020000000000ULL, "half-duplex" }, { 0x0000020000000000ULL
, "hdx" }, { 0x0000100000000000ULL, "flag0" }, { 0x0000200000000000ULL
, "flag1" }, { 0x0000400000000000ULL, "flag2" }, { 0x0000800000000000ULL
, "loopback" }, { 0x0000800000000000ULL, "hw-loopback"}, { 0x0000800000000000ULL
, "loop" }, { 0x0000000000000100ULL|0x0000000000010000ULL, "master"
}, { 0x0000000000000100ULL|0x0000000000020000ULL, "rxpause" }
, { 0x0000000000000100ULL|0x0000000000040000ULL, "txpause" },
{ 0x0000000000000300ULL|0x00000100, "dual-attach" }, { 0x0000000000000300ULL
|0x00000100, "das" }, { 0x0000000000000400ULL|0x0000000000010000ULL
, "adhoc" }, { 0x0000000000000400ULL|0x0000000000020000ULL, "hostap"
}, { 0x0000000000000400ULL|0x0000000000040000ULL, "ibss" }, {
0x0000000000000400ULL|0x0000000000080000ULL, "ibss-master" }
, { 0x0000000000000400ULL|0x0000000000100000ULL, "monitor" },
{ 0x0000000000000500ULL|0x0100, "hdlc-crc16" }, { 0x0000000000000500ULL
|0x0200, "ppp" }, { 0x0000000000000500ULL|0x0400, "framerelay-ansi"
}, { 0x0000000000000500ULL|0x0800, "framerelay-cisco" }, { 0x0000000000000500ULL
|0x0400, "framerelay-itu" }, { 0, ((void*)0) }, }
;
3070
3071const char *
3072get_media_type_string(uint64_t mword)
3073{
3074 const struct ifmedia_description *desc;
3075
3076 for (desc = ifm_type_descriptions; desc->ifmt_string != NULL((void*)0);
3077 desc++) {
3078 if (IFM_TYPE(mword)((mword) & 0x000000000000ff00ULL) == desc->ifmt_word)
3079 return (desc->ifmt_string);
3080 }
3081 return ("<unknown type>");
3082}
3083
3084const char *
3085get_media_subtype_string(uint64_t mword)
3086{
3087 const struct ifmedia_description *desc;
3088
3089 for (desc = ifm_subtype_descriptions; desc->ifmt_string != NULL((void*)0);
3090 desc++) {
3091 if (IFM_TYPE_MATCH(desc->ifmt_word, mword)((((desc->ifmt_word)) & 0x000000000000ff00ULL) == 0 ||
(((desc->ifmt_word)) & 0x000000000000ff00ULL) == (((mword
)) & 0x000000000000ff00ULL))
&&
3092 IFM_SUBTYPE(desc->ifmt_word)((desc->ifmt_word) & 0x00000000000000ffULL) == IFM_SUBTYPE(mword)((mword) & 0x00000000000000ffULL))
3093 return (desc->ifmt_string);
3094 }
3095 return ("<unknown subtype>");
3096}
3097
3098uint64_t
3099get_media_subtype(uint64_t type, const char *val)
3100{
3101 uint64_t rval;
3102
3103 rval = lookup_media_word(ifm_subtype_descriptions, type, val);
3104 if (rval == -1)
3105 errx(1, "unknown %s media subtype: %s",
3106 get_media_type_string(type), val);
3107
3108 return (rval);
3109}
3110
3111uint64_t
3112get_media_mode(uint64_t type, const char *val)
3113{
3114 uint64_t rval;
3115
3116 rval = lookup_media_word(ifm_mode_descriptions, type, val);
3117 if (rval == -1)
3118 errx(1, "unknown %s media mode: %s",
3119 get_media_type_string(type), val);
3120 return (rval);
3121}
3122
3123uint64_t
3124get_media_options(uint64_t type, const char *val)
3125{
3126 char *optlist, *str;
3127 uint64_t option, rval = 0;
3128
3129 /* We muck with the string, so copy it. */
3130 optlist = strdup(val);
3131 if (optlist == NULL((void*)0))
3132 err(1, "strdup");
3133 str = optlist;
3134
3135 /*
3136 * Look up the options in the user-provided comma-separated list.
3137 */
3138 for (; (str = strtok(str, ",")) != NULL((void*)0); str = NULL((void*)0)) {
3139 option = lookup_media_word(ifm_option_descriptions, type, str);
3140 if (option == -1)
3141 errx(1, "unknown %s media option: %s",
3142 get_media_type_string(type), str);
3143 rval |= IFM_OPTIONS(option)((option) & (0x00000000ffff0000ULL|0x00ffff0000000000ULL)
)
;
3144 }
3145
3146 free(optlist);
3147 return (rval);
3148}
3149
3150uint64_t
3151lookup_media_word(const struct ifmedia_description *desc, uint64_t type,
3152 const char *val)
3153{
3154
3155 for (; desc->ifmt_string != NULL((void*)0); desc++) {
3156 if (IFM_TYPE_MATCH(desc->ifmt_word, type)((((desc->ifmt_word)) & 0x000000000000ff00ULL) == 0 ||
(((desc->ifmt_word)) & 0x000000000000ff00ULL) == (((type
)) & 0x000000000000ff00ULL))
&&
3157 strcasecmp(desc->ifmt_string, val) == 0)
3158 return (desc->ifmt_word);
3159 }
3160 return (-1);
3161}
3162
3163void
3164print_media_word(uint64_t ifmw, int print_type, int as_syntax)
3165{
3166 const struct ifmedia_description *desc;
3167 uint64_t seen_option = 0;
3168
3169 if (print_type)
3170 printf("%s ", get_media_type_string(ifmw));
3171 printf("%s%s", as_syntax ? "media " : "",
3172 get_media_subtype_string(ifmw));
3173
3174 /* Find mode. */
3175 if (IFM_MODE(ifmw)((ifmw) & 0x000000ff00000000ULL) != 0) {
3176 for (desc = ifm_mode_descriptions; desc->ifmt_string != NULL((void*)0);
3177 desc++) {
3178 if (IFM_TYPE_MATCH(desc->ifmt_word, ifmw)((((desc->ifmt_word)) & 0x000000000000ff00ULL) == 0 ||
(((desc->ifmt_word)) & 0x000000000000ff00ULL) == (((ifmw
)) & 0x000000000000ff00ULL))
&&
3179 IFM_MODE(ifmw)((ifmw) & 0x000000ff00000000ULL) == IFM_MODE(desc->ifmt_word)((desc->ifmt_word) & 0x000000ff00000000ULL)) {
3180 printf(" mode %s", desc->ifmt_string);
3181 break;
3182 }
3183 }
3184 }
3185
3186 /* Find options. */
3187 for (desc = ifm_option_descriptions; desc->ifmt_string != NULL((void*)0);
3188 desc++) {
3189 if (IFM_TYPE_MATCH(desc->ifmt_word, ifmw)((((desc->ifmt_word)) & 0x000000000000ff00ULL) == 0 ||
(((desc->ifmt_word)) & 0x000000000000ff00ULL) == (((ifmw
)) & 0x000000000000ff00ULL))
&&
3190 (IFM_OPTIONS(ifmw)((ifmw) & (0x00000000ffff0000ULL|0x00ffff0000000000ULL)) & IFM_OPTIONS(desc->ifmt_word)((desc->ifmt_word) & (0x00000000ffff0000ULL|0x00ffff0000000000ULL
))
) != 0 &&
3191 (seen_option & IFM_OPTIONS(desc->ifmt_word)((desc->ifmt_word) & (0x00000000ffff0000ULL|0x00ffff0000000000ULL
))
) == 0) {
3192 if (seen_option == 0)
3193 printf(" %s", as_syntax ? "mediaopt " : "");
3194 printf("%s%s", seen_option ? "," : "",
3195 desc->ifmt_string);
3196 seen_option |= IFM_OPTIONS(desc->ifmt_word)((desc->ifmt_word) & (0x00000000ffff0000ULL|0x00ffff0000000000ULL
))
;
3197 }
3198 }
3199 if (IFM_INST(ifmw)(((ifmw) & 0xff00000000000000ULL) >> 56) != 0)
3200 printf(" instance %lld", IFM_INST(ifmw)(((ifmw) & 0xff00000000000000ULL) >> 56));
3201}
3202
3203static void
3204print_tunnel(const struct if_laddrreq *req)
3205{
3206 char psrcaddr[NI_MAXHOST256];
3207 char pdstaddr[NI_MAXHOST256];
3208 const char *ver = "";
3209 const int niflag = NI_NUMERICHOST1;
3210
3211 if (req == NULL((void*)0)) {
3212 printf("(unset)");
3213 return;
3214 }
3215
3216 psrcaddr[0] = pdstaddr[0] = '\0';
3217
3218 if (getnameinfo((struct sockaddr *)&req->addr, req->addr.ss_len,
3219 psrcaddr, sizeof(psrcaddr), 0, 0, niflag) != 0)
3220 strlcpy(psrcaddr, "<error>", sizeof(psrcaddr));
3221 if (req->addr.ss_family == AF_INET624)
3222 ver = "6";
3223
3224 printf("inet%s %s", ver, psrcaddr);
3225
3226 if (req->dstaddr.ss_family != AF_UNSPEC0) {
3227 in_port_t dstport = 0;
3228 const struct sockaddr_in *sin;
3229 const struct sockaddr_in6 *sin6;
3230
3231 if (getnameinfo((struct sockaddr *)&req->dstaddr,
3232 req->dstaddr.ss_len, pdstaddr, sizeof(pdstaddr),
3233 0, 0, niflag) != 0)
3234 strlcpy(pdstaddr, "<error>", sizeof(pdstaddr));
3235
3236 printf(" --> %s", pdstaddr);
3237
3238 switch (req->dstaddr.ss_family) {
3239 case AF_INET2:
3240 sin = (const struct sockaddr_in *)&req->dstaddr;
3241 dstport = sin->sin_port;
3242 break;
3243 case AF_INET624:
3244 sin6 = (const struct sockaddr_in6 *)&req->dstaddr;
3245 dstport = sin6->sin6_port;
3246 break;
3247 }
3248
3249 if (dstport)
3250 printf(":%u", ntohs(dstport)(__uint16_t)(__builtin_constant_p(dstport) ? (__uint16_t)(((__uint16_t
)(dstport) & 0xffU) << 8 | ((__uint16_t)(dstport) &
0xff00U) >> 8) : __swap16md(dstport))
);
3251 }
3252}
3253
3254/* ARGSUSED */
3255static void
3256phys_status(int force)
3257{
3258 struct if_laddrreq req;
3259 struct if_laddrreq *r = &req;
3260
3261 memset(&req, 0, sizeof(req));
3262 (void) strlcpy(req.iflr_name, ifname, sizeof(req.iflr_name));
3263 if (ioctl(sock, SIOCGLIFPHYADDR(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct if_laddrreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((75)))
, (caddr_t)&req) == -1) {
3264 if (errno(*__errno()) != EADDRNOTAVAIL49)
3265 return;
3266
3267 r = NULL((void*)0);
3268 }
3269
3270 printf("\ttunnel: ");
3271 print_tunnel(r);
3272
3273 if (ioctl(sock, SIOCGLIFPHYTTL(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((169)))
, (caddr_t)&ifr) == 0) {
3274 if (ifr.ifr_ttlifr_ifru.ifru_metric == -1)
3275 printf(" ttl copy");
3276 else if (ifr.ifr_ttlifr_ifru.ifru_metric > 0)
3277 printf(" ttl %d", ifr.ifr_ttlifr_ifru.ifru_metric);
3278 }
3279
3280 if (ioctl(sock, SIOCGLIFPHYDF(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((194)))
, (caddr_t)&ifr) == 0)
3281 printf(" %s", ifr.ifr_dfifr_ifru.ifru_metric ? "df" : "nodf");
3282
3283#ifndef SMALL
3284 if (ioctl(sock, SIOCGLIFPHYECN(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((200)))
, (caddr_t)&ifr) == 0)
3285 printf(" %s", ifr.ifr_metricifr_ifru.ifru_metric ? "ecn" : "noecn");
3286
3287 if (ioctl(sock, SIOCGLIFPHYRTABLE(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((162)))
, (caddr_t)&ifr) == 0 &&
3288 (rdomainid != 0 || ifr.ifr_rdomainidifr_ifru.ifru_metric != 0))
3289 printf(" rdomain %d", ifr.ifr_rdomainidifr_ifru.ifru_metric);
3290#endif
3291 printf("\n");
3292}
3293
3294#ifndef SMALL
3295const uint64_t ifm_status_valid_list[] = IFM_STATUS_VALID_LIST{ 0x0000000000000001ULL, 0 };
3296
3297const struct ifmedia_status_description ifm_status_descriptions[] =
3298 IFM_STATUS_DESCRIPTIONS{ { 0x0000000000000100ULL, 0x0000000000000001ULL, 0x0000000000000002ULL
, { "no carrier", "active" } }, { 0x0000000000000300ULL, 0x0000000000000001ULL
, 0x0000000000000002ULL, { "no ring", "inserted" } }, { 0x0000000000000400ULL
, 0x0000000000000001ULL, 0x0000000000000002ULL, { "no network"
, "active" } }, { 0x0000000000000500ULL, 0x0000000000000001ULL
, 0x0000000000000002ULL, { "no carrier", "active" } }, { 0x0000000000000600ULL
, 0x0000000000000001ULL, 0x0000000000000002ULL, { "backup", "master"
} }, { 0, 0, 0, { ((void*)0), ((void*)0) } } }
;
3299#endif
3300
3301const struct if_status_description if_status_descriptions[] =
3302 LINK_STATE_DESCRIPTIONS{ { 0x06, 2, "no carrier" }, { 0x47, 2, "no network" }, { 0x17
, 2, "no carrier" }, { 0xf7, 2, "backup" }, { 0xf7, 4, "master"
}, { 0xf7, 5, "master" }, { 0xf7, 6, "master" }, { 0, 4, "active"
}, { 0, 5, "active" }, { 0, 6, "active" }, { 0, 0, "unknown"
}, { 0, 1, "invalid" }, { 0, 2, "down" }, { 0, 3, "keepalive down"
}, { 0, 0, ((void*)0) } }
;
3303
3304const char *
3305get_linkstate(int mt, int link_state)
3306{
3307 const struct if_status_description *p;
3308 static char buf[8];
3309
3310 for (p = if_status_descriptions; p->ifs_string != NULL((void*)0); p++) {
3311 if (LINK_STATE_DESC_MATCH(p, mt, link_state)(((p)->ifs_type == (mt) || (p)->ifs_type == 0) &&
(p)->ifs_state == (link_state))
)
3312 return (p->ifs_string);
3313 }
3314 snprintf(buf, sizeof(buf), "[#%d]", link_state);
3315 return buf;
3316}
3317
3318/*
3319 * Print the status of the interface. If an address family was
3320 * specified, show it and it only; otherwise, show them all.
3321 */
3322void
3323status(int link, struct sockaddr_dl *sdl, int ls)
3324{
3325 const struct afswtch *p = afp;
3326 struct ifmediareq ifmr;
3327#ifndef SMALL
3328 struct ifreq ifrdesc;
3329 struct ifkalivereq ikardesc;
3330 char ifdescr[IFDESCRSIZE64];
3331 char pifname[IF_NAMESIZE16];
3332#endif
3333 uint64_t *media_list;
3334 int i;
3335 char sep;
3336
3337
3338 printf("%s: ", ifname);
3339 printb("flags", flags | (xflags << 16), IFFBITS"\024\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\6STATICARP"
"\7RUNNING\10NOARP\11PROMISC\12ALLMULTI\13OACTIVE\14SIMPLEX"
"\15LINK0\16LINK1\17LINK2\20MULTICAST" "\23AUTOCONF6TEMP\24MPLS\25WOL\26AUTOCONF6\27INET6_NOSOII"
"\30AUTOCONF4" "\31MONITOR"
);
3340#ifndef SMALL
3341 if (rdomainid)
3342 printf(" rdomain %d", rdomainid);
3343#endif
3344 if (metric)
3345 printf(" metric %lu", metric);
3346 if (mtu)
3347 printf(" mtu %lu", mtu);
3348 putchar('\n')(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n',
(&__sF[1])))
;
3349#ifndef SMALL
3350 if (showcapsflag)
3351 printifhwfeatures(NULL((void*)0), 1);
3352#endif
3353 if (sdl != NULL((void*)0) && sdl->sdl_alen &&
3354 (sdl->sdl_type == IFT_ETHER0x06 || sdl->sdl_type == IFT_CARP0xf7))
3355 (void)printf("\tlladdr %s\n", ether_ntoa(
3356 (struct ether_addr *)LLADDR(sdl)((caddr_t)((sdl)->sdl_data + (sdl)->sdl_nlen))));
3357
3358 sep = '\t';
3359#ifndef SMALL
3360 (void) memset(&ifrdesc, 0, sizeof(ifrdesc));
3361 (void) strlcpy(ifrdesc.ifr_name, ifname, sizeof(ifrdesc.ifr_name));
3362 ifrdesc.ifr_dataifr_ifru.ifru_data = (caddr_t)&ifdescr;
3363 if (ioctl(sock, SIOCGIFDESCR(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((129)))
, &ifrdesc) == 0 &&
3364 strlen(ifrdesc.ifr_dataifr_ifru.ifru_data))
3365 printf("\tdescription: %s\n", ifrdesc.ifr_dataifr_ifru.ifru_data);
3366
3367 if (sdl != NULL((void*)0)) {
3368 printf("%cindex %u", sep, sdl->sdl_index);
3369 sep = ' ';
3370 }
3371 if (!is_bridge() && ioctl(sock, SIOCGIFPRIORITY(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((156)))
, &ifrdesc) == 0) {
3372 printf("%cpriority %d", sep, ifrdesc.ifr_metricifr_ifru.ifru_metric);
3373 sep = ' ';
3374 }
3375#endif
3376 printf("%cllprio %d\n", sep, llprio);
3377
3378#ifndef SMALL
3379 (void) memset(&ikardesc, 0, sizeof(ikardesc));
3380 (void) strlcpy(ikardesc.ikar_name, ifname, sizeof(ikardesc.ikar_name));
3381 if (ioctl(sock, SIOCGETKALIVE(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifkalivereq) & 0x1fff) << 16) | ((('i')) <<
8) | ((164)))
, &ikardesc) == 0 &&
3382 (ikardesc.ikar_timeo != 0 || ikardesc.ikar_cnt != 0))
3383 printf("\tkeepalive: timeout %d count %d\n",
3384 ikardesc.ikar_timeo, ikardesc.ikar_cnt);
3385 if (ioctl(sock, SIOCGIFPAIR(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((177)))
, &ifrdesc) == 0 && ifrdesc.ifr_indexifr_ifru.ifru_index != 0 &&
3386 if_indextoname(ifrdesc.ifr_indexifr_ifru.ifru_index, pifname) != NULL((void*)0))
3387 printf("\tpatch: %s\n", pifname);
3388#endif
3389 getencap();
3390#ifndef SMALL
3391 carp_status();
3392 pfsync_status();
3393 pppoe_status();
3394 sppp_status();
3395 mpls_status();
3396 pflow_status();
3397 umb_status();
3398 wg_status();
3399#endif
3400 trunk_status();
3401 getifgroups();
3402
3403 (void) memset(&ifmr, 0, sizeof(ifmr));
3404 (void) strlcpy(ifmr.ifm_name, ifname, sizeof(ifmr.ifm_name));
3405
3406 if (ioctl(sock, SIOCGIFMEDIA(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifmediareq) & 0x1fff) << 16) | ((('i')) <<
8) | ((56)))
, (caddr_t)&ifmr) == -1) {
3407 /*
3408 * Interface doesn't support SIOC{G,S}IFMEDIA.
3409 */
3410 if (ls != LINK_STATE_UNKNOWN0)
3411 printf("\tstatus: %s\n",
3412 get_linkstate(sdl->sdl_type, ls));
3413 goto proto_status;
3414 }
3415
3416 if (ifmr.ifm_count == 0) {
3417 warnx("%s: no media types?", ifname);
3418 goto proto_status;
3419 }
3420
3421 media_list = calloc(ifmr.ifm_count, sizeof(*media_list));
3422 if (media_list == NULL((void*)0))
3423 err(1, "calloc");
3424 ifmr.ifm_ulist = media_list;
3425
3426 if (ioctl(sock, SIOCGIFMEDIA(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifmediareq) & 0x1fff) << 16) | ((('i')) <<
8) | ((56)))
, (caddr_t)&ifmr) == -1)
3427 err(1, "SIOCGIFMEDIA");
3428
3429 printf("\tmedia: ");
3430 print_media_word(ifmr.ifm_current, 1, 0);
3431 if (ifmr.ifm_active != ifmr.ifm_current) {
3432 putchar(' ')(!__isthreaded ? __sputc(' ', (&__sF[1])) : (putc)(' ', (
&__sF[1])))
;
3433 putchar('(')(!__isthreaded ? __sputc('(', (&__sF[1])) : (putc)('(', (
&__sF[1])))
;
3434 print_media_word(ifmr.ifm_active, 0, 0);
3435 putchar(')')(!__isthreaded ? __sputc(')', (&__sF[1])) : (putc)(')', (
&__sF[1])))
;
3436 }
3437 putchar('\n')(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n',
(&__sF[1])))
;
3438
3439#ifdef SMALL
3440 printf("\tstatus: %s\n", get_linkstate(sdl->sdl_type, ls));
3441#else
3442 if (ifmr.ifm_status & IFM_AVALID0x0000000000000001ULL) {
3443 const struct ifmedia_status_description *ifms;
3444 int bitno, found = 0;
3445
3446 printf("\tstatus: ");
3447 for (bitno = 0; ifm_status_valid_list[bitno] != 0; bitno++) {
3448 for (ifms = ifm_status_descriptions;
3449 ifms->ifms_valid != 0; ifms++) {
3450 if (ifms->ifms_type !=
3451 IFM_TYPE(ifmr.ifm_current)((ifmr.ifm_current) & 0x000000000000ff00ULL) ||
3452 ifms->ifms_valid !=
3453 ifm_status_valid_list[bitno])
3454 continue;
3455 printf("%s%s", found ? ", " : "",
3456 IFM_STATUS_DESC(ifms, ifmr.ifm_status)(ifms)->ifms_string[((ifms)->ifms_bit & (ifmr.ifm_status
)) ? 1 : 0]
);
3457 found = 1;
3458
3459 /*
3460 * For each valid indicator bit, there's
3461 * only one entry for each media type, so
3462 * terminate the inner loop now.
3463 */
3464 break;
3465 }
3466 }
3467
3468 if (found == 0)
3469 printf("unknown");
3470 putchar('\n')(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n',
(&__sF[1])))
;
3471 }
3472
3473 if (showtransceiver) {
3474 if (if_sff_info(0) == -1)
3475 if (!aflag && errno(*__errno()) != EPERM1 && errno(*__errno()) != ENOTTY25)
3476 warn("%s transceiver", ifname);
3477 }
3478#endif
3479 ieee80211_status();
3480
3481 if (showmediaflag) {
3482 uint64_t type;
3483 int printed_type = 0;
3484
3485 for (type = IFM_NMIN0x0000000000000100ULL; type <= IFM_NMAX0x000000000000ff00ULL; type += IFM_NMIN0x0000000000000100ULL) {
3486 for (i = 0, printed_type = 0; i < ifmr.ifm_count; i++) {
3487 if (IFM_TYPE(media_list[i])((media_list[i]) & 0x000000000000ff00ULL) == type) {
3488
3489 /*
3490 * Don't advertise media with fixed
3491 * data rates for wireless interfaces.
3492 * Normal people don't need these.
3493 */
3494 if (type == IFM_IEEE802110x0000000000000400ULL &&
3495 (media_list[i] & IFM_TMASK0x00000000000000ffULL) !=
3496 IFM_AUTO0ULL)
3497 continue;
3498
3499 if (printed_type == 0) {
3500 printf("\tsupported media:\n");
3501 printed_type = 1;
3502 }
3503 printf("\t\t");
3504 print_media_word(media_list[i], 0, 1);
3505 printf("\n");
3506 }
3507 }
3508 }
3509 }
3510
3511 free(media_list);
3512
3513 proto_status:
3514 if (link == 0) {
3515 if ((p = afp) != NULL((void*)0)) {
3516 p->af_status(1);
3517 } else for (p = afs; p->af_name; p++) {
3518 ifr.ifr_addrifr_ifru.ifru_addr.sa_family = p->af_af;
3519 p->af_status(0);
3520 }
3521 }
3522
3523 phys_status(0);
3524#ifndef SMALL
3525 bridge_status();
3526#endif
3527}
3528
3529/* ARGSUSED */
3530void
3531in_status(int force)
3532{
3533 struct sockaddr_in *sin, sin2;
3534
3535 getsock(AF_INET2);
3536 if (sock == -1) {
3537 if (errno(*__errno()) == EPROTONOSUPPORT43)
3538 return;
3539 err(1, "socket");
3540 }
3541 (void) strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
3542 sin = (struct sockaddr_in *)&ifr.ifr_addrifr_ifru.ifru_addr;
3543
3544 /*
3545 * We keep the interface address and reset it before each
3546 * ioctl() so we can get ifaliases information (as opposed
3547 * to the primary interface netmask/dstaddr/broadaddr, if
3548 * the ifr_addr field is zero).
3549 */
3550 memcpy(&sin2, &ifr.ifr_addrifr_ifru.ifru_addr, sizeof(sin2));
3551
3552 printf("\tinet %s", inet_ntoa(sin->sin_addr));
3553 (void) strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
3554 if (ioctl(sock, SIOCGIFNETMASK(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((37)))
, (caddr_t)&ifr) == -1) {
3555 if (errno(*__errno()) != EADDRNOTAVAIL49)
3556 warn("SIOCGIFNETMASK");
3557 memset(&ifr.ifr_addrifr_ifru.ifru_addr, 0, sizeof(ifr.ifr_addrifr_ifru.ifru_addr));
3558 } else
3559 netmask.sin_addr =
3560 ((struct sockaddr_in *)&ifr.ifr_addrifr_ifru.ifru_addr)->sin_addr;
3561 if (flags & IFF_POINTOPOINT0x10) {
3562 memcpy(&ifr.ifr_addrifr_ifru.ifru_addr, &sin2, sizeof(sin2));
3563 if (ioctl(sock, SIOCGIFDSTADDR(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((34)))
, (caddr_t)&ifr) == -1) {
3564 if (errno(*__errno()) == EADDRNOTAVAIL49)
3565 memset(&ifr.ifr_addrifr_ifru.ifru_addr, 0, sizeof(ifr.ifr_addrifr_ifru.ifru_addr));
3566 else
3567 warn("SIOCGIFDSTADDR");
3568 }
3569 (void) strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
3570 sin = (struct sockaddr_in *)&ifr.ifr_dstaddrifr_ifru.ifru_dstaddr;
3571 printf(" --> %s", inet_ntoa(sin->sin_addr));
3572 }
3573 printf(" netmask 0x%x", ntohl(netmask.sin_addr.s_addr)(__uint32_t)(__builtin_constant_p(netmask.sin_addr.s_addr) ? (
__uint32_t)(((__uint32_t)(netmask.sin_addr.s_addr) & 0xff
) << 24 | ((__uint32_t)(netmask.sin_addr.s_addr) & 0xff00
) << 8 | ((__uint32_t)(netmask.sin_addr.s_addr) & 0xff0000
) >> 8 | ((__uint32_t)(netmask.sin_addr.s_addr) & 0xff000000
) >> 24) : __swap32md(netmask.sin_addr.s_addr))
);
3574 if (flags & IFF_BROADCAST0x2) {
3575 memcpy(&ifr.ifr_addrifr_ifru.ifru_addr, &sin2, sizeof(sin2));
3576 if (ioctl(sock, SIOCGIFBRDADDR(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((35)))
, (caddr_t)&ifr) == -1) {
3577 if (errno(*__errno()) == EADDRNOTAVAIL49)
3578 memset(&ifr.ifr_addrifr_ifru.ifru_addr, 0, sizeof(ifr.ifr_addrifr_ifru.ifru_addr));
3579 else
3580 warn("SIOCGIFBRDADDR");
3581 }
3582 (void) strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
3583 sin = (struct sockaddr_in *)&ifr.ifr_addrifr_ifru.ifru_addr;
3584 if (sin->sin_addr.s_addr != 0)
3585 printf(" broadcast %s", inet_ntoa(sin->sin_addr));
3586 }
3587 putchar('\n')(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n',
(&__sF[1])))
;
3588}
3589
3590/* ARGSUSED */
3591void
3592setifprefixlen(const char *addr, int d)
3593{
3594 if (afp->af_getprefix)
3595 afp->af_getprefix(addr, MASK2);
3596 explicit_prefix = 1;
3597}
3598
3599void
3600in6_fillscopeid(struct sockaddr_in6 *sin6)
3601{
3602#ifdef __KAME__
3603 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)(((&sin6->sin6_addr)->__u6_addr.__u6_addr8[0] == 0xfe
) && (((&sin6->sin6_addr)->__u6_addr.__u6_addr8
[1] & 0xc0) == 0x80))
&&
3604 sin6->sin6_scope_id == 0) {
3605 sin6->sin6_scope_id =
3606 ntohs(*(u_int16_t *)&sin6->sin6_addr.s6_addr[2])(__uint16_t)(__builtin_constant_p(*(u_int16_t *)&sin6->
sin6_addr.__u6_addr.__u6_addr8[2]) ? (__uint16_t)(((__uint16_t
)(*(u_int16_t *)&sin6->sin6_addr.__u6_addr.__u6_addr8[
2]) & 0xffU) << 8 | ((__uint16_t)(*(u_int16_t *)&
sin6->sin6_addr.__u6_addr.__u6_addr8[2]) & 0xff00U) >>
8) : __swap16md(*(u_int16_t *)&sin6->sin6_addr.__u6_addr
.__u6_addr8[2]))
;
3607 sin6->sin6_addr.s6_addr__u6_addr.__u6_addr8[2] = sin6->sin6_addr.s6_addr__u6_addr.__u6_addr8[3] = 0;
3608 }
3609#endif /* __KAME__ */
3610}
3611
3612/* XXX not really an alias */
3613void
3614in6_alias(struct in6_ifreq *creq)
3615{
3616 struct sockaddr_in6 *sin6;
3617 struct in6_ifreq ifr6; /* shadows file static variable */
3618 u_int32_t scopeid;
3619 char hbuf[NI_MAXHOST256];
3620 const int niflag = NI_NUMERICHOST1;
3621
3622 /* Get the non-alias address for this interface. */
3623 getsock(AF_INET624);
3624 if (sock == -1) {
3625 if (errno(*__errno()) == EPROTONOSUPPORT43)
3626 return;
3627 err(1, "socket");
3628 }
3629
3630 sin6 = (struct sockaddr_in6 *)&creq->ifr_addrifr_ifru.ifru_addr;
3631
3632 in6_fillscopeid(sin6);
3633 scopeid = sin6->sin6_scope_id;
3634 if (getnameinfo((struct sockaddr *)sin6, sin6->sin6_len,
3635 hbuf, sizeof(hbuf), NULL((void*)0), 0, niflag) != 0)
3636 strlcpy(hbuf, "", sizeof hbuf);
3637 printf("\tinet6 %s", hbuf);
3638
3639 if (flags & IFF_POINTOPOINT0x10) {
3640 (void) memset(&ifr6, 0, sizeof(ifr6));
3641 (void) strlcpy(ifr6.ifr_name, ifname, sizeof(ifr6.ifr_name));
3642 ifr6.ifr_addrifr_ifru.ifru_addr = creq->ifr_addrifr_ifru.ifru_addr;
3643 if (ioctl(sock, SIOCGIFDSTADDR_IN6(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct in6_ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((34)))
, (caddr_t)&ifr6) == -1) {
3644 if (errno(*__errno()) != EADDRNOTAVAIL49)
3645 warn("SIOCGIFDSTADDR_IN6");
3646 (void) memset(&ifr6.ifr_addrifr_ifru.ifru_addr, 0, sizeof(ifr6.ifr_addrifr_ifru.ifru_addr));
3647 ifr6.ifr_addrifr_ifru.ifru_addr.sin6_family = AF_INET624;
3648 ifr6.ifr_addrifr_ifru.ifru_addr.sin6_len = sizeof(struct sockaddr_in6);
3649 }
3650 sin6 = (struct sockaddr_in6 *)&ifr6.ifr_addrifr_ifru.ifru_addr;
3651 in6_fillscopeid(sin6);
3652 if (getnameinfo((struct sockaddr *)sin6, sin6->sin6_len,
3653 hbuf, sizeof(hbuf), NULL((void*)0), 0, niflag) != 0)
3654 strlcpy(hbuf, "", sizeof hbuf);
3655 printf(" --> %s", hbuf);
3656 }
3657
3658 (void) memset(&ifr6, 0, sizeof(ifr6));
3659 (void) strlcpy(ifr6.ifr_name, ifname, sizeof(ifr6.ifr_name));
3660 ifr6.ifr_addrifr_ifru.ifru_addr = creq->ifr_addrifr_ifru.ifru_addr;
3661 if (ioctl(sock, SIOCGIFNETMASK_IN6(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct in6_ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((37)))
, (caddr_t)&ifr6) == -1) {
3662 if (errno(*__errno()) != EADDRNOTAVAIL49)
3663 warn("SIOCGIFNETMASK_IN6");
3664 } else {
3665 sin6 = (struct sockaddr_in6 *)&ifr6.ifr_addrifr_ifru.ifru_addr;
3666 printf(" prefixlen %d", prefix(&sin6->sin6_addr,
3667 sizeof(struct in6_addr)));
3668 }
3669
3670 (void) memset(&ifr6, 0, sizeof(ifr6));
3671 (void) strlcpy(ifr6.ifr_name, ifname, sizeof(ifr6.ifr_name));
3672 ifr6.ifr_addrifr_ifru.ifru_addr = creq->ifr_addrifr_ifru.ifru_addr;
3673 if (ioctl(sock, SIOCGIFAFLAG_IN6(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct in6_ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((73)))
, (caddr_t)&ifr6) == -1) {
3674 if (errno(*__errno()) != EADDRNOTAVAIL49)
3675 warn("SIOCGIFAFLAG_IN6");
3676 } else {
3677 if (ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_ANYCAST0x01)
3678 printf(" anycast");
3679 if (ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_TENTATIVE0x02)
3680 printf(" tentative");
3681 if (ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_DUPLICATED0x04)
3682 printf(" duplicated");
3683 if (ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_DETACHED0x08)
3684 printf(" detached");
3685 if (ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_DEPRECATED0x10)
3686 printf(" deprecated");
3687 if (ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_AUTOCONF0x40)
3688 printf(" autoconf");
3689 if (ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_TEMPORARY0x80)
3690 printf(" temporary");
3691 }
3692
3693 if (scopeid)
3694 printf(" scopeid 0x%x", scopeid);
3695
3696 if (Lflag) {
3697 struct in6_addrlifetime *lifetime;
3698
3699 (void) memset(&ifr6, 0, sizeof(ifr6));
3700 (void) strlcpy(ifr6.ifr_name, ifname, sizeof(ifr6.ifr_name));
3701 ifr6.ifr_addrifr_ifru.ifru_addr = creq->ifr_addrifr_ifru.ifru_addr;
3702 lifetime = &ifr6.ifr_ifru.ifru_lifetime;
3703 if (ioctl(sock, SIOCGIFALIFETIME_IN6(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct in6_ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((81)))
, (caddr_t)&ifr6) == -1) {
3704 if (errno(*__errno()) != EADDRNOTAVAIL49)
3705 warn("SIOCGIFALIFETIME_IN6");
3706 } else if (lifetime->ia6t_preferred || lifetime->ia6t_expire) {
3707 time_t t = time(NULL((void*)0));
3708
3709 printf(" pltime ");
3710 if (lifetime->ia6t_preferred) {
3711 printf("%s", lifetime->ia6t_preferred < t
3712 ? "0" :
3713 sec2str(lifetime->ia6t_preferred - t));
3714 } else
3715 printf("infty");
3716
3717 printf(" vltime ");
3718 if (lifetime->ia6t_expire) {
3719 printf("%s", lifetime->ia6t_expire < t
3720 ? "0"
3721 : sec2str(lifetime->ia6t_expire - t));
3722 } else
3723 printf("infty");
3724 }
3725 }
3726
3727 printf("\n");
3728}
3729
3730void
3731in6_status(int force)
3732{
3733 in6_alias((struct in6_ifreq *)&ifr6);
3734}
3735
3736#ifndef SMALL
3737void
3738settunnel(const char *src, const char *dst)
3739{
3740 char buf[HOST_NAME_MAX255+1 + sizeof (":65535")], *dstport;
3741 const char *dstip;
3742 struct addrinfo *srcres, *dstres;
3743 int ecode;
3744 struct if_laddrreq req;
3745
3746 if (strchr(dst, ':') == NULL((void*)0) || strchr(dst, ':') != strrchr(dst, ':')) {
3747 /* no port or IPv6 */
3748 dstip = dst;
3749 dstport = NULL((void*)0);
3750 } else {
3751 if (strlcpy(buf, dst, sizeof(buf)) >= sizeof(buf))
3752 errx(1, "%s bad value", dst);
3753 dstport = strchr(buf, ':');
3754 *dstport++ = '\0';
3755 dstip = buf;
3756 }
3757
3758 if ((ecode = getaddrinfo(src, NULL((void*)0), NULL((void*)0), &srcres)) != 0)
3759 errx(1, "error in parsing address string: %s",
3760 gai_strerror(ecode));
3761
3762 if ((ecode = getaddrinfo(dstip, dstport, NULL((void*)0), &dstres)) != 0)
3763 errx(1, "error in parsing address string: %s",
3764 gai_strerror(ecode));
3765
3766 if (srcres->ai_addr->sa_family != dstres->ai_addr->sa_family)
3767 errx(1,
3768 "source and destination address families do not match");
3769
3770 memset(&req, 0, sizeof(req));
3771 (void) strlcpy(req.iflr_name, ifname, sizeof(req.iflr_name));
3772 memcpy(&req.addr, srcres->ai_addr, srcres->ai_addrlen);
3773 memcpy(&req.dstaddr, dstres->ai_addr, dstres->ai_addrlen);
3774 if (ioctl(sock, SIOCSLIFPHYADDR((unsigned long)0x80000000 | ((sizeof(struct if_laddrreq) &
0x1fff) << 16) | ((('i')) << 8) | ((74)))
, &req) == -1)
3775 warn("SIOCSLIFPHYADDR");
3776
3777 freeaddrinfo(srcres);
3778 freeaddrinfo(dstres);
3779}
3780
3781void
3782settunneladdr(const char *addr, int ignored)
3783{
3784 struct addrinfo hints, *res;
3785 struct if_laddrreq req;
3786 ssize_t len;
3787 int rv;
3788
3789 memset(&hints, 0, sizeof(hints));
3790 hints.ai_family = AF_UNSPEC0;
3791 hints.ai_socktype = SOCK_DGRAM2;
3792 hints.ai_protocol = 0;
3793 hints.ai_flags = AI_PASSIVE1;
3794
3795 rv = getaddrinfo(addr, NULL((void*)0), &hints, &res);
3796 if (rv != 0)
3797 errx(1, "tunneladdr %s: %s", addr, gai_strerror(rv));
3798
3799 memset(&req, 0, sizeof(req));
3800 len = strlcpy(req.iflr_name, ifname, sizeof(req.iflr_name));
3801 if (len >= sizeof(req.iflr_name))
3802 errx(1, "%s: Interface name too long", ifname);
3803
3804 memcpy(&req.addr, res->ai_addr, res->ai_addrlen);
3805
3806 req.dstaddr.ss_len = 2;
3807 req.dstaddr.ss_family = AF_UNSPEC0;
3808
3809 if (ioctl(sock, SIOCSLIFPHYADDR((unsigned long)0x80000000 | ((sizeof(struct if_laddrreq) &
0x1fff) << 16) | ((('i')) << 8) | ((74)))
, &req) == -1)
3810 warn("tunneladdr %s", addr);
3811
3812 freeaddrinfo(res);
3813}
3814
3815/* ARGSUSED */
3816void
3817deletetunnel(const char *ignored, int alsoignored)
3818{
3819 if (ioctl(sock, SIOCDIFPHYADDR((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((73)))
, &ifr) == -1)
3820 warn("SIOCDIFPHYADDR");
3821}
3822
3823void
3824settunnelinst(const char *id, int param)
3825{
3826 const char *errmsg = NULL((void*)0);
3827 int rdomainid;
3828
3829 rdomainid = strtonum(id, 0, RT_TABLEID_MAX255, &errmsg);
3830 if (errmsg)
3831 errx(1, "rdomain %s: %s", id, errmsg);
3832
3833 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
3834 ifr.ifr_rdomainidifr_ifru.ifru_metric = rdomainid;
3835 if (ioctl(sock, SIOCSLIFPHYRTABLE((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((161)))
, (caddr_t)&ifr) == -1)
3836 warn("SIOCSLIFPHYRTABLE");
3837}
3838
3839void
3840unsettunnelinst(const char *ignored, int alsoignored)
3841{
3842 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
3843 ifr.ifr_rdomainidifr_ifru.ifru_metric = 0;
3844 if (ioctl(sock, SIOCSLIFPHYRTABLE((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((161)))
, (caddr_t)&ifr) == -1)
3845 warn("SIOCSLIFPHYRTABLE");
3846}
3847
3848void
3849settunnelttl(const char *id, int param)
3850{
3851 const char *errmsg = NULL((void*)0);
3852 int ttl;
3853
3854 if (strcmp(id, "copy") == 0)
3855 ttl = -1;
3856 else {
3857 ttl = strtonum(id, 0, 0xff, &errmsg);
3858 if (errmsg)
3859 errx(1, "tunnelttl %s: %s", id, errmsg);
3860 }
3861
3862 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
3863 ifr.ifr_ttlifr_ifru.ifru_metric = ttl;
3864 if (ioctl(sock, SIOCSLIFPHYTTL((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((168)))
, (caddr_t)&ifr) == -1)
3865 warn("SIOCSLIFPHYTTL");
3866}
3867
3868void
3869settunneldf(const char *ignored, int alsoignored)
3870{
3871 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
3872 ifr.ifr_dfifr_ifru.ifru_metric = 1;
3873 if (ioctl(sock, SIOCSLIFPHYDF((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((193)))
, (caddr_t)&ifr) == -1)
3874 warn("SIOCSLIFPHYDF");
3875}
3876
3877void
3878settunnelnodf(const char *ignored, int alsoignored)
3879{
3880 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
3881 ifr.ifr_dfifr_ifru.ifru_metric = 0;
3882 if (ioctl(sock, SIOCSLIFPHYDF((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((193)))
, (caddr_t)&ifr) == -1)
3883 warn("SIOCSLIFPHYDF");
3884}
3885
3886void
3887settunnelecn(const char *ignored, int alsoignored)
3888{
3889 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
3890 ifr.ifr_metricifr_ifru.ifru_metric = 1;
3891 if (ioctl(sock, SIOCSLIFPHYECN((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((199)))
, (caddr_t)&ifr) == -1)
3892 warn("SIOCSLIFPHYECN");
3893}
3894
3895void
3896settunnelnoecn(const char *ignored, int alsoignored)
3897{
3898 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
3899 ifr.ifr_metricifr_ifru.ifru_metric = 0;
3900 if (ioctl(sock, SIOCSLIFPHYECN((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((199)))
, (caddr_t)&ifr) == -1)
3901 warn("SIOCSLIFPHYECN");
3902}
3903
3904void
3905setvnetflowid(const char *ignored, int alsoignored)
3906{
3907 if (strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)) >=
3908 sizeof(ifr.ifr_name))
3909 errx(1, "vnetflowid: name is too long");
3910
3911 ifr.ifr_vnetidifr_ifru.ifru_vnetid = 1;
3912 if (ioctl(sock, SIOCSVNETFLOWID((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((195)))
, &ifr) == -1)
3913 warn("SIOCSVNETFLOWID");
3914}
3915
3916void
3917delvnetflowid(const char *ignored, int alsoignored)
3918{
3919 if (strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)) >=
3920 sizeof(ifr.ifr_name))
3921 errx(1, "vnetflowid: name is too long");
3922
3923 ifr.ifr_vnetidifr_ifru.ifru_vnetid = 0;
3924 if (ioctl(sock, SIOCSVNETFLOWID((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((195)))
, &ifr) == -1)
3925 warn("SIOCSVNETFLOWID");
3926}
3927
3928static void
3929pwe3_neighbor(void)
3930{
3931 const char *prefix = "pwe3 remote label";
3932 struct if_laddrreq req;
3933 char hbuf[NI_MAXHOST256];
3934 struct sockaddr_mpls *smpls;
3935 int error;
3936
3937 memset(&req, 0, sizeof(req));
3938 if (strlcpy(req.iflr_name, ifname, sizeof(req.iflr_name)) >=
3939 sizeof(req.iflr_name))
3940 errx(1, "pwe3 neighbor: name is too long");
3941
3942 if (ioctl(sock, SIOCGPWE3NEIGHBOR(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct if_laddrreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((222)))
, &req) == -1) {
3943 if (errno(*__errno()) != EADDRNOTAVAIL49)
3944 return;
3945
3946 printf(" %s (unset)", prefix);
3947 return;
3948 }
3949
3950 if (req.dstaddr.ss_family != AF_MPLS33) {
3951 warnc(EPFNOSUPPORT46, "pwe3 neighbor");
3952 return;
3953 }
3954 smpls = (struct sockaddr_mpls *)&req.dstaddr;
3955
3956 error = getnameinfo((struct sockaddr *)&req.addr, sizeof(req.addr),
3957 hbuf, sizeof(hbuf), NULL((void*)0), 0, NI_NUMERICHOST1);
3958 if (error != 0) {
3959 warnx("%s: %s", prefix, gai_strerror(error));
3960 return;
3961 }
3962
3963 printf(" %s %u on %s", prefix, smpls->smpls_label, hbuf);
3964}
3965
3966static void
3967pwe3_cword(void)
3968{
3969 struct ifreq req;
3970
3971 memset(&req, 0, sizeof(req));
3972 if (strlcpy(req.ifr_name, ifname, sizeof(req.ifr_name)) >=
3973 sizeof(req.ifr_name))
3974 errx(1, "pwe3 control word: name is too long");
3975
3976 if (ioctl(sock, SIOCGPWE3CTRLWORD(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((220)))
, &req) == -1) {
3977 return;
3978 }
3979
3980 printf(" %s", req.ifr_pwe3ifr_ifru.ifru_metric ? "cw" : "nocw");
3981}
3982
3983static void
3984pwe3_fword(void)
3985{
3986 struct ifreq req;
3987
3988 memset(&req, 0, sizeof(req));
3989 if (strlcpy(req.ifr_name, ifname, sizeof(req.ifr_name)) >=
3990 sizeof(req.ifr_name))
3991 errx(1, "pwe3 control word: name is too long");
3992
3993 if (ioctl(sock, SIOCGPWE3FAT(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((221)))
, &req) == -1)
3994 return;
3995
3996 printf(" %s", req.ifr_pwe3ifr_ifru.ifru_metric ? "fat" : "nofat");
3997}
3998
3999void
4000mpls_status(void)
4001{
4002 struct shim_hdr shim;
4003
4004 bzero(&shim, sizeof(shim));
4005 ifr.ifr_dataifr_ifru.ifru_data = (caddr_t)&shim;
4006
4007 if (ioctl(sock, SIOCGETLABEL((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((154)))
, (caddr_t)&ifr) == -1) {
4008 if (errno(*__errno()) != EADDRNOTAVAIL49)
4009 return;
4010
4011 printf("\tmpls: label (unset)");
4012 } else
4013 printf("\tmpls: label %u", shim.shim_label);
4014
4015 pwe3_neighbor();
4016 pwe3_cword();
4017 pwe3_fword();
4018
4019 printf("\n");
4020}
4021
4022/* ARGSUSED */
4023void
4024setmplslabel(const char *val, int d)
4025{
4026 struct shim_hdr shim;
4027 const char *estr;
4028
4029 bzero(&shim, sizeof(shim));
4030 ifr.ifr_dataifr_ifru.ifru_data = (caddr_t)&shim;
4031 shim.shim_label = strtonum(val, 0, MPLS_LABEL_MAX((1 << 20) - 1), &estr);
4032
4033 if (estr)
4034 errx(1, "mpls label %s is %s", val, estr);
4035 if (ioctl(sock, SIOCSETLABEL((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((153)))
, (caddr_t)&ifr) == -1)
4036 warn("SIOCSETLABEL");
4037}
4038
4039void
4040unsetmplslabel(const char *val, int d)
4041{
4042 struct ifreq req;
4043
4044 memset(&req, 0, sizeof(req));
4045 if (strlcpy(req.ifr_name, ifname, sizeof(req.ifr_name)) >=
4046 sizeof(req.ifr_name))
4047 errx(1, "interface name is too long");
4048
4049 if (ioctl(sock, SIOCDELLABEL((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((151)))
, (caddr_t)&ifr) == -1)
4050 warn("-mplslabel");
4051}
4052
4053static void
4054setpwe3(unsigned long cmd, const char *cmdname, int value)
4055{
4056 struct ifreq req;
4057
4058 memset(&req, 0, sizeof(req));
4059 if (strlcpy(req.ifr_name, ifname, sizeof(req.ifr_name)) >=
4060 sizeof(req.ifr_name))
4061 errx(1, "interface name is too long");
4062
4063 req.ifr_pwe3ifr_ifru.ifru_metric = value;
4064
4065 if (ioctl(sock, cmd, &req) == -1)
4066 warn("%s", cmdname);
4067}
4068
4069void
4070setpwe3cw(const char *val, int d)
4071{
4072 setpwe3(SIOCSPWE3CTRLWORD((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((220)))
, "pwecw", 1);
4073}
4074
4075void
4076unsetpwe3cw(const char *val, int d)
4077{
4078 setpwe3(SIOCSPWE3CTRLWORD((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((220)))
, "-pwecw", 0);
4079}
4080
4081void
4082setpwe3fat(const char *val, int d)
4083{
4084 setpwe3(SIOCSPWE3FAT((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((221)))
, "pwefat", 1);
4085}
4086
4087void
4088unsetpwe3fat(const char *val, int d)
4089{
4090 setpwe3(SIOCSPWE3FAT((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((221)))
, "-pwefat", 0);
4091}
4092
4093void
4094setpwe3neighbor(const char *label, const char *neighbor)
4095{
4096 struct if_laddrreq req;
4097 struct addrinfo hints, *res;
4098 struct sockaddr_mpls *smpls = (struct sockaddr_mpls *)&req.dstaddr;
4099 const char *errstr;
4100 int error;
4101
4102 memset(&req, 0, sizeof(req));
4103 if (strlcpy(req.iflr_name, ifname, sizeof(req.iflr_name)) >=
4104 sizeof(req.iflr_name))
4105 errx(1, "interface name is too long");
4106
4107 memset(&hints, 0, sizeof(hints));
4108 hints.ai_family = AF_UNSPEC0;
4109 hints.ai_socktype = SOCK_DGRAM2;
4110 error = getaddrinfo(neighbor, NULL((void*)0), &hints, &res);
4111 if (error != 0)
4112 errx(1, "pweneighbor %s: %s", neighbor, gai_strerror(error));
4113
4114 smpls->smpls_len = sizeof(*smpls);
4115 smpls->smpls_family = AF_MPLS33;
4116 smpls->smpls_label = strtonum(label,
4117 (MPLS_LABEL_RESERVED_MAX15 + 1), MPLS_LABEL_MAX((1 << 20) - 1), &errstr);
4118 if (errstr != NULL((void*)0))
4119 errx(1, "pweneighbor: invalid label: %s", errstr);
4120
4121
4122 if (res->ai_addrlen > sizeof(req.addr))
4123 errx(1, "pweneighbors: unexpected socklen");
4124
4125 memcpy(&req.addr, res->ai_addr, res->ai_addrlen);
4126
4127 freeaddrinfo(res);
4128
4129 if (ioctl(sock, SIOCSPWE3NEIGHBOR((unsigned long)0x80000000 | ((sizeof(struct if_laddrreq) &
0x1fff) << 16) | ((('i')) << 8) | ((222)))
, &req) == -1)
4130 warn("pweneighbor");
4131}
4132
4133void
4134unsetpwe3neighbor(const char *val, int d)
4135{
4136 struct ifreq req;
4137
4138 memset(&req, 0, sizeof(req));
4139 if (strlcpy(req.ifr_name, ifname, sizeof(req.ifr_name)) >=
4140 sizeof(req.ifr_name))
4141 errx(1, "interface name is too long");
4142
4143 if (ioctl(sock, SIOCDPWE3NEIGHBOR((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((222)))
, &req) == -1)
4144 warn("-pweneighbor");
4145}
4146
4147void
4148transceiver(const char *value, int d)
4149{
4150 showtransceiver = 1;
4151}
4152
4153void
4154transceiverdump(const char *value, int d)
4155{
4156 if (if_sff_info(1) == -1)
4157 err(1, "%s transceiver", ifname);
4158}
4159#endif /* SMALL */
4160
4161void
4162getvnetflowid(struct ifencap *ife)
4163{
4164 if (strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)) >=
4165 sizeof(ifr.ifr_name))
4166 errx(1, "vnetflowid: name is too long");
4167
4168 if (ioctl(sock, SIOCGVNETFLOWID(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((196)))
, &ifr) == -1)
4169 return;
4170
4171 if (ifr.ifr_vnetidifr_ifru.ifru_vnetid)
4172 ife->ife_flags |= IFE_VNETFLOWID0x10;
4173}
4174
4175void
4176setvnetid(const char *id, int param)
4177{
4178 const char *errmsg = NULL((void*)0);
4179 int64_t vnetid;
4180
4181 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
4182
4183 if (strcasecmp("any", id) == 0)
4184 vnetid = -1;
4185 else {
4186 vnetid = strtonum(id, 0, INT64_MAX0x7fffffffffffffffLL, &errmsg);
4187 if (errmsg)
4188 errx(1, "vnetid %s: %s", id, errmsg);
4189 }
4190
4191 ifr.ifr_vnetidifr_ifru.ifru_vnetid = vnetid;
4192 if (ioctl(sock, SIOCSVNETID((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((166)))
, (caddr_t)&ifr) == -1)
4193 warn("SIOCSVNETID");
4194}
4195
4196/* ARGSUSED */
4197void
4198delvnetid(const char *ignored, int alsoignored)
4199{
4200 if (ioctl(sock, SIOCDVNETID((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((175)))
, &ifr) == -1)
4201 warn("SIOCDVNETID");
4202}
4203
4204void
4205getvnetid(struct ifencap *ife)
4206{
4207 if (strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)) >=
4208 sizeof(ifr.ifr_name))
4209 errx(1, "vnetid: name is too long");
4210
4211 if (ioctl(sock, SIOCGVNETID(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((167)))
, &ifr) == -1) {
4212 if (errno(*__errno()) != EADDRNOTAVAIL49)
4213 return;
4214
4215 ife->ife_flags |= IFE_VNETID_NONE0x1;
4216 return;
4217 }
4218
4219 if (ifr.ifr_vnetidifr_ifru.ifru_vnetid < 0) {
4220 ife->ife_flags |= IFE_VNETID_ANY0x2;
4221 return;
4222 }
4223
4224 ife->ife_flags |= IFE_VNETID_SET0x3;
4225 ife->ife_vnetid = ifr.ifr_vnetidifr_ifru.ifru_vnetid;
4226}
4227
4228void
4229setifparent(const char *id, int param)
4230{
4231 struct if_parent ifp;
4232
4233 if (strlcpy(ifp.ifp_name, ifname, sizeof(ifp.ifp_name)) >=
4234 sizeof(ifp.ifp_name))
4235 errx(1, "parent: name too long");
4236
4237 if (strlcpy(ifp.ifp_parent, id, sizeof(ifp.ifp_parent)) >=
4238 sizeof(ifp.ifp_parent))
4239 errx(1, "parent: parent too long");
4240
4241 if (ioctl(sock, SIOCSIFPARENT((unsigned long)0x80000000 | ((sizeof(struct if_parent) &
0x1fff) << 16) | ((('i')) << 8) | ((178)))
, (caddr_t)&ifp) == -1)
4242 warn("SIOCSIFPARENT");
4243}
4244
4245/* ARGSUSED */
4246void
4247delifparent(const char *ignored, int alsoignored)
4248{
4249 if (ioctl(sock, SIOCDIFPARENT((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((180)))
, &ifr) == -1)
4250 warn("SIOCDIFPARENT");
4251}
4252
4253void
4254getifparent(struct ifencap *ife)
4255{
4256 struct if_parent ifp;
4257
4258 memset(&ifp, 0, sizeof(ifp));
4259 if (strlcpy(ifp.ifp_name, ifname, sizeof(ifp.ifp_name)) >=
4260 sizeof(ifp.ifp_name))
4261 errx(1, "parent: name too long");
4262
4263 if (ioctl(sock, SIOCGIFPARENT(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct if_parent) & 0x1fff) << 16) | ((('i')) <<
8) | ((179)))
, (caddr_t)&ifp) == -1) {
4264 if (errno(*__errno()) != EADDRNOTAVAIL49)
4265 return;
4266
4267 ife->ife_flags |= IFE_PARENT_NONE0x100;
4268 } else {
4269 memcpy(ife->ife_parent, ifp.ifp_parent,
4270 sizeof(ife->ife_parent));
4271 ife->ife_flags |= IFE_PARENT_SET0x200;
4272 }
4273}
4274
4275#ifndef SMALL
4276void
4277gettxprio(struct ifencap *ife)
4278{
4279 if (strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)) >=
4280 sizeof(ifr.ifr_name))
4281 errx(1, "hdr prio: name is too long");
4282
4283 if (ioctl(sock, SIOCGTXHPRIO(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((198)))
, (caddr_t)&ifr) == -1)
4284 return;
4285
4286 ife->ife_flags |= IFE_TXHPRIO_SET0x1000;
4287 ife->ife_txhprio = ifr.ifr_hdrprioifr_ifru.ifru_metric;
4288}
4289
4290void
4291settxprio(const char *val, int d)
4292{
4293 const char *errmsg = NULL((void*)0);
4294
4295 if (strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)) >=
4296 sizeof(ifr.ifr_name))
4297 errx(1, "tx prio: name is too long");
4298
4299 if (strcmp(val, "packet") == 0)
4300 ifr.ifr_hdrprioifr_ifru.ifru_metric = IF_HDRPRIO_PACKET-1;
4301 else if (strcmp(val, "payload") == 0)
4302 ifr.ifr_hdrprioifr_ifru.ifru_metric = IF_HDRPRIO_PAYLOAD-2;
4303 else {
4304 ifr.ifr_hdrprioifr_ifru.ifru_metric = strtonum(val,
4305 IF_HDRPRIO_MIN0, IF_HDRPRIO_MAX8 - 1, &errmsg);
4306 if (errmsg)
4307 errx(1, "tx prio %s: %s", val, errmsg);
4308 }
4309
4310 if (ioctl(sock, SIOCSTXHPRIO((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((197)))
, (caddr_t)&ifr) == -1)
4311 warn("SIOCSTXHPRIO");
4312}
4313
4314void
4315getrxprio(struct ifencap *ife)
4316{
4317 if (strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)) >=
4318 sizeof(ifr.ifr_name))
4319 errx(1, "hdr prio: name is too long");
4320
4321 if (ioctl(sock, SIOCGRXHPRIO(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((219)))
, (caddr_t)&ifr) == -1)
4322 return;
4323
4324 ife->ife_flags |= IFE_RXHPRIO_SET0x2000;
4325 ife->ife_rxhprio = ifr.ifr_hdrprioifr_ifru.ifru_metric;
4326}
4327
4328void
4329setrxprio(const char *val, int d)
4330{
4331 const char *errmsg = NULL((void*)0);
4332
4333 if (strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)) >=
4334 sizeof(ifr.ifr_name))
4335 errx(1, "rx prio: name is too long");
4336
4337 if (strcmp(val, "packet") == 0)
4338 ifr.ifr_hdrprioifr_ifru.ifru_metric = IF_HDRPRIO_PACKET-1;
4339 else if (strcmp(val, "payload") == 0)
4340 ifr.ifr_hdrprioifr_ifru.ifru_metric = IF_HDRPRIO_PAYLOAD-2;
4341 else if (strcmp(val, "outer") == 0)
4342 ifr.ifr_hdrprioifr_ifru.ifru_metric = IF_HDRPRIO_OUTER-3;
4343 else {
4344 ifr.ifr_hdrprioifr_ifru.ifru_metric = strtonum(val,
4345 IF_HDRPRIO_MIN0, IF_HDRPRIO_MAX8 - 1, &errmsg);
4346 if (errmsg)
4347 errx(1, "rx prio %s: %s", val, errmsg);
4348 }
4349
4350 if (ioctl(sock, SIOCSRXHPRIO((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((219)))
, (caddr_t)&ifr) == -1)
4351 warn("SIOCSRXHPRIO");
4352}
4353#endif
4354
4355void
4356getencap(void)
4357{
4358 struct ifencap ife = { .ife_flags = 0 };
4359
4360 getvnetid(&ife);
4361 getvnetflowid(&ife);
4362 getifparent(&ife);
4363#ifndef SMALL
4364 gettxprio(&ife);
4365 getrxprio(&ife);
4366#endif
4367
4368 if (ife.ife_flags == 0)
4369 return;
4370
4371 printf("\tencap:");
4372
4373 switch (ife.ife_flags & IFE_VNETID_MASK0xf) {
4374 case IFE_VNETID_NONE0x1:
4375 printf(" vnetid none");
4376 break;
4377 case IFE_VNETID_ANY0x2:
4378 printf(" vnetid any");
4379 break;
4380 case IFE_VNETID_SET0x3:
4381 printf(" vnetid %lld", ife.ife_vnetid);
4382 if (ife.ife_flags & IFE_VNETFLOWID0x10)
4383 printf("+");
4384 break;
4385 }
4386
4387 switch (ife.ife_flags & IFE_PARENT_MASK0xf00) {
4388 case IFE_PARENT_NONE0x100:
4389 printf(" parent none");
4390 break;
4391 case IFE_PARENT_SET0x200:
4392 printf(" parent %s", ife.ife_parent);
4393 break;
4394 }
4395
4396#ifndef SMALL
4397 if (ife.ife_flags & IFE_TXHPRIO_SET0x1000) {
4398 printf(" txprio ");
4399 switch (ife.ife_txhprio) {
4400 case IF_HDRPRIO_PACKET-1:
4401 printf("packet");
4402 break;
4403 case IF_HDRPRIO_PAYLOAD-2:
4404 printf("payload");
4405 break;
4406 default:
4407 printf("%d", ife.ife_txhprio);
4408 break;
4409 }
4410 }
4411
4412 if (ife.ife_flags & IFE_RXHPRIO_SET0x2000) {
4413 printf(" rxprio ");
4414 switch (ife.ife_rxhprio) {
4415 case IF_HDRPRIO_PACKET-1:
4416 printf("packet");
4417 break;
4418 case IF_HDRPRIO_PAYLOAD-2:
4419 printf("payload");
4420 break;
4421 case IF_HDRPRIO_OUTER-3:
4422 printf("outer");
4423 break;
4424 default:
4425 printf("%d", ife.ife_rxhprio);
4426 break;
4427 }
4428 }
4429#endif
4430
4431 printf("\n");
4432}
4433
4434void
4435settrunkport(const char *val, int d)
4436{
4437 struct trunk_reqport rp;
4438
4439 bzero(&rp, sizeof(rp));
4440 strlcpy(rp.rp_ifname, ifname, sizeof(rp.rp_ifname));
4441 strlcpy(rp.rp_portname, val, sizeof(rp.rp_portname));
4442
4443 if (ioctl(sock, SIOCSTRUNKPORT((unsigned long)0x80000000 | ((sizeof(struct trunk_reqport) &
0x1fff) << 16) | ((('i')) << 8) | ((141)))
, &rp) == -1)
4444 err(1, "SIOCSTRUNKPORT");
4445}
4446
4447void
4448unsettrunkport(const char *val, int d)
4449{
4450 struct trunk_reqport rp;
4451
4452 bzero(&rp, sizeof(rp));
4453 strlcpy(rp.rp_ifname, ifname, sizeof(rp.rp_ifname));
4454 strlcpy(rp.rp_portname, val, sizeof(rp.rp_portname));
4455
4456 if (ioctl(sock, SIOCSTRUNKDELPORT((unsigned long)0x80000000 | ((sizeof(struct trunk_reqport) &
0x1fff) << 16) | ((('i')) << 8) | ((142)))
, &rp) == -1)
4457 err(1, "SIOCSTRUNKDELPORT");
4458}
4459
4460void
4461settrunkproto(const char *val, int d)
4462{
4463 struct trunk_protos tpr[] = TRUNK_PROTOS{ { "roundrobin", TRUNK_PROTO_ROUNDROBIN }, { "failover", TRUNK_PROTO_FAILOVER
}, { "lacp", TRUNK_PROTO_LACP }, { "loadbalance", TRUNK_PROTO_LOADBALANCE
}, { "broadcast", TRUNK_PROTO_BROADCAST }, { "none", TRUNK_PROTO_NONE
}, { "default", TRUNK_PROTO_ROUNDROBIN } }
;
4464 struct trunk_reqall ra;
4465 int i;
4466
4467 bzero(&ra, sizeof(ra));
4468 ra.ra_proto = TRUNK_PROTO_MAX;
4469
4470 for (i = 0; i < (sizeof(tpr) / sizeof(tpr[0])); i++) {
4471 if (strcmp(val, tpr[i].tpr_name) == 0) {
4472 ra.ra_proto = tpr[i].tpr_proto;
4473 break;
4474 }
4475 }
4476 if (ra.ra_proto == TRUNK_PROTO_MAX)
4477 errx(1, "Invalid trunk protocol: %s", val);
4478
4479 strlcpy(ra.ra_ifname, ifname, sizeof(ra.ra_ifname));
4480 if (ioctl(sock, SIOCSTRUNK((unsigned long)0x80000000 | ((sizeof(struct trunk_reqall) &
0x1fff) << 16) | ((('i')) << 8) | ((144)))
, &ra) != 0)
4481 err(1, "SIOCSTRUNK");
4482}
4483
4484void
4485settrunklacpmode(const char *val, int d)
4486{
4487 struct trunk_reqall ra;
4488 struct trunk_opts tops;
4489
4490 bzero(&ra, sizeof(ra));
4491 strlcpy(ra.ra_ifname, ifname, sizeof(ra.ra_ifname));
4492
4493 if (ioctl(sock, SIOCGTRUNK(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct trunk_reqall) & 0x1fff) << 16) | ((('i')) <<
8) | ((143)))
, &ra) != 0)
4494 err(1, "SIOCGTRUNK");
4495
4496 if (ra.ra_proto != TRUNK_PROTO_LACP)
4497 errx(1, "Invalid option for trunk: %s", ifname);
4498
4499 if (strcmp(val, lacpmodeactive) != 0 &&
4500 strcmp(val, lacpmodepassive) != 0)
4501 errx(1, "Invalid lacpmode option for trunk: %s", ifname);
4502
4503 bzero(&tops, sizeof(tops));
4504 strlcpy(tops.to_ifname, ifname, sizeof(tops.to_ifname));
4505 tops.to_proto = TRUNK_PROTO_LACP;
4506 tops.to_opts |= TRUNK_OPT_LACP_MODE0x01;
4507
4508 if (strcmp(val, lacpmodeactive) == 0)
4509 tops.to_lacpoptsto_psc.rpsc_lacp.lacp_mode = 1;
4510 else
4511 tops.to_lacpoptsto_psc.rpsc_lacp.lacp_mode = 0;
4512
4513 if (ioctl(sock, SIOCSTRUNKOPTS((unsigned long)0x80000000 | ((sizeof(struct trunk_opts) &
0x1fff) << 16) | ((('i')) << 8) | ((146)))
, &tops) != 0)
4514 err(1, "SIOCSTRUNKOPTS");
4515}
4516
4517void
4518settrunklacptimeout(const char *val, int d)
4519{
4520 struct trunk_reqall ra;
4521 struct trunk_opts tops;
4522
4523 bzero(&ra, sizeof(ra));
4524 strlcpy(ra.ra_ifname, ifname, sizeof(ra.ra_ifname));
4525
4526 if (ioctl(sock, SIOCGTRUNK(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct trunk_reqall) & 0x1fff) << 16) | ((('i')) <<
8) | ((143)))
, &ra) != 0)
4527 err(1, "SIOCGTRUNK");
4528
4529 if (ra.ra_proto != TRUNK_PROTO_LACP)
4530 errx(1, "Invalid option for trunk: %s", ifname);
4531
4532 if (strcmp(val, lacptimeoutfast) != 0 &&
4533 strcmp(val, lacptimeoutslow) != 0)
4534 errx(1, "Invalid lacptimeout option for trunk: %s", ifname);
4535
4536 bzero(&tops, sizeof(tops));
4537 strlcpy(tops.to_ifname, ifname, sizeof(tops.to_ifname));
4538 tops.to_proto = TRUNK_PROTO_LACP;
4539 tops.to_opts |= TRUNK_OPT_LACP_TIMEOUT0x02;
4540
4541 if (strcmp(val, lacptimeoutfast) == 0)
4542 tops.to_lacpoptsto_psc.rpsc_lacp.lacp_timeout = 1;
4543 else
4544 tops.to_lacpoptsto_psc.rpsc_lacp.lacp_timeout = 0;
4545
4546 if (ioctl(sock, SIOCSTRUNKOPTS((unsigned long)0x80000000 | ((sizeof(struct trunk_opts) &
0x1fff) << 16) | ((('i')) << 8) | ((146)))
, &tops) != 0)
4547 err(1, "SIOCSTRUNKOPTS");
4548}
4549
4550void
4551trunk_status(void)
4552{
4553 struct trunk_protos tpr[] = TRUNK_PROTOS{ { "roundrobin", TRUNK_PROTO_ROUNDROBIN }, { "failover", TRUNK_PROTO_FAILOVER
}, { "lacp", TRUNK_PROTO_LACP }, { "loadbalance", TRUNK_PROTO_LOADBALANCE
}, { "broadcast", TRUNK_PROTO_BROADCAST }, { "none", TRUNK_PROTO_NONE
}, { "default", TRUNK_PROTO_ROUNDROBIN } }
;
4554 struct trunk_reqport rp, rpbuf[TRUNK_MAX_PORTS32];
4555 struct trunk_reqall ra;
4556 struct lacp_opreq *lp;
4557 const char *proto = "<unknown>";
4558 int i, isport = 0;
4559
4560 bzero(&rp, sizeof(rp));
4561 bzero(&ra, sizeof(ra));
4562
4563 strlcpy(rp.rp_ifname, ifname, sizeof(rp.rp_ifname));
4564 strlcpy(rp.rp_portname, ifname, sizeof(rp.rp_portname));
4565
4566 if (ioctl(sock, SIOCGTRUNKPORT(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct trunk_reqport) & 0x1fff) << 16) | ((('i')) <<
8) | ((140)))
, &rp) == 0)
4567 isport = 1;
4568
4569 strlcpy(ra.ra_ifname, ifname, sizeof(ra.ra_ifname));
4570 ra.ra_size = sizeof(rpbuf);
4571 ra.ra_port = rpbuf;
4572
4573 if (ioctl(sock, SIOCGTRUNK(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct trunk_reqall) & 0x1fff) << 16) | ((('i')) <<
8) | ((143)))
, &ra) == 0) {
4574 lp = (struct lacp_opreq *)&ra.ra_lacpreqra_psc.rpsc_lacp;
4575
4576 for (i = 0; i < (sizeof(tpr) / sizeof(tpr[0])); i++) {
4577 if (ra.ra_proto == tpr[i].tpr_proto) {
4578 proto = tpr[i].tpr_name;
4579 break;
4580 }
4581 }
4582
4583 printf("\ttrunk: trunkproto %s", proto);
4584 if (isport)
4585 printf(" trunkdev %s", rp.rp_ifname);
4586 putchar('\n')(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n',
(&__sF[1])))
;
4587 if (ra.ra_proto == TRUNK_PROTO_LACP) {
4588 char *act_mac = strdup(
4589 ether_ntoa((struct ether_addr*)lp->actor_mac));
4590 if (act_mac == NULL((void*)0))
4591 err(1, "strdup");
4592 printf("\ttrunk id: [(%04X,%s,%04X,%04X,%04X),\n"
4593 "\t\t (%04X,%s,%04X,%04X,%04X)]\n",
4594 lp->actor_prio, act_mac,
4595 lp->actor_key, lp->actor_portprio, lp->actor_portno,
4596 lp->partner_prio,
4597 ether_ntoa((struct ether_addr*)lp->partner_mac),
4598 lp->partner_key, lp->partner_portprio,
4599 lp->partner_portno);
4600 free(act_mac);
4601 }
4602
4603 for (i = 0; i < ra.ra_ports; i++) {
4604 lp = (struct lacp_opreq *)&(rpbuf[i].rp_lacpreqrp_psc.rpsc_lacp);
4605 if (ra.ra_proto == TRUNK_PROTO_LACP) {
4606 printf("\t\t%s lacp actor "
4607 "system pri 0x%x mac %s, key 0x%x, "
4608 "port pri 0x%x number 0x%x\n",
4609 rpbuf[i].rp_portname,
4610 lp->actor_prio,
4611 ether_ntoa((struct ether_addr*)
4612 lp->actor_mac),
4613 lp->actor_key,
4614 lp->actor_portprio, lp->actor_portno);
4615 printf("\t\t%s lacp actor state ",
4616 rpbuf[i].rp_portname);
4617 printb_status(lp->actor_state,
4618 LACP_STATE_BITS"\020" "\001ACTIVITY" "\002TIMEOUT" "\003AGGREGATION" "\004SYNC"
"\005COLLECTING" "\006DISTRIBUTING" "\007DEFAULTED" "\010EXPIRED"
);
4619 putchar('\n')(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n',
(&__sF[1])))
;
4620
4621 printf("\t\t%s lacp partner "
4622 "system pri 0x%x mac %s, key 0x%x, "
4623 "port pri 0x%x number 0x%x\n",
4624 rpbuf[i].rp_portname,
4625 lp->partner_prio,
4626 ether_ntoa((struct ether_addr*)
4627 lp->partner_mac),
4628 lp->partner_key,
4629 lp->partner_portprio, lp->partner_portno);
4630 printf("\t\t%s lacp partner state ",
4631 rpbuf[i].rp_portname);
4632 printb_status(lp->partner_state,
4633 LACP_STATE_BITS"\020" "\001ACTIVITY" "\002TIMEOUT" "\003AGGREGATION" "\004SYNC"
"\005COLLECTING" "\006DISTRIBUTING" "\007DEFAULTED" "\010EXPIRED"
);
4634 putchar('\n')(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n',
(&__sF[1])))
;
4635 }
4636
4637 printf("\t\t%s port ", rpbuf[i].rp_portname);
4638 printb_status(rpbuf[i].rp_flags, TRUNK_PORT_BITS"\20\01MASTER\02STACK\03ACTIVE" "\04COLLECTING\05DISTRIBUTING\06DISABLED");
4639 putchar('\n')(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n',
(&__sF[1])))
;
4640 }
4641
4642 if (showmediaflag) {
4643 printf("\tsupported trunk protocols:\n");
4644 for (i = 0; i < (sizeof(tpr) / sizeof(tpr[0])); i++)
4645 printf("\t\ttrunkproto %s\n", tpr[i].tpr_name);
4646 }
4647 } else if (isport)
4648 printf("\ttrunk: trunkdev %s\n", rp.rp_ifname);
4649}
4650
4651#ifndef SMALL
4652static const char *carp_states[] = { CARP_STATES"INIT", "BACKUP", "MASTER" };
4653static const char *carp_bal_modes[] = { CARP_BAL_MODES"none", "ip", "ip-stealth", "ip-unicast" };
4654
4655void
4656carp_status(void)
4657{
4658 const char *state, *balmode;
4659 struct carpreq carpr;
4660 char peer[32];
4661 int i;
4662
4663 memset((char *)&carpr, 0, sizeof(struct carpreq));
4664 ifr.ifr_dataifr_ifru.ifru_data = (caddr_t)&carpr;
4665
4666 if (ioctl(sock, SIOCGVH(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((246)))
, (caddr_t)&ifr) == -1)
4667 return;
4668
4669 if (carpr.carpr_vhids[0] == 0)
4670 return;
4671
4672 if (carpr.carpr_balancing > CARP_BAL_MAXID3)
4673 balmode = "<UNKNOWN>";
4674 else
4675 balmode = carp_bal_modes[carpr.carpr_balancing];
4676
4677 if (carpr.carpr_peer.s_addr != htonl(INADDR_CARP_GROUP)(__uint32_t)(__builtin_constant_p(((u_int32_t)(0xe0000012))) ?
(__uint32_t)(((__uint32_t)(((u_int32_t)(0xe0000012))) & 0xff
) << 24 | ((__uint32_t)(((u_int32_t)(0xe0000012))) &
0xff00) << 8 | ((__uint32_t)(((u_int32_t)(0xe0000012))
) & 0xff0000) >> 8 | ((__uint32_t)(((u_int32_t)(0xe0000012
))) & 0xff000000) >> 24) : __swap32md(((u_int32_t)(
0xe0000012))))
)
4678 snprintf(peer, sizeof(peer),
4679 " carppeer %s", inet_ntoa(carpr.carpr_peer));
4680 else
4681 peer[0] = '\0';
4682
4683 for (i = 0; carpr.carpr_vhids[i]; i++) {
4684 if (carpr.carpr_states[i] > CARP_MAXSTATE2)
4685 state = "<UNKNOWN>";
4686 else
4687 state = carp_states[carpr.carpr_states[i]];
4688 if (carpr.carpr_vhids[1] == 0) {
4689 printf("\tcarp: %s carpdev %s vhid %u advbase %d "
4690 "advskew %u%s\n", state,
4691 carpr.carpr_carpdev[0] != '\0' ?
4692 carpr.carpr_carpdev : "none", carpr.carpr_vhids[0],
4693 carpr.carpr_advbase, carpr.carpr_advskews[0],
4694 peer);
4695 } else {
4696 if (i == 0) {
4697 printf("\tcarp: carpdev %s advbase %d"
4698 " balancing %s%s\n",
4699 carpr.carpr_carpdev[0] != '\0' ?
4700 carpr.carpr_carpdev : "none",
4701 carpr.carpr_advbase, balmode, peer);
4702 }
4703 printf("\t\tstate %s vhid %u advskew %u\n", state,
4704 carpr.carpr_vhids[i], carpr.carpr_advskews[i]);
4705 }
4706 }
4707}
4708
4709/* ARGSUSED */
4710void
4711setcarp_passwd(const char *val, int d)
4712{
4713 struct carpreq carpr;
4714
4715 bzero(&carpr, sizeof(struct carpreq));
4716 ifr.ifr_dataifr_ifru.ifru_data = (caddr_t)&carpr;
4717
4718 if (ioctl(sock, SIOCGVH(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((246)))
, (caddr_t)&ifr) == -1)
4719 err(1, "SIOCGVH");
4720
4721 bzero(carpr.carpr_key, CARP_KEY_LEN20);
4722 strlcpy((char *)carpr.carpr_key, val, CARP_KEY_LEN20);
4723
4724 if (ioctl(sock, SIOCSVH(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((245)))
, (caddr_t)&ifr) == -1)
4725 err(1, "SIOCSVH");
4726}
4727
4728/* ARGSUSED */
4729void
4730setcarp_vhid(const char *val, int d)
4731{
4732 const char *errmsg = NULL((void*)0);
4733 struct carpreq carpr;
4734 int vhid;
4735
4736 vhid = strtonum(val, 1, 255, &errmsg);
4737 if (errmsg)
4738 errx(1, "vhid %s: %s", val, errmsg);
4739
4740 bzero(&carpr, sizeof(struct carpreq));
4741 ifr.ifr_dataifr_ifru.ifru_data = (caddr_t)&carpr;
4742
4743 if (ioctl(sock, SIOCGVH(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((246)))
, (caddr_t)&ifr) == -1)
4744 err(1, "SIOCGVH");
4745
4746 carpr.carpr_vhids[0] = vhid;
4747 carpr.carpr_vhids[1] = 0;
4748
4749 if (ioctl(sock, SIOCSVH(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((245)))
, (caddr_t)&ifr) == -1)
4750 err(1, "SIOCSVH");
4751}
4752
4753/* ARGSUSED */
4754void
4755setcarp_advskew(const char *val, int d)
4756{
4757 const char *errmsg = NULL((void*)0);
4758 struct carpreq carpr;
4759 int advskew;
4760
4761 advskew = strtonum(val, 0, 254, &errmsg);
4762 if (errmsg)
4763 errx(1, "advskew %s: %s", val, errmsg);
4764
4765 bzero(&carpr, sizeof(struct carpreq));
4766 ifr.ifr_dataifr_ifru.ifru_data = (caddr_t)&carpr;
4767
4768 if (ioctl(sock, SIOCGVH(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((246)))
, (caddr_t)&ifr) == -1)
4769 err(1, "SIOCGVH");
4770
4771 carpr.carpr_advskews[0] = advskew;
4772
4773 if (ioctl(sock, SIOCSVH(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((245)))
, (caddr_t)&ifr) == -1)
4774 err(1, "SIOCSVH");
4775}
4776
4777/* ARGSUSED */
4778void
4779setcarp_advbase(const char *val, int d)
4780{
4781 const char *errmsg = NULL((void*)0);
4782 struct carpreq carpr;
4783 int advbase;
4784
4785 advbase = strtonum(val, 0, 254, &errmsg);
4786 if (errmsg)
4787 errx(1, "advbase %s: %s", val, errmsg);
4788
4789 bzero(&carpr, sizeof(struct carpreq));
4790 ifr.ifr_dataifr_ifru.ifru_data = (caddr_t)&carpr;
4791
4792 if (ioctl(sock, SIOCGVH(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((246)))
, (caddr_t)&ifr) == -1)
4793 err(1, "SIOCGVH");
4794
4795 carpr.carpr_advbase = advbase;
4796
4797 if (ioctl(sock, SIOCSVH(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((245)))
, (caddr_t)&ifr) == -1)
4798 err(1, "SIOCSVH");
4799}
4800
4801/* ARGSUSED */
4802void
4803setcarppeer(const char *val, int d)
4804{
4805 struct carpreq carpr;
4806 struct addrinfo hints, *peerres;
4807 int ecode;
4808
4809 bzero(&carpr, sizeof(struct carpreq));
4810 ifr.ifr_dataifr_ifru.ifru_data = (caddr_t)&carpr;
4811
4812 if (ioctl(sock, SIOCGVH(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((246)))
, (caddr_t)&ifr) == -1)
4813 err(1, "SIOCGVH");
4814
4815 bzero(&hints, sizeof(hints));
4816 hints.ai_family = AF_INET2;
4817 hints.ai_socktype = SOCK_DGRAM2;
4818
4819 if ((ecode = getaddrinfo(val, NULL((void*)0), &hints, &peerres)) != 0)
4820 errx(1, "error in parsing address string: %s",
4821 gai_strerror(ecode));
4822
4823 if (peerres->ai_addr->sa_family != AF_INET2)
4824 errx(1, "only IPv4 addresses supported for the carppeer");
4825
4826 carpr.carpr_peer.s_addr = ((struct sockaddr_in *)
4827 peerres->ai_addr)->sin_addr.s_addr;
4828
4829 if (ioctl(sock, SIOCSVH(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((245)))
, (caddr_t)&ifr) == -1)
4830 err(1, "SIOCSVH");
4831
4832 freeaddrinfo(peerres);
4833}
4834
4835void
4836unsetcarppeer(const char *val, int d)
4837{
4838 struct carpreq carpr;
4839
4840 bzero(&carpr, sizeof(struct carpreq));
4841 ifr.ifr_dataifr_ifru.ifru_data = (caddr_t)&carpr;
4842
4843 if (ioctl(sock, SIOCGVH(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((246)))
, (caddr_t)&ifr) == -1)
4844 err(1, "SIOCGVH");
4845
4846 bzero(&carpr.carpr_peer, sizeof(carpr.carpr_peer));
4847
4848 if (ioctl(sock, SIOCSVH(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((245)))
, (caddr_t)&ifr) == -1)
4849 err(1, "SIOCSVH");
4850}
4851
4852/* ARGSUSED */
4853void
4854setcarp_state(const char *val, int d)
4855{
4856 struct carpreq carpr;
4857 int i;
4858
4859 bzero(&carpr, sizeof(struct carpreq));
4860 ifr.ifr_dataifr_ifru.ifru_data = (caddr_t)&carpr;
4861
4862 if (ioctl(sock, SIOCGVH(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((246)))
, (caddr_t)&ifr) == -1)
4863 err(1, "SIOCGVH");
4864
4865 for (i = 0; i <= CARP_MAXSTATE2; i++) {
4866 if (!strcasecmp(val, carp_states[i])) {
4867 carpr.carpr_state = i;
4868 break;
4869 }
4870 }
4871
4872 if (ioctl(sock, SIOCSVH(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((245)))
, (caddr_t)&ifr) == -1)
4873 err(1, "SIOCSVH");
4874}
4875
4876/* ARGSUSED */
4877void
4878setcarpdev(const char *val, int d)
4879{
4880 struct carpreq carpr;
4881
4882 bzero(&carpr, sizeof(struct carpreq));
4883 ifr.ifr_dataifr_ifru.ifru_data = (caddr_t)&carpr;
4884
4885 if (ioctl(sock, SIOCGVH(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((246)))
, (caddr_t)&ifr) == -1)
4886 err(1, "SIOCGVH");
4887
4888 strlcpy(carpr.carpr_carpdev, val, sizeof(carpr.carpr_carpdev));
4889
4890 if (ioctl(sock, SIOCSVH(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((245)))
, (caddr_t)&ifr) == -1)
4891 err(1, "SIOCSVH");
4892}
4893
4894void
4895setcarp_nodes(const char *val, int d)
4896{
4897 char *optlist, *str;
4898 int i;
4899 struct carpreq carpr;
4900
4901 bzero(&carpr, sizeof(struct carpreq));
4902 ifr.ifr_dataifr_ifru.ifru_data = (caddr_t)&carpr;
4903
4904 if (ioctl(sock, SIOCGVH(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((246)))
, (caddr_t)&ifr) == -1)
4905 err(1, "SIOCGVH");
4906
4907 bzero(carpr.carpr_vhids, sizeof(carpr.carpr_vhids));
4908 bzero(carpr.carpr_advskews, sizeof(carpr.carpr_advskews));
4909
4910 optlist = strdup(val);
4911 if (optlist == NULL((void*)0))
4912 err(1, "strdup");
4913
4914 str = strtok(optlist, ",");
4915 for (i = 0; str != NULL((void*)0); i++) {
4916 u_int vhid, advskew;
4917
4918 if (i >= CARP_MAXNODES32)
4919 errx(1, "too many carp nodes");
4920 if (sscanf(str, "%u:%u", &vhid, &advskew) != 2) {
4921 errx(1, "non parsable arg: %s", str);
4922 }
4923 if (vhid > 255)
4924 errx(1, "vhid %u: value too large", vhid);
4925 if (advskew >= 255)
4926 errx(1, "advskew %u: value too large", advskew);
4927
4928 carpr.carpr_vhids[i] = vhid;
4929 carpr.carpr_advskews[i] = advskew;
4930 str = strtok(NULL((void*)0), ",");
4931 }
4932 free(optlist);
4933
4934 if (ioctl(sock, SIOCSVH(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((245)))
, (caddr_t)&ifr) == -1)
4935 err(1, "SIOCSVH");
4936}
4937
4938void
4939setcarp_balancing(const char *val, int d)
4940{
4941 int i;
4942 struct carpreq carpr;
4943
4944 bzero(&carpr, sizeof(struct carpreq));
4945 ifr.ifr_dataifr_ifru.ifru_data = (caddr_t)&carpr;
4946
4947 if (ioctl(sock, SIOCGVH(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((246)))
, (caddr_t)&ifr) == -1)
4948 err(1, "SIOCGVH");
4949
4950 for (i = 0; i <= CARP_BAL_MAXID3; i++)
4951 if (!strcasecmp(val, carp_bal_modes[i]))
4952 break;
4953
4954 if (i > CARP_BAL_MAXID3)
4955 errx(1, "balancing %s: unknown mode", val);
4956
4957 carpr.carpr_balancing = i;
4958
4959 if (ioctl(sock, SIOCSVH(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((245)))
, (caddr_t)&ifr) == -1)
4960 err(1, "SIOCSVH");
4961}
4962
4963void
4964setpfsync_syncdev(const char *val, int d)
4965{
4966 struct pfsyncreq preq;
4967
4968 bzero(&preq, sizeof(struct pfsyncreq));
4969 ifr.ifr_dataifr_ifru.ifru_data = (caddr_t)&preq;
4970
4971 if (ioctl(sock, SIOCGETPFSYNC(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((248)))
, (caddr_t)&ifr) == -1)
4972 err(1, "SIOCGETPFSYNC");
4973
4974 strlcpy(preq.pfsyncr_syncdev, val, sizeof(preq.pfsyncr_syncdev));
4975
4976 if (ioctl(sock, SIOCSETPFSYNC((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((247)))
, (caddr_t)&ifr) == -1)
4977 err(1, "SIOCSETPFSYNC");
4978}
4979
4980/* ARGSUSED */
4981void
4982unsetpfsync_syncdev(const char *val, int d)
4983{
4984 struct pfsyncreq preq;
4985
4986 bzero(&preq, sizeof(struct pfsyncreq));
4987 ifr.ifr_dataifr_ifru.ifru_data = (caddr_t)&preq;
4988
4989 if (ioctl(sock, SIOCGETPFSYNC(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((248)))
, (caddr_t)&ifr) == -1)
4990 err(1, "SIOCGETPFSYNC");
4991
4992 bzero(&preq.pfsyncr_syncdev, sizeof(preq.pfsyncr_syncdev));
4993
4994 if (ioctl(sock, SIOCSETPFSYNC((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((247)))
, (caddr_t)&ifr) == -1)
4995 err(1, "SIOCSETPFSYNC");
4996}
4997
4998/* ARGSUSED */
4999void
5000setpfsync_syncpeer(const char *val, int d)
5001{
5002 struct pfsyncreq preq;
5003 struct addrinfo hints, *peerres;
5004 int ecode;
5005
5006 bzero(&preq, sizeof(struct pfsyncreq));
5007 ifr.ifr_dataifr_ifru.ifru_data = (caddr_t)&preq;
5008
5009 if (ioctl(sock, SIOCGETPFSYNC(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((248)))
, (caddr_t)&ifr) == -1)
5010 err(1, "SIOCGETPFSYNC");
5011
5012 memset(&hints, 0, sizeof(hints));
5013 hints.ai_family = AF_INET2;
5014 hints.ai_socktype = SOCK_DGRAM2; /*dummy*/
5015
5016 if ((ecode = getaddrinfo(val, NULL((void*)0), &hints, &peerres)) != 0)
5017 errx(1, "error in parsing address string: %s",
5018 gai_strerror(ecode));
5019
5020 if (peerres->ai_addr->sa_family != AF_INET2)
5021 errx(1, "only IPv4 addresses supported for the syncpeer");
5022
5023 preq.pfsyncr_syncpeer.s_addr = ((struct sockaddr_in *)
5024 peerres->ai_addr)->sin_addr.s_addr;
5025
5026 if (ioctl(sock, SIOCSETPFSYNC((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((247)))
, (caddr_t)&ifr) == -1)
5027 err(1, "SIOCSETPFSYNC");
5028
5029 freeaddrinfo(peerres);
5030}
5031
5032/* ARGSUSED */
5033void
5034unsetpfsync_syncpeer(const char *val, int d)
5035{
5036 struct pfsyncreq preq;
5037
5038 bzero(&preq, sizeof(struct pfsyncreq));
5039 ifr.ifr_dataifr_ifru.ifru_data = (caddr_t)&preq;
5040
5041 if (ioctl(sock, SIOCGETPFSYNC(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((248)))
, (caddr_t)&ifr) == -1)
5042 err(1, "SIOCGETPFSYNC");
5043
5044 preq.pfsyncr_syncpeer.s_addr = 0;
5045
5046 if (ioctl(sock, SIOCSETPFSYNC((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((247)))
, (caddr_t)&ifr) == -1)
5047 err(1, "SIOCSETPFSYNC");
5048}
5049
5050/* ARGSUSED */
5051void
5052setpfsync_maxupd(const char *val, int d)
5053{
5054 const char *errmsg = NULL((void*)0);
5055 struct pfsyncreq preq;
5056 int maxupdates;
5057
5058 maxupdates = strtonum(val, 0, 255, &errmsg);
5059 if (errmsg)
5060 errx(1, "maxupd %s: %s", val, errmsg);
5061
5062 bzero(&preq, sizeof(struct pfsyncreq));
5063 ifr.ifr_dataifr_ifru.ifru_data = (caddr_t)&preq;
5064
5065 if (ioctl(sock, SIOCGETPFSYNC(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((248)))
, (caddr_t)&ifr) == -1)
5066 err(1, "SIOCGETPFSYNC");
5067
5068 preq.pfsyncr_maxupdates = maxupdates;
5069
5070 if (ioctl(sock, SIOCSETPFSYNC((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((247)))
, (caddr_t)&ifr) == -1)
5071 err(1, "SIOCSETPFSYNC");
5072}
5073
5074void
5075setpfsync_defer(const char *val, int d)
5076{
5077 struct pfsyncreq preq;
5078
5079 bzero(&preq, sizeof(struct pfsyncreq));
5080 ifr.ifr_dataifr_ifru.ifru_data = (caddr_t)&preq;
5081
5082 if (ioctl(sock, SIOCGETPFSYNC(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((248)))
, (caddr_t)&ifr) == -1)
5083 err(1, "SIOCGETPFSYNC");
5084
5085 preq.pfsyncr_defer = d;
5086 if (ioctl(sock, SIOCSETPFSYNC((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((247)))
, (caddr_t)&ifr) == -1)
5087 err(1, "SIOCSETPFSYNC");
5088}
5089
5090void
5091pfsync_status(void)
5092{
5093 struct pfsyncreq preq;
5094
5095 bzero(&preq, sizeof(struct pfsyncreq));
5096 ifr.ifr_dataifr_ifru.ifru_data = (caddr_t)&preq;
5097
5098 if (ioctl(sock, SIOCGETPFSYNC(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((248)))
, (caddr_t)&ifr) == -1)
5099 return;
5100
5101 if (preq.pfsyncr_syncdev[0] != '\0') {
5102 printf("\tpfsync: syncdev: %s ", preq.pfsyncr_syncdev);
5103 if (preq.pfsyncr_syncpeer.s_addr != htonl(INADDR_PFSYNC_GROUP)(__uint32_t)(__builtin_constant_p(((u_int32_t)(0xe00000f0))) ?
(__uint32_t)(((__uint32_t)(((u_int32_t)(0xe00000f0))) & 0xff
) << 24 | ((__uint32_t)(((u_int32_t)(0xe00000f0))) &
0xff00) << 8 | ((__uint32_t)(((u_int32_t)(0xe00000f0))
) & 0xff0000) >> 8 | ((__uint32_t)(((u_int32_t)(0xe00000f0
))) & 0xff000000) >> 24) : __swap32md(((u_int32_t)(
0xe00000f0))))
)
5104 printf("syncpeer: %s ",
5105 inet_ntoa(preq.pfsyncr_syncpeer));
5106 printf("maxupd: %d ", preq.pfsyncr_maxupdates);
5107 printf("defer: %s\n", preq.pfsyncr_defer ? "on" : "off");
5108 }
5109}
5110
5111void
5112pflow_status(void)
5113{
5114 struct pflowreq preq;
5115 struct sockaddr_in *sin;
5116 struct sockaddr_in6 *sin6;
5117 int error;
5118 char buf[INET6_ADDRSTRLEN46];
5119
5120 bzero(&preq, sizeof(struct pflowreq));
5121 ifr.ifr_dataifr_ifru.ifru_data = (caddr_t)&preq;
5122
5123 if (ioctl(sock, SIOCGETPFLOW(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((254)))
, (caddr_t)&ifr) == -1)
5124 return;
5125
5126 if (preq.flowsrc.ss_family == AF_INET2 || preq.flowsrc.ss_family ==
5127 AF_INET624) {
5128 error = getnameinfo((struct sockaddr*)&preq.flowsrc,
5129 preq.flowsrc.ss_len, buf, sizeof(buf), NULL((void*)0), 0,
5130 NI_NUMERICHOST1);
5131 if (error)
5132 err(1, "sender: %s", gai_strerror(error));
5133 }
5134
5135 printf("\tpflow: ");
5136 switch (preq.flowsrc.ss_family) {
5137 case AF_INET2:
5138 sin = (struct sockaddr_in*) &preq.flowsrc;
5139 if (sin->sin_addr.s_addr != INADDR_ANY((u_int32_t)(0x00000000))) {
5140 printf("sender: %s", buf);
5141 if (sin->sin_port != 0)
5142 printf(":%u", ntohs(sin->sin_port)(__uint16_t)(__builtin_constant_p(sin->sin_port) ? (__uint16_t
)(((__uint16_t)(sin->sin_port) & 0xffU) << 8 | (
(__uint16_t)(sin->sin_port) & 0xff00U) >> 8) : __swap16md
(sin->sin_port))
);
5143 printf(" ");
5144 }
5145 break;
5146 case AF_INET624:
5147 sin6 = (struct sockaddr_in6*) &preq.flowsrc;
5148 if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)((*(const u_int32_t *)(const void *)(&(&sin6->sin6_addr
)->__u6_addr.__u6_addr8[0]) == 0) && (*(const u_int32_t
*)(const void *)(&(&sin6->sin6_addr)->__u6_addr
.__u6_addr8[4]) == 0) && (*(const u_int32_t *)(const void
*)(&(&sin6->sin6_addr)->__u6_addr.__u6_addr8[8
]) == 0) && (*(const u_int32_t *)(const void *)(&
(&sin6->sin6_addr)->__u6_addr.__u6_addr8[12]) == 0)
)
) {
5149 printf("sender: [%s]", buf);
5150 if (sin6->sin6_port != 0)
5151 printf(":%u", ntohs(sin6->sin6_port)(__uint16_t)(__builtin_constant_p(sin6->sin6_port) ? (__uint16_t
)(((__uint16_t)(sin6->sin6_port) & 0xffU) << 8 |
((__uint16_t)(sin6->sin6_port) & 0xff00U) >> 8)
: __swap16md(sin6->sin6_port))
);
5152 printf(" ");
5153 }
5154 default:
5155 break;
5156 }
5157 if (preq.flowdst.ss_family == AF_INET2 || preq.flowdst.ss_family ==
5158 AF_INET624) {
5159 error = getnameinfo((struct sockaddr*)&preq.flowdst,
5160 preq.flowdst.ss_len, buf, sizeof(buf), NULL((void*)0), 0,
5161 NI_NUMERICHOST1);
5162 if (error)
5163 err(1, "receiver: %s", gai_strerror(error));
5164 }
5165 switch (preq.flowdst.ss_family) {
5166 case AF_INET2:
5167 sin = (struct sockaddr_in*)&preq.flowdst;
5168 printf("receiver: %s:", sin->sin_addr.s_addr != INADDR_ANY((u_int32_t)(0x00000000)) ?
5169 buf : "INVALID");
5170 if (sin->sin_port == 0)
5171 printf("%s ", "INVALID");
5172 else
5173 printf("%u ", ntohs(sin->sin_port)(__uint16_t)(__builtin_constant_p(sin->sin_port) ? (__uint16_t
)(((__uint16_t)(sin->sin_port) & 0xffU) << 8 | (
(__uint16_t)(sin->sin_port) & 0xff00U) >> 8) : __swap16md
(sin->sin_port))
);
5174 break;
5175 case AF_INET624:
5176 sin6 = (struct sockaddr_in6*) &preq.flowdst;
5177 printf("receiver: [%s]:",
5178 !IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)((*(const u_int32_t *)(const void *)(&(&sin6->sin6_addr
)->__u6_addr.__u6_addr8[0]) == 0) && (*(const u_int32_t
*)(const void *)(&(&sin6->sin6_addr)->__u6_addr
.__u6_addr8[4]) == 0) && (*(const u_int32_t *)(const void
*)(&(&sin6->sin6_addr)->__u6_addr.__u6_addr8[8
]) == 0) && (*(const u_int32_t *)(const void *)(&
(&sin6->sin6_addr)->__u6_addr.__u6_addr8[12]) == 0)
)
? buf :
5179 "INVALID");
5180 if (sin6->sin6_port == 0)
5181 printf("%s ", "INVALID");
5182 else
5183 printf("%u ", ntohs(sin6->sin6_port)(__uint16_t)(__builtin_constant_p(sin6->sin6_port) ? (__uint16_t
)(((__uint16_t)(sin6->sin6_port) & 0xffU) << 8 |
((__uint16_t)(sin6->sin6_port) & 0xff00U) >> 8)
: __swap16md(sin6->sin6_port))
);
5184 break;
5185 default:
5186 printf("receiver: INVALID:INVALID ");
5187 break;
5188 }
5189 printf("version: %d\n", preq.version);
5190}
5191
5192void
5193pflow_addr(const char *val, struct sockaddr_storage *ss) {
5194 struct addrinfo hints, *res0;
5195 int error, flag;
5196 char *cp, *ip, *port, buf[HOST_NAME_MAX255+1 + sizeof (":65535")];
5197
5198 if (strlcpy(buf, val, sizeof(buf)) >= sizeof(buf))
5199 errx(1, "%s bad value", val);
5200
5201 port = NULL((void*)0);
5202 cp = buf;
5203 if (*cp == '[')
5204 flag = 1;
5205 else
5206 flag = 0;
5207
5208 for(; *cp; ++cp) {
5209 if (*cp == ']' && *(cp + 1) == ':' && flag) {
5210 *cp = '\0';
5211 *(cp + 1) = '\0';
5212 port = cp + 2;
5213 break;
5214 }
5215 if (*cp == ']' && *(cp + 1) == '\0' && flag) {
5216 *cp = '\0';
5217 port = NULL((void*)0);
5218 break;
5219 }
5220 if (*cp == ':' && !flag) {
5221 *cp = '\0';
5222 port = cp + 1;
5223 break;
5224 }
5225 }
5226
5227 ip = buf;
5228 if (flag)
5229 ip++;
5230
5231 bzero(&hints, sizeof(hints));
5232 hints.ai_family = AF_UNSPEC0;
5233 hints.ai_socktype = SOCK_DGRAM2; /*dummy*/
5234 hints.ai_flags = AI_NUMERICHOST4;
5235
5236 if ((error = getaddrinfo(ip, port, &hints, &res0)) != 0)
5237 errx(1, "error in parsing address string: %s",
5238 gai_strerror(error));
5239
5240 memcpy(ss, res0->ai_addr, res0->ai_addr->sa_len);
5241 freeaddrinfo(res0);
5242}
5243
5244void
5245setpflow_sender(const char *val, int d)
5246{
5247 struct pflowreq preq;
5248
5249 bzero(&preq, sizeof(struct pflowreq));
5250 ifr.ifr_dataifr_ifru.ifru_data = (caddr_t)&preq;
5251 preq.addrmask |= PFLOW_MASK_SRCIP0x01;
5252 pflow_addr(val, &preq.flowsrc);
5253
5254 if (ioctl(sock, SIOCSETPFLOW((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((253)))
, (caddr_t)&ifr) == -1)
5255 err(1, "SIOCSETPFLOW");
5256}
5257
5258void
5259unsetpflow_sender(const char *val, int d)
5260{
5261 struct pflowreq preq;
5262
5263 bzero(&preq, sizeof(struct pflowreq));
5264 preq.addrmask |= PFLOW_MASK_SRCIP0x01;
5265 ifr.ifr_dataifr_ifru.ifru_data = (caddr_t)&preq;
5266 if (ioctl(sock, SIOCSETPFLOW((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((253)))
, (caddr_t)&ifr) == -1)
5267 err(1, "SIOCSETPFLOW");
5268}
5269
5270void
5271setpflow_receiver(const char *val, int d)
5272{
5273 struct pflowreq preq;
5274
5275 bzero(&preq, sizeof(struct pflowreq));
5276 ifr.ifr_dataifr_ifru.ifru_data = (caddr_t)&preq;
5277 preq.addrmask |= PFLOW_MASK_DSTIP0x02;
5278 pflow_addr(val, &preq.flowdst);
5279
5280 if (ioctl(sock, SIOCSETPFLOW((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((253)))
, (caddr_t)&ifr) == -1)
5281 err(1, "SIOCSETPFLOW");
5282}
5283
5284void
5285unsetpflow_receiver(const char *val, int d)
5286{
5287 struct pflowreq preq;
5288
5289 bzero(&preq, sizeof(struct pflowreq));
5290 ifr.ifr_dataifr_ifru.ifru_data = (caddr_t)&preq;
5291 preq.addrmask |= PFLOW_MASK_DSTIP0x02;
5292 if (ioctl(sock, SIOCSETPFLOW((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((253)))
, (caddr_t)&ifr) == -1)
5293 err(1, "SIOCSETPFLOW");
5294}
5295
5296/* PFLOWPROTO XXX */
5297void
5298setpflowproto(const char *val, int d)
5299{
5300 struct pflow_protos ppr[] = PFLOW_PROTOS{ { "5", 5 }, { "10", 10 }, };
5301 struct pflowreq preq;
5302 int i;
5303
5304 bzero(&preq, sizeof(preq));
5305 preq.version = PFLOW_PROTO_MAX11;
5306
5307 for (i = 0; i < (sizeof(ppr) / sizeof(ppr[0])); i++) {
5308 if (strcmp(val, ppr[i].ppr_name) == 0) {
5309 preq.version = ppr[i].ppr_proto;
5310 break;
5311 }
5312 }
5313 if (preq.version == PFLOW_PROTO_MAX11)
5314 errx(1, "Invalid pflow protocol: %s", val);
5315
5316 preq.addrmask |= PFLOW_MASK_VERSION0x04;
5317
5318 ifr.ifr_dataifr_ifru.ifru_data = (caddr_t)&preq;
5319
5320 if (ioctl(sock, SIOCSETPFLOW((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((253)))
, (caddr_t)&ifr) == -1)
5321 err(1, "SIOCSETPFLOW");
5322}
5323
5324void
5325pppoe_status(void)
5326{
5327 struct pppoediscparms parms;
5328 struct pppoeconnectionstate state;
5329
5330 memset(&state, 0, sizeof(state));
5331
5332 strlcpy(parms.ifname, ifname, sizeof(parms.ifname));
5333 if (ioctl(sock, PPPOEGETPARMS(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct pppoediscparms) & 0x1fff) << 16) | ((('i'))
<< 8) | ((111)))
, &parms) == -1)
5334 return;
5335
5336 printf("\tdev: %s ", parms.eth_ifname);
5337
5338 if (*parms.ac_name)
5339 printf("ac: %s ", parms.ac_name);
5340 if (*parms.service_name)
5341 printf("svc: %s ", parms.service_name);
5342
5343 strlcpy(state.ifname, ifname, sizeof(state.ifname));
5344 if (ioctl(sock, PPPOEGETSESSION(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct pppoeconnectionstate) & 0x1fff) << 16) | ((
('i')) << 8) | ((112)))
, &state) == -1)
5345 err(1, "PPPOEGETSESSION");
5346
5347 printf("state: ");
5348 switch (state.state) {
5349 case PPPOE_STATE_INITIAL0:
5350 printf("initial"); break;
5351 case PPPOE_STATE_PADI_SENT1:
5352 printf("PADI sent"); break;
5353 case PPPOE_STATE_PADR_SENT2:
5354 printf("PADR sent"); break;
5355 case PPPOE_STATE_SESSION3:
5356 printf("session"); break;
5357 case PPPOE_STATE_CLOSING4:
5358 printf("closing"); break;
5359 }
5360 printf("\n\tsid: 0x%x", state.session_id);
5361 printf(" PADI retries: %d", state.padi_retry_no);
5362 printf(" PADR retries: %d", state.padr_retry_no);
5363
5364 if (state.state == PPPOE_STATE_SESSION3) {
5365 struct timespec temp_time;
5366 time_t diff_time, day = 0;
5367 unsigned int hour = 0, min = 0, sec = 0;
5368
5369 if (state.session_time.tv_sec != 0) {
5370 if (clock_gettime(CLOCK_BOOTTIME6, &temp_time) == -1)
5371 goto notime;
5372 diff_time = temp_time.tv_sec -
5373 state.session_time.tv_sec;
5374
5375 day = diff_time / (60 * 60 * 24);
5376 diff_time %= (60 * 60 * 24);
5377
5378 hour = diff_time / (60 * 60);
5379 diff_time %= (60 * 60);
5380
5381 min = diff_time / 60;
5382 diff_time %= 60;
5383
5384 sec = diff_time;
5385 }
5386 printf(" time: ");
5387 if (day != 0)
5388 printf("%lldd ", (long long)day);
5389 printf("%02u:%02u:%02u", hour, min, sec);
5390 }
5391notime:
5392 putchar('\n')(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n',
(&__sF[1])))
;
5393}
5394
5395/* ARGSUSED */
5396void
5397setpppoe_dev(const char *val, int d)
5398{
5399 struct pppoediscparms parms;
5400
5401 strlcpy(parms.ifname, ifname, sizeof(parms.ifname));
5402 if (ioctl(sock, PPPOEGETPARMS(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct pppoediscparms) & 0x1fff) << 16) | ((('i'))
<< 8) | ((111)))
, &parms) == -1)
5403 return;
5404
5405 strlcpy(parms.eth_ifname, val, sizeof(parms.eth_ifname));
5406
5407 if (ioctl(sock, PPPOESETPARMS((unsigned long)0x80000000 | ((sizeof(struct pppoediscparms) &
0x1fff) << 16) | ((('i')) << 8) | ((110)))
, &parms) == -1)
5408 err(1, "PPPOESETPARMS");
5409}
5410
5411/* ARGSUSED */
5412void
5413setpppoe_svc(const char *val, int d)
5414{
5415 struct pppoediscparms parms;
5416
5417 strlcpy(parms.ifname, ifname, sizeof(parms.ifname));
5418 if (ioctl(sock, PPPOEGETPARMS(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct pppoediscparms) & 0x1fff) << 16) | ((('i'))
<< 8) | ((111)))
, &parms) == -1)
5419 return;
5420
5421 if (d == 0)
5422 strlcpy(parms.service_name, val, sizeof(parms.service_name));
5423 else
5424 memset(parms.service_name, 0, sizeof(parms.service_name));
5425
5426 if (ioctl(sock, PPPOESETPARMS((unsigned long)0x80000000 | ((sizeof(struct pppoediscparms) &
0x1fff) << 16) | ((('i')) << 8) | ((110)))
, &parms) == -1)
5427 err(1, "PPPOESETPARMS");
5428}
5429
5430/* ARGSUSED */
5431void
5432setpppoe_ac(const char *val, int d)
5433{
5434 struct pppoediscparms parms;
5435
5436 strlcpy(parms.ifname, ifname, sizeof(parms.ifname));
5437 if (ioctl(sock, PPPOEGETPARMS(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct pppoediscparms) & 0x1fff) << 16) | ((('i'))
<< 8) | ((111)))
, &parms) == -1)
5438 return;
5439
5440 if (d == 0)
5441 strlcpy(parms.ac_name, val, sizeof(parms.ac_name));
5442 else
5443 memset(parms.ac_name, 0, sizeof(parms.ac_name));
5444
5445 if (ioctl(sock, PPPOESETPARMS((unsigned long)0x80000000 | ((sizeof(struct pppoediscparms) &
0x1fff) << 16) | ((('i')) << 8) | ((110)))
, &parms) == -1)
5446 err(1, "PPPOESETPARMS");
5447}
5448
5449void
5450spppauthinfo(struct sauthreq *spa, int d)
5451{
5452 bzero(spa, sizeof(struct sauthreq));
5453
5454 ifr.ifr_dataifr_ifru.ifru_data = (caddr_t)spa;
5455 spa->cmd = d == 0 ? SPPPIOGMAUTH((int)(('S' << 24) + (3 << 16) + sizeof(struct sauthreq
)))
: SPPPIOGHAUTH((int)(('S' << 24) + (5 << 16) + sizeof(struct sauthreq
)))
;
5456 if (ioctl(sock, SIOCGSPPPPARAMS(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((148)))
, &ifr) == -1)
5457 err(1, "SIOCGSPPPPARAMS(SPPPIOGXAUTH)");
5458}
5459
5460void
5461spppdnsinfo(struct sdnsreq *spd)
5462{
5463 memset(spd, 0, sizeof(*spd));
5464
5465 ifr.ifr_dataifr_ifru.ifru_data = (caddr_t)spd;
5466 spd->cmd = SPPPIOGDNS((int)(('S' << 24) + (7 << 16) + sizeof(struct sdnsreq
)))
;
5467 if (ioctl(sock, SIOCGSPPPPARAMS(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((148)))
, &ifr) == -1)
5468 err(1, "SIOCGSPPPPARAMS(SPPPIOGDNS)");
5469}
5470
5471void
5472setspppproto(const char *val, int d)
5473{
5474 struct sauthreq spa;
5475
5476 spppauthinfo(&spa, d);
5477
5478 if (strcmp(val, "pap") == 0)
5479 spa.proto = PPP_PAP0xc023;
5480 else if (strcmp(val, "chap") == 0)
5481 spa.proto = PPP_CHAP0xc223;
5482 else if (strcmp(val, "none") == 0)
5483 spa.proto = 0;
5484 else
5485 errx(1, "setpppproto");
5486
5487 spa.cmd = d == 0 ? SPPPIOSMAUTH((int)(('S' << 24) + (4 << 16) + sizeof(struct sauthreq
)))
: SPPPIOSHAUTH((int)(('S' << 24) + (6 << 16) + sizeof(struct sauthreq
)))
;
5488 if (ioctl(sock, SIOCSSPPPPARAMS((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((147)))
, &ifr) == -1)
5489 err(1, "SIOCSSPPPPARAMS(SPPPIOSXAUTH)");
5490}
5491
5492void
5493setsppppeerproto(const char *val, int d)
5494{
5495 setspppproto(val, 1);
5496}
5497
5498void
5499setspppname(const char *val, int d)
5500{
5501 struct sauthreq spa;
5502
5503 spppauthinfo(&spa, d);
5504
5505 if (spa.proto == 0)
5506 errx(1, "unspecified protocol");
5507 if (strlcpy(spa.name, val, sizeof(spa.name)) >= sizeof(spa.name))
5508 errx(1, "setspppname");
5509
5510 spa.cmd = d == 0 ? SPPPIOSMAUTH((int)(('S' << 24) + (4 << 16) + sizeof(struct sauthreq
)))
: SPPPIOSHAUTH((int)(('S' << 24) + (6 << 16) + sizeof(struct sauthreq
)))
;
5511 if (ioctl(sock, SIOCSSPPPPARAMS((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((147)))
, &ifr) == -1)
5512 err(1, "SIOCSSPPPPARAMS(SPPPIOSXAUTH)");
5513}
5514
5515void
5516setsppppeername(const char *val, int d)
5517{
5518 setspppname(val, 1);
5519}
5520
5521void
5522setspppkey(const char *val, int d)
5523{
5524 struct sauthreq spa;
5525
5526 spppauthinfo(&spa, d);
5527
5528 if (spa.proto == 0)
5529 errx(1, "unspecified protocol");
5530 if (strlcpy(spa.secret, val, sizeof(spa.secret)) >= sizeof(spa.secret))
5531 errx(1, "setspppkey");
5532
5533 spa.cmd = d == 0 ? SPPPIOSMAUTH((int)(('S' << 24) + (4 << 16) + sizeof(struct sauthreq
)))
: SPPPIOSHAUTH((int)(('S' << 24) + (6 << 16) + sizeof(struct sauthreq
)))
;
5534 if (ioctl(sock, SIOCSSPPPPARAMS((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((147)))
, &ifr) == -1)
5535 err(1, "SIOCSSPPPPARAMS(SPPPIOSXAUTH)");
5536}
5537
5538void
5539setsppppeerkey(const char *val, int d)
5540{
5541 setspppkey(val, 1);
5542}
5543
5544void
5545setsppppeerflag(const char *val, int d)
5546{
5547 struct sauthreq spa;
5548 int flag;
5549
5550 spppauthinfo(&spa, 1);
5551
5552 if (spa.proto == 0)
5553 errx(1, "unspecified protocol");
5554 if (strcmp(val, "callin") == 0)
5555 flag = AUTHFLAG_NOCALLOUT1;
5556 else if (strcmp(val, "norechallenge") == 0)
5557 flag = AUTHFLAG_NORECHALLENGE2;
5558 else
5559 errx(1, "setppppeerflags");
5560
5561 if (d)
5562 spa.flags &= ~flag;
5563 else
5564 spa.flags |= flag;
5565
5566 spa.cmd = SPPPIOSHAUTH((int)(('S' << 24) + (6 << 16) + sizeof(struct sauthreq
)))
;
5567 if (ioctl(sock, SIOCSSPPPPARAMS((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((147)))
, &ifr) == -1)
5568 err(1, "SIOCSSPPPPARAMS(SPPPIOSXAUTH)");
5569}
5570
5571void
5572unsetsppppeerflag(const char *val, int d)
5573{
5574 setsppppeerflag(val, 1);
5575}
5576
5577void
5578sppp_printproto(const char *name, struct sauthreq *auth)
5579{
5580 if (auth->proto == 0)
5581 return;
5582 printf("%sproto ", name);
5583 switch (auth->proto) {
5584 case PPP_PAP0xc023:
5585 printf("pap ");
5586 break;
5587 case PPP_CHAP0xc223:
5588 printf("chap ");
5589 break;
5590 default:
5591 printf("0x%04x ", auth->proto);
5592 break;
5593 }
5594 if (auth->name[0])
5595 printf("%sname \"%s\" ", name, auth->name);
5596 if (auth->secret[0])
5597 printf("%skey \"%s\" ", name, auth->secret);
5598}
5599
5600void
5601sppp_status(void)
5602{
5603 struct spppreq spr;
5604 struct sauthreq spa;
5605 struct sdnsreq spd;
5606 char astr[INET_ADDRSTRLEN16];
5607 int i, n;
5608
5609 bzero(&spr, sizeof(spr));
5610
5611 ifr.ifr_dataifr_ifru.ifru_data = (caddr_t)&spr;
5612 spr.cmd = SPPPIOGDEFS((int)(('S' << 24) + (1 << 16) + sizeof(struct spppreq
)))
;
5613 if (ioctl(sock, SIOCGSPPPPARAMS(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((148)))
, &ifr) == -1) {
5614 return;
5615 }
5616
5617 if (spr.phase == PHASE_DEAD)
5618 return;
5619 printf("\tsppp: phase ");
5620 switch (spr.phase) {
5621 case PHASE_ESTABLISH:
5622 printf("establish ");
5623 break;
5624 case PHASE_TERMINATE:
5625 printf("terminate ");
5626 break;
5627 case PHASE_AUTHENTICATE:
5628 printf("authenticate ");
5629 break;
5630 case PHASE_NETWORK:
5631 printf("network ");
5632 break;
5633 default:
5634 printf("illegal ");
5635 break;
5636 }
5637
5638 spppauthinfo(&spa, 0);
5639 sppp_printproto("auth", &spa);
5640 spppauthinfo(&spa, 1);
5641 sppp_printproto("peer", &spa);
5642 if (spa.flags & AUTHFLAG_NOCALLOUT1)
5643 printf("callin ");
5644 if (spa.flags & AUTHFLAG_NORECHALLENGE2)
5645 printf("norechallenge ");
5646 putchar('\n')(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n',
(&__sF[1])))
;
5647
5648 spppdnsinfo(&spd);
5649 for (i = 0, n = 0; i < IPCP_MAX_DNSSRV2; i++) {
5650 if (spd.dns[i].s_addr == INADDR_ANY((u_int32_t)(0x00000000)))
5651 break;
5652 printf("%s %s", n++ ? "" : "\tdns:",
5653 inet_ntop(AF_INET2, &spd.dns[i], astr, sizeof(astr)));
5654 }
5655 if (n)
5656 printf("\n");
5657}
5658
5659void
5660setkeepalive(const char *timeout, const char *count)
5661{
5662 const char *errmsg = NULL((void*)0);
5663 struct ifkalivereq ikar;
5664 int t, c;
5665
5666 t = strtonum(timeout, 1, 3600, &errmsg);
5667 if (errmsg)
5668 errx(1, "keepalive period %s: %s", timeout, errmsg);
5669 c = strtonum(count, 2, 600, &errmsg);
5670 if (errmsg)
5671 errx(1, "keepalive count %s: %s", count, errmsg);
5672
5673 strlcpy(ikar.ikar_name, ifname, sizeof(ikar.ikar_name));
5674 ikar.ikar_timeo = t;
5675 ikar.ikar_cnt = c;
5676 if (ioctl(sock, SIOCSETKALIVE((unsigned long)0x80000000 | ((sizeof(struct ifkalivereq) &
0x1fff) << 16) | ((('i')) << 8) | ((163)))
, (caddr_t)&ikar) == -1)
5677 warn("SIOCSETKALIVE");
5678}
5679
5680void
5681unsetkeepalive(const char *val, int d)
5682{
5683 struct ifkalivereq ikar;
5684
5685 bzero(&ikar, sizeof(ikar));
5686 strlcpy(ikar.ikar_name, ifname, sizeof(ikar.ikar_name));
5687 if (ioctl(sock, SIOCSETKALIVE((unsigned long)0x80000000 | ((sizeof(struct ifkalivereq) &
0x1fff) << 16) | ((('i')) << 8) | ((163)))
, (caddr_t)&ikar) == -1)
5688 warn("SIOCSETKALIVE");
5689}
5690
5691void
5692setifpriority(const char *id, int param)
5693{
5694 const char *errmsg = NULL((void*)0);
5695 int prio;
5696
5697 prio = strtonum(id, 0, 15, &errmsg);
5698 if (errmsg)
5699 errx(1, "priority %s: %s", id, errmsg);
5700
5701 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
5702 ifr.ifr_metricifr_ifru.ifru_metric = prio;
5703 if (ioctl(sock, SIOCSIFPRIORITY((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((155)))
, (caddr_t)&ifr) == -1)
5704 warn("SIOCSIFPRIORITY");
5705}
5706
5707/*
5708 * WireGuard configuration
5709 *
5710 * WG_BASE64_KEY_LEN specifies the size of a base64 encoded WireGuard key.
5711 * WG_TMP_KEY_LEN specifies the size of a decoded base64 key. For every 4
5712 * input (base64) bytes, 3 output bytes wil be produced. The output will be
5713 * padded with 0 bits, therefore we need more than the regular 32 bytes of
5714 * space.
5715 */
5716#define WG_BASE64_KEY_LEN(4 * ((32 + 2) / 3)) (4 * ((WG_KEY_LEN32 + 2) / 3))
5717#define WG_LOAD_KEY(dst, src, fn_name)do { uint8_t _tmp[32]; int _r; if (strlen(src) != (4 * ((32 +
2) / 3))) errx(1, fn_name " (key): invalid length"); if ((_r
= __b64_pton(src, _tmp, sizeof(_tmp))) != sizeof(_tmp)) errx
(1, fn_name " (key): invalid base64 %d/%zu", _r, sizeof(_tmp)
); memcpy(dst, _tmp, 32); } while (0)
do { \
5718 uint8_t _tmp[WG_KEY_LEN32]; int _r; \
5719 if (strlen(src) != WG_BASE64_KEY_LEN(4 * ((32 + 2) / 3))) \
5720 errx(1, fn_name " (key): invalid length"); \
5721 if ((_r = b64_pton__b64_pton(src, _tmp, sizeof(_tmp))) != sizeof(_tmp)) \
5722 errx(1, fn_name " (key): invalid base64 %d/%zu", _r, sizeof(_tmp)); \
5723 memcpy(dst, _tmp, WG_KEY_LEN32); \
5724} while (0)
5725
5726struct wg_data_io wgdata = { 0 };
5727struct wg_interface_io *wg_interface = NULL((void*)0);
5728struct wg_peer_io *wg_peer = NULL((void*)0);
5729struct wg_aip_io *wg_aip = NULL((void*)0);
5730
5731void
5732ensurewginterface(void)
5733{
5734 if (wg_interface != NULL((void*)0))
5735 return;
5736 wgdata.wgd_size = sizeof(*wg_interface);
5737 wgdata.wgd_interface = wg_interface = calloc(1, wgdata.wgd_size);
5738 if (wg_interface == NULL((void*)0))
5739 err(1, "calloc");
5740}
5741
5742void
5743growwgdata(size_t by)
5744{
5745 ptrdiff_t peer_offset, aip_offset;
5746
5747 if (wg_interface == NULL((void*)0))
5748 wgdata.wgd_size = sizeof(*wg_interface);
5749
5750 peer_offset = (void *)wg_peer - (void *)wg_interface;
5751 aip_offset = (void *)wg_aip - (void *)wg_interface;
5752
5753 wgdata.wgd_size += by;
5754 wgdata.wgd_interface = realloc(wg_interface, wgdata.wgd_size);
5755 if (wgdata.wgd_interface == NULL((void*)0))
5756 err(1, "calloc");
5757 if (wg_interface == NULL((void*)0))
5758 bzero(wgdata.wgd_interface, sizeof(*wg_interface));
5759 wg_interface = wgdata.wgd_interface;
5760
5761 if (wg_peer != NULL((void*)0))
5762 wg_peer = (void *)wg_interface + peer_offset;
5763 if (wg_aip != NULL((void*)0))
5764 wg_aip = (void *)wg_interface + aip_offset;
5765
5766 bzero((char *)wg_interface + wgdata.wgd_size - by, by);
5767}
5768
5769void
5770setwgpeer(const char *peerkey_b64, int param)
5771{
5772 growwgdata(sizeof(*wg_peer));
5773 if (wg_aip)
5774 wg_peer = (struct wg_peer_io *)wg_aip;
5775 else
5776 wg_peer = &wg_interface->i_peers[0];
5777 wg_aip = &wg_peer->p_aips[0];
5778 wg_peer->p_flags |= WG_PEER_HAS_PUBLIC(1 << 0);
5779 WG_LOAD_KEY(wg_peer->p_public, peerkey_b64, "wgpeer")do { uint8_t _tmp[32]; int _r; if (strlen(peerkey_b64) != (4 *
((32 + 2) / 3))) errx(1, "wgpeer" " (key): invalid length");
if ((_r = __b64_pton(peerkey_b64, _tmp, sizeof(_tmp))) != sizeof
(_tmp)) errx(1, "wgpeer" " (key): invalid base64 %d/%zu", _r,
sizeof(_tmp)); memcpy(wg_peer->p_public, _tmp, 32); } while
(0)
;
5780 wg_interface->i_peers_count++;
5781}
5782
5783void
5784setwgpeeraip(const char *aip, int param)
5785{
5786 int res;
5787 if (wg_peer == NULL((void*)0))
5788 errx(1, "wgaip: wgpeer not set");
5789
5790 growwgdata(sizeof(*wg_aip));
5791
5792 if ((res = inet_net_pton(AF_INET2, aip, &wg_aip->a_ipv4a_addr.addr_ipv4,
5793 sizeof(wg_aip->a_ipv4a_addr.addr_ipv4))) != -1) {
5794 wg_aip->a_af = AF_INET2;
5795 } else if ((res = inet_net_pton(AF_INET624, aip, &wg_aip->a_ipv6a_addr.addr_ipv6,
5796 sizeof(wg_aip->a_ipv6a_addr.addr_ipv6))) != -1) {
5797 wg_aip->a_af = AF_INET624;
5798 } else {
5799 errx(1, "wgaip: bad address");
5800 }
5801
5802 wg_aip->a_cidr = res;
5803
5804 wg_peer->p_flags |= WG_PEER_REPLACE_AIPS(1 << 4);
5805 wg_peer->p_aips_count++;
5806
5807 wg_aip++;
5808}
5809
5810void
5811setwgpeerep(const char *host, const char *service)
5812{
5813 int error;
5814 struct addrinfo *ai;
5815
5816 if (wg_peer == NULL((void*)0))
5817 errx(1, "wgendpoint: wgpeer not set");
5818
5819 if ((error = getaddrinfo(host, service, NULL((void*)0), &ai)) != 0)
5820 errx(1, "%s", gai_strerror(error));
5821
5822 wg_peer->p_flags |= WG_PEER_HAS_ENDPOINT(1 << 3);
5823 memcpy(&wg_peer->p_sap_endpoint.sa_sa, ai->ai_addr, ai->ai_addrlen);
5824 freeaddrinfo(ai);
5825}
5826
5827void
5828setwgpeerpsk(const char *psk_b64, int param)
5829{
5830 if (wg_peer == NULL((void*)0))
5831 errx(1, "wgpsk: wgpeer not set");
5832 wg_peer->p_flags |= WG_PEER_HAS_PSK(1 << 1);
5833 WG_LOAD_KEY(wg_peer->p_psk, psk_b64, "wgpsk")do { uint8_t _tmp[32]; int _r; if (strlen(psk_b64) != (4 * ((
32 + 2) / 3))) errx(1, "wgpsk" " (key): invalid length"); if (
(_r = __b64_pton(psk_b64, _tmp, sizeof(_tmp))) != sizeof(_tmp
)) errx(1, "wgpsk" " (key): invalid base64 %d/%zu", _r, sizeof
(_tmp)); memcpy(wg_peer->p_psk, _tmp, 32); } while (0)
;
5834}
5835
5836void
5837setwgpeerpka(const char *pka, int param)
5838{
5839 const char *errmsg = NULL((void*)0);
5840 if (wg_peer == NULL((void*)0))
5841 errx(1, "wgpka: wgpeer not set");
5842 /* 43200 == 12h, reasonable for a 16 bit value */
5843 wg_peer->p_flags |= WG_PEER_HAS_PKA(1 << 2);
5844 wg_peer->p_pka = strtonum(pka, 0, 43200, &errmsg);
5845 if (errmsg)
5846 errx(1, "wgpka: %s, %s", pka, errmsg);
5847}
5848
5849void
5850setwgport(const char *port, int param)
5851{
5852 const char *errmsg = NULL((void*)0);
5853 ensurewginterface();
5854 wg_interface->i_flags |= WG_INTERFACE_HAS_PORT(1 << 2);
5855 wg_interface->i_port = strtonum(port, 0, 65535, &errmsg);
5856 if (errmsg)
5857 errx(1, "wgport: %s, %s", port, errmsg);
5858}
5859
5860void
5861setwgkey(const char *private_b64, int param)
5862{
5863 ensurewginterface();
5864 wg_interface->i_flags |= WG_INTERFACE_HAS_PRIVATE(1 << 1);
5865 WG_LOAD_KEY(wg_interface->i_private, private_b64, "wgkey")do { uint8_t _tmp[32]; int _r; if (strlen(private_b64) != (4 *
((32 + 2) / 3))) errx(1, "wgkey" " (key): invalid length"); if
((_r = __b64_pton(private_b64, _tmp, sizeof(_tmp))) != sizeof
(_tmp)) errx(1, "wgkey" " (key): invalid base64 %d/%zu", _r, sizeof
(_tmp)); memcpy(wg_interface->i_private, _tmp, 32); } while
(0)
;
5866}
5867
5868void
5869setwgrtable(const char *id, int param)
5870{
5871 const char *errmsg = NULL((void*)0);
5872 ensurewginterface();
5873 wg_interface->i_flags |= WG_INTERFACE_HAS_RTABLE(1 << 3);
5874 wg_interface->i_rtable = strtonum(id, 0, RT_TABLEID_MAX255, &errmsg);
5875 if (errmsg)
5876 errx(1, "wgrtable %s: %s", id, errmsg);
5877}
5878
5879void
5880unsetwgpeer(const char *peerkey_b64, int param)
5881{
5882 setwgpeer(peerkey_b64, param);
5883 wg_peer->p_flags |= WG_PEER_REMOVE(1 << 5);
5884}
5885
5886void
5887unsetwgpeerpsk(const char *value, int param)
5888{
5889 if (wg_peer == NULL((void*)0))
5890 errx(1, "wgpsk: wgpeer not set");
5891 wg_peer->p_flags |= WG_PEER_HAS_PSK(1 << 1);
5892 bzero(wg_peer->p_psk, WG_KEY_LEN32);
5893}
5894
5895void
5896unsetwgpeerall(const char *value, int param)
5897{
5898 ensurewginterface();
5899 wg_interface->i_flags |= WG_INTERFACE_REPLACE_PEERS(1 << 4);
5900}
5901
5902void
5903process_wg_commands(void)
5904{
5905 if (actions & A_WIREGUARD0x0040) {
5906 strlcpy(wgdata.wgd_name, ifname, sizeof(wgdata.wgd_name));
5907
5908 if (ioctl(sock, SIOCSWG(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct wg_data_io) & 0x1fff) << 16) | ((('i')) <<
8) | ((210)))
, (caddr_t)&wgdata) == -1)
5909 err(1, "SIOCSWG");
5910 }
5911}
5912
5913void
5914wg_status(void)
5915{
5916 size_t i, j, last_size;
5917 struct timespec now;
5918 char hbuf[NI_MAXHOST256], sbuf[NI_MAXSERV32];
5919 char key[WG_BASE64_KEY_LEN(4 * ((32 + 2) / 3)) + 1];
5920
5921 strlcpy(wgdata.wgd_name, ifname, sizeof(wgdata.wgd_name));
5922 wgdata.wgd_size = 0;
5923 wgdata.wgd_interface = NULL((void*)0);
5924 for (last_size = wgdata.wgd_size;; last_size = wgdata.wgd_size) {
5925 if (ioctl(sock, SIOCGWG(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct wg_data_io) & 0x1fff) << 16) | ((('i')) <<
8) | ((211)))
, (caddr_t)&wgdata) < 0) {
5926 if (errno(*__errno()) == ENOTTY25)
5927 goto out;
5928 err(1, "SIOCGWG");
5929 }
5930 if (last_size >= wgdata.wgd_size)
5931 break;
5932 wgdata.wgd_interface = realloc(wgdata.wgd_interface,
5933 wgdata.wgd_size);
5934 if (!wgdata.wgd_interface)
5935 err(1, "realloc");
5936 }
5937 wg_interface = wgdata.wgd_interface;
5938
5939 if (wg_interface->i_flags & WG_INTERFACE_HAS_PORT(1 << 2))
5940 printf("\twgport %hu\n", wg_interface->i_port);
5941 if (wg_interface->i_flags & WG_INTERFACE_HAS_RTABLE(1 << 3))
5942 printf("\twgrtable %d\n", wg_interface->i_rtable);
5943 if (wg_interface->i_flags & WG_INTERFACE_HAS_PUBLIC(1 << 0)) {
5944 b64_ntop__b64_ntop(wg_interface->i_public, WG_KEY_LEN32,
5945 key, sizeof(key));
5946 printf("\twgpubkey %s\n", key);
5947 }
5948
5949 wg_peer = &wg_interface->i_peers[0];
5950 for (i = 0; i < wg_interface->i_peers_count; i++) {
5951 b64_ntop__b64_ntop(wg_peer->p_public, WG_KEY_LEN32,
5952 key, sizeof(key));
5953 printf("\twgpeer %s\n", key);
5954
5955 if (wg_peer->p_flags & WG_PEER_HAS_PSK(1 << 1))
5956 printf("\t\twgpsk (present)\n");
5957
5958 if (wg_peer->p_flags & WG_PEER_HAS_PKA(1 << 2) && wg_peer->p_pka)
5959 printf("\t\twgpka %u (sec)\n", wg_peer->p_pka);
5960
5961 if (wg_peer->p_flags & WG_PEER_HAS_ENDPOINT(1 << 3)) {
5962 if (getnameinfo(&wg_peer->p_sap_endpoint.sa_sa, wg_peer->p_sap_endpoint.sa_sa.sa_len,
5963 hbuf, sizeof(hbuf), sbuf, sizeof(sbuf),
5964 NI_NUMERICHOST1 | NI_NUMERICSERV2) == 0)
5965 printf("\t\twgendpoint %s %s\n", hbuf, sbuf);
5966 else
5967 printf("\t\twgendpoint unable to print\n");
5968 }
5969
5970 printf("\t\ttx: %llu, rx: %llu\n",
5971 wg_peer->p_txbytes, wg_peer->p_rxbytes);
5972
5973 if (wg_peer->p_last_handshake.tv_sec != 0) {
5974 timespec_get(&now, TIME_UTC1);
5975 printf("\t\tlast handshake: %lld seconds ago\n",
5976 now.tv_sec - wg_peer->p_last_handshake.tv_sec);
5977 }
5978
5979
5980 wg_aip = &wg_peer->p_aips[0];
5981 for (j = 0; j < wg_peer->p_aips_count; j++) {
5982 inet_ntop(wg_aip->a_af, &wg_aip->a_addr,
5983 hbuf, sizeof(hbuf));
5984 printf("\t\twgaip %s/%d\n", hbuf, wg_aip->a_cidr);
5985 wg_aip++;
5986 }
5987 wg_peer = (struct wg_peer_io *)wg_aip;
5988 }
5989out:
5990 free(wgdata.wgd_interface);
5991}
5992
5993const struct umb_valdescr umb_regstate[] = MBIM_REGSTATE_DESCRIPTIONS{ { 0, "unknown" }, { 1, "not registered" }, { 2, "searching"
}, { 3, "home network" }, { 4, "roaming network" }, { 5, "partner network"
}, { 6, "access denied" }, { 0, ((void*)0) } }
;
5994const struct umb_valdescr umb_dataclass[] = MBIM_DATACLASS_DESCRIPTIONS{ { 0x00000000, "none" }, { 0x00000001, "GPRS" }, { 0x00000002
, "EDGE" }, { 0x00000004, "UMTS" }, { 0x00000008, "HSDPA" }, {
0x00000010, "HSUPA" }, { 0x00000008|0x00000010, "HSPA" }, { 0x00000020
, "LTE" }, { 0x00010000, "CDMA2000" }, { 0x00020000, "CDMA2000"
}, { 0x00040000, "CDMA2000" }, { 0x00080000, "CDMA2000" }, {
0x00100000, "CDMA2000" }, { 0x00200000, "CDMA2000" }, { 0x00400000
, "CDMA2000" }, { 0x80000000, "custom" }, { 0, ((void*)0) } }
;
5995const struct umb_valdescr umb_simstate[] = MBIM_SIMSTATE_DESCRIPTIONS{ { 0, "not initialized" }, { 1, "initialized" }, { 2, "not inserted"
}, { 3, "bad type" }, { 4, "failed" }, { 5, "not activated" }
, { 6, "locked" }, { 0, ((void*)0) } }
;
5996const struct umb_valdescr umb_istate[] = UMB_INTERNAL_STATE_DESCRIPTIONS{ { UMB_S_DOWN, "down" }, { UMB_S_OPEN, "open" }, { UMB_S_CID
, "CID allocated" }, { UMB_S_RADIO, "radio on" }, { UMB_S_SIMREADY
, "SIM is ready" }, { UMB_S_ATTACHED, "attached" }, { UMB_S_CONNECTED
, "connected" }, { UMB_S_UP, "up" }, { 0, ((void*)0) } }
;
5997const struct umb_valdescr umb_pktstate[] = MBIM_PKTSRV_STATE_DESCRIPTIONS{ { 0, "unknown" }, { 1, "attaching" }, { 2, "attached" }, { 3
, "detaching" }, { 4, "detached" }, { 0, ((void*)0) } }
;
5998const struct umb_valdescr umb_actstate[] = MBIM_ACTIVATION_STATE_DESCRIPTIONS{ { 0, "unknown" }, { 1, "activated" }, { 2, "activating" }, {
3, "deactivated" }, { 4, "deactivating" }, { 0, ((void*)0) }
}
;
5999
6000const struct umb_valdescr umb_classalias[] = {
6001 { MBIM_DATACLASS_GPRS0x00000001 | MBIM_DATACLASS_EDGE0x00000002, "2g" },
6002 { MBIM_DATACLASS_UMTS0x00000004 | MBIM_DATACLASS_HSDPA0x00000008 | MBIM_DATACLASS_HSUPA0x00000010,
6003 "3g" },
6004 { MBIM_DATACLASS_LTE0x00000020, "4g" },
6005 { 0, NULL((void*)0) }
6006};
6007
6008static int
6009umb_descr2val(const struct umb_valdescr *vdp, char *str)
6010{
6011 while (vdp->descr != NULL((void*)0)) {
6012 if (!strcasecmp(vdp->descr, str))
6013 return vdp->val;
6014 vdp++;
6015 }
6016 return 0;
6017}
6018
6019void
6020umb_status(void)
6021{
6022 struct umb_info mi;
6023 char provider[UMB_PROVIDERNAME_MAXLEN20+1];
6024 char providerid[UMB_PROVIDERID_MAXLEN20+1];
6025 char roamingtxt[UMB_ROAMINGTEXT_MAXLEN63+1];
6026 char devid[UMB_DEVID_MAXLEN18+1];
6027 char fwinfo[UMB_FWINFO_MAXLEN30+1];
6028 char hwinfo[UMB_HWINFO_MAXLEN30+1];
6029 char sid[UMB_SUBSCRIBERID_MAXLEN15+1];
6030 char iccid[UMB_ICCID_MAXLEN20+1];
6031 char apn[UMB_APN_MAXLEN100+1];
6032 char pn[UMB_PHONENR_MAXLEN22+1];
6033 int i, n;
6034 char astr[INET6_ADDRSTRLEN46];
6035
6036 memset((char *)&mi, 0, sizeof(mi));
6037 ifr.ifr_dataifr_ifru.ifru_data = (caddr_t)&mi;
6038 if (ioctl(sock, SIOCGUMBINFO(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((190)))
, (caddr_t)&ifr) == -1)
6039 return;
6040
6041 if (mi.nwerror) {
6042 /* 3GPP 24.008 Cause Code */
6043 printf("\terror: ");
6044 switch (mi.nwerror) {
6045 case 2:
6046 printf("SIM not activated");
6047 break;
6048 case 4:
6049 printf("Roaming not supported");
6050 break;
6051 case 6:
6052 printf("SIM reported stolen");
6053 break;
6054 case 7:
6055 printf("No GPRS subscription");
6056 break;
6057 case 8:
6058 printf("GPRS and non-GPRS services not allowed");
6059 break;
6060 case 11:
6061 printf("Subscription expired");
6062 break;
6063 case 12:
6064 printf("Subscription does not cover current location");
6065 break;
6066 case 13:
6067 printf("No roaming in this location");
6068 break;
6069 case 14:
6070 printf("GPRS not supported");
6071 break;
6072 case 15:
6073 printf("No subscription for the service");
6074 break;
6075 case 17:
6076 printf("Registration failed");
6077 break;
6078 case 22:
6079 printf("Network congestion");
6080 break;
6081 default:
6082 printf("Error code %d", mi.nwerror);
6083 break;
6084 }
6085 printf("\n");
6086 }
6087
6088 printf("\troaming %s registration %s",
6089 mi.enable_roaming ? "enabled" : "disabled",
6090 umb_val2descr(umb_regstate, mi.regstate));
6091 utf16_to_char(mi.roamingtxt, UMB_ROAMINGTEXT_MAXLEN63,
6092 roamingtxt, sizeof (roamingtxt));
6093 if (roamingtxt[0])
6094 printf(" [%s]", roamingtxt);
6095 printf("\n");
6096
6097 if (showclasses)
6098 umb_printclasses("available classes", mi.supportedclasses);
6099 printf("\tstate %s cell-class %s",
6100 umb_val2descr(umb_istate, mi.state),
6101 umb_val2descr(umb_dataclass, mi.highestclass));
6102 if (mi.rssi != UMB_VALUE_UNKNOWN-999 && mi.rssi != 0)
6103 printf(" rssi %ddBm", mi.rssi);
6104 if (mi.uplink_speed != 0 || mi.downlink_speed != 0) {
6105 char s[2][FMT_SCALED_STRSIZE7];
6106 if (fmt_scaled(mi.uplink_speed, s[0]) != 0)
6107 snprintf(s[0], sizeof (s[0]), "%llu", mi.uplink_speed);
6108 if (fmt_scaled(mi.downlink_speed, s[1]) != 0)
6109 snprintf(s[1], sizeof (s[1]), "%llu", mi.downlink_speed);
6110 printf(" speed %sbps up %sbps down", s[0], s[1]);
6111 }
6112 printf("\n");
6113
6114 printf("\tSIM %s PIN ", umb_val2descr(umb_simstate, mi.sim_state));
6115 switch (mi.pin_state) {
6116 case UMB_PIN_REQUIRED0:
6117 printf("required");
6118 break;
6119 case UMB_PIN_UNLOCKED1:
6120 printf("valid");
6121 break;
6122 case UMB_PUK_REQUIRED2:
6123 printf("locked (PUK required)");
6124 break;
6125 default:
6126 printf("unknown state (%d)", mi.pin_state);
6127 break;
6128 }
6129 if (mi.pin_attempts_left != UMB_VALUE_UNKNOWN-999)
6130 printf(" (%d attempts left)", mi.pin_attempts_left);
6131 printf("\n");
6132
6133 utf16_to_char(mi.sid, UMB_SUBSCRIBERID_MAXLEN15, sid, sizeof (sid));
6134 utf16_to_char(mi.iccid, UMB_ICCID_MAXLEN20, iccid, sizeof (iccid));
6135 utf16_to_char(mi.provider, UMB_PROVIDERNAME_MAXLEN20,
6136 provider, sizeof (provider));
6137 utf16_to_char(mi.providerid, UMB_PROVIDERID_MAXLEN20,
6138 providerid, sizeof (providerid));
6139 if (sid[0] || iccid[0]) {
6140 printf("\t");
6141 n = 0;
6142 if (sid[0])
6143 printf("%ssubscriber-id %s", n++ ? " " : "", sid);
6144 if (iccid[0])
6145 printf("%sICC-id %s", n++ ? " " : "", iccid);
6146 printf("\n");
6147 }
6148
6149 utf16_to_char(mi.hwinfo, UMB_HWINFO_MAXLEN30, hwinfo, sizeof (hwinfo));
6150 utf16_to_char(mi.devid, UMB_DEVID_MAXLEN18, devid, sizeof (devid));
6151 utf16_to_char(mi.fwinfo, UMB_FWINFO_MAXLEN30, fwinfo, sizeof (fwinfo));
6152 if (hwinfo[0] || devid[0] || fwinfo[0]) {
6153 printf("\t");
6154 n = 0;
6155 if (hwinfo[0])
6156 printf("%sdevice %s", n++ ? " " : "", hwinfo);
6157 if (devid[0]) {
6158 printf("%s", n++ ? " " : "");
6159 switch (mi.cellclass) {
6160 case MBIM_CELLCLASS_GSM0x00000001:
6161 printf("IMEI");
6162 break;
6163 case MBIM_CELLCLASS_CDMA0x00000002:
6164 n = strlen(devid);
6165 if (n == 8 || n == 11) {
6166 printf("ESN");
6167 break;
6168 } else if (n == 14 || n == 18) {
6169 printf("MEID");
6170 break;
6171 }
6172 /*FALLTHROUGH*/
6173 default:
6174 printf("ID");
6175 break;
6176 }
6177 printf(" %s", devid);
6178 }
6179 if (fwinfo[0])
6180 printf("%sfirmware %s", n++ ? " " : "", fwinfo);
6181 printf("\n");
6182 }
6183
6184 utf16_to_char(mi.pn, UMB_PHONENR_MAXLEN22, pn, sizeof (pn));
6185 utf16_to_char(mi.apn, UMB_APN_MAXLEN100, apn, sizeof (apn));
6186 if (pn[0] || apn[0] || provider[0] || providerid[0]) {
6187 printf("\t");
6188 n = 0;
6189 if (pn[0])
6190 printf("%sphone# %s", n++ ? " " : "", pn);
6191 if (apn[0])
6192 printf("%sAPN %s", n++ ? " " : "", apn);
6193 if (provider[0])
6194 printf("%sprovider %s", n++ ? " " : "", provider);
6195 if (providerid[0])
6196 printf("%sprovider-id %s", n ? " " : "", providerid);
6197 printf("\n");
6198 }
6199
6200 for (i = 0, n = 0; i < UMB_MAX_DNSSRV2; i++) {
6201 if (mi.ipv4dns[i].s_addr == INADDR_ANY((u_int32_t)(0x00000000)))
6202 break;
6203 printf("%s %s", n++ ? "" : "\tdns",
6204 inet_ntop(AF_INET2, &mi.ipv4dns[i], astr, sizeof(astr)));
6205 }
6206 for (i = 0; i < UMB_MAX_DNSSRV2; i++) {
6207 if (memcmp(&mi.ipv6dns[i], &in6addr_any,
6208 sizeof (mi.ipv6dns[i])) == 0)
6209 break;
6210 printf("%s %s", n++ ? "" : "\tdns",
6211 inet_ntop(AF_INET624, &mi.ipv6dns[i], astr, sizeof(astr)));
6212 }
6213 if (n)
6214 printf("\n");
6215}
6216
6217void
6218umb_printclasses(char *tag, int c)
6219{
6220 int i;
6221 char *sep = "";
6222
6223 printf("\t%s: ", tag);
6224 i = 0;
6225 while (umb_dataclass[i].descr) {
6226 if (umb_dataclass[i].val & c) {
6227 printf("%s%s", sep, umb_dataclass[i].descr);
6228 sep = ",";
6229 }
6230 i++;
6231 }
6232 printf("\n");
6233}
6234
6235int
6236umb_parse_classes(const char *spec)
6237{
6238 char *optlist, *str;
6239 int c = 0, v;
6240
6241 if ((optlist = strdup(spec)) == NULL((void*)0))
6242 err(1, "strdup");
6243 str = strtok(optlist, ",");
6244 while (str != NULL((void*)0)) {
6245 if ((v = umb_descr2val(umb_dataclass, str)) != 0 ||
6246 (v = umb_descr2val(umb_classalias, str)) != 0)
6247 c |= v;
6248 str = strtok(NULL((void*)0), ",");
6249 }
6250 free(optlist);
6251 return c;
6252}
6253
6254void
6255umb_setpin(const char *pin, int d)
6256{
6257 umb_pinop(MBIM_PIN_OP_ENTER0, 0, pin, NULL((void*)0));
6258}
6259
6260void
6261umb_chgpin(const char *pin, const char *newpin)
6262{
6263 umb_pinop(MBIM_PIN_OP_CHANGE3, 0, pin, newpin);
6264}
6265
6266void
6267umb_puk(const char *pin, const char *newpin)
6268{
6269 umb_pinop(MBIM_PIN_OP_ENTER0, 1, pin, newpin);
6270}
6271
6272void
6273umb_pinop(int op, int is_puk, const char *pin, const char *newpin)
6274{
6275 struct umb_parameter mp;
6276
6277 memset(&mp, 0, sizeof (mp));
6278 ifr.ifr_dataifr_ifru.ifru_data = (caddr_t)&mp;
6279 if (ioctl(sock, SIOCGUMBPARAM(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((192)))
, (caddr_t)&ifr) == -1)
6280 err(1, "SIOCGUMBPARAM");
6281
6282 mp.op = op;
6283 mp.is_puk = is_puk;
6284 if ((mp.pinlen = char_to_utf16(pin, (uint16_t *)mp.pin,
6285 sizeof (mp.pin))) == -1)
6286 errx(1, "PIN too long");
6287
6288 if (newpin) {
6289 if ((mp.newpinlen = char_to_utf16(newpin, (uint16_t *)mp.newpin,
6290 sizeof (mp.newpin))) == -1)
6291 errx(1, "new PIN too long");
6292 }
6293
6294 if (ioctl(sock, SIOCSUMBPARAM((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((191)))
, (caddr_t)&ifr) == -1)
6295 err(1, "SIOCSUMBPARAM");
6296}
6297
6298void
6299umb_apn(const char *apn, int d)
6300{
6301 struct umb_parameter mp;
6302
6303 memset(&mp, 0, sizeof (mp));
6304 ifr.ifr_dataifr_ifru.ifru_data = (caddr_t)&mp;
6305 if (ioctl(sock, SIOCGUMBPARAM(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((192)))
, (caddr_t)&ifr) == -1)
6306 err(1, "SIOCGUMBPARAM");
6307
6308 if (d != 0)
6309 memset(mp.apn, 0, sizeof (mp.apn));
6310 else if ((mp.apnlen = char_to_utf16(apn, mp.apn,
6311 sizeof (mp.apn))) == -1)
6312 errx(1, "APN too long");
6313
6314 if (ioctl(sock, SIOCSUMBPARAM((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((191)))
, (caddr_t)&ifr) == -1)
6315 err(1, "SIOCSUMBPARAM");
6316}
6317
6318void
6319umb_setclass(const char *val, int d)
6320{
6321 struct umb_parameter mp;
6322
6323 if (val == NULL((void*)0)) {
6324 if (showclasses)
6325 usage();
6326 showclasses = 1;
6327 return;
6328 }
6329
6330 memset(&mp, 0, sizeof (mp));
6331 ifr.ifr_dataifr_ifru.ifru_data = (caddr_t)&mp;
6332 if (ioctl(sock, SIOCGUMBPARAM(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((192)))
, (caddr_t)&ifr) == -1)
6333 err(1, "SIOCGUMBPARAM");
6334 if (d != -1)
6335 mp.preferredclasses = umb_parse_classes(val);
6336 else
6337 mp.preferredclasses = MBIM_DATACLASS_NONE0x00000000;
6338 if (ioctl(sock, SIOCSUMBPARAM((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((191)))
, (caddr_t)&ifr) == -1)
6339 err(1, "SIOCSUMBPARAM");
6340}
6341
6342void
6343umb_roaming(const char *val, int d)
6344{
6345 struct umb_parameter mp;
6346
6347 memset(&mp, 0, sizeof (mp));
6348 ifr.ifr_dataifr_ifru.ifru_data = (caddr_t)&mp;
6349 if (ioctl(sock, SIOCGUMBPARAM(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((192)))
, (caddr_t)&ifr) == -1)
6350 err(1, "SIOCGUMBPARAM");
6351 mp.roaming = d;
6352 if (ioctl(sock, SIOCSUMBPARAM((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((191)))
, (caddr_t)&ifr) == -1)
6353 err(1, "SIOCSUMBPARAM");
6354}
6355
6356void
6357utf16_to_char(uint16_t *in, int inlen, char *out, size_t outlen)
6358{
6359 uint16_t c;
6360
6361 while (outlen > 0) {
6362 c = inlen > 0 ? letoh16(*in)((__uint16_t)(*in)) : 0;
6363 if (c == 0 || --outlen == 0) {
6364 /* always NUL terminate result */
6365 *out = '\0';
6366 break;
6367 }
6368 *out++ = isascii(c) ? (char)c : '?';
6369 in++;
6370 inlen--;
6371 }
6372}
6373
6374int
6375char_to_utf16(const char *in, uint16_t *out, size_t outlen)
6376{
6377 int n = 0;
6378 uint16_t c;
6379
6380 for (;;) {
6381 c = *in++;
6382
6383 if (c == '\0') {
6384 /*
6385 * NUL termination is not required, but zero out the
6386 * residual buffer
6387 */
6388 memset(out, 0, outlen);
6389 return n;
6390 }
6391 if (outlen < sizeof (*out))
6392 return -1;
6393
6394 *out++ = htole16(c)((__uint16_t)(c));
6395 n += sizeof (*out);
6396 outlen -= sizeof (*out);
6397 }
6398}
6399
6400#endif
6401
6402#define SIN(x)((struct sockaddr_in *) &(x)) ((struct sockaddr_in *) &(x))
6403struct sockaddr_in *sintab[] = {
6404SIN(ridreq.ifr_addr)((struct sockaddr_in *) &(ridreq.ifr_ifru.ifru_addr)), SIN(in_addreq.ifra_addr)((struct sockaddr_in *) &(in_addreq.ifra_ifrau.ifrau_addr
))
,
6405SIN(in_addreq.ifra_mask)((struct sockaddr_in *) &(in_addreq.ifra_mask)), SIN(in_addreq.ifra_broadaddr)((struct sockaddr_in *) &(in_addreq.ifra_dstaddr))};
6406
6407void
6408in_getaddr(const char *s, int which)
6409{
6410 struct sockaddr_in *sin = sintab[which], tsin;
6411 struct hostent *hp;
6412 int bits, l;
6413 char p[3];
6414
6415 bzero(&tsin, sizeof(tsin));
6416 sin->sin_len = sizeof(*sin);
6417 if (which != MASK2)
6418 sin->sin_family = AF_INET2;
6419
6420 if (which == ADDR1 && strrchr(s, '/') != NULL((void*)0) &&
6421 (bits = inet_net_pton(AF_INET2, s, &tsin.sin_addr,
6422 sizeof(tsin.sin_addr))) != -1) {
6423 l = snprintf(p, sizeof(p), "%d", bits);
6424 if (l < 0 || l >= sizeof(p))
6425 errx(1, "%d: bad prefixlen", bits);
6426 in_getprefix(p, MASK2);
6427 memcpy(&sin->sin_addr, &tsin.sin_addr, sizeof(sin->sin_addr));
6428 } else if (inet_aton(s, &sin->sin_addr) == 0) {
6429 if ((hp = gethostbyname(s)))
6430 memcpy(&sin->sin_addr, hp->h_addrh_addr_list[0], hp->h_length);
6431 else
6432 errx(1, "%s: bad value", s);
6433 }
6434 if (which == MASK2 && (ntohl(sin->sin_addr.s_addr)(__uint32_t)(__builtin_constant_p(sin->sin_addr.s_addr) ? (
__uint32_t)(((__uint32_t)(sin->sin_addr.s_addr) & 0xff
) << 24 | ((__uint32_t)(sin->sin_addr.s_addr) & 0xff00
) << 8 | ((__uint32_t)(sin->sin_addr.s_addr) & 0xff0000
) >> 8 | ((__uint32_t)(sin->sin_addr.s_addr) & 0xff000000
) >> 24) : __swap32md(sin->sin_addr.s_addr))
&
6435 (~ntohl(sin->sin_addr.s_addr)(__uint32_t)(__builtin_constant_p(sin->sin_addr.s_addr) ? (
__uint32_t)(((__uint32_t)(sin->sin_addr.s_addr) & 0xff
) << 24 | ((__uint32_t)(sin->sin_addr.s_addr) & 0xff00
) << 8 | ((__uint32_t)(sin->sin_addr.s_addr) & 0xff0000
) >> 8 | ((__uint32_t)(sin->sin_addr.s_addr) & 0xff000000
) >> 24) : __swap32md(sin->sin_addr.s_addr))
>> 1)))
6436 errx(1, "%s: non-contiguous mask", s);
6437}
6438
6439/* ARGSUSED */
6440void
6441in_getprefix(const char *plen, int which)
6442{
6443 struct sockaddr_in *sin = sintab[which];
6444 const char *errmsg = NULL((void*)0);
6445 u_char *cp;
6446 int len;
6447
6448 len = strtonum(plen, 0, 32, &errmsg);
6449 if (errmsg)
6450 errx(1, "prefix %s: %s", plen, errmsg);
6451
6452 sin->sin_len = sizeof(*sin);
6453 if (which != MASK2)
6454 sin->sin_family = AF_INET2;
6455 if ((len == 0) || (len == 32)) {
6456 memset(&sin->sin_addr, 0xff, sizeof(struct in_addr));
6457 return;
6458 }
6459 memset((void *)&sin->sin_addr, 0x00, sizeof(sin->sin_addr));
6460 for (cp = (u_char *)&sin->sin_addr; len > 7; len -= 8)
6461 *cp++ = 0xff;
6462 if (len)
6463 *cp = 0xff << (8 - len);
6464}
6465
6466/*
6467 * Print a value a la the %b format of the kernel's printf
6468 */
6469void
6470printb(char *s, unsigned int v, unsigned char *bits)
6471{
6472 int i, any = 0;
6473 unsigned char c;
6474
6475 if (bits && *bits == 8)
6476 printf("%s=%o", s, v);
6477 else
6478 printf("%s=%x", s, v);
6479
6480 if (bits) {
6481 bits++;
6482 putchar('<')(!__isthreaded ? __sputc('<', (&__sF[1])) : (putc)('<'
, (&__sF[1])))
;
6483 while ((i = *bits++)) {
6484 if (v & (1 << (i-1))) {
6485 if (any)
6486 putchar(',')(!__isthreaded ? __sputc(',', (&__sF[1])) : (putc)(',', (
&__sF[1])))
;
6487 any = 1;
6488 for (; (c = *bits) > 32; bits++)
6489 putchar(c)(!__isthreaded ? __sputc(c, (&__sF[1])) : (putc)(c, (&
__sF[1])))
;
6490 } else
6491 for (; *bits > 32; bits++)
6492 ;
6493 }
6494 putchar('>')(!__isthreaded ? __sputc('>', (&__sF[1])) : (putc)('>'
, (&__sF[1])))
;
6495 }
6496}
6497
6498/*
6499 * A simple version of printb for status output
6500 */
6501void
6502printb_status(unsigned short v, unsigned char *bits)
6503{
6504 int i, any = 0;
6505 unsigned char c;
6506
6507 if (bits) {
6508 bits++;
6509 while ((i = *bits++)) {
6510 if (v & (1 << (i-1))) {
6511 if (any)
6512 putchar(',')(!__isthreaded ? __sputc(',', (&__sF[1])) : (putc)(',', (
&__sF[1])))
;
6513 any = 1;
6514 for (; (c = *bits) > 32; bits++)
6515 putchar(tolower(c))(!__isthreaded ? __sputc(tolower(c), (&__sF[1])) : (putc)
(tolower(c), (&__sF[1])))
;
6516 } else
6517 for (; *bits > 32; bits++)
6518 ;
6519 }
6520 }
6521}
6522
6523#define SIN6(x)((struct sockaddr_in6 *) &(x)) ((struct sockaddr_in6 *) &(x))
6524struct sockaddr_in6 *sin6tab[] = {
6525SIN6(in6_ridreq.ifr_addr)((struct sockaddr_in6 *) &(in6_ridreq.ifr_ifru.ifru_addr)
)
, SIN6(in6_addreq.ifra_addr)((struct sockaddr_in6 *) &(in6_addreq.ifra_ifrau.ifrau_addr
))
,
6526SIN6(in6_addreq.ifra_prefixmask)((struct sockaddr_in6 *) &(in6_addreq.ifra_prefixmask)), SIN6(in6_addreq.ifra_dstaddr)((struct sockaddr_in6 *) &(in6_addreq.ifra_dstaddr))};
6527
6528void
6529in6_getaddr(const char *s, int which)
6530{
6531 struct sockaddr_in6 *sin6 = sin6tab[which];
6532 struct addrinfo hints, *res;
6533 char buf[HOST_NAME_MAX255+1 + sizeof("/128")], *pfxlen;
6534 int error;
6535
6536 memset(&hints, 0, sizeof(hints));
6537 hints.ai_family = AF_INET624;
6538 hints.ai_socktype = SOCK_DGRAM2; /*dummy*/
6539
6540 if (which == ADDR1 && strchr(s, '/') != NULL((void*)0)) {
6541 if (strlcpy(buf, s, sizeof(buf)) >= sizeof(buf))
6542 errx(1, "%s: bad value", s);
6543 pfxlen = strchr(buf, '/');
6544 *pfxlen++ = '\0';
6545 s = buf;
6546 in6_getprefix(pfxlen, MASK2);
6547 explicit_prefix = 1;
6548 }
6549
6550 error = getaddrinfo(s, "0", &hints, &res);
6551 if (error)
6552 errx(1, "%s: %s", s, gai_strerror(error));
6553 memcpy(sin6, res->ai_addr, res->ai_addrlen);
6554#ifdef __KAME__
6555 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)(((&sin6->sin6_addr)->__u6_addr.__u6_addr8[0] == 0xfe
) && (((&sin6->sin6_addr)->__u6_addr.__u6_addr8
[1] & 0xc0) == 0x80))
&&
6556 *(u_int16_t *)&sin6->sin6_addr.s6_addr__u6_addr.__u6_addr8[2] == 0 &&
6557 sin6->sin6_scope_id) {
6558 *(u_int16_t *)&sin6->sin6_addr.s6_addr__u6_addr.__u6_addr8[2] =
6559 htons(sin6->sin6_scope_id & 0xffff)(__uint16_t)(__builtin_constant_p(sin6->sin6_scope_id &
0xffff) ? (__uint16_t)(((__uint16_t)(sin6->sin6_scope_id &
0xffff) & 0xffU) << 8 | ((__uint16_t)(sin6->sin6_scope_id
& 0xffff) & 0xff00U) >> 8) : __swap16md(sin6->
sin6_scope_id & 0xffff))
;
6560 sin6->sin6_scope_id = 0;
6561 }
6562#endif /* __KAME__ */
6563 freeaddrinfo(res);
6564}
6565
6566void
6567in6_getprefix(const char *plen, int which)
6568{
6569 struct sockaddr_in6 *sin6 = sin6tab[which];
6570 const char *errmsg = NULL((void*)0);
6571 u_char *cp;
6572 int len;
6573
6574 len = strtonum(plen, 0, 128, &errmsg);
6575 if (errmsg)
6576 errx(1, "prefix %s: %s", plen, errmsg);
6577
6578 sin6->sin6_len = sizeof(*sin6);
6579 if (which != MASK2)
6580 sin6->sin6_family = AF_INET624;
6581 if ((len == 0) || (len == 128)) {
6582 memset(&sin6->sin6_addr, 0xff, sizeof(struct in6_addr));
6583 return;
6584 }
6585 memset((void *)&sin6->sin6_addr, 0x00, sizeof(sin6->sin6_addr));
6586 for (cp = (u_char *)&sin6->sin6_addr; len > 7; len -= 8)
6587 *cp++ = 0xff;
6588 if (len)
6589 *cp = 0xff << (8 - len);
6590}
6591
6592int
6593prefix(void *val, int size)
6594{
6595 u_char *nam = (u_char *)val;
6596 int byte, bit, plen = 0;
6597
6598 for (byte = 0; byte < size; byte++, plen += 8)
6599 if (nam[byte] != 0xff)
6600 break;
6601 if (byte == size)
6602 return (plen);
6603 for (bit = 7; bit != 0; bit--, plen++)
6604 if (!(nam[byte] & (1 << bit)))
6605 break;
6606 for (; bit != 0; bit--)
6607 if (nam[byte] & (1 << bit))
6608 return (0);
6609 byte++;
6610 for (; byte < size; byte++)
6611 if (nam[byte])
6612 return (0);
6613 return (plen);
6614}
6615
6616/* Print usage and exit */
6617__dead__attribute__((__noreturn__)) void
6618usage(void)
6619{
6620 fprintf(stderr(&__sF[2]),
6621 "usage: ifconfig [-AaC] [interface] [address_family] "
6622 "[address [dest_address]]\n"
6623 "\t\t[parameters]\n");
6624 exit(1);
6625}
6626
6627void
6628getifgroups(void)
6629{
6630 int len, cnt;
6631 struct ifgroupreq ifgr;
6632 struct ifg_req *ifg;
6633
6634 memset(&ifgr, 0, sizeof(ifgr));
6635 strlcpy(ifgr.ifgr_name, ifname, IFNAMSIZ16);
6636
6637 if (ioctl(sock, SIOCGIFGROUP(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifgroupreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((136)))
, (caddr_t)&ifgr) == -1) {
6638 if (errno(*__errno()) == EINVAL22 || errno(*__errno()) == ENOTTY25)
6639 return;
6640 else
6641 err(1, "SIOCGIFGROUP");
6642 }
6643
6644 len = ifgr.ifgr_len;
6645 ifgr.ifgr_groupsifgr_ifgru.ifgru_groups = calloc(len / sizeof(struct ifg_req),
6646 sizeof(struct ifg_req));
6647 if (ifgr.ifgr_groupsifgr_ifgru.ifgru_groups == NULL((void*)0))
6648 err(1, "getifgroups");
6649 if (ioctl(sock, SIOCGIFGROUP(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifgroupreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((136)))
, (caddr_t)&ifgr) == -1)
6650 err(1, "SIOCGIFGROUP");
6651
6652 cnt = 0;
6653 ifg = ifgr.ifgr_groupsifgr_ifgru.ifgru_groups;
6654 for (; ifg && len >= sizeof(struct ifg_req); ifg++) {
6655 len -= sizeof(struct ifg_req);
6656 if (strcmp(ifg->ifgrq_groupifgrq_ifgrqu.ifgrqu_group, "all")) {
6657 if (cnt == 0)
6658 printf("\tgroups:");
6659 cnt++;
6660 printf(" %s", ifg->ifgrq_groupifgrq_ifgrqu.ifgrqu_group);
6661 }
6662 }
6663 if (cnt)
6664 printf("\n");
6665
6666 free(ifgr.ifgr_groupsifgr_ifgru.ifgru_groups);
6667}
6668
6669#ifndef SMALL
6670void
6671printifhwfeatures(const char *unused, int show)
6672{
6673 struct if_data ifrdat;
6674
6675 if (!show) {
6676 if (showcapsflag)
6677 usage();
6678 showcapsflag = 1;
6679 return;
6680 }
6681 bzero(&ifrdat, sizeof(ifrdat));
6682 ifr.ifr_dataifr_ifru.ifru_data = (caddr_t)&ifrdat;
6683 if (ioctl(sock, SIOCGIFDATA(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((27)))
, (caddr_t)&ifr) == -1)
6684 err(1, "SIOCGIFDATA");
6685 printb("\thwfeatures", (u_int)ifrdat.ifi_capabilities, HWFEATURESBITS"\024\1CSUM_IPv4\2CSUM_TCPv4\3CSUM_UDPv4" "\5VLAN_MTU\6VLAN_HWTAGGING\10CSUM_TCPv6"
"\11CSUM_UDPv6\20WOL"
);
6686
6687 if (ioctl(sock, SIOCGIFHARDMTU(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((165)))
, (caddr_t)&ifr) != -1) {
6688 if (ifr.ifr_hardmtuifr_ifru.ifru_metric)
6689 printf(" hardmtu %u", ifr.ifr_hardmtuifr_ifru.ifru_metric);
6690 }
6691 putchar('\n')(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n',
(&__sF[1])))
;
6692}
6693#endif
6694
6695char *
6696sec2str(time_t total)
6697{
6698 static char result[256];
6699 char *p = result;
6700 char *end = &result[sizeof(result)];
6701
6702 snprintf(p, end - p, "%lld", (long long)total);
6703 return (result);
6704}
6705
6706/*ARGSUSED*/
6707void
6708setiflladdr(const char *addr, int param)
6709{
6710 struct ether_addr *eap, eabuf;
6711
6712 if (!strcmp(addr, "random")) {
6713 arc4random_buf(&eabuf, sizeof eabuf);
6714 /* Non-multicast and claim it is a hardware address */
6715 eabuf.ether_addr_octet[0] &= 0xfc;
6716 eap = &eabuf;
6717 } else {
6718 eap = ether_aton(addr);
6719 if (eap == NULL((void*)0)) {
6720 warnx("malformed link-level address");
6721 return;
6722 }
6723 }
6724 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
6725 ifr.ifr_addrifr_ifru.ifru_addr.sa_len = ETHER_ADDR_LEN6;
6726 ifr.ifr_addrifr_ifru.ifru_addr.sa_family = AF_LINK18;
6727 bcopy(eap, ifr.ifr_addrifr_ifru.ifru_addr.sa_data, ETHER_ADDR_LEN6);
6728 if (ioctl(sock, SIOCSIFLLADDR((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((31)))
, (caddr_t)&ifr) == -1)
6729 warn("SIOCSIFLLADDR");
6730}
6731
6732#ifndef SMALL
6733void
6734setrdomain(const char *id, int param)
6735{
6736 const char *errmsg = NULL((void*)0);
6737 int rdomainid;
6738
6739 rdomainid = strtonum(id, 0, RT_TABLEID_MAX255, &errmsg);
6740 if (errmsg)
6741 errx(1, "rdomain %s: %s", id, errmsg);
6742
6743 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
6744 ifr.ifr_rdomainidifr_ifru.ifru_metric = rdomainid;
6745 if (ioctl(sock, SIOCSIFRDOMAIN((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((159)))
, (caddr_t)&ifr) == -1)
6746 warn("SIOCSIFRDOMAIN");
6747}
6748
6749void
6750unsetrdomain(const char *ignored, int alsoignored)
6751{
6752 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
6753 ifr.ifr_rdomainidifr_ifru.ifru_metric = 0;
6754 if (ioctl(sock, SIOCSIFRDOMAIN((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((159)))
, (caddr_t)&ifr) == -1)
6755 warn("SIOCSIFRDOMAIN");
6756}
6757#endif
6758
6759#ifndef SMALL
6760void
6761setpair(const char *val, int d)
6762{
6763 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
6764 if ((ifr.ifr_indexifr_ifru.ifru_index = if_nametoindex(val)) == 0) {
6765 errno(*__errno()) = ENOENT2;
6766 err(1, "patch %s", val);
6767 }
6768 if (ioctl(sock, SIOCSIFPAIR((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((176)))
, (caddr_t)&ifr) == -1)
6769 warn("SIOCSIFPAIR");
6770}
6771
6772void
6773unsetpair(const char *val, int d)
6774{
6775 ifr.ifr_indexifr_ifru.ifru_index = 0;
6776 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
6777 if (ioctl(sock, SIOCSIFPAIR((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((176)))
, (caddr_t)&ifr) == -1)
6778 warn("SIOCSIFPAIR");
6779}
6780#endif
6781
6782#ifdef SMALL
6783void
6784setignore(const char *id, int param)
6785{
6786 /* just digest the command */
6787}
6788#endif