func (dp *DhcpPacket) ReplaceOption(optionToReplace option.SpecificOption) (err error) { done := false for i := len(dp.Options) - 2; 0 <= i; i-- { if dp.Options[i].GetType() == optionToReplace.GetNum() { rawOpt := dp.Options[i] // test whether this option is included into raw packet's data idx, err := rawOpt.GetIndexInto(dp.Raw) if err != nil { // this option is not included ??? continue } if done { // remove old data option from rawData. // It is used when several time same option in same packet // For example RFC 3396 : Encoding Long Options in the Dynamic Host Configuration Protocol (DHCPv4) dp.Raw = append(dp.Raw[:idx], dp.Raw[idx+int(rawOpt.GetRawLen()):]...) } else { // insert option into rawData dp.Raw = append(dp.Raw[:idx], append(optionToReplace.GetRawOption().GetRawValue(), dp.Raw[idx+int(rawOpt.GetRawLen()):]...)...) done = true } } } if done { dp.Options, err = option.ParseOptions(dp.Raw[240:]) //240th byte is where options are } else { err = dherrors.OptNotFound } return }
func (dp *DhcpPacket) AddOptionBefore(optionToAdd, beforeOption option.SpecificOption) (err error) { if !optionToAdd.GetRawOption().IsValid() { return dherrors.MalformedOption } done := false for i := len(dp.Options) - 2; 0 <= i; i-- { if dp.Options[i].GetType() != beforeOption.GetNum() { continue } if 0 < i && dp.Options[i-1].GetType() == beforeOption.GetNum() { // we don't insert here as this option use RFC 3396 : Encoding Long Options in the Dynamic Host Configuration Protocol (DHCPv4) continue } done = true rawOpt := dp.Options[i] // test whether this option is included into raw packet's data idx, err := rawOpt.GetIndexInto(dp.Raw) if err != nil { // this option is not included ??? continue } // insert data before option into rawData dp.Raw = append(dp.Raw[:idx], append(optionToAdd.GetRawOption().GetRawValue(), dp.Raw[idx:]...)...) break } if done { dp.Options, err = option.ParseOptions(dp.Raw[240:]) //240th byte is where options are } else { err = dherrors.OptNotFound } return }
func (dp *DhcpPacket) ResetAllOptions() error { var err error dp.Raw[240] = 0xff dp.Raw = dp.Raw[:241] // remove padding and hide it. dp.Options, err = option.ParseOptions(dp.Raw[240:]) //240th byte is where options are return err }
func (dp *DhcpPacket) RemoveOption(numOpt byte) (err error) { for i := len(dp.Options) - 2; 0 <= i; i-- { if dp.Options[i].GetType() == numOpt { rawOpt := dp.Options[i] // test whether this option is included into raw packet's data idx, err := rawOpt.GetIndexInto(dp.Raw) if err != nil { // this option is not included ??? continue } // remove data from rawData dp.Raw = append(dp.Raw[:idx], dp.Raw[idx+int(rawOpt.GetRawLen()):]...) } } dp.Options, err = option.ParseOptions(dp.Raw[240:]) //240th byte is where options are return }
func Parse(raw []byte) (dp *DhcpPacket, err error) { dp = new(DhcpPacket) dp.Raw = raw err = dp.headerSanityCheck() if err != nil { dp = nil return } dp.Options, err = option.ParseOptions(raw[240:]) //240th byte is where options are if err != nil { dp = nil return } if err = dp.optionSanityCheck(); err != nil { dp = nil return } return }