mirror of
https://github.com/cjdelisle/cjdns
synced 2025-10-06 00:32:50 +02:00
Make ETH address an official Sockaddr type.
This commit is contained in:
1
.clangd
1
.clangd
@@ -3,6 +3,7 @@ CompileFlags: # Tweak the parse settings, example directory given to show format
|
|||||||
- "-DPARANOIA=1"
|
- "-DPARANOIA=1"
|
||||||
- "-DIdentity_CHECK=1"
|
- "-DIdentity_CHECK=1"
|
||||||
- "-DCJDNS_RAND_U64_PER_FILE=1"
|
- "-DCJDNS_RAND_U64_PER_FILE=1"
|
||||||
|
- "-DHAS_ETH_INTERFACE=1"
|
||||||
- "-Wall"
|
- "-Wall"
|
||||||
- "-Wextra"
|
- "-Wextra"
|
||||||
|
|
||||||
|
@@ -44,20 +44,6 @@ struct ETHInterface_Header
|
|||||||
#define ETHInterface_Header_SIZE 6
|
#define ETHInterface_Header_SIZE 6
|
||||||
Assert_compileTime(sizeof(struct ETHInterface_Header) == ETHInterface_Header_SIZE);
|
Assert_compileTime(sizeof(struct ETHInterface_Header) == ETHInterface_Header_SIZE);
|
||||||
|
|
||||||
/** The content of a Sockaddr emitted from ETHInterface. */
|
|
||||||
struct ETHInterface_Sockaddr
|
|
||||||
{
|
|
||||||
struct Sockaddr generic;
|
|
||||||
/*
|
|
||||||
* We need to make the first byte following the Sockaddr be 0 because
|
|
||||||
* Sockaddr_normalizeNative will zero it.
|
|
||||||
*/
|
|
||||||
uint16_t zero;
|
|
||||||
uint8_t mac[6];
|
|
||||||
};
|
|
||||||
#define ETHInterface_Sockaddr_SIZE 16
|
|
||||||
Assert_compileTime(sizeof(struct ETHInterface_Sockaddr) == ETHInterface_Sockaddr_SIZE);
|
|
||||||
|
|
||||||
#define ETHInterface_CURRENT_VERSION 0
|
#define ETHInterface_CURRENT_VERSION 0
|
||||||
|
|
||||||
struct ETHInterface
|
struct ETHInterface
|
||||||
|
@@ -13,7 +13,6 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#include "interface/ETHInterface_admin.h"
|
#include "interface/ETHInterface_admin.h"
|
||||||
#include "exception/Err.h"
|
|
||||||
#include "interface/ETHInterface.h"
|
#include "interface/ETHInterface.h"
|
||||||
#include "benc/Int.h"
|
#include "benc/Int.h"
|
||||||
#include "admin/Admin.h"
|
#include "admin/Admin.h"
|
||||||
@@ -22,8 +21,8 @@
|
|||||||
#include "net/InterfaceController.h"
|
#include "net/InterfaceController.h"
|
||||||
#include "rust/cjdns_sys/RTypes.h"
|
#include "rust/cjdns_sys/RTypes.h"
|
||||||
#include "rust/cjdns_sys/Rffi.h"
|
#include "rust/cjdns_sys/Rffi.h"
|
||||||
#include "util/AddrTools.h"
|
|
||||||
#include "util/Identity.h"
|
#include "util/Identity.h"
|
||||||
|
#include "util/platform/Sockaddr.h"
|
||||||
|
|
||||||
struct Context
|
struct Context
|
||||||
{
|
{
|
||||||
@@ -56,19 +55,16 @@ static void beginConnection(Dict* args,
|
|||||||
|
|
||||||
uint8_t pkBytes[32];
|
uint8_t pkBytes[32];
|
||||||
|
|
||||||
struct ETHInterface_Sockaddr sockaddr = {
|
struct Sockaddr_storage ss;
|
||||||
.generic = {
|
|
||||||
.addrLen = ETHInterface_Sockaddr_SIZE
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (Key_parse(publicKey, pkBytes, NULL)) {
|
if (Key_parse(publicKey, pkBytes, NULL)) {
|
||||||
error = "invalid publicKey";
|
error = "invalid publicKey";
|
||||||
} else if (macAddress->len < 17 || AddrTools_parseMac(sockaddr.mac, macAddress->bytes)) {
|
} else if (Sockaddr_parse(macAddress->bytes, &ss)) {
|
||||||
|
error = "invalid macAddress";
|
||||||
|
} else if (ss.addr.type != Sockaddr_ETHERNET) {
|
||||||
error = "invalid macAddress";
|
error = "invalid macAddress";
|
||||||
} else {
|
} else {
|
||||||
int ret = InterfaceController_bootstrapPeer(
|
int ret = InterfaceController_bootstrapPeer(
|
||||||
ctx->ic, ifNum, pkBytes, &sockaddr.generic, password, login, peerName, version);
|
ctx->ic, ifNum, pkBytes, &ss.addr, password, login, peerName, version);
|
||||||
|
|
||||||
if (ret == InterfaceController_bootstrapPeer_BAD_IFNUM) {
|
if (ret == InterfaceController_bootstrapPeer_BAD_IFNUM) {
|
||||||
error = "invalid interfaceNumber";
|
error = "invalid interfaceNumber";
|
||||||
|
@@ -14,6 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
#include "interface/ETHInterface.h"
|
#include "interface/ETHInterface.h"
|
||||||
#include "exception/Err.h"
|
#include "exception/Err.h"
|
||||||
|
#include "util/platform/Sockaddr.h"
|
||||||
#include "wire/Message.h"
|
#include "wire/Message.h"
|
||||||
#include "wire/Ethernet.h"
|
#include "wire/Ethernet.h"
|
||||||
#include "util/Assert.h"
|
#include "util/Assert.h"
|
||||||
@@ -73,12 +74,8 @@ static Iface_DEFUN sendMessage(Message_t* msg, struct Iface* iface)
|
|||||||
{
|
{
|
||||||
struct ETHInterface_pvt* ctx = Identity_containerOf(iface, struct ETHInterface_pvt, iface);
|
struct ETHInterface_pvt* ctx = Identity_containerOf(iface, struct ETHInterface_pvt, iface);
|
||||||
|
|
||||||
struct Sockaddr* sa = (struct Sockaddr*) Message_bytes(msg);
|
struct Sockaddr_storage ss = { .addr.addrLen = 0 };
|
||||||
Assert_true(Message_getLength(msg) >= Sockaddr_OVERHEAD);
|
Err(Sockaddr_read(&ss, msg));
|
||||||
Assert_true(sa->addrLen <= ETHInterface_Sockaddr_SIZE);
|
|
||||||
|
|
||||||
struct ETHInterface_Sockaddr sockaddr = { .generic = { .addrLen = 0 } };
|
|
||||||
Err(Message_epop(msg, &sockaddr, sa->addrLen));
|
|
||||||
|
|
||||||
struct ETHInterface_Header hdr = {
|
struct ETHInterface_Header hdr = {
|
||||||
.version = ETHInterface_CURRENT_VERSION,
|
.version = ETHInterface_CURRENT_VERSION,
|
||||||
@@ -91,10 +88,12 @@ static Iface_DEFUN sendMessage(Message_t* msg, struct Iface* iface)
|
|||||||
struct ethernet_frame ethFr = {
|
struct ethernet_frame ethFr = {
|
||||||
.type = Ethernet_TYPE_CJDNS
|
.type = Ethernet_TYPE_CJDNS
|
||||||
};
|
};
|
||||||
if (sockaddr.generic.flags & Sockaddr_flags_BCAST) {
|
if (ss.addr.flags & Sockaddr_flags_BCAST) {
|
||||||
Bits_memset(ethFr.dest, 0xff, 6);
|
Bits_memset(ethFr.dest, 0xff, 6);
|
||||||
} else {
|
} else {
|
||||||
Bits_memcpy(ethFr.dest, sockaddr.mac, 6);
|
if (Sockaddr_getMac(ethFr.dest, &ss.addr)) {
|
||||||
|
Err_raise(Message_getAlloc(msg), "Sockaddr on message not ETH type");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Bits_memcpy(ethFr.src, ctx->myMac, 6);
|
Bits_memcpy(ethFr.src, ctx->myMac, 6);
|
||||||
Err(Message_epush(msg, ðFr, ethernet_frame_SIZE));
|
Err(Message_epush(msg, ðFr, ethernet_frame_SIZE));
|
||||||
@@ -152,14 +151,9 @@ static void handleEvent2(struct ETHInterface_pvt* context,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ETHInterface_Sockaddr sockaddr = { .zero = 0 };
|
struct Sockaddr_storage ss = { .addr.addrLen = 0 };
|
||||||
Bits_memcpy(sockaddr.mac, src, 6);
|
struct Sockaddr* sa = Sockaddr_initFromEth(&ss, src);
|
||||||
sockaddr.generic.addrLen = ETHInterface_Sockaddr_SIZE;
|
Err_assert(Sockaddr_write(sa, msg));
|
||||||
if (dst[0] == 0xff) {
|
|
||||||
sockaddr.generic.flags |= Sockaddr_flags_BCAST;
|
|
||||||
}
|
|
||||||
|
|
||||||
Err_assert(Message_epush(msg, &sockaddr, ETHInterface_Sockaddr_SIZE));
|
|
||||||
|
|
||||||
Assert_true(!((uintptr_t)Message_bytes(msg) % 4) && "Alignment fault");
|
Assert_true(!((uintptr_t)Message_bytes(msg) % 4) && "Alignment fault");
|
||||||
|
|
||||||
|
@@ -16,6 +16,7 @@
|
|||||||
#include "exception/Err.h"
|
#include "exception/Err.h"
|
||||||
#include "memory/Allocator.h"
|
#include "memory/Allocator.h"
|
||||||
#include "net/InterfaceController.h"
|
#include "net/InterfaceController.h"
|
||||||
|
#include "util/platform/Sockaddr.h"
|
||||||
#include "wire/Headers.h"
|
#include "wire/Headers.h"
|
||||||
#include "wire/Message.h"
|
#include "wire/Message.h"
|
||||||
#include "wire/Error.h"
|
#include "wire/Error.h"
|
||||||
@@ -103,20 +104,18 @@ static Iface_DEFUN sendMessage(Message_t* msg, struct Iface* iface)
|
|||||||
{
|
{
|
||||||
struct ETHInterface_pvt* ctx = Identity_containerOf(iface, struct ETHInterface_pvt, iface);
|
struct ETHInterface_pvt* ctx = Identity_containerOf(iface, struct ETHInterface_pvt, iface);
|
||||||
|
|
||||||
struct Sockaddr* sa = (struct Sockaddr*) Message_bytes(msg);
|
struct Sockaddr_storage ss = { .addr.addrLen = 0 };
|
||||||
Assert_true(Message_getLength(msg) >= Sockaddr_OVERHEAD);
|
Err(Sockaddr_read(&ss, msg));
|
||||||
Assert_true(sa->addrLen <= ETHInterface_Sockaddr_SIZE);
|
|
||||||
|
|
||||||
struct ETHInterface_Sockaddr sockaddr = { .generic = { .addrLen = 0 } };
|
|
||||||
Err(Message_epop(msg, &sockaddr, sa->addrLen));
|
|
||||||
|
|
||||||
struct sockaddr_ll addr;
|
struct sockaddr_ll addr;
|
||||||
Bits_memcpy(&addr, &ctx->addrBase, sizeof(struct sockaddr_ll));
|
Bits_memcpy(&addr, &ctx->addrBase, sizeof(struct sockaddr_ll));
|
||||||
|
|
||||||
if (sockaddr.generic.flags & Sockaddr_flags_BCAST) {
|
if (ss.addr.flags & Sockaddr_flags_BCAST) {
|
||||||
Bits_memset(addr.sll_addr, 0xff, 6);
|
Bits_memset(addr.sll_addr, 0xff, 6);
|
||||||
} else {
|
} else {
|
||||||
Bits_memcpy(addr.sll_addr, sockaddr.mac, 6);
|
if (Sockaddr_getMac(addr.sll_addr, &ss.addr)) {
|
||||||
|
Err_raise(Message_getAlloc(msg), "Sockaddr on message not ETH type");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ETHInterface_Header hdr = {
|
struct ETHInterface_Header hdr = {
|
||||||
@@ -180,14 +179,13 @@ static void handleEvent2(struct ETHInterface_pvt* context, struct Allocator* mes
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ETHInterface_Sockaddr sockaddr = { .zero = 0 };
|
struct Sockaddr_storage ss;
|
||||||
Bits_memcpy(sockaddr.mac, addr.sll_addr, 6);
|
Sockaddr_initFromEth(&ss, addr.sll_addr);
|
||||||
sockaddr.generic.addrLen = ETHInterface_Sockaddr_SIZE;
|
|
||||||
if (addr.sll_pkttype == PACKET_BROADCAST) {
|
if (addr.sll_pkttype == PACKET_BROADCAST) {
|
||||||
sockaddr.generic.flags |= Sockaddr_flags_BCAST;
|
ss.addr.flags |= Sockaddr_flags_BCAST;
|
||||||
}
|
}
|
||||||
|
|
||||||
Err_assert(Message_epush(msg, &sockaddr, ETHInterface_Sockaddr_SIZE));
|
Err_assert(Sockaddr_write(&ss.addr, msg));
|
||||||
|
|
||||||
Assert_true(!((uintptr_t)Message_bytes(msg) % 4) && "Alignment fault");
|
Assert_true(!((uintptr_t)Message_bytes(msg) % 4) && "Alignment fault");
|
||||||
|
|
||||||
|
@@ -89,19 +89,7 @@ static void adminPeerStats(Dict* args, void* vcontext, String* txid, struct Allo
|
|||||||
|
|
||||||
Dict_putStringC(d, "addr", Address_toStringKey(&stats[i].addr, alloc), alloc);
|
Dict_putStringC(d, "addr", Address_toStringKey(&stats[i].addr, alloc), alloc);
|
||||||
|
|
||||||
String* lladdrString;
|
String* lladdrString = String_new(Sockaddr_print(stats[i].lladdr, alloc), alloc);
|
||||||
#ifdef HAS_ETH_INTERFACE
|
|
||||||
if (ETHInterface_Sockaddr_SIZE == stats[i].lladdr->addrLen) {
|
|
||||||
struct ETHInterface_Sockaddr* eth = (struct ETHInterface_Sockaddr*) stats[i].lladdr;
|
|
||||||
uint8_t printedMac[18];
|
|
||||||
AddrTools_printMac(printedMac, eth->mac);
|
|
||||||
lladdrString = String_new(printedMac, alloc);
|
|
||||||
} else {
|
|
||||||
lladdrString = String_new(Sockaddr_print(stats[i].lladdr, alloc), alloc);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
lladdrString = String_new(Sockaddr_print(stats[i].lladdr, alloc), alloc);
|
|
||||||
#endif
|
|
||||||
Dict_putStringC(d, "lladdr", lladdrString, alloc);
|
Dict_putStringC(d, "lladdr", lladdrString, alloc);
|
||||||
|
|
||||||
String* stateString = String_new(InterfaceController_stateString(stats[i].state), alloc);
|
String* stateString = String_new(InterfaceController_stateString(stats[i].state), alloc);
|
||||||
|
@@ -12,15 +12,18 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
#include "exception/Err.h"
|
||||||
#include "rust/cjdns_sys/Rffi.h"
|
#include "rust/cjdns_sys/Rffi.h"
|
||||||
#include "benc/String.h"
|
#include "benc/String.h"
|
||||||
#include "memory/Allocator.h"
|
#include "memory/Allocator.h"
|
||||||
#include "util/platform/Sockaddr.h"
|
#include "util/platform/Sockaddr.h"
|
||||||
|
#include "util/AddrTools.h"
|
||||||
#include "util/CString.h"
|
#include "util/CString.h"
|
||||||
#include "util/Bits.h"
|
#include "util/Bits.h"
|
||||||
#include "util/Hex.h"
|
#include "util/Hex.h"
|
||||||
#include "util/Hash.h"
|
#include "util/Hash.h"
|
||||||
#include "util/Base10.h"
|
#include "util/Base10.h"
|
||||||
|
#include "wire/Message.h"
|
||||||
|
|
||||||
#include <sodium/crypto_hash_sha256.h>
|
#include <sodium/crypto_hash_sha256.h>
|
||||||
|
|
||||||
@@ -53,6 +56,13 @@ struct Sockaddr_in6_pvt
|
|||||||
struct Sockaddr pub;
|
struct Sockaddr pub;
|
||||||
struct sockaddr_in6 si;
|
struct sockaddr_in6 si;
|
||||||
};
|
};
|
||||||
|
typedef struct Sockaddr_eth_pvt
|
||||||
|
{
|
||||||
|
struct Sockaddr pub;
|
||||||
|
uint16_t zero;
|
||||||
|
uint8_t mac[6];
|
||||||
|
} Sockaddr_eth_pvt_t;
|
||||||
|
Assert_compileTime(sizeof(Sockaddr_eth_pvt_t) == 16);
|
||||||
|
|
||||||
const struct Sockaddr* const Sockaddr_LOOPBACK_be =
|
const struct Sockaddr* const Sockaddr_LOOPBACK_be =
|
||||||
(const struct Sockaddr*) &((const struct Sockaddr_in_pvt) {
|
(const struct Sockaddr*) &((const struct Sockaddr_in_pvt) {
|
||||||
@@ -106,6 +116,18 @@ int Sockaddr_parse(const char* input, struct Sockaddr_storage* out)
|
|||||||
}
|
}
|
||||||
CString_safeStrncpy(buff, input, 63);
|
CString_safeStrncpy(buff, input, 63);
|
||||||
|
|
||||||
|
if (CString_strlen(buff) == 17) {
|
||||||
|
// 17 bytes long, try it as a MAC
|
||||||
|
Bits_memset(out, 0, sizeof(struct Sockaddr_storage));
|
||||||
|
Sockaddr_eth_pvt_t* eth = (Sockaddr_eth_pvt_t*) out;
|
||||||
|
if (AddrTools_parseMac(eth->mac, buff) == 0) {
|
||||||
|
out->addr.addrLen = sizeof *eth;
|
||||||
|
out->addr.type = Sockaddr_ETHERNET;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// not a MaC, keep trying, lots of things are 17 bytes.
|
||||||
|
}
|
||||||
|
|
||||||
int64_t port = 0;
|
int64_t port = 0;
|
||||||
char* lastColon = CString_strrchr(buff, ':');
|
char* lastColon = CString_strrchr(buff, ':');
|
||||||
char* firstColon = CString_strchr(buff, ':');
|
char* firstColon = CString_strchr(buff, ':');
|
||||||
@@ -191,6 +213,16 @@ char* Sockaddr_print(struct Sockaddr* sockaddr, struct Allocator* alloc)
|
|||||||
return out->bytes;
|
return out->bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sockaddr->type == Sockaddr_ETHERNET) {
|
||||||
|
if (sockaddr->addrLen != sizeof(Sockaddr_eth_pvt_t)) {
|
||||||
|
return "eth/invalid";
|
||||||
|
}
|
||||||
|
Sockaddr_eth_pvt_t* eth = (Sockaddr_eth_pvt_t*) sockaddr;
|
||||||
|
String* out = String_printf(alloc, "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||||
|
eth->mac[0], eth->mac[1], eth->mac[2], eth->mac[3], eth->mac[4], eth->mac[5]);
|
||||||
|
return out->bytes;
|
||||||
|
}
|
||||||
|
|
||||||
struct Sockaddr_pvt* addr = (struct Sockaddr_pvt*) sockaddr;
|
struct Sockaddr_pvt* addr = (struct Sockaddr_pvt*) sockaddr;
|
||||||
|
|
||||||
void* inAddr;
|
void* inAddr;
|
||||||
@@ -244,6 +276,9 @@ static uint16_t* getPortPtr(struct Sockaddr* sockaddr)
|
|||||||
if (sockaddr->addrLen < (2 + Sockaddr_OVERHEAD)) {
|
if (sockaddr->addrLen < (2 + Sockaddr_OVERHEAD)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
if (sockaddr->type != Sockaddr_PLATFORM) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
struct Sockaddr_pvt* sa = (struct Sockaddr_pvt*) sockaddr;
|
struct Sockaddr_pvt* sa = (struct Sockaddr_pvt*) sockaddr;
|
||||||
switch (sa->ss.ss_family) {
|
switch (sa->ss.ss_family) {
|
||||||
case AF_INET: return &((struct sockaddr_in*)&sa->ss)->sin_port;
|
case AF_INET: return &((struct sockaddr_in*)&sa->ss)->sin_port;
|
||||||
@@ -281,6 +316,9 @@ int Sockaddr_getAddress(struct Sockaddr* sockaddr, void* addrPtr)
|
|||||||
if (sockaddr->addrLen < (2 + Sockaddr_OVERHEAD)) {
|
if (sockaddr->addrLen < (2 + Sockaddr_OVERHEAD)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if (sockaddr->type != Sockaddr_PLATFORM) {
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
struct Sockaddr_pvt* sa = (struct Sockaddr_pvt*) sockaddr;
|
struct Sockaddr_pvt* sa = (struct Sockaddr_pvt*) sockaddr;
|
||||||
if (addrPtr) {
|
if (addrPtr) {
|
||||||
void** ap = (void**) addrPtr;
|
void** ap = (void**) addrPtr;
|
||||||
@@ -303,6 +341,9 @@ int Sockaddr_getFamily(const struct Sockaddr* sockaddr)
|
|||||||
if (sockaddr->addrLen < (2 + Sockaddr_OVERHEAD)) {
|
if (sockaddr->addrLen < (2 + Sockaddr_OVERHEAD)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if (sockaddr->type != Sockaddr_PLATFORM) {
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
const struct Sockaddr_pvt* sa = (const struct Sockaddr_pvt*) sockaddr;
|
const struct Sockaddr_pvt* sa = (const struct Sockaddr_pvt*) sockaddr;
|
||||||
return sa->ss.ss_family;
|
return sa->ss.ss_family;
|
||||||
}
|
}
|
||||||
@@ -312,6 +353,27 @@ int Sockaddr_getFamily_fromRust(const struct Sockaddr* sockaddr)
|
|||||||
return Sockaddr_getFamily(sockaddr);
|
return Sockaddr_getFamily(sockaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Sockaddr* Sockaddr_initFromEth(struct Sockaddr_storage* out, const uint8_t mac[static 6]) {
|
||||||
|
Sockaddr_eth_pvt_t* eth = (Sockaddr_eth_pvt_t*) out;
|
||||||
|
Bits_memset(eth, 0, sizeof *eth);
|
||||||
|
Bits_memcpy(eth->mac, mac, 6);
|
||||||
|
eth->pub.addrLen = sizeof *eth;
|
||||||
|
eth->pub.type = Sockaddr_ETHERNET;
|
||||||
|
if (mac[0] == 0xff) {
|
||||||
|
eth->pub.flags |= Sockaddr_flags_BCAST;
|
||||||
|
}
|
||||||
|
return &out->addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Sockaddr_getMac(uint8_t out[static 6], const struct Sockaddr* sockaddr) {
|
||||||
|
if (sockaddr->addrLen != sizeof(Sockaddr_eth_pvt_t) || sockaddr->type != Sockaddr_ETHERNET) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
Sockaddr_eth_pvt_t* eth = (Sockaddr_eth_pvt_t*) sockaddr;
|
||||||
|
Bits_memcpy(out, eth->mac, 6);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
struct Sockaddr* Sockaddr_initFromBytes(struct Sockaddr_storage* out, const uint8_t* bytes, int addrFamily)
|
struct Sockaddr* Sockaddr_initFromBytes(struct Sockaddr_storage* out, const uint8_t* bytes, int addrFamily)
|
||||||
{
|
{
|
||||||
switch (addrFamily) {
|
switch (addrFamily) {
|
||||||
@@ -351,13 +413,6 @@ struct Sockaddr* Sockaddr_fromBytes(const uint8_t* bytes, int addrFamily, struct
|
|||||||
return Sockaddr_clone(sa, alloc);
|
return Sockaddr_clone(sa, alloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sockaddr_normalizeNative(void* nativeSockaddr)
|
|
||||||
{
|
|
||||||
#if defined(freebsd) || defined(openbsd) || defined(netbsd) || defined(darwin)
|
|
||||||
((struct sockaddr*)nativeSockaddr)->sa_len = 0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t Sockaddr_hash(const struct Sockaddr* addr)
|
uint32_t Sockaddr_hash(const struct Sockaddr* addr)
|
||||||
{
|
{
|
||||||
return Hash_compute((uint8_t*)addr, addr->addrLen);
|
return Hash_compute((uint8_t*)addr, addr->addrLen);
|
||||||
@@ -375,7 +430,7 @@ void Sockaddr_asIp6(uint8_t addrOut[static 16], const struct Sockaddr* sockaddr)
|
|||||||
}
|
}
|
||||||
struct Sockaddr_pvt* sa = (struct Sockaddr_pvt*) sockaddr;
|
struct Sockaddr_pvt* sa = (struct Sockaddr_pvt*) sockaddr;
|
||||||
Bits_memset(addrOut, 0, 16);
|
Bits_memset(addrOut, 0, 16);
|
||||||
switch (sa->ss.ss_family) {
|
switch (Sockaddr_getFamily(sockaddr)) {
|
||||||
case AF_INET: {
|
case AF_INET: {
|
||||||
// IPv4 in 6
|
// IPv4 in 6
|
||||||
addrOut[10] = 0xff;
|
addrOut[10] = 0xff;
|
||||||
@@ -392,7 +447,7 @@ void Sockaddr_asIp6(uint8_t addrOut[static 16], const struct Sockaddr* sockaddr)
|
|||||||
uint16_t len = sa->pub.addrLen - Sockaddr_OVERHEAD;
|
uint16_t len = sa->pub.addrLen - Sockaddr_OVERHEAD;
|
||||||
if (len <= 14) {
|
if (len <= 14) {
|
||||||
addrOut[0] = 0xff;
|
addrOut[0] = 0xff;
|
||||||
addrOut[1] = 0xfe;
|
addrOut[1] = 0xfe - sockaddr->type;
|
||||||
Bits_memcpy(&addrOut[16-len], &sa->ss, len);
|
Bits_memcpy(&addrOut[16-len], &sa->ss, len);
|
||||||
} else {
|
} else {
|
||||||
uint8_t hash[32];
|
uint8_t hash[32];
|
||||||
@@ -411,7 +466,13 @@ void Sockaddr_asIp6_fromRust(uint8_t addrOut[static 16], const struct Sockaddr*
|
|||||||
|
|
||||||
int Sockaddr_compare(const struct Sockaddr* a, const struct Sockaddr* b)
|
int Sockaddr_compare(const struct Sockaddr* a, const struct Sockaddr* b)
|
||||||
{
|
{
|
||||||
return Bits_memcmp(a, b, a->addrLen);
|
if (a->addrLen < b->addrLen) {
|
||||||
|
return -1;
|
||||||
|
} else if (a->addrLen > b->addrLen) {
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return Bits_memcmp(a, b, a->addrLen);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t Sockaddr_addrHandle(const struct Sockaddr* addr)
|
uint32_t Sockaddr_addrHandle(const struct Sockaddr* addr)
|
||||||
@@ -436,3 +497,21 @@ void Sockaddr_addrFromHandle(struct Sockaddr* addr, uint32_t handle)
|
|||||||
addr->addrLen = sizeof(struct Sockaddr);
|
addr->addrLen = sizeof(struct Sockaddr);
|
||||||
Bits_memcpy(&((uint8_t*)addr)[4], &handle, 4);
|
Bits_memcpy(&((uint8_t*)addr)[4], &handle, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Err_DEFUN Sockaddr_read(struct Sockaddr_storage* out, Message_t* readFrom) {
|
||||||
|
if (Message_getLength(readFrom) < Sockaddr_OVERHEAD) {
|
||||||
|
Err_raise(Message_getAlloc(readFrom),
|
||||||
|
"Error: Message len [%d] too short to contain Sockaddr",
|
||||||
|
Message_getLength(readFrom));
|
||||||
|
}
|
||||||
|
Err(Message_epop(readFrom, &out->addr, sizeof out->addr));
|
||||||
|
if (out->addr.addrLen < Sockaddr_OVERHEAD) {
|
||||||
|
Err_raise(Message_getAlloc(readFrom),
|
||||||
|
"Invalid addrLen in Sockaddr: [%d]", out->addr.addrLen);
|
||||||
|
}
|
||||||
|
Err(Message_epop(readFrom, &out->nativeAddr, out->addr.addrLen - Sockaddr_OVERHEAD));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
Err_DEFUN Sockaddr_write(const struct Sockaddr* from, Message_t* writeTo) {
|
||||||
|
return Message_epush(writeTo, from, from->addrLen);
|
||||||
|
}
|
@@ -15,9 +15,11 @@
|
|||||||
#ifndef Sockaddr_H
|
#ifndef Sockaddr_H
|
||||||
#define Sockaddr_H
|
#define Sockaddr_H
|
||||||
|
|
||||||
|
#include "exception/Err.h"
|
||||||
#include "memory/Allocator.h"
|
#include "memory/Allocator.h"
|
||||||
#include "util/Endian.h"
|
#include "util/Endian.h"
|
||||||
#include "util/Linker.h"
|
#include "util/Linker.h"
|
||||||
|
#include "wire/Message.h"
|
||||||
Linker_require("util/platform/Sockaddr.c")
|
Linker_require("util/platform/Sockaddr.c")
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
@@ -33,6 +35,7 @@ typedef struct Sockaddr
|
|||||||
|
|
||||||
#define Sockaddr_PLATFORM 0
|
#define Sockaddr_PLATFORM 0
|
||||||
#define Sockaddr_HANDLE 1
|
#define Sockaddr_HANDLE 1
|
||||||
|
#define Sockaddr_ETHERNET 2
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
|
|
||||||
/** Only applies if flags & Sockaddr_flags_PREFIX is true. */
|
/** Only applies if flags & Sockaddr_flags_PREFIX is true. */
|
||||||
@@ -177,11 +180,6 @@ Sockaddr_t* Sockaddr_fromBytes(const uint8_t* bytes, int addrFamily, struct Allo
|
|||||||
*/
|
*/
|
||||||
Sockaddr_t* Sockaddr_clone(const Sockaddr_t* addr, struct Allocator* alloc);
|
Sockaddr_t* Sockaddr_clone(const Sockaddr_t* addr, struct Allocator* alloc);
|
||||||
|
|
||||||
/**
|
|
||||||
* Normalize inconsistent native sockaddr implementations
|
|
||||||
*/
|
|
||||||
void Sockaddr_normalizeNative(void* nativeSockaddr);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a hash for hashtable lookup.
|
* Get a hash for hashtable lookup.
|
||||||
*/
|
*/
|
||||||
@@ -192,4 +190,11 @@ uint32_t Sockaddr_hash(const Sockaddr_t* addr);
|
|||||||
*/
|
*/
|
||||||
int Sockaddr_compare(const Sockaddr_t* a, const Sockaddr_t* b);
|
int Sockaddr_compare(const Sockaddr_t* a, const Sockaddr_t* b);
|
||||||
|
|
||||||
|
struct Sockaddr* Sockaddr_initFromEth(struct Sockaddr_storage* out, const uint8_t mac[static 6]);
|
||||||
|
|
||||||
|
int Sockaddr_getMac(uint8_t out[static 6], const struct Sockaddr* sockaddr);
|
||||||
|
|
||||||
|
Err_DEFUN Sockaddr_read(struct Sockaddr_storage* out, Message_t* readFrom);
|
||||||
|
Err_DEFUN Sockaddr_write(const struct Sockaddr* out, Message_t* writeTo);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user