125 lines
2.2 KiB
Go
125 lines
2.2 KiB
Go
|
package dhcp
|
||
|
|
||
|
import "net/netip"
|
||
|
|
||
|
type Parameter interface {
|
||
|
Code() OptionTag
|
||
|
Len() int
|
||
|
Bytes() []byte // the serialized parameter
|
||
|
Valid() bool
|
||
|
}
|
||
|
|
||
|
func (packet *Packet) AddParameter(p Parameter) {
|
||
|
packet.Parameters = append(packet.Parameters, p)
|
||
|
}
|
||
|
|
||
|
type parameterWithAddr struct {
|
||
|
code OptionTag
|
||
|
addr netip.Addr
|
||
|
}
|
||
|
|
||
|
func (p parameterWithAddr) Code() OptionTag {
|
||
|
return p.code
|
||
|
}
|
||
|
|
||
|
func (p parameterWithAddr) Len() int {
|
||
|
return len(p.addr.AsSlice())
|
||
|
}
|
||
|
|
||
|
func (p parameterWithAddr) Bytes() []byte {
|
||
|
return append([]byte{byte(p.code), uint8(p.Len())},
|
||
|
p.addr.AsSlice()...)
|
||
|
}
|
||
|
|
||
|
func (p parameterWithAddr) Valid() bool {
|
||
|
return p.addr.Is4() && p.addr.IsValid() && !p.addr.IsUnspecified()
|
||
|
}
|
||
|
|
||
|
type parameterWithAddrs struct {
|
||
|
code OptionTag
|
||
|
addrs []netip.Addr
|
||
|
}
|
||
|
|
||
|
func (p parameterWithAddrs) Code() OptionTag {
|
||
|
return p.code
|
||
|
}
|
||
|
|
||
|
func (p parameterWithAddrs) Len() int {
|
||
|
plen := 0
|
||
|
|
||
|
for _, addr := range p.addrs {
|
||
|
plen += len(addr.AsSlice())
|
||
|
}
|
||
|
|
||
|
return plen
|
||
|
}
|
||
|
|
||
|
func (p parameterWithAddrs) Bytes() []byte {
|
||
|
out := []byte{byte(p.code), byte(p.Len())}
|
||
|
|
||
|
for _, addr := range p.addrs {
|
||
|
out = append(out, addr.AsSlice()...)
|
||
|
}
|
||
|
|
||
|
return out
|
||
|
}
|
||
|
|
||
|
func (p parameterWithAddrs) Valid() bool {
|
||
|
for _, addr := range p.addrs {
|
||
|
if !(addr.Is4() && addr.IsValid() && !addr.IsUnspecified()) {
|
||
|
return false
|
||
|
}
|
||
|
}
|
||
|
return true
|
||
|
}
|
||
|
|
||
|
type parameterWithString struct {
|
||
|
code OptionTag
|
||
|
data string
|
||
|
}
|
||
|
|
||
|
func (p parameterWithString) Code() OptionTag {
|
||
|
return p.code
|
||
|
}
|
||
|
|
||
|
func (p parameterWithString) Len() int {
|
||
|
return len(p.data)
|
||
|
}
|
||
|
|
||
|
func (p parameterWithString) Bytes() []byte {
|
||
|
out := []byte{byte(p.code), byte(p.Len())}
|
||
|
return append(out, []byte(p.data)...)
|
||
|
}
|
||
|
|
||
|
func (p parameterWithString) Valid() bool {
|
||
|
return len(p.data) > 0
|
||
|
}
|
||
|
|
||
|
func ParameterRouter(router netip.Addr) Parameter {
|
||
|
return ¶meterWithAddr{
|
||
|
code: OptionTagRouter,
|
||
|
addr: router,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func ParameterSubnetMask(mask netip.Addr) Parameter {
|
||
|
return ¶meterWithAddr{
|
||
|
code: OptionTagSubnetMask,
|
||
|
addr: mask,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func ParameterDNS(dns []netip.Addr) Parameter {
|
||
|
return ¶meterWithAddrs{
|
||
|
code: OptionTagDomainNameServer,
|
||
|
addrs: dns,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func ParameterHostName(name string) Parameter {
|
||
|
return ¶meterWithString{
|
||
|
code: OptionTagHostName,
|
||
|
data: name,
|
||
|
}
|
||
|
}
|