kdhcp/dhcp/parameters.go

125 lines
2.2 KiB
Go
Raw Permalink Normal View History

2023-05-15 13:09:12 +00:00
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 &parameterWithAddr{
code: OptionTagRouter,
addr: router,
}
}
func ParameterSubnetMask(mask netip.Addr) Parameter {
return &parameterWithAddr{
code: OptionTagSubnetMask,
addr: mask,
}
}
func ParameterDNS(dns []netip.Addr) Parameter {
return &parameterWithAddrs{
code: OptionTagDomainNameServer,
addrs: dns,
}
}
func ParameterHostName(name string) Parameter {
return &parameterWithString{
code: OptionTagHostName,
data: name,
}
}