Bind to device (for vlan config)
git-svn-id: http://svn.eurecom.fr/openair4G/trunk@5068 818b1a75-f10b-46b9-bf7c-635c3b92a50f
This commit is contained in:
@@ -35,6 +35,11 @@
|
|||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <ifaddrs.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <net/if.h>
|
||||||
|
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <netinet/sctp.h>
|
#include <netinet/sctp.h>
|
||||||
@@ -128,6 +133,11 @@ void sctp_handle_new_association_req(
|
|||||||
struct sctp_cnx_list_elm_s *sctp_cnx = NULL;
|
struct sctp_cnx_list_elm_s *sctp_cnx = NULL;
|
||||||
enum sctp_connection_type_e connection_type = SCTP_TYPE_CLIENT;
|
enum sctp_connection_type_e connection_type = SCTP_TYPE_CLIENT;
|
||||||
|
|
||||||
|
struct ifreq ifr;
|
||||||
|
struct ifaddrs *ifaddr, *ifa;
|
||||||
|
int family, s;
|
||||||
|
struct in_addr in;
|
||||||
|
struct in6_addr in6;
|
||||||
/* Prepare a new SCTP association as requested by upper layer and try to connect
|
/* Prepare a new SCTP association as requested by upper layer and try to connect
|
||||||
* to remote host.
|
* to remote host.
|
||||||
*/
|
*/
|
||||||
@@ -162,6 +172,63 @@ void sctp_handle_new_association_req(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bind to device ... or we could bind to address also
|
||||||
|
if (getifaddrs(&ifaddr) == -1) {
|
||||||
|
SCTP_ERROR("getifaddrs failed: %s\n", strerror(errno));
|
||||||
|
close(sd);
|
||||||
|
}
|
||||||
|
/* Walk through linked list, maintaining head pointer so we
|
||||||
|
can free list later */
|
||||||
|
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
|
||||||
|
if (ifa->ifa_addr == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
family = ifa->ifa_addr->sa_family;
|
||||||
|
|
||||||
|
/* For an AF_INET* interface address, display the address */
|
||||||
|
if (sctp_new_association_req_p->local_address.ipv4 && family == AF_INET) {
|
||||||
|
// compare address
|
||||||
|
s = inet_aton(sctp_new_association_req_p->local_address.ipv4_address,
|
||||||
|
&in);
|
||||||
|
if (s > 0 ) {
|
||||||
|
if (((struct sockaddr_in*)ifa->ifa_addr)->sin_addr.s_addr == in.s_addr) {
|
||||||
|
memset(&ifr, 0, sizeof(ifr));
|
||||||
|
snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), ifa->ifa_name);
|
||||||
|
if (setsockopt(sd, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr)) < 0) {
|
||||||
|
SCTP_ERROR("Setsockopt SOL_SOCKET failed: %s\n",
|
||||||
|
strerror(errno));
|
||||||
|
} else {
|
||||||
|
SCTP_DEBUG("Setsockopt SOL_SOCKET socket bound to : %s\n",
|
||||||
|
ifa->ifa_name);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (sctp_new_association_req_p->local_address.ipv6 && family == AF_INET6) {
|
||||||
|
// compare address
|
||||||
|
s = inet_pton(AF_INET6,
|
||||||
|
sctp_new_association_req_p->local_address.ipv6_address,
|
||||||
|
&in6);
|
||||||
|
if (s == 1 ) {
|
||||||
|
if (memcmp(&((struct sockaddr_in6*)ifa->ifa_addr)->sin6_addr,
|
||||||
|
&in6, sizeof(in6)) == 0) {
|
||||||
|
memset(&ifr, 0, sizeof(ifr));
|
||||||
|
snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), ifa->ifa_name);
|
||||||
|
if (setsockopt(sd, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr)) < 0) {
|
||||||
|
SCTP_ERROR("Setsockopt SOL_SOCKET failed: %s\n",
|
||||||
|
strerror(errno));
|
||||||
|
} else {
|
||||||
|
SCTP_DEBUG("Setsockopt SOL_SOCKET socket bound to : %s\n",
|
||||||
|
ifa->ifa_name);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
freeifaddrs(ifaddr);
|
||||||
|
|
||||||
/* Mark the socket as non-blocking */
|
/* Mark the socket as non-blocking */
|
||||||
if (fcntl(sd, F_SETFL, O_NONBLOCK) < 0) {
|
if (fcntl(sd, F_SETFL, O_NONBLOCK) < 0) {
|
||||||
SCTP_ERROR("fcntl F_SETFL O_NONBLOCK failed: %s\n",
|
SCTP_ERROR("fcntl F_SETFL O_NONBLOCK failed: %s\n",
|
||||||
|
|||||||
Reference in New Issue
Block a user