Пример #1
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);
 }
        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;
 }