package net.floodlightcontroller.firewall;

import org.openflow.protocol.OFMatch;

import net.floodlightcontroller.packet.Ethernet;
import net.floodlightcontroller.packet.IPacket;
import net.floodlightcontroller.packet.IPv4;
import net.floodlightcontroller.packet.TCP;
import net.floodlightcontroller.packet.UDP;

public class FirewallRule implements Comparable<FirewallRule> {
    public int ruleid;

    public long dpid; 
    public short in_port; 
    public long dl_src; 
    public long dl_dst; 
    public short dl_type; 
    public int nw_src_prefix; 
    public int nw_src_maskbits;
    public int nw_dst_prefix;
    public int nw_dst_maskbits;
    public short nw_proto;
    public short tp_src;
    public short tp_dst;

    public boolean wildcard_dpid;
    public boolean wildcard_in_port; 
    public boolean wildcard_dl_src;
    public boolean wildcard_dl_dst;
    public boolean wildcard_dl_type;
    public boolean wildcard_nw_src;
    public boolean wildcard_nw_dst;
    public boolean wildcard_nw_proto;
    public boolean wildcard_tp_src;
    public boolean wildcard_tp_dst;

    public int priority = 0;

    public FirewallAction action;

    public enum FirewallAction {
        /*
         * DENY: Deny rule
         * ALLOW: Allow rule
         */
        DENY, ALLOW
    }

    public FirewallRule() {
        this.in_port = 0; 
        this.dl_src = 0;
        this.nw_src_prefix = 0;
        this.nw_src_maskbits = 0; 
        this.dl_dst = 0;
        this.nw_proto = 0;
        this.tp_src = 0;
        this.tp_dst = 0;
        this.dl_dst = 0;
        this.nw_dst_prefix = 0;
        this.nw_dst_maskbits = 0; 
        this.dpid = -1;
        this.wildcard_dpid = true; 
        this.wildcard_in_port = true; 
        this.wildcard_dl_src = true; 
        this.wildcard_dl_dst = true; 
        this.wildcard_dl_type = true; 
        this.wildcard_nw_src = true; 
        this.wildcard_nw_dst = true; 
        this.wildcard_nw_proto = true; 
        this.wildcard_tp_src = true; 
        this.wildcard_tp_dst = true; 
        this.priority = 0; 
        this.action = FirewallAction.ALLOW; 
        this.ruleid = 0; 
    }

    /**
     * Generates a unique ID for the instance
     * 
     * @return int representing the unique id
     */
    public int genID() {
        int uid = this.hashCode();
        if (uid < 0) {
            uid = Math.abs(uid);
            uid = uid * 15551;
        }
        return uid;
    }

    /**
     * Comparison method for Collections.sort method
     * 
     * @param rule
     *            the rule to compare with
     * @return number representing the result of comparison 0 if equal negative
     *         if less than 'rule' greater than zero if greater priority rule
     *         than 'rule'
     */
    @Override
    public int compareTo(FirewallRule rule) {
        return this.priority - rule.priority;
    }

    /**
     * Determines if this instance matches an existing rule instance
     * 
     * @param r
     *            : the FirewallRule instance to compare with
     * @return boolean: true if a match is found
     **/
    public boolean isSameAs(FirewallRule r) {
        if (this.action != r.action
                || this.wildcard_dl_type != r.wildcard_dl_type
                || (this.wildcard_dl_type == false && this.dl_type == r.dl_type)
                || this.wildcard_tp_src != r.wildcard_tp_src
                || (this.wildcard_tp_src == false && this.tp_src != r.tp_src)
                || this.wildcard_tp_dst != r.wildcard_tp_dst
                || (this.wildcard_tp_dst == false &&this.tp_dst != r.tp_dst)
                || this.wildcard_dpid != r.wildcard_dpid
                || (this.wildcard_dpid == false && this.dpid != r.dpid)
                || this.wildcard_in_port != r.wildcard_in_port
                || (this.wildcard_in_port == false && this.in_port != r.in_port)
                || this.wildcard_nw_src != r.wildcard_nw_src
                || (this.wildcard_nw_src == false && (this.nw_src_prefix != r.nw_src_prefix || this.nw_src_maskbits != r.nw_src_maskbits))
                || this.wildcard_dl_src != r.wildcard_dl_src
                || (this.wildcard_dl_src == false && this.dl_src != r.dl_src)
                || this.wildcard_nw_proto != r.wildcard_nw_proto
                || (this.wildcard_nw_proto == false && this.nw_proto != r.nw_proto)
                || this.wildcard_nw_dst != r.wildcard_nw_dst
                || (this.wildcard_nw_dst == false && (this.nw_dst_prefix != r.nw_dst_prefix || this.nw_dst_maskbits != r.nw_dst_maskbits))
                || this.wildcard_dl_dst != r.wildcard_dl_dst                
                || (this.wildcard_dl_dst == false && this.dl_dst != r.dl_dst)) {
            return false;
        }
        return true;
    }

    /**
     * Matches this rule to a given flow - incoming packet
     * 
     * @param switchDpid
     *            the Id of the connected switch
     * @param inPort
     *            the switch port where the packet originated from
     * @param packet
     *            the Ethernet packet that arrives at the switch
     * @param wildcards
     *            the pair of wildcards (allow and deny) given by Firewall
     *            module that is used by the Firewall module's matchWithRule
     *            method to derive wildcards for the decision to be taken
     * @return true if the rule matches the given packet-in, false otherwise
     */
    public boolean matchesFlow(long switchDpid, short inPort, Ethernet packet,
            WildcardsPair wildcards) {
        IPacket pkt = packet.getPayload();

        // dl_type type
        IPv4 pkt_ip = null;

        // nw_proto types
        TCP pkt_tcp = null;
        UDP pkt_udp = null;

        // tp_src and tp_dst (tp port numbers)
        short pkt_tp_src = 0;
        short pkt_tp_dst = 0;

        // switchID matches?
        if (wildcard_dpid == false && dpid != switchDpid)
            return false;

        // in_port matches?
        if (wildcard_in_port == false && in_port != inPort)
            return false;
        if (action == FirewallRule.FirewallAction.DENY) {
            wildcards.drop &= ~OFMatch.OFPFW_IN_PORT;
        } else {
            wildcards.allow &= ~OFMatch.OFPFW_IN_PORT;
        }

        // mac address (src and dst) match?
        if (wildcard_dl_src == false
                && dl_src != packet.getSourceMAC().toLong())
            return false;
        if (action == FirewallRule.FirewallAction.DENY) {
            wildcards.drop &= ~OFMatch.OFPFW_DL_SRC;
        } else {
            wildcards.allow &= ~OFMatch.OFPFW_DL_SRC;
        }

        if (wildcard_dl_dst == false
                && dl_dst != packet.getDestinationMAC().toLong())
            return false;
        if (action == FirewallRule.FirewallAction.DENY) {
            wildcards.drop &= ~OFMatch.OFPFW_DL_DST;
        } else {
            wildcards.allow &= ~OFMatch.OFPFW_DL_DST;
        }

        // dl_type check: ARP, IP

        // if this is not an ARP rule but the pkt is ARP,
        // return false match - no need to continue protocol specific check
        if (wildcard_dl_type == false) {
            if (dl_type == Ethernet.TYPE_ARP) {
                if (packet.getEtherType() != Ethernet.TYPE_ARP)
                    return false;
                else {
                    if (action == FirewallRule.FirewallAction.DENY) {
                        wildcards.drop &= ~OFMatch.OFPFW_DL_TYPE;
                    } else {
                        wildcards.allow &= ~OFMatch.OFPFW_DL_TYPE;
                    }
                }
            } else if (dl_type == Ethernet.TYPE_IPv4) {
                if (packet.getEtherType() != Ethernet.TYPE_IPv4)
                    return false;
                else {
                    if (action == FirewallRule.FirewallAction.DENY) {
                        wildcards.drop &= ~OFMatch.OFPFW_NW_PROTO;
                    } else {
                        wildcards.allow &= ~OFMatch.OFPFW_NW_PROTO;
                    }
                    // IP packets, proceed with ip address check
                    pkt_ip = (IPv4) pkt;

                    // IP addresses (src and dst) match?
                    if (wildcard_nw_src == false
                            && this.matchIPAddress(nw_src_prefix,
                                    nw_src_maskbits, pkt_ip.getSourceAddress()) == false)
                        return false;
                    if (action == FirewallRule.FirewallAction.DENY) {
                        wildcards.drop &= ~OFMatch.OFPFW_NW_SRC_ALL;
                        wildcards.drop |= (nw_src_maskbits << OFMatch.OFPFW_NW_SRC_SHIFT);
                    } else {
                        wildcards.allow &= ~OFMatch.OFPFW_NW_SRC_ALL;
                        wildcards.allow |= (nw_src_maskbits << OFMatch.OFPFW_NW_SRC_SHIFT);
                    }

                    if (wildcard_nw_dst == false
                            && this.matchIPAddress(nw_dst_prefix,
                                    nw_dst_maskbits,
                                    pkt_ip.getDestinationAddress()) == false)
                        return false;
                    if (action == FirewallRule.FirewallAction.DENY) {
                        wildcards.drop &= ~OFMatch.OFPFW_NW_DST_ALL;
                        wildcards.drop |= (nw_dst_maskbits << OFMatch.OFPFW_NW_DST_SHIFT);
                    } else {
                        wildcards.allow &= ~OFMatch.OFPFW_NW_DST_ALL;
                        wildcards.allow |= (nw_dst_maskbits << OFMatch.OFPFW_NW_DST_SHIFT);
                    }

                    // nw_proto check
                    if (wildcard_nw_proto == false) {
                        if (nw_proto == IPv4.PROTOCOL_TCP) {
                            if (pkt_ip.getProtocol() != IPv4.PROTOCOL_TCP)
                                return false;
                            else {
                                pkt_tcp = (TCP) pkt_ip.getPayload();
                                pkt_tp_src = pkt_tcp.getSourcePort();
                                pkt_tp_dst = pkt_tcp.getDestinationPort();
                            }
                        } else if (nw_proto == IPv4.PROTOCOL_UDP) {
                            if (pkt_ip.getProtocol() != IPv4.PROTOCOL_UDP)
                                return false;
                            else {
                                pkt_udp = (UDP) pkt_ip.getPayload();
                                pkt_tp_src = pkt_udp.getSourcePort();
                                pkt_tp_dst = pkt_udp.getDestinationPort();
                            }
                        } else if (nw_proto == IPv4.PROTOCOL_ICMP) {
                            if (pkt_ip.getProtocol() != IPv4.PROTOCOL_ICMP)
                                return false;
                            else {
                                // nothing more needed for ICMP
                            }
                        }
                        if (action == FirewallRule.FirewallAction.DENY) {
                            wildcards.drop &= ~OFMatch.OFPFW_NW_PROTO;
                        } else {
                            wildcards.allow &= ~OFMatch.OFPFW_NW_PROTO;
                        }

                        // TCP/UDP source and destination ports match?
                        if (pkt_tcp != null || pkt_udp != null) {
                            // does the source port match?
                            if (tp_src != 0 && tp_src != pkt_tp_src)
                                return false;
                            if (action == FirewallRule.FirewallAction.DENY) {
                                wildcards.drop &= ~OFMatch.OFPFW_TP_SRC;
                            } else {
                                wildcards.allow &= ~OFMatch.OFPFW_TP_SRC;
                            }

                            // does the destination port match?
                            if (tp_dst != 0 && tp_dst != pkt_tp_dst)
                                return false;
                            if (action == FirewallRule.FirewallAction.DENY) {
                                wildcards.drop &= ~OFMatch.OFPFW_TP_DST;
                            } else {
                                wildcards.allow &= ~OFMatch.OFPFW_TP_DST;
                            }
                        }
                    }

                }
            } else {
                // non-IP packet - not supported - report no match
                return false;
            }
        }
        if (action == FirewallRule.FirewallAction.DENY) {
            wildcards.drop &= ~OFMatch.OFPFW_DL_TYPE;
        } else {
            wildcards.allow &= ~OFMatch.OFPFW_DL_TYPE;
        }

        // all applicable checks passed
        return true;
    }

    /**
     * Determines if rule's CIDR address matches IP address of the packet
     * 
     * @param rulePrefix
     *            prefix part of the CIDR address
     * @param ruleBits
     *            the size of mask of the CIDR address
     * @param packetAddress
     *            the IP address of the incoming packet to match with
     * @return true if CIDR address matches the packet's IP address, false
     *         otherwise
     */
    protected boolean matchIPAddress(int rulePrefix, int ruleBits,
            int packetAddress) {
        boolean matched = true;

        int rule_iprng = 32 - ruleBits;
        int rule_ipint = rulePrefix;
        int pkt_ipint = packetAddress;
        // if there's a subnet range (bits to be wildcarded > 0)
        if (rule_iprng > 0) {
            // right shift bits to remove rule_iprng of LSB that are to be
            // wildcarded
            rule_ipint = rule_ipint >> rule_iprng;
            pkt_ipint = pkt_ipint >> rule_iprng;
            // now left shift to return to normal range, except that the
            // rule_iprng number of LSB
            // are now zeroed
            rule_ipint = rule_ipint << rule_iprng;
            pkt_ipint = pkt_ipint << rule_iprng;
        }
        // check if we have a match
        if (rule_ipint != pkt_ipint)
            matched = false;

        return matched;
    }

    @Override
    public int hashCode() {
        final int prime = 2521;
        int result = super.hashCode();
        result = prime * result + (int) dpid;
        result = prime * result + in_port;
        result = prime * result + (int) dl_src;
        result = prime * result + (int) dl_dst;
        result = prime * result + dl_type;
        result = prime * result + nw_src_prefix;
        result = prime * result + nw_src_maskbits;
        result = prime * result + nw_dst_prefix;
        result = prime * result + nw_dst_maskbits;
        result = prime * result + nw_proto;
        result = prime * result + tp_src;
        result = prime * result + tp_dst;
        result = prime * result + action.ordinal();
        result = prime * result + priority;
        result = prime * result + (new Boolean(wildcard_dpid)).hashCode();
        result = prime * result + (new Boolean(wildcard_in_port)).hashCode();
        result = prime * result + (new Boolean(wildcard_dl_src)).hashCode();
        result = prime * result + (new Boolean(wildcard_dl_dst)).hashCode();
        result = prime * result + (new Boolean(wildcard_dl_type)).hashCode();
        result = prime * result + (new Boolean(wildcard_nw_src)).hashCode();
        result = prime * result + (new Boolean(wildcard_nw_dst)).hashCode();
        result = prime * result + (new Boolean(wildcard_nw_proto)).hashCode();
        result = prime * result + (new Boolean(wildcard_tp_src)).hashCode();
        result = prime * result + (new Boolean(wildcard_tp_dst)).hashCode();
        return result;
    }
}
