public static void ProcessIncomingPacket(Bytes packet, IAdapter adapter) { //check the header //send it off to the instance of the protocol to further parse and handle try { ushort protocol; EthernetHeader.GetProtocol(packet, out protocol); switch (protocol) { case EthernetHeader.PROTOCOL_IP: DebugPrint("IP\n"); // DebugPrint("Received IP Packet...processing\n"); IP.ProcessIncomingPacket(packet, adapter); DebugPrint("IP D\n"); break; case EthernetHeader.PROTOCOL_ARP: // DebugPrint("Received ARP Packet...processing\n"); DebugPrint("ARP\n"); arp.ProcessIncomingPacket(packet, adapter); DebugPrint("ARPD\n"); break; case EthernetHeader.PROTOCOL_NLB: DebugPrint("Received NLB packet...discarding\n"); //delete packet; break; case 0x8100: DebugPrint("Q/P\n"); break; case EthernetHeader.PROTOCOL_IP6: DebugPrint("IPv6\n"); break; default: DebugPrint("Unexpected Ethernet protocol ", protocol.ToString("X") + ". "); // DebugStub.Break(); //delete packet; break; } } catch (Exception e) { DebugStub.Print("Exception in Ethernet.ProcessIncomingPacket txt:{0}\n", DebugStub.ArgList(e)); DebugStub.Break(); } }
internal static int AppMain(ServiceParameters parameters) { NicDeviceContract /*.Imp*/ nicImp = parameters.NicEndpointRef.Acquire(); nicImp.RecvSuccess(); //delete nicImp; DebugStub.WriteLine("Closed nic contract via reflection\n"); ARP arp = new ARP(); IP.Initialize(arp); Ethernet.Initialize(arp); NetStackApplication app = new NetStackApplication(parameters); try { return(app.Run()); } finally { //delete app; Dbg("NetStack is terminating."); } }
//There are several different flavors of implementation for WriteTo //BSD Unix assigns an ephemeral port for every packet, while Linux //picks an ephemeral port and assigns it permanantly. I'm unsure of the //behavior of windows. public bool WriteTo(IPv4 remoteAddr, ushort remotePort, Bytes buffer) { //allocate a local port if (localPort == 0) { bool rc; DebugPrint("Assigning local port to process for WriteTo\n"); rc = AssignNextAvailablePort(); VTable.Assert(rc); } if (localIPAddress == IPv4.Any) { HostConfiguration hostConfiguration = IP.GetHostConfiguration(); RouteEntry e = hostConfiguration.RoutingTable.Lookup(remoteAddr); if (e != null) { localIPAddress = e.InterfaceAddress; DebugPrint("local address now {0}\n", localIPAddress); } else { DebugPrint("No route for {0}\n", remoteAddr); } } int headerSize = EthernetHeader.Size + IpHeader.Size + UDPHeader.Size; Bytes header = new Bytes(new byte[headerSize]); WriteCompleteUDPHeader(header, buffer, buffer.Length); DebugPrint("Sending UDP packet\n"); IP.SendOutgoingPacket(header, buffer, remoteAddr); return(true); }
public bool IsLocalAddress(IPv4 ipAddress) { return(IP.IsLocalAddress(ipAddress)); }
// 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()); } }
internal bool InstallDhcpOptions(SortedList dhcpOptions) { if (activeDhcpOptions != null) { UninstallDhcpOptions(); } // // Add interface address binding // DhcpIPv4Option address = dhcpOptions[DhcpRequestedIPAddress.OptionCode] as DhcpIPv4Option; DhcpIPv4Option netmask = dhcpOptions[DhcpSubnetMask.OptionCode] as DhcpIPv4Option; DhcpMultiIPv4Option routers = dhcpOptions[DhcpRouter.OptionCode] as DhcpMultiIPv4Option; if (address == null || netmask == null || routers == null || routers.Values.Length == 0) { return(false); } HostConfiguration hostConfiguration = IP.GetHostConfiguration(); hostConfiguration.Bindings.Add( adapter, new InterfaceIPConfiguration(address.Value, netmask.Value, routers.Values[0]) ); // // Register Domain name // DhcpStringOption domain = dhcpOptions[DhcpDomainName.OptionCode] as DhcpStringOption; // string domainName = ip.HostConfiguration.GetDomainName(); // never used if (domain != null) { hostConfiguration.SetDomainName(domain.Value); } // // Add DNS servers // DhcpMultiIPv4Option dnsServers = dhcpOptions[DhcpDomainNameServer.OptionCode] as DhcpMultiIPv4Option; if (dnsServers != null) { foreach (IPv4 server in dnsServers.Values) { hostConfiguration.AddNameServer(server); } } // // Install static routes // DhcpMultiIPv4Option staticRoutes = dhcpOptions[DhcpStaticRoutes.OptionCode] as DhcpMultiIPv4Option; if (staticRoutes != null) { int routeCount = staticRoutes.Values.Length & ~1; // pairs for (int i = 0; i < routeCount; i += 2) { IPv4 destination = staticRoutes.Values[i]; IPv4 gateway = staticRoutes.Values[i + 1]; IPv4 ifAddress = address.Value; hostConfiguration.RoutingTable.AddRoute( new RouteEntry(destination, gateway, ifAddress, RouteEntry.DefaultRouteMetric, 0) ); } } activeDhcpOptions = dhcpOptions; return(true); }