return 0;
}
-/**
- *
- */
-inline int
-check_equal_v4(const struct in_addr * a,
- const struct in_addr * b)
-{
- return (a->s_addr == b->s_addr);
-}
-
-/**
- *
- */
-inline int
-check_equal_v6(const struct in6_addr * a,
- const struct in6_addr * b)
-{
- return (memcmp(a->s6_addr, b->s6_addr, 16) == 0) ? 1 : 0;
-}
-
-/**
- *
- */
-inline int
-check_in_network_v4(const struct in_addr * network,
- const struct in_addr * mask,
- const struct in_addr * address)
-{
- return ((address->s_addr & mask->s_addr) == (network->s_addr & mask->s_addr));
-}
-
-/**
- *
- */
-inline int
-check_in_network_v6(const struct in6_addr * network,
- const struct in6_addr * mask,
- const struct in6_addr * address)
-{
- unsigned int i;
- for (i=0; i<sizeof(struct in6_addr)/sizeof (int); i++)
- if ( ((((int *) address)[i] & ((int *) mask)[i])) !=
- (((int *) network)[i] & ((int *) mask)[i])) {
- return 0;
- }
- return 1;
-}
-
-/**
- *
- */
-inline int
-check_is_any_v4(const struct in_addr * address)
-{
- return (address->s_addr == INADDR_ANY);
-}
-
-/**
- *
- */
-inline int
-check_is_any_v6(const struct in6_addr * address)
-{
- return (check_equal_v6(address,&in6addr_any));
-}
-
/**
*
*/
int
-check_is_local_address(const struct sockaddr_storage *peer, const struct sockaddr_storage *local)
+ip_check_is_local_address
+ (const struct sockaddr_storage *peer, const struct sockaddr_storage *local)
{
struct ifaddrs *iflist, *ifdev = NULL;
struct sockaddr_storage *ifaddr, *ifnetmask;
- int any_address = 0;
-
- if ( (local->ss_family == AF_INET && check_is_any_v4(&((struct sockaddr_in *)local)->sin_addr) ) ||
- (local->ss_family == AF_INET6 && check_is_any_v6(&((struct sockaddr_in6 *)local)->sin6_addr) ) ) {
- any_address = 1;
- }
- tvhdebug(LS_SATIPS, "tcp_is_local_address(): ANY=%i",any_address);
+ int any_address, ret;
// Note: Not all platforms have getifaddrs()
// See http://docs.freeswitch.org/switch__utils_8c_source.html
- if (!local || !peer || getifaddrs(&iflist) < 0) return 0;
+ if (!local || !peer || getifaddrs(&iflist) < 0)
+ return 0;
- for (ifdev = iflist; ifdev; ifdev = ifdev->ifa_next) {
- ifaddr = (struct sockaddr_storage *)(ifdev->ifa_addr);
- ifnetmask = (struct sockaddr_storage *)(ifdev->ifa_netmask);
+ if (peer->ss_family != local->ss_family)
+ return 0;
- if (ifaddr && ifnetmask && ifaddr->ss_family == local->ss_family && ifaddr->ss_family == peer->ss_family) {
+ any_address = ip_check_is_any(local);
- if (ifaddr->ss_family == AF_INET) {
- if ((any_address || check_equal_v4( &((struct sockaddr_in *)ifaddr)->sin_addr, &((struct sockaddr_in *)local)->sin_addr ))
- && check_in_network_v4( &((struct sockaddr_in *)ifaddr)->sin_addr,
- &((struct sockaddr_in *)ifnetmask)->sin_addr,
- &((struct sockaddr_in *)peer)->sin_addr) ) {
- freeifaddrs(iflist);
- return 1;
- }
- } else if (ifaddr->ss_family == AF_INET6) {
- if ((any_address || check_equal_v6( &((struct sockaddr_in6 *)ifaddr)->sin6_addr, &((struct sockaddr_in6 *)local)->sin6_addr ))
- && check_in_network_v6( &((struct sockaddr_in6 *)ifaddr)->sin6_addr,
- &((struct sockaddr_in6 *)ifnetmask)->sin6_addr,
- &((struct sockaddr_in6 *)peer)->sin6_addr) ) {
- freeifaddrs(iflist);
- return 1;
- }
- }
- }
+ for (ifdev = iflist, ret = 0; ifdev && ret == 0; ifdev = ifdev->ifa_next) {
+ ifaddr = (struct sockaddr_storage *)(ifdev->ifa_addr);
+ ifnetmask = (struct sockaddr_storage *)(ifdev->ifa_netmask);
+ if (!ifaddr || !ifnetmask) continue;
+ if (ifaddr->ss_family != local->ss_family) continue;
+ if (!any_address && !ip_check_equal(ifaddr, local)) continue;
+ ret = !!ip_check_in_network_v4(ifaddr, ifnetmask, peer);
}
freeifaddrs(iflist);
- return 0;
+ return ret;
}
/**
void tcp_server_init(void);
void tcp_server_done(void);
-int check_equal_v4(const struct in_addr * a, const struct in_addr * b);
-int check_equal_v6(const struct in6_addr * a, const struct in6_addr * b);
-int check_in_network_v4(const struct in_addr * network,
- const struct in_addr * mask,
- const struct in_addr * address);
-int check_in_network_v6(const struct in6_addr * network,
- const struct in6_addr * mask,
- const struct in6_addr * address);
-int check_is_any_v4(const struct in_addr * address);
-int check_is_any_v6(const struct in6_addr * address);
-int check_is_local_address(const struct sockaddr_storage *peer, const struct sockaddr_storage *local);
+static inline int ip_check_equal_v4
+ (const struct sockaddr_storage *a, const struct sockaddr_storage *b)
+ { return IP_AS_V4(a, addr).s_addr == IP_AS_V4(b, addr).s_addr; }
+
+static inline int ip_check_equal_v6
+ (const struct sockaddr_storage *a, const struct sockaddr_storage *b)
+ { return ((uint64_t *)IP_AS_V6(a, addr).s6_addr)[0] == ((uint64_t *)IP_AS_V6(b, addr).s6_addr)[0] &&
+ ((uint64_t *)IP_AS_V6(a, addr).s6_addr)[1] == ((uint64_t *)IP_AS_V6(b, addr).s6_addr)[1]; }
+
+static inline int ip_check_equal
+ (const struct sockaddr_storage *a, const struct sockaddr_storage *b)
+ { return a->ss_family == b->ss_family &&
+ a->ss_family == AF_INET ? ip_check_equal_v4(a, b) :
+ (a->ss_family == AF_INET6 ? ip_check_equal_v6(a, b) : 0); }
+
+static inline int ip_check_in_network_v4(const struct sockaddr_storage *network,
+ const struct sockaddr_storage *mask,
+ const struct sockaddr_storage *address)
+ { return (IP_AS_V4(address, addr).s_addr & IP_AS_V4(mask, addr).s_addr) ==
+ (IP_AS_V4(network, addr).s_addr & IP_AS_V4(mask, addr).s_addr); }
+
+static inline int ip_check_in_network_v6(const struct sockaddr_storage *network,
+ const struct sockaddr_storage *mask,
+ const struct sockaddr_storage *address)
+ { return (((uint64_t *)IP_AS_V6(address, addr).s6_addr)[0] & ((uint64_t *)IP_AS_V6(mask, addr).s6_addr)[0]) ==
+ (((uint64_t *)IP_AS_V6(network, addr).s6_addr)[0] & ((uint64_t *)IP_AS_V6(mask, addr).s6_addr)[0]) &&
+ (((uint64_t *)IP_AS_V6(address, addr).s6_addr)[0] & ((uint64_t *)IP_AS_V6(mask, addr).s6_addr)[1]) ==
+ (((uint64_t *)IP_AS_V6(network, addr).s6_addr)[1] & ((uint64_t *)IP_AS_V6(mask, addr).s6_addr)[1]); }
+
+static inline int ip_check_in_network(const struct sockaddr_storage *network,
+ const struct sockaddr_storage *mask,
+ const struct sockaddr_storage *address)
+ { return address->ss_family == AF_INET ? ip_check_in_network_v4(network, mask, address) :
+ (address->ss_family == AF_INET6 ? ip_check_in_network_v6(network, mask, address) : 0); }
+
+static inline int ip_check_is_any_v4(const struct sockaddr_storage *address)
+ { return IP_AS_V4(address, addr).s_addr == INADDR_ANY; }
+
+static inline int ip_check_is_any_v6(const struct sockaddr_storage *address)
+ { return ((uint64_t *)IP_AS_V6(address, addr).s6_addr)[0] == ((uint64_t *)(&in6addr_any.s6_addr))[0] &&
+ ((uint64_t *)IP_AS_V6(address, addr).s6_addr)[1] == ((uint64_t *)(&in6addr_any.s6_addr))[1]; }
+
+static inline int ip_check_is_any(const struct sockaddr_storage *address)
+ { return address->ss_family == AF_INET ? ip_check_is_any_v4(address) :
+ (address->ss_family == AF_INET6 ? ip_check_is_any_v6(address) : 0); }
+
+int ip_check_is_local_address(const struct sockaddr_storage *peer, const struct sockaddr_storage *local);
int socket_set_dscp(int sockfd, uint32_t dscp, char *errbuf, size_t errbufsize);