win32: fix ethernet and bip6 (#774)
Switch from WinPcap ton npcap. Include npcap sdk in cmake add libs for ipv6 in cmake fix ethernet uninitialized var
This commit is contained in:
+31
-3
@@ -673,8 +673,8 @@ elseif(WIN32)
|
|||||||
|
|
||||||
target_link_libraries(${PROJECT_NAME} PRIVATE
|
target_link_libraries(${PROJECT_NAME} PRIVATE
|
||||||
winmm
|
winmm
|
||||||
$<$<BOOL:${BACDL_BIP}>:ws2_32>
|
$<$<BOOL:${BACDL_BIP} OR BOOL:${BACDL_BIP6}>:ws2_32>
|
||||||
$<$<BOOL:${BACDL_BIP}>:iphlpapi>)
|
$<$<BOOL:${BACDL_BIP} OR BOOL:${BACDL_BIP6}>:iphlpapi>)
|
||||||
|
|
||||||
target_sources(${PROJECT_NAME} PRIVATE
|
target_sources(${PROJECT_NAME} PRIVATE
|
||||||
ports/win32/bacport.h
|
ports/win32/bacport.h
|
||||||
@@ -683,10 +683,38 @@ elseif(WIN32)
|
|||||||
ports/win32/datetime-init.c
|
ports/win32/datetime-init.c
|
||||||
$<$<BOOL:${BACDL_MSTP}>:ports/win32/dlmstp.c>
|
$<$<BOOL:${BACDL_MSTP}>:ports/win32/dlmstp.c>
|
||||||
# ports/win32/dlmstp-mm.c
|
# ports/win32/dlmstp-mm.c
|
||||||
$<$<BOOL:${BACDL_ETHERNET}>:ports/win32/ethernet.c>
|
|
||||||
ports/win32/mstimer-init.c
|
ports/win32/mstimer-init.c
|
||||||
$<$<BOOL:${BACDL_MSTP}>:ports/win32/rs485.c>
|
$<$<BOOL:${BACDL_MSTP}>:ports/win32/rs485.c>
|
||||||
$<$<BOOL:${BACDL_MSTP}>:ports/win32/rs485.h>)
|
$<$<BOOL:${BACDL_MSTP}>:ports/win32/rs485.h>)
|
||||||
|
|
||||||
|
if(BACDL_ETHERNET)
|
||||||
|
include(ExternalProject)
|
||||||
|
set(PCAP_LIB_DIR ${CMAKE_CURRENT_BINARY_DIR}/npcap/Lib/x64)
|
||||||
|
set(PCAP_LIB_WPCAP ${PCAP_LIB_DIR}/wpcap.lib)
|
||||||
|
set(PCAP_LIB_PACKET ${PCAP_LIB_DIR}/Packet.lib)
|
||||||
|
set(PCAP_INCLUDE ${CMAKE_CURRENT_BINARY_DIR}/npcap/Include)
|
||||||
|
message(STATUS "BACNET: npcap Include:..................\"${PCAP_INCLUDE}\"")
|
||||||
|
message(STATUS "BACNET: npcap Lib wpcap:................\"${PCAP_LIB_WPCAP}\"")
|
||||||
|
message(STATUS "BACNET: npcap Lib Packet:...............\"${PCAP_LIB_PACKET}\"")
|
||||||
|
ExternalProject_Add(npcap
|
||||||
|
URL https://npcap.com/dist/npcap-sdk-1.13.zip
|
||||||
|
URL_HASH SHA1=8d5bb6f3adb813374402344a8d2a12b9cb725197
|
||||||
|
DOWNLOAD_EXTRACT_TIMESTAMP true
|
||||||
|
SOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/npcap
|
||||||
|
BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/npcap/Lib/x64
|
||||||
|
UPDATE_COMMAND ""
|
||||||
|
CONFIGURE_COMMAND ""
|
||||||
|
BUILD_COMMAND ""
|
||||||
|
INSTALL_COMMAND ""
|
||||||
|
TEST_COMMAND ""
|
||||||
|
BUILD_BYPRODUCTS ${PCAP_LIB_WPCAP}
|
||||||
|
BUILD_BYPRODUCTS ${PCAP_LIB_PACKET})
|
||||||
|
include_directories(${PCAP_INCLUDE})
|
||||||
|
target_link_libraries(${PROJECT_NAME} PRIVATE ${PCAP_LIB_WPCAP})
|
||||||
|
target_link_libraries(${PROJECT_NAME} PRIVATE ${PCAP_LIB_PACKET})
|
||||||
|
target_sources(${PROJECT_NAME} PRIVATE
|
||||||
|
ports/win32/ethernet.c)
|
||||||
|
endif()
|
||||||
elseif(APPLE)
|
elseif(APPLE)
|
||||||
message(STATUS "BACNET: building for APPLE")
|
message(STATUS "BACNET: building for APPLE")
|
||||||
set(BACNET_PORT_DIRECTORY_PATH ${CMAKE_CURRENT_LIST_DIR}/ports/bsd)
|
set(BACNET_PORT_DIRECTORY_PATH ${CMAKE_CURRENT_LIST_DIR}/ports/bsd)
|
||||||
|
|||||||
+3
-3
@@ -393,9 +393,9 @@ int bip6_send_mpdu(
|
|||||||
* Otherwise, -1 shall be returned and errno set to indicate the error.
|
* Otherwise, -1 shall be returned and errno set to indicate the error.
|
||||||
*/
|
*/
|
||||||
int bip6_send_pdu(
|
int bip6_send_pdu(
|
||||||
const BACNET_ADDRESS *dest,
|
BACNET_ADDRESS *dest,
|
||||||
const BACNET_NPDU_DATA *npdu_data,
|
BACNET_NPDU_DATA *npdu_data,
|
||||||
const uint8_t *pdu,
|
uint8_t *pdu,
|
||||||
unsigned pdu_len)
|
unsigned pdu_len)
|
||||||
{
|
{
|
||||||
return bvlc6_send_pdu(dest, npdu_data, pdu, pdu_len);
|
return bvlc6_send_pdu(dest, npdu_data, pdu, pdu_len);
|
||||||
|
|||||||
+168
-47
@@ -15,21 +15,20 @@
|
|||||||
#include "bacnet/datalink/ethernet.h"
|
#include "bacnet/datalink/ethernet.h"
|
||||||
#include "bacnet/bacdcode.h"
|
#include "bacnet/bacdcode.h"
|
||||||
|
|
||||||
/* Uses WinPCap to access raw ethernet */
|
/* Uses Npcap to access raw ethernet */
|
||||||
/* Notes: */
|
/* Notes: */
|
||||||
/* To make ethernet.c work under win32, you have to: */
|
/* To make ethernet.c work under win32, you have to: */
|
||||||
/* 1. install winpcap 3.1 development pack; */
|
/* 1. install Npcap 1.80 installer for Windows; */
|
||||||
/* 2. install Microsoft Platform SDK Feb 2003. */
|
/* 2. install msys2 x86_64 */
|
||||||
/* 3. remove or modify functions used for log such as */
|
/* 3. remove or modify functions used for log such as */
|
||||||
/* "LogError()", "LogInfo()", which were implemented */
|
/* "LogError()", "LogInfo()", which were implemented */
|
||||||
/* as a wrapper of Log4cpp. */
|
/* as a wrapper of Log4cpp. */
|
||||||
/* -- Kevin Liao */
|
/* -- Kevin Liao */
|
||||||
|
/* -- Patrick Grimm */
|
||||||
|
|
||||||
/* includes for accessing ethernet by using winpcap */
|
/* includes for accessing ethernet by using winpcap */
|
||||||
#include "pcap.h"
|
#include "pcap.h"
|
||||||
#include "packet32.h"
|
|
||||||
#include "ntddndis.h"
|
#include "ntddndis.h"
|
||||||
#include "remote-ext.h"
|
|
||||||
|
|
||||||
/* commonly used comparison address for ethernet */
|
/* commonly used comparison address for ethernet */
|
||||||
uint8_t Ethernet_Broadcast[MAX_MAC_LEN] = {
|
uint8_t Ethernet_Broadcast[MAX_MAC_LEN] = {
|
||||||
@@ -46,14 +45,105 @@ static char pcap_errbuf[PCAP_ERRBUF_SIZE + 1];
|
|||||||
static pcap_t *pcap_eth802_fp = NULL; /* 802.2 file handle, from winpcap */
|
static pcap_t *pcap_eth802_fp = NULL; /* 802.2 file handle, from winpcap */
|
||||||
static unsigned eth_timeout = 100;
|
static unsigned eth_timeout = 100;
|
||||||
|
|
||||||
|
/* #######Begin Packet32.h copy########*/
|
||||||
|
/*!
|
||||||
|
\brief Structure containing an OID request.
|
||||||
|
|
||||||
|
It is used by the PacketRequest() function to send an OID to the interface
|
||||||
|
card driver. It can be used, for example, to retrieve the status of the error
|
||||||
|
counters on the adapter, its MAC address, the list of the multicast groups
|
||||||
|
defined on it, and so on.
|
||||||
|
*/
|
||||||
|
struct _PACKET_OID_DATA {
|
||||||
|
ULONG Oid; /* ///< OID code. See the Microsoft DDK
|
||||||
|
documentation or the file ntddndis.h
|
||||||
|
///< for a complete list of valid codes. */
|
||||||
|
ULONG Length; /* ///< Length of the data field
|
||||||
|
_Field_size_full_(Length)*/
|
||||||
|
UCHAR Data[1]; /* ///< variable-lenght field that contains the
|
||||||
|
information passed to or received
|
||||||
|
///< from the adapter.*/
|
||||||
|
};
|
||||||
|
typedef struct _PACKET_OID_DATA PACKET_OID_DATA, *PPACKET_OID_DATA;
|
||||||
|
|
||||||
|
#define MAX_LINK_NAME_LENGTH \
|
||||||
|
64 /* //< Maximum length of the devices symbolic links*/
|
||||||
|
#define ADAPTER_NAME_LENGTH \
|
||||||
|
256 + 12 /*///< Maximum length for the name of an adapter. The value is \
|
||||||
|
the same used by the IP Helper API.*/
|
||||||
|
typedef struct WAN_ADAPTER_INT
|
||||||
|
WAN_ADAPTER; /*///< Describes an opened wan (dialup, VPN...) network adapter
|
||||||
|
using the NetMon API*/
|
||||||
|
typedef WAN_ADAPTER
|
||||||
|
*PWAN_ADAPTER; /*///< Describes an opened wan (dialup, VPN...) network
|
||||||
|
adapter using the NetMon API*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Describes an opened network adapter.
|
||||||
|
|
||||||
|
This structure is the most important for the functioning of packet.dll, but
|
||||||
|
the great part of its fields should be ignored by the user, since the library
|
||||||
|
offers functions that avoid to cope with low-level parameters
|
||||||
|
*/
|
||||||
|
typedef struct _ADAPTER {
|
||||||
|
HANDLE hFile; /* ///< \internal Handle to an open instance of the
|
||||||
|
NPF driver.*/
|
||||||
|
CHAR
|
||||||
|
SymbolicLink[MAX_LINK_NAME_LENGTH]; /*///< \internal A string containing
|
||||||
|
the name of the network adapter
|
||||||
|
currently opened.*/
|
||||||
|
int NumWrites; /* ///< \internal Number of times a packets written
|
||||||
|
on this adapter will be repeated
|
||||||
|
///< on the wire.*/
|
||||||
|
HANDLE
|
||||||
|
ReadEvent; /* ///< A notification event associated with the read
|
||||||
|
calls on the adapter.
|
||||||
|
///< It can be passed to standard Win32 functions (like WaitForSingleObject
|
||||||
|
///< or WaitForMultipleObjects) to wait until the driver's buffer contains some
|
||||||
|
///< data. It is particularly useful in GUI applications that need to wait
|
||||||
|
///< concurrently on several events. The PacketSetMinToCopy()
|
||||||
|
///< function can be used to define the minimum amount of data in the kernel
|
||||||
|
buffer
|
||||||
|
///< that will cause the event to be signalled. */
|
||||||
|
|
||||||
|
UINT ReadTimeOut; /*///< \internal The amount of time PacketReceivePacket
|
||||||
|
will wait for the ReadEvent to be signalled before
|
||||||
|
issuing a ReadFile.*/
|
||||||
|
CHAR Name[ADAPTER_NAME_LENGTH];
|
||||||
|
PWAN_ADAPTER pWanAdapter;
|
||||||
|
UINT Flags; /* ///< Adapter's flags. Tell if this adapter must be
|
||||||
|
treated in a different way.*/
|
||||||
|
|
||||||
|
#ifdef HAVE_AIRPCAP_API
|
||||||
|
PAirpcapHandle AirpcapAd;
|
||||||
|
#endif /*// HAVE_AIRPCAP_API*/
|
||||||
|
} ADAPTER, *LPADAPTER;
|
||||||
|
|
||||||
|
_Ret_maybenull_ LPADAPTER PacketOpenAdapter(_In_ PCCH AdapterName);
|
||||||
|
_Success_(return) BOOLEAN PacketRequest(
|
||||||
|
_In_ LPADAPTER AdapterObject,
|
||||||
|
_In_ BOOLEAN Set,
|
||||||
|
_Inout_ PPACKET_OID_DATA OidData);
|
||||||
|
VOID PacketCloseAdapter(_In_ _Post_invalid_ LPADAPTER lpAdapter);
|
||||||
|
|
||||||
|
/* #######End Packet32.h copy##########*/
|
||||||
|
|
||||||
/* couple of external func for runtime error logging, you can simply */
|
/* couple of external func for runtime error logging, you can simply */
|
||||||
/* replace them with standard "printf(...)" */
|
/* Logging functions: Info level */
|
||||||
/* Logging extern functions: Info level */
|
void LogInfo(const char *msg)
|
||||||
extern void LogInfo(const char *msg);
|
{
|
||||||
/* Logging extern functions: Error level*/
|
fprintf(stdout, "info ethernet: %s", msg);
|
||||||
extern void LogError(const char *msg);
|
}
|
||||||
/* Logging extern functions: Debug level*/
|
/* Logging functions: Error level*/
|
||||||
extern void LogDebug(const char *msg);
|
void LogError(const char *msg)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "error ethernet: %s", msg);
|
||||||
|
}
|
||||||
|
/* Logging functions: Debug level*/
|
||||||
|
void LogDebug(const char *msg)
|
||||||
|
{
|
||||||
|
fprintf(stdout, "debug ethernet: %s", msg);
|
||||||
|
}
|
||||||
|
|
||||||
bool ethernet_valid(void)
|
bool ethernet_valid(void)
|
||||||
{
|
{
|
||||||
@@ -66,7 +156,7 @@ void ethernet_cleanup(void)
|
|||||||
pcap_close(pcap_eth802_fp);
|
pcap_close(pcap_eth802_fp);
|
||||||
pcap_eth802_fp = NULL;
|
pcap_eth802_fp = NULL;
|
||||||
}
|
}
|
||||||
LogInfo("ethernet.c: ethernet_cleanup() ok.\n");
|
LogInfo("ethernet_cleanup() ok.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ethernet_set_timeout(unsigned timeout)
|
void ethernet_set_timeout(unsigned timeout)
|
||||||
@@ -108,7 +198,9 @@ bool ethernet_init(char *if_name)
|
|||||||
BOOLEAN result;
|
BOOLEAN result;
|
||||||
CHAR str[sizeof(PACKET_OID_DATA) + 128];
|
CHAR str[sizeof(PACKET_OID_DATA) + 128];
|
||||||
int i;
|
int i;
|
||||||
char msg[200];
|
char msg[400];
|
||||||
|
int devnum;
|
||||||
|
char *device = NULL;
|
||||||
|
|
||||||
if (ethernet_valid()) {
|
if (ethernet_valid()) {
|
||||||
ethernet_cleanup();
|
ethernet_cleanup();
|
||||||
@@ -118,24 +210,42 @@ bool ethernet_init(char *if_name)
|
|||||||
* Find the interface user specified
|
* Find the interface user specified
|
||||||
*/
|
*/
|
||||||
/* Retrieve the device list */
|
/* Retrieve the device list */
|
||||||
if (pcap_findalldevs(&pcap_all_if, pcap_errbuf) == -1) {
|
if (pcap_findalldevs(&pcap_all_if, pcap_errbuf) == PCAP_ERROR) {
|
||||||
snprintf(
|
snprintf(msg, sizeof(msg), "pcap_findalldevs: %s\n", pcap_errbuf);
|
||||||
msg, sizeof(msg), "ethernet.c: error in pcap_findalldevs: %s\n",
|
|
||||||
pcap_errbuf);
|
|
||||||
LogError(msg);
|
LogError(msg);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
/* Scan the list printing every entry */
|
/* Scan the list printing every entry */
|
||||||
|
devnum = atoi(if_name);
|
||||||
|
i = 0;
|
||||||
for (dev = pcap_all_if; dev; dev = dev->next) {
|
for (dev = pcap_all_if; dev; dev = dev->next) {
|
||||||
if (strcmp(if_name, dev->name) == 0) {
|
/* struct pcap_addr *dev_addr;*/
|
||||||
break;
|
i++;
|
||||||
|
if (devnum == i) {
|
||||||
|
device = dev->name;
|
||||||
|
snprintf(msg, sizeof(msg), "interface select index: %i\n", i);
|
||||||
|
LogInfo(msg);
|
||||||
|
}
|
||||||
|
if ((dev->flags & PCAP_IF_UP) && !(dev->flags & PCAP_IF_LOOPBACK) &&
|
||||||
|
(dev->flags & PCAP_IF_RUNNING) &&
|
||||||
|
(dev->flags & PCAP_IF_CONNECTION_STATUS_CONNECTED)) {
|
||||||
|
snprintf(msg, sizeof(msg), "interface index: %i\n", i);
|
||||||
|
LogInfo(msg);
|
||||||
|
snprintf(msg, sizeof(msg), " name: %s\n", dev->name);
|
||||||
|
LogInfo(msg);
|
||||||
|
snprintf(msg, sizeof(msg), " description: %s\n", dev->description);
|
||||||
|
LogInfo(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pcap_freealldevs(pcap_all_if); /* we don't need it anymore */
|
pcap_freealldevs(pcap_all_if); /* we don't need it anymore */
|
||||||
if (dev == NULL) {
|
if (if_name == NULL) {
|
||||||
|
snprintf(msg, sizeof(msg), "interface index not set\n");
|
||||||
|
LogError(msg);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (device == NULL) {
|
||||||
snprintf(
|
snprintf(
|
||||||
msg, sizeof(msg), "ethernet.c: specified interface not found: %s\n",
|
msg, sizeof(msg), "specified interface not found: %s\n", if_name);
|
||||||
if_name);
|
|
||||||
LogError(msg);
|
LogError(msg);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -144,12 +254,11 @@ bool ethernet_init(char *if_name)
|
|||||||
* Get local MAC address
|
* Get local MAC address
|
||||||
*/
|
*/
|
||||||
ZeroMemory(str, sizeof(PACKET_OID_DATA) + 128);
|
ZeroMemory(str, sizeof(PACKET_OID_DATA) + 128);
|
||||||
lpAdapter = PacketOpenAdapter(if_name);
|
lpAdapter = PacketOpenAdapter(device);
|
||||||
if (lpAdapter == NULL) {
|
if (lpAdapter == NULL) {
|
||||||
ethernet_cleanup();
|
ethernet_cleanup();
|
||||||
snprintf(
|
snprintf(
|
||||||
msg, sizeof(msg),
|
msg, sizeof(msg), "local mac PacketOpenAdapter(\"%s\")\n", device);
|
||||||
"ethernet.c: error in PacketOpenAdapter(\"%s\")\n", if_name);
|
|
||||||
LogError(msg);
|
LogError(msg);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -160,7 +269,7 @@ bool ethernet_init(char *if_name)
|
|||||||
if (!result) {
|
if (!result) {
|
||||||
PacketCloseAdapter(lpAdapter);
|
PacketCloseAdapter(lpAdapter);
|
||||||
ethernet_cleanup();
|
ethernet_cleanup();
|
||||||
LogError("ethernet.c: error in PacketRequest()\n");
|
LogError("local mac PacketRequest()\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (i = 0; i < 6; ++i) {
|
for (i = 0; i < 6; ++i) {
|
||||||
@@ -168,16 +277,23 @@ bool ethernet_init(char *if_name)
|
|||||||
}
|
}
|
||||||
PacketCloseAdapter(lpAdapter);
|
PacketCloseAdapter(lpAdapter);
|
||||||
|
|
||||||
|
snprintf(
|
||||||
|
msg, sizeof(msg), "local mac %02x:%02x:%02x:%02x:%02x:%02x \n",
|
||||||
|
Ethernet_MAC_Address[0], Ethernet_MAC_Address[1],
|
||||||
|
Ethernet_MAC_Address[2], Ethernet_MAC_Address[3],
|
||||||
|
Ethernet_MAC_Address[4], Ethernet_MAC_Address[5]);
|
||||||
|
LogInfo(msg);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open interface for subsequent sending and receiving
|
* Open interface for subsequent sending and receiving
|
||||||
*/
|
*/
|
||||||
/* Open the output device */
|
/* Open the output device */
|
||||||
pcap_eth802_fp = pcap_open(
|
pcap_eth802_fp = pcap_open_live(
|
||||||
if_name, /* name of the device */
|
device, /* name of the device */
|
||||||
ETHERNET_MPDU_MAX, /* portion of the packet to capture */
|
ETHERNET_MPDU_MAX, /* portion of the packet to capture */
|
||||||
PCAP_OPENFLAG_PROMISCUOUS, /* promiscuous mode */
|
PCAP_OPENFLAG_PROMISCUOUS, /* promiscuous mode */
|
||||||
eth_timeout, /* read timeout */
|
eth_timeout, /* read timeout */
|
||||||
NULL, /* authentication on the remote machine */
|
/* NULL, */ /* authentication on the remote machine */
|
||||||
pcap_errbuf /* error buffer */
|
pcap_errbuf /* error buffer */
|
||||||
);
|
);
|
||||||
if (pcap_eth802_fp == NULL) {
|
if (pcap_eth802_fp == NULL) {
|
||||||
@@ -185,14 +301,14 @@ bool ethernet_init(char *if_name)
|
|||||||
ethernet_cleanup();
|
ethernet_cleanup();
|
||||||
snprintf(
|
snprintf(
|
||||||
msg, sizeof(msg),
|
msg, sizeof(msg),
|
||||||
"ethernet.c: unable to open the adapter. %s is not supported by "
|
"unable to open the adapter. %s is not supported by "
|
||||||
"WinPcap\n",
|
"Npcap\n",
|
||||||
if_name);
|
device);
|
||||||
LogError(msg);
|
LogError(msg);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
LogInfo("ethernet.c: ethernet_init() ok.\n");
|
LogInfo("ethernet_init() ok.\n");
|
||||||
|
|
||||||
atexit(ethernet_cleanup);
|
atexit(ethernet_cleanup);
|
||||||
|
|
||||||
@@ -201,21 +317,21 @@ bool ethernet_init(char *if_name)
|
|||||||
|
|
||||||
/* function to send a packet out the 802.2 socket */
|
/* function to send a packet out the 802.2 socket */
|
||||||
/* returns bytes sent success, negative on failure */
|
/* returns bytes sent success, negative on failure */
|
||||||
int ethernet_send(
|
int ethernet_send_dst(
|
||||||
BACNET_ADDRESS *dest, /* destination address */
|
BACNET_ADDRESS *dest, /* destination address */
|
||||||
BACNET_ADDRESS *src, /* source address */
|
BACNET_ADDRESS *src, /* source address */
|
||||||
uint8_t *pdu, /* any data to be sent - may be null */
|
uint8_t *pdu, /* any data to be sent - may be null */
|
||||||
unsigned pdu_len /* number of bytes of data */
|
unsigned pdu_len /* number of bytes of data */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
int bytes = 0;
|
/* int bytes = 0; */
|
||||||
uint8_t mtu[ETHERNET_MPDU_MAX] = { 0 };
|
uint8_t mtu[ETHERNET_MPDU_MAX] = { 0 };
|
||||||
int mtu_len = 0;
|
int mtu_len = 0;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
/* don't waste time if the socket is not valid */
|
/* don't waste time if the socket is not valid */
|
||||||
if (!ethernet_valid()) {
|
if (!ethernet_valid()) {
|
||||||
LogError("ethernet.c: invalid 802.2 ethernet interface descriptor!\n");
|
LogError("invalid 802.2 ethernet interface descriptor!\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
/* load destination ethernet MAC address */
|
/* load destination ethernet MAC address */
|
||||||
@@ -225,7 +341,7 @@ int ethernet_send(
|
|||||||
mtu_len++;
|
mtu_len++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LogError("ethernet.c: invalid destination MAC address!\n");
|
LogError("invalid destination MAC address!\n");
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,11 +352,11 @@ int ethernet_send(
|
|||||||
mtu_len++;
|
mtu_len++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LogError("ethernet.c: invalid source MAC address!\n");
|
LogError("invalid source MAC address!\n");
|
||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
if ((14 + 3 + pdu_len) > ETHERNET_MPDU_MAX) {
|
if ((14 + 3 + pdu_len) > ETHERNET_MPDU_MAX) {
|
||||||
LogError("ethernet.c: PDU is too big to send!\n");
|
LogError("PDU is too big to send!\n");
|
||||||
return -4;
|
return -4;
|
||||||
}
|
}
|
||||||
/* packet length */
|
/* packet length */
|
||||||
@@ -257,7 +373,7 @@ int ethernet_send(
|
|||||||
/* did it get sent? */
|
/* did it get sent? */
|
||||||
char msg[200];
|
char msg[200];
|
||||||
snprintf(
|
snprintf(
|
||||||
msg, sizeof(msg), "ethernet.c: error sending packet: %s\n",
|
msg, sizeof(msg), "error sending packet: %s\n",
|
||||||
pcap_geterr(pcap_eth802_fp));
|
pcap_geterr(pcap_eth802_fp));
|
||||||
LogError(msg);
|
LogError(msg);
|
||||||
return -5;
|
return -5;
|
||||||
@@ -270,12 +386,14 @@ int ethernet_send(
|
|||||||
/* returns number of bytes sent on success, negative on failure */
|
/* returns number of bytes sent on success, negative on failure */
|
||||||
int ethernet_send_pdu(
|
int ethernet_send_pdu(
|
||||||
BACNET_ADDRESS *dest, /* destination address */
|
BACNET_ADDRESS *dest, /* destination address */
|
||||||
|
BACNET_NPDU_DATA *npdu_data, /* network information */
|
||||||
uint8_t *pdu, /* any data to be sent - may be null */
|
uint8_t *pdu, /* any data to be sent - may be null */
|
||||||
unsigned pdu_len /* number of bytes of data */
|
unsigned pdu_len /* number of bytes of data */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
int i = 0; /* counter */
|
int i = 0; /* counter */
|
||||||
BACNET_ADDRESS src = { 0 }; /* source address */
|
BACNET_ADDRESS src = { 0 }; /* source address */
|
||||||
|
(void)npdu_data;
|
||||||
|
|
||||||
for (i = 0; i < 6; i++) {
|
for (i = 0; i < 6; i++) {
|
||||||
src.mac[i] = Ethernet_MAC_Address[i];
|
src.mac[i] = Ethernet_MAC_Address[i];
|
||||||
@@ -283,7 +401,7 @@ int ethernet_send_pdu(
|
|||||||
}
|
}
|
||||||
/* function to send a packet out the 802.2 socket */
|
/* function to send a packet out the 802.2 socket */
|
||||||
/* returns 1 on success, 0 on failure */
|
/* returns 1 on success, 0 on failure */
|
||||||
return ethernet_send(
|
return ethernet_send_dst(
|
||||||
dest, /* destination address */
|
dest, /* destination address */
|
||||||
&src, /* source address */
|
&src, /* source address */
|
||||||
pdu, /* any data to be sent - may be null */
|
pdu, /* any data to be sent - may be null */
|
||||||
@@ -303,12 +421,14 @@ uint16_t ethernet_receive(
|
|||||||
{
|
{
|
||||||
struct pcap_pkthdr *header;
|
struct pcap_pkthdr *header;
|
||||||
int res;
|
int res;
|
||||||
u_char *pkt_data;
|
const u_char *pkt_data;
|
||||||
uint16_t pdu_len = 0; /* return value */
|
uint16_t pdu_len = 0; /* return value */
|
||||||
|
|
||||||
|
/* unused ? */
|
||||||
|
(void)timeout;
|
||||||
/* Make sure the socket is open */
|
/* Make sure the socket is open */
|
||||||
if (!ethernet_valid()) {
|
if (!ethernet_valid()) {
|
||||||
LogError("ethernet.c: invalid 802.2 ethernet interface descriptor!\n");
|
LogError("invalid 802.2 ethernet interface descriptor!\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -317,8 +437,9 @@ uint16_t ethernet_receive(
|
|||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
char msg[200];
|
char msg[200];
|
||||||
snprintf(
|
snprintf(
|
||||||
msg, sizeof(), "ethernet.c: error in receiving packet: %s\n",
|
msg, sizeof(msg), "error in receiving packet: %s\n",
|
||||||
pcap_geterr(pcap_eth802_fp));
|
pcap_geterr(pcap_eth802_fp));
|
||||||
|
LogError(msg);
|
||||||
return 0;
|
return 0;
|
||||||
} else if (res == 0) {
|
} else if (res == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -330,7 +451,7 @@ uint16_t ethernet_receive(
|
|||||||
|
|
||||||
/* the signature of an 802.2 BACnet packet */
|
/* the signature of an 802.2 BACnet packet */
|
||||||
if ((pkt_data[14] != 0x82) && (pkt_data[15] != 0x82)) {
|
if ((pkt_data[14] != 0x82) && (pkt_data[15] != 0x82)) {
|
||||||
/*eth_log_error("ethernet.c: Non-BACnet packet\n"); */
|
/*LogError("ethernet.c: Non-BACnet packet\n"); */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* copy the source address */
|
/* copy the source address */
|
||||||
@@ -341,7 +462,7 @@ uint16_t ethernet_receive(
|
|||||||
/* the Ethernet card is in promiscious mode */
|
/* the Ethernet card is in promiscious mode */
|
||||||
if ((memcmp(&pkt_data[0], Ethernet_MAC_Address, 6) != 0) &&
|
if ((memcmp(&pkt_data[0], Ethernet_MAC_Address, 6) != 0) &&
|
||||||
(memcmp(&pkt_data[0], Ethernet_Broadcast, 6) != 0)) {
|
(memcmp(&pkt_data[0], Ethernet_Broadcast, 6) != 0)) {
|
||||||
/*eth_log_error( "ethernet.c: This packet isn't for us\n"); */
|
/*LogError( "ethernet.c: This packet isn't for us\n"); */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user