public void PutDhcpOption(DhcpOption dhcpOption) { if ((dhcpOption != null)) { this.dhcpOptions[dhcpOption.GetCode()] = dhcpOption; } }
/// <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 } } }
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()); }
/// <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); }
public void PutDhcpOption(DhcpOption dhcpOption) { if (dhcpOption != null) { _dhcpOptions[dhcpOption.GetCode()] = dhcpOption; } }
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); }
public void AddSuboption(DhcpOption suboption) { if (suboptionList == null) { suboptionList = new List <DhcpOption>(); } suboptionList.Add(suboption); }
/** * 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); }
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)); }
/// <summary> /// Remove custom option type. /// </summary> public Boolean RemoveOption(DhcpOption option) { if (this._options.Contains(option)) { this._options.Remove(option); return(true); } return(false); }
/// <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; }
public Byte[] GetOptionData(DhcpOption option) { if (this.m_Options.ContainsKey(option)) { return(this.m_Options[option]); } else { return(null); } }
/// <summary> /// Get option data. /// </summary> public byte[] GetOptionData(DhcpOption option) { if (this._options.Contains(option)) { return((byte[])this._options[option]); } else { return(null); } }
/// <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); }
/** * 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); }
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 } } }
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); }
/// <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); }
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()); }
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()); }
/** * 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); }
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); }
/// <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; }
public Byte[] GetOptionData(DhcpOption option) { if (this.m_Options.ContainsKey(option)) { return this.m_Options[option]; } else { return null; } }
/// <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()); }
//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)); }
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; }
/// <summary> /// Add or define a new custom option type. /// </summary> public void AddOption(DhcpOption option, byte[] data) { _options.Add(option, data); }
/// <summary> /// Remove custom option type. /// </summary> public Boolean RemoveOption(DhcpOption option) { if (this._options.Contains(option)) { this._options.Remove(option); return true; } return false; }
/// <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; } } }
protected void SetDhcpOption(IaAddress iaAddr, DhcpOption option) { iaAddr.SetDhcpOption(option); UpdateIpAddrOptions(iaAddr.GetIpAddress(), iaAddr.GetDhcpOptions()); }
/// <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; } } }
/// <summary> /// Get option data. /// </summary> public byte[] GetOptionData(DhcpOption option) { if (this._options.Contains(option)) { return (byte[])this._options[option]; } else { return null; } }
/// <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; }
/// <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()); }
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); }
public byte[] GetOptionData(DhcpOption option) { if (_mOptions.ContainsKey(option)) { return _mOptions[option]; } return null; }
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; }
public bool RemoveOption(DhcpOption option) { if (_mOptions.ContainsKey(option)) { _mOptionDataSize -= _mOptions[option].Length; } return _mOptions.Remove(option); }
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); }
/// <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); }
/** * Implement DhcpOptionable. * * @param dhcpOption the dhcp option */ public void PutDhcpOption(DhcpOption dhcpOption) { dhcpOptions[dhcpOption.GetCode()] = dhcpOption; }
/// <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); }