/* -*- P4_16 -*- */ #ifndef PARSERS_P4 #define PARSERS_P4 #include #include #include "headers.p4" parser MyParser(packet_in packet, out headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) { state start { packet.extract(hdr.ethernet); transition select(hdr.ethernet.ethertype){ TYPE_IPV4: ipv4; TYPE_IPV6: ipv6; default: accept; } } state ipv4 { packet.extract(hdr.ipv4); meta.tcp_length = hdr.ipv4.totalLen - 16w20; transition select(hdr.ipv4.protocol){ PROTO_TCP: tcp; PROTO_UDP: udp; PROTO_ICMP: icmp; default: accept; } } state ipv6 { packet.extract(hdr.ipv6); meta.tcp_length = hdr.ipv6.payload_length; transition select(hdr.ipv6.next_header){ PROTO_TCP: tcp; PROTO_UDP: udp; PROTO_ICMP6: icmp6; default: accept; } } state icmp6 { packet.extract(hdr.icmp6); transition select(hdr.icmp6.type) { ICMP6_NS: icmp6_neighbor_solicitation; default: accept; } } state icmp6_neighbor_solicitation { packet.extract(hdr.icmp6_na_ns); /* BUG: This MIGHT fail */ packet.extract(hdr.icmp6_option_link_layer_addr); transition accept; } /* Leaf */ state tcp { packet.extract(hdr.tcp); transition accept; } state udp { packet.extract(hdr.udp); transition accept; } // state icmp6 { // packet.extract(hdr.icmp6); // transition accept; // } state icmp { packet.extract(hdr.icmp); transition accept; } } /************************************************************************* ************************ D E P A R S E R ******************************* *************************************************************************/ control MyDeparser(packet_out packet, in headers hdr) { apply { /* always */ packet.emit(hdr.ethernet); /* only if information is sent to the controller */ packet.emit(hdr.cpu); /* either */ packet.emit(hdr.ipv4); packet.emit(hdr.ipv6); /* either */ packet.emit(hdr.tcp); packet.emit(hdr.udp); packet.emit(hdr.icmp); /* might be more than one subtype */ packet.emit(hdr.icmp6); packet.emit(hdr.icmp6_na_ns); packet.emit(hdr.icmp6_option_link_layer_addr); } } #endif