/// <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 DhcpV6RelayMessage HandleRelayForward(DhcpV6RelayMessage relayMessage) { IPAddress linkAddr = relayMessage.GetLinkAddress(); _log.Info(("Handling relay forward on link address: " + linkAddr.ToString())); DhcpV6RelayOption relayOption = relayMessage.GetRelayOption(); if ((relayOption != null)) { DhcpV6Message relayOptionMessage = relayOption.GetDhcpMessage(); while ((relayOptionMessage != null)) { // check what kind of message is in the option if ((relayOptionMessage is DhcpV6RelayMessage)) { // encapsulated message is another relay message DhcpV6RelayMessage anotherRelayMessage = ((DhcpV6RelayMessage)(relayOptionMessage)); // flip this inner relay_forward into a relay_reply, // because we reuse the relay message "stack" for the reply anotherRelayMessage.SetMessageType(DhcpConstants.V6MESSAGE_TYPE_RELAY_REPL); // reset the client link reference linkAddr = anotherRelayMessage.GetLinkAddress(); // reset the current relay option reference to the // encapsulated relay message's relay option relayOption = anotherRelayMessage.GetRelayOption(); // reset the relayOptionMessage reference to recurse relayOptionMessage = relayOption.GetDhcpMessage(); } else { // we've peeled off all the layers of the relay message(s), // so now go handle the client request _log.Info(("Handling client request on remote client link address: " + linkAddr.ToString())); DhcpV6Message replyMessage = DhcpV6MessageHandler.HandleClientRequest(linkAddr, relayOptionMessage, null); if ((replyMessage != null)) { // replace the original client request message inside // the relayed message with the generated Reply message relayOption.SetDhcpMessage(replyMessage); // flip the outer-most relay_foward into a relay_reply relayMessage.SetMessageType(DhcpConstants.V6MESSAGE_TYPE_RELAY_REPL); // return the relay message we started with, // with each relay "layer" flipped from a relay_forward // to a relay_reply, and the lowest level relayOption // will contain our Reply for the client request return(relayMessage); } relayOptionMessage = null; // done with relayed messages } } } else { _log.Error("Relay message does not contain a relay option"); } // if we get here, no reply was generated return(null); }
public void SetRelayOption(DhcpV6RelayOption relayOption) { this.relayOption = relayOption; }