Package net.floodlightcontroller.firewall

Source Code of net.floodlightcontroller.firewall.FirewallRulesResource

/**
*    Copyright 2011, Big Switch Networks, Inc.
*    Originally created by Amer Tahir
*
*    Licensed under the Apache License, Version 2.0 (the "License"); you may
*    not use this file except in compliance with the License. You may obtain
*    a copy of the License at
*
*         http://www.apache.org/licenses/LICENSE-2.0
*
*    Unless required by applicable law or agreed to in writing, software
*    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
*    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
*    License for the specific language governing permissions and limitations
*    under the License.
**/

package net.floodlightcontroller.firewall;

import java.io.IOException;
import java.util.Iterator;
import java.util.List;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.MappingJsonFactory;
import org.openflow.util.HexString;
import org.restlet.resource.Delete;
import org.restlet.resource.Post;
import org.restlet.resource.Get;
import org.restlet.resource.ServerResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import net.floodlightcontroller.packet.Ethernet;
import net.floodlightcontroller.packet.IPv4;

public class FirewallRulesResource extends ServerResource {
    protected static Logger log = LoggerFactory.getLogger(FirewallRulesResource.class);

    @Get("json")
    public List<FirewallRule> retrieve() {
        IFirewallService firewall =
                (IFirewallService)getContext().getAttributes().
                get(IFirewallService.class.getCanonicalName());

        return firewall.getRules();
    }

    /**
     * Takes a Firewall Rule string in JSON format and parses it into
     * our firewall rule data structure, then adds it to the firewall.
     * @param fmJson The Firewall rule entry in JSON format.
     * @return A string status message
     */
    @Post
    public String store(String fmJson) {
        IFirewallService firewall =
                (IFirewallService)getContext().getAttributes().
                get(IFirewallService.class.getCanonicalName());

        FirewallRule rule;
        try {
            rule = jsonToFirewallRule(fmJson);
        } catch (IOException e) {
            log.error("Error parsing firewall rule: " + fmJson, e);
            return "{\"status\" : \"Error! Could not parse firewall rule, see log for details.\"}";
        }
        String status = null;
        if (checkRuleExists(rule, firewall.getRules())) {
            status = "Error! A similar firewall rule already exists.";
            log.error(status);
          return ("{\"status\" : \"" + status + "\"}");
        } else {
            // add rule to firewall
            firewall.addRule(rule);
            status = "Rule added";
          return ("{\"status\" : \"" + status + "\", \"rule-id\" : \""+ Integer.toString(rule.ruleid) + "\"}");
        }
    }

    /**
     * Takes a Firewall Rule string in JSON format and parses it into
     * our firewall rule data structure, then deletes it from the firewall.
     * @param fmJson The Firewall rule entry in JSON format.
     * @return A string status message
     */

    @Delete
    public String remove(String fmJson) {
        IFirewallService firewall =
                (IFirewallService)getContext().getAttributes().
                get(IFirewallService.class.getCanonicalName());

        FirewallRule rule;
        try {
            rule = jsonToFirewallRule(fmJson);
        } catch (IOException e) {
            log.error("Error parsing firewall rule: " + fmJson, e);
            return "{\"status\" : \"Error! Could not parse firewall rule, see log for details.\"}";
        }
        String status = null;
        boolean exists = false;
        Iterator<FirewallRule> iter = firewall.getRules().iterator();
        while (iter.hasNext()) {
            FirewallRule r = iter.next();
            if (r.ruleid == rule.ruleid) {
                exists = true;
                break;
            }
        }
        if (!exists) {
            status = "Error! Can't delete, a rule with this ID doesn't exist.";
            log.error(status);
        } else {
            // delete rule from firewall
            firewall.deleteRule(rule.ruleid);
            status = "Rule deleted";
        }
        return ("{\"status\" : \"" + status + "\"}");
    }

    /**
     * Turns a JSON formatted Firewall Rule string into a FirewallRule instance
     * @param fmJson The JSON formatted static firewall rule
     * @return The FirewallRule instance
     * @throws IOException If there was an error parsing the JSON
     */

    public static FirewallRule jsonToFirewallRule(String fmJson) throws IOException {
        FirewallRule rule = new FirewallRule();
        MappingJsonFactory f = new MappingJsonFactory();
        JsonParser jp;

        try {
            jp = f.createJsonParser(fmJson);
        } catch (JsonParseException e) {
            throw new IOException(e);
        }

        jp.nextToken();
        if (jp.getCurrentToken() != JsonToken.START_OBJECT) {
            throw new IOException("Expected START_OBJECT");
        }

        while (jp.nextToken() != JsonToken.END_OBJECT) {
            if (jp.getCurrentToken() != JsonToken.FIELD_NAME) {
                throw new IOException("Expected FIELD_NAME");
            }

            String n = jp.getCurrentName();
            jp.nextToken();
            if (jp.getText().equals(""))
                continue;

            String tmp;

            // This is currently only applicable for remove().  In store(), ruleid takes a random number
            if (n == "ruleid") {
                rule.ruleid = Integer.parseInt(jp.getText());
            }

            // This assumes user having dpid info for involved switches
            else if (n == "switchid") {
                tmp = jp.getText();
                if (tmp.equalsIgnoreCase("-1") == false) {
                    // user inputs hex format dpid
                    rule.dpid = HexString.toLong(tmp);
                    rule.wildcard_dpid = false;
                }
            }

            else if (n == "src-inport") {
                rule.in_port = Short.parseShort(jp.getText());
                rule.wildcard_in_port = false;
            }

            else if (n == "src-mac") {
                tmp = jp.getText();
                if (tmp.equalsIgnoreCase("ANY") == false) {
                    rule.wildcard_dl_src = false;
                    rule.dl_src = Ethernet.toLong(Ethernet.toMACAddress(tmp));
                }
            }

            else if (n == "dst-mac") {
                tmp = jp.getText();
                if (tmp.equalsIgnoreCase("ANY") == false) {
                    rule.wildcard_dl_dst = false;
                    rule.dl_dst = Ethernet.toLong(Ethernet.toMACAddress(tmp));
                }
            }

            else if (n == "dl-type") {
                tmp = jp.getText();
                if (tmp.equalsIgnoreCase("ARP")) {
                    rule.wildcard_dl_type = false;
                    rule.dl_type = Ethernet.TYPE_ARP;
                }
                if (tmp.equalsIgnoreCase("IPv4")) {
                    rule.wildcard_dl_type = false;
                    rule.dl_type = Ethernet.TYPE_IPv4;
                }
            }

            else if (n == "src-ip") {
                tmp = jp.getText();
                if (tmp.equalsIgnoreCase("ANY") == false) {
                    rule.wildcard_nw_src = false;
                    rule.wildcard_dl_type = false;
                    rule.dl_type = Ethernet.TYPE_IPv4;
                    int[] cidr = IPCIDRToPrefixBits(tmp);
                    rule.nw_src_prefix = cidr[0];
                    rule.nw_src_maskbits = cidr[1];
                }
            }

            else if (n == "dst-ip") {
                tmp = jp.getText();
                if (tmp.equalsIgnoreCase("ANY") == false) {
                    rule.wildcard_nw_dst = false;
                    rule.wildcard_dl_type = false;
                    rule.dl_type = Ethernet.TYPE_IPv4;
                    int[] cidr = IPCIDRToPrefixBits(tmp);
                    rule.nw_dst_prefix = cidr[0];
                    rule.nw_dst_maskbits = cidr[1];
                }
            }

            else if (n == "nw-proto") {
                tmp = jp.getText();
                if (tmp.equalsIgnoreCase("TCP")) {
                    rule.wildcard_nw_proto = false;
                    rule.nw_proto = IPv4.PROTOCOL_TCP;
                    rule.wildcard_dl_type = false;
                    rule.dl_type = Ethernet.TYPE_IPv4;
                } else if (tmp.equalsIgnoreCase("UDP")) {
                    rule.wildcard_nw_proto = false;
                    rule.nw_proto = IPv4.PROTOCOL_UDP;
                    rule.wildcard_dl_type = false;
                    rule.dl_type = Ethernet.TYPE_IPv4;
                } else if (tmp.equalsIgnoreCase("ICMP")) {
                    rule.wildcard_nw_proto = false;
                    rule.nw_proto = IPv4.PROTOCOL_ICMP;
                    rule.wildcard_dl_type = false;
                    rule.dl_type = Ethernet.TYPE_IPv4;
                }
            }

            else if (n == "tp-src") {
                rule.wildcard_tp_src = false;
                rule.tp_src = Short.parseShort(jp.getText());
            }

            else if (n == "tp-dst") {
                rule.wildcard_tp_dst = false;
                rule.tp_dst = Short.parseShort(jp.getText());
            }

            else if (n == "priority") {
                rule.priority = Integer.parseInt(jp.getText());
            }

            else if (n == "action") {
                if (jp.getText().equalsIgnoreCase("allow") == true) {
                    rule.action = FirewallRule.FirewallAction.ALLOW;
                } else if (jp.getText().equalsIgnoreCase("deny") == true) {
                    rule.action = FirewallRule.FirewallAction.DENY;
                }
            }
        }

        return rule;
    }

    public static int[] IPCIDRToPrefixBits(String cidr) {
        int ret[] = new int[2];

        // as IP can also be a prefix rather than an absolute address
        // split it over "/" to get the bit range
        String[] parts = cidr.split("/");
        String cidr_prefix = parts[0].trim();
        int cidr_bits = 0;
        if (parts.length == 2) {
            try {
                cidr_bits = Integer.parseInt(parts[1].trim());
            } catch (Exception exp) {
                cidr_bits = 32;
            }
        }
        ret[0] = IPv4.toIPv4Address(cidr_prefix);
        ret[1] = cidr_bits;

        return ret;
    }

    public static boolean checkRuleExists(FirewallRule rule, List<FirewallRule> rules) {
        Iterator<FirewallRule> iter = rules.iterator();
        while (iter.hasNext()) {
            FirewallRule r = iter.next();

            // check if we find a similar rule
            if (rule.isSameAs(r)) {
                return true;
            }
        }

        // no rule matched, so it doesn't exist in the rules
        return false;
    }
}
TOP

Related Classes of net.floodlightcontroller.firewall.FirewallRulesResource

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.