Exemplo n.º 1
0
        public RPCResult <bool> PacketReceived(byte[] packet, int dev_no, int payload_offset,
                                               int payload_len, p_addr devsrc)
        {
            HWAddr dest = ReadHWAddr(packet, payload_offset);
            HWAddr src  = ReadHWAddr(packet, payload_offset + 6);

            /* Whole packet is 6 bytes dest MAC, 6 bytes source MAC,
             *  optional 4 bytes VLAN packet, 2 bytes ethertype,
             *  payload, 4 bytes frame check sequence (FCS) */
            payload_len    -= 18;
            payload_offset += 14;

            if (packet[14] == 0x81 && packet[15] == 0x00)
            {
                /* This is a VLAN tagged packet
                 *  We don't do anything special (yet) */
                payload_len    -= 4;
                payload_offset += 4;
            }

            ushort ethertype = (ushort)(((uint)packet[payload_offset - 2] << 8) |
                                        packet[payload_offset - 1]);

            System.Diagnostics.Debugger.Log(0, null, "Received packet of size " +
                                            packet.Length.ToString() + ", ethertype: " + ethertype.ToString("X4") +
                                            " from device " + dev_no.ToString());

            if (packet_handlers.ContainsKey(ethertype))
            {
                packet_handlers[ethertype].PacketReceived(packet, dev_no, payload_offset, payload_len, src);
            }

            return(true);
        }
Exemplo n.º 2
0
        public static HWAddr ReadHWAddr(byte[] buf, int offset)
        {
            HWAddr ret = new HWAddr();

            for (int i = 0; i < 6; i++)
            {
                ret.MAC[i] = buf[offset + i];
            }
            return(ret);
        }
Exemplo n.º 3
0
        public override bool Equals(p_addr other)
        {
            HWAddr o = other as HWAddr;

            if (o == null)
            {
                return(false);
            }
            for (int i = 0; i < 6; i++)
            {
                if (mac[i] != o.mac[i])
                {
                    return(false);
                }
            }
            return(true);
        }
Exemplo n.º 4
0
        public RPCResult <bool> PacketReceived(byte[] packet, int dev_no, int payload_offset,
                                               int payload_len, p_addr src)
        {
            ushort htype = net.ReadWord(packet, payload_offset);
            ushort ptype = net.ReadWord(packet, payload_offset + 2);
            byte   hlen  = packet[payload_offset + 4];
            byte   plen  = packet[payload_offset + 5];
            ushort oper  = net.ReadWord(packet, payload_offset + 6);

            if (htype != 1)
            {
                System.Diagnostics.Debugger.Log(0, null, "Packet with unknown HTYPE: " +
                                                htype.ToString("X4"));
                return(false);
            }
            if (hlen != 6)
            {
                System.Diagnostics.Debugger.Log(0, null, "Invalid HLEN: " +
                                                hlen.ToString());
                return(false);
            }

            HWAddr sha = net.ReadHWAddr(packet, payload_offset + 8);
            HWAddr tha = net.ReadHWAddr(packet, payload_offset + 8 + hlen + plen);

            var nd = net.devs[dev_no];

            // Reject those packets sent by ourselves (don't reply to our own
            //  announce packets)
            if (sha.Equals(nd.HWAddr))
            {
                return(false);
            }

            switch (ptype)
            {
            case 0x0800:
                // IPv4
            {
                if (plen != 4)
                {
                    System.Diagnostics.Debugger.Log(0, null, "Invalid HLEN: " +
                                                    hlen.ToString());
                    return(false);
                }

                IPv4Address spa = net.ReadIPv4Addr(packet, payload_offset + 14);
                IPv4Address tpa = net.ReadIPv4Addr(packet, payload_offset + 24);

                System.Diagnostics.Debugger.Log(0, null, "Received IPv4 packet: oper: " +
                                                oper.ToString() + ", SHA: " + sha.ToString() +
                                                ", SPA: " + spa.ToString() +
                                                ", THA: " + tha.ToString() +
                                                ", TPA: " + tpa.ToString());

                if (oper == 1)
                {
                    /* Is it a request for our own IP address? */
                    //var addr = net.devs[dev_no].a as IPv4Address
                    if (net.devs[dev_no].a.Equals(tpa))
                    {
                        System.Diagnostics.Debugger.Log(0, null, "Received ARP request for our IP");

                        // build a response packet.  We are usually directly above
                        //  the link layer in the stack, so only need to reserve space
                        //  for ethernet headers (if we are not big enough, the
                        //  ethernet layer will do this for us anyway, but it involves
                        //  a memcpy and so is less efficient)

                        byte[] ret           = new byte[100];
                        int    packet_offset = 32;
                        int    packet_len    = 0;

                        ret[packet_offset + packet_len++] = 0x00;               // HTYPE
                        ret[packet_offset + packet_len++] = 0x01;
                        ret[packet_offset + packet_len++] = 0x08;               // PTYPE
                        ret[packet_offset + packet_len++] = 0x00;
                        ret[packet_offset + packet_len++] = 0x06;               // HLEN
                        ret[packet_offset + packet_len++] = 0x04;               // PLEN
                        ret[packet_offset + packet_len++] = 0x00;               // OPER
                        ret[packet_offset + packet_len++] = 0x02;

                        // SHA
                        for (int i = 0; i < 6; i++)
                        {
                            ret[packet_offset + packet_len++] = net.devs[dev_no].HWAddr.MAC[i];
                        }
                        // SPA
                        for (int i = 0; i < 4; i++)
                        {
                            ret[packet_offset + packet_len++] = tpa.Octets[i];
                        }
                        // THA
                        for (int i = 0; i < 6; i++)
                        {
                            ret[packet_offset + packet_len++] = sha.MAC[i];
                        }
                        // TPA
                        for (int i = 0; i < 4; i++)
                        {
                            ret[packet_offset + packet_len++] = spa.Octets[i];
                        }


                        /*net.InvokeAsync("TransmitPacket",
                         *  new object[] { ret, dev_no, packet_offset, packet_len, sha },
                         *  net.sig_packet);*/
                        net.TransmitEthernetPacket(ret, dev_no, packet_offset,
                                                   packet_len, sha, 0x0806);
                    }
                    else if (tpa.Equals(spa) && tha.Equals(HWAddr.Zero))
                    {
                        // This is a gratuitous request (announce) packet
                        // Interpret it as a response
                        oper = 2;
                    }
                }
                if (oper == 2)
                {
                    /* This is a reply to a previous request, or an announcement */

                    // Cache the current response
                    System.Diagnostics.Debugger.Log(0, null, "Cacheing " +
                                                    spa.ToString() + " to " + sha.ToString());
                    GetProtocolDictionary(dev_no, 0x0800)[spa] = sha;

                    // Fulfil pending requests
                    var pending_list = GetPendingRequestList(dev_no, 0x0800,
                                                             spa);
                    while (pending_list.Count > 0)
                    {
                        var e = pending_list[pending_list.Count - 1];
                        System.Diagnostics.Debugger.Log(0, null, "Handling pending request");
                        ((RPCResult <HWAddr>)e.result).Result = sha;
                        e.result.Set();
                        pending_list.RemoveAt(pending_list.Count - 1);
                    }

                    // Remove the pointer to the pending list so it is collected
                    pending_reqs[dev_no][0x0800].Remove(spa);
                }
            }
            break;

            default:
                System.Diagnostics.Debugger.Log(0, null, "Packet with unknown PTYPE: " +
                                                htype.ToString("X4"));
                return(false);
            }

            return(true);
        }
Exemplo n.º 5
0
        public RPCResult <bool> AnnounceDevice(int dev_no, ushort etype)
        {
            if (etype == 0)
            {
                // Announce all addresses
                var addrs = new List <ushort>(net.devs[dev_no].addresses.Keys);
                foreach (var addr in addrs)
                {
                    AnnounceDevice(dev_no, addr);
                }
            }
            else
            {
                switch (etype)
                {
                case 0x0800:
                {
                    /* IPv4 */
                    HWAddr      sha           = net.devs[dev_no].HWAddr;
                    IPv4Address spa           = net.devs[dev_no].addresses[etype] as IPv4Address;
                    IPv4Address tpa           = spa;
                    HWAddr      tha           = HWAddr.Zero;
                    byte[]      pkt           = new byte[100];
                    int         packet_offset = 32;
                    int         packet_len    = 0;

                    pkt[packet_offset + packet_len++] = 0x00;               // HTYPE
                    pkt[packet_offset + packet_len++] = 0x01;
                    pkt[packet_offset + packet_len++] = 0x08;               // PTYPE
                    pkt[packet_offset + packet_len++] = 0x00;
                    pkt[packet_offset + packet_len++] = 0x06;               // HLEN
                    pkt[packet_offset + packet_len++] = 0x04;               // PLEN
                    pkt[packet_offset + packet_len++] = 0x00;               // OPER
                    pkt[packet_offset + packet_len++] = 0x01;

                    // SHA
                    for (int i = 0; i < 6; i++)
                    {
                        pkt[packet_offset + packet_len++] = sha.MAC[i];
                    }
                    // SPA
                    for (int i = 0; i < 4; i++)
                    {
                        pkt[packet_offset + packet_len++] = spa.Octets[i];
                    }
                    // THA
                    for (int i = 0; i < 6; i++)
                    {
                        pkt[packet_offset + packet_len++] = 0;
                    }
                    // TPA
                    for (int i = 0; i < 4; i++)
                    {
                        pkt[packet_offset + packet_len++] = tpa.Octets[i];
                    }

                    net.TransmitEthernetPacket(pkt, dev_no, packet_offset,
                                               packet_len, HWAddr.Multicast, 0x0806);
                }
                break;
                }
            }

            return(true);
        }
Exemplo n.º 6
0
        public RPCResult <HWAddr> ResolveAddress(int dev_no, p_addr addr)
        {
            /* Get the appropriate dictionary */
            var prot_dict = GetProtocolDictionary(dev_no, addr.EtherType);

            /* If the cache contains the value we need, then we can use it
             *  directly, otherwise we need to send a request for it */
            HWAddr ret;

            if (prot_dict.TryGetValue(addr, out ret) == true)
            {
                System.Diagnostics.Debugger.Log(0, null, "Resolving " +
                                                addr.ToString() + " from cache to " + ret.ToString());
                return(ret);
            }

            /* We need to send a ARP request out to the network, then respond to
             *  the reply.  Unfortunately, messages sent to the arp subsystem are
             *  processed sequentially, therefore the reply will never be processed
             *  until the current function exits.  To get around this, we tell the
             *  Invoke mechanism not to return from the synchronous call until
             *  we have that response */
            var e = CurrentMessage;

            e.EventSetsOnReturn = false;

            /* Send the request */
            switch (addr.EtherType)
            {
            case 0x0800:
                /* IPv4 */
                HWAddr      sha           = net.devs[dev_no].HWAddr;
                IPv4Address spa           = net.devs[dev_no].addresses[0x0800] as IPv4Address;
                IPv4Address tpa           = addr as IPv4Address;
                byte[]      pkt           = new byte[100];
                int         packet_offset = 32;
                int         packet_len    = 0;

                pkt[packet_offset + packet_len++] = 0x00;           // HTYPE
                pkt[packet_offset + packet_len++] = 0x01;
                pkt[packet_offset + packet_len++] = 0x08;           // PTYPE
                pkt[packet_offset + packet_len++] = 0x00;
                pkt[packet_offset + packet_len++] = 0x06;           // HLEN
                pkt[packet_offset + packet_len++] = 0x04;           // PLEN
                pkt[packet_offset + packet_len++] = 0x00;           // OPER
                pkt[packet_offset + packet_len++] = 0x01;

                // SHA
                for (int i = 0; i < 6; i++)
                {
                    pkt[packet_offset + packet_len++] = sha.MAC[i];
                }
                // SPA
                for (int i = 0; i < 4; i++)
                {
                    pkt[packet_offset + packet_len++] = spa.Octets[i];
                }
                // THA
                for (int i = 0; i < 6; i++)
                {
                    pkt[packet_offset + packet_len++] = 0;
                }
                // TPA
                for (int i = 0; i < 4; i++)
                {
                    pkt[packet_offset + packet_len++] = tpa.Octets[i];
                }

                net.TransmitEthernetPacket(pkt, dev_no, packet_offset,
                                           packet_len, HWAddr.Multicast, 0x0806);

                break;
            }

            // Store this request
            GetPendingRequestList(dev_no, addr.EtherType, addr).Add(e);

            // Return null for now until we actually get a result
            return(null);
        }