Author: gherzan Date: Wed Apr 14 19:30:36 2010 New Revision: 2266 Log: libpisa: add firewall wrapper and Linux/iptables implementation. Added: trunk/libpisa/sysdep_fw.c Modified: trunk/Makefile.am trunk/libpisa/sysdep.h trunk/libpisa/tunnel.c Modified: trunk/Makefile.am ============================================================================== --- trunk/Makefile.am Wed Apr 14 16:38:45 2010 (r2265) +++ trunk/Makefile.am Wed Apr 14 19:30:36 2010 (r2266) @@ -81,6 +81,7 @@ libpisa/packet.c \ libpisa/pisaconf.c \ libpisa/scheduler.c \ + libpisa/sysdep_fw.c \ libpisa/sysdep_tun.c \ libpisa/tunnel.c \ libpisa/util.c Modified: trunk/libpisa/sysdep.h ============================================================================== --- trunk/libpisa/sysdep.h Wed Apr 14 16:38:45 2010 (r2265) +++ trunk/libpisa/sysdep.h Wed Apr 14 19:30:36 2010 (r2266) @@ -14,6 +14,7 @@ #ifndef PISA_SYSDEP_H #define PISA_SYSDEP_H +#include <stdint.h> #include <sys/types.h> #include "config.h" @@ -66,4 +67,45 @@ */ int pisa_tunnel_open_tundev(char *devicename, size_t len); +/* firewall rule action */ +#define FW_ADD 1 +#define FW_DELETE 2 + +/* firewall protocols */ +#define FW_TCP 1 +#define FW_UDP 2 + +/* firewall packet direction/chain */ +#define FW_INPUT 1 +#define FW_OUTPUT 2 + +/* firewall action/target */ +#define FW_ACCEPT 1 +#define FW_DROP 2 + +/** firewall command */ +struct firewall_cmd { + /** action: add of remove rule */ + short action; + /** direction with respect to the local host */ + short dir; + /** name of the interface */ + const char *iface; + /** transport protocol */ + int proto; + /** source port */ + uint16_t sport; + /** destination port */ + uint16_t dport; + /** target: DROP, ACCEPT */ + short target; +}; + +/** + * Give a command (add/remove a rule) to the system firewall. + * @param cmd the command to be performed + * @return 0 on success, nonzero otherwise + */ +int pisa_firewall_do(struct firewall_cmd *cmd); + #endif /* PISA_SYSDEP_H */ Added: trunk/libpisa/sysdep_fw.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ trunk/libpisa/sysdep_fw.c Wed Apr 14 19:30:36 2010 (r2266) @@ -0,0 +1,76 @@ +/* vim: set expandtab tabstop=4 shiftwidth=4: */ +/* + * Copyright (c) 2010, Distributed Systems Group, RWTH Aachen + * All rights reserved. + */ + +/** + * @file sysdep_fw.c + * @brief System firewall control routines + * @author Mircea Gherzan <mgherzan@xxxxxxxxx> + * @date April 2010 + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "sysdep.h" + +#define CMD_SIZE 256 + +int pisa_firewall_do(struct firewall_cmd *cmd) +{ + char line[CMD_SIZE], temp[CMD_SIZE/4]; + + if ((!cmd->action) || (!cmd->dir) || (!cmd->target)) { + return -1; + } + + snprintf(line, sizeof(line), "iptables -%c %s ", + (cmd->action == FW_ADD) ? 'A' : 'D', + (cmd->dir == FW_INPUT) ? "INPUT" : "OUTPUT"); + + if (cmd->iface) { + snprintf(temp, sizeof(temp), "-%c %s ", + (cmd->dir == FW_INPUT) ? 'i' : 'o', cmd->iface); + strcat(line, temp); + } + + if (cmd->proto) { + snprintf(temp, sizeof(temp), "-p %s ", + (cmd->proto == FW_TCP) ? "tcp" : "udp"); + strcat(line, temp); + + if (cmd->sport) { + sprintf(temp, "--sport %d ", cmd->sport); + strcat(line, temp); + } + if (cmd->dport) { + sprintf(temp, "--dport %d ", cmd->dport); + strcat(line, temp); + } + } + + snprintf(temp, sizeof(temp), "-j %s", + (cmd->target == FW_ACCEPT) ? "ACCEPT" : "DROP"); + strcat(line, temp); + + printf("FIREWALL COMMAND: %s\n", line); + + return system(line); +} + +#ifdef __linux__ + + +#elif defined(__APPLE__) + +int pisa_firewall_do(struct firewall_cmd *cmd) +{ + /*TODO: ipfw implementation */ + + return 0; +} + +#endif Modified: trunk/libpisa/tunnel.c ============================================================================== --- trunk/libpisa/tunnel.c Wed Apr 14 16:38:45 2010 (r2265) +++ trunk/libpisa/tunnel.c Wed Apr 14 19:30:36 2010 (r2266) @@ -26,6 +26,7 @@ #include "debug.h" #include "tunnel.h" #include "util.h" +#include "sysdep.h" /** * Configure the newly created tunnel device - at the moment this calls @@ -43,6 +44,7 @@ int mtu) { char buffer[1024], ip[INET_ADDRSTRLEN], mask[INET_ADDRSTRLEN]; + struct firewall_cmd cmd; inet_ntop(AF_INET, ipv4, ip, sizeof(ip)); inet_ntop(AF_INET, netmask, mask, sizeof(ip)); @@ -54,18 +56,22 @@ __FUNCTION__); } - snprintf(buffer, sizeof(buffer), - "iptables -A INPUT -i %s -p udp --sport 50500 --dport 50500 -j DROP", - devicename); - if (system(buffer) < 0) { - PISA_ERROR("ERROR: %s: cannot configure iptables.\n", __FUNCTION__); + cmd.action = FW_ADD; + cmd.dir = FW_INPUT; + cmd.iface = devicename; + cmd.proto = FW_UDP; + cmd.sport = 50500; + cmd.dport = 50500; + cmd.target = FW_DROP; + + if (pisa_firewall_do(&cmd)) { + PISA_ERROR("ERROR: %s: cannot configure firewall.\n", __FUNCTION__); } - snprintf(buffer, sizeof(buffer), - "iptables -A OUTPUT -o %s -p udp --sport 50500 --dport 50500 -j DROP", - devicename); - if (system(buffer) < 0) { - PISA_ERROR("ERROR: %s: cannot configure iptables.\n", __FUNCTION__); + cmd.dir = FW_OUTPUT; + + if (pisa_firewall_do(&cmd)) { + PISA_ERROR("ERROR: %s: cannot configure firewall.\n", __FUNCTION__); } } @@ -76,20 +82,24 @@ */ void pisa_tunnel_remove_firewall_rules(const char *devicename) { - char buffer[1024]; + struct firewall_cmd cmd; - snprintf(buffer, sizeof(buffer), - "iptables -D INPUT -i %s -p udp --sport 50500 --dport 50500 -j DROP", - devicename); - if (system(buffer) < 0) { - PISA_ERROR("ERROR: %s: cannot configure iptables.\n", __FUNCTION__); + cmd.action = FW_DELETE; + cmd.dir = FW_INPUT; + cmd.iface = devicename; + cmd.proto = FW_UDP; + cmd.sport = 50500; + cmd.dport = 50500; + cmd.target = FW_DROP; + + if (pisa_firewall_do(&cmd)) { + PISA_ERROR("ERROR: %s: cannot configure firewall.\n", __FUNCTION__); } - snprintf(buffer, sizeof(buffer), - "iptables -D OUTPUT -o %s -p udp --sport 50500 --dport 50500 -j DROP", - devicename); - if (system(buffer) < 0) { - PISA_ERROR("ERROR: %s: cannot configure iptables.\n", __FUNCTION__); + cmd.dir = FW_OUTPUT; + + if (pisa_firewall_do(&cmd)) { + PISA_ERROR("ERROR: %s: cannot configure firewall.\n", __FUNCTION__); } }