#ifndef NICO_ICMP6_NDP_ICMP #define NICO_ICMP6_NDP_ICMP /********************** ICMP6 + NDP + ICMP ***********************************/ /* old/unused action -- is it??*/ action icmp6_answer() { if(hdr.icmp6.isValid()) { if(hdr.icmp6.code == ICMP6_ECHO_REQUEST) { ipv6_addr_t tmp = hdr.ipv6.src_addr; hdr.ipv6.src_addr = hdr.ipv6.dst_addr; hdr.ipv6.dst_addr = tmp; hdr.icmp6.code = ICMP6_ECHO_REPLY; } } } action icmp6_neighbor_solicitation(ipv6_addr_t addr, mac_addr_t mac_addr) { /* egress = ingress */ standard_metadata.egress_spec = standard_metadata.ingress_port; /* 1. IPv6 changes */ hdr.ipv6.dst_addr = hdr.ipv6.src_addr; hdr.ipv6.src_addr = addr; /* 2. ICMP6 changes */ hdr.icmp6.type = ICMP6_NA; hdr.icmp6.code = 0; hdr.icmp6.checksum = 42; // checksum is calculated in deparser - marking with 42 to see whether it is calculated /* 3. icmp6/neighbor advertisement: values taken from real world answers */ hdr.icmp6_na_ns.router = 0; hdr.icmp6_na_ns.solicitated = 1; hdr.icmp6_na_ns.override = 1; hdr.icmp6_na_ns.reserved = 0; hdr.icmp6_na_ns.target_addr = addr; /* 4. Link layer options */ hdr.icmp6_option_link_layer_addr.type = ICMP6_NDP_OPT_TARGET_LL; hdr.icmp6_option_link_layer_addr.ll_length = 1; /* 1* 64 bit */ hdr.icmp6_option_link_layer_addr.mac_addr = mac_addr; /* 5. Checksum trigger/info */ meta.chk_icmp6_na_ns = 1; meta.cast_length = (bit<32>) hdr.ipv6.payload_length; } action icmp6_echo_reply() { mac_addr_t mac_tmp = hdr.ethernet.dst_addr; hdr.ethernet.dst_addr = hdr.ethernet.src_addr; hdr.ethernet.src_addr = mac_tmp; ipv6_addr_t addr_tmp = hdr.ipv6.dst_addr; hdr.ipv6.dst_addr = hdr.ipv6.src_addr; hdr.ipv6.src_addr = addr_tmp; hdr.icmp6.type = ICMP6_ECHO_REPLY; meta.chk_icmp6 = 1; meta.cast_length = (bit<32>) hdr.ipv6.payload_length; } table icmp6 { key = { hdr.ipv6.dst_addr: lpm; hdr.icmp6.type: exact; } actions = { controller_debug; icmp6_neighbor_solicitation; icmp6_echo_reply; controller_debug_table_id; NoAction; } size = ICMP6_TABLE_SIZE; default_action = controller_debug_table_id(TABLE_ICMP6); } action icmp_echo_reply() { mac_addr_t mac_tmp = hdr.ethernet.dst_addr; ipv4_addr_t ipv4_tmp = hdr.ipv4.src_addr; /* swap ethernet addresses */ hdr.ethernet.dst_addr = hdr.ethernet.src_addr; hdr.ethernet.src_addr = mac_tmp; /* swap ipv4 addresses */ hdr.ipv4.src_addr = hdr.ipv4.dst_addr; hdr.ipv4.dst_addr = ipv4_tmp; /* set correct type */ hdr.icmp.type = ICMP_ECHO_REPLY; meta.chk_icmp = 1; } table icmp { key = { hdr.ipv4.dst_addr: lpm; hdr.icmp.type: exact; } actions = { icmp_echo_reply; controller_debug_table_id; NoAction; } size = ICMP_TABLE_SIZE; // default_action = controller_debug_table_id(TABLE_ICMP); default_action = NoAction; /* do not clone on miss */ } #endif