+
+char **get_container_interface_ips(const char *container_name, const char *interface_name) {
+ char **ips;
+ struct lxc_container *container = find_container(container_name);
+ assert(container);
+
+ char **interfaces = container->get_interfaces(container);
+ assert(interfaces);
+
+ int i;
+ ips = NULL;
+
+ for(i = 0; interfaces[i]; i++) {
+ if(!strcasecmp(interfaces[i], interface_name)) {
+ ips = container->get_ips(container, interface_name, "inet", 0);
+ assert(ips);
+ break;
+ }
+ }
+
+ free(interfaces);
+
+ return ips;
+}
+
+/* Install an app in a container */
+void install_in_container(const char *node, const char *app) {
+ char install_cmd[100];
+
+ assert(snprintf(install_cmd, sizeof(install_cmd),
+ "apt-get install %s -y >> /dev/null", app) >= 0);
+ run_in_container(install_cmd, node, false);
+ // TODO: Check in container whether app has installed or not with a timeout
+ sleep(10);
+}
+
+/* Return container's IP address */
+char *get_container_ip(const char *node_name) {
+ int node = -1, i;
+
+ for(i = 0; i < state_ptr->num_nodes; i++) {
+ if(!strcasecmp(state_ptr->node_names[i], node_name)) {
+ node = i;
+ break;
+ }
+ }
+
+ if(i == state_ptr->num_nodes) {
+ return NULL;
+ }
+
+ char *ip = strdup(container_ips[node]);
+ assert(ip);
+
+ return ip;
+}
+
+/* Simulate a network failure by adding NAT rule in the container with it's IP address */
+void block_node_ip(const char *node) {
+ char block_cmd[100];
+ char *node_ip;
+
+ node_ip = get_container_ip(node);
+ assert(node_ip);
+ assert(snprintf(block_cmd, sizeof(block_cmd), "iptables -A OUTPUT -p all -s %s -j DROP", node_ip) >= 0);
+ run_in_container(block_cmd, node, false);
+
+ assert(snprintf(block_cmd, sizeof(block_cmd), "iptables -A INPUT -p all -s %s -j DROP", node_ip) >= 0);
+ run_in_container(block_cmd, node, false);
+
+ assert(snprintf(block_cmd, sizeof(block_cmd), "iptables -A FORWARD -p all -s %s -j DROP", node_ip) >= 0);
+ run_in_container(block_cmd, node, false);
+
+ free(node_ip);
+}
+
+void accept_port_rule(const char *node, const char *chain, const char *protocol, int port) {
+ char block_cmd[100];
+
+ assert(port >= 0 && port < 65536);
+ assert(!strcmp(chain, "INPUT") || !strcmp(chain, "FORWARD") || !strcmp(chain, "OUTPUT"));
+ assert(!strcmp(protocol, "all") || !strcmp(protocol, "tcp") || !strcmp(protocol, "udp") || !strcmp(protocol, "icmp"));
+ assert(snprintf(block_cmd, sizeof(block_cmd), "iptables -A %s -p %s --dport %d -j ACCEPT", chain, protocol, port) >= 0);
+ run_in_container(block_cmd, node, false);
+}
+
+/* Restore the network that was blocked before by the NAT rule with it's own IP address */
+void unblock_node_ip(const char *node) {
+ char unblock_cmd[100];
+ char *node_ip;
+
+ node_ip = get_container_ip(node);
+ assert(node_ip);
+ assert(snprintf(unblock_cmd, sizeof(unblock_cmd), "iptables -D OUTPUT -p all -s %s -j DROP", node_ip) >= 0);
+ run_in_container(unblock_cmd, node, false);
+
+ assert(snprintf(unblock_cmd, sizeof(unblock_cmd), "iptables -D INPUT -p all -s %s -j DROP", node_ip) >= 0);
+ run_in_container(unblock_cmd, node, false);
+
+ assert(snprintf(unblock_cmd, sizeof(unblock_cmd), "iptables -D FORWARD -p all -s %s -j DROP", node_ip) >= 0);
+ run_in_container(unblock_cmd, node, false);
+}
+
+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);
+}
+
+/* Takes bridgeName as input parameter and creates a bridge */
+void create_bridge(const char *bridgeName) {
+ char command[100] = "brctl addbr ";
+ strcat(command, bridgeName);
+ int create_bridge_status = system(command);
+ assert(create_bridge_status == 0);
+ PRINT_TEST_CASE_MSG("%s bridge created\n", bridgeName);
+}
+
+/* Add interface for the bridge created */
+void add_interface(const char *bridgeName, const char *interfaceName) {
+ char command[100] = "brctl addif ";
+ char cmd[100] = "dhclient ";
+
+ strcat(command, bridgeName);
+ strcat(command, " ");
+ strcat(command, interfaceName);
+ int addif_status = system(command);
+ assert(addif_status == 0);
+ strcat(cmd, bridgeName);
+ int dhclient_status = system(cmd);
+ assert(dhclient_status == 0);
+ PRINT_TEST_CASE_MSG("Added interface for %s\n", bridgeName);
+}
+
+/* Create a veth pair and bring them up */
+void add_veth_pair(const char *vethName1, const char *vethName2) {
+ char command[100] = "ip link add ";
+ char upCommand1[100] = "ip link set ";
+ char upCommand2[100] = "ip link set ";
+
+ strcat(command, vethName1);
+ strcat(command, " type veth peer name ");
+ strcat(command, vethName2);
+ int link_add_status = system(command);
+ assert(link_add_status == 0);
+ strcat(upCommand1, vethName1);
+ strcat(upCommand1, " up");
+ int link_set_veth1_status = system(upCommand1);
+ assert(link_set_veth1_status == 0);
+ strcat(upCommand2, vethName2);
+ strcat(upCommand2, " up");
+ int link_set_veth2_status = system(upCommand2);
+ assert(link_set_veth2_status == 0);
+ PRINT_TEST_CASE_MSG("Added veth pairs %s and %s\n", vethName1, vethName2);
+}
+
+/* Bring the interface up for the bridge created */
+void bring_if_up(const char *bridgeName) {
+ char command[300] = "ifconfig ";
+ strcat(command, bridgeName);
+ strcat(command, " up");
+ int if_up_status = system(command);
+ assert(if_up_status == 0);
+ sleep(2);
+ PRINT_TEST_CASE_MSG("Interface brought up for %s created\n", bridgeName);
+}
+
+/**
+ * Replace all occurrences of a given a word in string.
+ */
+void replaceAll(char *str, const char *oldWord, const char *newWord) {
+ char *pos, temp[BUFSIZ];
+ int index = 0;
+ int owlen;
+ owlen = strlen(oldWord);
+
+ while((pos = strstr(str, oldWord)) != NULL) {
+ strcpy(temp, str);
+ index = pos - str;
+ str[index] = '\0';
+ strcat(str, newWord);
+ strcat(str, temp + index + owlen);
+ }
+}
+
+/* Switches the bridge for a given container */
+void switch_bridge(const char *containerName, const char *currentBridge, const char *newBridge) {
+ char command[100] = "lxc-stop -n ";
+ char command_start[100] = "lxc-start -n ";
+ PRINT_TEST_CASE_MSG("Switching %s container to %s\n", containerName, newBridge);
+ strcat(command, containerName);
+ strcat(command_start, containerName);
+ int container_stop_status = system(command);
+ assert(container_stop_status == 0);
+ sleep(2);
+ FILE *fPtr;
+ FILE *fTemp;
+ char path[300] = "/var/lib/lxc/";
+ strcat(path, containerName);
+ strcat(path, "/config");
+
+ char buffer[BUFSIZ];
+ /* Open all required files */
+ fPtr = fopen(path, "r");
+ fTemp = fopen("replace.tmp", "w");
+
+ if(fPtr == NULL || fTemp == NULL) {
+ PRINT_TEST_CASE_MSG("\nUnable to open file.\n");
+ PRINT_TEST_CASE_MSG("Please check whether file exists and you have read/write privilege.\n");
+ exit(EXIT_SUCCESS);
+ }
+
+ while((fgets(buffer, BUFSIZ, fPtr)) != NULL) {
+ replaceAll(buffer, currentBridge, newBridge);
+ fputs(buffer, fTemp);
+ }
+
+ fclose(fPtr);
+ fclose(fTemp);
+ remove(path);
+ rename("replace.tmp", path);
+ PRINT_TEST_CASE_MSG("Switching procedure done successfully\n");
+ int container_start_status = system(command_start);
+ assert(container_start_status == 0);
+ sleep(2);
+}
+
+/* Bring the interface down for the bridge created */
+void bring_if_down(const char *bridgeName) {
+ char command[300] = "ip link set dev ";
+ strcat(command, bridgeName);
+ strcat(command, " down");
+ int if_down_status = system(command);
+ assert(if_down_status == 0);
+ PRINT_TEST_CASE_MSG("Interface brought down for %s created\n", bridgeName);
+}
+
+/* Delete interface for the bridge created */
+void del_interface(const char *bridgeName, const char *interfaceName) {
+ char command[300] = "brctl delif ";
+ strcat(command, bridgeName);
+ strcat(command, interfaceName);
+ int if_delete_status = system(command);
+ assert(if_delete_status == 0);
+ PRINT_TEST_CASE_MSG("Deleted interface for %s\n", bridgeName);
+}
+
+/* Takes bridgeName as input parameter and deletes a bridge */
+void delete_bridge(const char *bridgeName) {
+ bring_if_down(bridgeName);
+ char command[300] = "brctl delbr ";
+ strcat(command, bridgeName);
+ int bridge_delete = system(command);
+ assert(bridge_delete == 0);
+ PRINT_TEST_CASE_MSG("%s bridge deleted\n", bridgeName);
+ sleep(2);
+}
+
+/* Creates container on a specified bridge with added interface */
+void create_container_on_bridge(const char *containerName, const char *bridgeName, const char *ifName) {
+ char command[100] = "lxc-create -t download -n ";
+ char cmd[100] = " -- -d ubuntu -r trusty -a ";
+ char start[100] = "lxc-start -n ";
+ FILE *fPtr;
+ char path[300] = "/var/lib/lxc/";
+ strcat(path, containerName);
+ strcat(path, "/config");
+ strcat(command, containerName);
+ strcat(command, cmd);
+ strcat(command, choose_arch);
+ int container_create_status = system(command);
+ assert(container_create_status == 0);
+ sleep(3);
+ assert((fPtr = fopen(path, "a+")));
+ fprintf(fPtr, "lxc.net.0.name = eth0\n");
+ fprintf(fPtr, "\n");
+ fprintf(fPtr, "lxc.net.1.type = veth\n");
+ fprintf(fPtr, "lxc.net.1.flags = up\n");
+ fprintf(fPtr, "lxc.net.1.link = %s\n", bridgeName);
+ fprintf(fPtr, "lxc.net.1.name = %s\n", ifName);
+ fprintf(fPtr, "lxc.net.1.hwaddr = 00:16:3e:ab:xx:xx\n");
+ fclose(fPtr);
+ strcat(start, containerName);
+ int container_start_status = system(start);
+ assert(container_start_status == 0);
+ sleep(3);
+ PRINT_TEST_CASE_MSG("Created %s on %s with interface name %s\n", containerName, bridgeName, ifName);
+}
+
+/* Configures dnsmasq and iptables for the specified container with inputs of listen address and dhcp range */
+void config_dnsmasq(const char *containerName, const char *ifName, const char *listenAddress, const char *dhcpRange) {
+ char command[500] = "echo \"apt-get install dnsmasq iptables -y\" | lxc-attach -n ";
+ strcat(command, containerName);
+ strcat(command, " --");
+ int iptables_install_status = system(command);
+ assert(iptables_install_status == 0);
+ sleep(5);
+ char com1[300] = "echo \"echo \"interface=eth1\" >> /etc/dnsmasq.conf\" | lxc-attach -n ";
+ strcat(com1, containerName);
+ strcat(com1, " --");
+ int dnsmasq_status = system(com1);
+ assert(dnsmasq_status == 0);
+ sleep(5);
+ char com2[300] = "echo \"echo \"bind-interfaces\" >> /etc/dnsmasq.conf\" | lxc-attach -n ";
+ strcat(com2, containerName);
+ strcat(com2, " --");
+ dnsmasq_status = system(com2);
+ assert(dnsmasq_status == 0);
+ sleep(5);
+ char com3[300] = "echo \"echo \"listen-address=";
+ strcat(com3, listenAddress);
+ strcat(com3, "\" >> /etc/dnsmasq.conf\" | lxc-attach -n ");
+ strcat(com3, containerName);
+ strcat(com3, " --");
+ dnsmasq_status = system(com3);
+ assert(dnsmasq_status == 0);
+ sleep(5);
+ char com4[300] = "echo \"echo \"dhcp-range=";
+ strcat(com4, dhcpRange);
+ strcat(com4, "\" >> /etc/dnsmasq.conf\" | lxc-attach -n ");
+ strcat(com4, containerName);
+ strcat(com4, " --");
+ dnsmasq_status = system(com4);
+ assert(dnsmasq_status == 0);
+ sleep(5);
+ char cmd[300] = "echo \"ifconfig ";
+ strcat(cmd, ifName);
+ strcat(cmd, " ");
+ strcat(cmd, listenAddress);
+ strcat(cmd, " netmask 255.255.255.0 up\" | lxc-attach -n ");
+ strcat(cmd, containerName);
+ strcat(cmd, " --");
+ dnsmasq_status = system(cmd);
+ assert(dnsmasq_status == 0);
+ sleep(2);
+ char com[500] = "echo \"service dnsmasq restart >> /dev/null\" | lxc-attach -n ";
+ strcat(com, containerName);
+ strcat(com, " --");
+ dnsmasq_status = system(com);
+ assert(dnsmasq_status == 0);
+ sleep(2);
+ PRINT_TEST_CASE_MSG("Configured dnsmasq in %s with interface name %s, listen-address = %s, dhcp-range = %s\n", containerName, ifName, listenAddress, dhcpRange);
+}
+
+/* Configure the NAT rules inside the container */
+void config_nat(const char *containerName, const char *listenAddress) {
+ char *last_dot_in_ip;
+ int last_ip_byte = 0;
+ char new_ip[300] = {0};
+ strncpy(new_ip, listenAddress, sizeof(new_ip) - 1);
+ assert((last_dot_in_ip = strrchr(new_ip, '.')));
+ assert(snprintf(last_dot_in_ip + 1, 4, "%d", last_ip_byte) >= 0);
+ char comd[300] = "echo \"iptables -t nat -A POSTROUTING -s ";
+ strcat(comd, new_ip);
+ strcat(comd, "/24 ! -d ");
+ strcat(comd, new_ip);
+ strcat(comd, "/24 -j MASQUERADE\" | lxc-attach -n ");
+ strcat(comd, containerName);
+ strcat(comd, " --");
+ int conf_nat_status = system(comd);
+ assert(conf_nat_status == 0);
+ sleep(2);
+ PRINT_TEST_CASE_MSG("Configured NAT on %s\n", containerName);
+}
+
+/* Creates a NAT layer on a specified bridge with certain dhcp range to allocate ips for nodes */
+void create_nat_layer(const char *containerName, const char *bridgeName, const char *ifName, const char *listenAddress, char *dhcpRange) {
+ create_bridge(bridgeName);
+ bring_if_up(bridgeName);
+ create_container_on_bridge(containerName, bridgeName, ifName);
+ config_dnsmasq(containerName, ifName, listenAddress, dhcpRange);
+ config_nat(containerName, listenAddress);
+ PRINT_TEST_CASE_MSG("NAT layer created with %s\n", containerName);
+}
+
+/* Destroys the NAT layer created */
+void destroy_nat_layer(const char *containerName, const char *bridgeName) {
+ bring_if_down(bridgeName);
+ delete_bridge(bridgeName);
+ char command[100] = "lxc-stop -n ";
+ strcat(command, containerName);
+ int container_stop_status = system(command);
+ assert(container_stop_status == 0);
+ char destroy[100] = "lxc-destroy -n ";
+ strcat(destroy, containerName);
+ strcat(destroy, " -s");
+ int container_destroy_status = system(destroy);
+ assert(container_destroy_status == 0);
+ PRINT_TEST_CASE_MSG("NAT layer destroyed with %s\n", containerName);
+}
+
+/* Add incoming firewall rules for ipv4 addresses with packet type and port number */
+void incoming_firewall_ipv4(const char *packetType, int portNumber) {
+ char buf[5];
+ snprintf(buf, sizeof(buf), "%d", portNumber);
+ assert(system("iptables -F") == 0);
+ assert(system("iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT") == 0);
+ assert(system("iptables -A INPUT -s 127.0.0.1 -d 127.0.0.1 -j ACCEPT") == 0);
+ char command[100] = "iptables -A INPUT -p ";
+ strcat(command, packetType);
+ strcat(command, " --dport ");
+ strcat(command, buf);
+ strcat(command, " -j ACCEPT");
+ assert(system(command) == 0);
+ sleep(2);
+ assert(system("iptables -A INPUT -j DROP") == 0);
+ PRINT_TEST_CASE_MSG("Firewall for incoming requests added on IPv4");
+ assert(system("iptables -L") == 0);
+}
+
+/* Add incoming firewall rules for ipv6 addresses with packet type and port number */
+void incoming_firewall_ipv6(const char *packetType, int portNumber) {
+ char buf[5];
+ snprintf(buf, sizeof(buf), "%d", portNumber);
+ assert(system("ip6tables -F") == 0);
+ assert(system("ip6tables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT") == 0);
+ assert(system("ip6tables -A INPUT -s ::1 -d ::1 -j ACCEPT") == 0);
+ char command[100] = "ip6tables -A INPUT -p ";
+ strcat(command, packetType);
+ strcat(command, " --dport ");
+ strcat(command, buf);
+ strcat(command, " -j ACCEPT");
+ assert(system(command) == 0);
+ sleep(2);
+ assert(system("ip6tables -A INPUT -j DROP") == 0);
+ PRINT_TEST_CASE_MSG("Firewall for incoming requests added on IPv6");
+ assert(system("ip6tables -L") == 0);
+}
+
+/* Add outgoing firewall rules for ipv4 addresses with packet type and port number */
+void outgoing_firewall_ipv4(const char *packetType, int portNumber) {
+ char buf[5];
+ snprintf(buf, sizeof(buf), "%d", portNumber);
+ assert(system("iptables -F") == 0);
+ assert(system("iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT") == 0);
+ assert(system("iptables -A OUTPUT -s 127.0.0.1 -d 127.0.0.1 -j ACCEPT") == 0);
+ char command[100] = "iptables -A OUTPUT -p ";
+ strcat(command, packetType);
+ strcat(command, " --dport ");
+ strcat(command, buf);
+ strcat(command, " -j ACCEPT");
+ assert(system(command) == 0);
+ sleep(2);
+ assert(system("iptables -A OUTPUT -j DROP") == 0);
+ PRINT_TEST_CASE_MSG("Firewall for outgoing requests added on IPv4");
+ assert(system("iptables -L") == 0);
+}
+
+/* Add outgoing firewall rules for ipv6 addresses with packet type and port number */
+void outgoing_firewall_ipv6(const char *packetType, int portNumber) {
+ char buf[5];
+ snprintf(buf, sizeof(buf), "%d", portNumber);
+ assert(system("ip6tables -F") == 0);
+ assert(system("ip6tables -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT") == 0);
+ assert(system("ip6tables -A OUTPUT -s ::1 -d ::1 -j ACCEPT") == 0);
+ char command[100] = "ip6tables -A OUTPUT -p ";
+ strcat(command, packetType);
+ strcat(command, " --dport ");
+ strcat(command, buf);
+ strcat(command, " -j ACCEPT");
+ assert(system(command) == 0);
+ sleep(2);
+ assert(system("ip6tables -A OUTPUT -j DROP") == 0);
+ PRINT_TEST_CASE_MSG("Firewall for outgoing requests added on IPv6");
+ assert(system("ip6tables -L") == 0);
+}
+
+void bridge_add(const char *bridge_name) {
+ char cmd[500];
+
+ assert(bridge_name);
+ assert(snprintf(cmd, sizeof(cmd), "brctl addbr %s", bridge_name) >= 0);
+ assert(system(cmd) == 0);
+ assert(snprintf(cmd, sizeof(cmd), "ifconfig %s up", bridge_name) >= 0);
+ assert(system(cmd) == 0);
+}
+
+void bridge_delete(const char *bridge_name) {
+ char cmd[500];
+
+ assert(bridge_name);
+ assert(snprintf(cmd, sizeof(cmd), "brctl delbr %s", bridge_name) >= 0);
+ assert(system(cmd) == 0);
+}
+
+void bridge_add_interface(const char *bridge_name, const char *interface_name) {
+ char cmd[500];
+
+ assert(bridge_name || interface_name);
+ assert(snprintf(cmd, sizeof(cmd), "brctl addif %s %s", bridge_name, interface_name) >= 0);
+ assert(system(cmd) == 0);
+}