mirror of
https://github.com/markqvist/Reticulum.git
synced 2024-11-22 13:40:19 +00:00
Compare commits
4 Commits
9685726644
...
b5cc343b95
Author | SHA1 | Date | |
---|---|---|---|
|
b5cc343b95 | ||
|
583e65419e | ||
|
1564930a51 | ||
|
746a38f818 |
@ -77,6 +77,15 @@ class AutoInterface(Interface):
|
|||||||
ifas = self.netinfo.ifaddresses(ifname)
|
ifas = self.netinfo.ifaddresses(ifname)
|
||||||
return ifas
|
return ifas
|
||||||
|
|
||||||
|
def interface_name_to_index(self, ifname):
|
||||||
|
|
||||||
|
# socket.if_nametoindex doesn't work with uuid interface names on windows, it wants the ethernet_0 style
|
||||||
|
# we will just get the index from netinfo instead as it seems to work
|
||||||
|
if RNS.vendor.platformutils.is_windows():
|
||||||
|
return self.netinfo.interface_names_to_indexes()[ifname]
|
||||||
|
|
||||||
|
return socket.if_nametoindex(ifname)
|
||||||
|
|
||||||
def __init__(self, owner, name, group_id=None, discovery_scope=None, discovery_port=None, multicast_address_type=None, data_port=None, allowed_interfaces=None, ignored_interfaces=None, configured_bitrate=None):
|
def __init__(self, owner, name, group_id=None, discovery_scope=None, discovery_port=None, multicast_address_type=None, data_port=None, allowed_interfaces=None, ignored_interfaces=None, configured_bitrate=None):
|
||||||
from RNS.vendor.ifaddr import niwrapper
|
from RNS.vendor.ifaddr import niwrapper
|
||||||
super().__init__()
|
super().__init__()
|
||||||
@ -205,7 +214,7 @@ class AutoInterface(Interface):
|
|||||||
RNS.log(str(self)+" Creating multicast discovery listener on "+str(ifname)+" with address "+str(mcast_addr), RNS.LOG_EXTREME)
|
RNS.log(str(self)+" Creating multicast discovery listener on "+str(ifname)+" with address "+str(mcast_addr), RNS.LOG_EXTREME)
|
||||||
|
|
||||||
# Struct with interface index
|
# Struct with interface index
|
||||||
if_struct = struct.pack("I", socket.if_nametoindex(ifname))
|
if_struct = struct.pack("I", self.interface_name_to_index(ifname))
|
||||||
|
|
||||||
# Set up multicast socket
|
# Set up multicast socket
|
||||||
discovery_socket = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
|
discovery_socket = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
|
||||||
@ -219,12 +228,21 @@ class AutoInterface(Interface):
|
|||||||
discovery_socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, mcast_group)
|
discovery_socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, mcast_group)
|
||||||
|
|
||||||
# Bind socket
|
# Bind socket
|
||||||
if self.discovery_scope == AutoInterface.SCOPE_LINK:
|
if RNS.vendor.platformutils.is_windows():
|
||||||
addr_info = socket.getaddrinfo(mcast_addr+"%"+ifname, self.discovery_port, socket.AF_INET6, socket.SOCK_DGRAM)
|
|
||||||
else:
|
|
||||||
addr_info = socket.getaddrinfo(mcast_addr, self.discovery_port, socket.AF_INET6, socket.SOCK_DGRAM)
|
|
||||||
|
|
||||||
discovery_socket.bind(addr_info[0][4])
|
# window throws "[WinError 10049] The requested address is not valid in its context"
|
||||||
|
# when trying to use the multicast address as host, or when providing interface index
|
||||||
|
# passing an empty host appears to work, but probably not exactly how we want it to...
|
||||||
|
discovery_socket.bind(('', self.discovery_port))
|
||||||
|
|
||||||
|
else:
|
||||||
|
|
||||||
|
if self.discovery_scope == AutoInterface.SCOPE_LINK:
|
||||||
|
addr_info = socket.getaddrinfo(mcast_addr+"%"+ifname, self.discovery_port, socket.AF_INET6, socket.SOCK_DGRAM)
|
||||||
|
else:
|
||||||
|
addr_info = socket.getaddrinfo(mcast_addr, self.discovery_port, socket.AF_INET6, socket.SOCK_DGRAM)
|
||||||
|
|
||||||
|
discovery_socket.bind(addr_info[0][4])
|
||||||
|
|
||||||
# Set up thread for discovery packets
|
# Set up thread for discovery packets
|
||||||
def discovery_loop():
|
def discovery_loop():
|
||||||
@ -253,7 +271,7 @@ class AutoInterface(Interface):
|
|||||||
socketserver.UDPServer.address_family = socket.AF_INET6
|
socketserver.UDPServer.address_family = socket.AF_INET6
|
||||||
|
|
||||||
for ifname in self.adopted_interfaces:
|
for ifname in self.adopted_interfaces:
|
||||||
local_addr = self.adopted_interfaces[ifname]+"%"+ifname
|
local_addr = self.adopted_interfaces[ifname]+"%"+str(self.interface_name_to_index(ifname))
|
||||||
addr_info = socket.getaddrinfo(local_addr, self.data_port, socket.AF_INET6, socket.SOCK_DGRAM)
|
addr_info = socket.getaddrinfo(local_addr, self.data_port, socket.AF_INET6, socket.SOCK_DGRAM)
|
||||||
address = addr_info[0][4]
|
address = addr_info[0][4]
|
||||||
|
|
||||||
@ -380,7 +398,7 @@ class AutoInterface(Interface):
|
|||||||
announce_socket = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
|
announce_socket = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
|
||||||
addr_info = socket.getaddrinfo(self.mcast_discovery_address, self.discovery_port, socket.AF_INET6, socket.SOCK_DGRAM)
|
addr_info = socket.getaddrinfo(self.mcast_discovery_address, self.discovery_port, socket.AF_INET6, socket.SOCK_DGRAM)
|
||||||
|
|
||||||
ifis = struct.pack("I", socket.if_nametoindex(ifname))
|
ifis = struct.pack("I", self.interface_name_to_index(ifname))
|
||||||
announce_socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_IF, ifis)
|
announce_socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_IF, ifis)
|
||||||
announce_socket.sendto(discovery_token, addr_info[0][4])
|
announce_socket.sendto(discovery_token, addr_info[0][4])
|
||||||
announce_socket.close()
|
announce_socket.close()
|
||||||
@ -433,8 +451,8 @@ class AutoInterface(Interface):
|
|||||||
try:
|
try:
|
||||||
if self.outbound_udp_socket == None:
|
if self.outbound_udp_socket == None:
|
||||||
self.outbound_udp_socket = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
|
self.outbound_udp_socket = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
|
||||||
|
|
||||||
peer_addr = str(peer)+"%"+str(self.peers[peer][0])
|
peer_addr = str(peer)+"%"+str(self.interface_name_to_index(self.peers[peer][0]))
|
||||||
addr_info = socket.getaddrinfo(peer_addr, self.data_port, socket.AF_INET6, socket.SOCK_DGRAM)
|
addr_info = socket.getaddrinfo(peer_addr, self.data_port, socket.AF_INET6, socket.SOCK_DGRAM)
|
||||||
self.outbound_udp_socket.sendto(data, addr_info[0][4])
|
self.outbound_udp_socket.sendto(data, addr_info[0][4])
|
||||||
|
|
||||||
|
@ -536,46 +536,40 @@ class Reticulum:
|
|||||||
|
|
||||||
if (("interface_enabled" in c) and c.as_bool("interface_enabled") == True) or (("enabled" in c) and c.as_bool("enabled") == True):
|
if (("interface_enabled" in c) and c.as_bool("interface_enabled") == True) or (("enabled" in c) and c.as_bool("enabled") == True):
|
||||||
if c["type"] == "AutoInterface":
|
if c["type"] == "AutoInterface":
|
||||||
if not RNS.vendor.platformutils.is_windows():
|
group_id = c["group_id"] if "group_id" in c else None
|
||||||
group_id = c["group_id"] if "group_id" in c else None
|
discovery_scope = c["discovery_scope"] if "discovery_scope" in c else None
|
||||||
discovery_scope = c["discovery_scope"] if "discovery_scope" in c else None
|
discovery_port = int(c["discovery_port"]) if "discovery_port" in c else None
|
||||||
discovery_port = int(c["discovery_port"]) if "discovery_port" in c else None
|
multicast_address_type = c["multicast_address_type"] if "multicast_address_type" in c else None
|
||||||
multicast_address_type = c["multicast_address_type"] if "multicast_address_type" in c else None
|
data_port = int(c["data_port"]) if "data_port" in c else None
|
||||||
data_port = int(c["data_port"]) if "data_port" in c else None
|
allowed_interfaces = c.as_list("devices") if "devices" in c else None
|
||||||
allowed_interfaces = c.as_list("devices") if "devices" in c else None
|
ignored_interfaces = c.as_list("ignored_devices") if "ignored_devices" in c else None
|
||||||
ignored_interfaces = c.as_list("ignored_devices") if "ignored_devices" in c else None
|
|
||||||
|
|
||||||
interface = AutoInterface.AutoInterface(
|
interface = AutoInterface.AutoInterface(
|
||||||
RNS.Transport,
|
RNS.Transport,
|
||||||
name,
|
name,
|
||||||
group_id,
|
group_id,
|
||||||
discovery_scope,
|
discovery_scope,
|
||||||
discovery_port,
|
discovery_port,
|
||||||
multicast_address_type,
|
multicast_address_type,
|
||||||
data_port,
|
data_port,
|
||||||
allowed_interfaces,
|
allowed_interfaces,
|
||||||
ignored_interfaces
|
ignored_interfaces
|
||||||
)
|
)
|
||||||
|
|
||||||
if "outgoing" in c and c.as_bool("outgoing") == False:
|
|
||||||
interface.OUT = False
|
|
||||||
else:
|
|
||||||
interface.OUT = True
|
|
||||||
|
|
||||||
interface.mode = interface_mode
|
|
||||||
|
|
||||||
interface.announce_cap = announce_cap
|
|
||||||
if configured_bitrate:
|
|
||||||
interface.bitrate = configured_bitrate
|
|
||||||
if ifac_size != None:
|
|
||||||
interface.ifac_size = ifac_size
|
|
||||||
else:
|
|
||||||
interface.ifac_size = 16
|
|
||||||
|
|
||||||
|
if "outgoing" in c and c.as_bool("outgoing") == False:
|
||||||
|
interface.OUT = False
|
||||||
else:
|
else:
|
||||||
RNS.log("AutoInterface is not currently supported on Windows, disabling interface.", RNS.LOG_ERROR);
|
interface.OUT = True
|
||||||
RNS.log("Please remove this AutoInterface instance from your configuration file.", RNS.LOG_ERROR);
|
|
||||||
RNS.log("You will have to manually configure other interfaces for connectivity.", RNS.LOG_ERROR);
|
interface.mode = interface_mode
|
||||||
|
|
||||||
|
interface.announce_cap = announce_cap
|
||||||
|
if configured_bitrate:
|
||||||
|
interface.bitrate = configured_bitrate
|
||||||
|
if ifac_size != None:
|
||||||
|
interface.ifac_size = ifac_size
|
||||||
|
else:
|
||||||
|
interface.ifac_size = 16
|
||||||
|
|
||||||
if c["type"] == "UDPInterface":
|
if c["type"] == "UDPInterface":
|
||||||
device = c["device"] if "device" in c else None
|
device = c["device"] if "device" in c else None
|
||||||
|
@ -324,6 +324,7 @@ class RNode():
|
|||||||
self.checksum = None
|
self.checksum = None
|
||||||
self.device_hash = None
|
self.device_hash = None
|
||||||
self.firmware_hash = None
|
self.firmware_hash = None
|
||||||
|
self.firmware_hash_target = None
|
||||||
self.signature = None
|
self.signature = None
|
||||||
self.signature_valid = False
|
self.signature_valid = False
|
||||||
self.locally_signed = False
|
self.locally_signed = False
|
||||||
@ -471,6 +472,8 @@ class RNode():
|
|||||||
escape = False
|
escape = False
|
||||||
command_buffer = command_buffer+bytes([byte])
|
command_buffer = command_buffer+bytes([byte])
|
||||||
if (len(command_buffer) == 33):
|
if (len(command_buffer) == 33):
|
||||||
|
if command_buffer[0] == 0x01:
|
||||||
|
self.firmware_hash_target = command_buffer[1:]
|
||||||
if command_buffer[0] == 0x02:
|
if command_buffer[0] == 0x02:
|
||||||
self.firmware_hash = command_buffer[1:]
|
self.firmware_hash = command_buffer[1:]
|
||||||
|
|
||||||
@ -588,7 +591,7 @@ class RNode():
|
|||||||
self.version = str(self.major_version)+"."+minstr
|
self.version = str(self.major_version)+"."+minstr
|
||||||
|
|
||||||
def detect(self):
|
def detect(self):
|
||||||
kiss_command = bytes([KISS.FEND, KISS.CMD_DETECT, KISS.DETECT_REQ, KISS.FEND, KISS.CMD_FW_VERSION, 0x00, KISS.FEND, KISS.CMD_PLATFORM, 0x00, KISS.FEND, KISS.CMD_MCU, 0x00, KISS.FEND, KISS.CMD_BOARD, 0x00, KISS.FEND, KISS.CMD_DEV_HASH, 0x01, KISS.FEND, KISS.CMD_HASHES, 0x02, KISS.FEND])
|
kiss_command = bytes([KISS.FEND, KISS.CMD_DETECT, KISS.DETECT_REQ, KISS.FEND, KISS.CMD_FW_VERSION, 0x00, KISS.FEND, KISS.CMD_PLATFORM, 0x00, KISS.FEND, KISS.CMD_MCU, 0x00, KISS.FEND, KISS.CMD_BOARD, 0x00, KISS.FEND, KISS.CMD_DEV_HASH, 0x01, KISS.FEND, KISS.CMD_HASHES, 0x01, KISS.FEND, KISS.CMD_HASHES, 0x02, KISS.FEND])
|
||||||
written = self.serial.write(kiss_command)
|
written = self.serial.write(kiss_command)
|
||||||
if written != len(kiss_command):
|
if written != len(kiss_command):
|
||||||
raise IOError("An IO error occurred while detecting hardware for "+self(str))
|
raise IOError("An IO error occurred while detecting hardware for "+self(str))
|
||||||
@ -1249,6 +1252,8 @@ def main():
|
|||||||
parser.add_argument("-k", "--key", action="store_true", help="Generate a new signing key and exit") #
|
parser.add_argument("-k", "--key", action="store_true", help="Generate a new signing key and exit") #
|
||||||
parser.add_argument("-S", "--sign", action="store_true", help="Display public part of signing key")
|
parser.add_argument("-S", "--sign", action="store_true", help="Display public part of signing key")
|
||||||
parser.add_argument("-H", "--firmware-hash", action="store", help="Display installed firmware hash")
|
parser.add_argument("-H", "--firmware-hash", action="store", help="Display installed firmware hash")
|
||||||
|
parser.add_argument("-K", "--get-target-firmware-hash", action="store_true", help=argparse.SUPPRESS) # Get target firmware hash from device
|
||||||
|
parser.add_argument("-L", "--get-firmware-hash", action="store_true", help=argparse.SUPPRESS) # Get calculated firmware hash from device
|
||||||
parser.add_argument("--platform", action="store", metavar="platform", type=str, default=None, help="Platform specification for device bootstrap")
|
parser.add_argument("--platform", action="store", metavar="platform", type=str, default=None, help="Platform specification for device bootstrap")
|
||||||
parser.add_argument("--product", action="store", metavar="product", type=str, default=None, help="Product specification for device bootstrap") #
|
parser.add_argument("--product", action="store", metavar="product", type=str, default=None, help="Product specification for device bootstrap") #
|
||||||
parser.add_argument("--model", action="store", metavar="model", type=str, default=None, help="Model code for device bootstrap")
|
parser.add_argument("--model", action="store", metavar="model", type=str, default=None, help="Model code for device bootstrap")
|
||||||
@ -3367,6 +3372,22 @@ def main():
|
|||||||
RNS.log("This device has not been provisioned yet, cannot set firmware hash")
|
RNS.log("This device has not been provisioned yet, cannot set firmware hash")
|
||||||
graceful_exit(77)
|
graceful_exit(77)
|
||||||
|
|
||||||
|
if args.get_target_firmware_hash:
|
||||||
|
if rnode.provisioned:
|
||||||
|
RNS.log(f"The target firmware hash is: {rnode.firmware_hash_target.hex()}")
|
||||||
|
|
||||||
|
else:
|
||||||
|
RNS.log("This device has not been provisioned yet, cannot get firmware hash")
|
||||||
|
exit(77)
|
||||||
|
|
||||||
|
if args.get_firmware_hash:
|
||||||
|
if rnode.provisioned:
|
||||||
|
RNS.log(f"The actual firmware hash is: {rnode.firmware_hash.hex()}")
|
||||||
|
|
||||||
|
else:
|
||||||
|
RNS.log("This device has not been provisioned yet, cannot get firmware hash")
|
||||||
|
exit(77)
|
||||||
|
|
||||||
if rnode.provisioned:
|
if rnode.provisioned:
|
||||||
if args.normal:
|
if args.normal:
|
||||||
rnode.setNormalMode()
|
rnode.setNormalMode()
|
||||||
|
7
RNS/vendor/ifaddr/niwrapper.py
vendored
7
RNS/vendor/ifaddr/niwrapper.py
vendored
@ -11,6 +11,13 @@ def interfaces() -> List[str]:
|
|||||||
adapters = RNS.vendor.ifaddr.get_adapters(include_unconfigured=True)
|
adapters = RNS.vendor.ifaddr.get_adapters(include_unconfigured=True)
|
||||||
return [a.name for a in adapters]
|
return [a.name for a in adapters]
|
||||||
|
|
||||||
|
def interface_names_to_indexes() -> dict:
|
||||||
|
adapters = RNS.vendor.ifaddr.get_adapters(include_unconfigured=True)
|
||||||
|
results = {}
|
||||||
|
for adapter in adapters:
|
||||||
|
results[adapter.name] = adapter.index
|
||||||
|
return results
|
||||||
|
|
||||||
def ifaddresses(ifname) -> dict:
|
def ifaddresses(ifname) -> dict:
|
||||||
adapters = RNS.vendor.ifaddr.get_adapters(include_unconfigured=True)
|
adapters = RNS.vendor.ifaddr.get_adapters(include_unconfigured=True)
|
||||||
ifa = {}
|
ifa = {}
|
||||||
|
Loading…
Reference in New Issue
Block a user