static void test_netaddr_is_in_subnet(void) { struct netaddr_str str1, str2; size_t a, s; START_TEST(); for (s = 0; s < sizeof(in_subnet_subnets) / sizeof(*in_subnet_subnets); s++) { for (a = 0; a < sizeof(in_subnet_addrs) / sizeof(*in_subnet_addrs); a++) { CHECK_TRUE( in_subnet_results[a][s] == netaddr_binary_is_in_subnet(&in_subnet_subnets[s], &in_subnet_addrs[a], netaddr_get_maxprefix(&in_subnet_addrs[a])/8, in_subnet_addrs[a]._type), "%s should %sbe in %s", netaddr_to_string(&str1, &in_subnet_addrs[a]), in_subnet_results[a][s] ? "" : "not ", netaddr_to_string(&str2, &in_subnet_subnets[s])); CHECK_TRUE( in_subnet_results[a][s] == netaddr_is_in_subnet(&in_subnet_subnets[s], &in_subnet_addrs[a]), "%s should %sbe in %s", netaddr_to_string(&str1, &in_subnet_addrs[a]), in_subnet_results[a][s] ? "" : "not ", netaddr_to_string(&str2, &in_subnet_subnets[s])); } } END_TEST(); }
static void test_netaddr_is_in_subnet(void) { struct netaddr_str str1, str2; size_t a, s; START_TEST(); for (s = 0; s < sizeof(in_subnet_subnets) / sizeof(*in_subnet_subnets); s++) { for (a = 0; a < sizeof(in_subnet_addrs) / sizeof(*in_subnet_addrs); a++) { CHECK_TRUE( in_subnet_results[a][s] == netaddr_binary_is_in_subnet(&in_subnet_subnets[s], &in_subnet_addrs[a], 4, AF_INET), "%s is not in %s", netaddr_to_string(&str1, &in_subnet_addrs[a]), netaddr_to_string(&str2, &in_subnet_subnets[s])); CHECK_TRUE( in_subnet_results[a][s] == netaddr_is_in_subnet(&in_subnet_subnets[s], &in_subnet_addrs[a]), "%s is not in %s", netaddr_to_string(&str1, &in_subnet_addrs[a]), netaddr_to_string(&str2, &in_subnet_subnets[s])); } } END_TEST(); }
/** * Apply a new configuration to an unicast/multicast socket pair * @param managed pointer to managed socket * @param data pointer to interface to bind sockets, NULL if unbound socket * @param sock pointer to unicast packet socket * @param bind_ip address to bind unicast socket to * @param mc_sock pointer to multicast packet socket * @param mc_ip multicast address * @return */ static int _apply_managed_socketpair(int af_type, struct oonf_packet_managed *managed, struct os_interface *os_if, bool *changed, struct oonf_packet_socket *sock, struct oonf_packet_socket *mc_sock, struct netaddr *mc_ip) { struct netaddr_acl *bind_ip_acl; int sockstate = 0, result = 0; uint16_t mc_port; bool real_multicast; const struct netaddr *bind_ip; bind_ip_acl = &managed->_managed_config.bindto; /* copy unicast port if necessary */ mc_port = managed->_managed_config.multicast_port; if (mc_port == 0) { mc_port = managed->_managed_config.port; } /* Get address the unicast socket should bind on */ if (os_if != NULL && !os_if->flags.up) { bind_ip = NULL; } else if (os_if != NULL && netaddr_get_address_family(os_if->if_linklocal_v6) == af_type && netaddr_acl_check_accept(bind_ip_acl, os_if->if_linklocal_v6)) { bind_ip = os_if->if_linklocal_v6; } else if (os_if != NULL && netaddr_get_address_family(os_if->if_linklocal_v4) == af_type && netaddr_acl_check_accept(bind_ip_acl, os_if->if_linklocal_v4)) { bind_ip = os_if->if_linklocal_v4; } else { bind_ip = os_interface_get_bindaddress(af_type, bind_ip_acl, os_if); } if (!bind_ip) { oonf_packet_remove(sock, false); oonf_packet_remove(mc_sock, false); return 0; } /* handle loopback interface */ if (os_if != NULL && os_if->flags.loopback && netaddr_get_address_family(mc_ip) != AF_UNSPEC) { memcpy(mc_ip, bind_ip, sizeof(*mc_ip)); } /* check if multicast IP is a real multicast (and not a broadcast) */ real_multicast = netaddr_is_in_subnet( netaddr_get_address_family(mc_ip) == AF_INET ? &NETADDR_IPV4_MULTICAST : &NETADDR_IPV6_MULTICAST, mc_ip); sockstate = _apply_managed_socket( managed, sock, bind_ip, managed->_managed_config.port, managed->_managed_config.dscp, managed->_managed_config.rawip ? managed->_managed_config.protocol : 0, os_if); if (sockstate == 0) { /* settings really changed */ *changed = true; if (real_multicast && os_if != NULL && os_if->flags.up) { os_fd_join_mcast_send(&sock->scheduler_entry.fd, mc_ip, os_if, managed->_managed_config.loop_multicast, LOG_PACKET); } } else if (sockstate < 0) { /* error */ result = -1; oonf_packet_remove(sock, true); } if (real_multicast && netaddr_get_address_family(mc_ip) != AF_UNSPEC) { /* multicast */ sockstate = _apply_managed_socket( managed, mc_sock, mc_ip, mc_port, managed->_managed_config.dscp, managed->_managed_config.rawip ? managed->_managed_config.protocol : 0, os_if); if (sockstate == 0) { /* settings really changed */ *changed = true; mc_sock->scheduler_entry.process = _cb_packet_event_multicast; /* join multicast group */ os_fd_join_mcast_recv(&mc_sock->scheduler_entry.fd, mc_ip, os_if, LOG_PACKET); } else if (sockstate < 0) { /* error */ result = -1; oonf_packet_remove(sock, true); } } else { oonf_packet_remove(mc_sock, true); /* * initialize anyways because we use it for sending broadcasts with * oonf_packet_send_managed_multicast() */ netaddr_socket_init(&mc_sock->local_socket, mc_ip, mc_port, os_if == NULL ? 0 : os_if->index); } return result; }