Пример #1
0
indigo_error_t
icmpa_create_send_packet_in (of_octets_t *of_octets, uint64_t reason, 
                             of_port_no_t in_port)
{
    of_packet_in_t *of_packet_in;
    of_match_t     match;

    memset(&match, 0, sizeof(of_match_t)); 

    if (!of_octets) return INDIGO_ERROR_UNKNOWN;

    if ((of_packet_in = of_packet_in_new(OF_VERSION_1_3)) == NULL) {
        return INDIGO_ERROR_RESOURCE;
    }

    of_packet_in_total_len_set(of_packet_in, of_octets->bytes);
    match.version = OF_VERSION_1_3;
    match.fields.in_port = in_port;
    OF_MATCH_MASK_IN_PORT_EXACT_SET(&match);
    match.fields.metadata |= reason;
    OF_MATCH_MASK_METADATA_EXACT_SET(&match);
    if ((of_packet_in_match_set(of_packet_in, &match)) != OF_ERROR_NONE) {
        printf("Failed to write match to packet-in message\n");
        of_packet_in_delete(of_packet_in);
        return INDIGO_ERROR_UNKNOWN;
    }

    if ((of_packet_in_data_set(of_packet_in, of_octets)) != OF_ERROR_NONE) {
        printf("Failed to write packet data to packet-in message\n");
        of_packet_in_delete(of_packet_in);
        return INDIGO_ERROR_UNKNOWN;
    }

    if (icmpa_packet_in_handler(of_packet_in) == 
        INDIGO_CORE_LISTENER_RESULT_DROP) {
        printf("Listener dropped packet-in\n");
    } else {
        printf("Listener passed packet-in\n");
    }

    of_packet_in_delete(of_packet_in);
    return INDIGO_ERROR_NONE;

}
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);
};
Пример #3
0
int
test_discovery_pkt_in(int port_no, int indigo_ret_expected)
{

#define OUT_PKT_BUF_SIZE 1500
    uint8_t  buf[OUT_PKT_BUF_SIZE];

    int rv = 0;
    of_packet_in_t *obj = 0;
    ppe_packet_t    ppep;
    of_octets_t data = {
        .bytes = sizeof(Dhcp_discovery) //346 bytes (342 + 4byteVLAN
    };

    /* Timeout due to re-register the timer */
    printf("\n\n*******************************\n");
    printf("TEST 1 DHCP Discovery: PKT_IN on port:%d\nExpect Option Added\n", port_no);
    printf("pkt_in bytes = %d\n", data.bytes);
    printf("*******************************\n");

    /* Set up GOLDEN Expected pkt*/
    AIM_TRUE_OR_DIE(sizeof(Dhcp_discovery_expected) <= OUT_PKT_BUF_SIZE);
    convert_chars_to_bytes(Dhcp_discovery_expected, 
                           Dhcp_discovery_expected_hex_stream, 
                           sizeof(Dhcp_discovery_expected));
    
    /* Setup discovery pkt */
    AIM_TRUE_OR_DIE(sizeof(Dhcp_discovery) <= OUT_PKT_BUF_SIZE);
    convert_chars_to_bytes(Dhcp_discovery, Dhcp_discovery_hex_stream, sizeof(Dhcp_discovery));
    memcpy(buf, Dhcp_discovery, sizeof(Dhcp_discovery));
    data.data = buf;

    obj = of_packet_in_new(OF_VERSION_1_0);
    AIM_TRUE_OR_DIE(obj);

    of_packet_in_reason_set(obj, OF_PACKET_IN_REASON_BSN_DHCP);
    of_packet_in_in_port_set(obj,port_no);

    if(of_packet_in_data_set(obj, &data) < 0) {
        AIM_TRUE_OR_DIE(obj);
    }

    /* Dump pkt in obj */
//    of_object_dump((loci_writer_f)aim_printf, &aim_pvs_stdout, obj);

    ppe_packet_init(&ppep, data.data, data.bytes);
	if (ppe_parse(&ppep) < 0) {
	    printf("\nERROR: Packet parsing failed. packet=%p, len=%u", data.data, data.bytes);
	}

    /* Dump up to DHCP hdr */
//    ppe_packet_dump(&ppep,&aim_pvs_stdout);
//    parse_dhcp_options(&ppep, data.bytes, 0, 0);

    /* Handle packet */
    rv = dhcpra_handle_pkt (obj);

    AIM_TRUE_OR_DIE(rv == indigo_ret_expected);

    of_packet_in_delete(obj);
    return rv;
}

int
test_offer_pkt_in(int port_no)
{

#define OUT_PKT_BUF_SIZE 1500
    uint8_t  buf[OUT_PKT_BUF_SIZE];

    int rv = 0;
    of_packet_in_t *obj;
    ppe_packet_t    ppep;
    of_octets_t data = {
        .bytes = sizeof(Dhcp_offer) //354 (342 + 4byte VLAN + 8bytes CirID)
    };

    printf("\n\n*******************************\n"
           "TEST 2 DHCP OFFER: PKT_IN on port:%d\nExpect Option Removed\n", port_no);
    printf("pkt_in bytes = %d\n", data.bytes);
    printf("*******************************\n\n");

     /* Set up GOLDEN Expected pkt*/
    //printf("Expected Offer pkt:\n");
    AIM_TRUE_OR_DIE(sizeof(Dhcp_offer_expected) <= OUT_PKT_BUF_SIZE);
    convert_chars_to_bytes(Dhcp_offer_expected, 
                           Dhcp_offer_expected_hex_stream, 
                           sizeof(Dhcp_offer_expected));

    /* Setup offer pkt */
    //printf("Offer pkt:\n");
    AIM_TRUE_OR_DIE(sizeof(Dhcp_offer) <= OUT_PKT_BUF_SIZE);
    convert_chars_to_bytes(Dhcp_offer,  Dhcp_offer_hex_stream, sizeof(Dhcp_offer));
    memcpy(buf, Dhcp_offer, sizeof(Dhcp_offer));
    data.data = buf;

    obj = of_packet_in_new(OF_VERSION_1_0);
    AIM_TRUE_OR_DIE(obj);
    of_packet_in_in_port_set(obj,port_no);

    of_packet_in_reason_set(obj, OF_PACKET_IN_REASON_BSN_DHCP);
    if(of_packet_in_data_set(obj, &data) < 0) {
        AIM_TRUE_OR_DIE(obj);
    }

    /* Dump pkt in obj */
    //of_object_dump((loci_writer_f)aim_printf, &aim_pvs_stdout, obj);
    ppe_packet_init(&ppep, data.data, data.bytes);
	if (ppe_parse(&ppep) < 0) {
	    printf("\nERROR: Packet parsing failed. packet=%p, len=%u", data.data, data.bytes);
	}

    /* Dump up to DHCP hdr */
    //ppe_packet_dump(&ppep,&aim_pvs_stdout);
    //parse_dhcp_options(&ppep, data.bytes, 0, 0);

    /* Handle packet */
    rv = dhcpra_handle_pkt (obj);

    if (rv == INDIGO_CORE_LISTENER_RESULT_PASS) {
        printf("\nError: NOT DHCP packet-in\n");
    } else if (rv == INDIGO_CORE_LISTENER_RESULT_DROP)
        printf("\nIS DHCP packet-in\n");
    else
        printf("\nError: Unsupport packet-in\n");

    of_packet_in_delete(obj);
    return rv;
}


int aim_main(int argc, char* argv[])
{
    printf("dhcpra Utest Is Empty\n");
    dhcpra_config_show(&aim_pvs_stdout);
    dhcpra_system_init();

    printf("\n*********\n0. PRE-TEST TABLE\n********\n");
    test_pass[0] = fill_all_vlan_dhcpr_table_test();

    printf("\n*********\nI. TEST PASS AFTER ADD and MOD\n********\n");
    add_entry_to_dhcpr_table();
    mod_entry_to_dhcpr_table();

    //Port 1: Correct setup, packet process
    //Driver will take care of sending L2_SRC_MISSED to controller
    test_discovery_pkt_in(1, INDIGO_CORE_LISTENER_RESULT_DROP);
    test_offer_pkt_in(1);

    printf("\n\nSUMMARY:\nDISCOV:\t%s\n", dhcp_pkt_matched[0] ? "PASSED" : "FAILED");
    printf("OFFER:\t%s\n", dhcp_pkt_matched[1] ? "PASSED" : "FAILED");
    test_pass[1] = dhcp_pkt_matched[0];
    test_pass[2] = dhcp_pkt_matched[1];

    printf("\n*********\nII. TEST FAILED AFTER DELETE\n********\n");
    dhcp_pkt_matched[0] = 0;
    dhcp_pkt_matched[1] = 0;
    del_entry_to_dhcpr_table();

    //Incorrect VLAN pass packet
    test_discovery_pkt_in(1, INDIGO_CORE_LISTENER_RESULT_PASS);
    test_offer_pkt_in(1);
    printf("\n\nSUMMARY:\nDISCOV:\t%s\n", dhcp_pkt_matched[0] ? "PASSED" : "FAILED");
    printf("OFFER:\t%s\n", dhcp_pkt_matched[1] ? "PASSED" : "FAILED");
    test_pass[3] = !dhcp_pkt_matched[0];
    test_pass[4] = !dhcp_pkt_matched[1];

    printf("\n\n*****SUMMARY ALL 3 TESTS*****\n");
    printf("TEST DHCP TABLE: %s\n", test_pass[0] ? "PASSED" : "FAILED");
    printf("TEST DISCOVER with valid table: %s\n", test_pass[1] ? "PASSED" : "FAILED");
    printf("TEST OFFER with valid table: %s\n",    test_pass[2] ? "PASSED" : "FAILED");
    printf("TEST DISCOVER with in valid table: %s\n", test_pass[3] ? "PASSED" : "FAILED");
    printf("TEST OFFER with in valid table: %s\n",    test_pass[4] ? "PASSED" : "FAILED");

    return 0;
}