Ejemplo n.º 1
0
 public void PutDhcpOption(DhcpOption dhcpOption)
 {
     if ((dhcpOption != null))
     {
         this.dhcpOptions[dhcpOption.GetCode()] = dhcpOption;
     }
 }
Ejemplo n.º 2
0
 /// <summary>
 /// Decode any options sent by the client inside this IA_NA.  Mostly, we are
 /// a hint to which address(es) it may want.RFC 3315 does not specify if
 /// a client can actually provide any options other than IA_ADDR options in
 /// inside the IA_NA, but it does not say that the client cannot do so, and
 /// the IA_NA option definition supports any type of sub-options.
 /// </summary>
 /// <param name="buf">buf ByteBuffer positioned at the start of the options in the packet</param>
 /// <param name="eof">eof the eof</param>
 protected void DecodeOptions(ByteBuffer buf, long eof)
 {
     while (buf.position() < eof)
     {
         int code = Util.GetUnsignedShort(buf);
         log.Debug("Option code=" + code);
         DhcpOption option = DhcpV6OptionFactory.GetDhcpOption(code);
         if (option != null)
         {
             option.Decode(buf);
             if (option is DhcpV6IaAddrOption)
             {
                 iaAddrOptions.Add((DhcpV6IaAddrOption)option);
             }
             else
             {
                 PutDhcpOption(option);
             }
         }
         else
         {
             break;  // no more options, or one is malformed, so we're done
         }
     }
 }
Ejemplo n.º 3
0
        private static byte[] buildDhcpPayload()
        {
            // Create optional payload bytes that can be added to the main payload.
            DhcpOption dhcpServerIdentifierOption = new DhcpOption()
            {
                optionId     = dhcpOptionIds.DhcpMessageType,
                optionLength = new byte[] { 0x01 },
                optionValue  = new byte[] { 0x03 },
            };

            DhcpOption dhcpRequestedIpAddressOption = new DhcpOption()
            {
                optionId     = dhcpOptionIds.RequestedIpAddress,
                optionLength = new byte[] { 0x04 },
                optionValue  = IPAddress.Parse("192.168.178.101").GetAddressBytes(),
            };

            // Create the main payload of the dhcp-packet and add the options to it.
            DhcpPacket dhcpDiscoveryPacket = new DhcpPacket()
            {
                transactionID = new byte[] { 0x00, 0x00, 0x00, 0x00 },
                dhcpOptions   = dhcpServerIdentifierOption.buildDhcpOption().Concat(dhcpRequestedIpAddressOption.buildDhcpOption()).ToArray(),
            };

            return(dhcpDiscoveryPacket.buildPacket());
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Returns option content
        /// </summary>
        /// <param name="option">Option to retrieve</param>
        /// <returns>Option content</returns>
        internal byte[] GetOptionData(DhcpOption option)
        {
            int  DHCPId = 0;
            byte DDataID, DataLength = 0;

            byte[] dumpData;

            DHCPId = (int)option;
            for (int i = 0; i < requestData.options.Length; i++)
            {
                DDataID = requestData.options[i];
                if (DDataID == (byte)DhcpOption.END_Option)
                {
                    break;
                }
                if (DDataID == DHCPId)
                {
                    DataLength = requestData.options[i + 1];
                    dumpData   = new byte[DataLength];
                    Array.Copy(requestData.options, i + 2, dumpData, 0, DataLength);
                    return(dumpData);
                }
                else if (DDataID == 0)
                {
                }
                else
                {
                    DataLength = requestData.options[i + 1];
                    i         += 1 + DataLength;
                }
            }

            return(null);
        }
Ejemplo n.º 5
0
 public void PutDhcpOption(DhcpOption dhcpOption)
 {
     if (dhcpOption != null)
     {
         _dhcpOptions[dhcpOption.GetCode()] = dhcpOption;
     }
 }
Ejemplo n.º 6
0
        public static DhcpPacket CreateFromRaw(byte[] rawPacket)
        {
            DhcpPacket packet = new DhcpPacket();

            using (var reader = new BinaryReader(new MemoryStream(rawPacket)))
            {
                packet.MessageType = (DhcpMessageType)reader.ReadByte();
                HardwareAddressType hardwareAddressType = (HardwareAddressType)reader.ReadByte();
                byte hardwareAddressLength = reader.ReadByte();
                packet.Hops              = reader.ReadByte();
                packet.TransactionId     = (uint)IPAddress.NetworkToHostOrder(reader.ReadInt32());
                packet.SecondsElapsed    = (ushort)IPAddress.NetworkToHostOrder(reader.ReadInt16());
                packet.Flags             = (ushort)IPAddress.NetworkToHostOrder(reader.ReadInt16());
                packet.ClientAddress     = new IPAddress(reader.ReadBytes(4));
                packet.YourClientAddress = new IPAddress(reader.ReadBytes(4));
                packet.NextServerAddress = new IPAddress(reader.ReadBytes(4));
                packet.RelayAgentAddress = new IPAddress(reader.ReadBytes(4));
                packet.HardwareAddress   = new HardwareAddress(hardwareAddressType,
                                                               reader.ReadBytes(hardwareAddressLength));
                reader.ReadBytes(16 - hardwareAddressLength); // padding
                packet.ServerName   = Encoding.ASCII.GetString(reader.ReadBytes(64));
                packet.BootFileName = Encoding.ASCII.GetString(reader.ReadBytes(128));

                int packetMagicCookie = IPAddress.NetworkToHostOrder(reader.ReadInt32());
                if (packetMagicCookie != MagicCookie)
                {
                    throw new InvalidDataException("Magic cookie not found!");
                }

                byte messageType = reader.ReadByte();
                if (messageType != 53)
                {
                    throw new InvalidDataException("Options should start with Message type!");
                }
                reader.ReadByte(); // length
                packet.MessageType = (DhcpMessageType)reader.ReadByte();

                var  optionFactory = new DhcpOptionFactory();
                byte optionType    = reader.ReadByte();
                while (optionType != 255)
                {
                    DhcpOptionType type       = (DhcpOptionType)optionType;
                    byte           length     = reader.ReadByte();
                    byte[]         optionData = reader.ReadBytes(length);

                    DhcpOption option = optionFactory.CreateFromRaw(type, optionData);
                    if (option != null)
                    {
                        packet.Options.Add(option);
                    }
                    else
                    {
                        Console.WriteLine($"WARN: Unsupported option type: {type}");
                    }
                    optionType = reader.ReadByte();
                }
            }
            return(packet);
        }
Ejemplo n.º 7
0
 public void AddSuboption(DhcpOption suboption)
 {
     if (suboptionList == null)
     {
         suboptionList = new List <DhcpOption>();
     }
     suboptionList.Add(suboption);
 }
Ejemplo n.º 8
0
 /**
  * Adds the ia addr dhcp option.
  *
  * @param iaDhcpOption the ia dhcp option
  */
 public void AddIaAddrDhcpOption(DhcpOption iaDhcpOption)
 {
     if (iaAddrDhcpOptions == null)
     {
         //TODO: consider a Set?
         iaAddrDhcpOptions = new List <DhcpOption>();
     }
     iaAddrDhcpOptions.Add(iaDhcpOption);
 }
Ejemplo n.º 9
0
        public Boolean RemoveOption(DhcpOption option)
        {
            if (this.m_Options.ContainsKey(option))
            {
                this.m_OptionDataSize -= this.m_Options[option].Length;
            }

            return(this.m_Options.Remove(option));
        }
Ejemplo n.º 10
0
 /// <summary>
 /// Remove custom option type.
 /// </summary>
 public Boolean RemoveOption(DhcpOption option)
 {
     if (this._options.Contains(option))
     {
         this._options.Remove(option);
         return(true);
     }
     return(false);
 }
Ejemplo n.º 11
0
        /// <summary>
        /// Add or define a new custom option type.
        /// </summary>
        public void AddOption(DhcpOption option, params Byte[] data)
        {
            if (option == DhcpOption.Pad || option == DhcpOption.End)
            {
                throw new ArgumentException("The Pad and End DhcpOptions cannot be added explicitly", "option");
            }

            this._options.Add(option, data);
            this._optionDataSize += data.Length;
        }
Ejemplo n.º 12
0
 public Byte[] GetOptionData(DhcpOption option)
 {
     if (this.m_Options.ContainsKey(option))
     {
         return(this.m_Options[option]);
     }
     else
     {
         return(null);
     }
 }
Ejemplo n.º 13
0
 /// <summary>
 /// Get option data.
 /// </summary>
 public byte[] GetOptionData(DhcpOption option)
 {
     if (this._options.Contains(option))
     {
         return((byte[])this._options[option]);
     }
     else
     {
         return(null);
     }
 }
Ejemplo n.º 14
0
 /// <summary>
 /// Remove a custom option type.
 /// </summary>
 public bool RemoveOption(DhcpOption option)
 {
     if (this._options.Contains(option))
     {
         byte[] optionValue = (byte[])this._options[option];
         this._optionDataSize -= optionValue.Length;
         this._options.Remove(option);
         return(true);
     }
     return(false);
 }
Ejemplo n.º 15
0
 /**
  * Instantiates a new dhcp vendor info option.
  *
  * @param vendorInfoOption the vendor info option
  */
 public DhcpV6VendorInfoOption(v6VendorInfoOption vendorInfoOption) : base()
 {
     if (vendorInfoOption != null)
     {
         enterpriseNumber = vendorInfoOption.enterpriseNumber;
         List <optionDefType> optdefs = vendorInfoOption.suboptionList;
         if (optdefs != null)
         {
             foreach (optionDefType optdef in optdefs)
             {
                 DhcpOption subopt = GenericOptionFactory.GetDhcpOption(optdef);
                 AddSuboption(subopt);
             }
         }
     }
     SetCode(DhcpConstants.V6OPTION_VENDOR_OPTS);
 }
Ejemplo n.º 16
0
        static private void CreateOptionElement(ref byte[] options, DhcpOption option, byte[] data)
        {
            byte[] optionData;

            optionData    = new byte[data.Length + 2];
            optionData[0] = (byte)option;
            optionData[1] = (byte)data.Length;
            Array.Copy(data, 0, optionData, 2, data.Length);
            if (options == null)
            {
                Array.Resize(ref options, (int)optionData.Length);
            }
            else
            {
                Array.Resize(ref options, options.Length + optionData.Length);
            }
            Array.Copy(optionData, 0, options, options.Length - optionData.Length, optionData.Length);
        }
 protected void DecodeOptions(ByteBuffer buf)
 {
     while (buf.hasRemaining())
     {
         int code = Util.GetUnsignedShort(buf);
         log.Debug("Option code=" + code);
         DhcpOption option = DhcpV6OptionFactory.GetDhcpOption(code);
         if (option != null)
         {
             option.Decode(buf);
             dhcpOptions[option.GetCode()] = option;
         }
         else
         {
             break;  // no more options, or one is malformed, so we're done
         }
     }
 }
Ejemplo n.º 18
0
        public void SetDhcpOption(DhcpOption newOption)
        {
            if ((this.dhcpOptions == null))
            {
                this.dhcpOptions = new List <DhcpOption>();
            }

            //  first remove the option, if it exists
            foreach (DhcpOption dhcpOption in this.dhcpOptions)
            {
                if ((dhcpOption.GetCode() == newOption.GetCode()))
                {
                    this.dhcpOptions.Remove(dhcpOption);
                    break;
                }
            }

            this.dhcpOptions.Add(newOption);
        }
Ejemplo n.º 19
0
 /// <summary>
 /// Decode the options.
 /// </summary>
 /// <param name="buf">ByteBuffer positioned at the start of the options in the packet</param>
 /// <returns>a Map of DhcpOptions keyed by the option code</returns>
 protected Dictionary <int, DhcpOption> DecodeOptions(ByteBuffer buf)
 {
     while (buf.hasRemaining())
     {
         int code = Util.GetUnsignedShort(buf);
         if (log.IsDebugEnabled)
         {
             log.Debug("Option code=" + code);
         }
         DhcpOption option = DhcpV6OptionFactory.GetDhcpOption(code);
         if (option != null)
         {
             if ((option is DhcpV6RelayOption) &&
                 (this is DhcpV6RelayMessage))
             {
                 DhcpV6RelayOption relayOption = (DhcpV6RelayOption)option;
                 relayOption.SetRelayMessage((DhcpV6RelayMessage)this);
             }
             option.Decode(buf);
             if (option is DhcpV6IaNaOption)
             {
                 iaNaOptions.Add((DhcpV6IaNaOption)option);
             }
             else if (option is DhcpV6IaTaOption)
             {
                 iaTaOptions.Add((DhcpV6IaTaOption)option);
             }
             else if (option is DhcpV6IaPdOption)
             {
                 iaPdOptions.Add((DhcpV6IaPdOption)option);
             }
             else
             {
                 dhcpOptions[option.GetCode()] = option;
             }
         }
         else
         {
             break;  // no more options, or one is malformed, so we're done
         }
     }
     return(dhcpOptions);
 }
Ejemplo n.º 20
0
        private static byte[] buildDhcpPayload()
        {
            // Create optional payload bytes that can be added to the main payload.
            DhcpOption dhcpMessageTypeOption = new DhcpOption()
            {
                optionId     = dhcpOptionIds.DhcpMessageType,
                optionLength = new byte[] { 0x01 },
                optionValue  = new byte[] { 0x01 },
            };

            // Create the main payload of the dhcp-packet and add the options to it.
            DhcpPacket dhcpDiscoveryPacket = new DhcpPacket()
            {
                transactionID = new byte[] { 0x00, 0x00, 0x00, 0x00 },
                dhcpOptions   = dhcpServerIdentifierOption.buildDhcpOption().ToArray(),
            };

            return(dhcpDiscoveryPacket.buildPacket());
        }
Ejemplo n.º 21
0
        private static byte[] buildDhcpReleasePacket(IPAddress pClientIpAddress, PhysicalAddress pClientHwAddress, IPAddress pDestinationIpAddress)
        {
            Random rand = new Random();

            byte[] _transactionID = new byte[4];
            rand.NextBytes(_transactionID);

            DhcpOption dhcpMessageTypeOption = new DhcpOption()
            {
                optionId     = dhcpOptionIds.DhcpMessageType,
                optionLength = new byte[] { 0x01 },
                optionValue  = new byte[] { 0x07 },
            };

            DhcpOption dhcpServerIdOption = new DhcpOption()
            {
                optionId     = dhcpOptionIds.ServerIdentifier,
                optionLength = new byte[] { 0x04 },
                optionValue  = pDestinationIpAddress.GetAddressBytes(),
            };

            DhcpOption clientIdOption = new DhcpOption()
            {
                optionId     = dhcpOptionIds.ClientIdentifier,
                optionLength = new byte[] { 0x04 },
                optionValue  = pClientIpAddress.GetAddressBytes(),
            };

            byte[] options = dhcpMessageTypeOption.buildDhcpOption().Concat(dhcpServerIdOption.buildDhcpOption()).Concat(clientIdOption.buildDhcpOption()).ToArray();

            DhcpPacket dhcpReleasePacket = new DhcpPacket()
            {
                transactionID = _transactionID,
                clientIP      = pClientIpAddress.GetAddressBytes(),
                clientMac     = pClientHwAddress.GetAddressBytes(),

                dhcpOptions = options,
            };

            return(dhcpReleasePacket.buildPacket());
        }
Ejemplo n.º 22
0
 /**
  * Decode the options.
  * @param buf	ByteBuffer positioned at the start of the options in the packet
  * @return	a Map of DhcpOptions keyed by the option code
  * @throws IOException
  */
 protected Dictionary <int, DhcpOption> DecodeOptions(ByteBuffer buf)
 {
     while (buf.hasRemaining())
     {
         short code = Util.GetUnsignedByte(buf);
         if (log.IsDebugEnabled)
         {
             log.Debug("Option code=" + code);
         }
         DhcpOption option = DhcpV4OptionFactory.GetDhcpOption(code);
         if (option != null)
         {
             option.Decode(buf);
             _dhcpOptions[option.GetCode()] = option;
         }
         else
         {
             break;  // no more options, or one is malformed, so we're done
         }
     }
     return(_dhcpOptions);
 }
Ejemplo n.º 23
0
        protected DhcpOption FindIaAddressOption(IaAddress iaAddr, BaseDhcpOption baseOption)
        {
            DhcpOption dbOption = null;
            DhcpLease  lease    = FindDhcpLeaseForInetAddr(iaAddr.GetIpAddress());

            if (lease != null)
            {
                List <DhcpOption> iaAddrOptions = lease.GetIaAddrDhcpOptions();
                if (iaAddrOptions != null)
                {
                    foreach (DhcpOption iaAddrOption in iaAddrOptions)
                    {
                        if (iaAddrOption.GetCode() == baseOption.GetCode())
                        {
                            dbOption = iaAddrOption;
                            break;
                        }
                    }
                }
            }
            return(dbOption);
        }
Ejemplo n.º 24
0
        /// <summary>
        /// Add or define a new custom option type.
        /// </summary>   
        public void AddOption(DhcpOption option, params Byte[] data)
        {
            if (option == DhcpOption.Pad || option == DhcpOption.End)
            {
                throw new ArgumentException("The Pad and End DhcpOptions cannot be added explicitly", "option");
            }

            this._options.Add(option, data);
            this._optionDataSize += data.Length;
        }
Ejemplo n.º 25
0
 public Byte[] GetOptionData(DhcpOption option)
 {
     if (this.m_Options.ContainsKey(option))
     {
         return this.m_Options[option];
     }
     else
     {
         return null;
     }
 }
Ejemplo n.º 26
0
        /// <summary>
        /// Gets the DHCP request list string.
        /// </summary>
        /// <param name="dhcpOptionValue">The DHCP option value.</param>
        /// <param name="dhcpRequestListFormat">The DHCP request list format.</param>
        /// <param name="logger">The logger.</param>
        /// <returns>System.String.</returns>
        /// <autogeneratedoc />
        public static string GetDhcpRequestListString(byte[] dhcpOptionValue,
                                                      DhcpRequestListFormat dhcpRequestListFormat, IPureLogger logger = null)
        {
            StringBuilder sb = new StringBuilder();

            foreach (var requestOption in dhcpOptionValue)
            {
                DhcpOption dhcpRequestOption = (DhcpOption)requestOption;

                switch (dhcpRequestListFormat)
                {
                case DhcpRequestListFormat.StringCommaSeparated:
                    sb.Append($"{dhcpRequestOption.ToString()}, ");
                    break;

                case DhcpRequestListFormat.StringNewlineSeparated:
                    sb.Append($"{Environment.NewLine}{dhcpRequestOption.ToString()}");
                    break;

                case DhcpRequestListFormat.StringNewlineIndentedSeparated:
                    sb.Append($"{Environment.NewLine}    {dhcpRequestOption.ToString()}");
                    break;

                case DhcpRequestListFormat.HexValueCommaSeparated:
                    sb.Append($"{ByteUtility.ByteToHex((byte) dhcpRequestOption)}, ");
                    break;

                case DhcpRequestListFormat.HexValueSpaceSeparated:
                    sb.Append($"{ByteUtility.ByteToHex((byte) dhcpRequestOption)} ");
                    break;

                case DhcpRequestListFormat.HexValueDashSeparated:
                    sb.Append($"{ByteUtility.ByteToHex((byte) dhcpRequestOption)}-");
                    break;

                case DhcpRequestListFormat.DecimalValueCommaSeparated:
                    sb.Append($"{(byte) dhcpRequestOption}, ");
                    break;

                case DhcpRequestListFormat.DecimalValueSpaceSeparated:
                    sb.Append($"{(byte) dhcpRequestOption} ");
                    break;
                }
            }

            // Remove trailing space
            if (sb.Length > 1)
            {
                if (sb[sb.Length - 1] == ' ' || sb[sb.Length - 1] == '-')
                {
                    sb.Length--;
                }
            }

            // Remove trailing comma
            if (sb.Length > 1)
            {
                if (sb[sb.Length - 1] == ',')
                {
                    sb.Length--;
                }
            }

            return(sb.ToString());
        }
Ejemplo n.º 27
0
        //void SendDhcpDecline(UInt32 ipAddress, Int64 timeoutInMachineTicks)
        //{
        //    if (_isDisposed)
        //        return;

        //    // 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
        //    {
        //        // bind the reserved socket to the DHCPv4 client port
        //        socket.Bind(0 /* IP_ADDRESS_ANY */, DHCP_CLIENT_PORT);

        //        // generate unique transaction ID
        //        UInt32 transactionID = GenerateRandomTransactionID();

        //        // set our clientIdentifier
        //        byte[] clientIdentifier = new byte[1 + HARDWARE_ADDRESS_SIZE];
        //        clientIdentifier[0] = HARDWARE_TYPE_ETHERNET;
        //        clientIdentifier[1] = (byte)((_physicalAddress >> 40) & 0xFF);
        //        clientIdentifier[2] = (byte)((_physicalAddress >> 32) & 0xFF);
        //        clientIdentifier[3] = (byte)((_physicalAddress >> 24) & 0xFF);
        //        clientIdentifier[4] = (byte)((_physicalAddress >> 16) & 0xFF);
        //        clientIdentifier[5] = (byte)((_physicalAddress >> 8) & 0xFF);
        //        clientIdentifier[6] = (byte)(_physicalAddress & 0xFF);

        //        byte[] requestedIPAddress = new byte[4];
        //        requestedIPAddress[0] = (byte)((ipAddress >> 24) & 0xFF);
        //        requestedIPAddress[1] = (byte)((ipAddress >> 16) & 0xFF);
        //        requestedIPAddress[2] = (byte)((ipAddress >> 8) & 0xFF);
        //        requestedIPAddress[3] = (byte)(ipAddress & 0xFF);

        //        byte[] serverIdentifier = new byte[4];
        //        serverIdentifier[0] = (byte)((_dhcpServerAddress >> 24) & 0xFF);
        //        serverIdentifier[1] = (byte)((_dhcpServerAddress >> 16) & 0xFF);
        //        serverIdentifier[2] = (byte)((_dhcpServerAddress >> 8) & 0xFF);
        //        serverIdentifier[3] = (byte)(_dhcpServerAddress & 0xFF);

        //        DhcpOption[] options = new DhcpOption[3];
        //        options[0] = new DhcpOption(DhcpOptionCode.ClientIdentifier, clientIdentifier);
        //        options[1] = new DhcpOption(DhcpOptionCode.ServerIdentifier, serverIdentifier);
        //        options[2] = new DhcpOption(DhcpOptionCode.RequestedIPAddress, requestedIPAddress);

        //        // send DHCP message
        //        SendDhcpMessage(socket, DhcpMessageType.DHCPDECLINE, 0xFFFFFFFF, transactionID, 0, 0, _physicalAddress, options, timeoutInMachineTicks);
        //    }
        //    finally
        //    {
        //        // close the reserved socket
        //        _ipv4Layer.CloseSocket(socketHandle);
        //    }
        //}

        //void SendDhcpRelease(Int64 timeoutInMachineTicks)
        //{
        //    if (_isDisposed)
        //        return;

        //    if (_ipConfigIPAddress == 0 || _dhcpServerAddress == 0)
        //        return;

        //    // 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
        //    {
        //        // bind the reserved socket to the DHCPv4 client port
        //        socket.Bind(0 /* IP_ADDRESS_ANY */, DHCP_CLIENT_PORT);

        //        // generate unique transaction ID
        //        UInt32 transactionID = GenerateRandomTransactionID();

        //        // set our clientIdentifier
        //        byte[] clientIdentifier = new byte[1 + HARDWARE_ADDRESS_SIZE];
        //        clientIdentifier[0] = HARDWARE_TYPE_ETHERNET;
        //        clientIdentifier[1] = (byte)((_physicalAddress >> 40) & 0xFF);
        //        clientIdentifier[2] = (byte)((_physicalAddress >> 32) & 0xFF);
        //        clientIdentifier[3] = (byte)((_physicalAddress >> 24) & 0xFF);
        //        clientIdentifier[4] = (byte)((_physicalAddress >> 16) & 0xFF);
        //        clientIdentifier[5] = (byte)((_physicalAddress >> 8) & 0xFF);
        //        clientIdentifier[6] = (byte)(_physicalAddress & 0xFF);

        //        byte[] serverIdentifier = new byte[4];
        //        serverIdentifier[0] = (byte)((_dhcpServerAddress >> 24) & 0xFF);
        //        serverIdentifier[1] = (byte)((_dhcpServerAddress >> 16) & 0xFF);
        //        serverIdentifier[2] = (byte)((_dhcpServerAddress >> 8) & 0xFF);
        //        serverIdentifier[3] = (byte)(_dhcpServerAddress & 0xFF);

        //        DhcpOption[] options = new DhcpOption[2];
        //        options[0] = new DhcpOption(DhcpOptionCode.ClientIdentifier, clientIdentifier);
        //        options[1] = new DhcpOption(DhcpOptionCode.ServerIdentifier, serverIdentifier);

        //        // send DHCP message
        //        SendDhcpMessage(socket, DhcpMessageType.DHCPRELEASE, _dhcpServerAddress, transactionID, 0, _ipConfigIPAddress, _physicalAddress, options, timeoutInMachineTicks);
        //    }
        //    finally
        //    {
        //        // close the reserved socket
        //        _ipv4Layer.CloseSocket(socketHandle);
        //    }

        //    // clear our DHCP settings and move to init state
        //    _ipConfigIPAddress = 0;
        //    _ipConfigSubnetMask = 0;
        //    _ipConfigGatewayAddress = 0;
        //    _dhcpServerAddress = 0;
        //    _dhcpStateMachineState = DhcpStateMachineState.InitReboot;

        //    /* NOTE: uncomment the following line if you want to automatically retrieve a new address after DHCPRELEASE */
        //    //_dhcpStateMachineEvent.Set();
        //}

        /* this function returns true if an offer has been received */
        DhcpOffer[] SendDhcpDiscoverAndCollectOffers(out UInt16 secondsElapsed, 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);

            System.Collections.ArrayList dhcpOffers;
            try
            {
                // bind the reserved socket to the DHCPv4 client port
                socket.Bind(0 /* IP_ADDRESS_ANY */, DHCP_CLIENT_PORT);

                // generate unique transaction ID
                UInt32 transactionID = GenerateRandomTransactionID();

                // we will retry the DHCP request up to four times.  first delay will be 4 +/-1 seconds; second delay will be 8 +/-1 seconds; third delay will be 16 +/-1 seconds; fourth delay will be 32 +/-1 seconds.
                // if our current timeoutInMachineTicks is longer than 64 seconds (the maximum wait for DHCP transmission) then reduce it to the maximum
                timeoutInMachineTicks = (Int64)System.Math.Max(timeoutInMachineTicks, Microsoft.SPOT.Hardware.Utility.GetMachineTime().Ticks + (TimeSpan.TicksPerSecond * 64));
                Int64 startTicks = Microsoft.SPOT.Hardware.Utility.GetMachineTime().Ticks;
                secondsElapsed = 0;
                byte nextRetrySeconds = 4;
                Int64 nextRetryInMachineTicks = (Int64)(Microsoft.SPOT.Hardware.Utility.GetMachineTime().Ticks + (((double)nextRetrySeconds + GenerateRandomPlusMinusOne()) * TimeSpan.TicksPerSecond));

                // set our clientIdentifier
                byte[] clientIdentifier = new byte[1 + HARDWARE_ADDRESS_SIZE];
                clientIdentifier[0] = HARDWARE_TYPE_ETHERNET;
                clientIdentifier[1] = (byte)((_physicalAddress >> 40) & 0xFF);
                clientIdentifier[2] = (byte)((_physicalAddress >> 32) & 0xFF);
                clientIdentifier[3] = (byte)((_physicalAddress >> 24) & 0xFF);
                clientIdentifier[4] = (byte)((_physicalAddress >> 16) & 0xFF);
                clientIdentifier[5] = (byte)((_physicalAddress >> 8) & 0xFF);
                clientIdentifier[6] = (byte)(_physicalAddress & 0xFF);

                byte[] parameterRequestList;
                if (_isDhcpDnsConfigEnabled)
                {
                    parameterRequestList = new byte[] { (byte)DhcpOptionCode.SubnetMask, (byte)DhcpOptionCode.Router, (byte)DhcpOptionCode.DomainNameServer };
                }
                else
                {
                    parameterRequestList = new byte[] { (byte)DhcpOptionCode.SubnetMask, (byte)DhcpOptionCode.Router };
                }

                byte[] maximumDhcpMessageSize = new byte[2];
                maximumDhcpMessageSize[0] = (byte)((DHCP_FRAME_BUFFER_LENGTH >> 8) & 0xFF);
                maximumDhcpMessageSize[1] = (byte)(DHCP_FRAME_BUFFER_LENGTH & 0xFF);

                dhcpOffers = new System.Collections.ArrayList();
                while (timeoutInMachineTicks > Microsoft.SPOT.Hardware.Utility.GetMachineTime().Ticks)
                {
                    // assemble options
                    DhcpOption[] options = new DhcpOption[3];
                    options[0] = new DhcpOption(DhcpOptionCode.ClientIdentifier, clientIdentifier);
                    options[1] = new DhcpOption(DhcpOptionCode.ParameterRequestList, parameterRequestList);
                    options[2] = new DhcpOption(DhcpOptionCode.MaximumDhcpMessageSize, maximumDhcpMessageSize);

                    // send DHCP message
                    SendDhcpMessage(socket, DhcpMessageType.DHCPDISCOVER, 0xFFFFFFFF, transactionID, secondsElapsed, 0, _physicalAddress, options, timeoutInMachineTicks);

                    // collect offers
                    DhcpOffer dhcpOffer;
                    bool success = RetrieveDhcpOffer(socket, transactionID, _physicalAddress, out dhcpOffer, nextRetryInMachineTicks);

                    if (success)
                    {
                        dhcpOffers.Add(dhcpOffer);
                        break;
                    }

                    secondsElapsed = (UInt16)((Microsoft.SPOT.Hardware.Utility.GetMachineTime().Ticks - startTicks) / TimeSpan.TicksPerSecond);
                    nextRetrySeconds *= 2;
                    nextRetryInMachineTicks = (Int64)(Microsoft.SPOT.Hardware.Utility.GetMachineTime().Ticks + (((double)nextRetrySeconds + GenerateRandomPlusMinusOne()) * TimeSpan.TicksPerSecond));
                }
            }
            finally
            {
                // close the reserved socket
                _ipv4Layer.CloseSocket(socketHandle);
            }

            return (DhcpOffer[])dhcpOffers.ToArray(typeof(DhcpOffer));
        }
Ejemplo n.º 28
0
        bool RetrieveDhcpMessage(UdpSocket socket, DhcpMessageType[] messageTypes, UInt32 transactionID, UInt64 clientHardwareAddress, out UInt32 assignedIPAddress, out DhcpOption[] options, Int64 timeoutInMachineTicks)
        {
            byte[] dhcpFrameBuffer = new byte[DHCP_FRAME_BUFFER_LENGTH];
            while (timeoutInMachineTicks > Microsoft.SPOT.Hardware.Utility.GetMachineTime().Ticks)
            {
                Int32 bytesReceived = socket.Receive(dhcpFrameBuffer, 0, dhcpFrameBuffer.Length, 0, timeoutInMachineTicks);

                if (bytesReceived == 0) // timeout
                    break;

                /* parse our DHCP frame */
                // validate the operation
                if ((BootpOperation)dhcpFrameBuffer[0] != BootpOperation.BOOTREPLY)
                    continue; /* filter out this BOOTP/DHCP frame */
                /* verify magic cookie {99, 130, 83, 99} is the first 4-byte entry, as per RFC 1497 */
                if ((dhcpFrameBuffer[236] != 99) ||
                    (dhcpFrameBuffer[237] != 130) ||
                    (dhcpFrameBuffer[238] != 83) ||
                    (dhcpFrameBuffer[239] != 99))
                    continue; /* filter out this BOOTP non-DHCP frame */
                // verify that the transaction ID matches
                UInt32 verifyTransactionID = (
                    (UInt32)(dhcpFrameBuffer[4] << 24) +
                    (UInt32)(dhcpFrameBuffer[5] << 16) +
                    (UInt32)(dhcpFrameBuffer[6] << 8) +
                    (UInt32)(dhcpFrameBuffer[7])
                    );
                if (transactionID != verifyTransactionID)
                    continue; /* filter out this DHCP frame */
                // verify the the physical hardware type matches
                if (dhcpFrameBuffer[1] != (byte)HARDWARE_TYPE_ETHERNET)
                    continue; /* filter out this DHCP frame */
                if (dhcpFrameBuffer[2] != (byte)HARDWARE_ADDRESS_SIZE)
                    continue; /* filter out this DHCP frame */
                // verify that the physical address matches
                UInt64 verifyClientHardwareAddress = (
                    ((UInt64)(dhcpFrameBuffer[28]) << 40) +
                    ((UInt64)(dhcpFrameBuffer[29]) << 32) +
                    ((UInt64)(dhcpFrameBuffer[30]) << 24) +
                    ((UInt64)(dhcpFrameBuffer[31]) << 16) +
                    ((UInt64)(dhcpFrameBuffer[32]) << 8) +
                    (UInt64)(dhcpFrameBuffer[33])
                    );
                if (clientHardwareAddress != verifyClientHardwareAddress)
                    continue; /* filter out this DHCP frame */

                // retrieve allocated ip address
                /* yiaddr (ip address, populated by server */
                assignedIPAddress = (
                    (UInt32)(dhcpFrameBuffer[16] << 24) +
                    (UInt32)(dhcpFrameBuffer[17] << 16) +
                    (UInt32)(dhcpFrameBuffer[18] << 8) +
                    (UInt32)(dhcpFrameBuffer[19])
                    );
                // retrieve options
                System.Collections.ArrayList optionsArrayList = new System.Collections.ArrayList();
                bool optionOverloadReceived = false;
                DhcpOptionsBlockRange[] optionsBlocks = new DhcpOptionsBlockRange[]
                {
                    new DhcpOptionsBlockRange(240, DHCP_FRAME_BUFFER_LENGTH - 240 - 1),
                };
                int optionsBlocksIndex = 0;

                DhcpMessageType verifyMessageType = 0;
                while (optionsBlocksIndex < optionsBlocks.Length)
                {
                    Int32 index = optionsBlocks[optionsBlocksIndex].BeginOffset;
                    bool endOpcodeReceived = false;
                    while (!endOpcodeReceived && index <= optionsBlocks[optionsBlocksIndex].EndOffset)
                    {
                        DhcpOptionCode optionCode = (DhcpOptionCode)dhcpFrameBuffer[index];
                        switch ((DhcpOptionCode)optionCode)
                        {
                            case DhcpOptionCode.Pad:
                                {
                                    index++;
                                }
                                break;
                            case DhcpOptionCode.End:
                                {
                                    index++;
                                    endOpcodeReceived = true;
                                }
                                break;
                            case DhcpOptionCode.OptionOverload:
                                {
                                    if (optionsBlocksIndex == 0)
                                    {
                                        index++;
                                        if (dhcpFrameBuffer[index] != 1)
                                            break;
                                        index++;
                                        byte value = dhcpFrameBuffer[index];
                                        index++;
                                        int numBlocks = 1 + (((value & 0x01) == 0x01) ? 1 : 0) + (((value & 0x02) == 0x02) ? 1 : 0);
                                        optionsBlocks = new DhcpOptionsBlockRange[numBlocks];
                                        int iOptionBlock = 0;
                                        optionsBlocks[iOptionBlock++] = new DhcpOptionsBlockRange(240, DHCP_FRAME_BUFFER_LENGTH - 240 - 1);
                                        if ((value & 0x01) == 0x01)
                                        {
                                            /* use file field for extended options */
                                            optionsBlocks[iOptionBlock++] = new DhcpOptionsBlockRange(108, 235);
                                        }
                                        if ((value & 0x02) == 0x02)
                                        {
                                            /* use sname field for extended options */
                                            optionsBlocks[iOptionBlock++] = new DhcpOptionsBlockRange(44, 107);
                                        }
                                    }
                                }
                                break;
                            default:
                                {
                                    index++;
                                    byte[] value = new byte[Math.Min(dhcpFrameBuffer[index], DHCP_FRAME_BUFFER_LENGTH - index)];
                                    index++;
                                    Array.Copy(dhcpFrameBuffer, index, value, 0, value.Length);
                                    index += value.Length;

                                    // if the option already exists, append to it
                                    bool foundOption = false;
                                    for (int iExistingOption = 0; iExistingOption < optionsArrayList.Count; iExistingOption++)
                                    {
                                        if (((DhcpOption)optionsArrayList[iExistingOption]).Code == optionCode)
                                        {
                                            byte[] newValue = new byte[((DhcpOption)optionsArrayList[iExistingOption]).Value.Length + value.Length];
                                            Array.Copy(((DhcpOption)optionsArrayList[iExistingOption]).Value, 0, newValue, 0, ((DhcpOption)optionsArrayList[iExistingOption]).Value.Length);
                                            Array.Copy(value, 0, newValue, ((DhcpOption)optionsArrayList[iExistingOption]).Value.Length, value.Length);
                                            optionsArrayList.RemoveAt(iExistingOption);
                                            optionsArrayList.Add(new DhcpOption(optionCode, newValue));

                                            foundOption = true;
                                            break;
                                        }
                                    }
                                    if (!foundOption)
                                    {
                                        optionsArrayList.Add(new DhcpOption(optionCode, value));
                                    }

                                    if (optionCode == DhcpOptionCode.DhcpMessageType)
                                    {
                                        verifyMessageType = (DhcpMessageType)value[0];
                                    }
                                }
                                break;
                        }
                    }

                    optionsBlocksIndex++;
                }
                options = (DhcpOption[])optionsArrayList.ToArray(typeof(DhcpOption));

                // verify that the DHCP message type matches
                bool messageTypeMatches = false;
                for (int iMessageType = 0; iMessageType < messageTypes.Length; iMessageType++)
                {
                    if (messageTypes[iMessageType] == verifyMessageType)
                    {
                        messageTypeMatches = true;
                        break;
                    }
                }

                if (messageTypeMatches)
                    return true; /* message matches the messageTypes filter, with a valid frame; return all data to the caller  */
            }

            // if we did not receive a message before timeout, return false.
            // set default return values
            assignedIPAddress = 0;
            options = null;
            return false;
        }
Ejemplo n.º 29
0
 /// <summary>
 /// Add or define a new custom option type.
 /// </summary>   
 public void AddOption(DhcpOption option, byte[] data)
 {
     _options.Add(option, data);
 }
Ejemplo n.º 30
0
 /// <summary>
 /// Remove custom option type.
 /// </summary>   
 public Boolean RemoveOption(DhcpOption option)
 {
     if (this._options.Contains(option))
     {
         this._options.Remove(option);
         return true;
     }
     return false;
 }
Ejemplo n.º 31
0
        /// <summary>
        /// Initializes a new instance of the <see cref="DhcpMessage"/> class.
        /// <param name="data">Array containing the data to decode.</param>
        /// </summary>
        public DhcpMessage(byte[] data)
        {
            ByteReader byteReader = new ByteReader(data, ByteOrder.Network);

            _timestamp = DateTime.Now;

            _op     = byteReader.ReadByte();
            _htype  = byteReader.ReadByte();
            _hlen   = byteReader.ReadByte();
            _hops   = byteReader.ReadByte();
            _xid    = byteReader.ReadUInt32();
            _secs   = byteReader.ReadUInt16();
            _flags  = byteReader.ReadBytes(2);
            _ciaddr = byteReader.ReadBytes(4);
            _yiaddr = byteReader.ReadBytes(4);
            _siaddr = byteReader.ReadBytes(4);
            _giaddr = byteReader.ReadBytes(4);
            _chaddr = byteReader.ReadBytes(16);
            _sname  = byteReader.ReadBytes(64);
            _file   = byteReader.ReadBytes(128);

            byte[] rawOptions = byteReader.ReadBytes(byteReader.AvailableBytes);
            int    offset     = 0;

            // if magic number is valid then process options
            if (offset + 4 < rawOptions.Length &&
                (BitConverter.ToUInt32(rawOptions, offset) == Constants.DHCP_OPTIONS_MAGIC_NUMBER ||
                 BitConverter.ToUInt32(rawOptions, offset) == Constants.DHCP_WIN_OPTIONS_MAGIC_NUMBER))
            {
                offset += 4;
                Boolean end = false;

                while (!end && offset < rawOptions.Length)
                {
                    DhcpOption option = (DhcpOption)rawOptions[offset];
                    offset++;

                    int optionLen;

                    switch (option)
                    {
                    case DhcpOption.Pad:
                        continue;

                    case DhcpOption.End:
                        end = true;
                        continue;

                    default:
                        optionLen = (int)rawOptions[offset];
                        offset++;
                        break;
                    }

                    byte[] optionData = new byte[optionLen];

                    Array.Copy(rawOptions, offset, optionData, 0, optionLen);
                    offset += optionLen;

                    this._options.Add(option, optionData);
                    this._optionDataSize += optionLen;
                }
            }
        }
Ejemplo n.º 32
0
 protected void SetDhcpOption(IaAddress iaAddr, DhcpOption option)
 {
     iaAddr.SetDhcpOption(option);
     UpdateIpAddrOptions(iaAddr.GetIpAddress(), iaAddr.GetDhcpOptions());
 }
Ejemplo n.º 33
0
        /// <summary>
        /// Initializes a new instance of the <see cref="DhcpMessage" /> class.
        /// </summary>
        /// <param name="data">Array containing the data to decode.</param>
        /// <param name="loggerFactory">The logger factory.</param>
        /// <param name="logger">The logger.</param>
        public DhcpMessage(byte[] data, IPureLoggerFactory loggerFactory, IPureLogger logger = null)
            : base(loggerFactory, logger)
        {
            ByteReader byteReader = new ByteReader(data, ByteOrder.Network);

            CreatedTimestamp = DateTimeOffset.Now;

            _op     = byteReader.ReadByte();
            _htype  = byteReader.ReadByte();
            _hlen   = byteReader.ReadByte();
            _hops   = byteReader.ReadByte();
            _xid    = byteReader.ReadUInt32();
            _secs   = byteReader.ReadUInt16();
            _flags  = byteReader.ReadBytes(2);
            _ciaddr = byteReader.ReadBytes(4);
            _yiaddr = byteReader.ReadBytes(4);
            _siaddr = byteReader.ReadBytes(4);
            _giaddr = byteReader.ReadBytes(4);
            _chaddr = byteReader.ReadBytes(16);
            _sname  = byteReader.ReadBytes(64);
            _file   = byteReader.ReadBytes(128);

            byte[] rawOptions = byteReader.ReadBytes(byteReader.AvailableBytes);
            int    offset     = 0;

            // if magic number is valid then process options
            if (offset + 4 < rawOptions.Length &&
                (BitConverter.ToUInt32(rawOptions, offset) == DhcpConstants.DhcpOptionsMagicNumber ||
                 BitConverter.ToUInt32(rawOptions, offset) == DhcpConstants.DhcpWinOptionsMagicNumber))
            {
                offset += 4;
                bool end = false;

                while (!end && offset < rawOptions.Length)
                {
                    DhcpOption option = (DhcpOption)rawOptions[offset];
                    offset++;

                    int optionLen;

                    switch (option)
                    {
                    case DhcpOption.Pad:
                        continue;

                    case DhcpOption.End:
                        end = true;
                        continue;

                    default:
                        optionLen = rawOptions[offset];
                        offset++;
                        break;
                    }

                    byte[] optionData = new byte[optionLen];

                    Array.Copy(rawOptions, offset, optionData, 0, optionLen);
                    offset += optionLen;

                    _options.Add(option, optionData);
                    _optionDataSize += optionLen;
                }
            }
        }
Ejemplo n.º 34
0
        /// <summary>
        /// Get option data.
        /// </summary> 
        public byte[] GetOptionData(DhcpOption option)
        {
            if (this._options.Contains(option))
            {

                return (byte[])this._options[option];
            }
            else
            {
                return null;
            }
        }
Ejemplo n.º 35
0
 /// <summary>
 /// Remove a custom option type.
 /// </summary>  
 public bool RemoveOption(DhcpOption option)
 {
     if (this._options.Contains(option))
     {
         byte[] optionValue = (byte[])this._options[option];
         this._optionDataSize -= optionValue.Length;
         this._options.Remove(option);
         return true;
     }
     return false;
 }
Ejemplo n.º 36
0
        /// <summary>
        /// Converts dhcp message into a byte array.
        /// </summary>
        public byte[] ToArray()
        {
            ByteWriter byteWriter = new ByteWriter(Constants.DHCP_MIN_MESSAGE_SIZE, ByteOrder.Network);

            byteWriter.Write(_op);
            byteWriter.Write(_htype);
            byteWriter.Write(_hlen);
            byteWriter.Write(_hops);
            byteWriter.Write(_xid);
            byteWriter.Write(_secs); // (ReverseByteOrder(BitConverter.GetBytes(this._secs))) ??
            byteWriter.Write(_flags);
            byteWriter.Write(_ciaddr);
            byteWriter.Write(_yiaddr);
            byteWriter.Write(_siaddr);
            byteWriter.Write(_giaddr);
            byteWriter.Write(_chaddr);
            byteWriter.Write(_sname);
            byteWriter.Write(_file);

            byte[] data = new byte[(_options.Count > 0 ? 4 + _options.Count * 2 + _optionDataSize + 1 : 0)];

            int offset = 0;

            if (_options.Count > 0)
            {
                BitConverter.GetBytes(Constants.DHCP_WIN_OPTIONS_MAGIC_NUMBER).CopyTo(data, offset);
                offset += 4;

                foreach (Byte optionId in _optionOrdering)
                {
                    DhcpOption option = (DhcpOption)optionId;
                    if (this._options.Contains(option))
                    {
                        data[offset++] = optionId;
                        byte[] optionValue = (byte[])_options[option];

                        if (this._options[option] != null && optionValue.Length > 0)
                        {
                            data[offset++] = (Byte)optionValue.Length;
                            Array.Copy((byte[])_options[option], 0, data, offset, optionValue.Length);
                            offset += optionValue.Length;
                        }
                    }
                }

                foreach (DhcpOption option in _options.Keys)
                {
                    if (Array.IndexOf(_optionOrdering, (Byte)option) == -1)
                    {
                        data[offset++] = (Byte)option;
                        byte[] optionValue = (byte[])_options[option];

                        if (this._options[option] != null && optionValue.Length > 0)
                        {
                            data[offset++] = (Byte)optionValue.Length;
                            Array.Copy((byte[])_options[option], 0, data, offset, optionValue.Length);
                            offset += optionValue.Length;
                        }
                    }
                }

                data[offset] = (Byte)DhcpOption.End;
            }
            byteWriter.Write(data);

            return(byteWriter.GetBytes());
        }
Ejemplo n.º 37
0
        void SendDhcpMessage(UdpSocket socket, DhcpMessageType messageType, UInt32 dhcpServerIPAddress, UInt32 transactionID, UInt16 secondsElapsed, UInt32 clientIPAddress, UInt64 clientHardwareAddress, DhcpOption[] options, Int64 timeoutInMachineTicks)
        {
            if (_isDisposed) return;

            byte[] dhcpFrameBuffer = new byte[DHCP_FRAME_BUFFER_LENGTH];

            // configure DHCP frame
            /* op (bootp operation) */
            dhcpFrameBuffer[0] = (byte)BootpOperation.BOOTREQUEST;
            /* htype (hardware type) */
            dhcpFrameBuffer[1] = (byte)HARDWARE_TYPE_ETHERNET;
            /* hlen (hardware address length) */
            dhcpFrameBuffer[2] = (byte)HARDWARE_ADDRESS_SIZE;
            /* hops (bootp relay hops; we should always set this to zero) */
            dhcpFrameBuffer[3] = 0;
            /* xid (transaction id; this should be a randomly-generated number) */
            dhcpFrameBuffer[4] = (byte)((transactionID >> 24) & 0xFF);
            dhcpFrameBuffer[5] = (byte)((transactionID >> 16) & 0xFF);
            dhcpFrameBuffer[6] = (byte)((transactionID >> 8) & 0xFF);
            dhcpFrameBuffer[7] = (byte)(transactionID & 0xFF);
            /* secs (seconds elasped since start of DHCP config acquisition process) */
            dhcpFrameBuffer[8] = (byte)((secondsElapsed >> 8) & 0xFF);
            dhcpFrameBuffer[9] = (byte)(secondsElapsed & 0xFF);
            /* flags (most significant bit is broadcast flags; all others are zeroes) */
            /* some DHCP servers do not process the broadcast flag properly, so we allow all broadcast and unicast packets with our hardwareAddress to pass through to the UDP layer instead */
            /* see https://support.microsoft.com/en-us/kb/928233 for more details */
            dhcpFrameBuffer[10] = 0x00; // 0x80; 
            dhcpFrameBuffer[11] = 0x00;
            /* ciaddr (client ip address; only filled in if client can respond to ARP requests and is in BOUND, RENEW or REBINDING state) */
            dhcpFrameBuffer[12] = (byte)((clientIPAddress >> 24) & 0xFF);
            dhcpFrameBuffer[13] = (byte)((clientIPAddress >> 16) & 0xFF);
            dhcpFrameBuffer[14] = (byte)((clientIPAddress >> 8) & 0xFF);
            dhcpFrameBuffer[15] = (byte)(clientIPAddress & 0xFF);
            /* yiaddr (ip address, populated by server; this should always be zero in client requests */
            dhcpFrameBuffer[16] = 0;
            dhcpFrameBuffer[17] = 0;
            dhcpFrameBuffer[18] = 0;
            dhcpFrameBuffer[19] = 0;
            /* siaddr (ip address of next address to use in bootp boot process, populated by server; this should always be zero in client requests */
            dhcpFrameBuffer[20] = 0;
            dhcpFrameBuffer[21] = 0;
            dhcpFrameBuffer[22] = 0;
            dhcpFrameBuffer[23] = 0;
            /* giaddr (ip address of relay agent, populated by relay agents; this should always be zero in client requests */
            dhcpFrameBuffer[24] = 0;
            dhcpFrameBuffer[25] = 0;
            dhcpFrameBuffer[26] = 0;
            dhcpFrameBuffer[27] = 0;
            /* chaddr (client hardware address; we fill in the first 6 bytes with our MAC address) */
            dhcpFrameBuffer[28] = (byte)((clientHardwareAddress >> 40) & 0xFF);
            dhcpFrameBuffer[29] = (byte)((clientHardwareAddress >> 32) & 0xFF);
            dhcpFrameBuffer[30] = (byte)((clientHardwareAddress >> 24) & 0xFF);
            dhcpFrameBuffer[31] = (byte)((clientHardwareAddress >> 16) & 0xFF);
            dhcpFrameBuffer[32] = (byte)((clientHardwareAddress >> 8) & 0xFF);
            dhcpFrameBuffer[33] = (byte)(clientHardwareAddress & 0xFF);
            Array.Clear(dhcpFrameBuffer, 34, 10);
            /* sname (null-terminated server hostname, populated by server; always set to zero in client requests */
            Array.Clear(dhcpFrameBuffer, 44, 64);
            /* file (null-terminated boot file name, populaetd by server; always set to zero in client requests */
            Array.Clear(dhcpFrameBuffer, 108, 128);
            /* options; NOTE: we do support overflowing options into the sname and file fields in this implementation of DHCP. */
            /* magic cookie {99, 130, 83, 99} is the first 4-byte entry, as per RFC 1497 */
            dhcpFrameBuffer[236] = 99;
            dhcpFrameBuffer[237] = 130;
            dhcpFrameBuffer[238] = 83;
            dhcpFrameBuffer[239] = 99;
            /* now we fill in the options (starting with the DhcpMessageType, then all of the passed-in options, and then the END option */
            dhcpFrameBuffer[240] = (byte)DhcpOptionCode.DhcpMessageType;
            dhcpFrameBuffer[241] = 1; /* Length */
            dhcpFrameBuffer[242] = (byte)messageType;
            int currentOptionPos = 243;
            if (options != null)
            {
                for (int iOption = 0; iOption < options.Length; iOption++)
                {
                    /* do not include missing/empty options (or pad) */
                    if (options[iOption].Code != 0)
                    {
                        // if this option will not fit in the options section, stop processing options.
                        if (currentOptionPos + options.Length + 2 /* size of code + length bytes */ + 1 /* size of END option */ > DHCP_FRAME_BUFFER_LENGTH)
                            break;

                        dhcpFrameBuffer[currentOptionPos++] = (byte)options[iOption].Code;
                        dhcpFrameBuffer[currentOptionPos++] = (byte)options[iOption].Value.Length;
                        Array.Copy(options[iOption].Value, 0, dhcpFrameBuffer, currentOptionPos, options[iOption].Value.Length);
                        currentOptionPos += options[iOption].Value.Length;
                    }
                }
            }
            /* finish with "END" option */
            dhcpFrameBuffer[currentOptionPos++] = (byte)DhcpOptionCode.End;
            Array.Clear(dhcpFrameBuffer, currentOptionPos, DHCP_FRAME_BUFFER_LENGTH - currentOptionPos);

            // expand frame to word boundary, just in case DHCP servers have troubles processing non-aligned frames.
            Int32 lengthOfFrame = Math.Min(currentOptionPos + (currentOptionPos % 4 != 0 ? (4 - (currentOptionPos % 4)) : 0), DHCP_FRAME_BUFFER_LENGTH);

            socket.SendTo(dhcpFrameBuffer, 0, lengthOfFrame, 0, timeoutInMachineTicks, dhcpServerIPAddress, DHCP_SERVER_PORT);
        }
Ejemplo n.º 38
0
 public byte[] GetOptionData(DhcpOption option)
 {
     if (_mOptions.ContainsKey(option))
     {
         return _mOptions[option];
     }
     return null;
 }
Ejemplo n.º 39
0
        bool SendDhcpRequestAndWaitForAck(DhcpOffer dhcpOffer, UInt16 secondsElapsed, UInt32 dhcpServerIPAddress, UInt32 clientIPAddress, Int64 timeoutInMachineTicks)
        {
            bool success = false;

            // 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
            {
                // bind the reserved socket to the DHCPv4 client port
                socket.Bind(0 /* IP_ADDRESS_ANY */, DHCP_CLIENT_PORT);

                // we will retry the DHCP request up to four times.  first delay will be 4 +/-1 seconds; second delay will be 8 +/-1 seconds; third delay will be 16 +/-1 seconds; fourth delay will be 32 +/-1 seconds.
                // if our current timeoutInMachineTicks is longer than 64 seconds (the maximum wait for DHCP transmission) then reduce it to the maximum
                timeoutInMachineTicks = (Int64)System.Math.Max(timeoutInMachineTicks, Microsoft.SPOT.Hardware.Utility.GetMachineTime().Ticks + (TimeSpan.TicksPerSecond * 64));
                byte nextRetrySeconds = 4;
                Int64 nextRetryInMachineTicks = (Int64)(Microsoft.SPOT.Hardware.Utility.GetMachineTime().Ticks + (((double)nextRetrySeconds + GenerateRandomPlusMinusOne()) * TimeSpan.TicksPerSecond));

                // set our clientIdentifier
                byte[] clientIdentifier = new byte[1 + HARDWARE_ADDRESS_SIZE];
                clientIdentifier[0] = HARDWARE_TYPE_ETHERNET;
                clientIdentifier[1] = (byte)((_physicalAddress >> 40) & 0xFF);
                clientIdentifier[2] = (byte)((_physicalAddress >> 32) & 0xFF);
                clientIdentifier[3] = (byte)((_physicalAddress >> 24) & 0xFF);
                clientIdentifier[4] = (byte)((_physicalAddress >> 16) & 0xFF);
                clientIdentifier[5] = (byte)((_physicalAddress >> 8) & 0xFF);
                clientIdentifier[6] = (byte)(_physicalAddress & 0xFF);

                byte[] parameterRequestList;
                if (_isDhcpDnsConfigEnabled)
                {
                    parameterRequestList = new byte[] { (byte)DhcpOptionCode.SubnetMask, (byte)DhcpOptionCode.Router, (byte)DhcpOptionCode.DomainNameServer };
                }
                else
                {
                    parameterRequestList = new byte[] { (byte)DhcpOptionCode.SubnetMask, (byte)DhcpOptionCode.Router };
                }

                byte[] maximumDhcpMessageSize = new byte[2];
                maximumDhcpMessageSize[0] = (byte)((DHCP_FRAME_BUFFER_LENGTH >> 8) & 0xFF);
                maximumDhcpMessageSize[1] = (byte)(DHCP_FRAME_BUFFER_LENGTH & 0xFF);

                byte[] requestedIPAddress = new byte[4];
                requestedIPAddress[0] = (byte)((dhcpOffer.IPAddress >> 24) & 0xFF);
                requestedIPAddress[1] = (byte)((dhcpOffer.IPAddress >> 16) & 0xFF);
                requestedIPAddress[2] = (byte)((dhcpOffer.IPAddress >> 8) & 0xFF);
                requestedIPAddress[3] = (byte)(dhcpOffer.IPAddress & 0xFF);

                byte[] serverIdentifier = new byte[4];
                serverIdentifier[0] = (byte)((dhcpOffer.ServerIdentifier >> 24) & 0xFF);
                serverIdentifier[1] = (byte)((dhcpOffer.ServerIdentifier >> 16) & 0xFF);
                serverIdentifier[2] = (byte)((dhcpOffer.ServerIdentifier >> 8) & 0xFF);
                serverIdentifier[3] = (byte)(dhcpOffer.ServerIdentifier & 0xFF);

                while (timeoutInMachineTicks > Microsoft.SPOT.Hardware.Utility.GetMachineTime().Ticks)
                {
                    // assemble options
                    DhcpOption[] options = new DhcpOption[5];
                    options[0] = new DhcpOption(DhcpOptionCode.ClientIdentifier, clientIdentifier);
                    options[1] = new DhcpOption(DhcpOptionCode.ParameterRequestList, parameterRequestList);
                    options[2] = new DhcpOption(DhcpOptionCode.MaximumDhcpMessageSize, maximumDhcpMessageSize);
                    if (dhcpOffer.IPAddress != 0)
                        options[3] = new DhcpOption(DhcpOptionCode.RequestedIPAddress, requestedIPAddress);
                    if (dhcpOffer.ServerIdentifier != 0)
                        options[4] = new DhcpOption(DhcpOptionCode.ServerIdentifier, serverIdentifier);

                    // send DHCP message
                    SendDhcpMessage(socket, DhcpMessageType.DHCPREQUEST, dhcpServerIPAddress, dhcpOffer.TransactionID, secondsElapsed, clientIPAddress, _physicalAddress, options, timeoutInMachineTicks);

                    // wait for ACK/NAK
                    bool responseIsAck;
                    bool ackNakReceived = RetrieveAckNak(socket, dhcpOffer.TransactionID, _physicalAddress, ref dhcpOffer, out responseIsAck, nextRetryInMachineTicks);

                    if (ackNakReceived)
                    {
                        success = responseIsAck;
                        break;
                    }

                    secondsElapsed += nextRetrySeconds;
                    nextRetrySeconds *= 2;
                    nextRetryInMachineTicks = (Int64)(Microsoft.SPOT.Hardware.Utility.GetMachineTime().Ticks + (((double)nextRetrySeconds + GenerateRandomPlusMinusOne()) * TimeSpan.TicksPerSecond));
                }
            }
            finally
            {
                // close the reserved socket
                _ipv4Layer.CloseSocket(socketHandle);
            }

            return success;
        }
Ejemplo n.º 40
0
        public bool RemoveOption(DhcpOption option)
        {
            if (_mOptions.ContainsKey(option))
            {
                _mOptionDataSize -= _mOptions[option].Length;
            }

            return _mOptions.Remove(option);
        }
Ejemplo n.º 41
0
        public Boolean RemoveOption(DhcpOption option)
        {
            if (this.m_Options.ContainsKey(option))
            {
                this.m_OptionDataSize -= this.m_Options[option].Length;
            }

            return this.m_Options.Remove(option);
        }
Ejemplo n.º 42
0
        /// <summary>
        /// Gets the DHCP option string.
        /// </summary>
        /// <param name="dhcpOption">The DHCP option.</param>
        /// <param name="dhcpOptionValue">The DHCP option value.</param>
        /// <param name="dhcpRequestListFormat">The DHCP request list format.</param>
        /// <param name="logger">The logger.</param>
        /// <returns>System.String.</returns>
        /// <autogeneratedoc />
        public static string GetDhcpOptionString(
            DhcpOption dhcpOption, byte[] dhcpOptionValue,
            DhcpRequestListFormat dhcpRequestListFormat = DhcpRequestListFormat.StringNewlineIndentedSeparated,
            IPureLogger logger = null
            )
        {
            try
            {
                if (dhcpOptionValue == null)
                {
                    return("Null");
                }

                if (dhcpOption == DhcpOption.ParamReqList)
                {
                    return(GetDhcpRequestListString(dhcpOptionValue, dhcpRequestListFormat, logger));
                }

                switch (DhcpOptionTypes[dhcpOption])
                {
                case DhcpOptionType.IPAddress:
                    return(new IPAddress(dhcpOptionValue).ToString());

                case DhcpOptionType.PhysicalAddressSkip1DashString:
                    return(new PhysicalAddress(dhcpOptionValue.Skip(1).ToArray()).ToDashString());

                case DhcpOptionType.PhysicalAddressSkip1ColonString:
                    return(new PhysicalAddress(dhcpOptionValue.Skip(1).ToArray()).ToColonString());

                case DhcpOptionType.PhysicalAddressDashString:
                    return(new PhysicalAddress(dhcpOptionValue).ToDashString());

                case DhcpOptionType.PhysicalAddressColonString:
                    return(new PhysicalAddress(dhcpOptionValue).ToColonString());

                case DhcpOptionType.MessageTypeString:
                    return(MessageTypeString.GetName((MessageType)dhcpOptionValue[0]));

                case DhcpOptionType.SafeString:
                    return(ByteUtility.GetSafeString(dhcpOptionValue));

                case DhcpOptionType.SafeBytes:
                    return(ByteUtility.PrintSafeBytes(dhcpOptionValue));

                case DhcpOptionType.UInt16:
                    return(BitConverter.ToUInt16(dhcpOptionValue, 0).ToString());

                case DhcpOptionType.UInt32:
                    return(BitConverter.ToUInt32(dhcpOptionValue, 0).ToString());

                case DhcpOptionType.UInt16Network:
                    return(IPAddress.NetworkToHostOrder(BitConverter.ToUInt16(dhcpOptionValue, 0)).ToString());

                case DhcpOptionType.UInt32Network:
                    return(IPAddress.NetworkToHostOrder(BitConverter.ToUInt32(dhcpOptionValue, 0)).ToString());
                }
            }
            catch (Exception ex)
            {
                logger?.LogError(ex, "Invalid DhcpOption: {dhcpOption}", dhcpOption);
            }

            return(string.Empty);
        }
Ejemplo n.º 43
0
 /**
  * Implement DhcpOptionable.
  *
  * @param dhcpOption the dhcp option
  */
 public void PutDhcpOption(DhcpOption dhcpOption)
 {
     dhcpOptions[dhcpOption.GetCode()] = dhcpOption;
 }
Ejemplo n.º 44
0
        /// <summary>发送DHCP消息</summary>
        /// <param name="dhcp"></param>
        protected void Send(DhcpEntity dhcp)
        {
            dhcp.ClientMac = Mac;

            var opt = new DhcpOption();
            opt.SetClientId(Mac);
            dhcp.Options.Add(opt);

            if (Address != IPAddress.Any)
            {
                opt = new DhcpOption();
                opt.SetData(DhcpOptions.RequestedIP, Address.GetAddressBytes());
                dhcp.Options.Add(opt);
            }

            opt = new DhcpOption();
            opt.SetData(DhcpOptions.HostName, ("WSWL_SmartOS_").GetBytes());
            dhcp.Options.Add(opt);

            opt = new DhcpOption();
            opt.SetData(DhcpOptions.Vendor, "http://www.NewLifeX.com".GetBytes());
            dhcp.Options.Add(opt);

            opt = new DhcpOption();
            opt.SetData(DhcpOptions.ParameterList, new Byte[] { 0x01, 0x06, 0x03, 0x2b });
            dhcp.Options.Add(opt);

            dhcp.TransactionID = TransID;

            WriteLog("发送:{0}", dhcp);

            var buf = dhcp.ToArray();
            Client.Client.Broadcast(buf, 68);
        }