File: | src/sbin/ifconfig/ifconfig.c |
Warning: | line 912, column 6 Called function pointer is null (null dereference) |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 | |||||
127 | struct 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 | |||||
149 | struct ifreq ifr, ridreq; | ||||
150 | struct in_aliasreq in_addreq; | ||||
151 | struct in6_ifreq ifr6; | ||||
152 | struct in6_ifreq in6_ridreq; | ||||
153 | struct in6_aliasreq in6_addreq; | ||||
154 | struct sockaddr_in netmask; | ||||
155 | |||||
156 | #ifndef SMALL | ||||
157 | struct ifaliasreq addreq; | ||||
158 | |||||
159 | int wconfig = 0; | ||||
160 | int wcwconfig = 0; | ||||
161 | int rdomainid; | ||||
162 | #endif /* SMALL */ | ||||
163 | |||||
164 | char ifname[IFNAMSIZ16]; | ||||
165 | int flags, xflags, setaddr, setipdst, doalias; | ||||
166 | u_long metric, mtu; | ||||
167 | int llprio; | ||||
168 | int clearaddr, sock; | ||||
169 | int newaddr = 0; | ||||
170 | int af = AF_INET2; | ||||
171 | int explicit_prefix = 0; | ||||
172 | int Lflag = 1; | ||||
173 | int show_join = 0; | ||||
174 | |||||
175 | int showmediaflag; | ||||
176 | int showcapsflag; | ||||
177 | int shownet80211chans; | ||||
178 | int shownet80211nodes; | ||||
179 | int showclasses; | ||||
180 | int showtransceiver; | ||||
181 | |||||
182 | struct ifencap; | ||||
183 | |||||
184 | struct ieee80211_join join; | ||||
185 | |||||
186 | const char *lacpmodeactive = "active"; | ||||
187 | const char *lacpmodepassive = "passive"; | ||||
188 | const char *lacptimeoutfast = "fast"; | ||||
189 | const char *lacptimeoutslow = "slow"; | ||||
190 | |||||
191 | void notealias(const char *, int); | ||||
192 | void setifaddr(const char *, int); | ||||
193 | void setiflladdr(const char *, int); | ||||
194 | void setifdstaddr(const char *, int); | ||||
195 | void setifflags(const char *, int); | ||||
196 | void setifxflags(const char *, int); | ||||
197 | void addaf(const char *, int); | ||||
198 | void removeaf(const char *, int); | ||||
199 | void setifbroadaddr(const char *, int); | ||||
200 | void setifmtu(const char *, int); | ||||
201 | void setifllprio(const char *, int); | ||||
202 | void setifnwid(const char *, int); | ||||
203 | void setifjoin(const char *, int); | ||||
204 | void delifjoin(const char *, int); | ||||
205 | void delifjoinlist(const char *, int); | ||||
206 | void showjoin(const char *, int); | ||||
207 | void setifbssid(const char *, int); | ||||
208 | void setifnwkey(const char *, int); | ||||
209 | void setifwpa(const char *, int); | ||||
210 | void setifwpaprotos(const char *, int); | ||||
211 | void setifwpaakms(const char *, int); | ||||
212 | void setifwpaciphers(const char *, int); | ||||
213 | void setifwpagroupcipher(const char *, int); | ||||
214 | void setifwpakey(const char *, int); | ||||
215 | void setifchan(const char *, int); | ||||
216 | void setifscan(const char *, int); | ||||
217 | void setifnwflag(const char *, int); | ||||
218 | void unsetifnwflag(const char *, int); | ||||
219 | void setifnetmask(const char *, int); | ||||
220 | void setifprefixlen(const char *, int); | ||||
221 | void setvnetid(const char *, int); | ||||
222 | void delvnetid(const char *, int); | ||||
223 | void getvnetid(struct ifencap *); | ||||
224 | void setifparent(const char *, int); | ||||
225 | void delifparent(const char *, int); | ||||
226 | void getifparent(struct ifencap *); | ||||
227 | void getencap(void); | ||||
228 | void setia6flags(const char *, int); | ||||
229 | void setia6pltime(const char *, int); | ||||
230 | void setia6vltime(const char *, int); | ||||
231 | void setia6lifetime(const char *, const char *); | ||||
232 | void setia6eui64(const char *, int); | ||||
233 | void setmedia(const char *, int); | ||||
234 | void setmediaopt(const char *, int); | ||||
235 | void setmediamode(const char *, int); | ||||
236 | void unsetmediamode(const char *, int); | ||||
237 | void clone_create(const char *, int); | ||||
238 | void clone_destroy(const char *, int); | ||||
239 | void unsetmediaopt(const char *, int); | ||||
240 | void setmediainst(const char *, int); | ||||
241 | int prefix(void *val, int); | ||||
242 | void getifgroups(void); | ||||
243 | void setifgroup(const char *, int); | ||||
244 | void unsetifgroup(const char *, int); | ||||
245 | void setgroupattribs(char *, int, char *[]); | ||||
246 | int printgroup(char *, int); | ||||
247 | void setautoconf(const char *, int); | ||||
248 | void settemporary(const char *, int); | ||||
249 | void settrunkport(const char *, int); | ||||
250 | void unsettrunkport(const char *, int); | ||||
251 | void settrunkproto(const char *, int); | ||||
252 | void settrunklacpmode(const char *, int); | ||||
253 | void settrunklacptimeout(const char *, int); | ||||
254 | void trunk_status(void); | ||||
255 | void list_cloners(void); | ||||
256 | |||||
257 | #ifndef SMALL | ||||
258 | void setifrtlabel(const char *, int); | ||||
259 | void setrdomain(const char *, int); | ||||
260 | void unsetrdomain(const char *, int); | ||||
261 | void setkeepalive(const char *, const char *); | ||||
262 | void unsetkeepalive(const char *, int); | ||||
263 | void carp_status(void); | ||||
264 | void setcarp_advbase(const char *,int); | ||||
265 | void setcarp_advskew(const char *, int); | ||||
266 | void setcarppeer(const char *, int); | ||||
267 | void unsetcarppeer(const char *, int); | ||||
268 | void setcarp_passwd(const char *, int); | ||||
269 | void setcarp_vhid(const char *, int); | ||||
270 | void setcarp_state(const char *, int); | ||||
271 | void setcarpdev(const char *, int); | ||||
272 | void setcarp_nodes(const char *, int); | ||||
273 | void setcarp_balancing(const char *, int); | ||||
274 | void setpfsync_syncdev(const char *, int); | ||||
275 | void setpfsync_maxupd(const char *, int); | ||||
276 | void unsetpfsync_syncdev(const char *, int); | ||||
277 | void setpfsync_syncpeer(const char *, int); | ||||
278 | void unsetpfsync_syncpeer(const char *, int); | ||||
279 | void setpfsync_defer(const char *, int); | ||||
280 | void pfsync_status(void); | ||||
281 | void setvnetflowid(const char *, int); | ||||
282 | void delvnetflowid(const char *, int); | ||||
283 | void getvnetflowid(struct ifencap *); | ||||
284 | void gettxprio(struct ifencap *); | ||||
285 | void settxprio(const char *, int); | ||||
286 | void getrxprio(struct ifencap *); | ||||
287 | void setrxprio(const char *, int); | ||||
288 | void setmplslabel(const char *, int); | ||||
289 | void unsetmplslabel(const char *, int); | ||||
290 | void setpwe3cw(const char *, int); | ||||
291 | void unsetpwe3cw(const char *, int); | ||||
292 | void setpwe3fat(const char *, int); | ||||
293 | void unsetpwe3fat(const char *, int); | ||||
294 | void setpwe3neighbor(const char *, const char *); | ||||
295 | void unsetpwe3neighbor(const char *, int); | ||||
296 | void mpls_status(void); | ||||
297 | void settunnel(const char *, const char *); | ||||
298 | void settunneladdr(const char *, int); | ||||
299 | void deletetunnel(const char *, int); | ||||
300 | void settunnelinst(const char *, int); | ||||
301 | void unsettunnelinst(const char *, int); | ||||
302 | void settunnelttl(const char *, int); | ||||
303 | void settunneldf(const char *, int); | ||||
304 | void settunnelnodf(const char *, int); | ||||
305 | void settunnelecn(const char *, int); | ||||
306 | void settunnelnoecn(const char *, int); | ||||
307 | void setpppoe_dev(const char *,int); | ||||
308 | void setpppoe_svc(const char *,int); | ||||
309 | void setpppoe_ac(const char *,int); | ||||
310 | void pppoe_status(void); | ||||
311 | void setspppproto(const char *, int); | ||||
312 | void setspppname(const char *, int); | ||||
313 | void setspppkey(const char *, int); | ||||
314 | void setsppppeerproto(const char *, int); | ||||
315 | void setsppppeername(const char *, int); | ||||
316 | void setsppppeerkey(const char *, int); | ||||
317 | void setsppppeerflag(const char *, int); | ||||
318 | void unsetsppppeerflag(const char *, int); | ||||
319 | void sppp_status(void); | ||||
320 | void sppp_printproto(const char *, struct sauthreq *); | ||||
321 | void setifpriority(const char *, int); | ||||
322 | void setifpowersave(const char *, int); | ||||
323 | void setifmetric(const char *, int); | ||||
324 | void pflow_status(void); | ||||
325 | void pflow_addr(const char*, struct sockaddr_storage *); | ||||
326 | void setpflow_sender(const char *, int); | ||||
327 | void unsetpflow_sender(const char *, int); | ||||
328 | void setpflow_receiver(const char *, int); | ||||
329 | void unsetpflow_receiver(const char *, int); | ||||
330 | void setpflowproto(const char *, int); | ||||
331 | void setifipdst(const char *, int); | ||||
332 | void setifdesc(const char *, int); | ||||
333 | void unsetifdesc(const char *, int); | ||||
334 | void printifhwfeatures(const char *, int); | ||||
335 | void setpair(const char *, int); | ||||
336 | void unsetpair(const char *, int); | ||||
337 | void umb_status(void); | ||||
338 | void umb_printclasses(char *, int); | ||||
339 | int umb_parse_classes(const char *); | ||||
340 | void umb_setpin(const char *, int); | ||||
341 | void umb_chgpin(const char *, const char *); | ||||
342 | void umb_puk(const char *, const char *); | ||||
343 | void umb_pinop(int, int, const char *, const char *); | ||||
344 | void umb_apn(const char *, int); | ||||
345 | void umb_setclass(const char *, int); | ||||
346 | void umb_roaming(const char *, int); | ||||
347 | void utf16_to_char(uint16_t *, int, char *, size_t); | ||||
348 | int char_to_utf16(const char *, uint16_t *, size_t); | ||||
349 | void transceiver(const char *, int); | ||||
350 | void transceiverdump(const char *, int); | ||||
351 | |||||
352 | /* WG */ | ||||
353 | void setwgpeer(const char *, int); | ||||
354 | void setwgpeerep(const char *, const char *); | ||||
355 | void setwgpeeraip(const char *, int); | ||||
356 | void setwgpeerpsk(const char *, int); | ||||
357 | void setwgpeerpka(const char *, int); | ||||
358 | void setwgport(const char *, int); | ||||
359 | void setwgkey(const char *, int); | ||||
360 | void setwgrtable(const char *, int); | ||||
361 | |||||
362 | void unsetwgpeer(const char *, int); | ||||
363 | void unsetwgpeerpsk(const char *, int); | ||||
364 | void unsetwgpeerall(const char *, int); | ||||
365 | |||||
366 | void wg_status(); | ||||
367 | #else | ||||
368 | void 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 | */ | ||||
378 | uint64_t media_current; | ||||
379 | uint64_t mediaopt_set; | ||||
380 | uint64_t mediaopt_clear; | ||||
381 | |||||
382 | int 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 | |||||
398 | const 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 | |||||
674 | int getinfo(struct ifreq *, int); | ||||
675 | void getsock(int); | ||||
676 | void printgroupattribs(char *); | ||||
677 | void printif(char *, int); | ||||
678 | void printb_status(unsigned short, unsigned char *); | ||||
679 | const char *get_linkstate(int, int); | ||||
680 | void status(int, struct sockaddr_dl *, int); | ||||
681 | __dead__attribute__((__noreturn__)) void usage(void); | ||||
682 | const char *get_string(const char *, const char *, u_int8_t *, int *); | ||||
683 | int len_string(const u_int8_t *, int); | ||||
684 | int print_string(const u_int8_t *, int); | ||||
685 | char *sec2str(time_t); | ||||
686 | |||||
687 | const char *get_media_type_string(uint64_t); | ||||
688 | const char *get_media_subtype_string(uint64_t); | ||||
689 | uint64_t get_media_mode(uint64_t, const char *); | ||||
690 | uint64_t get_media_subtype(uint64_t, const char *); | ||||
691 | uint64_t get_media_options(uint64_t, const char *); | ||||
692 | uint64_t lookup_media_word(const struct ifmedia_description *, uint64_t, | ||||
693 | const char *); | ||||
694 | void print_media_word(uint64_t, int, int); | ||||
695 | void process_media_commands(void); | ||||
696 | void init_current_media(void); | ||||
697 | |||||
698 | void process_join_commands(void); | ||||
699 | |||||
700 | void process_wg_commands(void); | ||||
701 | |||||
702 | unsigned long get_ts_map(int, int, int); | ||||
703 | |||||
704 | void in_status(int); | ||||
705 | void in_getaddr(const char *, int); | ||||
706 | void in_getprefix(const char *, int); | ||||
707 | void in6_fillscopeid(struct sockaddr_in6 *); | ||||
708 | void in6_alias(struct in6_ifreq *); | ||||
709 | void in6_status(int); | ||||
710 | void in6_getaddr(const char *, int); | ||||
711 | void in6_getprefix(const char *, int); | ||||
712 | void ieee80211_status(void); | ||||
713 | void join_status(void); | ||||
714 | void ieee80211_listchans(void); | ||||
715 | void ieee80211_listnodes(void); | ||||
716 | void ieee80211_printnode(struct ieee80211_nodereq *); | ||||
717 | u_int getwpacipher(const char *); | ||||
718 | void print_cipherset(u_int32_t); | ||||
719 | |||||
720 | void spppauthinfo(struct sauthreq *, int); | ||||
721 | void spppdnsinfo(struct sdnsreq *); | ||||
722 | |||||
723 | /* Known address families */ | ||||
724 | const 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 | |||||
743 | const struct afswtch *afp; /*the address family being set or asked about*/ | ||||
744 | |||||
745 | char joinname[IEEE80211_NWID_LEN32]; | ||||
746 | size_t joinlen; | ||||
747 | char nwidname[IEEE80211_NWID_LEN32]; | ||||
748 | size_t nwidlen; | ||||
749 | |||||
750 | int ifaliases = 0; | ||||
751 | int aflag = 0; | ||||
752 | |||||
753 | int | ||||
754 | main(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) { | ||||
| |||||
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] == '-') { | ||||
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) | ||||
809 | errx(1, "interface name '%s' too long", *argv); | ||||
810 | argc--, argv++; | ||||
811 | |||||
812 | for (i = 0; i < argc; i++) { | ||||
813 | if (strcmp(argv[i], "rulefile") == 0) { | ||||
814 | found_rulefile = 1; | ||||
815 | break; | ||||
816 | } | ||||
817 | } | ||||
818 | |||||
819 | if (!found_rulefile
| ||||
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
| ||||
831 | for (afp = rafp = afs; rafp->af_name; rafp++) | ||||
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
| ||||
842 | if (argc > 0 || aflag) | ||||
843 | usage(); | ||||
844 | list_cloners(); | ||||
845 | return (0); | ||||
846 | } | ||||
847 | if (gflag
| ||||
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
| ||||
865 | clone_create(argv[0], 0); | ||||
866 | argc--, argv++; | ||||
867 | if (argc == 0) | ||||
868 | return (0); | ||||
869 | } | ||||
870 | if (aflag
| ||||
871 | create = (argc
| ||||
872 | (void)getinfo(&ifr, create); | ||||
873 | } | ||||
874 | |||||
875 | if (argc
| ||||
876 | addaf(ifname, AF_INET624); | ||||
877 | |||||
878 | while (argc
| ||||
879 | const struct cmd *p; | ||||
880 | |||||
881 | for (p = cmds; p->c_name; p++) | ||||
882 | if (strcmp(*argv, p->c_name) == 0) | ||||
883 | break; | ||||
884 | #ifndef SMALL | ||||
885 | if (strcmp(*argv, "rule") == 0) { | ||||
886 | argc--, argv++; | ||||
887 | return bridge_rule(argc, argv, -1); | ||||
888 | } | ||||
889 | #endif | ||||
890 | if (p->c_name
| ||||
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) { | ||||
897 | if (p->c_parameter == NEXTARG00xffffff) { | ||||
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
| ||||
912 | (*p->c_func)(NULL((void*)0), 0); | ||||
| |||||
913 | else | ||||
914 | goto nextarg; | ||||
915 | } else if (p->c_parameter == NEXTARG0xfffffe) { | ||||
916 | nextarg: | ||||
917 | if (argv[1] == NULL((void*)0)) | ||||
918 | errx(1, "'%s' requires argument", | ||||
919 | p->c_name); | ||||
920 | (*p->c_func)(argv[1], 0); | ||||
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 | |||||
985 | void | ||||
986 | getsock(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 | |||||
1001 | int | ||||
1002 | getinfo(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 | |||||
1052 | int | ||||
1053 | printgroup(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 | |||||
1087 | void | ||||
1088 | printgroupattribs(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 | |||||
1103 | void | ||||
1104 | setgroupattribs(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 | |||||
1135 | void | ||||
1136 | printif(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 = 𝔦 | ||||
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*/ | ||||
1238 | void | ||||
1239 | clone_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*/ | ||||
1251 | void | ||||
1252 | clone_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 | |||||
1260 | void | ||||
1261 | list_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*/ | ||||
1309 | void | ||||
1310 | setifaddr(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 | ||||
1326 | void | ||||
1327 | setifrtlabel(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 */ | ||||
1339 | void | ||||
1340 | setifnetmask(const char *addr, int ignored) | ||||
1341 | { | ||||
1342 | afp->af_getaddr(addr, MASK2); | ||||
1343 | explicit_prefix = 1; | ||||
1344 | } | ||||
1345 | |||||
1346 | /* ARGSUSED */ | ||||
1347 | void | ||||
1348 | setifbroadaddr(const char *addr, int ignored) | ||||
1349 | { | ||||
1350 | afp->af_getaddr(addr, DSTADDR3); | ||||
1351 | } | ||||
1352 | |||||
1353 | #ifndef SMALL | ||||
1354 | /* ARGSUSED */ | ||||
1355 | void | ||||
1356 | setifdesc(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 */ | ||||
1364 | void | ||||
1365 | unsetifdesc(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 */ | ||||
1373 | void | ||||
1374 | setifipdst(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*/ | ||||
1385 | void | ||||
1386 | notealias(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*/ | ||||
1400 | void | ||||
1401 | setifdstaddr(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 */ | ||||
1414 | void | ||||
1415 | setifflags(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 */ | ||||
1437 | void | ||||
1438 | setifxflags(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 | |||||
1459 | void | ||||
1460 | addaf(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 | |||||
1470 | void | ||||
1471 | removeaf(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 | |||||
1481 | void | ||||
1482 | setia6flags(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 | |||||
1492 | void | ||||
1493 | setia6pltime(const char *val, int d) | ||||
1494 | { | ||||
1495 | |||||
1496 | setia6lifetime("pltime", val); | ||||
1497 | } | ||||
1498 | |||||
1499 | void | ||||
1500 | setia6vltime(const char *val, int d) | ||||
1501 | { | ||||
1502 | |||||
1503 | setia6lifetime("vltime", val); | ||||
1504 | } | ||||
1505 | |||||
1506 | void | ||||
1507 | setia6lifetime(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 | |||||
1529 | void | ||||
1530 | setia6eui64(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 | |||||
1565 | void | ||||
1566 | setautoconf(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 | |||||
1584 | void | ||||
1585 | settemporary(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 */ | ||||
1598 | void | ||||
1599 | setifmetric(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 */ | ||||
1614 | void | ||||
1615 | setifmtu(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 */ | ||||
1629 | void | ||||
1630 | setifllprio(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 */ | ||||
1644 | void | ||||
1645 | setifgroup(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 */ | ||||
1669 | void | ||||
1670 | unsetifgroup(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 | |||||
1683 | const char * | ||||
1684 | get_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 | |||||
1733 | int | ||||
1734 | len_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 | |||||
1756 | int | ||||
1757 | print_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 | |||||
1786 | void | ||||
1787 | setifnwid(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 | |||||
1818 | void | ||||
1819 | process_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 | |||||
1829 | void | ||||
1830 | setifjoin(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 | |||||
1860 | void | ||||
1861 | delifjoin(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 | |||||
1888 | void | ||||
1889 | delifjoinlist(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 | |||||
1910 | void | ||||
1911 | setifbssid(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 | |||||
1934 | void | ||||
1935 | setifnwkey(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 */ | ||||
2034 | void | ||||
2035 | setifwpa(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 */ | ||||
2055 | void | ||||
2056 | setifwpaprotos(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 */ | ||||
2096 | void | ||||
2097 | setifwpaakms(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 | |||||
2137 | static 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 | |||||
2148 | u_int | ||||
2149 | getwpacipher(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 */ | ||||
2160 | void | ||||
2161 | setifwpaciphers(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 */ | ||||
2197 | void | ||||
2198 | setifwpagroupcipher(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 | |||||
2223 | void | ||||
2224 | setifwpakey(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 | |||||
2297 | void | ||||
2298 | setifchan(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 */ | ||||
2327 | void | ||||
2328 | setifscan(const char *val, int d) | ||||
2329 | { | ||||
2330 | if (shownet80211chans || shownet80211nodes) | ||||
2331 | usage(); | ||||
2332 | shownet80211nodes = 1; | ||||
2333 | } | ||||
2334 | |||||
2335 | #ifndef SMALL | ||||
2336 | |||||
2337 | void | ||||
2338 | setifnwflag(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 | |||||
2364 | void | ||||
2365 | unsetifnwflag(const char *val, int d) | ||||
2366 | { | ||||
2367 | setifnwflag(val, 1); | ||||
2368 | } | ||||
2369 | |||||
2370 | /* ARGSUSED */ | ||||
2371 | void | ||||
2372 | setifpowersave(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 | |||||
2395 | void | ||||
2396 | print_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 | |||||
2413 | static void | ||||
2414 | print_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 | |||||
2428 | void | ||||
2429 | ieee80211_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 | |||||
2577 | void | ||||
2578 | showjoin(const char *cmd, int val) | ||||
2579 | { | ||||
2580 | show_join = 1; | ||||
2581 | return; | ||||
2582 | } | ||||
2583 | |||||
2584 | void | ||||
2585 | join_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 | |||||
2674 | void | ||||
2675 | ieee80211_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 | */ | ||||
2707 | static int | ||||
2708 | rssicmp(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 | |||||
2714 | void | ||||
2715 | ieee80211_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 | |||||
2759 | void | ||||
2760 | ieee80211_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 | |||||
2843 | void | ||||
2844 | init_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 | |||||
2873 | void | ||||
2874 | process_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 */ | ||||
2897 | void | ||||
2898 | setmedia(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 */ | ||||
2941 | void | ||||
2942 | setmediamode(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 | |||||
2963 | void | ||||
2964 | unsetmediamode(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 | |||||
2984 | void | ||||
2985 | setmediaopt(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 */ | ||||
3004 | void | ||||
3005 | unsetmediaopt(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 */ | ||||
3029 | void | ||||
3030 | setmediainst(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 | |||||
3059 | const 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 | |||||
3062 | const 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 | |||||
3065 | struct 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 | |||||
3068 | const 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 | |||||
3071 | const char * | ||||
3072 | get_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 | |||||
3084 | const char * | ||||
3085 | get_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 | |||||
3098 | uint64_t | ||||
3099 | get_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 | |||||
3111 | uint64_t | ||||
3112 | get_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 | |||||
3123 | uint64_t | ||||
3124 | get_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 | |||||
3150 | uint64_t | ||||
3151 | lookup_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 | |||||
3163 | void | ||||
3164 | print_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 | |||||
3203 | static void | ||||
3204 | print_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 */ | ||||
3255 | static void | ||||
3256 | phys_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 | ||||
3295 | const uint64_t ifm_status_valid_list[] = IFM_STATUS_VALID_LIST{ 0x0000000000000001ULL, 0 }; | ||||
3296 | |||||
3297 | const 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 | |||||
3301 | const 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 | |||||
3304 | const char * | ||||
3305 | get_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 | */ | ||||
3322 | void | ||||
3323 | status(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 */ | ||||
3530 | void | ||||
3531 | in_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 */ | ||||
3591 | void | ||||
3592 | setifprefixlen(const char *addr, int d) | ||||
3593 | { | ||||
3594 | if (afp->af_getprefix) | ||||
3595 | afp->af_getprefix(addr, MASK2); | ||||
3596 | explicit_prefix = 1; | ||||
3597 | } | ||||
3598 | |||||
3599 | void | ||||
3600 | in6_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 */ | ||||
3613 | void | ||||
3614 | in6_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 | |||||
3730 | void | ||||
3731 | in6_status(int force) | ||||
3732 | { | ||||
3733 | in6_alias((struct in6_ifreq *)&ifr6); | ||||
3734 | } | ||||
3735 | |||||
3736 | #ifndef SMALL | ||||
3737 | void | ||||
3738 | settunnel(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 | |||||
3781 | void | ||||
3782 | settunneladdr(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 */ | ||||
3816 | void | ||||
3817 | deletetunnel(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 | |||||
3823 | void | ||||
3824 | settunnelinst(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 | |||||
3839 | void | ||||
3840 | unsettunnelinst(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 | |||||
3848 | void | ||||
3849 | settunnelttl(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 | |||||
3868 | void | ||||
3869 | settunneldf(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 | |||||
3877 | void | ||||
3878 | settunnelnodf(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 | |||||
3886 | void | ||||
3887 | settunnelecn(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 | |||||
3895 | void | ||||
3896 | settunnelnoecn(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 | |||||
3904 | void | ||||
3905 | setvnetflowid(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 | |||||
3916 | void | ||||
3917 | delvnetflowid(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 | |||||
3928 | static void | ||||
3929 | pwe3_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 | |||||
3966 | static void | ||||
3967 | pwe3_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 | |||||
3983 | static void | ||||
3984 | pwe3_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 | |||||
3999 | void | ||||
4000 | mpls_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 */ | ||||
4023 | void | ||||
4024 | setmplslabel(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 | |||||
4039 | void | ||||
4040 | unsetmplslabel(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 | |||||
4053 | static void | ||||
4054 | setpwe3(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 | |||||
4069 | void | ||||
4070 | setpwe3cw(const char *val, int d) | ||||
4071 | { | ||||
4072 | setpwe3(SIOCSPWE3CTRLWORD((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff ) << 16) | ((('i')) << 8) | ((220))), "pwecw", 1); | ||||
4073 | } | ||||
4074 | |||||
4075 | void | ||||
4076 | unsetpwe3cw(const char *val, int d) | ||||
4077 | { | ||||
4078 | setpwe3(SIOCSPWE3CTRLWORD((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff ) << 16) | ((('i')) << 8) | ((220))), "-pwecw", 0); | ||||
4079 | } | ||||
4080 | |||||
4081 | void | ||||
4082 | setpwe3fat(const char *val, int d) | ||||
4083 | { | ||||
4084 | setpwe3(SIOCSPWE3FAT((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff ) << 16) | ((('i')) << 8) | ((221))), "pwefat", 1); | ||||
4085 | } | ||||
4086 | |||||
4087 | void | ||||
4088 | unsetpwe3fat(const char *val, int d) | ||||
4089 | { | ||||
4090 | setpwe3(SIOCSPWE3FAT((unsigned long)0x80000000 | ((sizeof(struct ifreq) & 0x1fff ) << 16) | ((('i')) << 8) | ((221))), "-pwefat", 0); | ||||
4091 | } | ||||
4092 | |||||
4093 | void | ||||
4094 | setpwe3neighbor(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 | |||||
4133 | void | ||||
4134 | unsetpwe3neighbor(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 | |||||
4147 | void | ||||
4148 | transceiver(const char *value, int d) | ||||
4149 | { | ||||
4150 | showtransceiver = 1; | ||||
4151 | } | ||||
4152 | |||||
4153 | void | ||||
4154 | transceiverdump(const char *value, int d) | ||||
4155 | { | ||||
4156 | if (if_sff_info(1) == -1) | ||||
4157 | err(1, "%s transceiver", ifname); | ||||
4158 | } | ||||
4159 | #endif /* SMALL */ | ||||
4160 | |||||
4161 | void | ||||
4162 | getvnetflowid(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 | |||||
4175 | void | ||||
4176 | setvnetid(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 */ | ||||
4197 | void | ||||
4198 | delvnetid(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 | |||||
4204 | void | ||||
4205 | getvnetid(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 | |||||
4228 | void | ||||
4229 | setifparent(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 */ | ||||
4246 | void | ||||
4247 | delifparent(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 | |||||
4253 | void | ||||
4254 | getifparent(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 | ||||
4276 | void | ||||
4277 | gettxprio(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 | |||||
4290 | void | ||||
4291 | settxprio(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 | |||||
4314 | void | ||||
4315 | getrxprio(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 | |||||
4328 | void | ||||
4329 | setrxprio(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 | |||||
4355 | void | ||||
4356 | getencap(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 | |||||
4434 | void | ||||
4435 | settrunkport(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 | |||||
4447 | void | ||||
4448 | unsettrunkport(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 | |||||
4460 | void | ||||
4461 | settrunkproto(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 | |||||
4484 | void | ||||
4485 | settrunklacpmode(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 | |||||
4517 | void | ||||
4518 | settrunklacptimeout(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 | |||||
4550 | void | ||||
4551 | trunk_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 | ||||
4652 | static const char *carp_states[] = { CARP_STATES"INIT", "BACKUP", "MASTER" }; | ||||
4653 | static const char *carp_bal_modes[] = { CARP_BAL_MODES"none", "ip", "ip-stealth", "ip-unicast" }; | ||||
4654 | |||||
4655 | void | ||||
4656 | carp_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 */ | ||||
4710 | void | ||||
4711 | setcarp_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 */ | ||||
4729 | void | ||||
4730 | setcarp_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 */ | ||||
4754 | void | ||||
4755 | setcarp_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 */ | ||||
4778 | void | ||||
4779 | setcarp_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 */ | ||||
4802 | void | ||||
4803 | setcarppeer(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 | |||||
4835 | void | ||||
4836 | unsetcarppeer(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 */ | ||||
4853 | void | ||||
4854 | setcarp_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 */ | ||||
4877 | void | ||||
4878 | setcarpdev(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 | |||||
4894 | void | ||||
4895 | setcarp_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 | |||||
4938 | void | ||||
4939 | setcarp_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 | |||||
4963 | void | ||||
4964 | setpfsync_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 */ | ||||
4981 | void | ||||
4982 | unsetpfsync_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 */ | ||||
4999 | void | ||||
5000 | setpfsync_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 */ | ||||
5033 | void | ||||
5034 | unsetpfsync_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 */ | ||||
5051 | void | ||||
5052 | setpfsync_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 | |||||
5074 | void | ||||
5075 | setpfsync_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 | |||||
5090 | void | ||||
5091 | pfsync_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 | |||||
5111 | void | ||||
5112 | pflow_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 | |||||
5192 | void | ||||
5193 | pflow_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 | |||||
5244 | void | ||||
5245 | setpflow_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 | |||||
5258 | void | ||||
5259 | unsetpflow_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 | |||||
5270 | void | ||||
5271 | setpflow_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 | |||||
5284 | void | ||||
5285 | unsetpflow_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 */ | ||||
5297 | void | ||||
5298 | setpflowproto(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 | |||||
5324 | void | ||||
5325 | pppoe_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 | } | ||||
5391 | notime: | ||||
5392 | putchar('\n')(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n', (&__sF[1]))); | ||||
5393 | } | ||||
5394 | |||||
5395 | /* ARGSUSED */ | ||||
5396 | void | ||||
5397 | setpppoe_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 */ | ||||
5412 | void | ||||
5413 | setpppoe_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 */ | ||||
5431 | void | ||||
5432 | setpppoe_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 | |||||
5449 | void | ||||
5450 | spppauthinfo(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 | |||||
5460 | void | ||||
5461 | spppdnsinfo(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 | |||||
5471 | void | ||||
5472 | setspppproto(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 | |||||
5492 | void | ||||
5493 | setsppppeerproto(const char *val, int d) | ||||
5494 | { | ||||
5495 | setspppproto(val, 1); | ||||
5496 | } | ||||
5497 | |||||
5498 | void | ||||
5499 | setspppname(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 | |||||
5515 | void | ||||
5516 | setsppppeername(const char *val, int d) | ||||
5517 | { | ||||
5518 | setspppname(val, 1); | ||||
5519 | } | ||||
5520 | |||||
5521 | void | ||||
5522 | setspppkey(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 | |||||
5538 | void | ||||
5539 | setsppppeerkey(const char *val, int d) | ||||
5540 | { | ||||
5541 | setspppkey(val, 1); | ||||
5542 | } | ||||
5543 | |||||
5544 | void | ||||
5545 | setsppppeerflag(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 | |||||
5571 | void | ||||
5572 | unsetsppppeerflag(const char *val, int d) | ||||
5573 | { | ||||
5574 | setsppppeerflag(val, 1); | ||||
5575 | } | ||||
5576 | |||||
5577 | void | ||||
5578 | sppp_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 | |||||
5600 | void | ||||
5601 | sppp_status(void) |