From 96222574f85b766d6bbdbc5bb1083a5e6ec12edd Mon Sep 17 00:00:00 2001 From: Steve Karg Date: Tue, 30 Apr 2024 13:52:00 -0500 Subject: [PATCH] Bugfix/router mstp builds (#630) * Fixed example app router-ipv6 to build under ports/win32 * Fixed example app router-mstp to build under ports/win32 with MinGW * Added win32 builds of router-ipv6 and router-mstp to the Github pipeline --- .github/workflows/gcc.yml | 6 + Makefile | 24 ++- apps/Makefile | 17 +++ apps/lib/Makefile | 20 ++- apps/router-ipv6/Makefile | 40 +---- apps/router-ipv6/main.c | 29 +++- apps/router-mstp/Makefile | 41 +---- ports/win32/bip6.c | 201 +++++++++++++------------ src/bacnet/basic/bbmd6/vmac.c | 44 +++--- src/bacnet/datalink/bvlc6.c | 8 +- test/bacnet/basic/bbmd6/CMakeLists.txt | 1 + 11 files changed, 221 insertions(+), 210 deletions(-) diff --git a/.github/workflows/gcc.yml b/.github/workflows/gcc.yml index 8dbaee73..18ed8312 100644 --- a/.github/workflows/gcc.yml +++ b/.github/workflows/gcc.yml @@ -241,3 +241,9 @@ jobs: export LD=i686-w64-mingw32-ld i686-w64-mingw32-gcc --version make win32 + - name: Build Win32 Demo IP to IPv6 Router + run: make LEGACY=true BUILD=win32 router-ipv6 + - name: Build Win32 Demo IP to MS/TP Router + run: make LEGACY=true BUILD=win32 router-mstp + - name: Build Win32 Demo Gateway + run: make LEGACY=true BUILD=win32 gateway diff --git a/Makefile b/Makefile index c45fa469..231c3e2b 100644 --- a/Makefile +++ b/Makefile @@ -130,11 +130,11 @@ getevent: .PHONY: gateway gateway: - $(MAKE) -s -C apps $@ + $(MAKE) -s -B -C apps $@ .PHONY: gateway-win32 gateway-win32: - $(MAKE) BACNET_PORT=win32 -s -C apps gateway + $(MAKE) BACNET_PORT=win32 -s -B -C apps gateway .PHONY: piface piface: @@ -210,11 +210,27 @@ router: .PHONY: router-ipv6 router-ipv6: - $(MAKE) -s -C apps $@ + $(MAKE) -s -B BACDL=bip-bip6 -C apps $@ + +.PHONY: router-ipv6-win32 +router-ipv6-win32: + $(MAKE) BACNET_PORT=win32 -s -B BACDL=bip-bip6 -C apps router-ipv6 + +.PHONY: router-ipv6-clean +router-ipv6-clean: + $(MAKE) -C apps $@ .PHONY: router-mstp router-mstp: - $(MAKE) -s -C apps $@ + $(MAKE) -s -B BACDL=bip-mstp -C apps $@ + +.PHONY: router-mstp-win32 +router-mstp-win32: + $(MAKE) BACNET_PORT=win32 -s -B BACDL=bip-mstp -C apps router-mstp + +.PHONY: router-mstp-clean +router-mstp-clean: + $(MAKE) -C apps $@ .PHONY: fuzz-libfuzzer fuzz-libfuzzer: diff --git a/apps/Makefile b/apps/Makefile index 268ac228..524c411e 100644 --- a/apps/Makefile +++ b/apps/Makefile @@ -38,6 +38,15 @@ endif ifeq (${BACDL},none) BACDL_DEFINE=-DBACDL_NONE=1 endif +ifeq (${BACDL},bip-mstp) +BACDL_DEFINE=-DBACDL_ROUTER=1 +endif +ifeq (${BACDL},bip-bip6) +BACDL_DEFINE=-DBACDL_ROUTER=1 +endif +ifeq (${BACDL},all) +BACDL_DEFINE=-DBACDL_ALL=1 +endif ifeq (${BACDL},) BACDL_DEFINE ?= -DBACDL_BIP=1 BBMD_DEFINE ?= -DBBMD_ENABLED=1 -DBBMD_CLIENT_ENABLED @@ -418,10 +427,18 @@ router: router-ipv6: $(BACNET_LIB_TARGET) $(MAKE) -B -C $@ +.PHONY: router-ipv6-clean +router-ipv6-clean: + $(MAKE) -C router-ipv6 clean + .PHONY: router-mstp router-mstp: $(BACNET_LIB_TARGET) $(MAKE) -B -C $@ +.PHONY: router-mstp-clean +router-mstp-clean: + $(MAKE) -C router-mstp clean + .PHONY: fuzz-libfuzzer fuzz-libfuzzer: $(BACNET_LIB_TARGET) $(MAKE) -B -C $@ diff --git a/apps/lib/Makefile b/apps/lib/Makefile index abdf1a7f..2690e421 100644 --- a/apps/lib/Makefile +++ b/apps/lib/Makefile @@ -23,6 +23,9 @@ INCLUDES = -I$(BACNET_SRC_DIR) CFLAGS += $(WARNINGS) $(DEBUGGING) $(OPTIMIZATION) $(BACNET_DEFINES) $(INCLUDES) CFLAGS += -ffunction-sections -fdata-sections +APPS_ENVIRONMENT_SRC = \ + $(BACNET_SRC_DIR)/bacnet/datalink/dlenv.c + PORT_ARCNET_SRC = \ $(BACNET_PORT_DIR)/arcnet.c @@ -60,19 +63,19 @@ PORT_NONE_SRC = \ $(BACNET_SRC_DIR)/bacnet/datalink/datalink.c ifeq (${BACDL_DEFINE},-DBACDL_BIP=1) -BACNET_PORT_SRC = ${PORT_BIP_SRC} +BACNET_PORT_SRC = ${PORT_BIP_SRC} ${APPS_ENVIRONMENT_SRC} endif ifeq (${BACDL_DEFINE},-DBACDL_BIP6=1) -BACNET_PORT_SRC = ${PORT_BIP6_SRC} +BACNET_PORT_SRC = ${PORT_BIP6_SRC} ${APPS_ENVIRONMENT_SRC} endif ifeq (${BACDL_DEFINE},-DBACDL_MSTP=1) -BACNET_PORT_SRC = ${PORT_MSTP_SRC} +BACNET_PORT_SRC = ${PORT_MSTP_SRC} ${APPS_ENVIRONMENT_SRC} endif ifeq (${BACDL_DEFINE},-DBACDL_ARCNET=1) -BACNET_PORT_SRC = ${PORT_ARCNET_SRC} +BACNET_PORT_SRC = ${PORT_ARCNET_SRC} ${APPS_ENVIRONMENT_SRC} endif ifeq (${BACDL_DEFINE},-DBACDL_ETHERNET=1) -BACNET_PORT_SRC = ${PORT_ETHERNET_SRC} +BACNET_PORT_SRC = ${PORT_ETHERNET_SRC} ${APPS_ENVIRONMENT_SRC} endif ifeq (${BACDL_DEFINE},-DBACDL_NONE=1) BACNET_PORT_SRC = ${PORT_NONE_SRC} @@ -80,12 +83,17 @@ endif ifeq (${BACDL_DEFINE},-DBACDL_ALL=1) BACNET_PORT_SRC = ${PORT_ALL_SRC} endif +ifeq (${BACDL},bip-mstp) +BACNET_PORT_SRC = ${PORT_BIP_SRC} ${PORT_MSTP_SRC} +endif +ifeq (${BACDL},bip-bip6) +BACNET_PORT_SRC = ${PORT_BIP_SRC} ${PORT_BIP6_SRC} +endif ifneq (${BACDL_DEFINE},) CFLAGS += ${BACDL_DEFINE} endif BACNET_PORT_SRC += \ - $(BACNET_SRC_DIR)/bacnet/datalink/dlenv.c \ $(BACNET_PORT_DIR)/mstimer-init.c \ $(BACNET_PORT_DIR)/datetime-init.c diff --git a/apps/router-ipv6/Makefile b/apps/router-ipv6/Makefile index 5eade300..42f726cb 100644 --- a/apps/router-ipv6/Makefile +++ b/apps/router-ipv6/Makefile @@ -5,7 +5,7 @@ # CC = gcc # Executable file name -TARGET = bacroute +TARGET = router-ipv6 TARGET_BIN = ${TARGET}$(TARGET_EXT) @@ -13,49 +13,17 @@ TARGET_BIN = ${TARGET}$(TARGET_EXT) # BACNET_SRC_DIR is defined in common apps Makefile BACNET_OBJECT_DIR = $(BACNET_SRC_DIR)/bacnet/basic/object SRC = main.c \ - $(BACNET_OBJECT_DIR)/netport.c \ - $(BACNET_OBJECT_DIR)/client/device-client.c - -PORT_BIP6_SRC = \ - $(BACNET_PORT_DIR)/bip6.c \ - $(BACNET_SRC_DIR)/bacnet/datalink/bvlc6.c \ - $(BACNET_SRC_DIR)/bacnet/basic/bbmd6/h_bbmd6.c \ - $(BACNET_SRC_DIR)/bacnet/basic/bbmd6/vmac.c - -PORT_BIP_SRC = \ - $(BACNET_PORT_DIR)/bip-init.c \ - $(BACNET_SRC_DIR)/bacnet/datalink/bvlc.c \ - $(BACNET_SRC_DIR)/bacnet/basic/bbmd/h_bbmd.c + $(BACNET_SRC_DIR)/bacnet/basic/npdu/s_router.c # WARNINGS, DEBUGGING, OPTIMIZATION are defined in common apps Makefile # BACNET_DEFINES is defined in common apps Makefile # put all the flags together INCLUDES = -I$(BACNET_SRC_DIR) -I$(BACNET_PORT_DIR) -CFLAGS += $(WARNINGS) $(DEBUGGING) $(OPTIMIZATION) $(BACNET_DEFINES) $(INCLUDES) -LFLAGS += -Wl,$(SYSTEM_LIB) -ifneq (${BACNET_LIB},) -LFLAGS += -Wl,$(BACNET_LIB) -endif -# GCC dead code removal -CFLAGS += -ffunction-sections -fdata-sections -LFLAGS += -Wl,--gc-sections - -BACNET_SRC = \ - $(wildcard $(BACNET_SRC_DIR)/bacnet/*.c) \ - $(wildcard $(BACNET_SRC_DIR)/bacnet/basic/*.c) \ - $(wildcard $(BACNET_SRC_DIR)/bacnet/basic/binding/*.c) \ - $(wildcard $(BACNET_SRC_DIR)/bacnet/basic/service/*.c) \ - $(wildcard $(BACNET_SRC_DIR)/bacnet/basic/sys/*.c) \ - $(BACNET_SRC_DIR)/bacnet/basic/npdu/h_routed_npdu.c \ - $(BACNET_SRC_DIR)/bacnet/basic/npdu/s_router.c \ - $(BACNET_SRC_DIR)/bacnet/basic/tsm/tsm.c - -SRCS = ${SRC} ${BACNET_SRC} ${PORT_BIP6_SRC} ${PORT_BIP_SRC} - +SRCS = ${SRC} OBJS += ${SRCS:.c=.o} .PHONY: all -all: Makefile ${TARGET_BIN} +all: ${BACNET_LIB_TARGET} Makefile ${TARGET_BIN} ${TARGET_BIN}: ${OBJS} ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ diff --git a/apps/router-ipv6/main.c b/apps/router-ipv6/main.c index d33a541f..1f53e4fa 100644 --- a/apps/router-ipv6/main.c +++ b/apps/router-ipv6/main.c @@ -62,6 +62,7 @@ /* current version of the BACnet stack */ static const char *BACnet_Version = BACNET_VERSION_TEXT; +static uint32_t Device_Instance_Number = BACNET_MAX_INSTANCE; /** * 6.6.1 Routing Tables @@ -602,6 +603,8 @@ static void who_is_router_to_network_handler(uint16_t snet, uint16_t network = 0; uint16_t len = 0; + (void)src; + (void)npdu_data; if (npdu) { if (npdu_len >= 2) { len += decode_unsigned16(&npdu[len], &network); @@ -948,12 +951,16 @@ static void my_routing_npdu_handler( uint16_t snet, BACNET_ADDRESS *src, uint8_t *pdu, uint16_t pdu_len) { int apdu_offset = 0; + unsigned protocol_version = 0; BACNET_ADDRESS dest = { 0 }; BACNET_NPDU_DATA npdu_data = { 0 }; if (!pdu) { /* no packet */ - } else if (pdu[0] == BACNET_PROTOCOL_VERSION) { + } else { + protocol_version = pdu[0]; + } + if (protocol_version == BACNET_PROTOCOL_VERSION) { apdu_offset = bacnet_npdu_decode(pdu, pdu_len, &dest, src, &npdu_data); if (apdu_offset <= 0) { fprintf(stderr, "NPDU: Decoding failed; Discarded!\n"); @@ -994,7 +1001,9 @@ static void my_routing_npdu_handler( } } } else { - /* unsupported protocol version */ + fprintf( + stderr, "NPDU: unsupported protocol version %u. Discarded!\n", + protocol_version); } return; @@ -1126,6 +1135,17 @@ static void control_c_hooks(void) } #endif +/** + * @brief Get the Device object instance number + * @return The Device object instance number + * @note This is a proxy function to satisfy the BACnet Stack IPv6 port layer + * requirements since this application omits a Device object. + */ +uint32_t Device_Object_Instance_Number(void) +{ + return Device_Instance_Number; +} + /** * Main function of simple router demo. * @@ -1141,8 +1161,11 @@ int main(int argc, char *argv[]) time_t current_seconds = 0; uint32_t elapsed_seconds = 0; - printf("BACnet Simple IP Router Demo\n"); + printf("BACnet Simple IP to IPv6 Router Demo\n"); printf("BACnet Stack Version %s\n", BACnet_Version); + if (argc > 1) { + Device_Instance_Number = strtol(argv[1], NULL, 0); + } datalink_init(); atexit(cleanup); control_c_hooks(); diff --git a/apps/router-mstp/Makefile b/apps/router-mstp/Makefile index 848827b8..59e71900 100644 --- a/apps/router-mstp/Makefile +++ b/apps/router-mstp/Makefile @@ -12,52 +12,17 @@ TARGET_BIN = ${TARGET}$(TARGET_EXT) # BACNET_PORT, BACNET_PORT_DIR, BACNET_PORT_SRC are defined in common Makefile # BACNET_SRC_DIR is defined in common apps Makefile BACNET_OBJECT_DIR = $(BACNET_SRC_DIR)/bacnet/basic/object -SRC = main.c \ - $(BACNET_OBJECT_DIR)/netport.c \ - $(BACNET_OBJECT_DIR)/client/device-client.c - -PORT_MSTP_SRC = \ - $(BACNET_PORT_DIR)/rs485.c \ - $(BACNET_PORT_DIR)/dlmstp.c \ - $(BACNET_SRC_DIR)/bacnet/datalink/cobs.c \ - $(BACNET_SRC_DIR)/bacnet/datalink/mstp.c \ - $(BACNET_SRC_DIR)/bacnet/datalink/mstptext.c \ - $(BACNET_SRC_DIR)/bacnet/datalink/crc.c - -PORT_BIP_SRC = \ - $(BACNET_PORT_DIR)/bip-init.c \ - $(BACNET_SRC_DIR)/bacnet/datalink/bvlc.c \ - $(BACNET_SRC_DIR)/bacnet/basic/bbmd/h_bbmd.c +SRC = main.c # WARNINGS, DEBUGGING, OPTIMIZATION are defined in common apps Makefile # BACNET_DEFINES is defined in common apps Makefile # put all the flags together INCLUDES = -I$(BACNET_SRC_DIR) -I$(BACNET_PORT_DIR) -CFLAGS += $(WARNINGS) $(DEBUGGING) $(OPTIMIZATION) $(BACNET_DEFINES) $(INCLUDES) -LFLAGS += -Wl,$(SYSTEM_LIB) -ifneq (${BACNET_LIB},) -LFLAGS += -Wl,$(BACNET_LIB) -endif -# GCC dead code removal -CFLAGS += -ffunction-sections -fdata-sections -LFLAGS += -Wl,--gc-sections - -BACNET_SRC = \ - $(wildcard $(BACNET_SRC_DIR)/bacnet/*.c) \ - $(wildcard $(BACNET_SRC_DIR)/bacnet/basic/*.c) \ - $(wildcard $(BACNET_SRC_DIR)/bacnet/basic/binding/*.c) \ - $(wildcard $(BACNET_SRC_DIR)/bacnet/basic/service/*.c) \ - $(wildcard $(BACNET_SRC_DIR)/bacnet/basic/sys/*.c) \ - $(BACNET_SRC_DIR)/bacnet/basic/npdu/h_routed_npdu.c \ - $(BACNET_SRC_DIR)/bacnet/basic/npdu/s_router.c \ - $(BACNET_SRC_DIR)/bacnet/basic/tsm/tsm.c - -SRCS = ${SRC} ${BACNET_SRC} ${PORT_MSTP_SRC} ${PORT_BIP_SRC} - +SRCS = ${SRC} OBJS += ${SRCS:.c=.o} .PHONY: all -all: Makefile ${TARGET_BIN} +all: ${BACNET_LIB_TARGET} Makefile ${TARGET_BIN} ${TARGET_BIN}: ${OBJS} ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@ diff --git a/ports/win32/bip6.c b/ports/win32/bip6.c index 90f113fd..097232ab 100644 --- a/ports/win32/bip6.c +++ b/ports/win32/bip6.c @@ -53,17 +53,6 @@ static BACNET_IP6_ADDRESS BIP6_Broadcast_Addr; /* enable debugging */ static bool BIP6_Debug = false; -#if PRINT_ENABLED -#include -#include -#define PRINTF(...) \ - if (BIP6_Debug) { \ - fprintf(stderr,__VA_ARGS__); \ - fflush(stderr); \ - } -#else -#define PRINTF(...) -#endif /** * @brief Print the IPv6 address with debug info @@ -73,14 +62,15 @@ static bool BIP6_Debug = false; static void debug_print_ipv6(const char *str, const struct in6_addr *addr) { #if PRINT_ENABLED - char addstr[40] = {}; - BACNET_IP6_ADDRESS bip6_addr = {}; + char addstr[40] = { 0 }; + BACNET_IP6_ADDRESS bip6_addr = { 0 }; if (str && addr) { memcpy(&bip6_addr.address[0], &addr->s6_addr[0], IP6_ADDRESS_MAX); - bvlc6_address_to_ascii(&bip6_addr, addstr, - sizeof(addstr)); - PRINTF("BIP6: %s %s\n", str, addstr); + bvlc6_address_to_ascii(&bip6_addr, addstr, sizeof(addstr)); + if (BIP6_Debug) { + debug_fprintf(stdout, "BIP6: %s %s\n", str, addstr); + } } #endif } @@ -97,11 +87,12 @@ static LPSTR PrintError(int ErrorCode) { static char Message[1024]; - // If this program was multithreaded, we'd want to use - // FORMAT_MESSAGE_ALLOCATE_BUFFER instead of a static buffer here. - // (And of course, free the buffer when we were done with it) + /* If this program was multithreaded, we'd want to use + FORMAT_MESSAGE_ALLOCATE_BUFFER instead of a static buffer here. + (And of course, free the buffer when we were done with it) */ - FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | + FormatMessage( + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK, NULL, ErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)Message, 1024, NULL); @@ -114,132 +105,147 @@ void bip6_set_interface(char *ifname) int i, RetVal; struct addrinfo Hints, *AddrInfo, *AI; struct sockaddr_in6 *sin; - struct in6_addr broadcast_address = {}; - struct ipv6_mreq join_request = {}; - SOCKET ServSock[FD_SETSIZE] = {}; + struct in6_addr broadcast_address = { 0 }; + struct ipv6_mreq join_request = { 0 }; + SOCKET ServSock[FD_SETSIZE] = { 0 }; char port[6] = ""; int sockopt = 0; - // By setting the AI_PASSIVE flag in the hints to getaddrinfo, we're - // indicating that we intend to use the resulting address(es) to bind - // to a socket(s) for accepting incoming connections. This means that - // when the Address parameter is NULL, getaddrinfo will return one - // entry per allowed protocol family containing the unspecified address - // for that family. - // + /* By setting the AI_PASSIVE flag in the hints to getaddrinfo, we're + indicating that we intend to use the resulting address(es) to bind + to a socket(s) for accepting incoming connections. This means that + when the Address parameter is NULL, getaddrinfo will return one + entry per allowed protocol family containing the unspecified address + for that family. */ memset(&Hints, 0, sizeof(Hints)); Hints.ai_family = AF_INET6; Hints.ai_socktype = SOCK_DGRAM; Hints.ai_protocol = IPPROTO_UDP; Hints.ai_flags = AI_NUMERICHOST | AI_PASSIVE; snprintf(port, sizeof(port), "%u", BIP6_Addr.port); - PRINTF("BIP6: seeking IPv6 address %s port %s...\n", ifname, port); + if (BIP6_Debug) { + debug_fprintf( + stderr, "BIP6: seeking IPv6 address %s port %s...\n", ifname, port); + } RetVal = getaddrinfo(ifname, &port[0], &Hints, &AddrInfo); if (RetVal != 0) { - fprintf(stderr, "BIP6: getaddrinfo failed with error %d: %s\n", RetVal, + fprintf( + stderr, "BIP6: getaddrinfo failed with error %d: %s\n", RetVal, gai_strerror(RetVal)); WSACleanup(); return; } - PRINTF("BIP6: getaddrinfo() succeeded!\n"); - // - // Find the first matching address getaddrinfo returned so that - // we can create a new socket and bind that address to it, - // and create a queue to listen on. - // + if (BIP6_Debug) { + debug_fprintf(stderr, "BIP6: getaddrinfo() succeeded!\n"); + } + /* Find the first matching address getaddrinfo returned so that + we can create a new socket and bind that address to it, + and create a queue to listen on. */ for (i = 0, AI = AddrInfo; AI != NULL; AI = AI->ai_next) { - // Highly unlikely, but check anyway. + /* Highly unlikely, but check anyway. */ if (i == FD_SETSIZE) { - fprintf(stderr, + fprintf( + stderr, "BIP6: getaddrinfo returned more addresses than we could " "use.\n"); break; } - // only support AF_INET6. + /* only support AF_INET6. */ if (AI->ai_family != AF_INET6) { continue; } - // only support SOCK_DGRAM. + /* only support SOCK_DGRAM. */ if (AI->ai_socktype != SOCK_DGRAM) { continue; } - // only support IPPROTO_UDP. + /* only support IPPROTO_UDP. */ if (AI->ai_protocol != IPPROTO_UDP) { continue; } BIP6_Socket = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); if (BIP6_Socket == INVALID_SOCKET) { - fprintf(stderr, "BIP6: socket() failed with error %d: %s\n", + fprintf( + stderr, "BIP6: socket() failed with error %d: %s\n", WSAGetLastError(), PrintError(WSAGetLastError())); continue; } - if ((AI->ai_family == AF_INET6) && IN6_IS_ADDR_LINKLOCAL(AI->ai_addr) && - (((SOCKADDR_IN6 *)(AI->ai_addr))->sin6_scope_id == 0)) { + sin = (struct sockaddr_in6 *)AI->ai_addr; + if ((AI->ai_family == AF_INET6) && + IN6_IS_ADDR_LINKLOCAL(&sin->sin6_addr) && + (sin->sin6_scope_id == 0)) { fprintf( stderr, "BIP6: IPv6 link local addresses needs a scope ID!\n"); } /* Allow us to use the same socket for sending and receiving */ /* This makes sure that the src port is correct when sending */ sockopt = 1; - RetVal = setsockopt(BIP6_Socket, SOL_SOCKET, SO_REUSEADDR, - (char *)&sockopt, sizeof(sockopt)); + RetVal = setsockopt( + BIP6_Socket, SOL_SOCKET, SO_REUSEADDR, (char *)&sockopt, + sizeof(sockopt)); if (RetVal < 0) { closesocket(BIP6_Socket); BIP6_Socket = INVALID_SOCKET; - fprintf(stderr, + fprintf( + stderr, "BIP6: setsockopt(SO_REUSEADDR) failed with error %d: %s\n", WSAGetLastError(), PrintError(WSAGetLastError())); continue; } /* allow us to send a broadcast */ - RetVal = setsockopt(BIP6_Socket, SOL_SOCKET, SO_BROADCAST, - (char *)&sockopt, sizeof(sockopt)); + RetVal = setsockopt( + BIP6_Socket, SOL_SOCKET, SO_BROADCAST, (char *)&sockopt, + sizeof(sockopt)); if (RetVal < 0) { closesocket(BIP6_Socket); BIP6_Socket = INVALID_SOCKET; - fprintf(stderr, + fprintf( + stderr, "BIP6: setsockopt(SO_BROADCAST) failed " "with error %d: %s\n", WSAGetLastError(), PrintError(WSAGetLastError())); continue; } /* subscribe to a multicast address */ - memcpy(&broadcast_address.s6_addr[0], &BIP6_Broadcast_Addr.address[0], + memcpy( + &broadcast_address.s6_addr[0], &BIP6_Broadcast_Addr.address[0], IP6_ADDRESS_MAX); - memcpy(&join_request.ipv6mr_multiaddr, &broadcast_address, + memcpy( + &join_request.ipv6mr_multiaddr, &broadcast_address, sizeof(struct in6_addr)); /* Let system not choose the interface */ BIP6_Socket_Scope_Id = if_nametoindex(ifname); join_request.ipv6mr_interface = BIP6_Socket_Scope_Id; - RetVal = setsockopt(BIP6_Socket, IPPROTO_IPV6, IPV6_JOIN_GROUP, - (char *)&join_request, sizeof(join_request)); + RetVal = setsockopt( + BIP6_Socket, IPPROTO_IPV6, IPV6_JOIN_GROUP, (char *)&join_request, + sizeof(join_request)); if (RetVal < 0) { - fprintf(stderr, + fprintf( + stderr, "BIP6: setsockopt(IPV6_JOIN_GROUP) failed " "with error %d: %s\n", WSAGetLastError(), PrintError(WSAGetLastError())); } - // - // bind() associates a local address and port combination - // with the socket just created. This is most useful when - // the application is a server that has a well-known port - // that clients know about in advance. - // + /* bind() associates a local address and port combination + with the socket just created. This is most useful when + the application is a server that has a well-known port + that clients know about in advance. */ if (bind(BIP6_Socket, AI->ai_addr, AI->ai_addrlen) == SOCKET_ERROR) { - fprintf(stderr, "BIP6: bind() failed with error %d: %s\n", + fprintf( + stderr, "BIP6: bind() failed with error %d: %s\n", WSAGetLastError(), PrintError(WSAGetLastError())); closesocket(ServSock[i]); continue; } else { sin = (struct sockaddr_in6 *)AI->ai_addr; - bvlc6_address_set(&BIP6_Addr, ntohs(sin->sin6_addr.s6_addr16[0]), - ntohs(sin->sin6_addr.s6_addr16[1]), - ntohs(sin->sin6_addr.s6_addr16[2]), - ntohs(sin->sin6_addr.s6_addr16[3]), - ntohs(sin->sin6_addr.s6_addr16[4]), - ntohs(sin->sin6_addr.s6_addr16[5]), - ntohs(sin->sin6_addr.s6_addr16[6]), - ntohs(sin->sin6_addr.s6_addr16[7])); + bvlc6_address_set( + &BIP6_Addr, ntohs(sin->sin6_addr.u.Word[0]), + ntohs(sin->sin6_addr.u.Word[1]), + ntohs(sin->sin6_addr.u.Word[2]), + ntohs(sin->sin6_addr.u.Word[3]), + ntohs(sin->sin6_addr.u.Word[4]), + ntohs(sin->sin6_addr.u.Word[5]), + ntohs(sin->sin6_addr.u.Word[6]), + ntohs(sin->sin6_addr.u.Word[7])); debug_print_ipv6("bind() succeeded!", &sin->sin6_addr); /* https://msdn.microsoft.com/en-us/library/windows/desktop/ms740496(v=vs.85).aspx */ @@ -380,22 +386,24 @@ int bip6_send_mpdu(BACNET_IP6_ADDRESS *dest, uint8_t *mtu, uint16_t mtu_len) } /* load destination IP address */ bvlc_dest.sin6_family = AF_INET6; - bvlc6_address_get(dest, &addr16[0], &addr16[1], &addr16[2], &addr16[3], - &addr16[4], &addr16[5], &addr16[6], &addr16[7]); - bvlc_dest.sin6_addr.s6_addr16[0] = htons(addr16[0]); - bvlc_dest.sin6_addr.s6_addr16[1] = htons(addr16[1]); - bvlc_dest.sin6_addr.s6_addr16[2] = htons(addr16[2]); - bvlc_dest.sin6_addr.s6_addr16[3] = htons(addr16[3]); - bvlc_dest.sin6_addr.s6_addr16[4] = htons(addr16[4]); - bvlc_dest.sin6_addr.s6_addr16[5] = htons(addr16[5]); - bvlc_dest.sin6_addr.s6_addr16[6] = htons(addr16[6]); - bvlc_dest.sin6_addr.s6_addr16[7] = htons(addr16[7]); + bvlc6_address_get( + dest, &addr16[0], &addr16[1], &addr16[2], &addr16[3], &addr16[4], + &addr16[5], &addr16[6], &addr16[7]); + bvlc_dest.sin6_addr.u.Word[0] = htons(addr16[0]); + bvlc_dest.sin6_addr.u.Word[1] = htons(addr16[1]); + bvlc_dest.sin6_addr.u.Word[2] = htons(addr16[2]); + bvlc_dest.sin6_addr.u.Word[3] = htons(addr16[3]); + bvlc_dest.sin6_addr.u.Word[4] = htons(addr16[4]); + bvlc_dest.sin6_addr.u.Word[5] = htons(addr16[5]); + bvlc_dest.sin6_addr.u.Word[6] = htons(addr16[6]); + bvlc_dest.sin6_addr.u.Word[7] = htons(addr16[7]); bvlc_dest.sin6_port = htons(dest->port); bvlc_dest.sin6_scope_id = BIP6_Socket_Scope_Id; debug_print_ipv6("Sending MPDU->", &bvlc_dest.sin6_addr); /* Send the packet */ - return sendto(BIP6_Socket, (char *)mtu, mtu_len, 0, - (struct sockaddr *)&bvlc_dest, sizeof(bvlc_dest)); + return sendto( + BIP6_Socket, (char *)mtu, mtu_len, 0, (struct sockaddr *)&bvlc_dest, + sizeof(bvlc_dest)); } /** @@ -410,7 +418,8 @@ int bip6_send_mpdu(BACNET_IP6_ADDRESS *dest, uint8_t *mtu, uint16_t mtu_len) * @return Upon successful completion, returns the number of bytes sent. * Otherwise, -1 shall be returned and errno set to indicate the error. */ -int bip6_send_pdu(BACNET_ADDRESS *dest, +int bip6_send_pdu( + BACNET_ADDRESS *dest, BACNET_NPDU_DATA *npdu_data, uint8_t *pdu, unsigned pdu_len) @@ -436,7 +445,7 @@ uint16_t bip6_receive( int max = 0; struct timeval select_timeout; struct sockaddr_in6 sin = { 0 }; - BACNET_IP6_ADDRESS addr = { { 0 } }; + BACNET_IP6_ADDRESS addr = { 0 }; socklen_t sin_len = sizeof(sin); int received_bytes = 0; int offset = 0; @@ -462,8 +471,9 @@ uint16_t bip6_receive( max = BIP6_Socket; /* see if there is a packet for us */ if (select(max + 1, &read_fds, NULL, NULL, &select_timeout) > 0) { - received_bytes = recvfrom(BIP6_Socket, (char *)&npdu[0], max_npdu, 0, - (struct sockaddr *)&sin, &sin_len); + received_bytes = recvfrom( + BIP6_Socket, (char *)&npdu[0], max_npdu, 0, (struct sockaddr *)&sin, + &sin_len); } else { return 0; } @@ -537,9 +547,10 @@ bool bip6_init(char *ifname) WSADATA wd; int RetVal; - // Ask for Winsock version 2.2. + /* Ask for Winsock version 2.2. */ if ((RetVal = WSAStartup(MAKEWORD(2, 2), &wd)) != 0) { - fprintf(stderr, "BIP6: WSAStartup failed with error %d: %s\n", RetVal, + fprintf( + stderr, "BIP6: WSAStartup failed with error %d: %s\n", RetVal, PrintError(RetVal)); WSACleanup(); exit(1); @@ -547,11 +558,15 @@ bool bip6_init(char *ifname) if (BIP6_Addr.port == 0) { bip6_set_port(0xBAC0U); } - PRINTF("BIP6: IPv6 UDP port: 0x%04X\n", BIP6_Addr.port); + if (BIP6_Debug) { + debug_fprintf( + stderr, "BIP6: IPv6 UDP port: 0x%04X\n", (unsigned)BIP6_Addr.port); + } bip6_set_interface(ifname); if (BIP6_Broadcast_Addr.address[0] == 0) { - bvlc6_address_set(&BIP6_Broadcast_Addr, BIP6_MULTICAST_LINK_LOCAL, 0, 0, - 0, 0, 0, 0, BIP6_MULTICAST_GROUP_ID); + bvlc6_address_set( + &BIP6_Broadcast_Addr, BIP6_MULTICAST_LINK_LOCAL, 0, 0, 0, 0, 0, 0, + BIP6_MULTICAST_GROUP_ID); } if (BIP6_Socket == INVALID_SOCKET) { fprintf(stderr, "BIP6: Fatal error: unable to serve on any address.\n"); diff --git a/src/bacnet/basic/bbmd6/vmac.c b/src/bacnet/basic/bbmd6/vmac.c index b409304c..1bdd40cc 100644 --- a/src/bacnet/basic/bbmd6/vmac.c +++ b/src/bacnet/basic/bbmd6/vmac.c @@ -37,27 +37,13 @@ #include #include #include "bacnet/bacdef.h" +#include "bacnet/basic/sys/debug.h" #include "bacnet/basic/sys/keylist.h" /* me! */ #include "bacnet/basic/bbmd6/vmac.h" /* enable debugging */ static bool VMAC_Debug = false; -#if PRINT_ENABLED -#include -#include -#define PRINTF(...) \ - if (VMAC_Debug) { \ - fprintf(stderr, __VA_ARGS__); \ - fflush(stderr); \ - } -#else -#define PRINTF(...) - -#if !defined UNUSED -#define UNUSED(x) ((void)(x)) -#endif -#endif // PRINT_ENABLED /** * @brief Enable debugging if print is enabled @@ -115,7 +101,10 @@ bool VMAC_Add(uint32_t device_id, struct vmac_data *src) index = Keylist_Data_Add(VMAC_List, device_id, pVMAC); if (index >= 0) { status = true; - PRINTF("VMAC %u added.\n", (unsigned int)device_id); + if (VMAC_Debug) { + debug_fprintf( + stderr, "VMAC %u added.\n", (unsigned int)device_id); + } } } } @@ -261,20 +250,21 @@ void VMAC_Cleanup(void) if (VMAC_List) { do { -#if PRINT_ENABLED uint32_t device_id; - Keylist_Index_Key(VMAC_List, index, &device_id); -#endif + if (VMAC_Debug) { + Keylist_Index_Key(VMAC_List, index, &device_id); + } pVMAC = Keylist_Data_Delete_By_Index(VMAC_List, index); if (pVMAC) { -#if PRINT_ENABLED - PRINTF("VMAC List: %lu [", (unsigned long)device_id); - /* print the MAC */ - for (i = 0; i < pVMAC->mac_len; i++) { - PRINTF("%02X", pVMAC->mac[i]); + if (VMAC_Debug) { + debug_fprintf( + stderr, "VMAC List: %lu [", (unsigned long)device_id); + /* print the MAC */ + for (i = 0; i < pVMAC->mac_len; i++) { + debug_fprintf(stderr, "%02X", pVMAC->mac[i]); + } + debug_fprintf(stderr, "]\n"); } - PRINTF("]\n"); -#endif free(pVMAC); } } while (pVMAC); @@ -291,6 +281,6 @@ void VMAC_Init(void) VMAC_List = Keylist_Create(); if (VMAC_List) { atexit(VMAC_Cleanup); - PRINTF("VMAC List initialized.\n"); + debug_fprintf(stderr, "VMAC List initialized.\n"); } } diff --git a/src/bacnet/datalink/bvlc6.c b/src/bacnet/datalink/bvlc6.c index c1802d06..5a22f4d7 100644 --- a/src/bacnet/datalink/bvlc6.c +++ b/src/bacnet/datalink/bvlc6.c @@ -1466,13 +1466,15 @@ int bvlc6_decode_secure_bvll(uint8_t *pdu, int bytes_consumed = 0; uint16_t i = 0; - if (pdu && sbuf) { + if (pdu) { if (sbuf_len) { *sbuf_len = pdu_len; } - if (pdu_len) { + if (pdu_len && sbuf && sbuf_size) { for (i = 0; i < pdu_len; i++) { - sbuf[i] = pdu[i]; + if (i < sbuf_size) { + sbuf[i] = pdu[i]; + } } } bytes_consumed = (int)pdu_len; diff --git a/test/bacnet/basic/bbmd6/CMakeLists.txt b/test/bacnet/basic/bbmd6/CMakeLists.txt index 812352bc..92d8b452 100644 --- a/test/bacnet/basic/bbmd6/CMakeLists.txt +++ b/test/bacnet/basic/bbmd6/CMakeLists.txt @@ -39,6 +39,7 @@ add_executable(${PROJECT_NAME} ${SRC_DIR}/bacnet/iam.c ${SRC_DIR}/bacnet/npdu.c ${SRC_DIR}/bacnet/basic/sys/bigend.c + ${SRC_DIR}/bacnet/basic/sys/debug.c ${SRC_DIR}/bacnet/basic/sys/keylist.c ${SRC_DIR}/bacnet/basic/bbmd6/h_bbmd6.c ${SRC_DIR}/bacnet/basic/bbmd6/vmac.c