Bug Summary

File:src/sbin/ifconfig/brconfig.c
Warning:line 816, column 2
Value stored to 'ifrp' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name brconfig.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/sbin/ifconfig/obj -resource-dir /usr/local/lib/clang/13.0.0 -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/sbin/ifconfig/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/sbin/ifconfig/brconfig.c
1/* $OpenBSD: brconfig.c,v 1.30 2021/11/11 09:39:16 claudio Exp $ */
2
3/*
4 * Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net)
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
24 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
25 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#ifndef SMALL
30
31#include <stdio.h>
32#include <sys/types.h>
33#include <sys/stdint.h>
34#include <unistd.h>
35#include <stdlib.h>
36#include <sys/socket.h>
37#include <sys/ioctl.h>
38#include <net/if.h>
39#include <netinet/in.h>
40#include <netinet/if_ether.h>
41#include <net/if_bridge.h>
42#include <netdb.h>
43#include <string.h>
44#include <err.h>
45#include <errno(*__errno()).h>
46#include <getopt.h>
47#include <limits.h>
48#include <arpa/inet.h>
49
50#include "ifconfig.h"
51
52void bridge_ifsetflag(const char *, u_int32_t);
53void bridge_ifclrflag(const char *, u_int32_t);
54
55void bridge_list(char *);
56void bridge_cfg(const char *);
57void bridge_badrule(int, char **, int);
58void bridge_showrule(struct ifbrlreq *);
59int bridge_arprule(struct ifbrlreq *, int *, char ***);
60
61#define IFBAFBITS"\020\1STATIC" "\020\1STATIC"
62#define IFBIFBITS"\020\1LEARNING\2DISCOVER\3BLOCKNONIP\4STP\5EDGE\6AUTOEDGE\7PTP\10AUTOPTP\11SPAN\15LOCAL" \
63"\020\1LEARNING\2DISCOVER\3BLOCKNONIP\4STP\5EDGE\6AUTOEDGE\7PTP\10AUTOPTP\11SPAN\15LOCAL"
64
65#define PV2ID(pv, epri, eaddr)do { epri = pv >> 48; eaddr[0] = pv >> 40; eaddr[
1] = pv >> 32; eaddr[2] = pv >> 24; eaddr[3] = pv
>> 16; eaddr[4] = pv >> 8; eaddr[5] = pv >>
0; } while (0)
do { \
66 epri = pv >> 48; \
67 eaddr[0] = pv >> 40; \
68 eaddr[1] = pv >> 32; \
69 eaddr[2] = pv >> 24; \
70 eaddr[3] = pv >> 16; \
71 eaddr[4] = pv >> 8; \
72 eaddr[5] = pv >> 0; \
73} while (0)
74
75char *stpstates[] = {
76 "disabled",
77 "listening",
78 "learning",
79 "forwarding",
80 "blocking",
81 "discarding"
82};
83char *stpproto[] = {
84 "stp",
85 "(none)",
86 "rstp",
87};
88char *stproles[] = {
89 "disabled",
90 "root",
91 "designated",
92 "alternate",
93 "backup"
94};
95
96
97void
98setdiscover(const char *val, int d)
99{
100 bridge_ifsetflag(val, IFBIF_DISCOVER0x0002);
101}
102
103void
104unsetdiscover(const char *val, int d)
105{
106 bridge_ifclrflag(val, IFBIF_DISCOVER0x0002);
107}
108
109void
110setblocknonip(const char *val, int d)
111{
112 bridge_ifsetflag(val, IFBIF_BLOCKNONIP0x0004);
113}
114
115void
116unsetblocknonip(const char *val, int d)
117{
118 bridge_ifclrflag(val, IFBIF_BLOCKNONIP0x0004);
119}
120
121void
122setlearn(const char *val, int d)
123{
124 bridge_ifsetflag(val, IFBIF_LEARNING0x0001);
125}
126
127void
128unsetlearn(const char *val, int d)
129{
130 bridge_ifclrflag(val, IFBIF_LEARNING0x0001);
131}
132
133void
134setstp(const char *val, int d)
135{
136 bridge_ifsetflag(val, IFBIF_STP0x0008);
137}
138
139void
140unsetstp(const char *val, int d)
141{
142 bridge_ifclrflag(val, IFBIF_STP0x0008);
143}
144
145void
146setedge(const char *val, int d)
147{
148 bridge_ifsetflag(val, IFBIF_BSTP_EDGE0x0010);
149}
150
151void
152unsetedge(const char *val, int d)
153{
154 bridge_ifclrflag(val, IFBIF_BSTP_EDGE0x0010);
155}
156
157void
158setautoedge(const char *val, int d)
159{
160 bridge_ifsetflag(val, IFBIF_BSTP_AUTOEDGE0x0020);
161}
162
163void
164unsetautoedge(const char *val, int d)
165{
166 bridge_ifclrflag(val, IFBIF_BSTP_AUTOEDGE0x0020);
167}
168
169void
170setptp(const char *val, int d)
171{
172 bridge_ifsetflag(val, IFBIF_BSTP_PTP0x0040);
173}
174
175void
176unsetptp(const char *val, int d)
177{
178 bridge_ifclrflag(val, IFBIF_BSTP_PTP0x0040);
179}
180
181void
182setautoptp(const char *val, int d)
183{
184 bridge_ifsetflag(val, IFBIF_BSTP_AUTOPTP0x0080);
185}
186
187void
188unsetautoptp(const char *val, int d)
189{
190 bridge_ifclrflag(val, IFBIF_BSTP_AUTOPTP0x0080);
191}
192
193void
194addlocal(const char *ifsname, int d)
195{
196 struct ifbreq breq;
197
198 if (strncmp(ifsname, "vether", (sizeof("vether") - 1)) != 0)
199 errx(1, "only vether can be local interface");
200
201 /* Add local */
202 strlcpy(breq.ifbr_name, ifname, sizeof(breq.ifbr_name));
203 strlcpy(breq.ifbr_ifsname, ifsname, sizeof(breq.ifbr_ifsname));
204 if (ioctl(sock, SIOCBRDGADDL((unsigned long)0x80000000 | ((sizeof(struct ifbreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((73)))
, (caddr_t)&breq) == -1) {
205 if (errno(*__errno()) == EEXIST17)
206 return;
207 else
208 err(1, "%s: ioctl SIOCBRDGADDL %s", ifname, ifsname);
209 }
210}
211
212void
213bridge_ifsetflag(const char *ifsname, u_int32_t flag)
214{
215 struct ifbreq req;
216
217 strlcpy(req.ifbr_name, ifname, sizeof(req.ifbr_name));
218 strlcpy(req.ifbr_ifsname, ifsname, sizeof(req.ifbr_ifsname));
219 if (ioctl(sock, SIOCBRDGGIFFLGS(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifbreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((62)))
, (caddr_t)&req) == -1)
220 err(1, "%s: ioctl SIOCBRDGGIFFLGS %s", ifname, ifsname);
221
222 req.ifbr_ifsflags |= flag & ~IFBIF_RO_MASK0x0f00;
223
224 if (ioctl(sock, SIOCBRDGSIFFLGS((unsigned long)0x80000000 | ((sizeof(struct ifbreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((63)))
, (caddr_t)&req) == -1)
225 err(1, "%s: ioctl SIOCBRDGSIFFLGS %s", ifname, ifsname);
226}
227
228void
229bridge_ifclrflag(const char *ifsname, u_int32_t flag)
230{
231 struct ifbreq req;
232
233 strlcpy(req.ifbr_name, ifname, sizeof(req.ifbr_name));
234 strlcpy(req.ifbr_ifsname, ifsname, sizeof(req.ifbr_ifsname));
235
236 if (ioctl(sock, SIOCBRDGGIFFLGS(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifbreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((62)))
, (caddr_t)&req) == -1)
237 err(1, "%s: ioctl SIOCBRDGGIFFLGS %s", ifname, ifsname);
238
239 req.ifbr_ifsflags &= ~(flag | IFBIF_RO_MASK0x0f00);
240
241 if (ioctl(sock, SIOCBRDGSIFFLGS((unsigned long)0x80000000 | ((sizeof(struct ifbreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((63)))
, (caddr_t)&req) == -1)
242 err(1, "%s: ioctl SIOCBRDGSIFFLGS %s", ifname, ifsname);
243}
244
245void
246bridge_flushall(const char *val, int p)
247{
248 struct ifbreq req;
249
250 strlcpy(req.ifbr_name, ifname, sizeof(req.ifbr_name));
251 req.ifbr_ifsflags = IFBF_FLUSHALL0x1;
252 if (ioctl(sock, SIOCBRDGFLUSH((unsigned long)0x80000000 | ((sizeof(struct ifbreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((72)))
, &req) == -1)
253 err(1, "%s", ifname);
254}
255
256void
257bridge_flush(const char *val, int p)
258{
259 struct ifbreq req;
260
261 strlcpy(req.ifbr_name, ifname, sizeof(req.ifbr_name));
262 req.ifbr_ifsflags = IFBF_FLUSHDYN0x0;
263 if (ioctl(sock, SIOCBRDGFLUSH((unsigned long)0x80000000 | ((sizeof(struct ifbreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((72)))
, &req) == -1)
264 err(1, "%s", ifname);
265}
266
267void
268bridge_cfg(const char *delim)
269{
270 struct ifbropreq ifbp;
271 u_int16_t pri;
272 u_int8_t ht, fd, ma, hc, proto;
273 u_int8_t lladdr[ETHER_ADDR_LEN6];
274 u_int16_t bprio;
275
276 strlcpy(ifbp.ifbop_name, ifname, sizeof(ifbp.ifbop_name));
277 if (ioctl(sock, SIOCBRDGGPARAM(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifbropreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((88)))
, (caddr_t)&ifbp) == -1) {
278 if (errno(*__errno()) == ENOTTY25)
279 return;
280 err(1, "%s SIOCBRDGGPARAM", ifname);
281 }
282
283 printf("%s", delim);
284 pri = ifbp.ifbop_priority;
285 ht = ifbp.ifbop_hellotime;
286 fd = ifbp.ifbop_fwddelay;
287 ma = ifbp.ifbop_maxage;
288 hc = ifbp.ifbop_holdcount;
289 proto = ifbp.ifbop_protocol;
290
291 printf("priority %u hellotime %u fwddelay %u maxage %u "
292 "holdcnt %u proto %s\n", pri, ht, fd, ma, hc, stpproto[proto]);
293
294 if (aflag)
295 return;
296
297 PV2ID(ifbp.ifbop_desg_bridge, bprio, lladdr)do { bprio = ifbp.ifbop_desg_bridge >> 48; lladdr[0] = ifbp
.ifbop_desg_bridge >> 40; lladdr[1] = ifbp.ifbop_desg_bridge
>> 32; lladdr[2] = ifbp.ifbop_desg_bridge >> 24;
lladdr[3] = ifbp.ifbop_desg_bridge >> 16; lladdr[4] = ifbp
.ifbop_desg_bridge >> 8; lladdr[5] = ifbp.ifbop_desg_bridge
>> 0; } while (0)
;
298 printf("\tdesignated: id %s priority %u\n",
299 ether_ntoa((struct ether_addr *)lladdr), bprio);
300
301 if (ifbp.ifbop_root_bridge == ifbp.ifbop_desg_bridge)
302 return;
303
304 PV2ID(ifbp.ifbop_root_bridge, bprio, lladdr)do { bprio = ifbp.ifbop_root_bridge >> 48; lladdr[0] = ifbp
.ifbop_root_bridge >> 40; lladdr[1] = ifbp.ifbop_root_bridge
>> 32; lladdr[2] = ifbp.ifbop_root_bridge >> 24;
lladdr[3] = ifbp.ifbop_root_bridge >> 16; lladdr[4] = ifbp
.ifbop_root_bridge >> 8; lladdr[5] = ifbp.ifbop_root_bridge
>> 0; } while (0)
;
305 printf("\troot: id %s priority %u ifcost %u port %u\n",
306 ether_ntoa((struct ether_addr *)lladdr), bprio,
307 ifbp.ifbop_root_path_cost, ifbp.ifbop_root_port & 0xfff);
308}
309
310void
311bridge_list(char *delim)
312{
313 struct ifbreq *reqp;
314 struct ifbifconf bifc;
315 int i, len = 8192;
316 char buf[sizeof(reqp->ifbr_ifsname) + 1], *inbuf = NULL((void *)0), *inb;
317
318 while (1) {
319 bifc.ifbic_len = len;
320 inb = realloc(inbuf, len);
321 if (inb == NULL((void *)0))
322 err(1, "malloc");
323 bifc.ifbic_bufifbic_ifbicu.ifbicu_buf = inbuf = inb;
324 strlcpy(bifc.ifbic_name, ifname, sizeof(bifc.ifbic_name));
325 if (ioctl(sock, SIOCBRDGIFS(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifbreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((66)))
, &bifc) == -1) {
326 if (errno(*__errno()) == ENOTTY25)
327 return;
328 err(1, "%s SIOCBRDGIFS", ifname);
329 }
330 if (bifc.ifbic_len + sizeof(*reqp) < len)
331 break;
332 len *= 2;
333 }
334 for (i = 0; i < bifc.ifbic_len / sizeof(*reqp); i++) {
335 reqp = bifc.ifbic_reqifbic_ifbicu.ifbicu_req + i;
336 strlcpy(buf, reqp->ifbr_ifsname, sizeof(buf));
337 printf("%s%s ", delim, buf);
338 printb("flags", reqp->ifbr_ifsflags, IFBIFBITS"\020\1LEARNING\2DISCOVER\3BLOCKNONIP\4STP\5EDGE\6AUTOEDGE\7PTP\10AUTOPTP\11SPAN\15LOCAL");
339 printf("\n");
340 if (reqp->ifbr_ifsflags & IFBIF_SPAN0x0100)
341 continue;
342 printf("\t\t");
343 printf("port %u ifpriority %u ifcost %u",
344 reqp->ifbr_portno, reqp->ifbr_priority,
345 reqp->ifbr_path_cost);
346 if (reqp->ifbr_protected) {
347 int v;
348
349 v = ffs(reqp->ifbr_protected);
350 printf(" protected %u", v);
351 while (++v < 32) {
352 if ((1 << (v - 1)) & reqp->ifbr_protected)
353 printf(",%u", v);
354 }
355 }
356 if (reqp->ifbr_ifsflags & IFBIF_STP0x0008)
357 printf(" %s role %s",
358 stpstates[reqp->ifbr_state],
359 stproles[reqp->ifbr_role]);
360 printf("\n");
361 bridge_rules(buf, 1);
362 }
363 free(bifc.ifbic_bufifbic_ifbicu.ifbicu_buf);
364}
365
366void
367bridge_add(const char *ifn, int d)
368{
369 struct ifbreq req;
370
371 strlcpy(req.ifbr_name, ifname, sizeof(req.ifbr_name));
372 strlcpy(req.ifbr_ifsname, ifn, sizeof(req.ifbr_ifsname));
373 if (ioctl(sock, SIOCBRDGADD((unsigned long)0x80000000 | ((sizeof(struct ifbreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((60)))
, &req) == -1) {
374 if (errno(*__errno()) == EEXIST17)
375 return;
376 err(1, "%s: %s", ifname, ifn);
377 }
378}
379
380void
381bridge_delete(const char *ifn, int d)
382{
383 struct ifbreq req;
384
385 strlcpy(req.ifbr_name, ifname, sizeof(req.ifbr_name));
386 strlcpy(req.ifbr_ifsname, ifn, sizeof(req.ifbr_ifsname));
387 if (ioctl(sock, SIOCBRDGDEL((unsigned long)0x80000000 | ((sizeof(struct ifbreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((61)))
, &req) == -1)
388 err(1, "%s: %s", ifname, ifn);
389}
390
391void
392bridge_addspan(const char *ifn, int d)
393{
394 struct ifbreq req;
395
396 strlcpy(req.ifbr_name, ifname, sizeof(req.ifbr_name));
397 strlcpy(req.ifbr_ifsname, ifn, sizeof(req.ifbr_ifsname));
398 if (ioctl(sock, SIOCBRDGADDS((unsigned long)0x80000000 | ((sizeof(struct ifbreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((65)))
, &req) == -1) {
399 if (errno(*__errno()) == EEXIST17)
400 return;
401 err(1, "%s: %s", ifname, ifn);
402 }
403}
404
405void
406bridge_delspan(const char *ifn, int d)
407{
408 struct ifbreq req;
409
410 strlcpy(req.ifbr_name, ifname, sizeof(req.ifbr_name));
411 strlcpy(req.ifbr_ifsname, ifn, sizeof(req.ifbr_ifsname));
412 if (ioctl(sock, SIOCBRDGDELS((unsigned long)0x80000000 | ((sizeof(struct ifbreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((66)))
, &req) == -1)
413 err(1, "%s: %s", ifname, ifn);
414}
415
416void
417bridge_timeout(const char *arg, int d)
418{
419 struct ifbrparam bp;
420 const char *errstr;
421
422 bp.ifbrp_ctimeifbrp_ifbrpu.ifbrpu_ctime = strtonum(arg, 0, UINT32_MAX0xffffffffU, &errstr);
423 if (errstr)
424 err(1, "timeout %s is: %s", arg, errstr);
425
426 strlcpy(bp.ifbrp_name, ifname, sizeof(bp.ifbrp_name));
427 if (ioctl(sock, SIOCBRDGSTO((unsigned long)0x80000000 | ((sizeof(struct ifbrparam) &
0x1fff) << 16) | ((('i')) << 8) | ((69)))
, (caddr_t)&bp) == -1)
428 err(1, "%s", ifname);
429}
430
431void
432bridge_maxage(const char *arg, int d)
433{
434 struct ifbrparam bp;
435 const char *errstr;
436
437 bp.ifbrp_maxageifbrp_ifbrpu.ifbrpu_maxage = strtonum(arg, 0, UINT8_MAX0xff, &errstr);
438 if (errstr)
439 errx(1, "maxage %s is: %s", arg, errstr);
440
441 strlcpy(bp.ifbrp_name, ifname, sizeof(bp.ifbrp_name));
442 if (ioctl(sock, SIOCBRDGSMA((unsigned long)0x80000000 | ((sizeof(struct ifbrparam) &
0x1fff) << 16) | ((('i')) << 8) | ((83)))
, (caddr_t)&bp) == -1)
443 err(1, "%s", ifname);
444}
445
446void
447bridge_priority(const char *arg, int d)
448{
449 struct ifbrparam bp;
450 const char *errstr;
451
452 bp.ifbrp_prioifbrp_ifbrpu.ifbrpu_prio = strtonum(arg, 0, UINT16_MAX0xffff, &errstr);
453 if (errstr)
454 errx(1, "spanpriority %s is: %s", arg, errstr);
455
456 strlcpy(bp.ifbrp_name, ifname, sizeof(bp.ifbrp_name));
457 if (ioctl(sock, SIOCBRDGSPRI((unsigned long)0x80000000 | ((sizeof(struct ifbrparam) &
0x1fff) << 16) | ((('i')) << 8) | ((80)))
, (caddr_t)&bp) == -1)
458 err(1, "%s", ifname);
459}
460
461void
462bridge_protect(const char *ifsname, const char *val)
463{
464 struct ifbreq breq;
465 unsigned long v;
466 char *optlist, *str;
467 const char *errstr;
468
469 strlcpy(breq.ifbr_name, ifname, sizeof(breq.ifbr_name));
470 strlcpy(breq.ifbr_ifsname, ifsname, sizeof(breq.ifbr_ifsname));
471 breq.ifbr_protected = 0;
472
473 /* We muck with the string, so copy it. */
474 optlist = strdup(val);
475 if (optlist == NULL((void *)0))
476 err(1, "strdup");
477
478 str = strtok(optlist, ",");
479 while (str != NULL((void *)0)) {
480 v = strtonum(str, 1, 31, &errstr);
481 if (errstr)
482 err(1, "protected domain %s is: %s", str, errstr);
483 breq.ifbr_protected |= (1 << (v - 1));
484 str = strtok(NULL((void *)0), ",");
485 }
486
487 if (ioctl(sock, SIOCBRDGSIFPROT((unsigned long)0x80000000 | ((sizeof(struct ifbreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((74)))
, (caddr_t)&breq) == -1)
488 err(1, "%s: %s", ifname, val);
489
490 free(optlist);
491}
492
493void
494bridge_unprotect(const char *ifsname, int d)
495{
496 struct ifbreq breq;
497
498 strlcpy(breq.ifbr_name, ifname, sizeof(breq.ifbr_name));
499 strlcpy(breq.ifbr_ifsname, ifsname, sizeof(breq.ifbr_ifsname));
500
501 breq.ifbr_protected = 0;
502
503 if (ioctl(sock, SIOCBRDGSIFPROT((unsigned long)0x80000000 | ((sizeof(struct ifbreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((74)))
, (caddr_t)&breq) == -1)
504 err(1, "%s: %d", ifname, 0);
505}
506
507void
508bridge_proto(const char *arg, int d)
509{
510 struct ifbrparam bp;
511 int i, proto = -1;
512
513 for (i = 0; i <= BSTP_PROTO_MAX0x02; i++)
514 if (strcmp(arg, stpproto[i]) == 0) {
515 proto = i;
516 break;
517 }
518 if (proto == -1)
519 errx(1, "invalid arg for proto: %s", arg);
520
521 strlcpy(bp.ifbrp_name, ifname, sizeof(bp.ifbrp_name));
522 bp.ifbrp_prioifbrp_ifbrpu.ifbrpu_prio = proto;
523 if (ioctl(sock, SIOCBRDGSPROTO((unsigned long)0x80000000 | ((sizeof(struct ifbrparam) &
0x1fff) << 16) | ((('i')) << 8) | ((90)))
, (caddr_t)&bp) == -1)
524 err(1, "%s", ifname);
525}
526
527void
528bridge_fwddelay(const char *arg, int d)
529{
530 struct ifbrparam bp;
531 const char *errstr;
532
533 bp.ifbrp_fwddelayifbrp_ifbrpu.ifbrpu_fwddelay = strtonum(arg, 0, UINT8_MAX0xff, &errstr);
534 if (errstr)
535 errx(1, "fwddelay %s is: %s", arg, errstr);
536
537 strlcpy(bp.ifbrp_name, ifname, sizeof(bp.ifbrp_name));
538
539 if (ioctl(sock, SIOCBRDGSFD((unsigned long)0x80000000 | ((sizeof(struct ifbrparam) &
0x1fff) << 16) | ((('i')) << 8) | ((82)))
, (caddr_t)&bp) == -1)
540 err(1, "%s", ifname);
541}
542
543void
544bridge_hellotime(const char *arg, int d)
545{
546 struct ifbrparam bp;
547 const char *errstr;
548
549 bp.ifbrp_hellotimeifbrp_ifbrpu.ifbrpu_hellotime = strtonum(arg, 0, UINT8_MAX0xff, &errstr);
550 if (errstr)
551 errx(1, "hellotime %s is: %s", arg, errstr);
552
553 strlcpy(bp.ifbrp_name, ifname, sizeof(bp.ifbrp_name));
554
555 if (ioctl(sock, SIOCBRDGSHT((unsigned long)0x80000000 | ((sizeof(struct ifbrparam) &
0x1fff) << 16) | ((('i')) << 8) | ((81)))
, (caddr_t)&bp) == -1)
556 err(1, "%s", ifname);
557}
558
559void
560bridge_maxaddr(const char *arg, int d)
561{
562 struct ifbrparam bp;
563 unsigned long newsize;
564 const char *errstr;
565
566 bp.ifbrp_csizeifbrp_ifbrpu.ifbrpu_csize = strtonum(arg, 0, UINT32_MAX0xffffffffU, &errstr);
567 if (errstr)
568 errx(1, "maxaddr %s is: %s", arg, errstr);
569
570 strlcpy(bp.ifbrp_name, ifname, sizeof(bp.ifbrp_name));
571 if (ioctl(sock, SIOCBRDGSCACHE((unsigned long)0x80000000 | ((sizeof(struct ifbrparam) &
0x1fff) << 16) | ((('i')) << 8) | ((64)))
, (caddr_t)&bp) == -1)
572 err(1, "%s", ifname);
573}
574
575void
576bridge_deladdr(const char *addr, int d)
577{
578 struct ifbareq ifba;
579 struct ether_addr *ea;
580
581 strlcpy(ifba.ifba_name, ifname, sizeof(ifba.ifba_name));
582 ea = ether_aton(addr);
583 if (ea == NULL((void *)0))
584 err(1, "Invalid address: %s", addr);
585
586 bcopy(ea, &ifba.ifba_dst, sizeof(struct ether_addr));
587
588 if (ioctl(sock, SIOCBRDGDADDR((unsigned long)0x80000000 | ((sizeof(struct ifbareq) & 0x1fff
) << 16) | ((('i')) << 8) | ((71)))
, &ifba) == -1)
589 err(1, "%s: %s", ifname, addr);
590}
591
592void
593bridge_ifprio(const char *ifsname, const char *val)
594{
595 struct ifbreq breq;
596 const char *errstr;
597
598 breq.ifbr_priority = strtonum(val, 0, UINT8_MAX0xff, &errstr);
599 if (errstr)
600 errx(1, "ifpriority %s is: %s", val, errstr);
601
602 strlcpy(breq.ifbr_name, ifname, sizeof(breq.ifbr_name));
603 strlcpy(breq.ifbr_ifsname, ifsname, sizeof(breq.ifbr_ifsname));
604
605 if (ioctl(sock, SIOCBRDGSIFPRIO((unsigned long)0x80000000 | ((sizeof(struct ifbreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((84)))
, (caddr_t)&breq) == -1)
606 err(1, "%s: %s", ifname, val);
607}
608
609void
610bridge_ifcost(const char *ifsname, const char *val)
611{
612 struct ifbreq breq;
613 const char *errstr;
614
615 breq.ifbr_path_cost = strtonum(val, 0, UINT32_MAX0xffffffffU, &errstr);
616 if (errstr)
617 errx(1, "ifcost %s is: %s", val, errstr);
618
619 strlcpy(breq.ifbr_name, ifname, sizeof(breq.ifbr_name));
620 strlcpy(breq.ifbr_ifsname, ifsname, sizeof(breq.ifbr_ifsname));
621
622 if (ioctl(sock, SIOCBRDGSIFCOST((unsigned long)0x80000000 | ((sizeof(struct ifbreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((85)))
, (caddr_t)&breq) == -1)
623 err(1, "%s: %s", ifname, val);
624}
625
626void
627bridge_noifcost(const char *ifsname, int d)
628{
629 struct ifbreq breq;
630
631 strlcpy(breq.ifbr_name, ifname, sizeof(breq.ifbr_name));
632 strlcpy(breq.ifbr_ifsname, ifsname, sizeof(breq.ifbr_ifsname));
633
634 breq.ifbr_path_cost = 0;
635
636 if (ioctl(sock, SIOCBRDGSIFCOST((unsigned long)0x80000000 | ((sizeof(struct ifbreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((85)))
, (caddr_t)&breq) == -1)
637 err(1, "%s", ifname);
638}
639
640void
641bridge_addaddr(const char *ifsname, const char *addr)
642{
643 struct ifbareq ifba;
644 struct ether_addr *ea;
645
646 strlcpy(ifba.ifba_name, ifname, sizeof(ifba.ifba_name));
647 strlcpy(ifba.ifba_ifsname, ifsname, sizeof(ifba.ifba_ifsname));
648
649 ea = ether_aton(addr);
650 if (ea == NULL((void *)0))
651 errx(1, "Invalid address: %s", addr);
652
653 bcopy(ea, &ifba.ifba_dst, sizeof(struct ether_addr));
654 ifba.ifba_flags = IFBAF_STATIC0x01;
655
656 if (ioctl(sock, SIOCBRDGSADDR(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifbareq) & 0x1fff) << 16) | ((('i')) <<
8) | ((68)))
, &ifba) == -1)
657 err(1, "%s: %s", ifname, addr);
658}
659
660void
661bridge_addrs(const char *delim, int d)
662{
663 char dstaddr[NI_MAXHOST256];
664 char dstport[NI_MAXSERV32];
665 const int niflag = NI_NUMERICHOST1|NI_DGRAM16;
666 struct ifbaconf ifbac;
667 struct ifbareq *ifba;
668 char *inbuf = NULL((void *)0), buf[sizeof(ifba->ifba_ifsname) + 1], *inb;
669 struct sockaddr *sa;
670 int i, len = 8192;
671
672 /* ifconfig will call us with the argv of the command */
673 if (strcmp(delim, "addr") == 0)
674 delim = "";
675
676 while (1) {
677 ifbac.ifbac_len = len;
678 inb = realloc(inbuf, len);
679 if (inb == NULL((void *)0))
680 err(1, "malloc");
681 ifbac.ifbac_bufifbac_ifbacu.ifbacu_buf = inbuf = inb;
682 strlcpy(ifbac.ifbac_name, ifname, sizeof(ifbac.ifbac_name));
683 if (ioctl(sock, SIOCBRDGRTS(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifbaconf) & 0x1fff) << 16) | ((('i')) <<
8) | ((67)))
, &ifbac) == -1) {
684 if (errno(*__errno()) == ENETDOWN50)
685 return;
686 err(1, "%s", ifname);
687 }
688 if (ifbac.ifbac_len + sizeof(*ifba) < len)
689 break;
690 len *= 2;
691 }
692
693 for (i = 0; i < ifbac.ifbac_len / sizeof(*ifba); i++) {
694 ifba = ifbac.ifbac_reqifbac_ifbacu.ifbacu_req + i;
695 strlcpy(buf, ifba->ifba_ifsname, sizeof(buf));
696 printf("%s%s %s %u ", delim, ether_ntoa(&ifba->ifba_dst),
697 buf, ifba->ifba_age);
698 sa = (struct sockaddr *)&ifba->ifba_dstsa;
699 printb("flags", ifba->ifba_flags, IFBAFBITS"\020\1STATIC");
700 if (sa->sa_family != AF_UNSPEC0 &&
701 getnameinfo(sa, sa->sa_len,
702 dstaddr, sizeof(dstaddr),
703 dstport, sizeof(dstport), niflag) == 0)
704 printf(" tunnel %s:%s", dstaddr, dstport);
705 printf("\n");
706 }
707 free(inbuf);
708}
709
710void
711bridge_holdcnt(const char *value, int d)
712{
713 struct ifbrparam bp;
714 const char *errstr;
715
716 bp.ifbrp_txhcifbrp_ifbrpu.ifbrpu_txhc = strtonum(value, 0, UINT8_MAX0xff, &errstr);
717 if (errstr)
718 err(1, "holdcnt %s is: %s", value, errstr);
719
720 strlcpy(bp.ifbrp_name, ifname, sizeof(bp.ifbrp_name));
721 if (ioctl(sock, SIOCBRDGSTXHC((unsigned long)0x80000000 | ((sizeof(struct ifbrparam) &
0x1fff) << 16) | ((('i')) << 8) | ((89)))
, (caddr_t)&bp) == -1)
722 err(1, "%s", ifname);
723}
724
725/*
726 * Check to make sure interface is really a bridge interface.
727 */
728int
729is_bridge()
730{
731 struct ifbaconf ifbac;
732
733 ifbac.ifbac_len = 0;
734 strlcpy(ifbac.ifbac_name, ifname, sizeof(ifbac.ifbac_name));
735 if (ioctl(sock, SIOCBRDGRTS(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifbaconf) & 0x1fff) << 16) | ((('i')) <<
8) | ((67)))
, (caddr_t)&ifbac) == -1) {
736 if (errno(*__errno()) == ENETDOWN50)
737 return (1);
738 return (0);
739 }
740 return (1);
741}
742
743/* no tpmr(4) specific ioctls, name is enough if ifconfig.c:printif() passed */
744int
745is_tpmr(void)
746{
747 return (strncmp(ifname, "tpmr", sizeof("tpmr") - 1) == 0);
748}
749
750void
751bridge_status(void)
752{
753 struct ifbrparam bp1, bp2;
754
755 if (is_tpmr()) {
756 bridge_list("\t");
757 return;
758 }
759
760 if (!is_bridge())
761 return;
762
763 bridge_cfg("\t");
764 bridge_list("\t");
765
766 if (aflag && !ifaliases)
767 return;
768
769 strlcpy(bp1.ifbrp_name, ifname, sizeof(bp1.ifbrp_name));
770 if (ioctl(sock, SIOCBRDGGCACHE(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifbrparam) & 0x1fff) << 16) | ((('i')) <<
8) | ((65)))
, (caddr_t)&bp1) == -1)
771 return;
772
773 strlcpy(bp2.ifbrp_name, ifname, sizeof(bp2.ifbrp_name));
774 if (ioctl(sock, SIOCBRDGGTO(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifbrparam) & 0x1fff) << 16) | ((('i')) <<
8) | ((70)))
, (caddr_t)&bp2) == -1)
775 return;
776
777 printf("\tAddresses (max cache: %u, timeout: %u):\n",
778 bp1.ifbrp_csizeifbrp_ifbrpu.ifbrpu_csize, bp2.ifbrp_ctimeifbrp_ifbrpu.ifbrpu_ctime);
779
780 bridge_addrs("\t\t", 0);
781}
782
783void
784bridge_flushrule(const char *ifsname, int d)
785{
786 struct ifbrlreq req;
787
788 strlcpy(req.ifbr_name, ifname, sizeof(req.ifbr_name));
789 strlcpy(req.ifbr_ifsname, ifsname, sizeof(req.ifbr_ifsname));
790 if (ioctl(sock, SIOCBRDGFRL((unsigned long)0x80000000 | ((sizeof(struct ifbrlreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((78)))
, &req) == -1)
791 err(1, "%s: %s", ifname, ifsname);
792}
793
794void
795bridge_rules(const char *ifsname, int usetab)
796{
797 char *inbuf = NULL((void *)0), *inb;
798 struct ifbrlconf ifc;
799 struct ifbrlreq *ifrp;
800 int len = 8192, i;
801
802 while (1) {
803 ifc.ifbrl_len = len;
804 inb = realloc(inbuf, len);
805 if (inb == NULL((void *)0))
806 err(1, "malloc");
807 ifc.ifbrl_bufifbrl_ifbrlu.ifbrlu_buf = inbuf = inb;
808 strlcpy(ifc.ifbrl_name, ifname, sizeof(ifc.ifbrl_name));
809 strlcpy(ifc.ifbrl_ifsname, ifsname, sizeof(ifc.ifbrl_ifsname));
810 if (ioctl(sock, SIOCBRDGGRL(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifbrlconf) & 0x1fff) << 16) | ((('i')) <<
8) | ((79)))
, &ifc) == -1)
811 err(1, "ioctl(SIOCBRDGGRL)");
812 if (ifc.ifbrl_len + sizeof(*ifrp) < len)
813 break;
814 len *= 2;
815 }
816 ifrp = ifc.ifbrl_reqifbrl_ifbrlu.ifbrlu_req;
Value stored to 'ifrp' is never read
817 for (i = 0; i < ifc.ifbrl_len; i += sizeof(*ifrp)) {
818 ifrp = (struct ifbrlreq *)((caddr_t)ifc.ifbrl_reqifbrl_ifbrlu.ifbrlu_req + i);
819
820 if (usetab)
821 printf("\t");
822
823 bridge_showrule(ifrp);
824 }
825}
826
827void
828bridge_showrule(struct ifbrlreq *r)
829{
830 if (r->ifbr_action == BRL_ACTION_BLOCK0x01)
831 printf("block ");
832 else if (r->ifbr_action == BRL_ACTION_PASS0x02)
833 printf("pass ");
834 else
835 printf("[neither block nor pass?]\n");
836
837 if ((r->ifbr_flags & (BRL_FLAG_IN0x08 | BRL_FLAG_OUT0x04)) ==
838 (BRL_FLAG_IN0x08 | BRL_FLAG_OUT0x04))
839 printf("in/out ");
840 else if (r->ifbr_flags & BRL_FLAG_IN0x08)
841 printf("in ");
842 else if (r->ifbr_flags & BRL_FLAG_OUT0x04)
843 printf("out ");
844 else
845 printf("[neither in nor out?]\n");
846
847 printf("on %s", r->ifbr_ifsname);
848
849 if (r->ifbr_flags & BRL_FLAG_SRCVALID0x02)
850 printf(" src %s", ether_ntoa(&r->ifbr_src));
851 if (r->ifbr_flags & BRL_FLAG_DSTVALID0x01)
852 printf(" dst %s", ether_ntoa(&r->ifbr_dst));
853 if (r->ifbr_tagname[0])
854 printf(" tag %s", r->ifbr_tagname);
855
856 if (r->ifbr_arpf.brla_flags & BRLA_ARP0x01)
857 printf(" arp");
858 if (r->ifbr_arpf.brla_flags & BRLA_RARP0x02)
859 printf(" rarp");
860 if (r->ifbr_arpf.brla_op == ARPOP_REQUEST1 ||
861 r->ifbr_arpf.brla_op == ARPOP_REVREQUEST3)
862 printf(" request");
863 if (r->ifbr_arpf.brla_op == ARPOP_REPLY2 ||
864 r->ifbr_arpf.brla_op == ARPOP_REVREPLY4)
865 printf(" reply");
866 if (r->ifbr_arpf.brla_flags & BRLA_SHA0x10)
867 printf(" sha %s", ether_ntoa(&r->ifbr_arpf.brla_sha));
868 if (r->ifbr_arpf.brla_flags & BRLA_THA0x40)
869 printf(" tha %s", ether_ntoa(&r->ifbr_arpf.brla_tha));
870 if (r->ifbr_arpf.brla_flags & BRLA_SPA0x20)
871 printf(" spa %s", inet_ntoa(r->ifbr_arpf.brla_spa));
872 if (r->ifbr_arpf.brla_flags & BRLA_TPA0x80)
873 printf(" tpa %s", inet_ntoa(r->ifbr_arpf.brla_tpa));
874
875 printf("\n");
876}
877
878/*
879 * Parse a rule definition and send it upwards.
880 *
881 * Syntax:
882 * {block|pass} {in|out|in/out} on {ifs} [src {mac}] [dst {mac}]
883 */
884int
885bridge_rule(int targc, char **targv, int ln)
886{
887 char **argv = targv;
888 int argc = targc;
889 struct ifbrlreq rule;
890 struct ether_addr *ea, *dea;
891
892 if (argc == 0) {
893 warnx("invalid rule");
894 return (1);
895 }
896 bzero(&rule, sizeof(rule));
897 strlcpy(rule.ifbr_name, ifname, sizeof(rule.ifbr_name));
898
899 if (strcmp(argv[0], "block") == 0)
900 rule.ifbr_action = BRL_ACTION_BLOCK0x01;
901 else if (strcmp(argv[0], "pass") == 0)
902 rule.ifbr_action = BRL_ACTION_PASS0x02;
903 else
904 goto bad_rule;
905 argc--; argv++;
906
907 if (argc == 0) {
908 bridge_badrule(targc, targv, ln);
909 return (1);
910 }
911 if (strcmp(argv[0], "in") == 0)
912 rule.ifbr_flags |= BRL_FLAG_IN0x08;
913 else if (strcmp(argv[0], "out") == 0)
914 rule.ifbr_flags |= BRL_FLAG_OUT0x04;
915 else if (strcmp(argv[0], "in/out") == 0)
916 rule.ifbr_flags |= BRL_FLAG_IN0x08 | BRL_FLAG_OUT0x04;
917 else if (strcmp(argv[0], "on") == 0) {
918 rule.ifbr_flags |= BRL_FLAG_IN0x08 | BRL_FLAG_OUT0x04;
919 argc++; argv--;
920 } else
921 goto bad_rule;
922 argc--; argv++;
923
924 if (argc == 0 || strcmp(argv[0], "on"))
925 goto bad_rule;
926 argc--; argv++;
927
928 if (argc == 0)
929 goto bad_rule;
930 strlcpy(rule.ifbr_ifsname, argv[0], sizeof(rule.ifbr_ifsname));
931 argc--; argv++;
932
933 while (argc) {
934 dea = NULL((void *)0);
935 if (strcmp(argv[0], "dst") == 0) {
936 if (rule.ifbr_flags & BRL_FLAG_DSTVALID0x01)
937 goto bad_rule;
938 rule.ifbr_flags |= BRL_FLAG_DSTVALID0x01;
939 dea = &rule.ifbr_dst;
940 argc--; argv++;
941 } else if (strcmp(argv[0], "src") == 0) {
942 if (rule.ifbr_flags & BRL_FLAG_SRCVALID0x02)
943 goto bad_rule;
944 rule.ifbr_flags |= BRL_FLAG_SRCVALID0x02;
945 dea = &rule.ifbr_src;
946 argc--; argv++;
947 } else if (strcmp(argv[0], "tag") == 0) {
948 if (argc < 2) {
949 warnx("missing tag name");
950 goto bad_rule;
951 }
952 if (rule.ifbr_tagname[0]) {
953 warnx("tag already defined");
954 goto bad_rule;
955 }
956 argc--; argv++;
957 if (strlcpy(rule.ifbr_tagname, argv[0],
958 PF_TAG_NAME_SIZE64) > PF_TAG_NAME_SIZE64) {
959 warnx("tag name '%s' too long", argv[0]);
960 goto bad_rule;
961 }
962 argc--; argv++;
963 } else if (strcmp(argv[0], "arp") == 0) {
964 rule.ifbr_arpf.brla_flags |= BRLA_ARP0x01;
965 argc--; argv++;
966 if (bridge_arprule(&rule, &argc, &argv) == -1)
967 goto bad_rule;
968 } else if (strcmp(argv[0], "rarp") == 0) {
969 rule.ifbr_arpf.brla_flags |= BRLA_RARP0x02;
970 argc--; argv++;
971 if (bridge_arprule(&rule, &argc, &argv) == -1)
972 goto bad_rule;
973 } else
974 goto bad_rule;
975
976 if (dea != NULL((void *)0)) {
977 if (argc == 0)
978 goto bad_rule;
979 ea = ether_aton(argv[0]);
980 if (ea == NULL((void *)0)) {
981 warnx("invalid address: %s", argv[0]);
982 return (1);
983 }
984 bcopy(ea, dea, sizeof(*dea));
985 argc--; argv++;
986 }
987 }
988
989 if (ioctl(sock, SIOCBRDGARL((unsigned long)0x80000000 | ((sizeof(struct ifbrlreq) & 0x1fff
) << 16) | ((('i')) << 8) | ((77)))
, &rule) == -1) {
990 warn("%s", ifname);
991 return (1);
992 }
993 return (0);
994
995bad_rule:
996 bridge_badrule(targc, targv, ln);
997 return (1);
998}
999
1000int
1001bridge_arprule(struct ifbrlreq *rule, int *argc, char ***argv)
1002{
1003 while (*argc) {
1004 struct ether_addr *ea, *dea = NULL((void *)0);
1005 struct in_addr ia, *dia = NULL((void *)0);
1006
1007 if (strcmp((*argv)[0], "request") == 0) {
1008 if (rule->ifbr_arpf.brla_flags & BRLA_ARP0x01)
1009 rule->ifbr_arpf.brla_op = ARPOP_REQUEST1;
1010 else if (rule->ifbr_arpf.brla_flags & BRLA_RARP0x02)
1011 rule->ifbr_arpf.brla_op = ARPOP_REVREQUEST3;
1012 else
1013 errx(1, "bridge_arprule: arp/rarp undefined");
1014 } else if (strcmp((*argv)[0], "reply") == 0) {
1015 if (rule->ifbr_arpf.brla_flags & BRLA_ARP0x01)
1016 rule->ifbr_arpf.brla_op = ARPOP_REPLY2;
1017 else if (rule->ifbr_arpf.brla_flags & BRLA_RARP0x02)
1018 rule->ifbr_arpf.brla_op = ARPOP_REVREPLY4;
1019 else
1020 errx(1, "bridge_arprule: arp/rarp undefined");
1021 } else if (strcmp((*argv)[0], "sha") == 0) {
1022 rule->ifbr_arpf.brla_flags |= BRLA_SHA0x10;
1023 dea = &rule->ifbr_arpf.brla_sha;
1024 } else if (strcmp((*argv)[0], "tha") == 0) {
1025 rule->ifbr_arpf.brla_flags |= BRLA_THA0x40;
1026 dea = &rule->ifbr_arpf.brla_tha;
1027 } else if (strcmp((*argv)[0], "spa") == 0) {
1028 rule->ifbr_arpf.brla_flags |= BRLA_SPA0x20;
1029 dia = &rule->ifbr_arpf.brla_spa;
1030 } else if (strcmp((*argv)[0], "tpa") == 0) {
1031 rule->ifbr_arpf.brla_flags |= BRLA_TPA0x80;
1032 dia = &rule->ifbr_arpf.brla_tpa;
1033 } else
1034 return (0);
1035
1036 (*argc)--; (*argv)++;
1037 if (dea != NULL((void *)0)) {
1038 if (*argc == 0)
1039 return (-1);
1040 ea = ether_aton((*argv)[0]);
1041 if (ea == NULL((void *)0)) {
1042 warnx("invalid address: %s", (*argv)[0]);
1043 return (-1);
1044 }
1045 bcopy(ea, dea, sizeof(*dea));
1046 (*argc)--; (*argv)++;
1047 }
1048 if (dia != NULL((void *)0)) {
1049 if (*argc == 0)
1050 return (-1);
1051 ia.s_addr = inet_addr((*argv)[0]);
1052 if (ia.s_addr == INADDR_NONE((u_int32_t)(0xffffffff))) {
1053 warnx("invalid address: %s", (*argv)[0]);
1054 return (-1);
1055 }
1056 bcopy(&ia, dia, sizeof(*dia));
1057 (*argc)--; (*argv)++;
1058 }
1059 }
1060 return (0);
1061}
1062
1063
1064#define MAXRULEWORDS32 32
1065
1066void
1067bridge_rulefile(const char *fname, int d)
1068{
1069 FILE *f;
1070 char *str, *argv[MAXRULEWORDS32], buf[1024];
1071 int ln = 0, argc = 0;
1072
1073 f = fopen(fname, "r");
1074 if (f == NULL((void *)0))
1075 err(1, "%s", fname);
1076
1077 while (fgets(buf, sizeof(buf), f) != NULL((void *)0)) {
1078 ln++;
1079 if (buf[0] == '#' || buf[0] == '\n')
1080 continue;
1081
1082 argc = 0;
1083 str = strtok(buf, "\n\t\r ");
1084 while (str != NULL((void *)0) && argc < MAXRULEWORDS32) {
1085 argv[argc++] = str;
1086 str = strtok(NULL((void *)0), "\n\t\r ");
1087 }
1088
1089 /* Rule is too long if there's more. */
1090 if (str != NULL((void *)0)) {
1091 warnx("invalid rule: %d: %s ...", ln, buf);
1092 continue;
1093 }
1094
1095 bridge_rule(argc, argv, ln);
1096 }
1097 fclose(f);
1098}
1099
1100void
1101bridge_badrule(int argc, char *argv[], int ln)
1102{
1103 extern const char *__progname;
1104 int i;
1105
1106 fprintf(stderr(&__sF[2]), "%s: invalid rule: ", __progname);
1107 if (ln != -1)
1108 fprintf(stderr(&__sF[2]), "%d: ", ln);
1109 for (i = 0; i < argc; i++)
1110 fprintf(stderr(&__sF[2]), "%s ", argv[i]);
1111 fprintf(stderr(&__sF[2]), "\n");
1112}
1113
1114#endif