/* -*- P4_16 -*- */ #include #include /************************************************************************* *********************** C O N S T A N T S ***************************** *************************************************************************/ /* Define the useful global constants for your program */ const bit<16> ETHERTYPE_IPV4 = 0x0800; const bit<16> ETHERTYPE_ARP = 0x0806; const bit<8> IPPROTO_ICMP = 0x01; /************************************************************************* *********************** H E A D E R S ********************************* *************************************************************************/ /* Define the headers the program will recognize */ /* * Standard ethernet header */ typedef bit<48> mac_addr_t; typedef bit<32> ipv4_addr_t; typedef bit<9> port_id_t; header ethernet_t { mac_addr_t dstAddr; mac_addr_t srcAddr; bit<16> etherType; } header ipv4_t { bit<4> version; bit<4> ihl; bit<8> diffserv; bit<16> totalLen; bit<16> identification; bit<3> flags; bit<13> fragOffset; bit<8> ttl; bit<8> protocol; bit<16> hdrChecksum; ipv4_addr_t srcAddr; ipv4_addr_t dstAddr; } const bit<16> ARP_HTYPE_ETHERNET = 0x0001; const bit<16> ARP_PTYPE_IPV4 = 0x0800; const bit<8> ARP_HLEN_ETHERNET = 6; const bit<8> ARP_PLEN_IPV4 = 4; const bit<16> ARP_OPER_REQUEST = 1; const bit<16> ARP_OPER_REPLY = 2; header arp_t { bit<16> htype; bit<16> ptype; bit<8> hlen; bit<8> plen; bit<16> oper; } header arp_ipv4_t { mac_addr_t sha; ipv4_addr_t spa; mac_addr_t tha; ipv4_addr_t tpa; } const bit<8> ICMP_ECHO_REQUEST = 8; const bit<8> ICMP_ECHO_REPLY = 0; header icmp_t { bit<8> type; bit<8> code; bit<16> checksum; } /* Assemble headers in a single struct */ struct my_headers_t { ethernet_t ethernet; arp_t arp; arp_ipv4_t arp_ipv4; ipv4_t ipv4; icmp_t icmp; } /************************************************************************* *********************** M E T A D A T A ******************************* *************************************************************************/ /* Define the global metadata for your program */ struct my_metadata_t { ipv4_addr_t dst_ipv4; mac_addr_t mac_da; mac_addr_t mac_sa; port_id_t egress_port; mac_addr_t my_mac; } /************************************************************************* *********************** P A R S E R *********************************** *************************************************************************/ parser MyParser( packet_in packet, out my_headers_t hdr, inout my_metadata_t meta, inout standard_metadata_t standard_metadata) { state start { packet.extract(hdr.ethernet); transition select(hdr.ethernet.etherType) { ETHERTYPE_IPV4 : parse_ipv4; ETHERTYPE_ARP : parse_arp; default : accept; } } state parse_arp { /* * TODO: parse ARP. If the ARP protocol field is * IPV4, transtion to parse_arp_ipv4 */ transition accept; } state parse_arp_ipv4 { /* * TODO: parse ARP_IPV4. Hint: one * possible solution is to store the * target packet address in a meta data * field when parsing. */ transition accept; } state parse_ipv4 { packet.extract(hdr.ipv4); meta.dst_ipv4 = hdr.ipv4.dstAddr; transition select(hdr.ipv4.protocol) { IPPROTO_ICMP : parse_icmp; default : accept; } } state parse_icmp { /* TODO: parse ICMP */ transition accept; } } /************************************************************************* ************ C H E C K S U M V E R I F I C A T I O N ************* *************************************************************************/ control MyVerifyChecksum( in my_headers_t hdr, inout my_metadata_t meta) { apply { } } /************************************************************************* ************** I N G R E S S P R O C E S S I N G ******************* *************************************************************************/ control MyIngress( inout my_headers_t hdr, inout my_metadata_t meta, inout standard_metadata_t standard_metadata) { action drop() { mark_to_drop(); exit; } /* TODO: Define actions and tables here */ action set_dst_info(mac_addr_t mac_da, mac_addr_t mac_sa, port_id_t egress_port) { /* * TODO: add logic to store mac addresses and * egress ports in meta data */ } table ipv4_lpm { key = { meta.dst_ipv4 : lpm; } actions = { set_dst_info; drop; } default_action = drop(); } apply { meta.my_mac = 0x000102030405; ipv4_lpm.apply(); /* TODO: add contol logic */ } } /************************************************************************* **************** E G R E S S P R O C E S S I N G ******************* *************************************************************************/ control MyEgress( inout my_headers_t hdr, inout my_metadata_t meta, inout standard_metadata_t standard_metadata) { apply { } } /************************************************************************* ************* C H E C K S U M C O M P U T A T I O N ************** *************************************************************************/ control MyComputeChecksum( inout my_headers_t hdr, inout my_metadata_t meta) { apply { } } /************************************************************************* *********************** D E P A R S E R ******************************* *************************************************************************/ control MyDeparser( packet_out packet, in my_headers_t hdr) { apply { /* TODO: Implement deparser */ } } V1Switch( MyParser(), MyVerifyChecksum(), MyIngress(), MyEgress(), MyComputeChecksum(), MyDeparser() ) main;