/*
 * icmp_send_packet_out
 *
 * Send the ICMP message out
 */
indigo_error_t
icmpa_send_packet_out (of_octets_t *octets)
{
    of_packet_out_t    *obj;
    of_list_action_t   *list;
    of_action_output_t *action;
    indigo_error_t     rv;

    if (!octets) return INDIGO_ERROR_PARAM;

    obj = of_packet_out_new(OF_VERSION_1_3);
    AIM_TRUE_OR_DIE(obj != NULL);

    list = of_list_action_new(OF_VERSION_1_3);
    AIM_TRUE_OR_DIE(list != NULL);

    action = of_action_output_new(OF_VERSION_1_3);
    AIM_TRUE_OR_DIE(action != NULL);

    of_packet_out_buffer_id_set(obj, -1);
    of_packet_out_in_port_set(obj, OF_PORT_DEST_CONTROLLER);
    of_action_output_port_set(action, OF_PORT_DEST_USE_TABLE);
    of_list_append(list, action);
    of_object_delete(action);
    rv = of_packet_out_actions_set(obj, list);
    AIM_ASSERT(rv == 0);
    of_object_delete(list);

    rv = of_packet_out_data_set(obj, octets);
    if (rv < 0) {
        AIM_LOG_ERROR("ICMPA: Failed to set data on packet out");
        of_packet_out_delete(obj);
        return rv;
    }

    rv = indigo_fwd_packet_out(obj);
    of_packet_out_delete(obj);
    return rv;
}
Example #2
0
/* Generated from of10/packet_in.data */
static int
test_of10_packet_in(void) {
    uint8_t binary[] = {
        0x01, 0x0a, 0x00, 0x15, 0x12, 0x34, 0x56, 0x78, 
        0xab, 0xcd, 0xef, 0x01, 0x00, 0x09, 0xff, 0xfe, 
        0x01, 0x00, 0x61, 0x62, 0x63, 
    };

    of_object_t *obj;

    obj = of_packet_in_new(OF_VERSION_1_0);
    of_packet_in_buffer_id_set(obj, 2882400001);
    {
        of_octets_t data = { .bytes=3, .data=(uint8_t *)"\x61\x62\x63" };
        of_packet_in_data_set(obj, &data);
    }
    of_packet_in_in_port_set(obj, 65534);
    of_packet_in_reason_set(obj, 1);
    of_packet_in_total_len_set(obj, 9);
    of_packet_in_xid_set(obj, 305419896);

    if (sizeof(binary) != WBUF_CURRENT_BYTES(OF_OBJECT_TO_WBUF(obj))
        || memcmp(binary, WBUF_BUF(OF_OBJECT_TO_WBUF(obj)), sizeof(binary))) {
	show_failure(binary, sizeof(binary),
		     WBUF_BUF(OF_OBJECT_TO_WBUF(obj)),
		     WBUF_CURRENT_BYTES(OF_OBJECT_TO_WBUF(obj)));
	of_object_delete(obj);
	return TEST_FAIL;
    }

    of_object_delete(obj);
    return TEST_PASS;
}

/* Generated from of10/packet_out.data */
static int
test_of10_packet_out(void) {
    uint8_t binary[] = {
        0x01, 0x0d, 0x00, 0x23, 0x12, 0x34, 0x56, 0x78, 
        0xab, 0xcd, 0xef, 0x01, 0xff, 0xfe, 0x00, 0x10, 
        0x00, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 
        0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 
        0x61, 0x62, 0x63, 
    };

    of_object_t *obj;

    obj = of_packet_out_new(OF_VERSION_1_0);
    of_packet_out_buffer_id_set(obj, 2882400001);
    of_packet_out_in_port_set(obj, 65534);
    of_packet_out_xid_set(obj, 305419896);
    {
        of_object_t *list = of_list_action_new(OF_VERSION_1_0);
        {
            of_object_t *obj = of_action_output_new(OF_VERSION_1_0);
            of_action_output_max_len_set(obj, 0);
            of_action_output_port_set(obj, 1);
            of_list_append(list, obj);
            of_object_delete(obj);
        }
        {
            of_object_t *obj = of_action_output_new(OF_VERSION_1_0);
            of_action_output_max_len_set(obj, 0);
            of_action_output_port_set(obj, 2);
            of_list_append(list, obj);
            of_object_delete(obj);
        }
        of_packet_out_actions_set(obj, list);
        of_object_delete(list);
    }
    {
        of_octets_t data = { .bytes=3, .data=(uint8_t *)"\x61\x62\x63" };
        of_packet_out_data_set(obj, &data);
    }

    if (sizeof(binary) != WBUF_CURRENT_BYTES(OF_OBJECT_TO_WBUF(obj))
        || memcmp(binary, WBUF_BUF(OF_OBJECT_TO_WBUF(obj)), sizeof(binary))) {
	show_failure(binary, sizeof(binary),
		     WBUF_BUF(OF_OBJECT_TO_WBUF(obj)),
		     WBUF_CURRENT_BYTES(OF_OBJECT_TO_WBUF(obj)));
	of_object_delete(obj);
	return TEST_FAIL;
    }

    of_object_delete(obj);
    return TEST_PASS;
}

/* Generated from of10/port_desc.data */
static int
test_of10_port_desc(void) {
    uint8_t binary[] = {
        0xff, 0xfd, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 
        0x66, 0x6f, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
        0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0x00, 
        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 
        0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 
        
    };

    of_object_t *obj;

    obj = of_port_desc_new(OF_VERSION_1_0);
    of_port_desc_advertised_set(obj, 32);
    of_port_desc_config_set(obj, 16);
    of_port_desc_curr_set(obj, 1);
    {
        of_mac_addr_t hw_addr = { { 1, 2, 3, 4, 5, 6 } };
        of_port_desc_hw_addr_set(obj, hw_addr);
    }
    {
        of_port_name_t name = "foo";
        of_port_desc_name_set(obj, name);
    }
    of_port_desc_peer_set(obj, 2048);
    of_port_desc_port_no_set(obj, 65533);
    of_port_desc_state_set(obj, 512);
    of_port_desc_supported_set(obj, 512);

    if (sizeof(binary) != WBUF_CURRENT_BYTES(OF_OBJECT_TO_WBUF(obj))
        || memcmp(binary, WBUF_BUF(OF_OBJECT_TO_WBUF(obj)), sizeof(binary))) {
	show_failure(binary, sizeof(binary),
		     WBUF_BUF(OF_OBJECT_TO_WBUF(obj)),
		     WBUF_CURRENT_BYTES(OF_OBJECT_TO_WBUF(obj)));
	of_object_delete(obj);
	return TEST_FAIL;
    }

    of_object_delete(obj);
    return TEST_PASS;
}
Example #3
0
/* Generated from of10/flow_stats_reply.data */
static int
test_of10_flow_stats_reply(void) {
    uint8_t binary[] = {
        0x01, 0x11, 0x00, 0xe4, 0x00, 0x00, 0x00, 0x06, 
        0x00, 0x01, 0x00, 0x00, 0x00, 0x68, 0x03, 0x00, 
        0x00, 0x3f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 
        0x00, 0x64, 0x00, 0x05, 0x00, 0x0a, 0x00, 0x00, 
        0x00, 0x00, 0x00, 0x00, 0x01, 0x23, 0x45, 0x67, 
        0x89, 0xab, 0xcd, 0xef, 0x00, 0x00, 0x00, 0x00, 
        0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 
        0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x00, 0x08, 
        0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 
        0x00, 0x02, 0x00, 0x00, 0x00, 0x70, 0x04, 0x00, 
        0x00, 0x3f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 
        0x00, 0x64, 0x00, 0x05, 0x00, 0x0a, 0x00, 0x00, 
        0x00, 0x00, 0x00, 0x00, 0x01, 0x23, 0x45, 0x67, 
        0x89, 0xab, 0xcd, 0xef, 0x00, 0x00, 0x00, 0x00, 
        0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 
        0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x00, 0x08, 
        0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 
        0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 
        0x00, 0x03, 0x00, 0x00, 
    };

    of_object_t *obj;

    obj = of_flow_stats_reply_new(OF_VERSION_1_0);
    of_flow_stats_reply_flags_set(obj, 0);
    of_flow_stats_reply_xid_set(obj, 6);
    {
        of_object_t *entries = of_list_flow_stats_entry_new(OF_VERSION_1_0);
        {
            of_object_t *elem = of_flow_stats_entry_new(OF_VERSION_1_0);
            of_flow_stats_entry_byte_count_set(elem, 1000);
            of_flow_stats_entry_cookie_set(elem, 81985529216486895);
            of_flow_stats_entry_duration_nsec_set(elem, 2);
            of_flow_stats_entry_duration_sec_set(elem, 1);
            of_flow_stats_entry_hard_timeout_set(elem, 10);
            of_flow_stats_entry_idle_timeout_set(elem, 5);
            of_flow_stats_entry_packet_count_set(elem, 10);
            of_flow_stats_entry_priority_set(elem, 100);
            of_flow_stats_entry_table_id_set(elem, 3);
            {
                of_match_t match = { OF_VERSION_1_0 };
                of_flow_stats_entry_match_set(elem, &match);
            }
            {
                of_object_t *actions = of_list_action_new(OF_VERSION_1_0);
                {
                    of_object_t *elem = of_action_output_new(OF_VERSION_1_0);
                    of_action_output_max_len_set(elem, 0);
                    of_action_output_port_set(elem, 1);
                    of_list_append(actions, elem);
                    of_object_delete(elem);
                }
                {
                    of_object_t *elem = of_action_output_new(OF_VERSION_1_0);
                    of_action_output_max_len_set(elem, 0);
                    of_action_output_port_set(elem, 2);
                    of_list_append(actions, elem);
                    of_object_delete(elem);
                }
                of_flow_stats_entry_actions_set(elem, actions);
                of_object_delete(actions);
            }
            of_list_append(entries, elem);
            of_object_delete(elem);
        }
        {
            of_object_t *elem = of_flow_stats_entry_new(OF_VERSION_1_0);
            of_flow_stats_entry_byte_count_set(elem, 1000);
            of_flow_stats_entry_cookie_set(elem, 81985529216486895);
            of_flow_stats_entry_duration_nsec_set(elem, 2);
            of_flow_stats_entry_duration_sec_set(elem, 1);
            of_flow_stats_entry_hard_timeout_set(elem, 10);
            of_flow_stats_entry_idle_timeout_set(elem, 5);
            of_flow_stats_entry_packet_count_set(elem, 10);
            of_flow_stats_entry_priority_set(elem, 100);
            of_flow_stats_entry_table_id_set(elem, 4);
            {
                of_match_t match = { OF_VERSION_1_0 };
                of_flow_stats_entry_match_set(elem, &match);
            }
            {
                of_object_t *actions = of_list_action_new(OF_VERSION_1_0);
                {
                    of_object_t *elem = of_action_output_new(OF_VERSION_1_0);
                    of_action_output_max_len_set(elem, 0);
                    of_action_output_port_set(elem, 1);
                    of_list_append(actions, elem);
                    of_object_delete(elem);
                }
                {
                    of_object_t *elem = of_action_output_new(OF_VERSION_1_0);
                    of_action_output_max_len_set(elem, 0);
                    of_action_output_port_set(elem, 2);
                    of_list_append(actions, elem);
                    of_object_delete(elem);
                }
                {
                    of_object_t *elem = of_action_output_new(OF_VERSION_1_0);
                    of_action_output_max_len_set(elem, 0);
                    of_action_output_port_set(elem, 3);
                    of_list_append(actions, elem);
                    of_object_delete(elem);
                }
                of_flow_stats_entry_actions_set(elem, actions);
                of_object_delete(actions);
            }
            of_list_append(entries, elem);
            of_object_delete(elem);
        }
        of_flow_stats_reply_entries_set(obj, entries);
        of_object_delete(entries);
    }

    if (sizeof(binary) != WBUF_CURRENT_BYTES(OF_OBJECT_TO_WBUF(obj))
        || memcmp(binary, WBUF_BUF(OF_OBJECT_TO_WBUF(obj)), sizeof(binary))) {
	show_failure(binary, sizeof(binary),
		     WBUF_BUF(OF_OBJECT_TO_WBUF(obj)),
		     WBUF_CURRENT_BYTES(OF_OBJECT_TO_WBUF(obj)));
	of_object_delete(obj);
	return TEST_FAIL;
    }

    of_object_delete(obj);
    return TEST_PASS;
}
Example #4
0
/* Generated from of10/flow_stats_entry.data */
static int
test_of10_flow_stats_entry(void) {
    uint8_t binary[] = {
        0x00, 0x68, 0x03, 0x00, 0x00, 0x30, 0x00, 0xe2, 
        0x00, 0x03, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 
        0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x00, 0x00, 
        0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 
        0xc0, 0xa8, 0x03, 0x7f, 0xff, 0xff, 0xff, 0xff, 
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 
        0x00, 0x00, 0x00, 0x02, 0x00, 0x64, 0x00, 0x05, 
        0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
        0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe8, 
        0x00, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 
        0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 
        
    };

    of_object_t *obj;

    obj = of_flow_stats_entry_new(OF_VERSION_1_0);
    {
        of_object_t list;
        of_flow_stats_entry_actions_bind(obj, &list);
        {
            of_object_t *obj = of_action_output_new(OF_VERSION_1_0);
            of_action_output_max_len_set(obj, 0);
            of_action_output_port_set(obj, 1);
            of_list_append(&list, obj);
            of_object_delete(obj);
        }
        {
            of_object_t *obj = of_action_output_new(OF_VERSION_1_0);
            of_action_output_max_len_set(obj, 0);
            of_action_output_port_set(obj, 2);
            of_list_append(&list, obj);
            of_object_delete(obj);
        }
    }
    of_flow_stats_entry_byte_count_set(obj, 1000);
    of_flow_stats_entry_cookie_set(obj, 81985529216486895);
    of_flow_stats_entry_duration_nsec_set(obj, 2);
    of_flow_stats_entry_duration_sec_set(obj, 1);
    of_flow_stats_entry_hard_timeout_set(obj, 10);
    of_flow_stats_entry_idle_timeout_set(obj, 5);
    {
        of_match_t match = { OF_VERSION_1_0 };
        match.fields.in_port = 3;
        match.fields.eth_src = (of_mac_addr_t) { { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab } };
        match.fields.eth_dst = (of_mac_addr_t) { { 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67 } };
        match.fields.eth_type = 0x800;
        match.fields.ipv4_src = 0xc0a8037f;
        match.fields.ipv4_dst = 0xffffffff;
        OF_MATCH_MASK_IN_PORT_EXACT_SET(&match);
        OF_MATCH_MASK_ETH_SRC_EXACT_SET(&match);
        OF_MATCH_MASK_ETH_DST_EXACT_SET(&match);
        OF_MATCH_MASK_ETH_TYPE_EXACT_SET(&match);
        //OF_MATCH_MASK_VLAN_VID_EXACT_SET(&match);
        //OF_MATCH_MASK_VLAN_PCP_EXACT_SET(&match);
        OF_MATCH_MASK_ETH_TYPE_EXACT_SET(&match);
        //OF_MATCH_MASK_IP_DSCP_EXACT_SET(&match);
        //OF_MATCH_MASK_IP_PROTO_EXACT_SET(&match);
        OF_MATCH_MASK_IPV4_SRC_EXACT_SET(&match);
        OF_MATCH_MASK_IPV4_DST_EXACT_SET(&match);
        //OF_MATCH_MASK_TCP_SRC_EXACT_SET(&match);
        //OF_MATCH_MASK_TCP_DST_EXACT_SET(&match);
        of_flow_stats_entry_match_set(obj, &match);
    }
    of_flow_stats_entry_packet_count_set(obj, 10);
    of_flow_stats_entry_priority_set(obj, 100);
    of_flow_stats_entry_table_id_set(obj, 3);

    if (sizeof(binary) != WBUF_CURRENT_BYTES(OF_OBJECT_TO_WBUF(obj))
        || memcmp(binary, WBUF_BUF(OF_OBJECT_TO_WBUF(obj)), sizeof(binary))) {
	show_failure(binary, sizeof(binary),
		     WBUF_BUF(OF_OBJECT_TO_WBUF(obj)),
		     WBUF_CURRENT_BYTES(OF_OBJECT_TO_WBUF(obj)));
	of_object_delete(obj);
	return TEST_FAIL;
    }

    of_object_delete(obj);
    return TEST_PASS;
}
Example #5
0
/* Generated from of10/echo_request.data */
static int
test_of10_echo_request(void) {
    uint8_t binary[] = {
        0x01, 0x02, 0x00, 0x0b, 0x12, 0x34, 0x56, 0x78, 
        0x61, 0x62, 0x01, 
    };

    of_object_t *obj;

    obj = of_echo_request_new(OF_VERSION_1_0);
    of_echo_request_xid_set(obj, 0x12345678);
    {
        of_octets_t data = { .data=(uint8_t *)"ab\x01", .bytes=3 };
        of_echo_request_data_set(obj, &data);
    }

    if (sizeof(binary) != WBUF_CURRENT_BYTES(OF_OBJECT_TO_WBUF(obj))
        || memcmp(binary, WBUF_BUF(OF_OBJECT_TO_WBUF(obj)), sizeof(binary))) {
	show_failure(binary, sizeof(binary),
		     WBUF_BUF(OF_OBJECT_TO_WBUF(obj)),
		     WBUF_CURRENT_BYTES(OF_OBJECT_TO_WBUF(obj)));
	of_object_delete(obj);
	return TEST_FAIL;
    }

    of_object_delete(obj);
    return TEST_PASS;
}

/* Generated from of10/flow_add.data */
static int
test_of10_flow_add(void) {
    uint8_t binary[] = {
        0x01, 0x0e, 0x00, 0x70, 0x12, 0x34, 0x56, 0x78, 
        0x00, 0x30, 0x00, 0xe2, 0x00, 0x03, 0x01, 0x23, 
        0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 
        0x45, 0x67, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 
        0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x03, 0x7f, 
        0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
        0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 
        0x00, 0x00, 0x00, 0x08, 0xff, 0xfb, 0x00, 0x00, 
        0xff, 0xff, 0x00, 0x10, 0x00, 0x00, 0x23, 0x20, 
        0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
        0xff, 0xff, 0x00, 0x10, 0x00, 0x5c, 0x16, 0xc7, 
        0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 
        
    };

    of_object_t *obj;

    obj = of_flow_add_new(OF_VERSION_1_0);
    of_flow_add_xid_set(obj, 0x12345678);
    of_flow_add_idle_timeout_set(obj, 5);
    of_flow_add_flags_set(obj, 2);
    {
        of_match_t match = { OF_VERSION_1_0 };
        match.fields.in_port = 3;
        match.fields.eth_src = (of_mac_addr_t) { { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab } };
        match.fields.eth_dst = (of_mac_addr_t) { { 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67 } };
        match.fields.eth_type = 0x800;
        match.fields.ipv4_src = 0xc0a8037f;
        match.fields.ipv4_dst = 0xffffffff;
        OF_MATCH_MASK_IN_PORT_EXACT_SET(&match);
        OF_MATCH_MASK_ETH_SRC_EXACT_SET(&match);
        OF_MATCH_MASK_ETH_DST_EXACT_SET(&match);
        OF_MATCH_MASK_ETH_TYPE_EXACT_SET(&match);
        //OF_MATCH_MASK_VLAN_VID_EXACT_SET(&match);
        //OF_MATCH_MASK_VLAN_PCP_EXACT_SET(&match);
        OF_MATCH_MASK_ETH_TYPE_EXACT_SET(&match);
        //OF_MATCH_MASK_IP_DSCP_EXACT_SET(&match);
        //OF_MATCH_MASK_IP_PROTO_EXACT_SET(&match);
        OF_MATCH_MASK_IPV4_SRC_EXACT_SET(&match);
        OF_MATCH_MASK_IPV4_DST_EXACT_SET(&match);
        //OF_MATCH_MASK_TCP_SRC_EXACT_SET(&match);
        //OF_MATCH_MASK_TCP_DST_EXACT_SET(&match);
        of_flow_add_match_set(obj, &match);
    }
    {
        of_list_action_t actions;
        of_flow_add_actions_bind(obj, &actions);
        {
            of_action_t action;
            of_action_output_init(&action.output, OF_VERSION_1_0, -1, 1);
            of_list_action_append_bind(&actions, &action);
            of_action_output_port_set(&action.output, OF_PORT_DEST_FLOOD);
        }
        {
            of_action_t action;
            of_action_nicira_dec_ttl_init(&action.nicira_dec_ttl, OF_VERSION_1_0, -1, 1);
            of_list_action_append_bind(&actions, &action);
        }
        {
            of_action_t action;
            of_action_bsn_set_tunnel_dst_init(&action.bsn_set_tunnel_dst, OF_VERSION_1_0, -1, 1);
            of_list_action_append_bind(&actions, &action);
        }
    }

    if (sizeof(binary) != WBUF_CURRENT_BYTES(OF_OBJECT_TO_WBUF(obj))
        || memcmp(binary, WBUF_BUF(OF_OBJECT_TO_WBUF(obj)), sizeof(binary))) {
	show_failure(binary, sizeof(binary),
		     WBUF_BUF(OF_OBJECT_TO_WBUF(obj)),
		     WBUF_CURRENT_BYTES(OF_OBJECT_TO_WBUF(obj)));
	of_object_delete(obj);
	return TEST_FAIL;
    }

    of_object_delete(obj);
    return TEST_PASS;
}
void SimpleForwardingModule::handlePacketIn(const zmf::data::ZmfMessage& packetInMsg) {
    Device* destinationDevice = nullptr;
    // Unpack ZmfMessage which contains OpenFlow packet
    of_packet_in_t* ofPacketIn = zsdn::of_object_new_from_data_string_copy(packetInMsg.getData());
    of_octets_t ofPayload;
    of_packet_in_data_get(ofPacketIn, &ofPayload);
    // extracted message data
    uint8_t* payloadData = ofPayload.data;
    uint16_t payloadLength = ofPayload.bytes;
    // get the ethernet message frame
    Tins::EthernetII ethPacket(payloadData, payloadLength);
    of_version_t ofVersion = ofPacketIn->version;


    // some ethertype may be excluded from beeing handled by this module. we check if the received packet is one of them.
    bool ignoreEtherType = false;
    for (uint16_t ignoredType : ignoreEthertypes_) {
        if (ethPacket.payload_type() == ignoredType) {
            ignoreEtherType = true;
            break;
        }
    }
    if (ignoreEtherType) {
        getLogger().trace("Ignoring packet due to ethertype");
    }

    else {

        Tins::EthernetII::address_type dstAdress = ethPacket.dst_addr(); // extract the destination address

        uint64_t destinationMac = zsdn::NetUtils::mac_address_tins_to_uint64(dstAdress);
        // check for broadcast if == TRUE -> skip the message
        if (dstAdress.is_broadcast()) {
            this->getLogger().trace("Received Broadcast -> Message ignored");
        }

        else {

            this->getLogger().trace("Received Packet in");
            // check if the device is known if == FALSE -> request the device by a DeviceManager module
            if ((this->devices_.count(destinationMac) > 0)) {
                destinationDevice = &this->devices_.find(destinationMac)->second; // get the device out of the map
            } else {
                destinationDevice = this->requestDevice(destinationMac); // request the device by DeviceManager module
            }

            if (destinationDevice != nullptr) {
                // send the initial message payload to the destination switch port
                if (ofVersion == OF_VERSION_UNKNOWN) {
                    getLogger().warning("Received Packet with OF_VERSION_UNKNOWN. Ignoring Packet.");
                    return;
                }


                of_port_no_t port_no = destinationDevice->switchPort;



                of_object_t* resultObject = nullptr;
                switch (ofVersion) {

                    case OF_VERSION_UNKNOWN:
                        break;
                    case OF_VERSION_1_0:
                        of_packet_out_data_set(tempPacketOut_OF_1_0, &ofPayload);
                        of_action_output_port_set(tempOutPut_OF_1_0, port_no);
                        of_packet_out_actions_set(tempPacketOut_OF_1_0, tempActionList_OF_1_0);
                        resultObject = tempPacketOut_OF_1_0;
                        break;

                    case OF_VERSION_1_1:
                        break;
                    case OF_VERSION_1_2:
                        break;
                    case OF_VERSION_1_3:
                        of_packet_out_data_set(tempPacketOut_OF_1_3, &ofPayload);
                        of_action_output_port_set(tempOutPut_OF_1_3, port_no);
                        of_packet_out_actions_set(tempPacketOut_OF_1_3, tempActionList_OF_1_3);
                        resultObject = tempPacketOut_OF_1_3;
                        break;

                    case OF_VERSION_1_4:
                        break;
                }




                if (resultObject != nullptr) {
                    std::string messageBytes = zsdn::of_object_serialize_to_data_string(resultObject);

                    std::map<uint64_t, zmf::data::MessageType>::iterator msgType = this->linkDevicePacketOutMessageTypeMap_.find(
                            destinationDevice->macAddress);

                    this->getZmf()->publish(zmf::data::ZmfMessage(
                            msgType->second,
                            messageBytes));
                    if (this->getLogger().trace()) {
                        this->getLogger().trace(
                                "Forwarded packet to " + std::to_string(unsigned(destinationDevice->switchDpid)) + ":" +
                                std::to_string(unsigned(destinationDevice->switchPort)));
                    }
                }


            } else {
                this->getLogger().trace(
                        "Not able to forwared packet, host " + dstAdress.to_string() + " unknown");
            }
        }
    }
    of_packet_in_delete(ofPacketIn);
};