U0 IPV4Handler(CEthernetFrame *ethernet_frame) { CIPV4Packet packet; IPV4PacketParse(&packet, ethernet_frame); ARPCachePut(packet.source_ip_address, ethernet_frame->source_address); switch (packet.protocol) { case IP_PROTOCOL_ICMP: NetLog("IPV4 HANDLER: ICMP."); ICMPHandler(&packet); break; case IP_PROTOCOL_TCP: NetWarn("IPV4 HANDLER: TCP."); TCPHandler(&packet); break; case IP_PROTOCOL_UDP: NetLog("IPV4 HANDLER: UDP."); UDPHandler(&packet); break; default: NetErr("IPV4 HANDLER: Unrecognized protocol: 0x%X", packet.protocol); break; } NetLog("IPV4 HANDLER: Exiting."); } U0 NetQueueEntryHandle(CNetQueueEntry *entry) { CEthernetFrame ethernet_frame; EthernetFrameParse(ðernet_frame, entry->frame, entry->packet_length); switch (ethernet_frame.ethertype) { case ETHERTYPE_ARP: NetLog("HANDLE NETQUEUE ENTRY: ARP."); ARPHandler(ðernet_frame); break; case ETHERTYPE_IPV4: NetLog("HANDLE NETQUEUE ENTRY: IPV4."); IPV4Handler(ðernet_frame); break; case ETHERTYPE_IPV6: NetWarn("HANDLE NETQUEUE ENTRY: IPV6. FIXME"); break; default: NetErr("HANDLE NETQUEUE ENTRY: Unrecognized ethertype: 0x%X", ethernet_frame.ethertype); break; } NetLog("HANDLE NETQUEUE ENTRY: Exiting."); } interrupt U0 NetHandler() { CNetQueueEntry *entry; NetLog("$BG,DKGRAY$$FG,BLACK$" "=== NET HANDLER ===" "$BG$$FG$"); NetLog("$BD,LTGRAY$$FD,WHITE$" "NET HANDLER: Entering interrupt."); while (entry = NetQueuePull) { NetLog("NET HANDLER: Caught NetQueue Entry, handling."); NetQueueEntryHandle(entry); NetLog("NET HANDLER: Finished handling NetQueue Entry, Freeing."); Free(entry); } NetLog("NET HANDLER: NetQueue empty, exiting interrupt.\n" "$BD,WHITE$$FD,LTGRAY$" "$BG,DKGRAY$$FG,BLACK$" "===================" "$BG$$FG$"); *(dev.uncached_alias + LAPIC_EOI)(U32*) = 0; } U0 NetHandlerInit() { IntEntrySet(I_NETHANDLER, &NetHandler); } NetHandlerInit;