summaryrefslogtreecommitdiffhomepage
path: root/dhcpv4/modifiers.go
blob: 033718e80be28d48982c9e3e81c3f07909ebe68d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
package dhcpv4

import (
	"net"

	"github.com/insomniacslk/dhcp/rfc1035label"
)

// WithTransactionID sets the Transaction ID for the DHCPv4 packet
func WithTransactionID(xid uint32) Modifier {
	return func(d *DHCPv4) *DHCPv4 {
		d.SetTransactionID(xid)
		return d
	}
}

// WithBroadcast sets the packet to be broadcast or unicast
func WithBroadcast(broadcast bool) Modifier {
	return func(d *DHCPv4) *DHCPv4 {
		if broadcast {
			d.SetBroadcast()
		} else {
			d.SetUnicast()
		}
		return d
	}
}

// WithHwAddr sets the hardware address for a packet
func WithHwAddr(hwaddr []byte) Modifier {
	return func(d *DHCPv4) *DHCPv4 {
		d.SetClientHwAddr(hwaddr)
		return d
	}
}

// WithOption appends a DHCPv4 option provided by the user
func WithOption(opt Option) Modifier {
	return func(d *DHCPv4) *DHCPv4 {
		d.AddOption(opt)
		return d
	}
}

// WithUserClass adds a user class option to the packet.
// The rfc parameter allows you to specify if the userclass should be
// rfc compliant or not. More details in issue #113
func WithUserClass(uc []byte, rfc bool) Modifier {
	// TODO let the user specify multiple user classes
	return func(d *DHCPv4) *DHCPv4 {
		ouc := OptUserClass{
			UserClasses: [][]byte{uc},
			Rfc3004:     rfc,
		}
		d.AddOption(&ouc)
		return d
	}
}

// WithNetboot adds bootfile URL and bootfile param options to a DHCPv4 packet.
func WithNetboot(d *DHCPv4) *DHCPv4 {
	params := d.GetOneOption(OptionParameterRequestList)

	var (
		OptParams                 *OptParameterRequestList
		foundOptionTFTPServerName bool
		foundOptionBootfileName   bool
	)
	if params != nil {
		OptParams = params.(*OptParameterRequestList)
		for _, option := range OptParams.RequestedOpts {
			if option == OptionTFTPServerName {
				foundOptionTFTPServerName = true
			} else if option == OptionBootfileName {
				foundOptionBootfileName = true
			}
		}
		if !foundOptionTFTPServerName {
			OptParams.RequestedOpts = append(OptParams.RequestedOpts, OptionTFTPServerName)
		}
		if !foundOptionBootfileName {
			OptParams.RequestedOpts = append(OptParams.RequestedOpts, OptionBootfileName)
		}
	} else {
		OptParams = &OptParameterRequestList{
			RequestedOpts: []OptionCode{OptionTFTPServerName, OptionBootfileName},
		}
		d.AddOption(OptParams)
	}
	return d
}

// WithRequestedOptions adds requested options to the packet
func WithRequestedOptions(optionCodes ...OptionCode) Modifier {
	return func(d *DHCPv4) *DHCPv4 {
		params := d.GetOneOption(OptionParameterRequestList)
		if params == nil {
			params = &OptParameterRequestList{}
			d.AddOption(params)
		}
		opts := params.(*OptParameterRequestList)
		for _, optionCode := range optionCodes {
			opts.RequestedOpts = append(opts.RequestedOpts, optionCode)
		}
		return d
	}
}

// WithRelay adds parameters required for DHCPv4 to be relayed by the relay
// server with given ip
func WithRelay(ip net.IP) Modifier {
	return func(d *DHCPv4) *DHCPv4 {
		d.SetUnicast()
		d.SetGatewayIPAddr(ip)
		d.SetHopCount(1)
		return d
	}
}

// WithNetmask adds or updates an OptSubnetMask
func WithNetmask(mask net.IPMask) Modifier {
	return func(d *DHCPv4) *DHCPv4 {
		osm := OptSubnetMask{
			SubnetMask: mask,
		}
		d.UpdateOption(&osm)
		return d
	}
}

// WithLeaseTime adds or updates an OptIPAddressLeaseTime
func WithLeaseTime(leaseTime uint32) Modifier {
	return func(d *DHCPv4) *DHCPv4 {
		olt := OptIPAddressLeaseTime{
			LeaseTime: leaseTime,
		}
		d.UpdateOption(&olt)
		return d
	}
}

// WithDNS adds or updates an OptionDomainNameServer
func WithDNS(dnses ...net.IP) Modifier {
	return func(d *DHCPv4) *DHCPv4 {
		odns := OptDomainNameServer{NameServers: dnses}
		d.UpdateOption(&odns)
		return d
	}
}

// WithDomainSearchList adds or updates an OptionDomainSearch
func WithDomainSearchList(searchList ...string) Modifier {
	return func(d *DHCPv4) *DHCPv4 {
		labels := rfc1035label.Labels{
			Labels: searchList,
		}
		odsl := OptDomainSearch{DomainSearch: &labels}
		d.UpdateOption(&odsl)
		return d
	}
}

// WithRouter adds or updates an OptionRouter
func WithRouter(routers ...net.IP) Modifier {
	return func(d *DHCPv4) *DHCPv4 {
		ortr := OptRouter{Routers: routers}
		d.UpdateOption(&ortr)
		return d
	}
}