summaryrefslogtreecommitdiffhomepage
path: root/dhcpv4/dhcpv4.go
diff options
context:
space:
mode:
Diffstat (limited to 'dhcpv4/dhcpv4.go')
-rw-r--r--dhcpv4/dhcpv4.go70
1 files changed, 28 insertions, 42 deletions
diff --git a/dhcpv4/dhcpv4.go b/dhcpv4/dhcpv4.go
index 5005375..d452f6e 100644
--- a/dhcpv4/dhcpv4.go
+++ b/dhcpv4/dhcpv4.go
@@ -42,14 +42,11 @@ type DHCPv4 struct {
// structures. This is used to simplify packet manipulation
type Modifier func(d *DHCPv4) *DHCPv4
-// IPv4AddrsForInterface obtains the currently-configured, non-loopback IPv4
-// addresses for iface.
-func IPv4AddrsForInterface(iface *net.Interface) ([]net.IP, error) {
- addrs, err := iface.Addrs()
+// GetExternalIPv4Addrs obtains the currently-configured, non-loopback IPv4
+// addresses from `addrs` coming from a particular interface (e.g.
+// net.Interface.Addrs).
+func GetExternalIPv4Addrs(addrs []net.Addr) ([]net.IP, error) {
var v4addrs []net.IP
- if err != nil {
- return v4addrs, err
- }
for _, addr := range addrs {
var ip net.IP
switch v := addr.(type) {
@@ -121,23 +118,18 @@ func New() (*DHCPv4, error) {
return &d, nil
}
-// NewDiscoveryForInterface builds a new DHCPv4 Discovery message, with a default
-// Ethernet HW type and the hardware address obtained from the specified
-// interface.
-func NewDiscoveryForInterface(ifname string) (*DHCPv4, error) {
+// NewDiscovery builds a new DHCPv4 Discovery message, with a default Ethernet
+// HW type and specified hardware address.
+func NewDiscovery(hwaddr net.HardwareAddr) (*DHCPv4, error) {
d, err := New()
if err != nil {
return nil, err
}
// get hw addr
- iface, err := net.InterfaceByName(ifname)
- if err != nil {
- return nil, err
- }
d.SetOpcode(OpcodeBootRequest)
d.SetHwType(iana.HwTypeEthernet)
- d.SetHwAddrLen(uint8(len(iface.HardwareAddr)))
- d.SetClientHwAddr(iface.HardwareAddr)
+ d.SetHwAddrLen(uint8(len(hwaddr)))
+ d.SetClientHwAddr(hwaddr)
d.SetBroadcast()
d.AddOption(&OptMessageType{MessageType: MessageTypeDiscover})
d.AddOption(&OptParameterRequestList{
@@ -151,38 +143,20 @@ func NewDiscoveryForInterface(ifname string) (*DHCPv4, error) {
return d, nil
}
-// NewInformForInterface builds a new DHCPv4 Informational message with default
-// Ethernet HW type and the hardware address obtained from the specified
-// interface.
-func NewInformForInterface(ifname string, needsBroadcast bool) (*DHCPv4, error) {
+// NewInform builds a new DHCPv4 Informational message with default Ethernet HW
+// type and specified hardware address. It does NOT put a DHCP End option at the
+// end.
+func NewInform(hwaddr net.HardwareAddr, localIP net.IP) (*DHCPv4, error) {
d, err := New()
if err != nil {
return nil, err
}
- // get hw addr
- iface, err := net.InterfaceByName(ifname)
- if err != nil {
- return nil, err
- }
d.SetOpcode(OpcodeBootRequest)
d.SetHwType(iana.HwTypeEthernet)
- d.SetHwAddrLen(uint8(len(iface.HardwareAddr)))
- d.SetClientHwAddr(iface.HardwareAddr)
-
- if needsBroadcast {
- d.SetBroadcast()
- } else {
- d.SetUnicast()
- }
-
- // Set Client IP as iface's currently-configured IP.
- localIPs, err := IPv4AddrsForInterface(iface)
- if err != nil || len(localIPs) == 0 {
- return nil, fmt.Errorf("could not get local IPs for iface %s", ifname)
- }
- d.SetClientIPAddr(localIPs[0])
-
+ d.SetHwAddrLen(uint8(len(hwaddr)))
+ d.SetClientHwAddr(hwaddr)
+ d.SetClientIPAddr(localIP)
d.AddOption(&OptMessageType{MessageType: MessageTypeInform})
return d, nil
}
@@ -715,3 +689,15 @@ func (d *DHCPv4) ToBytes() []byte {
}
return ret
}
+
+// OptionGetter is a interface that knows how to retrieve an option from a
+// structure of options given an OptionCode.
+type OptionGetter interface {
+ GetOption(OptionCode) []Option
+ GetOneOption(OptionCode) Option
+}
+
+// HasOption checks whether the OptionGetter `o` has the given `opcode` Option.
+func HasOption(o OptionGetter, opcode OptionCode) bool {
+ return o.GetOneOption(opcode) != nil
+}