Exemple #1
0
        private static void SendMDNSNameReply()
        {
            if (Adapter.IPAddress == null || Networking.Adapter.Name == string.Empty)
            {
                return;
            }

            prefix.Overwrite(0, new byte[6] {
                0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb
            });
            prefix.Overwrite(6, Adapter.MacAddress);       // Source MAC Address
            prefix.Overwrite(26, Adapter.IPAddress);       // Source IP Address

            lock (lockObj)
            {
                // Set the all-important name and IP address -- that's the whole purpose here...!
                suffix.Overwrite(10, Adapter.IPAddress);
                var result = Utility.CombineArrays(prefix, Utility.CombineArrays(DNS.EncodeDnsName(Networking.Adapter.Name + ".local"), suffix));

                result.Overwrite(16, ((ushort)(result.Length - 14)).ToBytes()); // Set IPv4 message size

                result.Overwrite(38, ((ushort)(result.Length - 34)).ToBytes()); // Set UDP message size

                result.Overwrite(24, new byte[] { 0x00, 0x00 });                // clear header checksum, so that calc excludes the checksum itself
                result.Overwrite(24, result.InternetChecksum(20, 14));          // header checksum

                result.Overwrite(40, new byte[] { 0x00, 0x00 });                // clear UDP Checksum

                Debug.WriteLine("Sending MDNS name message! ");

                Adapter.nic.SendFrame(result);  // Send the packet out into the ether....!
            }
        }
Exemple #2
0
        /// <summary>
        /// Take care of a packet of Multicast DNS stuff
        /// </summary>
        /// <param name="payload"></param>
        internal static void HandlePacket(byte[] payload)
        {
            ushort ipHeaderLength = (ushort)((payload[14] & 0x0f) * 4);
            var    name           = DNS.DecodeDnsName(payload, 34 + ipHeaderLength); // Name from first Query

            if (Adapter.VerboseDebugging)
            {
                Debug.WriteLine("Local Name Request (MDNS) for " + name);
            }

            bool isQuery = (payload[24 + ipHeaderLength] & (1 << 7)) == 0;  // DNS Query ?

            if (!isQuery)
            {
                return;
            }

            // Validate that this is MDNS address 224.0.0.251
            if (payload[10 + ipHeaderLength] != 0xe0 || payload[11 + ipHeaderLength] != 0x00 || payload[12 + ipHeaderLength] != 0x00 || payload[13 + ipHeaderLength] != 0xfb)
            {
                return;
            }


            if (name != Networking.Adapter.Name + ".local")
            {
                return;                                              // if the name requested does not match ours, exit!
            }
            // Wow, if we made it past all that, we should send a reply...
            SendMDNSNameReply();
        }
Exemple #3
0
        /// <summary>
        /// A synchronous call to send an HTTP Request and Receive a Response --  this call will block (until the timeout) while trying to get the result
        /// </summary>
        /// <param name="timeout">Time out in seconds</param>
        /// <param name="RetrieveHeaderOnly">Set this to true if you don't need the content of the response (which can consume a lot of memory)</param>
        /// <returns>And HttpResponse object OR a null if it timeout happened</returns>
        public HttpResponse Send(ushort timeout = 5, bool ReturnHeaderOnly = false)
        {
            this.omitContent = ReturnHeaderOnly;

            // if _con is null, create and open a new connection.  with a DNS lookup of host if necessary
            if (_con == null)
            {
                var remoteIp = DNS.Lookup(Host);
                _con = new Connection()
                {
                    RemoteIP = remoteIp
                };
            }

            var r = AssembleRequest();

            _responseToSend = null;

            _con.OnConnectionPacketReceived += _con_OnConnectionPacketReceived;

            responseWaitHandle.Reset();  // This will release an Open() call waiting for the connection!

            _con.SendAsync(r, 0, (short)r.Length);

            //Wait for response or timeout

            responseWaitHandle.WaitOne(timeout * 1000, true);

            _con.OnConnectionPacketReceived -= _con_OnConnectionPacketReceived;

            return(_responseToSend);
        }
Exemple #4
0
        public void SendAsync()
        {
            // if _con is null, create and open a new connection.  with a DNS lookup of host if necessary
            if (_con == null)
            {
                var remoteIp = DNS.Lookup(Host);
                _con = new Connection()
                {
                    RemoteIP = remoteIp
                };
            }

            var r = AssembleRequest();

            _con.SendAsync(r, 0, (short)r.Length);
        }
Exemple #5
0
        /// <summary>
        ///
        /// </summary>
        private static void SendLLMNRNameReply(string name, byte[] tranID, byte[] destinationMac, byte[] destinationIP, byte[] destinationPort)
        {
            if (Adapter.IPAddress == null || Networking.Adapter.Name == string.Empty)
            {
                return;
            }

            lock (lockObj)
            {
                prefix.Overwrite(0, destinationMac);
                prefix.Overwrite(6, Adapter.MacAddress);       // Source MAC Address
                prefix.Overwrite(26, Adapter.IPAddress);       // Source IP Address
                prefix.Overwrite(30, destinationIP);
                prefix.Overwrite(36, destinationPort);
                prefix.Overwrite(42, tranID);

                var suffix   = new byte[name.Length * 2 + 22];
                var byteName = Utility.CombineArrays(DNS.EncodeDnsName(name), new byte[4] {
                    0x00, 0x01, 0x00, 0x01
                });
                suffix.Overwrite(0, Utility.CombineArrays(byteName, byteName));
                suffix.Overwrite(suffix.Length - 7, new byte[1] {
                    0x1e
                });                                                         // Time To Live (30 seconds)
                suffix.Overwrite(suffix.Length - 5, new byte[1] {
                    0x04
                });                                                         // IP Address length
                suffix.Overwrite(suffix.Length - 4, Adapter.IPAddress);

                var result = Utility.CombineArrays(prefix, suffix);

                result.Overwrite(16, ((ushort)(result.Length - 14)).ToBytes()); // Set IPv4 message size

                result.Overwrite(38, ((ushort)(result.Length - 34)).ToBytes()); // Set UDP message size

                result.Overwrite(24, new byte[] { 0x00, 0x00 });                // clear header checksum, so that calc excludes the checksum itself
                result.Overwrite(24, result.InternetChecksum(20, 14));          // header checksum

                result.Overwrite(40, new byte[] { 0x00, 0x00 });                // clear UDP Checksum

                Adapter.nic.SendFrame(result);                                  // Send the packet out into the ether....!

                Debug.WriteLine("LLMNR Response sent");
            }
        }
Exemple #6
0
        /// <summary>
        /// Take care of a packet of Linked-Local Multicast Name Resolution (LLMNR) stuff
        /// </summary>
        /// <param name="payload"></param>
        internal static void HandlePacket(byte[] payload)
        {
            ushort ipHeaderLength = (ushort)((payload[14] & 0x0f) * 4);
            var    name           = DNS.DecodeDnsName(payload, 34 + ipHeaderLength); // Name from first Query

            bool isQuery = (payload[24 + ipHeaderLength] & (1 << 7)) == 0;           // DNS Query ?

            if (!isQuery)
            {
                return;
            }

            // This is not a good or valid way to detect the type because there could be multiple answers, but I have bigger fish to fry...
            bool isTypeA = payload[payload.Length - 3] == 0x01;

            if (!isTypeA)
            {
                return;
            }

            // Validate that this is an LLMNR address 224.0.0.252
            if (payload[10 + ipHeaderLength] != 0xe0 || payload[11 + ipHeaderLength] != 0x00 || payload[12 + ipHeaderLength] != 0x00 || payload[13 + ipHeaderLength] != 0xfc)
            {
                return;
            }

            //Debug.WriteLine("Local Name Request (LLMNR, Type A) for " + name);

            if (name != Networking.Adapter.Name + ".local" && name != Networking.Adapter.Name)
            {
                return;                                                                                 // if the name requested does not match ours, exit!
            }
            if (Adapter.VerboseDebugging)
            {
                Debug.WriteLine("Local Name Request (LLMNR, Type A) for " + name);
            }

            SendLLMNRNameReply(name, Utility.ExtractRangeFromArray(payload, 42, 2), Utility.ExtractRangeFromArray(payload, 6, 6), Utility.ExtractRangeFromArray(payload, 26, 4), Utility.ExtractRangeFromArray(payload, 34, 2));
        }
        // event handler for new ethernet frame arrivals
        static void nic_OnFrameArrived(ENC28J60Driver sender, byte[] frame, DateTime timeReceived)
        {
            //if (buf[0] == 0x01)
            //{
            //    Debug.WriteLine("Probable Multicast Message Detected - " + buf.Length.ToString());
            //    if (buf[29] == 0x65) Debug.WriteLine("IP ending in 101");
            //}

            //if (buf[29] == 0x65)
            //{
            //    Debug.WriteLine("IP ending in 101 - size: " + buf.Length.ToString());

            //    if (buf.Length == 541)
            //        Debug.WriteLine("What is this? ");
            //}

            //var packetID = Guid.NewGuid().ToString();

            if (frame == null)
            {
                return;
            }

            //Debug.WriteLine("Memory: " + Microsoft.SPOT.Debug.GC(false).ToString() + ", packetID = " + packetID + ", age = " + timeReceived.Subtract(DateTime.Now).Seconds + "s, size = " + frame.Length + ", addys = " + Utility.ExtractRangeFromArray(frame, 0, 14).ToAddress());



            if (frame[13] == 0x06 && frame[12] == 0x08)  // ARP Packet Type
            {
                if (IPAddress != null)
                {
                    // If message request, and IP matches ours, we need to respond!
                    if (frame[41] == IPAddress[3] && frame[40] == IPAddress[2] && frame[39] == IPAddress[1] && frame[38] == IPAddress[0])
                    {
                        ARP.HandlePacket(frame);
                    }
                    else if (frame[21] == 0x02 && frame[31] == IPAddress[3] && frame[30] == IPAddress[2] && frame[29] == IPAddress[1] && frame[28] == IPAddress[0])
                    {
                        Debug.WriteLine("Possible IP Address Conflict Detected");
                        Adapter.Stop();  // IP Address Conflict!
                                         //TODO: if DHCP is enabled, don't stop the networking!  Just reset and get a new IP!!!!
                    }
                }
            }
            else if (frame[13] == 0x00 && frame[12] == 0x08) // Handle IP packets
            {
                if (frame[23] == 0x01)                       // Protocol 1 -- PING
                {
                    // Debug.WriteLine("Received ICMP (Ping) Packet -- " + frame.Length + " bytes");

                    ICMP.HandlePacket(frame);
                }
                else if (frame[23] == 0x11)                                      // Protocol 17 -- UDP
                {
                    if (frame[37] == 0x44 && !DhcpDisabled && frame[36] == 0x00) // DHCP port 68  -- Order of conditions to short-circuit earlier!
                    {
                        //Debug.WriteLine("Received DHCP Packet -- " + frame.Length + " bytes");

                        DHCP.HandlePacket(frame);
                    }
                    else if (frame[37] == 0x89 && frame[36] == 0x00 && Name != null && Name != string.Empty && IPAddress != null)  // NetBIOS port 137 and name is set
                    {
                        //Debug.WriteLine("Received NBNS Packet -- " + frame.Length + " bytes");

                        // Uncomment the line below to enable Netbios over TCP Name resolution
                        NetBiosNaming.HandlePacket(frame);
                    }
                    else if (frame[35] == 0x35 && frame[34] == 0x00)  // DNS Source Port of 53 (0x35h)
                    {
                        //Debug.WriteLine("Received DNS Packet -- " + frame.Length + " bytes");

                        DNS.HandlePacket(frame);
                    }
                    else if (frame[37] == 0xe9 && frame[36] == 0x14 && frame[35] == 0xe9 && frame[34] == 0x14 && Name != null && Name != string.Empty && IPAddress != null) // mDNS Source and Destination Port of 5353 or LLMNR Destination Port of 5355
                    {
                        //Debug.WriteLine("Received MDNS Packet -- " + frame.Length + " bytes");

                        MDNS.HandlePacket(frame);
                    }
                    else if (frame[37] == 0xeb && frame[36] == 0x14 && Name != null && Name != string.Empty && IPAddress != null)
                    {
                        // Debug.WriteLine("Received LLMNR Packet -- " + frame.Length + " bytes");

                        LLMNR.HandlePacket(frame);
                    }
                    else if (OnUdpReceivedPacketEvent != null && IPAddress != null)  // Check Listening ports
                    {
                        //Debug.WriteLine("Received UDP Packet -- " + frame.Length + " bytes");

                        foreach (byte[] aPort in ListeningPorts.Values)
                        {
                            if (aPort[0] == frame[36] && aPort[1] == frame[37])
                            {
                                UDP.HandlePacket(frame);
                            }
                        }
                    }
                }
                else if (frame[23] == 0x06 && IPAddress != null)  // Protocol 6 -- TCP
                {
                    //Debug.WriteLine("Received TCP Packet -- " + frame.Length + " bytes");

                    foreach (byte[] aPort in ListeningPorts.Values)
                    {
                        if (aPort[0] == frame[36] && aPort[1] == frame[37])
                        {
                            TCP.HandlePacket(frame);
                            return;
                        }
                    }

                    // Handle a response from a currently open connection
                    ulong conID = TCP.GenerateConnectionID(frame);
                    if (TCP.Connections.Contains(conID))
                    {
                        TCP.HandlePacket(frame);
                    }
                    //else
                    //TODO: Send a RST as a response to a closed port.

                    //var port = (new byte[2] { frame[36], frame[37] }).ToShort();

                    //foreach (Connection aCon in TCP.Connections)
                    //{
                    //    if (aCon.LocalPort == port)
                    //        TCP.HandlePacket(frame);
                    //    return;
                    //}
                }
            }

            // All other packets are ignored... like throwing back a fish :)

            //Debug.WriteLine("Memory: " + Microsoft.SPOT.Debug.GC(false).ToString() + ", packetID = " + packetID);


            //Microsoft.SPOT.Debug.EnableGCMessages(true);
        }
Exemple #8
0
        /// <summary>
        /// Seperate send method to share a lock so that we don't mix up packets...
        /// </summary>
        /// <param name="packetType"></param>
        internal static void SendMessage(byte[] packetType)
        {
            lock (MagicCookie)
            {
                scratch.Overwrite(0, Adapter.BroadcastMAC);          // Destination MAC Address
                scratch.Overwrite(6, Adapter.MacAddress);            // Source MAC Address
                scratch.Overwrite(30, Adapter.BroadcastIPAddress);   // Destiantion IP Address
                scratch.Overwrite(54, Adapter.BlankIPAddress);       // Source IP Address
                scratch.Overwrite(70, Adapter.MacAddress);           // Source MAC Address Again inside the DHCP section
                scratch.Overwrite(284, packetType);

                byte[] options = new byte[13 + (Adapter.Name == string.Empty ? 0 : Adapter.Name.Length + 2)];
                options.Overwrite(0, Adapter.MacAddress);

                transactionID = transactionID ?? Extensions.GetRandomBytes(4);  // Make up some transaction ID

                if (packetType == DHCP.Discover)
                {
                    // Debug.WriteLine("Composing Discover Message");

                    PendingIpAddress = null;
                    //scratch.Overwrite(306, suffix);  // write the Discover suffix
                    options.Overwrite(6, new byte[6] {
                        0x33, 0x04, 0x00, 0x76, 0xa7, 0x00
                    });                                                                        // Request an IP lease time of 90 days
                }
                else if (packetType == DHCP.Request && PendingIpAddress != null && Adapter.Gateway != null)
                {
                    //Debug.WriteLine("Composing Request Message");

                    options.Overwrite(6, new byte[2] {
                        0x32, 0x04
                    });                                                // Set the option prefix for IP Address
                    options.Overwrite(8, PendingIpAddress);            // Set the option Value
                    options.Overwrite(12, new byte[2] {
                        0x36, 0x04
                    });                                              // Set the option prefix for Gateway
                    options.Overwrite(14, Adapter.Gateway);          // Set the option value

                    if (Adapter.GatewayMac != null && Adapter.Gateway != null && Adapter.IPAddress != null)
                    {
                        // This is for the renewals
                        //TODO: Test to make sure this works!
                        //scratch.Overwrite(0, Adapter.GatewayMac);
                        //scratch.Overwrite(30, Adapter.Gateway);
                        scratch.Overwrite(54, Adapter.IPAddress);
                    }
                }
                else
                {
                    Debug.WriteLine("Odd DHCP situation... should we be concerned?");

                    return;
                }

                if (Adapter.Name != string.Empty)
                {
                    // Add Hostname option to Discover and Request messages
                    options.Overwrite(options.Length - (Adapter.Name.Length + 3), new byte[1] {
                        0x0c
                    });
                    options.Overwrite(options.Length - (Adapter.Name.Length + 2), DNS.EncodeDnsName(Adapter.Name));
                }

                options.Overwrite(options.Length - 1, new byte[1] {
                    0xFF
                });                                    // End of option section marker

                scratch.Overwrite(46, transactionID);  // Write the transaction ID

                var result = Utility.CombineArrays(scratch, options);

                result.Overwrite(16, ((ushort)(result.Length - 14)).ToBytes()); // Set IPv4 message size

                result.Overwrite(38, ((ushort)(result.Length - 34)).ToBytes()); // Set UDP message size

                result.Overwrite(24, new byte[] { 0x00, 0x00 });                // clear header checksum, so that calc excludes the checksum itself
                result.Overwrite(24, result.InternetChecksum(20, 14));          // header checksum

                result.Overwrite(40, new byte[] { 0x00, 0x00 });                // clear UDP Checksum

                Adapter.nic.SendFrame(result);                                  // Send the packet out into the ether....!
            }
        }