@@ -71,6 +71,11 @@ typedef struct tport_nat_s tport_nat_t;
71
71
#include <sofia-sip/rbtree.h>
72
72
73
73
#include "tport_internal.h"
74
+ #include <ifaddrs.h>
75
+ #if HAVE_NET_IF_H
76
+ #include <net/if.h>
77
+ #endif
78
+ #include <sys/ioctl.h>
74
79
75
80
#if HAVE_FUNC
76
81
#elif HAVE_FUNCTION
@@ -797,6 +802,51 @@ int tport_bind_socket(int socket,
797
802
}
798
803
#endif
799
804
805
+ if (tport_bind_socket_iface (socket , su , ai ) < 0 ) {
806
+ return -1 ;
807
+ }
808
+
809
+ return 0 ;
810
+ }
811
+
812
+ int tport_bind_socket_iface (int s ,
813
+ su_sockaddr_t * su ,
814
+ su_addrinfo_t * ai )
815
+ {
816
+ struct ifaddrs * addrs , * iap ;
817
+ struct sockaddr_in * sa ;
818
+ struct ifreq ifr ;
819
+ char ipaddr [SU_ADDRSIZE + 2 ];
820
+
821
+ getifaddrs (& addrs );
822
+ for (iap = addrs ; iap != NULL ; iap = iap -> ifa_next ) {
823
+ if (iap -> ifa_addr && (iap -> ifa_flags & IFF_UP ) && iap -> ifa_addr -> sa_family == su -> su_family ) {
824
+ sa = (struct sockaddr_in * )(iap -> ifa_addr );
825
+ if (sa -> sin_addr .s_addr == su -> su_sin .sin_addr .s_addr ) {
826
+ memset (& ifr , 0 , sizeof (struct ifreq ));
827
+ strncpy (ifr .ifr_name , (char const * ) iap -> ifa_name , IFNAMSIZ );
828
+
829
+ /* Assign socket to an already active access point (interface) */
830
+ ioctl (s , SIOCSIFNAME , & ifr );
831
+ if (setsockopt (s , SOL_SOCKET , SO_BINDTODEVICE , (void * )& ifr , sizeof (ifr )) < 0 ) {
832
+ SU_DEBUG_3 (("socket: %d setsockopt(SO_BINDTODEVICE) error binding to ifc %s: %s\n" ,
833
+ s , ifr .ifr_name , su_strerror (su_errno ())));
834
+ freeifaddrs (addrs );
835
+ return -1 ;
836
+ }
837
+ SU_DEBUG_9 (("socket: %d, bound %s to ifc: %s\n" , s ,
838
+ su_inet_ntop (su -> su_family , SU_ADDR (su ), ipaddr , sizeof (ipaddr )),
839
+ ifr .ifr_name ));
840
+ freeifaddrs (addrs );
841
+ return 0 ;
842
+ }
843
+ }
844
+ }
845
+ freeifaddrs (addrs );
846
+
847
+ SU_DEBUG_3 (("socket: %d: did not find ifc to bind %s\n" ,
848
+ s , su_inet_ntop (su -> su_family , SU_ADDR (su ), ipaddr , sizeof (ipaddr ))));
849
+ /* Technically it's not a "failure" */
800
850
return 0 ;
801
851
}
802
852
0 commit comments