diff options
Diffstat (limited to 'dhcpv4/dhcpv4.go')
-rw-r--r-- | dhcpv4/dhcpv4.go | 70 |
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 +} |