void handle_ip(const struct ip *ip, int len, void *userdata) { /* note: ip->ip_v does not work if header is not int-aligned */ /* fprintf(stderr, "IPv %d\n", (*(uint8_t *) ip) >> 4); */ switch ((*(uint8_t *) ip) >> 4) { case 4: handle_ipv4(ip, len, userdata); break; case 6: handle_ipv6((struct ip6_hdr *)ip, len, userdata); break; default: break; } }
dns_message * handle_ip(const struct ip * ip, int len) { switch(ip->ip_v) { case 4: return handle_ipv4(ip, len); break; #if USE_IPV6 case 6: return handle_ipv6((struct ip6_hdr *)ip, len); break; #endif default: return NULL; break; } }
/** * Ethernet: Receives an ethernet-packet and handles it according to * Receive-handle diagram. * * @return ZERO - packet was handled or no packets received; * NON ZERO - error condition occurs. */ int32_t receive_ether(void) { int32_t bytes_received; struct ethhdr * ethh; memset(ether_packet, 0, ETH_MTU_SIZE); bytes_received = recv(0, ether_packet, ETH_MTU_SIZE, 0); if (!bytes_received) // No messages return 0; if (bytes_received < sizeof(struct ethhdr)) return -1; // packet is too small ethh = (struct ethhdr *) ether_packet; if(memcmp(ethh->dest_mac, broadcast_mac, 6) != 0 && memcmp(ethh->dest_mac, multicast_mac, 3) != 0 && memcmp(ethh->dest_mac, own_mac, 6 ) != 0 && !is_multicast_mac(ethh->dest_mac)) return -1; // packet is too small switch (htons(ethh -> type)) { case ETHERTYPE_IP: return handle_ipv4((uint8_t*) (ethh + 1), bytes_received - sizeof(struct ethhdr)); /* case ETHERTYPE_IPv6: return handle_ipv6(ether_packet + sizeof(struct ethhdr), bytes_received - sizeof(struct ethhdr)); */ case ETHERTYPE_ARP: return handle_arp((uint8_t*) (ethh + 1), bytes_received - sizeof(struct ethhdr)); default: break; } return -1; // unknown protocol }