mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-16 17:23:35 +08:00
mavlink_main: fix broadcast computation
The way the broadcast IP is currently fetched is by sending an ioctl() request. The limitation of this is that the broadcast address may not be set on the network interface (more specifically, it is usually not set in docker containers). In those cases, it results in the broadcast address becoming 0.0.0.0, which is not valid [1]. This fix uses the network IP and the netmask to compute the directed broadcast address. This should be more reliable, as both of those are always set on the network interface. [1]: https://tools.ietf.org/html/rfc1122, section 3.2.1.3 (a)
This commit is contained in:
committed by
Lorenz Meier
parent
463217a5f9
commit
38c949731f
@@ -56,10 +56,6 @@
|
||||
#include <termios.h>
|
||||
#include <time.h>
|
||||
|
||||
#ifdef __PX4_POSIX
|
||||
#include <net/if.h>
|
||||
#endif
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
@@ -1121,7 +1117,6 @@ Mavlink::find_broadcast_address()
|
||||
offset += sizeof(struct ifreq)
|
||||
#endif
|
||||
) {
|
||||
|
||||
// Point to next network interface in buffer.
|
||||
cur_ifreq = (struct ifreq *) & (((uint8_t *)ifconf.ifc_req)[offset]);
|
||||
|
||||
@@ -1136,19 +1131,6 @@ Mavlink::find_broadcast_address()
|
||||
continue;
|
||||
}
|
||||
|
||||
struct ifreq bc_ifreq;
|
||||
|
||||
memset(&bc_ifreq, 0, sizeof(bc_ifreq));
|
||||
|
||||
strncpy(bc_ifreq.ifr_name, cur_ifreq->ifr_name, IF_NAMESIZE);
|
||||
|
||||
ret = ioctl(_socket_fd, SIOCGIFBRDADDR, &bc_ifreq);
|
||||
|
||||
if (ret != 0) {
|
||||
PX4_DEBUG("getting broadcast address failed for %s", cur_ifreq->ifr_name);
|
||||
continue;
|
||||
}
|
||||
|
||||
struct in_addr &sin_addr = ((struct sockaddr_in *)&cur_ifreq->ifr_addr)->sin_addr;
|
||||
|
||||
// Accept network interfaces to local network only. This means it's an IP starting with:
|
||||
@@ -1162,19 +1144,21 @@ Mavlink::find_broadcast_address()
|
||||
}
|
||||
|
||||
if (!_broadcast_address_found) {
|
||||
PX4_INFO("using network interface %s, IP: %s", cur_ifreq->ifr_name, inet_ntoa(sin_addr));
|
||||
const struct in_addr netmask_addr = query_netmask_addr(_socket_fd, *cur_ifreq);
|
||||
const struct in_addr broadcast_addr = compute_broadcast_addr(sin_addr, netmask_addr);
|
||||
|
||||
struct in_addr &bc_addr = ((struct sockaddr_in *)&bc_ifreq.ifr_broadaddr)->sin_addr;
|
||||
PX4_INFO("with broadcast IP: %s", inet_ntoa(bc_addr));
|
||||
PX4_INFO("using network interface %s, IP: %s", cur_ifreq->ifr_name, inet_ntoa(sin_addr));
|
||||
PX4_INFO("with netmask: %s", inet_ntoa(netmask_addr));
|
||||
PX4_INFO("and broadcast IP: %s", inet_ntoa(broadcast_addr));
|
||||
|
||||
_bcast_addr.sin_family = AF_INET;
|
||||
_bcast_addr.sin_addr = bc_addr;
|
||||
_bcast_addr.sin_addr = broadcast_addr;
|
||||
|
||||
_broadcast_address_found = true;
|
||||
|
||||
} else {
|
||||
PX4_INFO("ignoring additional network interface %s, IP: %s",
|
||||
cur_ifreq->ifr_name, inet_ntoa(sin_addr));
|
||||
PX4_DEBUG("ignoring additional network interface %s, IP: %s",
|
||||
cur_ifreq->ifr_name, inet_ntoa(sin_addr));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1201,6 +1185,28 @@ Mavlink::find_broadcast_address()
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef __PX4_POSIX
|
||||
const in_addr
|
||||
Mavlink::query_netmask_addr(const int socket_fd, const ifreq &ifreq)
|
||||
{
|
||||
struct ifreq netmask_ifreq;
|
||||
memset(&netmask_ifreq, 0, sizeof(netmask_ifreq));
|
||||
strncpy(netmask_ifreq.ifr_name, ifreq.ifr_name, IF_NAMESIZE);
|
||||
ioctl(socket_fd, SIOCGIFNETMASK, &netmask_ifreq);
|
||||
|
||||
return ((struct sockaddr_in *)&netmask_ifreq.ifr_addr)->sin_addr;
|
||||
}
|
||||
|
||||
const in_addr
|
||||
Mavlink::compute_broadcast_addr(const in_addr &host_addr, const in_addr &netmask_addr)
|
||||
{
|
||||
struct in_addr broadcast_addr;
|
||||
broadcast_addr.s_addr = ~netmask_addr.s_addr | host_addr.s_addr;
|
||||
|
||||
return broadcast_addr;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
Mavlink::init_udp()
|
||||
{
|
||||
|
||||
@@ -59,6 +59,10 @@
|
||||
#include <systemlib/mavlink_log.h>
|
||||
#include <drivers/device/ringbuffer.h>
|
||||
|
||||
#ifdef __PX4_POSIX
|
||||
#include <net/if.h>
|
||||
#endif
|
||||
|
||||
#include <uORB/uORB.h>
|
||||
#include <uORB/topics/mission.h>
|
||||
#include <uORB/topics/mission_result.h>
|
||||
@@ -417,6 +421,10 @@ public:
|
||||
|
||||
int get_socket_fd() { return _socket_fd; };
|
||||
#ifdef __PX4_POSIX
|
||||
const in_addr query_netmask_addr(const int socket_fd, const ifreq &ifreq);
|
||||
|
||||
const in_addr compute_broadcast_addr(const in_addr &host_addr, const in_addr &netmask_addr);
|
||||
|
||||
struct sockaddr_in *get_client_source_address() { return &_src_addr; }
|
||||
|
||||
void set_client_source_initialized() { _src_addr_initialized = true; }
|
||||
|
||||
Reference in New Issue
Block a user