Пример #1
0
 private void UpdatePendingRequests(IPv4 ipAddress,
                                    EthernetAddress macAddress)
 {
     using (pendingRequestsLock.Lock()) {
         //Sigh...we're missing a linked list in the current Singularity C# runtime
         foreach (PendingArpRequest pendingRequest in pendingRequests)
         {
             VTable.Assert(pendingRequest != null);
             if (pendingRequest.address == ipAddress)
             {
                 pendingRequest.active = false;
                 DebugStub.WriteLine("found waiting arp request...sending on out");
                 VectorQueueByte txBuffer = pendingRequest.txContainer.Acquire();
                 Bytes           header   = txBuffer.ExtractHead();
                 Bytes           buffer   = txBuffer.ExtractHead();
                 VTable.Assert(header != null);
                 VTable.Assert(buffer != null);
                 pendingRequest.txContainer.Release(txBuffer);
                 //Format ethernet header
                 EthernetHeader.Write(header, pendingRequest.localMac, macAddress, EthernetHeader.PROTOCOL_IP);
                 //send it!
                 VTable.Assert(pendingRequest.adapter != null);
                 pendingRequest.adapter.PopulateTxRing(header, buffer);
                 continue;
             }
         }
     }
 }
Пример #2
0
        public void ArpRequest(IPv4 sourceIP,
                               IPv4 targetIP,
                               EthernetAddress localMac,
                               Bytes header,
                               Bytes buffer,
                               IAdapter adapter)
        {
            //            AutoResetEvent requestComplete =
            AddPendingRequest(targetIP, TimeSpan.FromSeconds(3), localMac, header, buffer, adapter);

            // initiate an arp request...
            DebugPrint("Initiating request " +
                       "({0},{1}) --> ({2},{3})\n",
                       sourceIP, localMac, targetIP, EthernetAddress.Zero);

            //eventially we'll want to follow Orion's conservation of
            //packets philosophy
            Bytes arpHeader = new Bytes(new byte [EthernetHeader.Size]);
            Bytes arpMsg    = new Bytes(new byte [ArpHeader.Size]);

            //xxx I'd like to get rid of EthernetHeader eventually...

            EthernetHeader.Write(arpHeader,
                                 localMac,
                                 EthernetAddress.Broadcast,
                                 EthernetHeader.PROTOCOL_ARP);

            ArpHeader.Write(arpMsg, localMac, sourceIP,
                            ArpHeader.ARP_REQUEST, EthernetAddress.Zero,
                            targetIP);
            adapter.PopulateTxRing(arpHeader, arpMsg);
            //            DebugPrint("ArpRequest: waiting for reply\n");
            //requestComplete.WaitOne();
            //            DebugPrint("ArpRequest: reply received!\n");
        }
Пример #3
0
        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();
            }
        }
Пример #4
0
        internal bool Send(EthernetAddress dstAddr, DhcpFormat dhcp)
        {
            int   packetSize = dhcp.Size;
            int   headerSize = EthernetHeader.Size + UDPHeader.Size + IpHeader.Size;
            Bytes packet     = new Bytes(new byte [packetSize]);
            Bytes header     = new Bytes(new byte [headerSize]);

            // Write out DHCP packet
            dhcp.Write(packet, 0);
            //the correct ports/addresses should already be bound up in instance of the UDP object
            udp.WriteCompleteUDPHeader(header, packet, dhcp.Size);
            // Add Ethernet Header
            EthernetHeader.Write(header, adapter.HardwareAddress,
                                 dstAddr, EthernetHeader.PROTOCOL_IP);
            adapter.PopulateTxRing(header, packet);
            return(true);
        }
Пример #5
0
        // 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());
            }
        }
Пример #6
0
        //This function will format the higher layer packet to
        //have to correct ethernet and ip header?
        //Routing to multiple cards was broken in the old netstack...
        //for now we support a single interface
        //ipheader is already written...we just need to write the ethernet header
        public static void SendOutgoingPacket(Bytes header,
                                              Bytes buffer,
                                              IPv4 destinationAddress)
        {
            DebugPrint("IP.SendOutgoingPacket: dst {0}\n", destinationAddress);

            RouteEntry e = hostConfiguration.RoutingTable.Lookup(destinationAddress);

            if (e == null)
            {
                //delete header;
                //delete buffer;
                DebugPrint("Packet dropped -- no route\n");
                return;
            }

            IPv4 ifaddr = e.InterfaceAddress;
            IPv4 nextHop;

            if (e.Gateway == e.InterfaceAddress)
            {
                nextHop = destinationAddress;
            }
            else
            {
                nextHop = e.Gateway;
            }

            DebugPrint("Selected destination {0}\n", nextHop);

            DebugStub.Assert(e.Gateway == e.InterfaceAddress);

            IAdapter adapter = hostConfiguration.Bindings.GetAdapter(ifaddr);

            VTable.Assert(adapter != null);

            EthernetAddress localMac = adapter.HardwareAddress;
            EthernetAddress remoteMac;

            IAdapter targetAdapter = hostConfiguration.Bindings.GetAdapter(nextHop);

            if (targetAdapter != null)
            {
                remoteMac = targetAdapter.HardwareAddress;
            }
            else
            {
                if (arp.Lookup(nextHop, out remoteMac) == false)
                {
                    DebugStub.WriteLine("Outgoing packet, no ARP Entry for: {0}...about to wait\n",
                                        DebugStub.ArgList(nextHop));
                    arp.ArpRequest(ifaddr, nextHop, localMac, header, buffer, adapter);
                    //                    DebugPrint("ArpRequest complete...sending packet\n");
                    //                    bool rc = arp.Lookup(nextHop, out remoteMac);
                    //                    DebugStub.Assert(rc == true);
                    return;
                }
            }
            //Format ethernet header
            EthernetHeader.Write(header, localMac, remoteMac, EthernetHeader.PROTOCOL_IP);
            //send it!
            adapter.PopulateTxRing(header, buffer);
        }