diff --git a/src/network/net_switch.c b/src/network/net_switch.c index 001575348..ced2f0392 100644 --- a/src/network/net_switch.c +++ b/src/network/net_switch.c @@ -81,6 +81,7 @@ typedef struct net_switch_t { net_switch_hostaddr_t *hostaddrs; uint16_t port_out; + uint8_t secret_enabled; uint8_t secret_hash[32]; uint8_t promisc; union { @@ -197,10 +198,12 @@ net_switch_add_hostaddr(net_switch_t *netswitch, net_switch_sockaddr_t *addr, ne } /* Join IPv4 multicast group. */ - struct ip_mreq mreq = { - .imr_multiaddr = { .s_addr = htonl(SWITCH_MULTICAST_GROUP) }, - .imr_interface = { .s_addr = hostaddr->addr.sin.sin_addr.s_addr } - }; + struct ip_mreq mreq = { .imr_interface = { .s_addr = hostaddr->addr.sin.sin_addr.s_addr } }; + if (netswitch->secret_enabled) + mreq.imr_multiaddr.s_addr = htonl(SWITCH_MULTICAST_GROUP); + else + mreq.imr_multiaddr.s_addr = htonl(SWITCH_MULTICAST_GROUP + 0x600); // 239.255.86.86 + if (setsockopt(netswitch->socket_rx, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &mreq, sizeof(mreq)) < 0) { netswitch_log("Network Switch: could not join multicast group on interface %s\n", buf); goto broadcast; @@ -386,24 +389,34 @@ net_switch_thread(void *priv) if (!(net_cards_conf[netswitch->card->card_num].link_state & NET_LINK_DOWN)) { for (int i = 0; i < packets; i++) { int orig_len = netswitch->pkt_tx_v[i].len; - int send_len = orig_len + sizeof(netswitch->secret_hash); - - /* Build header with secret hash */ + int send_len = orig_len; uint8_t augmented[sizeof(netswitch->secret_hash) + NET_MAX_FRAME]; - uint8_t *hdr = augmented; - memcpy(hdr, netswitch->secret_hash, sizeof(netswitch->secret_hash)); - memcpy(augmented + sizeof(netswitch->secret_hash), - netswitch->pkt_tx_v[i].data, orig_len); + if (netswitch->secret_enabled) { + send_len = orig_len + sizeof(netswitch->secret_hash); + + /* Build header with secret hash */ + uint8_t *hdr = augmented; + memcpy(hdr, netswitch->secret_hash, sizeof(netswitch->secret_hash)); + memcpy(augmented + sizeof(netswitch->secret_hash), + netswitch->pkt_tx_v[i].data, orig_len); + } #define MAC_FORMAT "(%02X:%02X:%02X:%02X:%02X:%02X -> %02X:%02X:%02X:%02X:%02X:%02X)" +#define MAC_FORMAT_NOSECRET_ARGS(p) (p)[6], (p)[7], (p)[8], (p)[9], (p)[10], (p)[11], (p)[0], (p)[1], (p)[2], (p)[3], (p)[4], (p)[5] #define MAC_FORMAT_ARGS(p) (p)[38], (p)[39], (p)[40], (p)[41], (p)[42], (p)[43], (p)[32], (p)[33], (p)[34], (p)[35], (p)[36], (p)[37] netswitch_log("Network Switch: sending %d-byte packet " MAC_FORMAT "\n", - netswitch->pkt_tx_v[i].len, MAC_FORMAT_ARGS(netswitch->pkt_tx_v[i].data)); + netswitch->pkt_tx_v[i].len, + netswitch->secret_enabled ? MAC_FORMAT_ARGS(netswitch->pkt_tx_v[i].data) + : MAC_FORMAT_NOSECRET_ARGS(netswitch->pkt_tx_v[i].data)); /* Send through all known host interfaces. */ for (net_switch_hostaddr_t *hostaddr = netswitch->hostaddrs; hostaddr; hostaddr = hostaddr->next) - sendto(hostaddr->socket_tx, augmented, send_len, 0, - &hostaddr->addr_tx.sa, sizeof(hostaddr->addr_tx.sa)); + if (netswitch->secret_enabled) + sendto(hostaddr->socket_tx, (char *)augmented, send_len, 0, + &hostaddr->addr_tx.sa, sizeof(hostaddr->addr_tx.sa)); + else + sendto(hostaddr->socket_tx, (char *)netswitch->pkt_tx_v[i].data, + send_len, 0, &hostaddr->addr_tx.sa, sizeof(hostaddr->addr_tx.sa)); } } netswitch->during_tx = 0; @@ -426,24 +439,32 @@ net_switch_thread(void *priv) } if (pfd[NET_EVENT_RX].revents & POLLIN) { #endif - len = recv(netswitch->socket_rx, (char *) netswitch->pkt.data, NET_MAX_FRAME + sizeof(netswitch->secret_hash), 0); - if (len < sizeof(netswitch->secret_hash) + 12) { - netswitch_log("Network Switch: recv error (%d)\n", len); - continue; - } + if (netswitch->secret_enabled) { + len = recv(netswitch->socket_rx, (char *) netswitch->pkt.data, NET_MAX_FRAME + sizeof(netswitch->secret_hash), 0); + if (len < sizeof(netswitch->secret_hash) + 12) { + netswitch_log("Network Switch: recv error (%d)\n", len); + continue; + } - if (memcmp(netswitch->pkt.data, netswitch->secret_hash, sizeof(netswitch->secret_hash)) != 0) { - /* This packet contains a different secret hash, ignore it. */ - continue; + if (memcmp(netswitch->pkt.data, netswitch->secret_hash, sizeof(netswitch->secret_hash)) != 0) { + /* This packet contains a different secret hash, ignore it. */ + continue; + } else { + memmove(netswitch->pkt.data, + netswitch->pkt.data + sizeof(netswitch->secret_hash), + len - sizeof(netswitch->secret_hash)); + len = len - sizeof(netswitch->secret_hash); + netswitch->pkt.len = len; + } } else { - memmove(netswitch->pkt.data, - netswitch->pkt.data + sizeof(netswitch->secret_hash), - len - sizeof(netswitch->secret_hash)); - len = len - sizeof(netswitch->secret_hash); - netswitch->pkt.len = len; + len = recv(netswitch->socket_rx, (char *) netswitch->pkt.data, NET_MAX_FRAME, 0); + if (len < 12) { + netswitch_log("Network Switch: recv error (%d)\n", len); + continue; + } } - if ((AS_U64(netswitch->pkt.data[6]) & le64_to_cpu(0xffffffffffffULL)) == netswitch->mac_addr_u64) { + if ((AS_U64(netswitch->pkt.data[netswitch->secret_enabled ? 38 : 6]) & le64_to_cpu(0xffffffffffffULL)) == netswitch->mac_addr_u64) { /* A packet we've sent has looped back, drop it. */ } else if (!(net_cards_conf[netswitch->card->card_num].link_state & NET_LINK_DOWN) && (netswitch->promisc || /* promiscuous mode? */ (netswitch->pkt.data[0] & 1) || /* broadcast packet? */ @@ -482,10 +503,13 @@ net_switch_init(const netcard_t *card, const uint8_t *mac_addr, void *priv, char netswitch->card = (netcard_t *) card; netswitch->promisc = !!netcard->promisc_mode; - { + if (netcard->secret[0] != '\0') { uint8_t temp[32]; net_switch_secret_hash((const uint8_t *)netcard->secret, (uint8_t *) temp); memcpy(netswitch->secret_hash, temp, 32); + netswitch->secret_enabled = 1; + } else { + netswitch->secret_enabled = 0; } /* Initialize receive socket. */