1 /* 2 * Copyright (c) 2008 The DragonFly Project. All rights reserved. 3 * 4 * This code is derived from software contributed to The DragonFly Project 5 * by Matthew Dillon <dillon@backplane.com> 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 * 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 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * 3. Neither the name of The DragonFly Project nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific, prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * 34 * $DragonFly: src/usr.sbin/vknetd/bridge.c,v 1.1 2008/05/27 01:58:01 dillon Exp $ 35 */ 36 /* 37 * Bridging code (serialized) 38 */ 39 #include "vknetd.h" 40 41 static TAILQ_HEAD(, bridge) BridgeList = TAILQ_HEAD_INITIALIZER(BridgeList); 42 43 /* 44 * Add the unix domain descriptor to our bridge 45 */ 46 bridge_t 47 bridge_add(ioinfo_t io) 48 { 49 bridge_t bridge; 50 51 bridge = malloc(sizeof(struct bridge)); 52 bzero(bridge, sizeof(*bridge)); 53 bridge->io = io; 54 TAILQ_INIT(&bridge->mac_list); 55 TAILQ_INSERT_TAIL(&BridgeList, bridge, entry); 56 57 return(bridge); 58 } 59 60 /* 61 * Remove the unix domain descriptor from our bridge 62 */ 63 void 64 bridge_del(bridge_t bridge) 65 { 66 mac_t mac; 67 68 TAILQ_REMOVE(&BridgeList, bridge, entry); 69 70 while ((mac = TAILQ_FIRST(&bridge->mac_list)) != NULL) 71 mac_delete(mac); 72 73 free(bridge); 74 } 75 76 /* 77 * Bridge a packet. The packet is in the following form: 78 * 79 * [src_mac:6][dst_mac:6][packet] 80 */ 81 void 82 bridge_packet(bridge_t bridge, u_int8_t *pkt, int bytes) 83 { 84 bridge_t scan; 85 mac_t mac; 86 87 if (mac_broadcast(pkt + 6) == 0) { 88 mac = mac_find(pkt + 6); 89 if (mac == NULL) { 90 mac_add(bridge, pkt + 6); 91 } else if (mac->bridge != bridge) { 92 mac_delete(mac); 93 mac_add(bridge, pkt + 6); 94 } 95 } 96 if (mac_broadcast(pkt + 0) == 0 && (mac = mac_find(pkt + 0)) != NULL) { 97 if (mac->bridge != bridge && 98 (mac->bridge->io->istap == 0 || filter_ok(pkt, bytes))) { 99 write(mac->bridge->io->fd, pkt, bytes); 100 } 101 } else { 102 TAILQ_FOREACH(scan, &BridgeList, entry) { 103 if (scan != bridge && 104 (scan->io->istap == 0 || filter_ok(pkt, bytes))) { 105 write(scan->io->fd, pkt, bytes); 106 } 107 } 108 } 109 } 110 111