コード例 #1
0
ファイル: ppe_utm.c プロジェクト: Sovietaced/bigcode
static ucli_status_t
ppe_ucli_utm__data__(ucli_context_t* uc)
{
    uint8_t* data; 
    int size; 

    UCLI_COMMAND_INFO(uc, 
                      "data", 1, 
                      "Assign packet data."); 

    
    UCLI_ARGPARSE_OR_RETURN(uc, "{data}", &data, &size); 

    if(ppec->ppep.data) {
        aim_free(ppec->ppep.data); 
    }

    if(ppe_packet_init(&ppec->ppep, data, size) < 0) {
        return ucli_e_internal(uc, "ppe_packet_init()"); 
    }

    if(ppe_parse(&ppec->ppep) < 0) {
        return ucli_e_internal(uc, "ppe_parse()"); 
    }

    return UCLI_STATUS_OK; 
}
コード例 #2
0
ファイル: main.c プロジェクト: Broadcom-Switch/of-dpa
ucli_status_t
vt_ucli_module__ppedump__(ucli_context_t* uc)
{
    int count = 0;

    UCLI_COMMAND_INFO(uc,
                      "ppedump", 1,
                      "$summary#PPE dump all packets on the given VPI."
                      "$args#<vpi_spec>");

    UCLI_ARGPARSE_OR_RETURN(uc, "{vpi}", &vtc->vpi);

    while(1) {
        if(vpi_recv__(uc, vtc) > 0) {
            ppe_packet_t ppep;
            ppe_packet_init(&ppep, vtc->data, vtc->size);
            if(ppe_parse(&ppep) < 0) {
                ucli_printf(uc, "[%.3d] recv(%{vpi}):\n%{data}\n",
                            count, vtc->vpi, vtc->data, vtc->size);
            }
            else {
                ucli_printf(uc, "[%.3d] recv(%{vpi}):\n",
                            count, vtc->vpi);
                ppe_packet_dump(&ppep, &uc->pvs);
            }
            count++;
        }
        else {
            break;
        }
    }
    return UCLI_STATUS_OK;
}
コード例 #3
0
ファイル: ppe_packet.c プロジェクト: Broadcom-Switch/of-dpa
int
ppe_packet_dup(ppe_packet_t* dst, ppe_packet_t* src)
{
    ppe_packet_init(dst, aim_memdup(src->data, src->size), src->size);
    PPE_MEMCPY(dst->mh, src->mh, sizeof(dst->mh));
    ppe_parse(dst);
    dst->realloc = 1;
    return 0;
}
コード例 #4
0
ファイル: main.c プロジェクト: floodlight/switchlight-common
void
icmpa_verify_packet (of_octets_t *octets, uint32_t reason)
{
    ppe_packet_t               ppep;
    uint32_t                   icmp_type;

    if (!octets) return;

    ppe_packet_init(&ppep, octets->data, octets->bytes);    
    if (ppe_parse(&ppep) < 0) {
        AIM_LOG_ERROR("Packet_in parsing failed.");
        return;
    }

    assert(ppe_header_get(&ppep, PPE_HEADER_ICMP)); 
    ppe_field_get(&ppep, PPE_FIELD_ICMP_TYPE, &icmp_type);
    assert(icmp_type == reason); 
}
コード例 #5
0
/*
 * lacpa_receive
 *
 * Process incoming LACPDU and take appropriate action
 */
extern bool
lacpa_receive (lacpa_port_t *port, uint8_t *data, uint32_t bytes)
{
    lacpa_pdu_t  pdu;
    ppe_packet_t ppep;

	if (!port || !data) return FALSE;

    if (!port->lacp_enabled) {
        AIM_LOG_ERROR("LACPDU-Rx-FAILED - Agent is Disabled on port: %d",
                      port->actor.port_no);
		return FALSE;
    }

    LACPA_MEMSET(&pdu, DEFAULT_ZERO, sizeof(lacpa_pdu_t));
    AIM_LOG_TRACE("LACPDU Received on port: %d", port->actor.port_no);

    /*
     * Use ppe api's to fill info from data in our pdu
     */
    ppe_packet_init(&ppep, data, bytes);
    if (ppe_parse(&ppep) < 0) {
        AIM_LOG_ERROR("Packet parsing failed. packet=%{data}", data, bytes);
        return FALSE;
    }

    if (!ppe_header_get(&ppep, PPE_HEADER_LACP)) {
        AIM_LOG_ERROR("Not a Valid LCAP Packet");
        return FALSE;
    }

	/*
     * Retrieve the information from the LCAP packet
     */
    if (!lacpa_parse_pdu(&ppep, &pdu)) {
		AIM_LOG_ERROR("Packet parsing failed.");
        return FALSE;
    }

    port->lacp_event = LACPA_EVENT_PDU_RECEIVED;
    lacpa_machine(port, &pdu);

    return TRUE;
}
コード例 #6
0
ファイル: main.c プロジェクト: floodlight/switchlight-common
indigo_error_t
dhcpra_create_send_packet_in (of_port_no_t in_port, of_octets_t *of_octets)
{
    of_packet_in_t *of_packet_in;
    of_match_t     match;
    ppe_packet_t   ppep;
    ppe_header_t   format;
    uint8_t        buf[1500];
    int            option;

    int debug_dump = 0;
    if (!of_octets) return INDIGO_ERROR_UNKNOWN;

    /*
     * Check if the packet_in is untagged, then add the Vlan tag 
     */
    ppe_packet_init(&ppep, of_octets->data, of_octets->bytes);
    if (ppe_parse(&ppep) < 0) {
        printf("RAW untag linux packet parsing failed.\n");
        return INDIGO_ERROR_UNKNOWN;
    } 

    if (!(ppe_header_get(&ppep, PPE_HEADER_DHCP))) {
        /* Since we listen to all pkt_in
         * Rate is high, no need add debug msg here
         * Not LLDP packet, simply return */
        printf("in_port=%u: NOT DHCP packet IGNORED", in_port);
        return INDIGO_ERROR_NONE;
    }

    /* Dump up to DHCP hdr */
    printf("RAW untag Linux dump\n");
    get_dhcp_options(&ppep, of_octets->bytes, debug_dump, &option);

    ppe_packet_format_get(&ppep, &format);
    if (format != PPE_HEADER_8021Q) {
        of_octets->bytes += 4;
        memcpy(buf, of_octets->data, of_octets->bytes);
        memcpy(of_octets->data+16, buf+12, of_octets->bytes-16);
        of_octets->data[12] = ETHERTYPE_DOT1Q >> 8;
        of_octets->data[13] = ETHERTYPE_DOT1Q & 0xFF;
        of_octets->data[14] = 0;
        of_octets->data[15] = VLAN_TEST; //7;  
    } else {
コード例 #7
0
ファイル: main.c プロジェクト: floodlight/switchlight-common
indigo_error_t indigo_fwd_packet_out (of_packet_out_t *pkt)
{
    
    of_octets_t     data;
    ppe_packet_t    ppep;

    printf("\n********\n***DUMPING Fwd pkt out Received and Checked\n*************\n");
    //of_packet_out_OF_VERSION_1_3_dump((loci_writer_f)aim_printf, &aim_pvs_stdout, pkt);

    of_packet_out_data_get(pkt, &data);
	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);
	}
    //ppe_packet_dump(&ppep,&aim_pvs_stdout);

    parse_dhcp_options(&ppep, data.bytes, 1, 1);

    return INDIGO_ERROR_NONE;
}
コード例 #8
0
/*
 * lacpa_transmit
 *
 * Construct an LACPDU for the given port and transmit it out
 */
extern bool
lacpa_transmit (lacpa_port_t *port)
{
    ppe_packet_t ppep;
    uint8_t      data[LACP_PKT_BUF_SIZE];

	if (!port) return FALSE;

    if (!port->lacp_enabled) {
        AIM_LOG_ERROR("LACPDU-Tx-FAILED - Agent is Disabled on port: %d",
                      port->actor.port_no);
        return FALSE;
    }

    LACPA_MEMSET(data, DEFAULT_ZERO, LACP_PKT_BUF_SIZE);
    AIM_LOG_TRACE("Transmit Packet for port: %d, reason: %{lacpa_transmit}",
                  port->actor.port_no, port->ntt_reason);

    lacpa_dump_port(port);

	ppe_packet_init(&ppep, data, LACP_PKT_BUF_SIZE);

    /*
     * Set ethertype as slow-protocols and Set LACP subtype
     * Parse to recognize LACP packet.
     */
	data[12] = PPE_ETHERTYPE_SLOW_PROTOCOLS >> 8;
    data[13] = PPE_ETHERTYPE_SLOW_PROTOCOLS & 0xFF;
    data[14] = PPE_SLOW_PROTOCOL_LACP;

	if (ppe_parse(&ppep) < 0) {
        AIM_LOG_ERROR("Packet parsing failed after ethertype. packet=%{data}",
                      data, LACP_PKT_BUF_SIZE);
        return FALSE;
    }

    /*
     * Set the Src and Dest Mac.
     * Src Mac is provided to us and Dest Mac is the slow-protocols-mac-address
     */
    ppe_wide_field_set(&ppep, PPE_FIELD_ETHERNET_SRC_MAC, port->src_mac);
    ppe_wide_field_set(&ppep, PPE_FIELD_ETHERNET_DST_MAC,
                       slow_protocols_address);

    /*
     * Build the rest of the LCAP packet
     */
    if (!lacpa_build_pdu(&ppep, port)) {
        AIM_LOG_ERROR("Packet sending failed.");
        return FALSE;
    }

    /*
     *  Dump out the packet to verify all the fields are set properly
     */
    ppe_packet_dump(&ppep, &aim_pvs_stdout);

    lacpa_send(port, data, LACP_PKT_BUF_SIZE);

    return TRUE;

}
コード例 #9
0
/*
 * icmp_packet_in_handler
 *
 * API for handling incoming packets
 */
indigo_core_listener_result_t
icmpa_packet_in_handler (of_packet_in_t *packet_in)
{
    of_octets_t                octets;
    of_port_no_t               port_no;
    of_match_t                 match;
    ppe_packet_t               ppep;
    indigo_core_listener_result_t result = INDIGO_CORE_LISTENER_RESULT_PASS;
    uint32_t                   type, code;

    debug_counter_inc(&pkt_counters.icmp_total_in_packets);
    if (!packet_in) return INDIGO_CORE_LISTENER_RESULT_PASS;

    of_packet_in_data_get(packet_in, &octets);

    /*
     * Identify the recv port
     */
    if (packet_in->version <= OF_VERSION_1_1) {
        return INDIGO_CORE_LISTENER_RESULT_PASS;
    } else {
        if (of_packet_in_match_get(packet_in, &match) < 0) {
            AIM_LOG_ERROR("ICMPA: match get failed");
            debug_counter_inc(&pkt_counters.icmp_internal_errors);
            return INDIGO_CORE_LISTENER_RESULT_PASS;
        }
        port_no = match.fields.in_port;
    }

    if (port_no == OF_PORT_DEST_CONTROLLER) {
        debug_counter_inc(&pkt_counters.icmp_total_passed_packets);
        return INDIGO_CORE_LISTENER_RESULT_PASS;
    }

    if (port_no > MAX_PORTS) {
        AIM_LOG_ERROR("ICMPA: Port No: %d Out of Range %d", port_no, MAX_PORTS);
        debug_counter_inc(&pkt_counters.icmp_internal_errors);
        return INDIGO_CORE_LISTENER_RESULT_PASS;
    }

    /*
     * Check the packet-in reasons in metadata
     *
     * Icmp agent should not consume packets coming in due to L2 Src miss
     * and Station Move.
     */
    if ((match.fields.metadata & OFP_BSN_PKTIN_FLAG_STATION_MOVE) ||
        (match.fields.metadata & OFP_BSN_PKTIN_FLAG_NEW_HOST)) {
        debug_counter_inc(&pkt_counters.icmp_total_passed_packets);
        return INDIGO_CORE_LISTENER_RESULT_PASS;
    }

    ppe_packet_init(&ppep, octets.data, octets.bytes);
    if (ppe_parse(&ppep) < 0) {
        AIM_LOG_RL_ERROR(&icmp_pktin_log_limiter, os_time_monotonic(),
                         "ICMPA: Packet_in parsing failed.");
        debug_counter_inc(&pkt_counters.icmp_internal_errors);
        return INDIGO_CORE_LISTENER_RESULT_PASS;
    }

    /*
     * Identify if this is an Echo Request, destined to one of VRouter
     */
    if (ppe_header_get(&ppep, PPE_HEADER_ICMP)) {
        if (icmpa_reply(&ppep, port_no, &result)) {
            ++port_pkt_counters[port_no].icmp_echo_packets;
            return result;
        }
    }

    /*
     * To handle traceroute, we need to check for
     * a) UDP Packet
     * b) dest IP is Vrouter IP
     * c) UDP src and dest ports are ephemeral
     */
    if (ppe_header_get(&ppep, PPE_HEADER_UDP) &&
        ppe_header_get(&ppep, PPE_HEADER_IP4)) {
        uint32_t dest_ip, src_port, dest_port;
        ppe_field_get(&ppep, PPE_FIELD_IP4_DST_ADDR, &dest_ip);
        ppe_field_get(&ppep, PPE_FIELD_UDP_SRC_PORT, &src_port);
        ppe_field_get(&ppep, PPE_FIELD_UDP_DST_PORT, &dest_port);

        if (router_ip_check(dest_ip) && is_ephemeral(src_port) &&
            is_ephemeral(dest_port)) {
            AIM_LOG_TRACE("ICMP Port Unreachable received on port: %d",
                          port_no);
            type = ICMP_DEST_UNREACHABLE;
            code = 3;
            result = INDIGO_CORE_LISTENER_RESULT_DROP;
            if (icmpa_send(&ppep, port_no, type, code)) {
                ++port_pkt_counters[port_no].icmp_port_unreachable_packets;
                return result;
            }
        }
    }

    /*
     * Identify if the reason is valid for ICMP Agent to consume the packet
     */
    if (match.fields.metadata & OFP_BSN_PKTIN_FLAG_L3_MISS) {
        AIM_LOG_TRACE("ICMP Dest Network Unreachable received on port: %d",
                      port_no);
        type = ICMP_DEST_UNREACHABLE;
        code = 0;
        result = INDIGO_CORE_LISTENER_RESULT_DROP;
        if (icmpa_send(&ppep, port_no, type, code)) {
            ++port_pkt_counters[port_no].icmp_net_unreachable_packets;
        }
    } else if (match.fields.metadata & OFP_BSN_PKTIN_FLAG_TTL_EXPIRED) {
        AIM_LOG_TRACE("ICMP TTL Expired received on port: %d", port_no);
        type = ICMP_TIME_EXCEEDED;
        code = 0;
        result = INDIGO_CORE_LISTENER_RESULT_DROP;
        if (icmpa_send(&ppep, port_no, type, code)) {
            ++port_pkt_counters[port_no].icmp_time_exceeded_packets;
        }
    }

    return result;
}
コード例 #10
0
ファイル: ppe_packet.c プロジェクト: Broadcom-Switch/of-dpa
/*
 * This is clearly an unscaleable approach.
 * If the combinations increase this should be
 * rewritten properly.
 */
int
ppe_packet_format_set(ppe_packet_t* ppep, ppe_header_t type)
{
    int rv = 0;
    ppe_header_t current;

    ppe_packet_format_get(ppep, &current);

    PPE_LOG_FORMAT("convert (data=%p,size=%d) from format %s to format %s",
                   ppep->data,
                   ppep->size, ppe_header_name(current), ppe_header_name(type));

    if(current == type) {
        /* Already in the requested format. */
        return 0;
    }
    else {
        switch(current)
            {
            case PPE_HEADER_8021Q:
                {
                    switch(type)
                        {
                        case PPE_HEADER_ETHERII:
                            {
                                PPE_MEMMOVE(ppep->data + 12,
                                            ppep->data + 16,
                                            ppep->size - 16);
                                ppep->size -= 4;
                                break;
                            }
                        default:
                            {
                                AIM_LOG_ERROR("invalid format set (%s)",
                                              ppe_header_name(type));
                                return -1;
                            }
                        }
                    break;
                }
            case PPE_HEADER_ETHERII:
                {
                    switch(type)
                        {
                        case PPE_HEADER_8021Q:
                            {
                                /* @fixme architecture */
                                ppep->size += 4;
                                ppep->_data = ppep->data;
                                ppep->data = aim_zmalloc(ppep->size);

                                PPE_MEMCPY(ppep->data, ppep->_data, 12);
                                PPE_MEMCPY(ppep->data+16, ppep->_data+12, ppep->size-16);

                                ppep->data[12] = 0x81;
                                ppep->data[13] = 0;
                                ppep->data[14] = 0;
                                ppep->data[15] = 0;
                                ppep->realloc = 1;

                                rv = 1;
                                break;
                            }
                        default:
                            {
                                AIM_LOG_ERROR("invalid format set(%s)",
                                              ppe_header_name(type));
                                return -1;
                            }
                        }
                    break;
                }
            default:
                {
                    AIM_LOG_ERROR("cannot convert from current format (%s)",
                              ppe_header_name(type));
                    return -1;
                }
            }

        /**
         * Need to reparse
         */
        ppe_parse(ppep);
        return rv;
    }
}
コード例 #11
0
ファイル: main.c プロジェクト: floodlight/switchlight-common
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;
}