mirror of
https://github.com/86Box/86Box.git
synced 2026-02-21 17:15:32 -07:00
net_switch: Use old packet construction with no shared secret
This falls through to using 239.255.86.86 as the multicast address and excluding a shared secret hash, if no shared secret has been entered. This restores compatibility with QEMU’s `-netdev dgram` mode, as suggested by @richardg867.
This commit is contained in:
@@ -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. */
|
||||
|
||||
Reference in New Issue
Block a user