]>
git.cameronkatri.com Git - apple_cmds.git/blob - network_cmds/ifconfig.tproj/ifbridge.c
2 * Copyright (c) 2009-2019 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
30 * Copyright 2001 Wasabi Systems, Inc.
31 * All rights reserved.
33 * Written by Jason R. Thorpe for Wasabi Systems, Inc.
35 * Redistribution and use in source and binary forms, with or without
36 * modification, are permitted provided that the following conditions
38 * 1. Redistributions of source code must retain the above copyright
39 * notice, this list of conditions and the following disclaimer.
40 * 2. Redistributions in binary form must reproduce the above copyright
41 * notice, this list of conditions and the following disclaimer in the
42 * documentation and/or other materials provided with the distribution.
43 * 3. All advertising materials mentioning features or use of this software
44 * must display the following acknowledgement:
45 * This product includes software developed for the NetBSD Project by
46 * Wasabi Systems, Inc.
47 * 4. The name of Wasabi Systems, Inc. may not be used to endorse
48 * or promote products derived from this software without specific prior
51 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
52 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
53 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
54 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
55 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
56 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
57 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
58 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
59 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
60 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
61 * POSSIBILITY OF SUCH DAMAGE.
64 #include <sys/param.h>
65 #include <sys/ioctl.h>
66 #include <sys/socket.h>
67 #include <sys/sockio.h>
72 #include <net/ethernet.h>
74 #include <net/if_bridgevar.h>
75 #include <net/route.h>
85 #include <arpa/inet.h>
89 #define PV2ID(pv, epri, eaddr) do { \
91 eaddr[0] = pv >> 40; \
92 eaddr[1] = pv >> 32; \
93 eaddr[2] = pv >> 24; \
94 eaddr[3] = pv >> 16; \
99 static const char *stpstates
[] = {
107 static const char *stpproto
[] = {
112 static const char *stproles
[] = {
121 get_val(const char *cp
, u_long
*valp
)
127 val
= strtoul(cp
, &endptr
, 0);
128 if (cp
[0] == '\0' || endptr
[0] != '\0' || errno
== ERANGE
)
136 do_cmd(int sock
, u_long op
, void *arg
, size_t argsize
, int set
)
140 memset(&ifd
, 0, sizeof(ifd
));
142 strlcpy(ifd
.ifd_name
, ifr
.ifr_name
, sizeof(ifd
.ifd_name
));
144 ifd
.ifd_len
= argsize
;
147 return (ioctl(sock
, set
? SIOCSDRVSPEC
: SIOCGDRVSPEC
, &ifd
));
151 do_bridgeflag(int sock
, const char *ifs
, int flag
, int set
)
155 strlcpy(req
.ifbr_ifsname
, ifs
, sizeof(req
.ifbr_ifsname
));
157 if (do_cmd(sock
, BRDGGIFFLGS
, &req
, sizeof(req
), 0) < 0)
158 err(1, "unable to get bridge flags");
161 req
.ifbr_ifsflags
|= flag
;
163 req
.ifbr_ifsflags
&= ~flag
;
165 if (do_cmd(sock
, BRDGSIFFLGS
, &req
, sizeof(req
), 1) < 0)
166 err(1, "unable to set bridge flags");
170 bridge_interfaces(int s
, const char *prefix
)
172 struct ifbifconf bifc
;
174 char *inbuf
= NULL
, *ninbuf
;
178 pad
= strdup(prefix
);
181 /* replace the prefix with whitespace */
182 for (p
= pad
; *p
!= '\0'; p
++) {
188 ninbuf
= realloc(inbuf
, len
);
190 err(1, "unable to allocate interface buffer");
191 bifc
.ifbic_len
= len
;
192 bifc
.ifbic_buf
= inbuf
= ninbuf
;
193 if (do_cmd(s
, BRDGGIFS
, &bifc
, sizeof(bifc
), 0) < 0)
194 err(1, "unable to get interface list");
195 if ((bifc
.ifbic_len
+ sizeof(*req
)) < len
)
200 for (i
= 0; i
< bifc
.ifbic_len
/ sizeof(*req
); i
++) {
201 req
= bifc
.ifbic_req
+ i
;
202 printf("%s%s ", prefix
, req
->ifbr_ifsname
);
203 printb("flags", req
->ifbr_ifsflags
, IFBIFBITS
);
207 printf("ifmaxaddr %u", req
->ifbr_addrmax
);
208 printf(" port %u priority %u", req
->ifbr_portno
,
210 printf(" path cost %u", req
->ifbr_path_cost
);
212 if (req
->ifbr_ifsflags
& IFBIF_STP
) {
213 if (req
->ifbr_proto
<
214 sizeof(stpproto
) / sizeof(stpproto
[0]))
215 printf(" proto %s", stpproto
[req
->ifbr_proto
]);
217 printf(" <unknown proto %d>",
222 sizeof(stproles
) / sizeof(stproles
[0]))
223 printf("role %s", stproles
[req
->ifbr_role
]);
225 printf("<unknown role %d>",
227 if (req
->ifbr_state
<
228 sizeof(stpstates
) / sizeof(stpstates
[0]))
229 printf(" state %s", stpstates
[req
->ifbr_state
]);
231 printf(" <unknown state %d>",
237 struct ifbrhostfilter ifbrfh
;
239 struct ether_addr ea
;
241 bzero(&ifbrfh
, sizeof(struct ifbrhostfilter
));
242 strlcpy(ifbrfh
.ifbrhf_ifsname
, req
->ifbr_ifsname
, sizeof(ifbrfh
.ifbrhf_ifsname
));
243 if (do_cmd(s
, BRDGGHOSTFILTER
, &ifbrfh
, sizeof(ifbrfh
), 0) < 0)
244 err(1, "unable to get host filter settings for %s",
245 ifbrfh
.ifbrhf_ifsname
);
247 if (ifbrfh
.ifbrhf_flags
& IFBRHF_ENABLED
) {
248 in
.s_addr
= ifbrfh
.ifbrhf_ipsrc
;
249 bcopy(ifbrfh
.ifbrhf_hwsrca
, ea
.octet
, ETHER_ADDR_LEN
);
251 in
.s_addr
= INADDR_ANY
;
252 bzero(ea
.octet
, ETHER_ADDR_LEN
);
255 printf("hostfilter %d hw: %s ip: %s",
256 ifbrfh
.ifbrhf_flags
& IFBRHF_ENABLED
? 1 : 0,
257 ether_ntoa(&ea
), inet_ntoa(in
));
268 bridge_addresses(int s
, const char *prefix
)
270 struct ifbaconf ifbac
;
271 struct ifbareq
*ifba
;
272 char *inbuf
= NULL
, *ninbuf
;
274 struct ether_addr ea
;
277 ninbuf
= realloc(inbuf
, len
);
279 err(1, "unable to allocate address buffer");
280 ifbac
.ifbac_len
= len
;
281 ifbac
.ifbac_buf
= inbuf
= ninbuf
;
282 if (do_cmd(s
, BRDGRTS
, &ifbac
, sizeof(ifbac
), 0) < 0)
283 err(1, "unable to get address cache");
284 if ((ifbac
.ifbac_len
+ sizeof(*ifba
)) < len
)
289 for (i
= 0; i
< ifbac
.ifbac_len
/ sizeof(*ifba
); i
++) {
290 ifba
= ifbac
.ifbac_req
+ i
;
291 memcpy(ea
.octet
, ifba
->ifba_dst
,
293 printf("%s%s Vlan%d %s %lu ", prefix
, ether_ntoa(&ea
),
294 ifba
->ifba_vlan
, ifba
->ifba_ifsname
, ifba
->ifba_expire
);
295 printb("flags", ifba
->ifba_flags
, IFBAFBITS
);
302 #define MAX_IPv6_STR_LEN INET6_ADDRSTRLEN
303 #if __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ >= 135000
305 bridge_mac_nat(int s
, const char *prefix
)
309 struct ether_addr ea
;
311 struct ifbrmnelist mnl
;
314 bzero(&mnl
, sizeof(mnl
));
315 if (do_cmd(s
, BRDGGMACNATLIST
, &mnl
, sizeof(mnl
), 0) < 0) {
316 /* err(1, "unable to get mac nat list"); */
319 if (mnl
.ifbml_len
== 0) {
322 printf("\tMAC NAT list:\n");
323 if (mnl
.ifbml_elsize
== 0) {
324 err(1, "kernel reported zero length element size");
326 if (mnl
.ifbml_elsize
< sizeof(struct ifbrmne
)) {
327 err(1, "struct element size too small, kernel mismatch");
329 buf
= malloc(mnl
.ifbml_len
);
331 err(1, "unable to allocate mac nat list buffer");
334 if (do_cmd(s
, BRDGGMACNATLIST
, &mnl
, sizeof(mnl
), 0) < 0) {
335 err(1, "unable to get mac nat list");
337 count
= mnl
.ifbml_len
/ mnl
.ifbml_elsize
;
338 for (i
= 0, scan
= buf
; i
< count
; i
++, scan
+= mnl
.ifbml_elsize
) {
339 struct ifbrmne
*ifbmne
= (struct ifbrmne
*)scan
;
340 char ntopbuf
[INET6_ADDRSTRLEN
];
342 memcpy(ea
.octet
, ifbmne
->ifbmne_mac
,
344 inet_ntop(ifbmne
->ifbmne_af
, &ifbmne
->ifbmne_ip
,
345 ntopbuf
, sizeof(ntopbuf
));
346 printf("%s%s %s %s %lu\n",
347 prefix
, ifbmne
->ifbmne_ifname
, ntopbuf
, ether_ntoa(&ea
),
348 (unsigned long)ifbmne
->ifbmne_expire
);
357 struct ifbropreq ifbp
;
358 struct ifbrparam param
;
360 u_int8_t ht
, fd
, ma
, hc
, pro
;
361 u_int8_t lladdr
[ETHER_ADDR_LEN
];
363 u_int32_t csize
, ctime
;
366 if (do_cmd(s
, BRDGGCACHE
, ¶m
, sizeof(param
), 0) < 0)
368 csize
= param
.ifbrp_csize
;
369 if (do_cmd(s
, BRDGGTO
, ¶m
, sizeof(param
), 0) < 0)
371 ctime
= param
.ifbrp_ctime
;
372 if (do_cmd(s
, BRDGGFILT
, ¶m
, sizeof(param
), 0) < 0)
374 ipfflags
= param
.ifbrp_filter
;
375 if (do_cmd(s
, BRDGPARAM
, &ifbp
, sizeof(ifbp
), 0) < 0)
377 pri
= ifbp
.ifbop_priority
;
378 pro
= ifbp
.ifbop_protocol
;
379 ht
= ifbp
.ifbop_hellotime
;
380 fd
= ifbp
.ifbop_fwddelay
;
381 hc
= ifbp
.ifbop_holdcount
;
382 ma
= ifbp
.ifbop_maxage
;
384 printf("\tConfiguration:\n");
385 PV2ID(ifbp
.ifbop_bridgeid
, bprio
, lladdr
);
386 printf("\t\tid %s priority %u hellotime %u fwddelay %u\n",
387 ether_ntoa((struct ether_addr
*)lladdr
), pri
, ht
, fd
);
388 printf("\t\tmaxage %u holdcnt %u proto %s maxaddr %u timeout %u\n",
389 ma
, hc
, stpproto
[pro
], csize
, ctime
);
391 PV2ID(ifbp
.ifbop_designated_root
, bprio
, lladdr
);
392 printf("\t\troot id %s priority %d ifcost %u port %u\n",
393 ether_ntoa((struct ether_addr
*)lladdr
), bprio
,
394 ifbp
.ifbop_root_path_cost
, ifbp
.ifbop_root_port
& 0xfff);
396 printf("\t\tipfilter %s flags 0x%x\n",
397 (ipfflags
& IFBF_FILT_USEIPF
) ? "enabled" : "disabled", ipfflags
);
399 bridge_interfaces(s
, "\tmember: ");
401 if (!all
|| verbose
> 1) {
402 printf("\tAddress cache:\n");
403 bridge_addresses(s
, "\t\t");
404 #if __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ >= 135000
405 bridge_mac_nat(s
, "\t\t");
413 setbridge_add(const char *val
, int d
, int s
, const struct afswtch
*afp
)
417 memset(&req
, 0, sizeof(req
));
418 strlcpy(req
.ifbr_ifsname
, val
, sizeof(req
.ifbr_ifsname
));
419 if (do_cmd(s
, BRDGADD
, &req
, sizeof(req
), 1) < 0)
420 err(1, "BRDGADD %s", val
);
424 setbridge_delete(const char *val
, int d
, int s
, const struct afswtch
*afp
)
428 memset(&req
, 0, sizeof(req
));
429 strlcpy(req
.ifbr_ifsname
, val
, sizeof(req
.ifbr_ifsname
));
430 if (do_cmd(s
, BRDGDEL
, &req
, sizeof(req
), 1) < 0)
431 err(1, "BRDGDEL %s", val
);
435 setbridge_discover(const char *val
, int d
, int s
, const struct afswtch
*afp
)
438 do_bridgeflag(s
, val
, IFBIF_DISCOVER
, 1);
442 unsetbridge_discover(const char *val
, int d
, int s
, const struct afswtch
*afp
)
445 do_bridgeflag(s
, val
, IFBIF_DISCOVER
, 0);
449 setbridge_learn(const char *val
, int d
, int s
, const struct afswtch
*afp
)
452 do_bridgeflag(s
, val
, IFBIF_LEARNING
, 1);
456 unsetbridge_learn(const char *val
, int d
, int s
, const struct afswtch
*afp
)
459 do_bridgeflag(s
, val
, IFBIF_LEARNING
, 0);
464 setbridge_sticky(const char *val
, int d
, int s
, const struct afswtch
*afp
)
467 do_bridgeflag(s
, val
, IFBIF_STICKY
, 1);
471 unsetbridge_sticky(const char *val
, int d
, int s
, const struct afswtch
*afp
)
474 do_bridgeflag(s
, val
, IFBIF_STICKY
, 0);
478 setbridge_span(const char *val
, int d
, int s
, const struct afswtch
*afp
)
482 memset(&req
, 0, sizeof(req
));
483 strlcpy(req
.ifbr_ifsname
, val
, sizeof(req
.ifbr_ifsname
));
484 if (do_cmd(s
, BRDGADDS
, &req
, sizeof(req
), 1) < 0)
485 err(1, "BRDGADDS %s", val
);
489 unsetbridge_span(const char *val
, int d
, int s
, const struct afswtch
*afp
)
493 memset(&req
, 0, sizeof(req
));
494 strlcpy(req
.ifbr_ifsname
, val
, sizeof(req
.ifbr_ifsname
));
495 if (do_cmd(s
, BRDGDELS
, &req
, sizeof(req
), 1) < 0)
496 err(1, "BRDGDELS %s", val
);
501 setbridge_stp(const char *val
, int d
, int s
, const struct afswtch
*afp
)
504 do_bridgeflag(s
, val
, IFBIF_STP
, 1);
508 unsetbridge_stp(const char *val
, int d
, int s
, const struct afswtch
*afp
)
511 do_bridgeflag(s
, val
, IFBIF_STP
, 0);
516 setbridge_edge(const char *val
, int d
, int s
, const struct afswtch
*afp
)
518 do_bridgeflag(s
, val
, IFBIF_BSTP_EDGE
, 1);
522 unsetbridge_edge(const char *val
, int d
, int s
, const struct afswtch
*afp
)
524 do_bridgeflag(s
, val
, IFBIF_BSTP_EDGE
, 0);
528 setbridge_autoedge(const char *val
, int d
, int s
, const struct afswtch
*afp
)
530 do_bridgeflag(s
, val
, IFBIF_BSTP_AUTOEDGE
, 1);
534 unsetbridge_autoedge(const char *val
, int d
, int s
, const struct afswtch
*afp
)
536 do_bridgeflag(s
, val
, IFBIF_BSTP_AUTOEDGE
, 0);
540 setbridge_ptp(const char *val
, int d
, int s
, const struct afswtch
*afp
)
542 do_bridgeflag(s
, val
, IFBIF_BSTP_PTP
, 1);
546 unsetbridge_ptp(const char *val
, int d
, int s
, const struct afswtch
*afp
)
548 do_bridgeflag(s
, val
, IFBIF_BSTP_PTP
, 0);
552 setbridge_autoptp(const char *val
, int d
, int s
, const struct afswtch
*afp
)
554 do_bridgeflag(s
, val
, IFBIF_BSTP_AUTOPTP
, 1);
558 unsetbridge_autoptp(const char *val
, int d
, int s
, const struct afswtch
*afp
)
560 do_bridgeflag(s
, val
, IFBIF_BSTP_AUTOPTP
, 0);
565 setbridge_flush(const char *val
, int d
, int s
, const struct afswtch
*afp
)
569 memset(&req
, 0, sizeof(req
));
570 req
.ifbr_ifsflags
= IFBF_FLUSHDYN
;
571 if (do_cmd(s
, BRDGFLUSH
, &req
, sizeof(req
), 1) < 0)
576 setbridge_flushall(const char *val
, int d
, int s
, const struct afswtch
*afp
)
580 memset(&req
, 0, sizeof(req
));
581 req
.ifbr_ifsflags
= IFBF_FLUSHALL
;
582 if (do_cmd(s
, BRDGFLUSH
, &req
, sizeof(req
), 1) < 0)
587 setbridge_static(const char *val
, const char *mac
, int s
,
588 const struct afswtch
*afp
)
591 struct ether_addr
*ea
;
593 memset(&req
, 0, sizeof(req
));
594 strlcpy(req
.ifba_ifsname
, val
, sizeof(req
.ifba_ifsname
));
596 ea
= ether_aton(mac
);
598 errx(1, "%s: invalid address: %s", val
, mac
);
600 memcpy(req
.ifba_dst
, ea
->octet
, sizeof(req
.ifba_dst
));
601 req
.ifba_flags
= IFBAF_STATIC
;
602 req
.ifba_vlan
= 1; /* XXX allow user to specify */
604 if (do_cmd(s
, BRDGSADDR
, &req
, sizeof(req
), 1) < 0)
605 err(1, "BRDGSADDR %s", val
);
609 setbridge_deladdr(const char *val
, int d
, int s
, const struct afswtch
*afp
)
612 struct ether_addr
*ea
;
614 memset(&req
, 0, sizeof(req
));
616 ea
= ether_aton(val
);
618 errx(1, "invalid address: %s", val
);
620 memcpy(req
.ifba_dst
, ea
->octet
, sizeof(req
.ifba_dst
));
622 if (do_cmd(s
, BRDGDADDR
, &req
, sizeof(req
), 1) < 0)
623 err(1, "BRDGDADDR %s", val
);
627 setbridge_addr(const char *val
, int d
, int s
, const struct afswtch
*afp
)
630 bridge_addresses(s
, "");
634 setbridge_maxaddr(const char *arg
, int d
, int s
, const struct afswtch
*afp
)
636 struct ifbrparam param
;
639 if (get_val(arg
, &val
) < 0 || (val
& ~0xffffffff) != 0)
640 errx(1, "invalid value: %s", arg
);
642 param
.ifbrp_csize
= val
& 0xffffffff;
644 if (do_cmd(s
, BRDGSCACHE
, ¶m
, sizeof(param
), 1) < 0)
645 err(1, "BRDGSCACHE %s", arg
);
649 setbridge_hellotime(const char *arg
, int d
, int s
, const struct afswtch
*afp
)
651 struct ifbrparam param
;
654 if (get_val(arg
, &val
) < 0 || (val
& ~0xff) != 0)
655 errx(1, "invalid value: %s", arg
);
657 param
.ifbrp_hellotime
= val
& 0xff;
659 if (do_cmd(s
, BRDGSHT
, ¶m
, sizeof(param
), 1) < 0)
660 err(1, "BRDGSHT %s", arg
);
664 setbridge_fwddelay(const char *arg
, int d
, int s
, const struct afswtch
*afp
)
666 struct ifbrparam param
;
669 if (get_val(arg
, &val
) < 0 || (val
& ~0xff) != 0)
670 errx(1, "invalid value: %s", arg
);
672 param
.ifbrp_fwddelay
= val
& 0xff;
674 if (do_cmd(s
, BRDGSFD
, ¶m
, sizeof(param
), 1) < 0)
675 err(1, "BRDGSFD %s", arg
);
679 setbridge_maxage(const char *arg
, int d
, int s
, const struct afswtch
*afp
)
681 struct ifbrparam param
;
684 if (get_val(arg
, &val
) < 0 || (val
& ~0xff) != 0)
685 errx(1, "invalid value: %s", arg
);
687 param
.ifbrp_maxage
= val
& 0xff;
689 if (do_cmd(s
, BRDGSMA
, ¶m
, sizeof(param
), 1) < 0)
690 err(1, "BRDGSMA %s", arg
);
694 setbridge_priority(const char *arg
, int d
, int s
, const struct afswtch
*afp
)
696 struct ifbrparam param
;
699 if (get_val(arg
, &val
) < 0 || (val
& ~0xffff) != 0)
700 errx(1, "invalid value: %s", arg
);
702 param
.ifbrp_prio
= val
& 0xffff;
704 if (do_cmd(s
, BRDGSPRI
, ¶m
, sizeof(param
), 1) < 0)
705 err(1, "BRDGSPRI %s", arg
);
710 setbridge_protocol(const char *arg
, int d
, int s
, const struct afswtch
*afp
)
712 struct ifbrparam param
;
714 if (strcasecmp(arg
, "stp") == 0) {
715 param
.ifbrp_proto
= 0;
716 } else if (strcasecmp(arg
, "rstp") == 0) {
717 param
.ifbrp_proto
= 2;
719 errx(1, "unknown stp protocol");
722 if (do_cmd(s
, BRDGSPROTO
, ¶m
, sizeof(param
), 1) < 0)
723 err(1, "BRDGSPROTO %s", arg
);
727 setbridge_holdcount(const char *arg
, int d
, int s
, const struct afswtch
*afp
)
729 struct ifbrparam param
;
732 if (get_val(arg
, &val
) < 0 || (val
& ~0xff) != 0)
733 errx(1, "invalid value: %s", arg
);
735 param
.ifbrp_txhc
= val
& 0xff;
737 if (do_cmd(s
, BRDGSTXHC
, ¶m
, sizeof(param
), 1) < 0)
738 err(1, "BRDGSTXHC %s", arg
);
743 setbridge_ifpriority(const char *ifn
, const char *pri
, int s
,
744 const struct afswtch
*afp
)
749 memset(&req
, 0, sizeof(req
));
751 if (get_val(pri
, &val
) < 0 || (val
& ~0xff) != 0)
752 errx(1, "invalid value: %s", pri
);
754 strlcpy(req
.ifbr_ifsname
, ifn
, sizeof(req
.ifbr_ifsname
));
755 req
.ifbr_priority
= val
& 0xff;
757 if (do_cmd(s
, BRDGSIFPRIO
, &req
, sizeof(req
), 1) < 0)
758 err(1, "BRDGSIFPRIO %s", pri
);
762 setbridge_ifpathcost(const char *ifn
, const char *cost
, int s
,
763 const struct afswtch
*afp
)
768 memset(&req
, 0, sizeof(req
));
770 if (get_val(cost
, &val
) < 0)
771 errx(1, "invalid value: %s", cost
);
773 strlcpy(req
.ifbr_ifsname
, ifn
, sizeof(req
.ifbr_ifsname
));
774 req
.ifbr_path_cost
= val
;
776 if (do_cmd(s
, BRDGSIFCOST
, &req
, sizeof(req
), 1) < 0)
777 err(1, "BRDGSIFCOST %s", cost
);
782 setbridge_ifmaxaddr(const char *ifn
, const char *arg
, int s
,
783 const struct afswtch
*afp
)
788 memset(&req
, 0, sizeof(req
));
790 if (get_val(arg
, &val
) < 0 || (val
& ~0xffffffff) != 0)
791 errx(1, "invalid value: %s", arg
);
793 strlcpy(req
.ifbr_ifsname
, ifn
, sizeof(req
.ifbr_ifsname
));
794 req
.ifbr_addrmax
= val
& 0xffffffff;
796 if (do_cmd(s
, BRDGSIFAMAX
, &req
, sizeof(req
), 1) < 0)
797 err(1, "BRDGSIFAMAX %s", arg
);
802 setbridge_timeout(const char *arg
, int d
, int s
, const struct afswtch
*afp
)
804 struct ifbrparam param
;
807 if (get_val(arg
, &val
) < 0 || (val
& ~0xffffffff) != 0)
808 errx(1, "invalid value: %s", arg
);
810 param
.ifbrp_ctime
= val
& 0xffffffff;
812 if (do_cmd(s
, BRDGSTO
, ¶m
, sizeof(param
), 1) < 0)
813 err(1, "BRDGSTO %s", arg
);
818 setbridge_private(const char *val
, int d
, int s
, const struct afswtch
*afp
)
821 do_bridgeflag(s
, val
, IFBIF_PRIVATE
, 1);
825 unsetbridge_private(const char *val
, int d
, int s
, const struct afswtch
*afp
)
828 do_bridgeflag(s
, val
, IFBIF_PRIVATE
, 0);
834 setbridge_hostfilter(const char *ifn
, const char *addr
, int s
,
835 const struct afswtch
*afp
)
837 struct ifbrhostfilter req
;
838 struct ether_addr
*ea
;
841 memset(&req
, 0, sizeof(req
));
842 req
.ifbrhf_flags
= IFBRHF_ENABLED
;
844 strlcpy(req
.ifbrhf_ifsname
, ifn
, sizeof(req
.ifbrhf_ifsname
));
846 ea
= ether_aton(addr
);
848 req
.ifbrhf_flags
|= IFBRHF_HWSRC
;
849 bcopy(ea
, req
.ifbrhf_hwsrca
, sizeof(req
.ifbrhf_hwsrca
));
850 } else if (inet_aton(addr
, &in
) != 0) {
851 req
.ifbrhf_flags
|= IFBRHF_IPSRC
;
852 req
.ifbrhf_ipsrc
= in
.s_addr
;
854 errx(1, "invalid address: %s", addr
);
856 if (do_cmd(s
, BRDGSHOSTFILTER
, &req
, sizeof(req
), 1) < 0)
857 err(1, "BRDGSHOSTFILTER %s %s", ifn
, addr
);
861 unsetbridge_hostfilter(const char *ifn
, int d
, int s
, const struct afswtch
*afp
)
863 struct ifbrhostfilter req
;
865 memset(&req
, 0, sizeof(req
));
866 strlcpy(req
.ifbrhf_ifsname
, ifn
, sizeof(req
.ifbrhf_ifsname
));
868 if (do_cmd(s
, BRDGSHOSTFILTER
, &req
, sizeof(req
), 1) < 0)
869 err(1, "BRDGSHOSTFILTER");
872 #if __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ >= 135000
874 setbridge_macnat(const char *val
, int d
, int s
, const struct afswtch
*afp
)
877 do_bridgeflag(s
, val
, IFBIF_MAC_NAT
, 1);
881 unsetbridge_macnat(const char *val
, int d
, int s
, const struct afswtch
*afp
)
884 do_bridgeflag(s
, val
, IFBIF_MAC_NAT
, 0);
888 static struct cmd bridge_cmds
[] = {
889 DEF_CMD_ARG("addm", setbridge_add
),
890 DEF_CMD_ARG("deletem", setbridge_delete
),
891 DEF_CMD_ARG("discover", setbridge_discover
),
892 DEF_CMD_ARG("-discover", unsetbridge_discover
),
893 DEF_CMD_ARG("learn", setbridge_learn
),
894 DEF_CMD_ARG("-learn", unsetbridge_learn
),
896 DEF_CMD_ARG("sticky", setbridge_sticky
),
897 DEF_CMD_ARG("-sticky", unsetbridge_sticky
),
898 DEF_CMD_ARG("span", setbridge_span
),
899 DEF_CMD_ARG("-span", unsetbridge_span
),
901 DEF_CMD_ARG("stp", setbridge_stp
),
902 DEF_CMD_ARG("-stp", unsetbridge_stp
),
904 DEF_CMD_ARG("edge", setbridge_edge
),
905 DEF_CMD_ARG("-edge", unsetbridge_edge
),
906 DEF_CMD_ARG("autoedge", setbridge_autoedge
),
907 DEF_CMD_ARG("-autoedge", unsetbridge_autoedge
),
908 DEF_CMD_ARG("ptp", setbridge_ptp
),
909 DEF_CMD_ARG("-ptp", unsetbridge_ptp
),
910 DEF_CMD_ARG("autoptp", setbridge_autoptp
),
911 DEF_CMD_ARG("-autoptp", unsetbridge_autoptp
),
913 DEF_CMD("flush", 0, setbridge_flush
),
914 DEF_CMD("flushall", 0, setbridge_flushall
),
915 DEF_CMD_ARG2("static", setbridge_static
),
916 DEF_CMD_ARG("deladdr", setbridge_deladdr
),
917 DEF_CMD("addr", 1, setbridge_addr
),
918 DEF_CMD_ARG("maxaddr", setbridge_maxaddr
),
919 DEF_CMD_ARG("hellotime", setbridge_hellotime
),
920 DEF_CMD_ARG("fwddelay", setbridge_fwddelay
),
921 DEF_CMD_ARG("maxage", setbridge_maxage
),
922 DEF_CMD_ARG("priority", setbridge_priority
),
924 DEF_CMD_ARG("proto", setbridge_protocol
),
925 DEF_CMD_ARG("holdcnt", setbridge_holdcount
),
927 DEF_CMD_ARG2("ifpriority", setbridge_ifpriority
),
928 DEF_CMD_ARG2("ifpathcost", setbridge_ifpathcost
),
930 DEF_CMD_ARG2("ifmaxaddr", setbridge_ifmaxaddr
),
932 DEF_CMD_ARG("timeout", setbridge_timeout
),
934 DEF_CMD_ARG("private", setbridge_private
),
935 DEF_CMD_ARG("-private", unsetbridge_private
),
937 DEF_CMD_ARG2("hostfilter", setbridge_hostfilter
),
938 DEF_CMD_ARG("-hostfilter", unsetbridge_hostfilter
),
939 #if __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ >= 135000
940 DEF_CMD_ARG("macnat", setbridge_macnat
),
941 DEF_CMD_ARG("-macnat", unsetbridge_macnat
),
944 static struct afswtch af_bridge
= {
945 .af_name
= "af_bridge",
947 .af_other_status
= bridge_status
,
950 static __constructor
void
953 #define N(a) (sizeof(a) / sizeof(a[0]))
956 for (i
= 0; i
< N(bridge_cmds
); i
++)
957 cmd_register(&bridge_cmds
[i
]);
958 af_register(&af_bridge
);