From f3d22bbef3dbad7d198b280eeee908c46440c66a Mon Sep 17 00:00:00 2001 From: Mike Swanson Date: Mon, 9 Feb 2026 19:06:45 -0800 Subject: [PATCH 1/3] local switch: Implement shared-secret feature MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows for a “shared secret” to be entered for a network switch, segmenting traffic so that multiple people could use the feature simultaneously without accidentally entering into or interfering with each other's networks. Takes a string specified in the configuration file (using the net_%02i_secret key) and hashes it through SHA3-256 to prepend to each data packet. This hash is used to compare packets on reception and allow or discard them. --- src/config.c | 11 + src/include/86box/network.h | 1 + src/include/shathree.h | 481 ++++++++++++++++++++++++++++++++++++ src/network/net_switch.c | 49 +++- 4 files changed, 538 insertions(+), 4 deletions(-) create mode 100644 src/include/shathree.h diff --git a/src/config.c b/src/config.c index 06049713c..182b6bdf0 100644 --- a/src/config.c +++ b/src/config.c @@ -915,6 +915,11 @@ load_network(void) if (nc->switch_group < NET_SWITCH_GRP_MIN) nc->switch_group = NET_SWITCH_GRP_MIN; + sprintf(temp, "net_%02i_secret", c + 1); + p = ini_section_get_string(cat, temp, NULL); + strncpy(nc->secret, p ? p : "", sizeof(nc->secret) - 1); + nc->secret[sizeof(net_cards_conf[c].secret) - 1] = '\0'; + sprintf(temp, "net_%02i_promisc", c + 1); nc->promisc_mode = ini_section_get_int(cat, temp, 0); @@ -3025,6 +3030,12 @@ save_network(void) else ini_section_set_int(cat, temp, nc->switch_group); + sprintf(temp, "net_%02i_secret", c + 1); + if (nc->secret[0] == '\0') + ini_section_delete_var(cat, temp); + else + ini_section_set_string(cat, temp, net_cards_conf[c].secret); + sprintf(temp, "net_%02i_promisc", c + 1); if (nc->promisc_mode == 0) ini_section_delete_var(cat, temp); diff --git a/src/include/86box/network.h b/src/include/86box/network.h index f3f1b1f8a..78b03e439 100644 --- a/src/include/86box/network.h +++ b/src/include/86box/network.h @@ -98,6 +98,7 @@ typedef struct netcard_conf_t { char host_dev_name[128]; uint32_t link_state; uint8_t switch_group; + char secret[256]; uint8_t promisc_mode; char slirp_net[16]; char nrs_hostname[128]; diff --git a/src/include/shathree.h b/src/include/shathree.h new file mode 100644 index 000000000..98e804b33 --- /dev/null +++ b/src/include/shathree.h @@ -0,0 +1,481 @@ +/* +** This code is from SQLite +** (https://sqlite.org/src/info/2025-02-27T21:17:55z), at file path +** ext/misc/shathree.c. The SQLite functions have been removed, but +** it is the same code written by D. Richard Hipp. +*/ + +#ifndef SHATHREE_H + +/* +** 2017-03-08 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +*/ +#include +#include +#include + +/****************************************************************************** +** The Hash Engine +*/ +/* +** Macros to determine whether the machine is big or little endian, +** and whether or not that determination is run-time or compile-time. +** +** For best performance, an attempt is made to guess at the byte-order +** using C-preprocessor macros. If that is unsuccessful, or if +** -DSHA3_BYTEORDER=0 is set, then byte-order is determined +** at run-time. +*/ +#ifndef SHA3_BYTEORDER +# if defined(i386) || defined(__i386__) || defined(_M_IX86) || \ + defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \ + defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \ + defined(__arm__) +# define SHA3_BYTEORDER 1234 +# elif defined(sparc) || defined(__ppc__) +# define SHA3_BYTEORDER 4321 +# else +# define SHA3_BYTEORDER 0 +# endif +#endif + +#define u64 uint64_t + + +/* +** State structure for a SHA3 hash in progress +*/ +typedef struct SHA3Context SHA3Context; +struct SHA3Context { + union { + u64 s[25]; /* Keccak state. 5x5 lines of 64 bits each */ + unsigned char x[1600]; /* ... or 1600 bytes */ + } u; + unsigned nRate; /* Bytes of input accepted per Keccak iteration */ + unsigned nLoaded; /* Input bytes loaded into u.x[] so far this cycle */ + unsigned ixMask; /* Insert next input into u.x[nLoaded^ixMask]. */ + unsigned iSize; /* 224, 256, 358, or 512 */ +}; + +/* +** A single step of the Keccak mixing function for a 1600-bit state +*/ +static void KeccakF1600Step(SHA3Context *p){ + int i; + u64 b0, b1, b2, b3, b4; + u64 c0, c1, c2, c3, c4; + u64 d0, d1, d2, d3, d4; + static const u64 RC[] = { + 0x0000000000000001ULL, 0x0000000000008082ULL, + 0x800000000000808aULL, 0x8000000080008000ULL, + 0x000000000000808bULL, 0x0000000080000001ULL, + 0x8000000080008081ULL, 0x8000000000008009ULL, + 0x000000000000008aULL, 0x0000000000000088ULL, + 0x0000000080008009ULL, 0x000000008000000aULL, + 0x000000008000808bULL, 0x800000000000008bULL, + 0x8000000000008089ULL, 0x8000000000008003ULL, + 0x8000000000008002ULL, 0x8000000000000080ULL, + 0x000000000000800aULL, 0x800000008000000aULL, + 0x8000000080008081ULL, 0x8000000000008080ULL, + 0x0000000080000001ULL, 0x8000000080008008ULL + }; +# define a00 (p->u.s[0]) +# define a01 (p->u.s[1]) +# define a02 (p->u.s[2]) +# define a03 (p->u.s[3]) +# define a04 (p->u.s[4]) +# define a10 (p->u.s[5]) +# define a11 (p->u.s[6]) +# define a12 (p->u.s[7]) +# define a13 (p->u.s[8]) +# define a14 (p->u.s[9]) +# define a20 (p->u.s[10]) +# define a21 (p->u.s[11]) +# define a22 (p->u.s[12]) +# define a23 (p->u.s[13]) +# define a24 (p->u.s[14]) +# define a30 (p->u.s[15]) +# define a31 (p->u.s[16]) +# define a32 (p->u.s[17]) +# define a33 (p->u.s[18]) +# define a34 (p->u.s[19]) +# define a40 (p->u.s[20]) +# define a41 (p->u.s[21]) +# define a42 (p->u.s[22]) +# define a43 (p->u.s[23]) +# define a44 (p->u.s[24]) +# define ROL64(a,x) ((a<>(64-x))) + + for(i=0; i<24; i+=4){ + c0 = a00^a10^a20^a30^a40; + c1 = a01^a11^a21^a31^a41; + c2 = a02^a12^a22^a32^a42; + c3 = a03^a13^a23^a33^a43; + c4 = a04^a14^a24^a34^a44; + d0 = c4^ROL64(c1, 1); + d1 = c0^ROL64(c2, 1); + d2 = c1^ROL64(c3, 1); + d3 = c2^ROL64(c4, 1); + d4 = c3^ROL64(c0, 1); + + b0 = (a00^d0); + b1 = ROL64((a11^d1), 44); + b2 = ROL64((a22^d2), 43); + b3 = ROL64((a33^d3), 21); + b4 = ROL64((a44^d4), 14); + a00 = b0 ^((~b1)& b2 ); + a00 ^= RC[i]; + a11 = b1 ^((~b2)& b3 ); + a22 = b2 ^((~b3)& b4 ); + a33 = b3 ^((~b4)& b0 ); + a44 = b4 ^((~b0)& b1 ); + + b2 = ROL64((a20^d0), 3); + b3 = ROL64((a31^d1), 45); + b4 = ROL64((a42^d2), 61); + b0 = ROL64((a03^d3), 28); + b1 = ROL64((a14^d4), 20); + a20 = b0 ^((~b1)& b2 ); + a31 = b1 ^((~b2)& b3 ); + a42 = b2 ^((~b3)& b4 ); + a03 = b3 ^((~b4)& b0 ); + a14 = b4 ^((~b0)& b1 ); + + b4 = ROL64((a40^d0), 18); + b0 = ROL64((a01^d1), 1); + b1 = ROL64((a12^d2), 6); + b2 = ROL64((a23^d3), 25); + b3 = ROL64((a34^d4), 8); + a40 = b0 ^((~b1)& b2 ); + a01 = b1 ^((~b2)& b3 ); + a12 = b2 ^((~b3)& b4 ); + a23 = b3 ^((~b4)& b0 ); + a34 = b4 ^((~b0)& b1 ); + + b1 = ROL64((a10^d0), 36); + b2 = ROL64((a21^d1), 10); + b3 = ROL64((a32^d2), 15); + b4 = ROL64((a43^d3), 56); + b0 = ROL64((a04^d4), 27); + a10 = b0 ^((~b1)& b2 ); + a21 = b1 ^((~b2)& b3 ); + a32 = b2 ^((~b3)& b4 ); + a43 = b3 ^((~b4)& b0 ); + a04 = b4 ^((~b0)& b1 ); + + b3 = ROL64((a30^d0), 41); + b4 = ROL64((a41^d1), 2); + b0 = ROL64((a02^d2), 62); + b1 = ROL64((a13^d3), 55); + b2 = ROL64((a24^d4), 39); + a30 = b0 ^((~b1)& b2 ); + a41 = b1 ^((~b2)& b3 ); + a02 = b2 ^((~b3)& b4 ); + a13 = b3 ^((~b4)& b0 ); + a24 = b4 ^((~b0)& b1 ); + + c0 = a00^a20^a40^a10^a30; + c1 = a11^a31^a01^a21^a41; + c2 = a22^a42^a12^a32^a02; + c3 = a33^a03^a23^a43^a13; + c4 = a44^a14^a34^a04^a24; + d0 = c4^ROL64(c1, 1); + d1 = c0^ROL64(c2, 1); + d2 = c1^ROL64(c3, 1); + d3 = c2^ROL64(c4, 1); + d4 = c3^ROL64(c0, 1); + + b0 = (a00^d0); + b1 = ROL64((a31^d1), 44); + b2 = ROL64((a12^d2), 43); + b3 = ROL64((a43^d3), 21); + b4 = ROL64((a24^d4), 14); + a00 = b0 ^((~b1)& b2 ); + a00 ^= RC[i+1]; + a31 = b1 ^((~b2)& b3 ); + a12 = b2 ^((~b3)& b4 ); + a43 = b3 ^((~b4)& b0 ); + a24 = b4 ^((~b0)& b1 ); + + b2 = ROL64((a40^d0), 3); + b3 = ROL64((a21^d1), 45); + b4 = ROL64((a02^d2), 61); + b0 = ROL64((a33^d3), 28); + b1 = ROL64((a14^d4), 20); + a40 = b0 ^((~b1)& b2 ); + a21 = b1 ^((~b2)& b3 ); + a02 = b2 ^((~b3)& b4 ); + a33 = b3 ^((~b4)& b0 ); + a14 = b4 ^((~b0)& b1 ); + + b4 = ROL64((a30^d0), 18); + b0 = ROL64((a11^d1), 1); + b1 = ROL64((a42^d2), 6); + b2 = ROL64((a23^d3), 25); + b3 = ROL64((a04^d4), 8); + a30 = b0 ^((~b1)& b2 ); + a11 = b1 ^((~b2)& b3 ); + a42 = b2 ^((~b3)& b4 ); + a23 = b3 ^((~b4)& b0 ); + a04 = b4 ^((~b0)& b1 ); + + b1 = ROL64((a20^d0), 36); + b2 = ROL64((a01^d1), 10); + b3 = ROL64((a32^d2), 15); + b4 = ROL64((a13^d3), 56); + b0 = ROL64((a44^d4), 27); + a20 = b0 ^((~b1)& b2 ); + a01 = b1 ^((~b2)& b3 ); + a32 = b2 ^((~b3)& b4 ); + a13 = b3 ^((~b4)& b0 ); + a44 = b4 ^((~b0)& b1 ); + + b3 = ROL64((a10^d0), 41); + b4 = ROL64((a41^d1), 2); + b0 = ROL64((a22^d2), 62); + b1 = ROL64((a03^d3), 55); + b2 = ROL64((a34^d4), 39); + a10 = b0 ^((~b1)& b2 ); + a41 = b1 ^((~b2)& b3 ); + a22 = b2 ^((~b3)& b4 ); + a03 = b3 ^((~b4)& b0 ); + a34 = b4 ^((~b0)& b1 ); + + c0 = a00^a40^a30^a20^a10; + c1 = a31^a21^a11^a01^a41; + c2 = a12^a02^a42^a32^a22; + c3 = a43^a33^a23^a13^a03; + c4 = a24^a14^a04^a44^a34; + d0 = c4^ROL64(c1, 1); + d1 = c0^ROL64(c2, 1); + d2 = c1^ROL64(c3, 1); + d3 = c2^ROL64(c4, 1); + d4 = c3^ROL64(c0, 1); + + b0 = (a00^d0); + b1 = ROL64((a21^d1), 44); + b2 = ROL64((a42^d2), 43); + b3 = ROL64((a13^d3), 21); + b4 = ROL64((a34^d4), 14); + a00 = b0 ^((~b1)& b2 ); + a00 ^= RC[i+2]; + a21 = b1 ^((~b2)& b3 ); + a42 = b2 ^((~b3)& b4 ); + a13 = b3 ^((~b4)& b0 ); + a34 = b4 ^((~b0)& b1 ); + + b2 = ROL64((a30^d0), 3); + b3 = ROL64((a01^d1), 45); + b4 = ROL64((a22^d2), 61); + b0 = ROL64((a43^d3), 28); + b1 = ROL64((a14^d4), 20); + a30 = b0 ^((~b1)& b2 ); + a01 = b1 ^((~b2)& b3 ); + a22 = b2 ^((~b3)& b4 ); + a43 = b3 ^((~b4)& b0 ); + a14 = b4 ^((~b0)& b1 ); + + b4 = ROL64((a10^d0), 18); + b0 = ROL64((a31^d1), 1); + b1 = ROL64((a02^d2), 6); + b2 = ROL64((a23^d3), 25); + b3 = ROL64((a44^d4), 8); + a10 = b0 ^((~b1)& b2 ); + a31 = b1 ^((~b2)& b3 ); + a02 = b2 ^((~b3)& b4 ); + a23 = b3 ^((~b4)& b0 ); + a44 = b4 ^((~b0)& b1 ); + + b1 = ROL64((a40^d0), 36); + b2 = ROL64((a11^d1), 10); + b3 = ROL64((a32^d2), 15); + b4 = ROL64((a03^d3), 56); + b0 = ROL64((a24^d4), 27); + a40 = b0 ^((~b1)& b2 ); + a11 = b1 ^((~b2)& b3 ); + a32 = b2 ^((~b3)& b4 ); + a03 = b3 ^((~b4)& b0 ); + a24 = b4 ^((~b0)& b1 ); + + b3 = ROL64((a20^d0), 41); + b4 = ROL64((a41^d1), 2); + b0 = ROL64((a12^d2), 62); + b1 = ROL64((a33^d3), 55); + b2 = ROL64((a04^d4), 39); + a20 = b0 ^((~b1)& b2 ); + a41 = b1 ^((~b2)& b3 ); + a12 = b2 ^((~b3)& b4 ); + a33 = b3 ^((~b4)& b0 ); + a04 = b4 ^((~b0)& b1 ); + + c0 = a00^a30^a10^a40^a20; + c1 = a21^a01^a31^a11^a41; + c2 = a42^a22^a02^a32^a12; + c3 = a13^a43^a23^a03^a33; + c4 = a34^a14^a44^a24^a04; + d0 = c4^ROL64(c1, 1); + d1 = c0^ROL64(c2, 1); + d2 = c1^ROL64(c3, 1); + d3 = c2^ROL64(c4, 1); + d4 = c3^ROL64(c0, 1); + + b0 = (a00^d0); + b1 = ROL64((a01^d1), 44); + b2 = ROL64((a02^d2), 43); + b3 = ROL64((a03^d3), 21); + b4 = ROL64((a04^d4), 14); + a00 = b0 ^((~b1)& b2 ); + a00 ^= RC[i+3]; + a01 = b1 ^((~b2)& b3 ); + a02 = b2 ^((~b3)& b4 ); + a03 = b3 ^((~b4)& b0 ); + a04 = b4 ^((~b0)& b1 ); + + b2 = ROL64((a10^d0), 3); + b3 = ROL64((a11^d1), 45); + b4 = ROL64((a12^d2), 61); + b0 = ROL64((a13^d3), 28); + b1 = ROL64((a14^d4), 20); + a10 = b0 ^((~b1)& b2 ); + a11 = b1 ^((~b2)& b3 ); + a12 = b2 ^((~b3)& b4 ); + a13 = b3 ^((~b4)& b0 ); + a14 = b4 ^((~b0)& b1 ); + + b4 = ROL64((a20^d0), 18); + b0 = ROL64((a21^d1), 1); + b1 = ROL64((a22^d2), 6); + b2 = ROL64((a23^d3), 25); + b3 = ROL64((a24^d4), 8); + a20 = b0 ^((~b1)& b2 ); + a21 = b1 ^((~b2)& b3 ); + a22 = b2 ^((~b3)& b4 ); + a23 = b3 ^((~b4)& b0 ); + a24 = b4 ^((~b0)& b1 ); + + b1 = ROL64((a30^d0), 36); + b2 = ROL64((a31^d1), 10); + b3 = ROL64((a32^d2), 15); + b4 = ROL64((a33^d3), 56); + b0 = ROL64((a34^d4), 27); + a30 = b0 ^((~b1)& b2 ); + a31 = b1 ^((~b2)& b3 ); + a32 = b2 ^((~b3)& b4 ); + a33 = b3 ^((~b4)& b0 ); + a34 = b4 ^((~b0)& b1 ); + + b3 = ROL64((a40^d0), 41); + b4 = ROL64((a41^d1), 2); + b0 = ROL64((a42^d2), 62); + b1 = ROL64((a43^d3), 55); + b2 = ROL64((a44^d4), 39); + a40 = b0 ^((~b1)& b2 ); + a41 = b1 ^((~b2)& b3 ); + a42 = b2 ^((~b3)& b4 ); + a43 = b3 ^((~b4)& b0 ); + a44 = b4 ^((~b0)& b1 ); + } +} + +/* +** Initialize a new hash. iSize determines the size of the hash +** in bits and should be one of 224, 256, 384, or 512. Or iSize +** can be zero to use the default hash size of 256 bits. +*/ +static void SHA3Init(SHA3Context *p, int iSize){ + memset(p, 0, sizeof(*p)); + p->iSize = iSize; + if( iSize>=128 && iSize<=512 ){ + p->nRate = (1600 - ((iSize + 31)&~31)*2)/8; + }else{ + p->nRate = (1600 - 2*256)/8; + } +#if SHA3_BYTEORDER==1234 + /* Known to be little-endian at compile-time. No-op */ +#elif SHA3_BYTEORDER==4321 + p->ixMask = 7; /* Big-endian */ +#else + { + static unsigned int one = 1; + if( 1==*(unsigned char*)&one ){ + /* Little endian. No byte swapping. */ + p->ixMask = 0; + }else{ + /* Big endian. Byte swap. */ + p->ixMask = 7; + } + } +#endif +} + +/* +** Make consecutive calls to the SHA3Update function to add new content +** to the hash +*/ +static void SHA3Update( + SHA3Context *p, + const unsigned char *aData, + unsigned int nData +){ + unsigned int i = 0; + if( aData==0 ) return; +#if SHA3_BYTEORDER==1234 + if( (p->nLoaded % 8)==0 && ((aData - (const unsigned char*)0)&7)==0 ){ + for(; i+7u.s[p->nLoaded/8] ^= *(u64*)&aData[i]; + p->nLoaded += 8; + if( p->nLoaded>=p->nRate ){ + KeccakF1600Step(p); + p->nLoaded = 0; + } + } + } +#endif + for(; iu.x[p->nLoaded] ^= aData[i]; +#elif SHA3_BYTEORDER==4321 + p->u.x[p->nLoaded^0x07] ^= aData[i]; +#else + p->u.x[p->nLoaded^p->ixMask] ^= aData[i]; +#endif + p->nLoaded++; + if( p->nLoaded==p->nRate ){ + KeccakF1600Step(p); + p->nLoaded = 0; + } + } +} + +/* +** After all content has been added, invoke SHA3Final() to compute +** the final hash. The function returns a pointer to the binary +** hash value. +*/ +static unsigned char *SHA3Final(SHA3Context *p){ + unsigned int i; + if( p->nLoaded==p->nRate-1 ){ + const unsigned char c1 = 0x86; + SHA3Update(p, &c1, 1); + }else{ + const unsigned char c2 = 0x06; + const unsigned char c3 = 0x80; + SHA3Update(p, &c2, 1); + p->nLoaded = p->nRate - 1; + SHA3Update(p, &c3, 1); + } + for(i=0; inRate; i++){ + p->u.x[i+p->nRate] = p->u.x[i^p->ixMask]; + } + return &p->u.x[p->nRate]; +} + +#endif diff --git a/src/network/net_switch.c b/src/network/net_switch.c index d29513f74..0f0d4b509 100644 --- a/src/network/net_switch.c +++ b/src/network/net_switch.c @@ -49,6 +49,7 @@ #include <86box/config.h> #include <86box/net_event.h> #include <86box/bswap.h> +#include #define SWITCH_PKT_BATCH NET_QUEUE_LEN @@ -80,6 +81,7 @@ typedef struct net_switch_t { net_switch_hostaddr_t *hostaddrs; uint16_t port_out; + uint8_t secret_hash[32]; uint8_t promisc; union { uint8_t mac_addr[6]; @@ -123,6 +125,15 @@ net_switch_in_available(void *priv) net_event_set(&netswitch->tx_event); } +static void +net_switch_secret_hash(const char *secret, uint8_t *hash) +{ + SHA3Context cx; + SHA3Init(&cx, 256); + SHA3Update(&cx, (const uint8_t *)secret, strlen(secret)); + memcpy(hash, SHA3Final(&cx), 32); +} + static unsigned int net_switch_add_hostaddr(net_switch_t *netswitch, net_switch_sockaddr_t *addr, net_switch_sockaddr_t *broadcast, net_switch_sockaddr_t *netmask, unsigned int flags) { @@ -374,15 +385,30 @@ net_switch_thread(void *priv) packets = network_tx_popv(netswitch->card, netswitch->pkt_tx_v, SWITCH_PKT_BATCH); 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 + 32; + + if (send_len > NET_MAX_FRAME) { + netswitch_log("Network Switch: packet too large to add header (%d bytes)\n", + orig_len); + continue; + } + + /* Prepend secret hash data */ + memmove(netswitch->pkt_tx_v[i].data + 32, + netswitch->pkt_tx_v[i].data, + orig_len); + memcpy(netswitch->pkt_tx_v[i].data, netswitch->secret_hash, 32); + #define MAC_FORMAT "(%02X:%02X:%02X:%02X:%02X:%02X -> %02X:%02X:%02X:%02X:%02X:%02X)" -#define MAC_FORMAT_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)); /* Send through all known host interfaces. */ for (net_switch_hostaddr_t *hostaddr = netswitch->hostaddrs; hostaddr; hostaddr = hostaddr->next) sendto(hostaddr->socket_tx, - (char *) netswitch->pkt_tx_v[i].data, netswitch->pkt_tx_v[i].len, 0, + (char *) netswitch->pkt_tx_v[i].data, send_len, 0, &hostaddr->addr_tx.sa, sizeof(hostaddr->addr_tx.sa)); } } @@ -407,9 +433,18 @@ 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, 0); - if (len < 12) { + if (len < 44) { netswitch_log("Network Switch: recv error (%d)\n", len); - } else if ((AS_U64(netswitch->pkt.data[6]) & le64_to_cpu(0xffffffffffffULL)) == netswitch->mac_addr_u64) { + } + + if (memcmp(netswitch->pkt.data, netswitch->secret_hash, 32) != 0) { + /* This packet contains a different secret hash, ignore it. */ + continue; + } else { + memmove(netswitch->pkt.data, netswitch->pkt.data + 32, len - 32); + } + + if ((AS_U64(netswitch->pkt.data[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? */ @@ -450,6 +485,12 @@ 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; + { + uint8_t temp[32]; + net_switch_secret_hash((const uint8_t *)netcard->secret, (uint8_t *) temp); + memcpy(netswitch->secret_hash, temp, 32); + } + /* Initialize receive socket. */ netswitch->socket_rx = socket(AF_INET, SOCK_DGRAM, 0); if (netswitch->socket_rx < 0) { From 0d1e900fb60d5e96371b6a6a1cbb07d02ce5f0da Mon Sep 17 00:00:00 2001 From: Mike Swanson Date: Mon, 9 Feb 2026 20:05:42 -0800 Subject: [PATCH 2/3] Add GUI settings for shared secret, remove switch groups Two birds in one commit: with the introduction of shared secrets, there is a practically-infinite amount of local switches that can be used, by merely editing the shared secret string. As such, support for old switch groups has been removed. In addition to this, the multicast address for local switch has been altered to 239.255.80.86. This ensures a hard compatibility break with the previous code and old (albeit interim) builds of 86Box would not attempt to receive packets with shared secrets. --- src/config.c | 11 --- src/include/86box/network.h | 3 - src/network/net_switch.c | 6 +- src/qt/qt_settingsnetwork.cpp | 46 +++++------- src/qt/qt_settingsnetwork.ui | 136 +++++++--------------------------- 5 files changed, 50 insertions(+), 152 deletions(-) diff --git a/src/config.c b/src/config.c index 182b6bdf0..edd713755 100644 --- a/src/config.c +++ b/src/config.c @@ -910,11 +910,6 @@ load_network(void) nc->slirp_net[0] = '\0'; } - sprintf(temp, "net_%02i_switch_group", c + 1); - nc->switch_group = ini_section_get_int(cat, temp, NET_SWITCH_GRP_MIN); - if (nc->switch_group < NET_SWITCH_GRP_MIN) - nc->switch_group = NET_SWITCH_GRP_MIN; - sprintf(temp, "net_%02i_secret", c + 1); p = ini_section_get_string(cat, temp, NULL); strncpy(nc->secret, p ? p : "", sizeof(nc->secret) - 1); @@ -3024,12 +3019,6 @@ save_network(void) ini_section_delete_var(cat, temp); } - sprintf(temp, "net_%02i_switch_group", c + 1); - if (nc->switch_group == NET_SWITCH_GRP_MIN) - ini_section_delete_var(cat, temp); - else - ini_section_set_int(cat, temp, nc->switch_group); - sprintf(temp, "net_%02i_secret", c + 1); if (nc->secret[0] == '\0') ini_section_delete_var(cat, temp); diff --git a/src/include/86box/network.h b/src/include/86box/network.h index 78b03e439..d208cd345 100644 --- a/src/include/86box/network.h +++ b/src/include/86box/network.h @@ -60,8 +60,6 @@ #define NET_QUEUE_COUNT 4 #define NET_CARD_MAX 4 #define NET_HOST_INTF_MAX 64 -#define NET_SWITCH_GRP_MIN 1 -#define NET_SWITCH_GRP_MAX 10 #define NET_PERIOD_10M 0.8 #define NET_PERIOD_100M 0.08 @@ -97,7 +95,6 @@ typedef struct netcard_conf_t { int net_type; char host_dev_name[128]; uint32_t link_state; - uint8_t switch_group; char secret[256]; uint8_t promisc_mode; char slirp_net[16]; diff --git a/src/network/net_switch.c b/src/network/net_switch.c index 0f0d4b509..938443997 100644 --- a/src/network/net_switch.c +++ b/src/network/net_switch.c @@ -53,7 +53,7 @@ #define SWITCH_PKT_BATCH NET_QUEUE_LEN -#define SWITCH_MULTICAST_GROUP 0xefff5656 /* 239.255.86.86 */ +#define SWITCH_MULTICAST_GROUP 0xefff5056 /* 239.255.80.86 */ #define SWITCH_MULTICAST_PORT 8086 enum { @@ -478,8 +478,6 @@ net_switch_init(const netcard_t *card, const uint8_t *mac_addr, void *priv, char { netcard_conf_t *netcard = (netcard_conf_t *) priv; - netswitch_log("Network Switch: initializing with group %d...\n", netcard->switch_group); - net_switch_t *netswitch = calloc(1, sizeof(net_switch_t)); memcpy(netswitch->mac_addr, mac_addr, sizeof(netswitch->mac_addr)); netswitch->card = (netcard_t *) card; @@ -514,7 +512,7 @@ net_switch_init(const netcard_t *card, const uint8_t *mac_addr, void *priv, char val = 0; setsockopt(netswitch->socket_rx, IPPROTO_IP, IP_MULTICAST_LOOP, (char *) &val, sizeof(val)); - netswitch->port_out = htons(SWITCH_MULTICAST_PORT - NET_SWITCH_GRP_MIN + netcard->switch_group); + netswitch->port_out = htons(SWITCH_MULTICAST_PORT); struct sockaddr_in addr = { .sin_family = AF_INET, .sin_addr = { .s_addr = htonl(INADDR_ANY) }, diff --git a/src/qt/qt_settingsnetwork.cpp b/src/qt/qt_settingsnetwork.cpp index 878944e60..ff933fceb 100644 --- a/src/qt/qt_settingsnetwork.cpp +++ b/src/qt/qt_settingsnetwork.cpp @@ -49,13 +49,9 @@ SettingsNetwork::enableElements(Ui::SettingsNetwork *ui) auto *option_list_label = findChild(QString("labelOptionList%1").arg(i + 1)); auto *option_list_line = findChild(QString("lineOptionList%1").arg(i + 1)); - // Switch group - auto *switch_group_label = findChild(QString("labelSwitch%1").arg(i + 1)); - // auto *switch_group_hlayout = findChild(QString("HLayoutSwitch%1").arg(i + 1)); - // auto *switch_group_hspacer = findChild(QString("horizontalSpacerSwitch%1").arg(i + 1)); - auto *switch_group_value = findChild(QString("spinnerSwitch%1").arg(i + 1)); - switch_group_value->setMinimum(NET_SWITCH_GRP_MIN); - switch_group_value->setMaximum(NET_SWITCH_GRP_MAX); + // Shared secret + auto *secret_label = findChild(QString("labelSecret%1").arg(i + 1)); + auto *secret_value = findChild(QString("secretSwitch%1").arg(i + 1)); // Promiscuous option auto *promisc_label = findChild(QString("labelPromisc%1").arg(i + 1)); @@ -73,10 +69,8 @@ SettingsNetwork::enableElements(Ui::SettingsNetwork *ui) // NEW STUFF // Make all options invisible by default - // Switch group - switch_group_label->setVisible(false); - switch_group_value->setVisible(false); - // switch_group_hspacer->setVisible(false); + secret_label->setVisible(false); + secret_value->setVisible(false); // Promiscuous options promisc_label->setVisible(false); @@ -142,10 +136,9 @@ SettingsNetwork::enableElements(Ui::SettingsNetwork *ui) option_list_label->setVisible(true); option_list_line->setVisible(true); - // Switch group - switch_group_label->setVisible(true); - switch_group_value->setVisible(true); - // switch_group_hspacer->setVisible(false); + // Shared secret + secret_label->setVisible(true); + secret_value->setVisible(true); // Promiscuous options promisc_label->setVisible(true); @@ -157,10 +150,9 @@ SettingsNetwork::enableElements(Ui::SettingsNetwork *ui) option_list_label->setVisible(true); option_list_line->setVisible(true); - // Switch group - switch_group_label->setVisible(true); - switch_group_value->setVisible(true); - // switch_group_hspacer->setVisible(false); + // Shared secret + secret_label->setVisible(true); + secret_value->setVisible(true); // Hostname hostname_label->setVisible(true); @@ -215,7 +207,7 @@ SettingsNetwork::save() cbox = findChild(QString("comboBoxIntf%1").arg(i + 1)); auto *hostname_value = findChild(QString("hostnameSwitch%1").arg(i + 1)); auto *promisc_value = findChild(QString("boxPromisc%1").arg(i + 1)); - auto *switch_group_value = findChild(QString("spinnerSwitch%1").arg(i + 1)); + auto *secret_value = findChild(QString("secretSwitch%1").arg(i + 1)); memset(net_cards_conf[i].host_dev_name, '\0', sizeof(net_cards_conf[i].host_dev_name)); if (net_cards_conf[i].net_type == NET_TYPE_PCAP) strncpy(net_cards_conf[i].host_dev_name, network_devs[cbox->currentData().toInt()].device, sizeof(net_cards_conf[i].host_dev_name) - 1); @@ -230,10 +222,12 @@ SettingsNetwork::save() else if (net_cards_conf[i].net_type == NET_TYPE_NRSWITCH) { memset(net_cards_conf[i].nrs_hostname, '\0', sizeof(net_cards_conf[i].nrs_hostname)); strncpy(net_cards_conf[i].nrs_hostname, hostname_value->text().toUtf8().constData(), sizeof(net_cards_conf[i].nrs_hostname) - 1); - net_cards_conf[i].switch_group = switch_group_value->value(); + memset(net_cards_conf[i].secret, '\0', sizeof(net_cards_conf[i].secret)); + strncpy(net_cards_conf[i].secret, secret_value->text().toUtf8().constData(), sizeof(net_cards_conf[i].secret) - 1); } else if (net_cards_conf[i].net_type == NET_TYPE_NLSWITCH) { net_cards_conf[i].promisc_mode = promisc_value->isChecked(); - net_cards_conf[i].switch_group = switch_group_value->value(); + memset(net_cards_conf[i].secret, '\0', sizeof(net_cards_conf[i].secret)); + strncpy(net_cards_conf[i].secret, secret_value->text().toUtf8().constData(), sizeof(net_cards_conf[i].secret) - 1); } } } @@ -349,13 +343,13 @@ SettingsNetwork::onCurrentMachineChanged(int machineId) } else if (net_cards_conf[i].net_type == NET_TYPE_NLSWITCH) { auto *promisc_value = findChild(QString("boxPromisc%1").arg(i + 1)); promisc_value->setCheckState(net_cards_conf[i].promisc_mode == 1 ? Qt::CheckState::Checked : Qt::CheckState::Unchecked); - auto *switch_group_value = findChild(QString("spinnerSwitch%1").arg(i + 1)); - switch_group_value->setValue(net_cards_conf[i].switch_group); + auto *secret_value = findChild(QString("secretSwitch%1").arg(i + 1)); + secret_value->setText(net_cards_conf[i].secret); } else if (net_cards_conf[i].net_type == NET_TYPE_NRSWITCH) { auto *hostname_value = findChild(QString("hostnameSwitch%1").arg(i + 1)); hostname_value->setText(net_cards_conf[i].nrs_hostname); - auto *switch_group_value = findChild(QString("spinnerSwitch%1").arg(i + 1)); - switch_group_value->setValue(net_cards_conf[i].switch_group); + auto *secret_value = findChild(QString("secretSwitch%1").arg(i + 1)); + secret_value->setText(net_cards_conf[i].secret); } } } diff --git a/src/qt/qt_settingsnetwork.ui b/src/qt/qt_settingsnetwork.ui index 12b74004f..5f7bd316a 100644 --- a/src/qt/qt_settingsnetwork.ui +++ b/src/qt/qt_settingsnetwork.ui @@ -170,38 +170,18 @@ - + - Switch: + Shared secret: - - - - - 1 - - - 10 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - + + + 256 + + @@ -385,38 +365,18 @@ - + - Switch: + Shared secret: - - - - - 1 - - - 10 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - + + + 256 + + @@ -600,38 +560,18 @@ - + - Switch: + Shared secret: - - - - - 1 - - - 10 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - + + + 256 + + @@ -815,38 +755,18 @@ - + - Switch: + Shared secret: - - - - - 1 - - - 10 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - + + + 256 + + From cc2e97acc7dc9ee0c3d77c81599b8e9a7b89d5cf Mon Sep 17 00:00:00 2001 From: Mike Swanson Date: Mon, 9 Feb 2026 20:23:49 -0800 Subject: [PATCH 3/3] =?UTF-8?q?Translate=20=E2=80=9Cshared=20secret?= =?UTF-8?q?=E2=80=9D=20into=20the=20languages?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I used AI to translate the phrase. If it got any of the wrong, I trust it'll be fixed. :-) --- src/qt/languages/86box.pot | 2 +- src/qt/languages/ca-ES.po | 4 ++-- src/qt/languages/cs-CZ.po | 4 ++-- src/qt/languages/de-DE.po | 4 ++-- src/qt/languages/el-GR.po | 4 ++-- src/qt/languages/es-ES.po | 4 ++-- src/qt/languages/fi-FI.po | 4 ++-- src/qt/languages/fr-FR.po | 4 ++-- src/qt/languages/hr-HR.po | 4 ++-- src/qt/languages/it-IT.po | 4 ++-- src/qt/languages/ja-JP.po | 4 ++-- src/qt/languages/ko-KR.po | 4 ++-- src/qt/languages/nb-NO.po | 4 ++-- src/qt/languages/nl-NL.po | 4 ++-- src/qt/languages/pl-PL.po | 4 ++-- src/qt/languages/pt-BR.po | 4 ++-- src/qt/languages/pt-PT.po | 4 ++-- src/qt/languages/ru-RU.po | 4 ++-- src/qt/languages/sk-SK.po | 4 ++-- src/qt/languages/sl-SI.po | 4 ++-- src/qt/languages/sv-SE.po | 4 ++-- src/qt/languages/tr-TR.po | 4 ++-- src/qt/languages/uk-UA.po | 4 ++-- src/qt/languages/vi-VN.po | 4 ++-- src/qt/languages/zh-CN.po | 4 ++-- src/qt/languages/zh-TW.po | 4 ++-- 26 files changed, 51 insertions(+), 51 deletions(-) diff --git a/src/qt/languages/86box.pot b/src/qt/languages/86box.pot index c62c18ea8..8bcc5c794 100644 --- a/src/qt/languages/86box.pot +++ b/src/qt/languages/86box.pot @@ -2832,7 +2832,7 @@ msgstr "" msgid "Remote Switch" msgstr "" -msgid "Switch:" +msgid "Shared secret:" msgstr "" msgid "Hub Mode" diff --git a/src/qt/languages/ca-ES.po b/src/qt/languages/ca-ES.po index 0c1c8ac89..813b82dcb 100644 --- a/src/qt/languages/ca-ES.po +++ b/src/qt/languages/ca-ES.po @@ -2838,8 +2838,8 @@ msgstr "Commutador local" msgid "Remote Switch" msgstr "Commutador remot" -msgid "Switch:" -msgstr "Commutador:" +msgid "Shared secret:" +msgstr "Secret compartit:" msgid "Hub Mode" msgstr "Modalitat de concentrador" diff --git a/src/qt/languages/cs-CZ.po b/src/qt/languages/cs-CZ.po index 1df82475f..f27ac9d3c 100644 --- a/src/qt/languages/cs-CZ.po +++ b/src/qt/languages/cs-CZ.po @@ -2838,8 +2838,8 @@ msgstr "Lokální switch" msgid "Remote Switch" msgstr "Vzdálený switch" -msgid "Switch:" -msgstr "Switch:" +msgid "Shared secret:" +msgstr "Sdílené tajemství:" msgid "Hub Mode" msgstr "Režim hubu" diff --git a/src/qt/languages/de-DE.po b/src/qt/languages/de-DE.po index d0e649bc2..fc201c303 100644 --- a/src/qt/languages/de-DE.po +++ b/src/qt/languages/de-DE.po @@ -2838,8 +2838,8 @@ msgstr "Lokaler Schalter" msgid "Remote Switch" msgstr "Entfernter Schalter" -msgid "Switch:" -msgstr "Schalter:" +msgid "Shared secret:" +msgstr "Gemeinsames Geheimnis:" msgid "Hub Mode" msgstr "Hub-Modus" diff --git a/src/qt/languages/el-GR.po b/src/qt/languages/el-GR.po index 1442183df..6f10bbba9 100644 --- a/src/qt/languages/el-GR.po +++ b/src/qt/languages/el-GR.po @@ -2883,8 +2883,8 @@ msgstr "Τοπικός Διακόπτης" msgid "Remote Switch" msgstr "Απομακρυσμένος Διακόπτης" -msgid "Switch:" -msgstr "Διακόπτης:" +msgid "Shared secret:" +msgstr "κοινό μυστικό:" msgid "Hub Mode" msgstr "Λειτουργία Hub" diff --git a/src/qt/languages/es-ES.po b/src/qt/languages/es-ES.po index af2e1e75e..54e3d2079 100644 --- a/src/qt/languages/es-ES.po +++ b/src/qt/languages/es-ES.po @@ -2838,8 +2838,8 @@ msgstr "Conmutador local" msgid "Remote Switch" msgstr "Conmutador remoto" -msgid "Switch:" -msgstr "Conmutador:" +msgid "Shared secret:" +msgstr "Secreto compartido:" msgid "Hub Mode" msgstr "Modo de concentrador" diff --git a/src/qt/languages/fi-FI.po b/src/qt/languages/fi-FI.po index 2351f1afa..9d4e84f39 100644 --- a/src/qt/languages/fi-FI.po +++ b/src/qt/languages/fi-FI.po @@ -2838,8 +2838,8 @@ msgstr "Paikallinen kytkin" msgid "Remote Switch" msgstr "Etäkytkin" -msgid "Switch:" -msgstr "Kytkin:" +msgid "Shared secret:" +msgstr "Jaettu salaisuus:" msgid "Hub Mode" msgstr "Hubitila" diff --git a/src/qt/languages/fr-FR.po b/src/qt/languages/fr-FR.po index 42f1a8f40..453b52de4 100644 --- a/src/qt/languages/fr-FR.po +++ b/src/qt/languages/fr-FR.po @@ -2838,8 +2838,8 @@ msgstr "Commutateur local" msgid "Remote Switch" msgstr "Commutateur distant" -msgid "Switch:" -msgstr "Commutateur :" +msgid "Shared secret:" +msgstr "Secret partagé:" msgid "Hub Mode" msgstr "Mode concentrateur" diff --git a/src/qt/languages/hr-HR.po b/src/qt/languages/hr-HR.po index 32aaf1cf7..f1e8e3688 100644 --- a/src/qt/languages/hr-HR.po +++ b/src/qt/languages/hr-HR.po @@ -2840,8 +2840,8 @@ msgstr "Lokalni prekidač" msgid "Remote Switch" msgstr "Udaljeni prekidač" -msgid "Switch:" -msgstr "Prekidač:" +msgid "Shared secret:" +msgstr "Zajednička tajna:" msgid "Hub Mode" msgstr "Način čvorišta" diff --git a/src/qt/languages/it-IT.po b/src/qt/languages/it-IT.po index f46d09159..71fc69bce 100644 --- a/src/qt/languages/it-IT.po +++ b/src/qt/languages/it-IT.po @@ -2838,8 +2838,8 @@ msgstr "Commutatore locale" msgid "Remote Switch" msgstr "Commutatore remoto" -msgid "Switch:" -msgstr "Commutatore:" +msgid "Shared secret:" +msgstr "Segreto condiviso:" msgid "Hub Mode" msgstr "Modalità Hub" diff --git a/src/qt/languages/ja-JP.po b/src/qt/languages/ja-JP.po index 027b05204..2961a28f3 100644 --- a/src/qt/languages/ja-JP.po +++ b/src/qt/languages/ja-JP.po @@ -2839,8 +2839,8 @@ msgstr "ローカルスイッチ" msgid "Remote Switch" msgstr "リモートスイッチ" -msgid "Switch:" -msgstr "スイッチ:" +msgid "Shared secret:" +msgstr "きょうゆうひみつ:" msgid "Hub Mode" msgstr "ハブモード" diff --git a/src/qt/languages/ko-KR.po b/src/qt/languages/ko-KR.po index a46dc07c7..cd85aec57 100644 --- a/src/qt/languages/ko-KR.po +++ b/src/qt/languages/ko-KR.po @@ -2838,8 +2838,8 @@ msgstr "로컬 스위치" msgid "Remote Switch" msgstr "원격 스위치" -msgid "Switch:" -msgstr "스위치:" +msgid "Shared secret:" +msgstr "공유 비밀:" msgid "Hub Mode" msgstr "허브 모드" diff --git a/src/qt/languages/nb-NO.po b/src/qt/languages/nb-NO.po index b22f0bf69..b8370fedb 100644 --- a/src/qt/languages/nb-NO.po +++ b/src/qt/languages/nb-NO.po @@ -2839,8 +2839,8 @@ msgstr "Lokal svitsj" msgid "Remote Switch" msgstr "Ekstern svitsj" -msgid "Switch:" -msgstr "Svitsj:" +msgid "Shared secret:" +msgstr "Delt hemmelighet:" msgid "Hub Mode" msgstr "Hub-modus" diff --git a/src/qt/languages/nl-NL.po b/src/qt/languages/nl-NL.po index 3ad6f4feb..e48409dcd 100644 --- a/src/qt/languages/nl-NL.po +++ b/src/qt/languages/nl-NL.po @@ -2838,8 +2838,8 @@ msgstr "Lokale Switch" msgid "Remote Switch" msgstr "Externe Switch" -msgid "Switch:" -msgstr "Switch:" +msgid "Shared secret:" +msgstr "Gedeeld geheim:" msgid "Hub Mode" msgstr "Hub-modus" diff --git a/src/qt/languages/pl-PL.po b/src/qt/languages/pl-PL.po index e67ada685..e235bf995 100644 --- a/src/qt/languages/pl-PL.po +++ b/src/qt/languages/pl-PL.po @@ -2839,8 +2839,8 @@ msgstr "Switch lokalny" msgid "Remote Switch" msgstr "Switch zdalny" -msgid "Switch:" -msgstr "Switch:" +msgid "Shared secret:" +msgstr "Wspólny sekret:" msgid "Hub Mode" msgstr "Tryb hub" diff --git a/src/qt/languages/pt-BR.po b/src/qt/languages/pt-BR.po index 5ffbc2c72..05829de13 100644 --- a/src/qt/languages/pt-BR.po +++ b/src/qt/languages/pt-BR.po @@ -2832,8 +2832,8 @@ msgstr "Switch Local" msgid "Remote Switch" msgstr "Switch Remoto" -msgid "Switch:" -msgstr "Switch:" +msgid "Shared secret:" +msgstr "Segredo compartihado:" msgid "Hub Mode" msgstr "Modo Hub" diff --git a/src/qt/languages/pt-PT.po b/src/qt/languages/pt-PT.po index 8f0f55caf..87619edf7 100644 --- a/src/qt/languages/pt-PT.po +++ b/src/qt/languages/pt-PT.po @@ -2839,8 +2839,8 @@ msgstr "Comutador local" msgid "Remote Switch" msgstr "Comutador remoto" -msgid "Switch:" -msgstr "Comutador:" +msgid "Shared secret:" +msgstr "Segredo compartihado:" msgid "Hub Mode" msgstr "Modo de concentrador" diff --git a/src/qt/languages/ru-RU.po b/src/qt/languages/ru-RU.po index 9ca679356..2f272b262 100644 --- a/src/qt/languages/ru-RU.po +++ b/src/qt/languages/ru-RU.po @@ -2851,8 +2851,8 @@ msgstr "Локальный коммутатор" msgid "Remote Switch" msgstr "Удалённый коммутатор" -msgid "Switch:" -msgstr "Номер коммутатора:" +msgid "Shared secret:" +msgstr "Общий секрет:" msgid "Hub Mode" msgstr "Режим концентратора" diff --git a/src/qt/languages/sk-SK.po b/src/qt/languages/sk-SK.po index a5570faeb..2de580e32 100644 --- a/src/qt/languages/sk-SK.po +++ b/src/qt/languages/sk-SK.po @@ -2838,8 +2838,8 @@ msgstr "Lokálny prepínač" msgid "Remote Switch" msgstr "Vzdialený prepínač" -msgid "Switch:" -msgstr "Prepínač:" +msgid "Shared secret:" +msgstr "Zdieľané tajomstvo:" msgid "Hub Mode" msgstr "Režim hubu" diff --git a/src/qt/languages/sl-SI.po b/src/qt/languages/sl-SI.po index dfe0acbcd..b4d857e6a 100644 --- a/src/qt/languages/sl-SI.po +++ b/src/qt/languages/sl-SI.po @@ -2840,8 +2840,8 @@ msgstr "Lokalno stikalo" msgid "Remote Switch" msgstr "Oddaljeno stikalo" -msgid "Switch:" -msgstr "Stikalo:" +msgid "Shared secret:" +msgstr "Skupni skrivnost:" msgid "Hub Mode" msgstr "Način koncentratorja" diff --git a/src/qt/languages/sv-SE.po b/src/qt/languages/sv-SE.po index 5a8c7291c..c5a09f506 100644 --- a/src/qt/languages/sv-SE.po +++ b/src/qt/languages/sv-SE.po @@ -2838,8 +2838,8 @@ msgstr "Lokal switch" msgid "Remote Switch" msgstr "Fjärr-switch" -msgid "Switch:" -msgstr "Switch:" +msgid "Shared secret:" +msgstr "Delad hemlighet:" msgid "Hub Mode" msgstr "Hubb-läge" diff --git a/src/qt/languages/tr-TR.po b/src/qt/languages/tr-TR.po index 510fd82f3..d113c92b8 100644 --- a/src/qt/languages/tr-TR.po +++ b/src/qt/languages/tr-TR.po @@ -2838,8 +2838,8 @@ msgstr "Yerel Switch" msgid "Remote Switch" msgstr "Uzak Switch" -msgid "Switch:" -msgstr "Switch:" +msgid "Shared secret:" +msgstr "Paylaşılan sır:" msgid "Hub Mode" msgstr "Hub Modu" diff --git a/src/qt/languages/uk-UA.po b/src/qt/languages/uk-UA.po index d1964e647..3e6b695e1 100644 --- a/src/qt/languages/uk-UA.po +++ b/src/qt/languages/uk-UA.po @@ -2840,8 +2840,8 @@ msgstr "Локальний комутатор" msgid "Remote Switch" msgstr "Віддалений комутатор" -msgid "Switch:" -msgstr "Номер комутатора:" +msgid "Shared secret:" +msgstr "Спільний секрет:" msgid "Hub Mode" msgstr "Режим концентратора" diff --git a/src/qt/languages/vi-VN.po b/src/qt/languages/vi-VN.po index 73b59831a..4bd9d7baa 100644 --- a/src/qt/languages/vi-VN.po +++ b/src/qt/languages/vi-VN.po @@ -2839,8 +2839,8 @@ msgstr "Công tắc cục bộ" msgid "Remote Switch" msgstr "Công tắc từ xa" -msgid "Switch:" -msgstr "Công tắc:" +msgid "Shared secret:" +msgstr "Bí mật chia sẻ:" msgid "Hub Mode" msgstr "Chế độ hub" diff --git a/src/qt/languages/zh-CN.po b/src/qt/languages/zh-CN.po index 7e98480cd..ddca350e8 100644 --- a/src/qt/languages/zh-CN.po +++ b/src/qt/languages/zh-CN.po @@ -2839,8 +2839,8 @@ msgstr "本地交换机" msgid "Remote Switch" msgstr "远程交换机" -msgid "Switch:" -msgstr "交换机:" +msgid "Shared secret:" +msgstr "共享秘密:" msgid "Hub Mode" msgstr "集线器模式" diff --git a/src/qt/languages/zh-TW.po b/src/qt/languages/zh-TW.po index 78365a911..f1d720adc 100644 --- a/src/qt/languages/zh-TW.po +++ b/src/qt/languages/zh-TW.po @@ -2839,8 +2839,8 @@ msgstr "本地交換器" msgid "Remote Switch" msgstr "遠端交換器" -msgid "Switch:" -msgstr "交換器:" +msgid "Shared secret:" +msgstr "共享秘密:" msgid "Hub Mode" msgstr "集線器模式"