summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorChristopher Koch <chrisko@google.com>2019-01-09 13:19:46 -0800
committerinsomniac <insomniacslk@users.noreply.github.com>2019-01-09 23:54:01 +0000
commitdf450f2899aa103d7c754ff17df05afe74a9f462 (patch)
tree63026988bdf7efad97d9f1897110bfae9b23aa3c
parent2439a850c766acf2d21501bf075b4dbeb6d7d295 (diff)
dhcpv4: introduce TransactionID type.
-rw-r--r--dhcpv4/async/client.go4
-rw-r--r--dhcpv4/dhcpv4.go32
-rw-r--r--dhcpv4/dhcpv4_test.go10
-rw-r--r--dhcpv4/modifiers.go2
-rw-r--r--dhcpv4/modifiers_test.go4
-rw-r--r--dhcpv4/server_test.go2
-rw-r--r--dhcpv4/types.go6
7 files changed, 30 insertions, 30 deletions
diff --git a/dhcpv4/async/client.go b/dhcpv4/async/client.go
index e6c7302..c37d249 100644
--- a/dhcpv4/async/client.go
+++ b/dhcpv4/async/client.go
@@ -34,7 +34,7 @@ type Client struct {
receiveQueue chan *dhcpv4.DHCPv4
sendQueue chan *dhcpv4.DHCPv4
packetsLock sync.Mutex
- packets map[uint32]*promise.Promise
+ packets map[dhcpv4.TransactionID]*promise.Promise
errors chan error
}
@@ -69,7 +69,7 @@ func (c *Client) Open(bufferSize int) error {
c.stopping = new(sync.WaitGroup)
c.sendQueue = make(chan *dhcpv4.DHCPv4, bufferSize)
c.receiveQueue = make(chan *dhcpv4.DHCPv4, bufferSize)
- c.packets = make(map[uint32]*promise.Promise)
+ c.packets = make(map[dhcpv4.TransactionID]*promise.Promise)
c.packetsLock = sync.Mutex{}
c.errors = make(chan error)
diff --git a/dhcpv4/dhcpv4.go b/dhcpv4/dhcpv4.go
index 2931565..4660dba 100644
--- a/dhcpv4/dhcpv4.go
+++ b/dhcpv4/dhcpv4.go
@@ -25,7 +25,7 @@ type DHCPv4 struct {
hwType iana.HwTypeType
hwAddrLen uint8
hopCount uint8
- transactionID uint32
+ transactionID TransactionID
numSeconds uint16
flags uint16
clientIPAddr net.IP
@@ -83,17 +83,13 @@ func GetExternalIPv4Addrs(addrs []net.Addr) ([]net.IP, error) {
// GenerateTransactionID generates a random 32-bits number suitable for use as
// TransactionID
-func GenerateTransactionID() (*uint32, error) {
- b := make([]byte, 4)
- n, err := rand.Read(b)
+func GenerateTransactionID() (TransactionID, error) {
+ var xid TransactionID
+ n, err := rand.Read(xid[:])
if n != 4 {
- return nil, errors.New("Invalid random sequence: smaller than 32 bits")
+ return xid, errors.New("invalid random sequence for transaction ID: smaller than 32 bits")
}
- if err != nil {
- return nil, err
- }
- tid := binary.LittleEndian.Uint32(b)
- return &tid, nil
+ return xid, err
}
// New creates a new DHCPv4 structure and fill it up with default values. It
@@ -101,7 +97,7 @@ func GenerateTransactionID() (*uint32, error) {
// See also NewDiscovery, NewOffer, NewRequest, NewAcknowledge, NewInform and
// NewRelease .
func New() (*DHCPv4, error) {
- tid, err := GenerateTransactionID()
+ xid, err := GenerateTransactionID()
if err != nil {
return nil, err
}
@@ -110,7 +106,7 @@ func New() (*DHCPv4, error) {
hwType: iana.HwTypeEthernet,
hwAddrLen: 6,
hopCount: 0,
- transactionID: *tid,
+ transactionID: xid,
numSeconds: 0,
flags: 0,
clientIPAddr: net.IPv4zero,
@@ -281,7 +277,6 @@ func FromBytes(data []byte) (*DHCPv4, error) {
hwType: iana.HwTypeType(data[1]),
hwAddrLen: data[2],
hopCount: data[3],
- transactionID: binary.BigEndian.Uint32(data[4:8]),
numSeconds: binary.BigEndian.Uint16(data[8:10]),
flags: binary.BigEndian.Uint16(data[10:12]),
clientIPAddr: net.IP(data[12:16]),
@@ -289,6 +284,7 @@ func FromBytes(data []byte) (*DHCPv4, error) {
serverIPAddr: net.IP(data[20:24]),
gatewayIPAddr: net.IP(data[24:28]),
}
+ copy(d.transactionID[:], data[4:8])
copy(d.clientHwAddr[:], data[28:44])
copy(d.serverHostName[:], data[44:108])
copy(d.bootFileName[:], data[108:236])
@@ -365,13 +361,13 @@ func (d *DHCPv4) SetHopCount(hopCount uint8) {
}
// TransactionID returns the transaction ID as 32 bit unsigned integer.
-func (d *DHCPv4) TransactionID() uint32 {
+func (d *DHCPv4) TransactionID() TransactionID {
return d.transactionID
}
// SetTransactionID sets the value for the transaction ID.
-func (d *DHCPv4) SetTransactionID(transactionID uint32) {
- d.transactionID = transactionID
+func (d *DHCPv4) SetTransactionID(xid TransactionID) {
+ d.transactionID = xid
}
// NumSeconds returns the number of seconds.
@@ -731,15 +727,13 @@ func (d *DHCPv4) IsOptionRequested(requested OptionCode) bool {
func (d *DHCPv4) ToBytes() []byte {
// This won't check if the End option is present, you've been warned
var ret []byte
- u32 := make([]byte, 4)
u16 := make([]byte, 2)
ret = append(ret, byte(d.opcode))
ret = append(ret, byte(d.hwType))
ret = append(ret, byte(d.hwAddrLen))
ret = append(ret, byte(d.hopCount))
- binary.BigEndian.PutUint32(u32, d.transactionID)
- ret = append(ret, u32...)
+ ret = append(ret, d.transactionID[:]...)
binary.BigEndian.PutUint16(u16, d.numSeconds)
ret = append(ret, u16...)
binary.BigEndian.PutUint16(u16, d.flags)
diff --git a/dhcpv4/dhcpv4_test.go b/dhcpv4/dhcpv4_test.go
index 283e728..2e5b8b0 100644
--- a/dhcpv4/dhcpv4_test.go
+++ b/dhcpv4/dhcpv4_test.go
@@ -65,7 +65,7 @@ func TestFromBytes(t *testing.T) {
require.Equal(t, d.HwType(), iana.HwTypeEthernet)
require.Equal(t, d.HwAddrLen(), byte(6))
require.Equal(t, d.HopCount(), byte(3))
- require.Equal(t, d.TransactionID(), uint32(0xaabbccdd))
+ require.Equal(t, d.TransactionID(), TransactionID{0xaa, 0xbb, 0xcc, 0xdd})
require.Equal(t, d.NumSeconds(), uint16(3))
require.Equal(t, d.Flags(), uint16(1))
require.True(t, d.ClientIPAddr().Equal(net.IPv4zero))
@@ -177,9 +177,9 @@ func TestSettersAndGetters(t *testing.T) {
require.Equal(t, uint8(1), d.HopCount())
// getter/setter for TransactionID
- require.Equal(t, uint32(0xaabbccdd), d.TransactionID())
- d.SetTransactionID(0xeeff0011)
- require.Equal(t, uint32(0xeeff0011), d.TransactionID())
+ require.Equal(t, TransactionID{0xaa, 0xbb, 0xcc, 0xdd}, d.TransactionID())
+ d.SetTransactionID(TransactionID{0xee, 0xff, 0x00, 0x11})
+ require.Equal(t, TransactionID{0xee, 0xff, 0x00, 0x11}, d.TransactionID())
// getter/setter for TransactionID
require.Equal(t, uint16(3), d.NumSeconds())
@@ -318,7 +318,7 @@ func TestNewToBytes(t *testing.T) {
require.NoError(t, err)
// fix TransactionID to match the expected one, since it's randomly
// generated in New()
- d.SetTransactionID(0x11223344)
+ d.SetTransactionID(TransactionID{0x11, 0x22, 0x33, 0x44})
got := d.ToBytes()
require.Equal(t, expected, got)
}
diff --git a/dhcpv4/modifiers.go b/dhcpv4/modifiers.go
index 033718e..ba58884 100644
--- a/dhcpv4/modifiers.go
+++ b/dhcpv4/modifiers.go
@@ -7,7 +7,7 @@ import (
)
// WithTransactionID sets the Transaction ID for the DHCPv4 packet
-func WithTransactionID(xid uint32) Modifier {
+func WithTransactionID(xid TransactionID) Modifier {
return func(d *DHCPv4) *DHCPv4 {
d.SetTransactionID(xid)
return d
diff --git a/dhcpv4/modifiers_test.go b/dhcpv4/modifiers_test.go
index f50e40b..d85d2e9 100644
--- a/dhcpv4/modifiers_test.go
+++ b/dhcpv4/modifiers_test.go
@@ -10,8 +10,8 @@ import (
func TestTransactionIDModifier(t *testing.T) {
d, err := New()
require.NoError(t, err)
- d = WithTransactionID(0xddccbbaa)(d)
- require.Equal(t, uint32(0xddccbbaa), d.TransactionID())
+ d = WithTransactionID(TransactionID{0xdd, 0xcc, 0xbb, 0xaa})(d)
+ require.Equal(t, TransactionID{0xdd, 0xcc, 0xbb, 0xaa}, d.TransactionID())
}
func TestBroadcastModifier(t *testing.T) {
diff --git a/dhcpv4/server_test.go b/dhcpv4/server_test.go
index 68bd694..454a113 100644
--- a/dhcpv4/server_test.go
+++ b/dhcpv4/server_test.go
@@ -113,7 +113,7 @@ func TestServerActivateAndServe(t *testing.T) {
require.NoError(t, err)
require.NotEqual(t, 0, len(ifaces))
- xid := uint32(0xaabbccdd)
+ xid := TransactionID{0xaa, 0xbb, 0xcc, 0xdd}
hwaddr := [16]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf}
modifiers := []Modifier{
diff --git a/dhcpv4/types.go b/dhcpv4/types.go
index 5919275..aea5caf 100644
--- a/dhcpv4/types.go
+++ b/dhcpv4/types.go
@@ -3,6 +3,12 @@ package dhcpv4
// values from http://www.networksorcery.com/enp/protocol/dhcp.htm and
// http://www.networksorcery.com/enp/protocol/bootp/options.htm
+// TransactionID represents a 4-byte DHCP transaction ID as defined in RFC 951,
+// Section 3.
+//
+// The TransactionID is used to match DHCP replies to their original request.
+type TransactionID [4]byte
+
// MessageType represents the possible DHCP message types - DISCOVER, OFFER, etc
type MessageType byte