Example #1
0
        public static int socket(int family, int type, int protocol)
        {
            if (!_isInitialized)
            {
                Initialize();
            }

            switch (family)
            {
            case 2:     /* InterNetwork */
            {
                switch (type)
                {
                case 1:             /* Stream */
                {
                    if (protocol == 6 /* Tcp */)
                    {
                        return(_ipv4Layer.CreateSocket(IPv4Layer.ProtocolType.Tcp, Int64.MaxValue));
                    }
                }
                break;

                case 2:             /* Dgram */
                {
                    if (protocol == 17 /* Udp */)
                    {
                        return(_ipv4Layer.CreateSocket(IPv4Layer.ProtocolType.Udp, Int64.MaxValue));
                    }
                }
                break;
                }
            }
            break;
            }

            /* if we could not create a socket, return -1. */
            return(-1);
        }
        bool SendDnsQueryAndWaitForResponse(UInt32 dnsServerIPAddress, DnsRecordType recordType, string name, out DnsResponse dnsResponse, Int64 timeoutInMachineTicks)
        {
            // obtain an exclusive handle to the reserved socket
            int socketHandle = _ipv4Layer.CreateSocket(IPv4Layer.ProtocolType.Udp, timeoutInMachineTicks, true);
            // instantiate the reserved socket
            UdpSocket socket = (UdpSocket)_ipv4Layer.GetSocket(socketHandle);

            try
            {
                // create DNS request header
                byte[] dnsRequestBuffer = new byte[DNS_FRAME_BUFFER_LENGTH];
                int    bufferIndex      = 0;
                /* Transaction ID */
                UInt16 transactionID = _nextTransactionID++;
                dnsRequestBuffer[bufferIndex++] = (byte)((transactionID >> 8) & 0xFF);
                dnsRequestBuffer[bufferIndex++] = (byte)(transactionID & 0xFF);
                /* Flags (including OpCode and RCODE) */
                DnsMessageFlagsFlags flags = 0;

                /* QR = 0 (query)
                 * OpCode = 0 (standard query/response)
                 * RD = 1 (recursion desired) */
                flags |= DnsMessageFlagsFlags.RecursionDesired;
                dnsRequestBuffer[bufferIndex++] |= (byte)(((UInt16)flags >> 8) & 0xFF);
                dnsRequestBuffer[bufferIndex++] |= (byte)((UInt16)flags & 0xFF);
                /* Query Count */
                UInt16 queryCount = 1;
                dnsRequestBuffer[bufferIndex++] = (byte)((queryCount >> 8) & 0xFF);
                dnsRequestBuffer[bufferIndex++] = (byte)(queryCount & 0xFF);
                /* Answer Count */
                // skip bytes 6-7
                bufferIndex += 2;
                /* Authority Record Count */
                // skip bytes 8-9
                bufferIndex += 2;
                /* Additional Information Count */
                // skip bytes 10-11
                bufferIndex += 2;

                // create dns question (query)
                // Query Name
                Int32 namePosition = 0;
                while (true)
                {
                    Int32 labelLength = name.IndexOf('.', namePosition) - namePosition;
                    if (labelLength < 0)
                    {
                        bufferIndex++;
                        break;
                    }

                    dnsRequestBuffer[bufferIndex++] = (byte)labelLength;
                    Int32 labelLengthVerify = System.Text.Encoding.UTF8.GetBytes(name, namePosition, labelLength, dnsRequestBuffer, bufferIndex);
                    // if the label was not decoded as 8-bit characters, throw an exception; international punycode-encoded domains are not supported.
                    if (labelLengthVerify != labelLength)
                    {
                        throw new ArgumentException();
                    }

                    namePosition += labelLength + 1;
                    bufferIndex  += labelLength;
                }
                // Query Type
                dnsRequestBuffer[bufferIndex++] = (byte)((((UInt16)recordType) >> 8) & 0xFF);
                dnsRequestBuffer[bufferIndex++] = (byte)(((UInt16)recordType) & 0xFF);
                // Query Class
                UInt16 queryClass = DNS_RECORD_CLASS_INTERNET;
                dnsRequestBuffer[bufferIndex++] = (byte)((queryClass >> 8) & 0xFF);
                dnsRequestBuffer[bufferIndex++] = (byte)(queryClass & 0xFF);

                /* NOTE: this implementation queries the primary DNS address */
                // send DNS request
                socket.SendTo(dnsRequestBuffer, 0, bufferIndex, 0, timeoutInMachineTicks, dnsServerIPAddress, DNS_SERVER_PORT);

                // wait for DNS response
                bool success = RetrieveDnsResponse(socket, transactionID, out dnsResponse, timeoutInMachineTicks);

                if (success)
                {
                    return(true);
                }
            }
            finally
            {
                // close the reserved socket
                _ipv4Layer.CloseSocket(socketHandle);
            }

            return(false);  /* could not retrieve DNS response */
        }