Fixed BACnet/IP initialization on a network interface where the system reports the interface's unicast IP address as being the same. (#1011)

This commit is contained in:
Steve Karg
2025-06-03 19:49:03 -05:00
committed by GitHub
parent bc97e80f97
commit 80875add0a
5 changed files with 79 additions and 26 deletions
+3
View File
@@ -46,6 +46,9 @@ The git repositories are hosted at the following sites:
### Fixed ### Fixed
* Fixed BACnet/IP initialization on a network interface where the system
reports the interface's unicast IP address as being the same as its
broadcast IP address (e.g., utunX interfaces for VPNs on macOS). (#1011)
* Fixed ports/xplained conversion of double warning. (#1004) * Fixed ports/xplained conversion of double warning. (#1004)
* Fixed BACNET_USE_DOUBLE usage in AVR ports. (#1004) * Fixed BACNET_USE_DOUBLE usage in AVR ports. (#1004)
* Fixed integer out-of-range in AVR port. (#1004) * Fixed integer out-of-range in AVR port. (#1004)
+1 -1
View File
@@ -24,7 +24,7 @@ mingw32:
ORIGINAL_LD=$(LD) ; \ ORIGINAL_LD=$(LD) ; \
export CC=i686-w64-mingw32-gcc ; \ export CC=i686-w64-mingw32-gcc ; \
export LD=i686-w64-mingw32-ld ; \ export LD=i686-w64-mingw32-ld ; \
$(MAKE) BACNET_PORT=win32 -s -C apps all ; \ $(MAKE) BACNET_PORT=win32 LEGACY=true -s -C apps all ; \
export CC=$(ORIGINAL_CC) ; \ export CC=$(ORIGINAL_CC) ; \
export LD=$(ORIGINAL_LD) export LD=$(ORIGINAL_LD)
+24 -8
View File
@@ -693,6 +693,8 @@ bool bip_init(char *ifname)
{ {
struct sockaddr_in sin; struct sockaddr_in sin;
int sock_fd = -1; int sock_fd = -1;
struct sockaddr_in broadcast_sin_config;
int broadcast_sock_fd;
if (ifname) { if (ifname) {
snprintf(BIP_Interface_Name, sizeof(BIP_Interface_Name), "%s", ifname); snprintf(BIP_Interface_Name, sizeof(BIP_Interface_Name), "%s", ifname);
@@ -718,21 +720,35 @@ bool bip_init(char *ifname)
if (sock_fd < 0) { if (sock_fd < 0) {
return false; return false;
} }
broadcast_sin_config.sin_family = AF_INET;
broadcast_sin_config.sin_port = BIP_Port;
memset(&(broadcast_sin_config.sin_zero), '\0',
sizeof(broadcast_sin_config.sin_zero));
if (BIP_Broadcast_Binding_Address_Override) { if (BIP_Broadcast_Binding_Address_Override) {
sin.sin_addr.s_addr = BIP_Broadcast_Binding_Address.s_addr; broadcast_sin_config.sin_addr.s_addr =
BIP_Broadcast_Binding_Address.s_addr;
} else { } else {
#if defined(BACNET_IP_BROADCAST_USE_INADDR_ANY) #if defined(BACNET_IP_BROADCAST_USE_INADDR_ANY)
sin.sin_addr.s_addr = htonl(INADDR_ANY); broadcast_sin_config.sin_addr.s_addr = htonl(INADDR_ANY);
#elif defined(BACNET_IP_BROADCAST_USE_INADDR_BROADCAST) #elif defined(BACNET_IP_BROADCAST_USE_INADDR_BROADCAST)
sin.sin_addr.s_addr = htonl(INADDR_BROADCAST); broadcast_sin_config.sin_addr.s_addr = htonl(INADDR_BROADCAST);
#else #else
sin.sin_addr.s_addr = BIP_Broadcast_Addr.s_addr; broadcast_sin_config.sin_addr.s_addr = BIP_Broadcast_Addr.s_addr;
#endif #endif
} }
sock_fd = createSocket(&sin); if (broadcast_sin_config.sin_addr.s_addr == BIP_Address.s_addr) {
BIP_Broadcast_Socket = sock_fd; /* handle the case when a network interface on the system
if (sock_fd < 0) { reports the interface's unicast IP address as being
return false; the same as its broadcast IP address */
BIP_Broadcast_Socket = BIP_Socket;
} else {
broadcast_sock_fd = createSocket(&broadcast_sin_config);
BIP_Broadcast_Socket = broadcast_sock_fd;
if (broadcast_sock_fd < 0) {
bip_cleanup();
return false;
}
} }
bvlc_init(); bvlc_init();
+25 -8
View File
@@ -885,6 +885,8 @@ bool bip_init(char *ifname)
{ {
struct sockaddr_in sin; struct sockaddr_in sin;
int sock_fd = -1; int sock_fd = -1;
struct sockaddr_in broadcast_sin_config;
int broadcast_sock_fd;
if (ifname) { if (ifname) {
snprintf(BIP_Interface_Name, sizeof(BIP_Interface_Name), "%s", ifname); snprintf(BIP_Interface_Name, sizeof(BIP_Interface_Name), "%s", ifname);
@@ -910,21 +912,36 @@ bool bip_init(char *ifname)
if (sock_fd < 0) { if (sock_fd < 0) {
return false; return false;
} }
broadcast_sin_config.sin_family = AF_INET;
broadcast_sin_config.sin_port = BIP_Port;
memset(
&(broadcast_sin_config.sin_zero), '\0',
sizeof(broadcast_sin_config.sin_zero));
if (BIP_Broadcast_Binding_Address_Override) { if (BIP_Broadcast_Binding_Address_Override) {
sin.sin_addr.s_addr = BIP_Broadcast_Binding_Address.s_addr; broadcast_sin_config.sin_addr.s_addr =
BIP_Broadcast_Binding_Address.s_addr;
} else { } else {
#if defined(BACNET_IP_BROADCAST_USE_INADDR_ANY) #if defined(BACNET_IP_BROADCAST_USE_INADDR_ANY)
sin.sin_addr.s_addr = htonl(INADDR_ANY); broadcast_sin_config.sin_addr.s_addr = htonl(INADDR_ANY);
#elif defined(BACNET_IP_BROADCAST_USE_INADDR_BROADCAST) #elif defined(BACNET_IP_BROADCAST_USE_INADDR_BROADCAST)
sin.sin_addr.s_addr = htonl(INADDR_BROADCAST); broadcast_sin_config.sin_addr.s_addr = htonl(INADDR_BROADCAST);
#else #else
sin.sin_addr.s_addr = BIP_Broadcast_Addr.s_addr; broadcast_sin_config.sin_addr.s_addr = BIP_Broadcast_Addr.s_addr;
#endif #endif
} }
sock_fd = createSocket(&sin); if (broadcast_sin_config.sin_addr.s_addr == BIP_Address.s_addr) {
BIP_Broadcast_Socket = sock_fd; /* handle the case when a network interface on the system
if (sock_fd < 0) { reports the interface's unicast IP address as being
return false; the same as its broadcast IP address */
BIP_Broadcast_Socket = BIP_Socket;
} else {
broadcast_sock_fd = createSocket(&broadcast_sin_config);
BIP_Broadcast_Socket = broadcast_sock_fd;
if (broadcast_sock_fd < 0) {
bip_cleanup();
return false;
}
} }
bvlc_init(); bvlc_init();
+26 -9
View File
@@ -822,6 +822,8 @@ bool bip_init(char *ifname)
{ {
struct sockaddr_in sin; struct sockaddr_in sin;
SOCKET sock_fd = INVALID_SOCKET; SOCKET sock_fd = INVALID_SOCKET;
struct sockaddr_in broadcast_sin_config;
SOCKET broadcast_sock_fd = INVALID_SOCKET;
bip_init_windows(); bip_init_windows();
if (ifname) { if (ifname) {
@@ -859,29 +861,44 @@ bool bip_init(char *ifname)
sock_fd = createSocket(&sin); sock_fd = createSocket(&sin);
BIP_Socket = sock_fd; BIP_Socket = sock_fd;
if (sock_fd == INVALID_SOCKET) { if (sock_fd == INVALID_SOCKET) {
bip_cleanup();
return false; return false;
} }
broadcast_sin_config.sin_family = AF_INET;
broadcast_sin_config.sin_port = BIP_Port;
memset(
&(broadcast_sin_config.sin_zero), '\0',
sizeof(broadcast_sin_config.sin_zero));
if (BIP_Broadcast_Binding_Address_Override) { if (BIP_Broadcast_Binding_Address_Override) {
sin.sin_addr.s_addr = BIP_Broadcast_Binding_Address.s_addr; sin.sin_addr.s_addr = BIP_Broadcast_Binding_Address.s_addr;
} else { } else {
#if defined(BACNET_IP_BROADCAST_USE_INADDR_ANY) #if defined(BACNET_IP_BROADCAST_USE_INADDR_ANY)
sin.sin_addr.s_addr = htonl(INADDR_ANY); broadcast_sin_config.sin_addr.s_addr = htonl(INADDR_ANY);
#elif defined(BACNET_IP_BROADCAST_USE_INADDR_BROADCAST) #elif defined(BACNET_IP_BROADCAST_USE_INADDR_BROADCAST)
sin.sin_addr.s_addr = htonl(INADDR_BROADCAST); broadcast_sin_config.sin_addr.s_addr = htonl(INADDR_BROADCAST);
#else #else
sin.sin_addr.s_addr = BIP_Address.s_addr; broadcast_sin_config.sin_addr.s_addr = BIP_Address.s_addr;
#endif #endif
} }
if (BIP_Debug) { if (BIP_Debug) {
fprintf( fprintf(
stderr, "BIP: broadcast bind %s:%hu\n", inet_ntoa(sin.sin_addr), stderr, "BIP: broadcast bind %s:%hu\n",
ntohs(sin.sin_port)); inet_ntoa(broadcast_sin_config.sin_addr),
ntohs(broadcast_sin_config.sin_port));
fflush(stderr); fflush(stderr);
} }
sock_fd = createSocket(&sin); if (broadcast_sin_config.sin_addr.s_addr == BIP_Address.s_addr) {
BIP_Broadcast_Socket = sock_fd; /* handle the case when a network interface on the system
if (sock_fd == INVALID_SOCKET) { reports the interface's unicast IP address as being
return false; the same as its broadcast IP address */
BIP_Broadcast_Socket = BIP_Socket;
} else {
broadcast_sock_fd = createSocket(&broadcast_sin_config);
BIP_Broadcast_Socket = broadcast_sock_fd;
if (broadcast_sock_fd == INVALID_SOCKET) {
bip_cleanup();
return false;
}
} }
bvlc_init(); bvlc_init();