diff options
-rw-r--r-- | dhcpv4/client.go | 6 | ||||
-rw-r--r-- | dhcpv4/dhcpv4.go | 52 |
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. |