//process incoming packet public static bool ProcessIncomingPacket(Bytes packet, IpHeader ipHeader) { int offset = EthernetHeader.Size + IpHeader.Size; //14 byte ethernet header + 20 byte IP header VTable.Assert(offset == 34); UDPHeader udpHeader = new UDPHeader(packet, offset); DebugPrint("ProcessIncomingPacket: Received packet from address {0} port {1}\n", ipHeader.srcAddress.ToString(), udpHeader.srcPort); UDP udp = GetUDPSession(udpHeader.dstPort); //now we check to see whether the udp session wants to packet //XXX review this logic... //todo: check if udp is bound to local IP that dest IP matches. //UDP header? if ((udp != null) && ((udp.LocalAddress == IPv4.Any) || (udp.RemoteAddress == ipHeader.srcAddress && udp.RemotePort == udpHeader.srcPort) || (udp.RemotePort == 0))) { offset += UDPHeader.Size; Bytes data = Bitter.SplitOff(ref packet, offset); //delete packet; udp.PushPacket(data); udp.udpWaitEvent.Set(); return(true); } DebugPrint("Received packe destined for inactive UDP port {0}" + " source address {1} source port {2}\n", udpHeader.dstPort, ipHeader.srcAddress.ToString(), udpHeader.srcPort); //delete packet; return(false); }
// Original note from Yaron: // ARP logic: see RFC 826 http://www.faqs.org/rfcs/rfc826.html // public void ProcessIncomingPacket(Bytes packet, IAdapter adapter) { //Get the ARP packet info located after the ethernet header ArpHeader arpHeader = new ArpHeader(packet, 14); DebugPrint("ARP: ProcessIncomingPacket\n"); //do some checks to make sure the packet is copacetic if (arpHeader.htype != 0x1) { DebugPrint("ARP: ProcessIncomingPacket got wrong hardware type? 0x{0,8:x}\n", arpHeader.htype); //delete packet; return; } if (arpHeader.ptype != 0x0800) { DebugPrint("ARP: ProcessIncomingPacket got wrong protocol? 0x{0,8:x}\n", arpHeader.ptype); //delete packet; return; } //ethernet address should be 6 bytes if (arpHeader.hlen != 6) { DebugPrint("ARP: ProcessIncomingPacket got wrong hw length? 0x{0,8:x}\n", arpHeader.hlen); //delete packet; return; } if (arpHeader.plen != 4) { DebugPrint("ARP: ProcessIncomingPacket got wrong protocol address length? 0x{0,8:x}\n", arpHeader.plen); //delete packet; return; } DebugPrint("Incoming packet\n"); bool merged = false; bool updated = false; ArpEntry target = arpTable.Lookup(arpHeader.senderIPAddr); if (target != null && target.Dynamic == true) { DebugPrint("ARP UPDATE\n"); // we have it already - just update the details... target.MacAddress = arpHeader.senderEthernetAddr; target.EntryAge = arpTable.Age; merged = true; updated = true; } if (merged == false) { DebugPrint("ARP ADDITION\n"); arpTable.AddEntry(new ArpEntry(arpHeader.senderIPAddr, arpHeader.senderEthernetAddr, true)); merged = true; UpdatePendingRequests(arpHeader.senderIPAddr, arpHeader.senderEthernetAddr); } //Is this a local address bool forSelf = IP.IsLocalAddress(arpHeader.destIPAddr); if (forSelf == false) { //delete packet; return; } // now figure out the opcode if (arpHeader.op == ARP_REQUEST) { DebugPrint("Handling request ({0},{1}) ---> ({2},{3} \npkt dest {4} {5})\n", arpHeader.senderIPAddr, arpHeader.senderEthernetAddr, arpHeader.destIPAddr, adapter.HardwareAddress, arpHeader.destIPAddr, arpHeader.destEthernetAddr ); int dataLength = EthernetHeader.Size + ArpHeader.Size; VTable.Assert(packet.Length >= dataLength); Bytes data = Bitter.SplitOff(ref packet, EthernetHeader.Size); EthernetHeader.Write(packet, adapter.HardwareAddress, arpHeader.senderEthernetAddr, EthernetHeader.PROTOCOL_ARP); //use arp header to format reply ArpHeader.Write(data, adapter.HardwareAddress, arpHeader.destIPAddr, ArpHeader.ARP_REPLY, arpHeader.senderEthernetAddr, arpHeader.senderIPAddr); adapter.PopulateTxRing(packet, data); } else { // otherwise we are done DebugPrint( "Handling reply ({2},{3}) <--- ({0},{1})\n", arpHeader.senderIPAddr, arpHeader.senderEthernetAddr, arpHeader.destIPAddr, arpHeader.destEthernetAddr ); //delete packet; } if (merged && !updated) { DebugPrint(arpTable.ToString()); } }