Exemplo n.º 1
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");
        }
Exemplo n.º 2
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());
            }
        }