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
}
}