示例#1
0
        public void ArpRequest(IPv4 sourceIP,
                               IPv4 targetIP,
                               Multiplexer !targetMux,
                               ArpRequestCallback callback,
                               object cookie,
                               TimeSpan timeout)
        {
            //
            //XXXX Check pending request does not already exist!
            //
            EthernetAddress localMac = targetMux.Adapter.HardwareAddress;

            AddPendingRequest(targetIP, callback, cookie, timeout);

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

            byte[] data = new byte[ArpFormat.Size + EthernetFormat.Size];
            int    pos  = EthernetFormat.Write(data, 0, localMac,
                                               EthernetAddress.Broadcast,
                                               EthernetFormat.PROTOCOL_ARP);

            ArpFormat.Write(data, pos, localMac, sourceIP,
                            ArpFormat.Type.ARP_REQUEST, EthernetAddress.Zero,
                            targetIP);

            NetPacket pkt = new NetPacket(data);

            pkt.Mux = targetMux;
            OnProtocolSend(pkt);
        }
示例#2
0
        ///
        // ARP logic: see RFC 826 http://www.faqs.org/rfcs/rfc826.html
        //
        public NetStatus OnProtocolReceive(NetPacket !pkt)
        {
            NetStatus res = NetStatus.Code.PROTOCOL_OK;

            Debug.Assert(pkt != null);

            ArpFormat.Type  opcode;
            EthernetAddress senderMAC, targetMAC;
            IPv4            senderIP, targetIP;

            bool ok = ArpFormat.Read(pkt, out opcode,
                                     out senderMAC, out senderIP,
                                     out targetMAC, out targetIP);

            DebugPrint("ARP RESPONSE\n");

            // check for problems
            if (ok == false)
            {
                DebugPrint("ARP READ ERROR\n");
                return(NetStatus.Code.PROTOCOL_DROP_ERROR);
            }

            bool     merged  = false;
            bool     updated = false;
            ArpEntry target  = arpTable.Lookup(senderIP);

            if (target != null && target.Dynamic == true)
            {
                DebugPrint("ARP UPDATE\n");
                // we have it already - just update the details...
                target.MacAddress = senderMAC;
                target.EntryAge   = arpTable.Age;
                merged            = true;
                updated           = true;
            }

            bool forSelf = ipModule.HostConfiguration.IsLocalAddress(targetIP);

            if (forSelf == false)
            {
                return(NetStatus.Code.PROTOCOL_OK);
            }

            if (merged == false)
            {
                DebugPrint("ARP ADDITION\n");
                arpTable.AddEntry(new ArpEntry(senderIP, senderMAC, true));
                merged = true;
                UpdatePendingRequests(senderIP, senderMAC);
            }

            // now figure out the opcode
            if (opcode == ArpFormat.Type.ARP_REQUEST)
            {
                DebugPrint("Handling request ({0},{1}) ---> ({2},{3})\n",
                           senderIP, senderMAC, targetIP, targetMAC
                           );

                // send reply...
                // we reuse the received packet for sending a fast response
                // so we should NOT return it to the Demux's free list!!!
                // (we replace it with a new one instead)
                // we use the adapter from which the request arrived
                // (available in the context)
                Multiplexer mux = Core.Instance().GetMuxForAdapter((IAdapter !)pkt.AdapterContext);
                if (mux == null)
                {
                    // some internal bug, for now just panic
                    Core.Panic("At ArpModule.PacketReceive: " +
                               "context isn't Multiplexer!\n");
                    assert(false);
                }

                int dataLength = EthernetFormat.Size + ArpFormat.Size;
                if (dataLength < pkt.Length)
                {
                    dataLength = pkt.Length;
                }

                byte[] !data = new byte[dataLength];
                Array.Copy(pkt.GetRawData(), 0, data, 0, pkt.Length);

                ArpFormat.CreateArpReply(ref data, targetIP,
                                         mux.Adapter.HardwareAddress);
                mux.SendDirect(new NetPacket(data));
            }
            else
            {
                // otherwise we are done
                DebugPrint(
                    "Handling reply ({2},{3}) <--- ({0},{1})\n",
                    senderIP, senderMAC, targetIP, targetMAC
                    );
            }

            if (merged && !updated)
            {
                DebugPrint(arpTable.ToString());
            }

            return(res);
        }