dessert_cb_result_t lsr_sys2mesh(dessert_msg_t *msg, uint32_t len, dessert_msg_proc_t *proc, dessert_sysif_t *sysif, dessert_frameid_t id) {
	struct ether_header* l25h = dessert_msg_getl25ether(msg);
	msg->ttl = LSR_TTL_MAX;
	
	
	if(proc->lflags.l25_multicast) {
		msg->u16 = htons(lsr_db_broadcast_get_seq_nr());
		memcpy(msg->l2h.ether_dhost, ether_broadcast, ETH_ALEN);
		dessert_result_t result = lsr_send_randomized(msg);
		if(result != DESSERT_OK) {
			dessert_crit("error while trying to send multicast");
		}
	}
	else {
		msg->u16 = htons(lsr_db_unicast_get_seq_nr());
		dessert_meshif_t *out_iface;
		mac_addr next_hop;
		dessert_result_t result = lsr_db_get_next_hop(l25h->ether_dhost, &next_hop, &out_iface);
		
		if(result == DESSERT_OK) {
			memcpy(msg->l2h.ether_dhost, next_hop, ETH_ALEN);
			dessert_result_t result = lsr_send(msg, out_iface);
			if(result != DESSERT_OK) {
				dessert_crit("error while trying to send unicast");
			}
		}
		else {
			dessert_info("no route to dest " MAC, EXPLODE_ARRAY6(l25h->ether_dhost));
		}
	}
	return DESSERT_MSG_DROP;
}
Esempio n. 2
0
int aodv_metric_do(metric_t* metric, uint8_t last_hop[ETH_ALEN], dessert_meshif_t* iface) {

    switch(metric_type) {
        case AODV_METRIC_HOP_COUNT: {
            (*metric)++;
            break;
        }
        case AODV_METRIC_RSSI: {
            struct avg_node_result sample = dessert_rssi_avg(last_hop, iface);
            uint8_t interval = hf_rssi2interval(sample.avg_rssi);
            dessert_trace("incomming rssi_metric=%" AODV_PRI_METRIC ", add %" PRIu8 " (rssi=%" PRId8 ") for the last hop " MAC, (*metric), interval, sample.avg_rssi, EXPLODE_ARRAY6(last_hop));
            (*metric) += interval;
            break;
        }
        case AODV_METRIC_ETX: {
            dessert_crit("AODV_METRIC_ETX -> not implemented! -> using AODV_METRIC_HOP_COUNT as fallback");
            (*metric)++; /* HOP_COUNT */
            break;
        }
        case AODV_METRIC_ETT: {
            dessert_crit("AODV_METRIC_ETT -> not implemented! -> using AODV_METRIC_HOP_COUNT as fallback");
            (*metric)++; /* HOP_COUNT */
            break;
        }
        default: {
            dessert_crit("unknown metric=%" PRIu8 " -> using HOP_COUNT as fallback", metric_type);
            (*metric)++; /* HOP_COUNT */
            return false;
        }
    }

    return true;
}
void storeDroppedPacket(dessert_msg_t* msg) {
    trappedpacket_t* t;
    u_char* shost = dessert_msg_getl25ether(msg)->ether_shost;

    pkey_t lookup_key;
    memcpy(lookup_key.addr, shost, ETHER_ADDR_LEN);
    lookup_key.seq = msg->u16;

    /*###*/
    pthread_rwlock_wrlock(&packettrap_lock);
    HASH_FIND(hh, trappedpackets, &lookup_key, sizeof(pkey_t), t);
    if(t) {
        // TODO: gossip_10
        t->counter++;
    }
    pthread_rwlock_unlock(&packettrap_lock);
    /*###*/

    if(!t) {
        trappedpacket_t* t = malloc(sizeof(trappedpacket_t));
        if(!t) {
            dessert_crit("could not allocate memory");
            return;
        }

        dessert_msg_t* clone = NULL;
        dessert_msg_clone(&clone, msg, false);
        t->msg = clone;

        memcpy(&(t->key), &lookup_key, sizeof(pkey_t));
        t->counter = 1;
        t->counter2 = 0;
        t->forwarded = 0;

        /*###*/
        pthread_rwlock_wrlock(&packettrap_lock);
        HASH_ADD(hh, trappedpackets, key, sizeof(pkey_t), t);
        pthread_rwlock_unlock(&packettrap_lock);
        /*###*/

        uint32_t sec = timeout.tv_sec;
        uint32_t usec = timeout.tv_usec;
        if(gossip == gossip_7) {
            sec = 0;
            usec = 1000 * (random() % T_MAX_ms);
            while(usec >= 1000000) {
                sec += 1;
                usec -= 1000000;
            }
            dessert_debug("gossip7 random timeout: %ld s, %ld us", sec, usec);
        }
        struct timeval handle_interval;
        gettimeofday(&handle_interval, NULL);
        TIMEVAL_ADD(&handle_interval, sec, usec);
        dessert_periodic_add((dessert_periodiccallback_t *) handleTrappedPacket, t, &handle_interval, NULL);
    }
}
void storeForwardedPacket(dessert_msg_t* msg, uint8_t source) {
    trappedpacket_t* t;
    u_char* shost = dessert_msg_getl25ether(msg)->ether_shost;

    pkey_t lookup_key;
    memcpy(lookup_key.addr, shost, ETHER_ADDR_LEN);
    lookup_key.seq = msg->u16;

    /*###*/
    pthread_rwlock_wrlock(&packettrap_lock);
    HASH_FIND(hh, trappedpackets, &lookup_key, sizeof(pkey_t), t);
    if(t) {
        t->counter++;
    }
    pthread_rwlock_unlock(&packettrap_lock);
    /*###*/

    if(!t) {
        trappedpacket_t* t = malloc(sizeof(trappedpacket_t));
        if(!t) {
            dessert_crit("could not allocate memory");
            return;
        }

        dessert_msg_t* clone = NULL;
        dessert_msg_clone(&clone, msg, false);
        t->msg = clone;

        memcpy(&(t->key), &lookup_key, sizeof(pkey_t));
        if(source) {
            t->counter = 0;
        }
        else {
            t->counter = 1;
        }
        t->counter2 = 0;
        t->forwarded = 1;

        /*###*/
        pthread_rwlock_wrlock(&packettrap_lock);
        HASH_ADD(hh, trappedpackets, key, sizeof(pkey_t), t);
        pthread_rwlock_unlock(&packettrap_lock);
        /*###*/

        uint32_t sec = timeout.tv_sec;
        uint32_t usec = timeout.tv_usec;
        struct timeval handle_interval;
        gettimeofday(&handle_interval, NULL);
        TIMEVAL_ADD(&handle_interval, sec, usec);
        dessert_periodic_add((dessert_periodiccallback_t *) handleTrappedPacket, t, &handle_interval, NULL);
    }
}
Esempio n. 5
0
int aodv_metric_do(metric_t* metric, mac_addr last_hop, dessert_meshif_t* iface, struct timeval* timestamp) {

    switch(metric_type) {
        case AODV_METRIC_HOP_COUNT: {
            (*metric)++;
            break;
        }
#ifndef ANDROID
        case AODV_METRIC_RSSI: {
            struct avg_node_result sample = dessert_rssi_avg(last_hop, iface);
            metric_t interval = hf_rssi2interval(sample.avg_rssi);
            dessert_trace("incoming rssi_metric=%" AODV_PRI_METRIC ", add %" PRIu8 " (rssi=%" PRId8 ") for the last hop " MAC, (*metric), interval, sample.avg_rssi, EXPLODE_ARRAY6(last_hop));
            *metric += interval;
            break;
        }
#endif
        case AODV_METRIC_ETX_ADD: {
            metric_t link_etx_add = AODV_MAX_METRIC;
            if(aodv_db_pdr_get_etx_add(last_hop, &link_etx_add, timestamp)) {
                dessert_debug("Old metricval %" AODV_PRI_METRIC " ETX_ADD rcvd =%" PRIu16 " for this hop " MAC, (*metric), link_etx_add, EXPLODE_ARRAY6(last_hop));
            }
            else {
                dessert_debug("Old metricval %" AODV_PRI_METRIC " ETX_ADD for hop " MAC " failed", *metric, EXPLODE_ARRAY6(last_hop));
            }
            /**prevent overflow*/
            if(AODV_MAX_METRIC - link_etx_add > *metric) {
                *metric += link_etx_add;
            }
            else {
                *metric = AODV_MAX_METRIC;
            }
            dessert_debug("New metric value =%" AODV_PRI_METRIC " for hop " MAC, *metric, EXPLODE_ARRAY6(last_hop));
            break;
        }
        case AODV_METRIC_ETX_MUL: {
            metric_t link_etx_mul = 0;
            if(aodv_db_pdr_get_etx_mul(last_hop, &link_etx_mul, timestamp) == true) {
                dessert_debug("Old metricval %" AODV_PRI_METRIC " ETX_MUL rcvd =%" PRIu16 " for this hop " MAC, (*metric), link_etx_mul, EXPLODE_ARRAY6(last_hop));
                uintmax_t result = (*metric) * (uintmax_t)link_etx_mul;
                result /= (AODV_MAX_METRIC/32);
                (*metric) = (metric_t) result;
            }
            else {
                dessert_debug("Old metricval %" AODV_PRI_METRIC " ETX_MUL for hop " MAC " failed", (*metric), EXPLODE_ARRAY6(last_hop));
                (*metric) = 0;
            }
            dessert_debug("New metric value =%" AODV_PRI_METRIC " for hop " MAC, (*metric), EXPLODE_ARRAY6(last_hop));
            break;
        }
        case AODV_METRIC_PDR: {
            uint16_t link_pdr = 0;
            if(aodv_db_pdr_get_pdr(last_hop, &link_pdr, timestamp) == true){
                dessert_debug("Old metricval %" AODV_PRI_METRIC " PDR rcvd =%" PRIu16 " for this hop " MAC, (*metric), link_pdr, EXPLODE_ARRAY6(last_hop));
                uint32_t result = (*metric) * (uint32_t)link_pdr;
                result = result / AODV_MAX_METRIC;
                (*metric) = (metric_t) result;
            }
            else {
                dessert_debug("Old metricval %" AODV_PRI_METRIC " PDR for hop " MAC " failed", (*metric), EXPLODE_ARRAY6(last_hop));
                (*metric) = 0;
            }
            dessert_debug("New metric value =%" AODV_PRI_METRIC " for hop " MAC, (*metric), EXPLODE_ARRAY6(last_hop));
            break;
        }
        case AODV_METRIC_RFC: {
            break;
        }
        default: {
            dessert_crit("unknown metric set -> using AODV_METRIC_RFC as fallback");
            return false;
        }
    }

    return true;
}
dessert_cb_result_t lsr_unhandled(dessert_msg_t* msg, uint32_t len, dessert_msg_proc_t *proc, dessert_meshif_t *iface, dessert_frameid_t id) {
	dessert_crit("unhandled packet");
	return DESSERT_MSG_DROP;
}
/** Check if this packet is a duplicate
 *
 * Registers the sequence number as received if it is the first copy of the packet.
 * All subsequent received copies (duplicates) are dropped and the packet count is
 * increased, if the first copy is still in the packet trap.
 *
 * Looping packets sent by this host are also dropped.
 * The hop count value in the corresponding extension is incremented.
 */
int checkSeq(dessert_msg_t* msg, size_t len, dessert_msg_proc_t *proc, dessert_meshif_t *iface, dessert_frameid_t id) {
    if(/*proc->lflags & DESSERT_RX_FLAG_L2_SRC
    ||*/ proc->lflags & DESSERT_RX_FLAG_L25_SRC) {
        // TODO gossip_10
        dessert_debug("dropped looping packet from myself");
        return DESSERT_MSG_DROP;
    }

    seqlog_t* s = NULL;
    u_char* shost = dessert_msg_getl25ether(msg)->ether_shost;

    /*###*/
    pthread_rwlock_rdlock(&seqlog_lock);
    HASH_FIND(hh, seqlog, shost, ETHER_ADDR_LEN, s);
    pthread_rwlock_unlock(&seqlog_lock);
    /*###*/

    bool seq2_duplicate = false;
    if(s) {
        /*###*/
        pthread_rwlock_wrlock(&seqlog_lock);
        uint8_t dup = isDuplicate(s, msg->u16);
        if(!dup) {
            insertSeq(s, msg->u16);
#ifndef ANDROID
            seq2_duplicate = gossip13_rx_packet(s, msg, false);
#endif
            pthread_rwlock_unlock(&seqlog_lock);
            /*###*/
        }
        else {
            pthread_rwlock_unlock(&seqlog_lock);
            /*###*/
            if(!(msg->u8 & HELLO)) { // HELLOs are never trapped
                trappedpacket_t* t;
                pkey_t lookup_key;
                memcpy(lookup_key.addr, shost, ETHER_ADDR_LEN);
                lookup_key.seq = msg->u16;

                /*###*/
                pthread_rwlock_wrlock(&packettrap_lock);
                HASH_FIND(hh, trappedpackets, &lookup_key, sizeof(pkey_t), t);
                if(t) {
                    // TODO gossip_10
                    t->counter++;
                }
                pthread_rwlock_unlock(&packettrap_lock);
                /*###*/
            }
            return DESSERT_MSG_DROP;
        }
    }
    else {
        s = malloc(sizeof(seqlog_t));
        if(!s) {
            dessert_crit("could not allocate memory");
            return DESSERT_MSG_KEEP;
        }
        uint16_t i = 0;
        for(i=0; i<LOG_SIZE; i++) {
            s->seqs[i] = msg->u16;
        }
        s->next_seq = 1;
#ifndef ANDROID
        // what the other node tells me
        gossip13_new_history(&(s->rx_history), false); // does not require observation initialization
        gossip13_new_history(&(s->tx_history), false); // does not require observation initialization
        gossip13_new_history(&(s->total_tx_history), false); // does not require observation initialization
        gossip13_new_history_mean(&(s->hops_history), false); // does not require observation initialization
        gossip13_new_history(&(s->nodes_history), false); // does not require observation initialization
        gossip13_new_history_mean(&(s->mean_dist_history), false); // does not require observation initialization
        gossip13_new_history_mean(&(s->eccentricity_history), false); // does not require observation initialization

        // what I know about the other node
        gossip13_new_history(&(s->observed_history), true);
        gossip13_new_observation(&(s->observed_history->observations));
        gossip13_new_history_mean(&(s->my_hops_history), true);
        gossip13_new_observation_mean(&(s->my_hops_history->observations));
#endif

        s->tau = 0;
        memcpy(s->addr, shost, ETHER_ADDR_LEN);
        dessert_debug("registering seq=%d for src=" MAC " (previously unknown host)", msg->u16, EXPLODE_ARRAY6(shost));
#ifndef ANDROID
        seq2_duplicate = gossip13_rx_packet(s, msg, true);
#endif

        /*###*/
        pthread_rwlock_wrlock(&seqlog_lock);
        HASH_ADD(hh, seqlog, addr, ETHER_ADDR_LEN, s);
        pthread_rwlock_unlock(&seqlog_lock);
        /*###*/
    }
#ifndef ANDROID
    if(seq2_duplicate && gossip13_drop_seq2_duplicates
        && (proc->lflags & DESSERT_RX_FLAG_L25_DST || proc->lflags & DESSERT_RX_FLAG_L25_BROADCAST)) {
        return DESSERT_MSG_DROP;
    }
#endif

    dessert_ext_t* ext = NULL;
    if(dessert_msg_getext(msg, &ext, EXT_HOPS, 0)) {
        gossip_ext_hops_t* h = (gossip_ext_hops_t*) ext->data;
        h->hops++;
    }
    return DESSERT_MSG_KEEP;
}