-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathLowLatSocket.cpp
More file actions
122 lines (91 loc) · 3.16 KB
/
LowLatSocket.cpp
File metadata and controls
122 lines (91 loc) · 3.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// This file is part of the Open Audio Live System project, a live audio environment
// Copyright (c) 2026 - Mathis DELGADO
//
// This project is distributed under the Creative Commons CC-BY-NC-SA licence. https://creativecommons.org/licenses/by-nc-sa/4.0
#include "LowLatSocket.h"
#include "common/NetworkMapper.h"
#ifndef __linux__
extern "C" int _send_data(uint8_t* data, size_t data_len);
extern "C" int _recv_data(uint8_t* data_out, size_t data_size, EthProtocol filt_proto);
#endif // __linux__
std::optional<uint64_t> LowLatSocket::get_mac(uint16_t id) {
return m_mapper->get_mac_by_uid(id);
}
#ifdef __linux__
LowLatSocket::LowLatSocket(uint16_t self_uid, std::shared_ptr<NetworkMapper> mapper) {
m_socket = 0;
m_iface_addr = {};
m_self_uid = self_uid;
m_mapper = std::move(mapper);
}
LowLatSocket::~LowLatSocket() {
close(m_socket);
}
bool LowLatSocket::init_socket(std::string interface, EthProtocol proto) {
m_socket = socket(AF_PACKET, SOCK_RAW, htons(proto));
if (m_socket < 0) {
std::cerr << "LLS Failed to open low level socket. Err = " << errno << std::endl;
return false;
}
IfaceMeta meta = get_iface_meta(interface);
m_iface_addr.sll_ifindex = meta.idx;
m_iface_addr.sll_halen = ETH_ALEN;
m_iface_addr.sll_protocol = htons(proto);
memcpy(m_iface_addr.sll_addr, meta.mac, 6);
memset(m_hdr.h_dest, 0xFF, 6);
memcpy(m_hdr.h_source, meta.mac, 6);
m_hdr.h_proto = htons(proto);
m_self_proto = proto;
return true;
}
IfaceMeta get_iface_meta(const std::string &name) {
// Overflow check
assert(name.size() <= 16);
int sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0) {
perror("Failed to open temporary socket");
}
ifreq req{};
memset(req.ifr_ifrn.ifrn_name, 0x00, 16);
memcpy(req.ifr_ifrn.ifrn_name, name.data(), name.size());
IfaceMeta meta{};
if (ioctl(sock, SIOCGIFINDEX, &req) < 0) {
perror("LLS Failed to get iface index");
}
meta.idx = req.ifr_ifru.ifru_ivalue;
if (ioctl(sock, SIOCGIFHWADDR, &req) < 0) {
perror("LLS Failed to get iface MAC address");
}
memcpy(meta.mac, req.ifr_ifru.ifru_hwaddr.sa_data, 6);
close(sock);
return meta;
}
#else
// Embeddable interface that must be private
extern "C" IfaceMeta _fetch_iface_meta(std::string& name);
IfaceMeta get_iface_meta(std::string& name) {
return _fetch_iface_meta(name);
}
LowLatSocket::LowLatSocket(uint16_t self_uid, std::shared_ptr<NetworkMapper> mapper) {
m_socket = 0;
m_self_uid = self_uid;
m_mapper = std::move(mapper);
}
LowLatSocket::~LowLatSocket() {
}
bool LowLatSocket::init_socket(std::string interface, EthProtocol proto) {
IfaceMeta meta = get_iface_meta(interface);
memcpy(m_iface_addr, meta.mac, 6);
memset(m_hdr.h_dest, 0xFF, 6);
memcpy(m_hdr.h_source, meta.mac, 6);
m_hdr.h_proto = htons(proto);
m_self_proto = proto;
return true;
}
int LowLatSocket::send_data_internal(uint8_t *data, size_t size) {
return _send_data(data, size);
}
int LowLatSocket::recv_data_internal(uint8_t *data, size_t size) const {
return _recv_data(data, size, m_self_proto);
}
#endif // __linux__