fix BACnet/IP on OS to bind broadcast to specific port (#489)
* Fixes #346 by binding the broadcast socket to the port specific broadcast address rather than INADDR_ANY or INADDR_BROADCAST. Added additional compile and environment options for those who might need them. * Changed the define USE_CLASSADDR to BACNET_IP_BROADCAST_USE_CLASSADDR to help manage namespaces. * Added BACNET_IP_BROADCAST_BIND_ADDR environment variable to override the default broadcast binding address. --------- Co-authored-by: Steve Karg <skarg@users.sourceforge.net>
This commit is contained in:
+3
-2
@@ -29,7 +29,7 @@ BACnetAddress, and Weekly_Schedule and improved unit test code coverage. (#481)
|
|||||||
improved unit test code coverage. (#481)
|
improved unit test code coverage. (#481)
|
||||||
- secured BACnet Error service decoder and improved unit test code coverage. (#481)
|
- secured BACnet Error service decoder and improved unit test code coverage. (#481)
|
||||||
- improved test code coverage for BACnet objects and properties. (#481)
|
- improved test code coverage for BACnet objects and properties. (#481)
|
||||||
- fix ReinitializeDevice handler to clear password before decoding (#485)
|
- fix ReinitializeDevice handler to clear password before decoding (#485) (#487)
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
@@ -39,8 +39,9 @@ improved unit test code coverage. (#481)
|
|||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- Fixed missing Link_Speeds property in network port objects when
|
- Fixed missing Link_Speeds property in network port objects when
|
||||||
Link_Speed property is writable.
|
Link_Speed property is writable (#488)
|
||||||
- Fixed Microchip xmega xplained example project to build under GCC in pipeline.
|
- Fixed Microchip xmega xplained example project to build under GCC in pipeline.
|
||||||
|
- Fixed BACnet/IP on OS to bind broadcast to specific port (#489)
|
||||||
|
|
||||||
## [1.1.2] - 2023-08-18
|
## [1.1.2] - 2023-08-18
|
||||||
|
|
||||||
|
|||||||
@@ -73,6 +73,12 @@ ifeq (${BACNET_PORT},)
|
|||||||
ifeq ($(UNAME_S),Darwin)
|
ifeq ($(UNAME_S),Darwin)
|
||||||
BACNET_PORT = bsd
|
BACNET_PORT = bsd
|
||||||
endif
|
endif
|
||||||
|
ifeq ($(UNAME_S),FreeBSD)
|
||||||
|
BACNET_PORT = bsd
|
||||||
|
endif
|
||||||
|
ifeq ($(UNAME_S),OpenBSD)
|
||||||
|
BACNET_PORT = bsd
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -95,6 +101,7 @@ ifeq (${BACNET_PORT},bsd)
|
|||||||
PFLAGS = -pthread
|
PFLAGS = -pthread
|
||||||
TARGET_EXT =
|
TARGET_EXT =
|
||||||
SYSTEM_LIB=-lc,-lm
|
SYSTEM_LIB=-lc,-lm
|
||||||
|
CSTANDARD = -std=c99
|
||||||
endif
|
endif
|
||||||
ifeq (${BACNET_PORT},win32)
|
ifeq (${BACNET_PORT},win32)
|
||||||
# winget install --id=MSYS2.MSYS2 -e
|
# winget install --id=MSYS2.MSYS2 -e
|
||||||
|
|||||||
@@ -90,6 +90,8 @@ BACNET_BDT_MASK_1 - dotted IPv4 mask of the BBMD table
|
|||||||
|
|
||||||
BACNET_IP_NAT_ADDR - dotted IPv4 address of the public facing router
|
BACNET_IP_NAT_ADDR - dotted IPv4 address of the public facing router
|
||||||
|
|
||||||
|
BACNET_IP_BROADCAST_BIND_ADDR - dotted IPv4 address to bind broadcasts
|
||||||
|
|
||||||
Example Usage
|
Example Usage
|
||||||
-------------
|
-------------
|
||||||
You can communicate with the virtual BACnet Device by using the other BACnet
|
You can communicate with the virtual BACnet Device by using the other BACnet
|
||||||
|
|||||||
@@ -88,10 +88,12 @@
|
|||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
|
#include "bacnet/bacnet_stack_exports.h"
|
||||||
|
|
||||||
/** @file bsd/net.h Includes BSD network headers. */
|
/** @file bsd/net.h Includes BSD network headers. */
|
||||||
|
|
||||||
/* Local helper functions for this port */
|
/* Local helper functions for this port */
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
extern int bip_get_local_netmask(
|
extern int bip_get_local_netmask(
|
||||||
struct in_addr *netmask);
|
struct in_addr *netmask);
|
||||||
|
|
||||||
|
|||||||
+56
-3
@@ -58,6 +58,9 @@ static uint16_t BIP_Port;
|
|||||||
static struct in_addr BIP_Address;
|
static struct in_addr BIP_Address;
|
||||||
/* IP broadcast address - stored here in network byte order */
|
/* IP broadcast address - stored here in network byte order */
|
||||||
static struct in_addr BIP_Broadcast_Addr;
|
static struct in_addr BIP_Broadcast_Addr;
|
||||||
|
/* broadcast binding mechanism */
|
||||||
|
static bool BIP_Broadcast_Binding_Address_Override;
|
||||||
|
static struct in_addr BIP_Broadcast_Binding_Address;
|
||||||
/* enable debugging */
|
/* enable debugging */
|
||||||
static bool BIP_Debug = false;
|
static bool BIP_Debug = false;
|
||||||
/* interface name */
|
/* interface name */
|
||||||
@@ -188,6 +191,7 @@ void bip_get_broadcast_address(BACNET_ADDRESS *dest)
|
|||||||
*/
|
*/
|
||||||
bool bip_set_addr(BACNET_IP_ADDRESS *addr)
|
bool bip_set_addr(BACNET_IP_ADDRESS *addr)
|
||||||
{
|
{
|
||||||
|
(void)addr;
|
||||||
/* not something we do within this driver */
|
/* not something we do within this driver */
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -214,6 +218,7 @@ bool bip_get_addr(BACNET_IP_ADDRESS *addr)
|
|||||||
*/
|
*/
|
||||||
bool bip_set_broadcast_addr(BACNET_IP_ADDRESS *addr)
|
bool bip_set_broadcast_addr(BACNET_IP_ADDRESS *addr)
|
||||||
{
|
{
|
||||||
|
(void)addr;
|
||||||
/* not something we do within this driver */
|
/* not something we do within this driver */
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -239,6 +244,7 @@ bool bip_get_broadcast_addr(BACNET_IP_ADDRESS *addr)
|
|||||||
*/
|
*/
|
||||||
bool bip_set_subnet_prefix(uint8_t prefix)
|
bool bip_set_subnet_prefix(uint8_t prefix)
|
||||||
{
|
{
|
||||||
|
(void)prefix;
|
||||||
/* not something we do within this driver */
|
/* not something we do within this driver */
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -321,7 +327,7 @@ uint16_t bip_receive(
|
|||||||
int max = 0;
|
int max = 0;
|
||||||
struct timeval select_timeout;
|
struct timeval select_timeout;
|
||||||
struct sockaddr_in sin = { 0 };
|
struct sockaddr_in sin = { 0 };
|
||||||
BACNET_IP_ADDRESS addr = { { 0 } };
|
BACNET_IP_ADDRESS addr = { 0 };
|
||||||
socklen_t sin_len = sizeof(sin);
|
socklen_t sin_len = sizeof(sin);
|
||||||
int received_bytes = 0;
|
int received_bytes = 0;
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
@@ -547,6 +553,20 @@ int bip_get_local_netmask(struct in_addr *netmask)
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the broadcast socket binding address
|
||||||
|
* @param baddr The broadcast socket binding address, in host order.
|
||||||
|
* @return 0 on success
|
||||||
|
*/
|
||||||
|
int bip_set_broadcast_binding(
|
||||||
|
const char *ip4_broadcast)
|
||||||
|
{
|
||||||
|
BIP_Broadcast_Binding_Address.s_addr = inet_addr(ip4_broadcast);
|
||||||
|
BIP_Broadcast_Binding_Address_Override = true;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/** Gets the local IP address and local broadcast address from the system,
|
/** Gets the local IP address and local broadcast address from the system,
|
||||||
* and saves it into the BACnet/IP data structures.
|
* and saves it into the BACnet/IP data structures.
|
||||||
*
|
*
|
||||||
@@ -572,6 +592,29 @@ void bip_set_interface(char *ifname)
|
|||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
}
|
}
|
||||||
/* setup local broadcast address */
|
/* setup local broadcast address */
|
||||||
|
#ifdef BACNET_IP_BROADCAST_USE_CLASSADDR
|
||||||
|
long broadcast_address;
|
||||||
|
long net_address;
|
||||||
|
|
||||||
|
broadcast_address = 0;
|
||||||
|
net_address = local_address.s_addr;
|
||||||
|
if (IN_CLASSA(ntohl(net_address))) {
|
||||||
|
broadcast_address =
|
||||||
|
(ntohl(net_address) & ~IN_CLASSA_HOST) | IN_CLASSA_HOST;
|
||||||
|
} else if (IN_CLASSB(ntohl(net_address))) {
|
||||||
|
broadcast_address =
|
||||||
|
(ntohl(net_address) & ~IN_CLASSB_HOST) | IN_CLASSB_HOST;
|
||||||
|
} else if (IN_CLASSC(ntohl(net_address))) {
|
||||||
|
broadcast_address =
|
||||||
|
(ntohl(net_address) & ~IN_CLASSC_HOST) | IN_CLASSC_HOST;
|
||||||
|
} else if (IN_CLASSD(ntohl(net_address))) {
|
||||||
|
broadcast_address =
|
||||||
|
(ntohl(net_address) & ~IN_CLASSD_HOST) | IN_CLASSD_HOST;
|
||||||
|
} else {
|
||||||
|
broadcast_address = INADDR_BROADCAST;
|
||||||
|
}
|
||||||
|
BIP_Broadcast_Addr.s_addr = htonl(broadcast_address);
|
||||||
|
#else
|
||||||
request = "broadaddr";
|
request = "broadaddr";
|
||||||
rv = get_local_address(ifname, &broadcast_address, request);
|
rv = get_local_address(ifname, &broadcast_address, request);
|
||||||
if (rv < 0) {
|
if (rv < 0) {
|
||||||
@@ -579,6 +622,7 @@ void bip_set_interface(char *ifname)
|
|||||||
} else {
|
} else {
|
||||||
BIP_Broadcast_Addr.s_addr = broadcast_address.s_addr;
|
BIP_Broadcast_Addr.s_addr = broadcast_address.s_addr;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
if (BIP_Debug) {
|
if (BIP_Debug) {
|
||||||
fprintf(stderr, "BIP: Broadcast Address: %s\n",
|
fprintf(stderr, "BIP: Broadcast Address: %s\n",
|
||||||
inet_ntoa(BIP_Broadcast_Addr));
|
inet_ntoa(BIP_Broadcast_Addr));
|
||||||
@@ -672,8 +716,17 @@ bool bip_init(char *ifname)
|
|||||||
if (sock_fd < 0) {
|
if (sock_fd < 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (BIP_Broadcast_Binding_Address_Override) {
|
||||||
sin.sin_addr.s_addr = htonl(INADDR_ANY);
|
sin.sin_addr.s_addr = BIP_Broadcast_Binding_Address.s_addr;
|
||||||
|
} else {
|
||||||
|
#if defined(BACNET_IP_BROADCAST_USE_INADDR_ANY)
|
||||||
|
sin.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||||
|
#elif defined(BACNET_IP_BROADCAST_USE_INADDR_BROADCAST)
|
||||||
|
sin.sin_addr.s_addr = htonl(INADDR_BROADCAST);
|
||||||
|
#else
|
||||||
|
sin.sin_addr.s_addr = BIP_Broadcast_Addr.s_addr;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
sock_fd = createSocket(&sin);
|
sock_fd = createSocket(&sin);
|
||||||
BIP_Broadcast_Socket = sock_fd;
|
BIP_Broadcast_Socket = sock_fd;
|
||||||
if (sock_fd < 0) {
|
if (sock_fd < 0) {
|
||||||
|
|||||||
@@ -114,8 +114,11 @@
|
|||||||
BACNET_STACK_EXPORT
|
BACNET_STACK_EXPORT
|
||||||
extern int bip_get_local_netmask(
|
extern int bip_get_local_netmask(
|
||||||
struct in_addr *netmask);
|
struct in_addr *netmask);
|
||||||
|
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
extern int bip_get_local_address_ioctl(
|
extern int bip_get_local_address_ioctl(
|
||||||
char *ifname,
|
char *ifname,
|
||||||
struct in_addr *addr,
|
struct in_addr *addr,
|
||||||
int request);
|
int request);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+62
-8
@@ -73,6 +73,9 @@ static uint16_t BIP_Port;
|
|||||||
static struct in_addr BIP_Address;
|
static struct in_addr BIP_Address;
|
||||||
/* IP broadcast address - stored here in network byte order */
|
/* IP broadcast address - stored here in network byte order */
|
||||||
static struct in_addr BIP_Broadcast_Addr;
|
static struct in_addr BIP_Broadcast_Addr;
|
||||||
|
/* broadcast binding mechanism */
|
||||||
|
static bool BIP_Broadcast_Binding_Address_Override;
|
||||||
|
static struct in_addr BIP_Broadcast_Binding_Address;
|
||||||
/* enable debugging */
|
/* enable debugging */
|
||||||
static bool BIP_Debug = false;
|
static bool BIP_Debug = false;
|
||||||
/* interface name */
|
/* interface name */
|
||||||
@@ -409,9 +412,11 @@ uint16_t bip_receive(
|
|||||||
debug_print_ipv4(
|
debug_print_ipv4(
|
||||||
"Received MPDU->", &sin.sin_addr, sin.sin_port, received_bytes);
|
"Received MPDU->", &sin.sin_addr, sin.sin_port, received_bytes);
|
||||||
/* pass the packet into the BBMD handler */
|
/* pass the packet into the BBMD handler */
|
||||||
offset = socket == BIP_Socket ?
|
if (socket == BIP_Socket) {
|
||||||
bvlc_handler(&addr, src, npdu, received_bytes) :
|
offset = bvlc_handler(&addr, src, npdu, received_bytes);
|
||||||
bvlc_broadcast_handler(&addr, src, npdu, received_bytes);
|
} else {
|
||||||
|
offset = bvlc_broadcast_handler(&addr, src, npdu, received_bytes);
|
||||||
|
}
|
||||||
if (offset > 0) {
|
if (offset > 0) {
|
||||||
npdu_len = received_bytes - offset;
|
npdu_len = received_bytes - offset;
|
||||||
debug_print_ipv4(
|
debug_print_ipv4(
|
||||||
@@ -749,6 +754,20 @@ int bip_get_local_netmask(struct in_addr *netmask)
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the broadcast socket binding address
|
||||||
|
* @param baddr The broadcast socket binding address, in host order.
|
||||||
|
* @return 0 on success
|
||||||
|
*/
|
||||||
|
int bip_set_broadcast_binding(
|
||||||
|
const char *ip4_broadcast)
|
||||||
|
{
|
||||||
|
BIP_Broadcast_Binding_Address.s_addr = inet_addr(ip4_broadcast);
|
||||||
|
BIP_Broadcast_Binding_Address_Override = true;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/** Gets the local IP address and local broadcast address from the system,
|
/** Gets the local IP address and local broadcast address from the system,
|
||||||
* and saves it into the BACnet/IP data structures.
|
* and saves it into the BACnet/IP data structures.
|
||||||
*
|
*
|
||||||
@@ -773,6 +792,29 @@ void bip_set_interface(char *ifname)
|
|||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
}
|
}
|
||||||
/* setup local broadcast address */
|
/* setup local broadcast address */
|
||||||
|
#ifdef BACNET_IP_BROADCAST_USE_CLASSADDR
|
||||||
|
long broadcast_address;
|
||||||
|
long net_address;
|
||||||
|
|
||||||
|
broadcast_address = 0;
|
||||||
|
net_address = local_address.s_addr;
|
||||||
|
if (IN_CLASSA(ntohl(net_address))) {
|
||||||
|
broadcast_address =
|
||||||
|
(ntohl(net_address) & ~IN_CLASSA_HOST) | IN_CLASSA_HOST;
|
||||||
|
} else if (IN_CLASSB(ntohl(net_address))) {
|
||||||
|
broadcast_address =
|
||||||
|
(ntohl(net_address) & ~IN_CLASSB_HOST) | IN_CLASSB_HOST;
|
||||||
|
} else if (IN_CLASSC(ntohl(net_address))) {
|
||||||
|
broadcast_address =
|
||||||
|
(ntohl(net_address) & ~IN_CLASSC_HOST) | IN_CLASSC_HOST;
|
||||||
|
} else if (IN_CLASSD(ntohl(net_address))) {
|
||||||
|
broadcast_address =
|
||||||
|
(ntohl(net_address) & ~IN_CLASSD_HOST) | IN_CLASSD_HOST;
|
||||||
|
} else {
|
||||||
|
broadcast_address = INADDR_BROADCAST;
|
||||||
|
}
|
||||||
|
BIP_Broadcast_Addr.s_addr = htonl(broadcast_address);
|
||||||
|
#else
|
||||||
rv = bip_get_local_address_ioctl(ifname, &netmask, SIOCGIFNETMASK);
|
rv = bip_get_local_address_ioctl(ifname, &netmask, SIOCGIFNETMASK);
|
||||||
if (rv < 0) {
|
if (rv < 0) {
|
||||||
BIP_Broadcast_Addr.s_addr = ~0;
|
BIP_Broadcast_Addr.s_addr = ~0;
|
||||||
@@ -780,6 +822,7 @@ void bip_set_interface(char *ifname)
|
|||||||
BIP_Broadcast_Addr = local_address;
|
BIP_Broadcast_Addr = local_address;
|
||||||
BIP_Broadcast_Addr.s_addr |= (~netmask.s_addr);
|
BIP_Broadcast_Addr.s_addr |= (~netmask.s_addr);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
if (BIP_Debug) {
|
if (BIP_Debug) {
|
||||||
fprintf(stderr, "BIP: Broadcast Address: %s\n",
|
fprintf(stderr, "BIP: Broadcast Address: %s\n",
|
||||||
inet_ntoa(BIP_Broadcast_Addr));
|
inet_ntoa(BIP_Broadcast_Addr));
|
||||||
@@ -817,9 +860,11 @@ static int createSocket(struct sockaddr_in *sin)
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
/* Bind to the proper interface to send without default gateway */
|
/* Bind to the proper interface to send without default gateway */
|
||||||
setsockopt(sock_fd, SOL_SOCKET, SO_BINDTODEVICE, BIP_Interface_Name,
|
status = setsockopt(sock_fd, SOL_SOCKET, SO_BINDTODEVICE,
|
||||||
strlen(BIP_Interface_Name));
|
BIP_Interface_Name, strlen(BIP_Interface_Name));
|
||||||
|
if (status < 0) {
|
||||||
|
perror("SO_BINDTODEVICE: ");
|
||||||
|
}
|
||||||
/* bind the socket to the local port number and IP address */
|
/* bind the socket to the local port number and IP address */
|
||||||
status =
|
status =
|
||||||
bind(sock_fd, (const struct sockaddr *)sin, sizeof(struct sockaddr));
|
bind(sock_fd, (const struct sockaddr *)sin, sizeof(struct sockaddr));
|
||||||
@@ -876,8 +921,17 @@ bool bip_init(char *ifname)
|
|||||||
if (sock_fd < 0) {
|
if (sock_fd < 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (BIP_Broadcast_Binding_Address_Override) {
|
||||||
sin.sin_addr.s_addr = htonl(INADDR_ANY);
|
sin.sin_addr.s_addr = BIP_Broadcast_Binding_Address.s_addr;
|
||||||
|
} else {
|
||||||
|
#if defined(BACNET_IP_BROADCAST_USE_INADDR_ANY)
|
||||||
|
sin.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||||
|
#elif defined(BACNET_IP_BROADCAST_USE_INADDR_BROADCAST)
|
||||||
|
sin.sin_addr.s_addr = htonl(INADDR_BROADCAST);
|
||||||
|
#else
|
||||||
|
sin.sin_addr.s_addr = BIP_Broadcast_Addr.s_addr;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
sock_fd = createSocket(&sin);
|
sock_fd = createSocket(&sin);
|
||||||
BIP_Broadcast_Socket = sock_fd;
|
BIP_Broadcast_Socket = sock_fd;
|
||||||
if (sock_fd < 0) {
|
if (sock_fd < 0) {
|
||||||
|
|||||||
@@ -39,7 +39,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#if (!defined(USE_CLASSADDR) || (USE_CLASSADDR == 0))
|
#ifndef BACNET_IP_BROADCAST_USE_CLASSADDR
|
||||||
#include <iphlpapi.h>
|
#include <iphlpapi.h>
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#pragma comment(lib, "IPHLPAPI.lib")
|
#pragma comment(lib, "IPHLPAPI.lib")
|
||||||
@@ -81,6 +81,10 @@ and globals in favor of more secure versions. */
|
|||||||
#define snprintf _snprintf
|
#define snprintf _snprintf
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
extern int bip_get_local_netmask(
|
||||||
|
struct in_addr *netmask);
|
||||||
|
|
||||||
#define BACNET_OBJECT_TABLE(table_name, _type, _init, _count, \
|
#define BACNET_OBJECT_TABLE(table_name, _type, _init, _count, \
|
||||||
_index_to_instance, _valid_instance, _object_name, \
|
_index_to_instance, _valid_instance, _object_name, \
|
||||||
_read_property, _write_property, _RPM_list, \
|
_read_property, _write_property, _RPM_list, \
|
||||||
|
|||||||
+54
-20
@@ -45,10 +45,6 @@
|
|||||||
#include "bacnet/basic/bbmd/h_bbmd.h"
|
#include "bacnet/basic/bbmd/h_bbmd.h"
|
||||||
#include "bacport.h"
|
#include "bacport.h"
|
||||||
|
|
||||||
#ifndef USE_CLASSADDR
|
|
||||||
#define USE_CLASSADDR 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Windows sockets */
|
/* Windows sockets */
|
||||||
static SOCKET BIP_Socket = INVALID_SOCKET;
|
static SOCKET BIP_Socket = INVALID_SOCKET;
|
||||||
static SOCKET BIP_Broadcast_Socket = INVALID_SOCKET;
|
static SOCKET BIP_Broadcast_Socket = INVALID_SOCKET;
|
||||||
@@ -62,10 +58,12 @@ static uint16_t BIP_Port;
|
|||||||
/* IP address - stored here in network byte order */
|
/* IP address - stored here in network byte order */
|
||||||
static struct in_addr BIP_Address;
|
static struct in_addr BIP_Address;
|
||||||
/* IP broadcast address - stored here in network byte order */
|
/* IP broadcast address - stored here in network byte order */
|
||||||
static struct in_addr BIP_Broadcast_Address;
|
static struct in_addr BIP_Broadcast_Addr;
|
||||||
|
/* broadcast binding mechanism */
|
||||||
|
static bool BIP_Broadcast_Binding_Address_Override;
|
||||||
|
static struct in_addr BIP_Broadcast_Binding_Address;
|
||||||
/* enable debugging */
|
/* enable debugging */
|
||||||
static bool BIP_Debug = false;
|
static bool BIP_Debug;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Print the IPv4 address with debug info
|
* @brief Print the IPv4 address with debug info
|
||||||
@@ -328,7 +326,7 @@ void bip_get_broadcast_address(BACNET_ADDRESS *dest)
|
|||||||
|
|
||||||
if (dest) {
|
if (dest) {
|
||||||
dest->mac_len = 6;
|
dest->mac_len = 6;
|
||||||
memcpy(&dest->mac[0], &BIP_Broadcast_Address.s_addr, 4);
|
memcpy(&dest->mac[0], &BIP_Broadcast_Addr.s_addr, 4);
|
||||||
memcpy(&dest->mac[4], &BIP_Port, 2);
|
memcpy(&dest->mac[4], &BIP_Port, 2);
|
||||||
dest->net = BACNET_BROADCAST_NETWORK;
|
dest->net = BACNET_BROADCAST_NETWORK;
|
||||||
dest->len = 0; /* no SLEN */
|
dest->len = 0; /* no SLEN */
|
||||||
@@ -388,7 +386,7 @@ bool bip_set_broadcast_addr(BACNET_IP_ADDRESS *addr)
|
|||||||
bool bip_get_broadcast_addr(BACNET_IP_ADDRESS *addr)
|
bool bip_get_broadcast_addr(BACNET_IP_ADDRESS *addr)
|
||||||
{
|
{
|
||||||
if (addr) {
|
if (addr) {
|
||||||
memcpy(&addr->address[0], &BIP_Broadcast_Address.s_addr, 4);
|
memcpy(&addr->address[0], &BIP_Broadcast_Addr.s_addr, 4);
|
||||||
addr->port = ntohs(BIP_Port);
|
addr->port = ntohs(BIP_Port);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -418,8 +416,8 @@ uint8_t bip_get_subnet_prefix(void)
|
|||||||
uint32_t mask = 0xFFFFFFFE;
|
uint32_t mask = 0xFFFFFFFE;
|
||||||
uint8_t prefix = 0;
|
uint8_t prefix = 0;
|
||||||
|
|
||||||
address = BIP_Broadcast_Address.s_addr;
|
address = BIP_Broadcast_Addr.s_addr;
|
||||||
broadcast = BIP_Broadcast_Address.s_addr;
|
broadcast = BIP_Broadcast_Addr.s_addr;
|
||||||
/* calculate the subnet prefix from the broadcast address */
|
/* calculate the subnet prefix from the broadcast address */
|
||||||
for (prefix = 1; prefix <= 32; prefix++) {
|
for (prefix = 1; prefix <= 32; prefix++) {
|
||||||
test_broadcast = (address & mask) | (~mask);
|
test_broadcast = (address & mask) | (~mask);
|
||||||
@@ -653,7 +651,6 @@ static long gethostaddr(void)
|
|||||||
return *(long *)host_ent->h_addr;
|
return *(long *)host_ent->h_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (USE_CLASSADDR == 0)
|
|
||||||
/* returns the subnet mask in network byte order */
|
/* returns the subnet mask in network byte order */
|
||||||
static uint32_t getIpMaskForIpAddress(uint32_t ipAddress)
|
static uint32_t getIpMaskForIpAddress(uint32_t ipAddress)
|
||||||
{
|
{
|
||||||
@@ -696,11 +693,38 @@ static uint32_t getIpMaskForIpAddress(uint32_t ipAddress)
|
|||||||
|
|
||||||
return ipMask;
|
return ipMask;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
/**
|
||||||
|
* @brief Get the netmask of the BACnet/IP's interface via an ioctl() call.
|
||||||
|
* @param netmask [out] The netmask, in host order.
|
||||||
|
* @return 0 on success, else the error from the ioctl() call.
|
||||||
|
*/
|
||||||
|
int bip_get_local_netmask(struct in_addr *netmask)
|
||||||
|
{
|
||||||
|
if (netmask) {
|
||||||
|
netmask->s_addr = getIpMaskForIpAddress(BIP_Address.s_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the broadcast socket binding address
|
||||||
|
* @param baddr The broadcast socket binding address, in host order.
|
||||||
|
* @return 0 on success
|
||||||
|
*/
|
||||||
|
int bip_set_broadcast_binding(
|
||||||
|
const char *ip4_broadcast)
|
||||||
|
{
|
||||||
|
BIP_Broadcast_Binding_Address.s_addr = inet_addr(ip4_broadcast);
|
||||||
|
BIP_Broadcast_Binding_Address_Override = true;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void set_broadcast_address(uint32_t net_address)
|
static void set_broadcast_address(uint32_t net_address)
|
||||||
{
|
{
|
||||||
#if USE_CLASSADDR
|
#ifdef BACNET_IP_BROADCAST_USE_CLASSADDR
|
||||||
long broadcast_address = 0;
|
long broadcast_address = 0;
|
||||||
|
|
||||||
if (IN_CLASSA(ntohl(net_address)))
|
if (IN_CLASSA(ntohl(net_address)))
|
||||||
@@ -717,7 +741,7 @@ static void set_broadcast_address(uint32_t net_address)
|
|||||||
(ntohl(net_address) & ~IN_CLASSD_HOST) | IN_CLASSD_HOST;
|
(ntohl(net_address) & ~IN_CLASSD_HOST) | IN_CLASSD_HOST;
|
||||||
else
|
else
|
||||||
broadcast_address = INADDR_BROADCAST;
|
broadcast_address = INADDR_BROADCAST;
|
||||||
BIP_Broadcast_Address.s_addr = htonl(broadcast_address);
|
BIP_Broadcast_Addr.s_addr = htonl(broadcast_address);
|
||||||
#else
|
#else
|
||||||
/* these are network byte order variables */
|
/* these are network byte order variables */
|
||||||
long broadcast_address = 0;
|
long broadcast_address = 0;
|
||||||
@@ -731,7 +755,7 @@ static void set_broadcast_address(uint32_t net_address)
|
|||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
}
|
}
|
||||||
broadcast_address = (net_address & net_mask) | (~net_mask);
|
broadcast_address = (net_address & net_mask) | (~net_mask);
|
||||||
BIP_Broadcast_Address.s_addr = broadcast_address;
|
BIP_Broadcast_Addr.s_addr = broadcast_address;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -754,7 +778,7 @@ void bip_set_interface(char *ifname)
|
|||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
}
|
}
|
||||||
/* setup local broadcast address */
|
/* setup local broadcast address */
|
||||||
if (BIP_Broadcast_Address.s_addr == 0) {
|
if (BIP_Broadcast_Addr.s_addr == 0) {
|
||||||
set_broadcast_address(BIP_Address.s_addr);
|
set_broadcast_address(BIP_Address.s_addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -829,13 +853,13 @@ bool bip_init(char *ifname)
|
|||||||
BIP_Address.s_addr = gethostaddr();
|
BIP_Address.s_addr = gethostaddr();
|
||||||
}
|
}
|
||||||
/* has broadcast address been set? */
|
/* has broadcast address been set? */
|
||||||
if (BIP_Broadcast_Address.s_addr == 0) {
|
if (BIP_Broadcast_Addr.s_addr == 0) {
|
||||||
set_broadcast_address(BIP_Address.s_addr);
|
set_broadcast_address(BIP_Address.s_addr);
|
||||||
}
|
}
|
||||||
if (BIP_Debug) {
|
if (BIP_Debug) {
|
||||||
fprintf(stderr, "BIP: Address: %s\n", inet_ntoa(BIP_Address));
|
fprintf(stderr, "BIP: Address: %s\n", inet_ntoa(BIP_Address));
|
||||||
fprintf(stderr, "BIP: Broadcast Address: %s\n",
|
fprintf(stderr, "BIP: Broadcast Address: %s\n",
|
||||||
inet_ntoa(BIP_Broadcast_Address));
|
inet_ntoa(BIP_Broadcast_Addr));
|
||||||
fprintf(stderr, "BIP: UDP Port: 0x%04X [%hu]\n", ntohs(BIP_Port),
|
fprintf(stderr, "BIP: UDP Port: 0x%04X [%hu]\n", ntohs(BIP_Port),
|
||||||
ntohs(BIP_Port));
|
ntohs(BIP_Port));
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
@@ -855,7 +879,17 @@ bool bip_init(char *ifname)
|
|||||||
if (sock_fd == INVALID_SOCKET) {
|
if (sock_fd == INVALID_SOCKET) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
sin.sin_addr.s_addr = htonl(INADDR_ANY);
|
if (BIP_Broadcast_Binding_Address_Override) {
|
||||||
|
sin.sin_addr.s_addr = BIP_Broadcast_Binding_Address.s_addr;
|
||||||
|
} else {
|
||||||
|
#if defined(BACNET_IP_BROADCAST_USE_INADDR_ANY)
|
||||||
|
sin.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||||
|
#elif defined(BACNET_IP_BROADCAST_USE_INADDR_BROADCAST)
|
||||||
|
sin.sin_addr.s_addr = htonl(INADDR_BROADCAST);
|
||||||
|
#else
|
||||||
|
sin.sin_addr.s_addr = BIP_Address.s_addr;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
if (BIP_Debug) {
|
if (BIP_Debug) {
|
||||||
fprintf(stderr, "BIP: broadcast bind %s:%hu\n", inet_ntoa(sin.sin_addr),
|
fprintf(stderr, "BIP: broadcast bind %s:%hu\n", inet_ntoa(sin.sin_addr),
|
||||||
ntohs(sin.sin_port));
|
ntohs(sin.sin_port));
|
||||||
|
|||||||
@@ -715,14 +715,14 @@ int bvlc_bbmd_disabled_handler(BACNET_IP_ADDRESS *addr,
|
|||||||
if (function_len) {
|
if (function_len) {
|
||||||
if (bbmd_address_match_self(&fwd_address)) {
|
if (bbmd_address_match_self(&fwd_address)) {
|
||||||
/* ignore forwards from my IPv4 address */
|
/* ignore forwards from my IPv4 address */
|
||||||
debug_print_string("Forwarded-NPDU is me!");
|
debug_print_string("Dropped Forwarded-NPDU from me!");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
bvlc_ip_address_to_bacnet_local(src, &fwd_address);
|
bvlc_ip_address_to_bacnet_local(src, &fwd_address);
|
||||||
offset = header_len + function_len - npdu_len;
|
offset = header_len + function_len - npdu_len;
|
||||||
debug_print_npdu("Forwarded-NPDU", offset, npdu_len);
|
debug_print_npdu("Forwarded-NPDU", offset, npdu_len);
|
||||||
} else {
|
} else {
|
||||||
debug_print_string("Forwarded-NPDU: Unable to decode!");
|
debug_print_string("Dropped Forwarded-NPDU: Malformed!");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case BVLC_REGISTER_FOREIGN_DEVICE:
|
case BVLC_REGISTER_FOREIGN_DEVICE:
|
||||||
@@ -751,7 +751,8 @@ int bvlc_bbmd_disabled_handler(BACNET_IP_ADDRESS *addr,
|
|||||||
debug_print_bip("Received Original-Unicast-NPDU", addr);
|
debug_print_bip("Received Original-Unicast-NPDU", addr);
|
||||||
if (bbmd_address_match_self(addr)) {
|
if (bbmd_address_match_self(addr)) {
|
||||||
/* ignore messages from my IPv4 address */
|
/* ignore messages from my IPv4 address */
|
||||||
debug_print_string("Original-Unicast-NPDU is me!");
|
debug_print_string(
|
||||||
|
"Dropped Original-Unicast-NPDU from me!");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
function_len = bvlc_decode_original_unicast(
|
function_len = bvlc_decode_original_unicast(
|
||||||
@@ -762,14 +763,15 @@ int bvlc_bbmd_disabled_handler(BACNET_IP_ADDRESS *addr,
|
|||||||
debug_print_npdu("Original-Unicast-NPDU", offset, npdu_len);
|
debug_print_npdu("Original-Unicast-NPDU", offset, npdu_len);
|
||||||
} else {
|
} else {
|
||||||
debug_print_string(
|
debug_print_string(
|
||||||
"Original-Unicast-NPDU: Unable to decode!");
|
"Dropped Original-Unicast-NPDU: Malformed!");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case BVLC_ORIGINAL_BROADCAST_NPDU:
|
case BVLC_ORIGINAL_BROADCAST_NPDU:
|
||||||
debug_print_bip("Received Original-Broadcast-NPDU", addr);
|
debug_print_bip("Received Original-Broadcast-NPDU", addr);
|
||||||
if (bbmd_address_match_self(addr)) {
|
if (bbmd_address_match_self(addr)) {
|
||||||
/* ignore messages from my IPv4 address */
|
/* ignore messages from my IPv4 address */
|
||||||
debug_print_string("Original-Broadcast-NPDU is me!");
|
debug_print_string(
|
||||||
|
"Dropped Original-Broadcast-NPDU from me!");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
function_len = bvlc_decode_original_broadcast(
|
function_len = bvlc_decode_original_broadcast(
|
||||||
@@ -784,15 +786,15 @@ int bvlc_bbmd_disabled_handler(BACNET_IP_ADDRESS *addr,
|
|||||||
npdu = &mtu[offset];
|
npdu = &mtu[offset];
|
||||||
if (npdu_confirmed_service(npdu, npdu_len)) {
|
if (npdu_confirmed_service(npdu, npdu_len)) {
|
||||||
offset = 0;
|
offset = 0;
|
||||||
debug_print_string("Original-Broadcast-NPDU: "
|
debug_print_string("Dropped Original-Broadcast-NPDU: "
|
||||||
"Confirmed Service! Discard!");
|
"Confirmed Service!");
|
||||||
} else {
|
} else {
|
||||||
debug_print_npdu(
|
debug_print_npdu(
|
||||||
"Original-Broadcast-NPDU", offset, npdu_len);
|
"Original-Broadcast-NPDU", offset, npdu_len);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
debug_print_string(
|
debug_print_string(
|
||||||
"Original-Broadcast-NPDU: Unable to decode!");
|
"Dropped Original-Broadcast-NPDU: Malformed!");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case BVLC_SECURE_BVLL:
|
case BVLC_SECURE_BVLL:
|
||||||
@@ -922,7 +924,7 @@ int bvlc_bbmd_enabled_handler(BACNET_IP_ADDRESS *addr,
|
|||||||
if (function_len) {
|
if (function_len) {
|
||||||
if (bbmd_address_match_self(&fwd_address)) {
|
if (bbmd_address_match_self(&fwd_address)) {
|
||||||
/* ignore forwards from my IPv4 address */
|
/* ignore forwards from my IPv4 address */
|
||||||
debug_print_string("Forwarded-NPDU is me!");
|
debug_print_string("Dropped Forwarded-NPDU from me!");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (bbmd_bdt_member_mask_is_unicast(addr)) {
|
if (bbmd_bdt_member_mask_is_unicast(addr)) {
|
||||||
@@ -1057,7 +1059,7 @@ int bvlc_bbmd_enabled_handler(BACNET_IP_ADDRESS *addr,
|
|||||||
debug_print_bip("Received Original-Unicast-NPDU", addr);
|
debug_print_bip("Received Original-Unicast-NPDU", addr);
|
||||||
if (bbmd_address_match_self(addr)) {
|
if (bbmd_address_match_self(addr)) {
|
||||||
/* ignore messages from my IPv4 address */
|
/* ignore messages from my IPv4 address */
|
||||||
debug_print_string("Original-Unicast-NPDU is me!");
|
debug_print_string("Dropped Original-Unicast-NPDU from me!");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
function_len =
|
function_len =
|
||||||
@@ -1069,14 +1071,14 @@ int bvlc_bbmd_enabled_handler(BACNET_IP_ADDRESS *addr,
|
|||||||
debug_print_npdu("Original-Unicast-NPDU", offset, npdu_len);
|
debug_print_npdu("Original-Unicast-NPDU", offset, npdu_len);
|
||||||
} else {
|
} else {
|
||||||
debug_print_string(
|
debug_print_string(
|
||||||
"Original-Broadcast-NPDU: Unable to decode!");
|
"Dropped Original-Broadcast-NPDU: Malformed!");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case BVLC_ORIGINAL_BROADCAST_NPDU:
|
case BVLC_ORIGINAL_BROADCAST_NPDU:
|
||||||
debug_print_bip("Received Original-Broadcast-NPDU", addr);
|
debug_print_bip("Received Original-Broadcast-NPDU", addr);
|
||||||
if (bbmd_address_match_self(addr)) {
|
if (bbmd_address_match_self(addr)) {
|
||||||
/* ignore messages from my IPv4 address */
|
/* ignore messages from my IPv4 address */
|
||||||
debug_print_string("Original-Broadcast-NPDU is me!");
|
debug_print_string("Dropped Original-Broadcast-NPDU from me!");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
function_len = bvlc_decode_original_broadcast(
|
function_len = bvlc_decode_original_broadcast(
|
||||||
@@ -1105,8 +1107,8 @@ int bvlc_bbmd_enabled_handler(BACNET_IP_ADDRESS *addr,
|
|||||||
network layer. */
|
network layer. */
|
||||||
if (npdu_confirmed_service(npdu, npdu_len)) {
|
if (npdu_confirmed_service(npdu, npdu_len)) {
|
||||||
offset = 0;
|
offset = 0;
|
||||||
debug_print_string("Original-Broadcast-NPDU: "
|
debug_print_string("Dropped Original-Broadcast-NPDU: "
|
||||||
"Confirmed Service! Discard!");
|
"Confirmed Service!");
|
||||||
} else {
|
} else {
|
||||||
(void)bbmd_fdt_forward_npdu(addr, npdu, npdu_len, true);
|
(void)bbmd_fdt_forward_npdu(addr, npdu, npdu_len, true);
|
||||||
(void)bbmd_bdt_forward_npdu(addr, npdu, npdu_len, true);
|
(void)bbmd_bdt_forward_npdu(addr, npdu, npdu_len, true);
|
||||||
@@ -1115,7 +1117,7 @@ int bvlc_bbmd_enabled_handler(BACNET_IP_ADDRESS *addr,
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
debug_print_string(
|
debug_print_string(
|
||||||
"Original-Broadcast-NPDU: Unable to decode!");
|
"Dropped Original-Broadcast-NPDU: Malformed!");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case BVLC_SECURE_BVLL:
|
case BVLC_SECURE_BVLL:
|
||||||
@@ -1168,12 +1170,14 @@ int bvlc_broadcast_handler(BACNET_IP_ADDRESS *addr,
|
|||||||
uint16_t message_length = 0;
|
uint16_t message_length = 0;
|
||||||
int header_len = 0;
|
int header_len = 0;
|
||||||
|
|
||||||
|
debug_print_bip("Received Broadcast", addr);
|
||||||
header_len =
|
header_len =
|
||||||
bvlc_decode_header(npdu, npdu_len, &message_type, &message_length);
|
bvlc_decode_header(npdu, npdu_len, &message_type, &message_length);
|
||||||
if (header_len == 4) {
|
if (header_len == 4) {
|
||||||
switch (message_type) {
|
switch (message_type) {
|
||||||
case BVLC_ORIGINAL_UNICAST_NPDU:
|
case BVLC_ORIGINAL_UNICAST_NPDU:
|
||||||
/* drop unicast when sent as a broadcast */
|
/* drop unicast when sent as a broadcast */
|
||||||
|
debug_print_bip("Dropped BVLC (Original Unicast)", addr);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
offset = bvlc_handler(addr, src, npdu, npdu_len);
|
offset = bvlc_handler(addr, src, npdu, npdu_len);
|
||||||
|
|||||||
@@ -1154,7 +1154,7 @@ bool Binary_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* not using len at this time */
|
/* not using len at this time */
|
||||||
len = len;
|
(void)len;
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -414,4 +414,5 @@ bool tsm_invoke_id_failed(uint8_t invokeID)
|
|||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -44,10 +44,6 @@
|
|||||||
|
|
||||||
/* optional configuration for BACnet/IP datalink layer */
|
/* optional configuration for BACnet/IP datalink layer */
|
||||||
#if (defined(BACDL_BIP) || defined(BACDL_ALL))
|
#if (defined(BACDL_BIP) || defined(BACDL_ALL))
|
||||||
/* other BIP defines (define as 1 to enable):
|
|
||||||
USE_INADDR - uses INADDR_BROADCAST for broadcast and binds using INADDR_ANY
|
|
||||||
USE_CLASSADDR = uses IN_CLASSx_HOST where x=A,B,C or D for broadcast
|
|
||||||
*/
|
|
||||||
#if !defined(BBMD_ENABLED)
|
#if !defined(BBMD_ENABLED)
|
||||||
#define BBMD_ENABLED 1
|
#define BBMD_ENABLED 1
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -90,4 +90,5 @@ int create_object_ack_encode(
|
|||||||
}
|
}
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -122,6 +122,10 @@ extern "C" {
|
|||||||
BACNET_STACK_EXPORT
|
BACNET_STACK_EXPORT
|
||||||
int bip_get_broadcast_socket(void);
|
int bip_get_broadcast_socket(void);
|
||||||
|
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
int bip_set_broadcast_binding(
|
||||||
|
const char *ip4_broadcast);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|||||||
@@ -524,6 +524,7 @@ void dlenv_maintenance_timer(uint16_t elapsed_seconds)
|
|||||||
* - BACNET_BDT_MASK_1 - dotted IPv4 mask of the BBMD table
|
* - BACNET_BDT_MASK_1 - dotted IPv4 mask of the BBMD table
|
||||||
* entry 1..128 (optional)
|
* entry 1..128 (optional)
|
||||||
* - BACNET_IP_NAT_ADDR - dotted IPv4 address of the public facing router
|
* - BACNET_IP_NAT_ADDR - dotted IPv4 address of the public facing router
|
||||||
|
* - BACNET_IP_BROADCAST_BIND_ADDR - dotted IPv4 address to bind broadcasts
|
||||||
* - BACDL_MSTP: (BACnet MS/TP)
|
* - BACDL_MSTP: (BACnet MS/TP)
|
||||||
* - BACNET_MAX_INFO_FRAMES
|
* - BACNET_MAX_INFO_FRAMES
|
||||||
* - BACNET_MAX_MASTER
|
* - BACNET_MAX_MASTER
|
||||||
@@ -592,6 +593,10 @@ void dlenv_init(void)
|
|||||||
bip_set_port(0xBAC0);
|
bip_set_port(0xBAC0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pEnv = getenv("BACNET_IP_BROADCAST_BIND_ADDR");
|
||||||
|
if (pEnv) {
|
||||||
|
bip_set_broadcast_binding(pEnv);
|
||||||
|
}
|
||||||
pEnv = getenv("BACNET_IP_NAT_ADDR");
|
pEnv = getenv("BACNET_IP_NAT_ADDR");
|
||||||
if (pEnv) {
|
if (pEnv) {
|
||||||
if (bip_get_addr_by_name(pEnv, &addr)) {
|
if (bip_get_addr_by_name(pEnv, &addr)) {
|
||||||
|
|||||||
@@ -53,4 +53,5 @@ int delete_object_decode_service_request(
|
|||||||
}
|
}
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -80,4 +80,5 @@ int list_element_error_ack_decode(
|
|||||||
}
|
}
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user