voidinsert_mac_port(u8 mac[ETH_ALEN], iface_info_t *iface) { // insert mac -> iface pair into mac_port table // it is just a insertion to a hash table // first calc the hash value log(INFO, "insert "ETHER_STRING" -> %s into mac_port table", ETHER_FMT(mac), iface->name); int hash = hash8((char *)mac, ETH_ALEN); log(DEBUG, "hash value of "ETHER_STRING" is %d", ETHER_FMT(mac), hash); // lock pthread_mutex_lock(&mac_port_map.lock); mac_port_entry_t *entry = (mac_port_entry_t *)malloc(sizeof(mac_port_entry_t)); memcpy(entry->mac, mac, ETH_ALEN); entry->iface = iface; entry->visited = time(NULL); list_add_tail(&entry->list, &mac_port_map.hash_table[hash]); pthread_mutex_unlock(&mac_port_map.lock); }
voidhandle_packet(iface_info_t *iface, char *packet, int len) { structether_header *eh = (struct ether_header *)packet; log(DEBUG, "the dst mac address is " ETHER_STRING ".\n", ETHER_FMT(eh->ether_dhost)); log(DEBUG, "the src mac address is " ETHER_STRING ".\n", ETHER_FMT(eh->ether_shost)); // if the dest mac address is found in mac_port table, forward it; otherwise, // broadcast it. if (is_broadcast(eh->ether_dhost)) { log(DEBUG, "the dst mac address is broadcast address, broadcast it."); broadcast_packet(iface, packet, len); free(packet); return; } iface_info_t *dst_iface = lookup_port(eh->ether_dhost); if (dst_iface != NULL) { log(DEBUG, "found " ETHER_STRING " in mac_port table, forward it.", ETHER_FMT(eh->ether_dhost)); iface_send_packet(dst_iface, packet, len); } else { log(DEBUG, "not found " ETHER_STRING " in mac_port table, broadcast it.", ETHER_FMT(eh->ether_dhost)); broadcast_packet(iface, packet, len); } if (!lookup_port(eh->ether_shost)) insert_mac_port(eh->ether_shost, iface); free(packet); }