Fix point-to-point VPN tunnel sockets for BACnet/IP by using IFF_POINTTOPOINT flag when getting the broadcast address. (#1066)
This commit is contained in:
+40
-10
@@ -32,6 +32,8 @@ static struct in_addr BIP_Broadcast_Addr;
|
|||||||
/* broadcast binding mechanism */
|
/* broadcast binding mechanism */
|
||||||
static bool BIP_Broadcast_Binding_Address_Override;
|
static bool BIP_Broadcast_Binding_Address_Override;
|
||||||
static struct in_addr BIP_Broadcast_Binding_Address;
|
static struct in_addr BIP_Broadcast_Binding_Address;
|
||||||
|
/* point-to-point interface flag - uses the unicast socket for broadcast */
|
||||||
|
static bool BIP_Point_To_Point = false;
|
||||||
/* enable debugging */
|
/* enable debugging */
|
||||||
static bool BIP_Debug = false;
|
static bool BIP_Debug = false;
|
||||||
/* interface name */
|
/* interface name */
|
||||||
@@ -449,11 +451,15 @@ bool bip_get_addr_by_name(const char *host_name, BACNET_IP_ADDRESS *addr)
|
|||||||
static void *get_addr_ptr(struct sockaddr *sockaddr_ptr)
|
static void *get_addr_ptr(struct sockaddr *sockaddr_ptr)
|
||||||
{
|
{
|
||||||
void *addr_ptr = NULL;
|
void *addr_ptr = NULL;
|
||||||
|
|
||||||
|
if (sockaddr_ptr) {
|
||||||
if (sockaddr_ptr->sa_family == AF_INET) {
|
if (sockaddr_ptr->sa_family == AF_INET) {
|
||||||
addr_ptr = &((struct sockaddr_in *)sockaddr_ptr)->sin_addr;
|
addr_ptr = &((struct sockaddr_in *)sockaddr_ptr)->sin_addr;
|
||||||
} else if (sockaddr_ptr->sa_family == AF_INET6) {
|
} else if (sockaddr_ptr->sa_family == AF_INET6) {
|
||||||
addr_ptr = &((struct sockaddr_in6 *)sockaddr_ptr)->sin6_addr;
|
addr_ptr = &((struct sockaddr_in6 *)sockaddr_ptr)->sin6_addr;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return addr_ptr;
|
return addr_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -492,7 +498,9 @@ int bip_get_local_address_ioctl(
|
|||||||
char rv = '\0'; /* return value */
|
char rv = '\0'; /* return value */
|
||||||
|
|
||||||
struct ifaddrs *ifaddrs_ptr;
|
struct ifaddrs *ifaddrs_ptr;
|
||||||
|
void *addr_ptr = NULL;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
status = getifaddrs(&ifaddrs_ptr);
|
status = getifaddrs(&ifaddrs_ptr);
|
||||||
if (status == -1) {
|
if (status == -1) {
|
||||||
fprintf(
|
fprintf(
|
||||||
@@ -500,17 +508,25 @@ int bip_get_local_address_ioctl(
|
|||||||
}
|
}
|
||||||
while (ifaddrs_ptr) {
|
while (ifaddrs_ptr) {
|
||||||
if ((ifaddrs_ptr->ifa_addr->sa_family == AF_INET) &&
|
if ((ifaddrs_ptr->ifa_addr->sa_family == AF_INET) &&
|
||||||
(strcmp(ifaddrs_ptr->ifa_name, ifname) == 0)) {
|
(ifname && strcmp(ifaddrs_ptr->ifa_name, ifname) == 0)) {
|
||||||
void *addr_ptr = NULL;
|
|
||||||
if (!ifaddrs_ptr->ifa_addr) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
switch (request) {
|
switch (request) {
|
||||||
case SIOCGIFADDR:
|
case SIOCGIFADDR:
|
||||||
addr_ptr = get_addr_ptr(ifaddrs_ptr->ifa_addr);
|
addr_ptr = get_addr_ptr(ifaddrs_ptr->ifa_addr);
|
||||||
break;
|
break;
|
||||||
case SIOCGIFBRDADDR:
|
case SIOCGIFBRDADDR:
|
||||||
|
/* Depending on whether the bit
|
||||||
|
IFF_BROADCAST or IFF_POINTOPOINT is set
|
||||||
|
in ifa_flags (only one can be set at a time),
|
||||||
|
either ifa_broadaddr will contain the broadcast
|
||||||
|
address associated with ifa_addr or ifa_dstaddr
|
||||||
|
will contain the destination address of the
|
||||||
|
point-to-point interface.*/
|
||||||
|
if (ifaddrs_ptr->ifa_flags & IFF_POINTOPOINT) {
|
||||||
|
BIP_Point_To_Point = true;
|
||||||
|
addr_ptr = get_addr_ptr(ifaddrs_ptr->ifa_dstaddr);
|
||||||
|
} else {
|
||||||
addr_ptr = get_addr_ptr(ifaddrs_ptr->ifa_broadaddr);
|
addr_ptr = get_addr_ptr(ifaddrs_ptr->ifa_broadaddr);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case SIOCGIFNETMASK:
|
case SIOCGIFNETMASK:
|
||||||
addr_ptr = get_addr_ptr(ifaddrs_ptr->ifa_netmask);
|
addr_ptr = get_addr_ptr(ifaddrs_ptr->ifa_netmask);
|
||||||
@@ -525,6 +541,7 @@ int bip_get_local_address_ioctl(
|
|||||||
ifaddrs_ptr = ifaddrs_ptr->ifa_next;
|
ifaddrs_ptr = ifaddrs_ptr->ifa_next;
|
||||||
}
|
}
|
||||||
freeifaddrs(ifaddrs_ptr);
|
freeifaddrs(ifaddrs_ptr);
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -571,6 +588,9 @@ void bip_set_interface(const char *ifname)
|
|||||||
struct in_addr broadcast_address;
|
struct in_addr broadcast_address;
|
||||||
int rv = 0;
|
int rv = 0;
|
||||||
|
|
||||||
|
local_address.s_addr = 0;
|
||||||
|
broadcast_address.s_addr = 0;
|
||||||
|
BIP_Point_To_Point = false;
|
||||||
/* setup local address */
|
/* setup local address */
|
||||||
rv = bip_get_local_address_ioctl(ifname, &local_address, SIOCGIFADDR);
|
rv = bip_get_local_address_ioctl(ifname, &local_address, SIOCGIFADDR);
|
||||||
if (rv < 0) {
|
if (rv < 0) {
|
||||||
@@ -611,9 +631,12 @@ void bip_set_interface(const char *ifname)
|
|||||||
if (rv < 0) {
|
if (rv < 0) {
|
||||||
BIP_Broadcast_Addr.s_addr = ~0;
|
BIP_Broadcast_Addr.s_addr = ~0;
|
||||||
} else {
|
} else {
|
||||||
BIP_Broadcast_Addr = local_address;
|
if (BIP_Point_To_Point) {
|
||||||
|
BIP_Broadcast_Addr.s_addr = local_address.s_addr;
|
||||||
|
} else {
|
||||||
BIP_Broadcast_Addr.s_addr = broadcast_address.s_addr;
|
BIP_Broadcast_Addr.s_addr = broadcast_address.s_addr;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
if (BIP_Debug) {
|
if (BIP_Debug) {
|
||||||
fprintf(
|
fprintf(
|
||||||
@@ -626,6 +649,11 @@ void bip_set_interface(const char *ifname)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *bip_get_interface(void)
|
||||||
|
{
|
||||||
|
return BIP_Interface_Name;
|
||||||
|
}
|
||||||
|
|
||||||
static int createSocket(const struct sockaddr_in *sin)
|
static int createSocket(const struct sockaddr_in *sin)
|
||||||
{
|
{
|
||||||
int status = 0; /* return from socket lib calls */
|
int status = 0; /* return from socket lib calls */
|
||||||
@@ -710,18 +738,20 @@ bool bip_init(char *ifname)
|
|||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
sin.sin_family = AF_INET;
|
sin.sin_family = AF_INET;
|
||||||
sin.sin_port = BIP_Port;
|
sin.sin_port = BIP_Port;
|
||||||
memset(&(sin.sin_zero), '\0', sizeof(sin.sin_zero));
|
memset(&(sin.sin_zero), '\0', sizeof(sin.sin_zero));
|
||||||
|
|
||||||
sin.sin_addr.s_addr = BIP_Address.s_addr;
|
sin.sin_addr.s_addr = BIP_Address.s_addr;
|
||||||
sock_fd = createSocket(&sin);
|
sock_fd = createSocket(&sin);
|
||||||
BIP_Socket = sock_fd;
|
BIP_Socket = sock_fd;
|
||||||
if (sock_fd < 0) {
|
if (sock_fd < 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (BIP_Point_To_Point) {
|
||||||
|
/* point-to-point interface flag
|
||||||
|
uses the unicast socket for broadcast */
|
||||||
|
BIP_Broadcast_Socket = BIP_Socket;
|
||||||
|
} else {
|
||||||
broadcast_sin_config.sin_family = AF_INET;
|
broadcast_sin_config.sin_family = AF_INET;
|
||||||
broadcast_sin_config.sin_port = BIP_Port;
|
broadcast_sin_config.sin_port = BIP_Port;
|
||||||
memset(
|
memset(
|
||||||
@@ -752,7 +782,7 @@ bool bip_init(char *ifname)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
bvlc_init();
|
bvlc_init();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
Reference in New Issue
Block a user