+char *block_icmp(const char *container_name) {
+ char block_cmd[500];
+ assert(container_name);
+ assert(snprintf(block_cmd, sizeof(block_cmd), "iptables -A FORWARD -p icmp -j DROP") >= 0);
+ return execute_in_container(block_cmd, container_name, false);
+}
+
+char *unblock_icmp(const char *container_name) {
+ char block_cmd[500];
+ assert(container_name);
+ assert(snprintf(block_cmd, sizeof(block_cmd), "iptables -D FORWARD -p icmp -j DROP") >= 0);
+ return execute_in_container(block_cmd, container_name, false);
+}
+
+char *change_container_mtu(const char *container_name, const char *interface_name, int mtu) {
+ char cmd[500];
+ assert(container_name);
+ assert(snprintf(cmd, sizeof(cmd), "ifconfig %s mtu %d", interface_name, mtu) >= 0);
+ return execute_in_container(cmd, container_name, false);
+}
+
+char *flush_conntrack(const char *container_name) {
+ assert(container_name);
+
+ return execute_in_container("conntrack -F", container_name, false);
+}
+
+void flush_nat_rules(const char *container_name, const char *chain) {
+ char *ret;
+ char flush_cmd[500];
+
+ assert(container_name);
+ assert(snprintf(flush_cmd, sizeof(flush_cmd), "iptables -F %s", chain ? chain : "") >= 0);
+ ret = execute_in_container("iptables -F", container_name, false);
+ assert(ret == NULL);
+}
+
+void add_full_cone_nat_rules(const char *container_name, const char *pub_interface, const char *priv_interface_listen_address) {
+ char nat_cmd[500];
+
+ char **pub_interface_ips = get_container_interface_ips(container_name, pub_interface);
+ assert(pub_interface_ips[0]);
+ char *pub_interface_ip = pub_interface_ips[0];
+
+ assert(snprintf(nat_cmd, sizeof(nat_cmd),
+ "%s/" LXC_UTIL_REL_PATH "/" LXC_NAT_FULL_CONE " %s %s %s %s >/dev/null",
+ meshlink_root_path, container_name, pub_interface, pub_interface_ip, priv_interface_listen_address) >= 0);
+ assert(system(nat_cmd) == 0);
+ free(pub_interface_ips);
+}
+
+/* Create a NAT and a bridge, bridge connected to NAT and containers to be NATed can be switched
+ to the NAT bridge from lxcbr0 */
+void nat_create(const char *nat_name, const char *nat_bridge, int nat_type) {
+ (void)nat_type;
+
+ char build_command[200];
+ assert(snprintf(build_command, sizeof(build_command),
+ "%s/" LXC_UTIL_REL_PATH "/" LXC_NAT_BUILD " %s %s %s >/dev/stderr",
+ meshlink_root_path, nat_name, nat_bridge, meshlink_root_path) >= 0);
+ assert(system(build_command) == 0);
+}
+
+void nat_destroy(const char *nat_name) {
+ char build_command[200];
+ assert(snprintf(build_command, sizeof(build_command),
+ "%s/" LXC_UTIL_REL_PATH "/" LXC_NAT_DESTROY " %s +x >/dev/null",
+ meshlink_root_path, nat_name) >= 0);
+ assert(system(build_command) == 0);
+}
+
+/* Switches a container from current bridge to a new bridge */
+void container_switch_bridge(const char *container_name, char *lxc_conf_path, const char *current_bridge, const char *new_bridge) {
+ char config_path[500];
+ char buffer[500];
+ struct lxc_container *container;
+ char *lxc_path_temp;
+ char *ip;
+
+ PRINT_TEST_CASE_MSG("Switiching container %s from bridge '%s' to bridge '%s'", container_name, current_bridge, new_bridge);
+ lxc_path_temp = lxc_path;
+ lxc_path = lxc_conf_path;
+ container = find_container(container_name);
+ assert(container);
+ lxc_path = lxc_path_temp;
+ assert(snprintf(config_path, sizeof(config_path), "%s/%s/config", lxc_conf_path, container_name) >= 0);
+ FILE *fp = fopen(config_path, "r");
+ assert(fp);
+ FILE *fp_temp = fopen(".temp_file", "w");
+ assert(fp_temp);
+
+ int net_no;
+
+ while((fgets(buffer, sizeof(buffer), fp)) != NULL) {
+ if(sscanf(buffer, "lxc.net.%d.link", &net_no) == 1) {
+ char *ptr;
+ int len;
+
+ if((ptr = strstr(buffer, current_bridge)) != NULL) {
+ len = strlen(current_bridge);
+
+ if(((*(ptr - 1) == ' ') || (*(ptr - 1) == '\t') || (*(ptr - 1) == '=')) && ((ptr[len] == '\n') || (ptr[len] == '\t') || (ptr[len] == '\0') || (ptr[len] == ' '))) {
+ sprintf(buffer, "lxc.net.%d.link = %s\n", net_no, new_bridge);
+ }
+ }
+ }
+
+ fputs(buffer, fp_temp);
+ }
+
+ fclose(fp_temp);
+ fclose(fp);
+ remove(config_path);
+ rename(".temp_file", config_path);
+
+ /* Restart the Container after building it and wait for it to acquire an IP */
+ char cmd[200];
+ int sys_ret;
+ assert(snprintf(cmd, sizeof(cmd), "lxc-stop %s", container_name) >= 0);
+ sys_ret = system(cmd);
+ assert(snprintf(cmd, sizeof(cmd), "lxc-start %s", container_name) >= 0);
+ sys_ret = system(cmd);
+ assert(sys_ret == 0);
+ ip = container_wait_ip_ex(container_name);
+ PRINT_TEST_CASE_MSG("Obtained IP address: %s for container %s after switching bridge", ip, container_name);
+ free(ip);
+}
+