'Constructs an exact match for the given packet
@param in_port The switch port the packet arrived on if you want
the resulting match to have its in_port set.
If "packet" is a packet_in, this is ignored.
@param packet  A pox.packet.ethernet instance or a packet_in
@param spec_frags Handle IP fragments as specified in the spec.'

@classmethod
def from_packet(cls, packet, in_port=None, spec_frags=False):

    if isinstance(packet, ofp_packet_in):
        in_port = packet.in_port
        packet = ethernet(packet.data)
    assert assert_type('packet', packet, ethernet, none_ok=False)
    match = cls()
    if (in_port is not None):
        match.in_port = in_port
    match.dl_src = packet.src
    match.dl_dst = packet.dst
    match.dl_type = packet.type
    p = packet.next
    if (packet.type < 1536):
        match.dl_type = OFP_DL_TYPE_NOT_ETH_TYPE
    if isinstance(p, llc):
        if (p.has_snap and (p.oui == '\x00\x00\x00')):
            match.dl_type = p.eth_type
            p = p.next
    if isinstance(p, vlan):
        match.dl_type = p.eth_type
        match.dl_vlan = p.id
        match.dl_vlan_pcp = p.pcp
        p = p.next
    else:
        match.dl_vlan = OFP_VLAN_NONE
        match.dl_vlan_pcp = 0
    if isinstance(p, ipv4):
        match.nw_src = p.srcip
        match.nw_dst = p.dstip
        match.nw_proto = p.protocol
        match.nw_tos = p.tos
        if (spec_frags and ((p.flags & p.MF_FLAG) or (p.frag != 0))):
            match.tp_src = 0
            match.tp_dst = 0
            return match
        p = p.next
        if (isinstance(p, udp) or isinstance(p, tcp)):
            match.tp_src = p.srcport
            match.tp_dst = p.dstport
        elif isinstance(p, icmp):
            match.tp_src = p.type
            match.tp_dst = p.code
    elif isinstance(p, arp):
        if (p.opcode <= 255):
            match.nw_proto = p.opcode
            match.nw_src = p.protosrc
            match.nw_dst = p.protodst
    return match
