Example #1
0
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
}
Example #2
0
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
}
Example #3
0
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
}
Example #4
0
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
}
Example #5
0
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
}