summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--dhcpv4/client.go6
-rw-r--r--dhcpv4/dhcpv4.go52
2 files changed, 53 insertions, 5 deletions
diff --git a/dhcpv4/client.go b/dhcpv4/client.go
index 8a44338..9fd8501 100644
--- a/dhcpv4/client.go
+++ b/dhcpv4/client.go
@@ -137,14 +137,10 @@ func (c *Client) Exchange(ifname string, discover *DHCPv4, modifiers ...Modifier
if err != nil {
return conversation, err
}
- iface, err := net.InterfaceByName(ifname)
- if err != nil {
- return conversation, err
- }
// Discover
if discover == nil {
- discover, err = NewDiscovery(iface.HardwareAddr)
+ discover, err = NewDiscoveryForInterface(ifname)
if err != nil {
return conversation, err
}
diff --git a/dhcpv4/dhcpv4.go b/dhcpv4/dhcpv4.go
index 972d103..2519e2c 100644
--- a/dhcpv4/dhcpv4.go
+++ b/dhcpv4/dhcpv4.go
@@ -42,6 +42,19 @@ 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) {
+ if iface == nil {
+ return nil, errors.New("IPv4AddrsForInterface: iface cannot be nil")
+ }
+ addrs, err := iface.Addrs()
+ if err != nil {
+ return nil, err
+ }
+ return GetExternalIPv4Addrs(addrs)
+}
+
// GetExternalIPv4Addrs obtains the currently-configured, non-loopback IPv4
// addresses from `addrs` coming from a particular interface (e.g.
// net.Interface.Addrs).
@@ -118,6 +131,17 @@ 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) {
+ iface, err := net.InterfaceByName(ifname)
+ if err != nil {
+ return nil, err
+ }
+ return NewDiscovery(iface.HardwareAddr)
+}
+
// NewDiscovery builds a new DHCPv4 Discovery message, with a default Ethernet
// HW type and specified hardware address.
func NewDiscovery(hwaddr net.HardwareAddr) (*DHCPv4, error) {
@@ -143,6 +167,34 @@ func NewDiscovery(hwaddr net.HardwareAddr) (*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) {
+ // get hw addr
+ iface, err := net.InterfaceByName(ifname)
+ if err != nil {
+ return nil, err
+ }
+
+ // 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)
+ }
+ pkt, err := NewInform(iface.HardwareAddr, localIPs[0])
+ if err != nil {
+ return nil, err
+ }
+
+ if needsBroadcast {
+ pkt.SetBroadcast()
+ } else {
+ pkt.SetUnicast()
+ }
+ return pkt, nil
+}
+
// 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.