summaryrefslogtreecommitdiffhomepage
path: root/dhcpv4/modifiers.go
blob: 2bf79b8372880d9e781d351e22108c827466157d (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
package dhcpv4

import (
	"net"
	"time"

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

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

// WithClientIP sets the Client IP for a DHCPv4 packet.
func WithClientIP(ip net.IP) Modifier {
	return func(d *DHCPv4) {
		d.ClientIPAddr = ip
	}
}

// WithYourIP sets the Your IP for a DHCPv4 packet.
func WithYourIP(ip net.IP) Modifier {
	return func(d *DHCPv4) {
		d.YourIPAddr = ip
	}
}

// WithServerIP sets the Server IP for a DHCPv4 packet.
func WithServerIP(ip net.IP) Modifier {
	return func(d *DHCPv4) {
		d.ServerIPAddr = ip
	}
}

// WithGatewayIP sets the Gateway IP for the DHCPv4 packet.
func WithGatewayIP(ip net.IP) Modifier {
	return func(d *DHCPv4) {
		d.GatewayIPAddr = ip
	}
}

// WithRelayAgentInfo copies the relay options from the request to the reply.
func WithRelayAgentInfo(request *DHCPv4) Modifier {
	return func(d *DHCPv4) {
		// If request has Relay Agent Info copy it to the reply
		if relayOpt := request.RelayAgentInfo(); relayOpt != nil {
			d.UpdateOption(Option{Code: OptionRelayAgentInformation, Value: relayOpt})
		}
	}
}

// WithReply fills in opcode, hwtype, xid, clienthwaddr, flags, and gateway ip
// addr from the given packet.
func WithReply(request *DHCPv4) Modifier {
	return func(d *DHCPv4) {
		if request.OpCode == OpcodeBootRequest {
			d.OpCode = OpcodeBootReply
		} else {
			d.OpCode = OpcodeBootRequest
		}
		d.HWType = request.HWType
		d.TransactionID = request.TransactionID
		d.ClientHWAddr = request.ClientHWAddr
		d.Flags = request.Flags
	}
}

// WithHWType sets the Hardware Type for a DHCPv4 packet.
func WithHWType(hwt iana.HWType) Modifier {
	return func(d *DHCPv4) {
		d.HWType = hwt
	}
}

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

// WithHwAddr sets the hardware address for a packet
func WithHwAddr(hwaddr net.HardwareAddr) Modifier {
	return func(d *DHCPv4) {
		d.ClientHWAddr = hwaddr
	}
}

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

// 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 string, rfc bool) Modifier {
	// TODO let the user specify multiple user classes
	return func(d *DHCPv4) {
		if rfc {
			d.UpdateOption(OptRFC3004UserClass([]string{uc}))
		} else {
			d.UpdateOption(OptUserClass(uc))
		}
	}
}

// WithNetboot adds bootfile URL and bootfile param options to a DHCPv4 packet.
func WithNetboot(d *DHCPv4) {
	WithRequestedOptions(OptionTFTPServerName, OptionBootfileName)(d)
}

// WithMessageType adds the DHCPv4 message type m to a packet.
func WithMessageType(m MessageType) Modifier {
	return WithOption(OptMessageType(m))
}

// WithRequestedOptions adds requested options to the packet.
func WithRequestedOptions(optionCodes ...OptionCode) Modifier {
	return func(d *DHCPv4) {
		cl := d.ParameterRequestList()
		cl.Add(optionCodes...)
		d.UpdateOption(OptParameterRequestList(cl...))
	}
}

// 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) {
		d.SetUnicast()
		d.GatewayIPAddr = ip
		d.HopCount++
	}
}

// WithNetmask adds or updates an OptSubnetMask
func WithNetmask(mask net.IPMask) Modifier {
	return WithOption(OptSubnetMask(mask))
}

// WithLeaseTime adds or updates an OptIPAddressLeaseTime
func WithLeaseTime(leaseTime uint32) Modifier {
	return WithOption(OptIPAddressLeaseTime(time.Duration(leaseTime) * time.Second))
}

// WithDomainSearchList adds or updates an OptionDomainSearch
func WithDomainSearchList(searchList ...string) Modifier {
	return WithOption(OptDomainSearch(&rfc1035label.Labels{
		Labels: searchList,
	}))
}

func WithGeneric(code OptionCode, value []byte) Modifier {
	return WithOption(OptGeneric(code, value))
}