diff --git a/CHANGELOG.md b/CHANGELOG.md index 83c746d4..a44947a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,7 +29,7 @@ BACnetAddress, and Weekly_Schedule and improved unit test code coverage. (#481) 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) -- fix ReinitializeDevice handler to clear password before decoding (#485) +- fix ReinitializeDevice handler to clear password before decoding (#485) (#487) ### Added @@ -39,8 +39,9 @@ improved unit test code coverage. (#481) ### Fixed - 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 BACnet/IP on OS to bind broadcast to specific port (#489) ## [1.1.2] - 2023-08-18 diff --git a/apps/Makefile b/apps/Makefile index d0886fd0..ce264886 100644 --- a/apps/Makefile +++ b/apps/Makefile @@ -73,6 +73,12 @@ ifeq (${BACNET_PORT},) ifeq ($(UNAME_S),Darwin) BACNET_PORT = bsd endif + ifeq ($(UNAME_S),FreeBSD) + BACNET_PORT = bsd + endif + ifeq ($(UNAME_S),OpenBSD) + BACNET_PORT = bsd + endif endif endif @@ -95,6 +101,7 @@ ifeq (${BACNET_PORT},bsd) PFLAGS = -pthread TARGET_EXT = SYSTEM_LIB=-lc,-lm +CSTANDARD = -std=c99 endif ifeq (${BACNET_PORT},win32) # winget install --id=MSYS2.MSYS2 -e diff --git a/bin/readme.txt b/bin/readme.txt index 76030407..888f203d 100644 --- a/bin/readme.txt +++ b/bin/readme.txt @@ -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_BROADCAST_BIND_ADDR - dotted IPv4 address to bind broadcasts + Example Usage ------------- You can communicate with the virtual BACnet Device by using the other BACnet diff --git a/ports/bsd/bacport.h b/ports/bsd/bacport.h index e87235db..142dd3df 100644 --- a/ports/bsd/bacport.h +++ b/ports/bsd/bacport.h @@ -88,10 +88,12 @@ #include #include #include +#include "bacnet/bacnet_stack_exports.h" /** @file bsd/net.h Includes BSD network headers. */ /* Local helper functions for this port */ +BACNET_STACK_EXPORT extern int bip_get_local_netmask( struct in_addr *netmask); diff --git a/ports/bsd/bip-init.c b/ports/bsd/bip-init.c index 8ca0025a..c070eb60 100644 --- a/ports/bsd/bip-init.c +++ b/ports/bsd/bip-init.c @@ -58,6 +58,9 @@ static uint16_t BIP_Port; static struct in_addr BIP_Address; /* IP broadcast address - stored here in network byte order */ 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 */ static bool BIP_Debug = false; /* interface name */ @@ -188,6 +191,7 @@ void bip_get_broadcast_address(BACNET_ADDRESS *dest) */ bool bip_set_addr(BACNET_IP_ADDRESS *addr) { + (void)addr; /* not something we do within this driver */ return false; } @@ -214,6 +218,7 @@ bool bip_get_addr(BACNET_IP_ADDRESS *addr) */ bool bip_set_broadcast_addr(BACNET_IP_ADDRESS *addr) { + (void)addr; /* not something we do within this driver */ return false; } @@ -239,6 +244,7 @@ bool bip_get_broadcast_addr(BACNET_IP_ADDRESS *addr) */ bool bip_set_subnet_prefix(uint8_t prefix) { + (void)prefix; /* not something we do within this driver */ return false; } @@ -321,7 +327,7 @@ uint16_t bip_receive( int max = 0; struct timeval select_timeout; struct sockaddr_in sin = { 0 }; - BACNET_IP_ADDRESS addr = { { 0 } }; + BACNET_IP_ADDRESS addr = { 0 }; socklen_t sin_len = sizeof(sin); int received_bytes = 0; int offset = 0; @@ -547,6 +553,20 @@ int bip_get_local_netmask(struct in_addr *netmask) 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, * and saves it into the BACnet/IP data structures. * @@ -572,6 +592,29 @@ void bip_set_interface(char *ifname) fflush(stderr); } /* 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"; rv = get_local_address(ifname, &broadcast_address, request); if (rv < 0) { @@ -579,6 +622,7 @@ void bip_set_interface(char *ifname) } else { BIP_Broadcast_Addr.s_addr = broadcast_address.s_addr; } +#endif if (BIP_Debug) { fprintf(stderr, "BIP: Broadcast Address: %s\n", inet_ntoa(BIP_Broadcast_Addr)); @@ -672,8 +716,17 @@ bool bip_init(char *ifname) if (sock_fd < 0) { 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_Broadcast_Addr.s_addr; +#endif + } sock_fd = createSocket(&sin); BIP_Broadcast_Socket = sock_fd; if (sock_fd < 0) { diff --git a/ports/linux/bacport.h b/ports/linux/bacport.h index a689769a..dcf67ad3 100644 --- a/ports/linux/bacport.h +++ b/ports/linux/bacport.h @@ -114,8 +114,11 @@ BACNET_STACK_EXPORT extern int bip_get_local_netmask( struct in_addr *netmask); + +BACNET_STACK_EXPORT extern int bip_get_local_address_ioctl( char *ifname, struct in_addr *addr, int request); + #endif diff --git a/ports/linux/bip-init.c b/ports/linux/bip-init.c index 9170c6f8..62bcce92 100644 --- a/ports/linux/bip-init.c +++ b/ports/linux/bip-init.c @@ -73,6 +73,9 @@ static uint16_t BIP_Port; static struct in_addr BIP_Address; /* IP broadcast address - stored here in network byte order */ 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 */ static bool BIP_Debug = false; /* interface name */ @@ -409,9 +412,11 @@ uint16_t bip_receive( debug_print_ipv4( "Received MPDU->", &sin.sin_addr, sin.sin_port, received_bytes); /* pass the packet into the BBMD handler */ - offset = socket == BIP_Socket ? - bvlc_handler(&addr, src, npdu, received_bytes) : - bvlc_broadcast_handler(&addr, src, npdu, received_bytes); + if (socket == BIP_Socket) { + offset = bvlc_handler(&addr, src, npdu, received_bytes); + } else { + offset = bvlc_broadcast_handler(&addr, src, npdu, received_bytes); + } if (offset > 0) { npdu_len = received_bytes - offset; debug_print_ipv4( @@ -749,6 +754,20 @@ int bip_get_local_netmask(struct in_addr *netmask) 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, * and saves it into the BACnet/IP data structures. * @@ -773,6 +792,29 @@ void bip_set_interface(char *ifname) fflush(stderr); } /* 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); if (rv < 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.s_addr |= (~netmask.s_addr); } +#endif if (BIP_Debug) { fprintf(stderr, "BIP: Broadcast Address: %s\n", inet_ntoa(BIP_Broadcast_Addr)); @@ -817,9 +860,11 @@ static int createSocket(struct sockaddr_in *sin) return status; } /* Bind to the proper interface to send without default gateway */ - setsockopt(sock_fd, SOL_SOCKET, SO_BINDTODEVICE, BIP_Interface_Name, - strlen(BIP_Interface_Name)); - + status = setsockopt(sock_fd, SOL_SOCKET, SO_BINDTODEVICE, + BIP_Interface_Name, strlen(BIP_Interface_Name)); + if (status < 0) { + perror("SO_BINDTODEVICE: "); + } /* bind the socket to the local port number and IP address */ status = bind(sock_fd, (const struct sockaddr *)sin, sizeof(struct sockaddr)); @@ -876,8 +921,17 @@ bool bip_init(char *ifname) if (sock_fd < 0) { 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_Broadcast_Addr.s_addr; +#endif + } sock_fd = createSocket(&sin); BIP_Broadcast_Socket = sock_fd; if (sock_fd < 0) { diff --git a/ports/win32/bacport.h b/ports/win32/bacport.h index 75c43440..2fef8c01 100644 --- a/ports/win32/bacport.h +++ b/ports/win32/bacport.h @@ -39,7 +39,7 @@ #endif #include -#if (!defined(USE_CLASSADDR) || (USE_CLASSADDR == 0)) +#ifndef BACNET_IP_BROADCAST_USE_CLASSADDR #include #if defined(_MSC_VER) #pragma comment(lib, "IPHLPAPI.lib") @@ -81,6 +81,10 @@ and globals in favor of more secure versions. */ #define snprintf _snprintf #endif +BACNET_STACK_EXPORT +extern int bip_get_local_netmask( + struct in_addr *netmask); + #define BACNET_OBJECT_TABLE(table_name, _type, _init, _count, \ _index_to_instance, _valid_instance, _object_name, \ _read_property, _write_property, _RPM_list, \ diff --git a/ports/win32/bip-init.c b/ports/win32/bip-init.c index 098c2722..ac9f8585 100644 --- a/ports/win32/bip-init.c +++ b/ports/win32/bip-init.c @@ -45,10 +45,6 @@ #include "bacnet/basic/bbmd/h_bbmd.h" #include "bacport.h" -#ifndef USE_CLASSADDR -#define USE_CLASSADDR 0 -#endif - /* Windows sockets */ static SOCKET BIP_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 */ static struct in_addr BIP_Address; /* 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 */ -static bool BIP_Debug = false; +static bool BIP_Debug; /** * @brief Print the IPv4 address with debug info @@ -328,7 +326,7 @@ void bip_get_broadcast_address(BACNET_ADDRESS *dest) if (dest) { 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); dest->net = BACNET_BROADCAST_NETWORK; 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) { 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); } @@ -418,8 +416,8 @@ uint8_t bip_get_subnet_prefix(void) uint32_t mask = 0xFFFFFFFE; uint8_t prefix = 0; - address = BIP_Broadcast_Address.s_addr; - broadcast = BIP_Broadcast_Address.s_addr; + address = BIP_Broadcast_Addr.s_addr; + broadcast = BIP_Broadcast_Addr.s_addr; /* calculate the subnet prefix from the broadcast address */ for (prefix = 1; prefix <= 32; prefix++) { test_broadcast = (address & mask) | (~mask); @@ -653,7 +651,6 @@ static long gethostaddr(void) return *(long *)host_ent->h_addr; } -#if (USE_CLASSADDR == 0) /* returns the subnet mask in network byte order */ static uint32_t getIpMaskForIpAddress(uint32_t ipAddress) { @@ -696,11 +693,38 @@ static uint32_t getIpMaskForIpAddress(uint32_t ipAddress) 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) { -#if USE_CLASSADDR +#ifdef BACNET_IP_BROADCAST_USE_CLASSADDR long broadcast_address = 0; 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; else broadcast_address = INADDR_BROADCAST; - BIP_Broadcast_Address.s_addr = htonl(broadcast_address); + BIP_Broadcast_Addr.s_addr = htonl(broadcast_address); #else /* these are network byte order variables */ long broadcast_address = 0; @@ -731,7 +755,7 @@ static void set_broadcast_address(uint32_t net_address) fflush(stderr); } broadcast_address = (net_address & net_mask) | (~net_mask); - BIP_Broadcast_Address.s_addr = broadcast_address; + BIP_Broadcast_Addr.s_addr = broadcast_address; #endif } @@ -754,7 +778,7 @@ void bip_set_interface(char *ifname) fflush(stderr); } /* 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); } } @@ -829,13 +853,13 @@ bool bip_init(char *ifname) BIP_Address.s_addr = gethostaddr(); } /* 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); } if (BIP_Debug) { fprintf(stderr, "BIP: Address: %s\n", inet_ntoa(BIP_Address)); 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), ntohs(BIP_Port)); fflush(stderr); @@ -855,7 +879,17 @@ bool bip_init(char *ifname) if (sock_fd == INVALID_SOCKET) { 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) { fprintf(stderr, "BIP: broadcast bind %s:%hu\n", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); diff --git a/src/bacnet/basic/bbmd/h_bbmd.c b/src/bacnet/basic/bbmd/h_bbmd.c index 9b5ec055..d2d98989 100644 --- a/src/bacnet/basic/bbmd/h_bbmd.c +++ b/src/bacnet/basic/bbmd/h_bbmd.c @@ -715,14 +715,14 @@ int bvlc_bbmd_disabled_handler(BACNET_IP_ADDRESS *addr, if (function_len) { if (bbmd_address_match_self(&fwd_address)) { /* ignore forwards from my IPv4 address */ - debug_print_string("Forwarded-NPDU is me!"); + debug_print_string("Dropped Forwarded-NPDU from me!"); break; } bvlc_ip_address_to_bacnet_local(src, &fwd_address); offset = header_len + function_len - npdu_len; debug_print_npdu("Forwarded-NPDU", offset, npdu_len); } else { - debug_print_string("Forwarded-NPDU: Unable to decode!"); + debug_print_string("Dropped Forwarded-NPDU: Malformed!"); } break; 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); if (bbmd_address_match_self(addr)) { /* ignore messages from my IPv4 address */ - debug_print_string("Original-Unicast-NPDU is me!"); + debug_print_string( + "Dropped Original-Unicast-NPDU from me!"); break; } 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); } else { debug_print_string( - "Original-Unicast-NPDU: Unable to decode!"); + "Dropped Original-Unicast-NPDU: Malformed!"); } break; case BVLC_ORIGINAL_BROADCAST_NPDU: debug_print_bip("Received Original-Broadcast-NPDU", addr); if (bbmd_address_match_self(addr)) { /* ignore messages from my IPv4 address */ - debug_print_string("Original-Broadcast-NPDU is me!"); + debug_print_string( + "Dropped Original-Broadcast-NPDU from me!"); break; } function_len = bvlc_decode_original_broadcast( @@ -784,15 +786,15 @@ int bvlc_bbmd_disabled_handler(BACNET_IP_ADDRESS *addr, npdu = &mtu[offset]; if (npdu_confirmed_service(npdu, npdu_len)) { offset = 0; - debug_print_string("Original-Broadcast-NPDU: " - "Confirmed Service! Discard!"); + debug_print_string("Dropped Original-Broadcast-NPDU: " + "Confirmed Service!"); } else { debug_print_npdu( "Original-Broadcast-NPDU", offset, npdu_len); } } else { debug_print_string( - "Original-Broadcast-NPDU: Unable to decode!"); + "Dropped Original-Broadcast-NPDU: Malformed!"); } break; case BVLC_SECURE_BVLL: @@ -922,7 +924,7 @@ int bvlc_bbmd_enabled_handler(BACNET_IP_ADDRESS *addr, if (function_len) { if (bbmd_address_match_self(&fwd_address)) { /* ignore forwards from my IPv4 address */ - debug_print_string("Forwarded-NPDU is me!"); + debug_print_string("Dropped Forwarded-NPDU from me!"); break; } 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); if (bbmd_address_match_self(addr)) { /* ignore messages from my IPv4 address */ - debug_print_string("Original-Unicast-NPDU is me!"); + debug_print_string("Dropped Original-Unicast-NPDU from me!"); break; } function_len = @@ -1069,14 +1071,14 @@ int bvlc_bbmd_enabled_handler(BACNET_IP_ADDRESS *addr, debug_print_npdu("Original-Unicast-NPDU", offset, npdu_len); } else { debug_print_string( - "Original-Broadcast-NPDU: Unable to decode!"); + "Dropped Original-Broadcast-NPDU: Malformed!"); } break; case BVLC_ORIGINAL_BROADCAST_NPDU: debug_print_bip("Received Original-Broadcast-NPDU", addr); if (bbmd_address_match_self(addr)) { /* ignore messages from my IPv4 address */ - debug_print_string("Original-Broadcast-NPDU is me!"); + debug_print_string("Dropped Original-Broadcast-NPDU from me!"); break; } function_len = bvlc_decode_original_broadcast( @@ -1105,8 +1107,8 @@ int bvlc_bbmd_enabled_handler(BACNET_IP_ADDRESS *addr, network layer. */ if (npdu_confirmed_service(npdu, npdu_len)) { offset = 0; - debug_print_string("Original-Broadcast-NPDU: " - "Confirmed Service! Discard!"); + debug_print_string("Dropped Original-Broadcast-NPDU: " + "Confirmed Service!"); } else { (void)bbmd_fdt_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 { debug_print_string( - "Original-Broadcast-NPDU: Unable to decode!"); + "Dropped Original-Broadcast-NPDU: Malformed!"); } break; case BVLC_SECURE_BVLL: @@ -1168,12 +1170,14 @@ int bvlc_broadcast_handler(BACNET_IP_ADDRESS *addr, uint16_t message_length = 0; int header_len = 0; + debug_print_bip("Received Broadcast", addr); header_len = bvlc_decode_header(npdu, npdu_len, &message_type, &message_length); if (header_len == 4) { switch (message_type) { case BVLC_ORIGINAL_UNICAST_NPDU: /* drop unicast when sent as a broadcast */ + debug_print_bip("Dropped BVLC (Original Unicast)", addr); break; default: offset = bvlc_handler(addr, src, npdu, npdu_len); diff --git a/src/bacnet/basic/object/bo.c b/src/bacnet/basic/object/bo.c index 909703a1..cd6b0d54 100644 --- a/src/bacnet/basic/object/bo.c +++ b/src/bacnet/basic/object/bo.c @@ -1154,7 +1154,7 @@ bool Binary_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) break; } /* not using len at this time */ - len = len; + (void)len; return status; } diff --git a/src/bacnet/basic/tsm/tsm.c b/src/bacnet/basic/tsm/tsm.c index 730ab626..9c4ff532 100644 --- a/src/bacnet/basic/tsm/tsm.c +++ b/src/bacnet/basic/tsm/tsm.c @@ -414,4 +414,5 @@ bool tsm_invoke_id_failed(uint8_t invokeID) return status; } -#endif \ No newline at end of file +#endif + diff --git a/src/bacnet/config.h b/src/bacnet/config.h index f72c06de..f62cf372 100644 --- a/src/bacnet/config.h +++ b/src/bacnet/config.h @@ -44,10 +44,6 @@ /* optional configuration for BACnet/IP datalink layer */ #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) #define BBMD_ENABLED 1 #endif diff --git a/src/bacnet/create_object.h b/src/bacnet/create_object.h index 16e8511f..f0a92b97 100644 --- a/src/bacnet/create_object.h +++ b/src/bacnet/create_object.h @@ -90,4 +90,5 @@ int create_object_ack_encode( } #endif /* __cplusplus */ -#endif \ No newline at end of file +#endif + diff --git a/src/bacnet/datalink/bip.h b/src/bacnet/datalink/bip.h index 5a93a3de..668fd0be 100644 --- a/src/bacnet/datalink/bip.h +++ b/src/bacnet/datalink/bip.h @@ -122,6 +122,10 @@ extern "C" { BACNET_STACK_EXPORT int bip_get_broadcast_socket(void); + BACNET_STACK_EXPORT + int bip_set_broadcast_binding( + const char *ip4_broadcast); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/src/bacnet/datalink/dlenv.c b/src/bacnet/datalink/dlenv.c index 49834cdc..b04e0e66 100644 --- a/src/bacnet/datalink/dlenv.c +++ b/src/bacnet/datalink/dlenv.c @@ -524,6 +524,7 @@ void dlenv_maintenance_timer(uint16_t elapsed_seconds) * - BACNET_BDT_MASK_1 - dotted IPv4 mask of the BBMD table * entry 1..128 (optional) * - 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) * - BACNET_MAX_INFO_FRAMES * - BACNET_MAX_MASTER @@ -592,6 +593,10 @@ void dlenv_init(void) bip_set_port(0xBAC0); } } + pEnv = getenv("BACNET_IP_BROADCAST_BIND_ADDR"); + if (pEnv) { + bip_set_broadcast_binding(pEnv); + } pEnv = getenv("BACNET_IP_NAT_ADDR"); if (pEnv) { if (bip_get_addr_by_name(pEnv, &addr)) { diff --git a/src/bacnet/delete_object.h b/src/bacnet/delete_object.h index 6e1c8bce..461a9ef6 100644 --- a/src/bacnet/delete_object.h +++ b/src/bacnet/delete_object.h @@ -53,4 +53,5 @@ int delete_object_decode_service_request( } #endif /* __cplusplus */ -#endif \ No newline at end of file +#endif + diff --git a/src/bacnet/list_element.h b/src/bacnet/list_element.h index 846c35a9..bfd059ce 100644 --- a/src/bacnet/list_element.h +++ b/src/bacnet/list_element.h @@ -80,4 +80,5 @@ int list_element_error_ack_decode( } #endif /* __cplusplus */ -#endif \ No newline at end of file +#endif +