diff options
author | Christopher Koch <chrisko@google.com> | 2019-01-09 13:19:46 -0800 |
---|---|---|
committer | insomniac <insomniacslk@users.noreply.github.com> | 2019-01-09 23:54:01 +0000 |
commit | df450f2899aa103d7c754ff17df05afe74a9f462 (patch) | |
tree | 63026988bdf7efad97d9f1897110bfae9b23aa3c | |
parent | 2439a850c766acf2d21501bf075b4dbeb6d7d295 (diff) |
dhcpv4: introduce TransactionID type.
-rw-r--r-- | dhcpv4/async/client.go | 4 | ||||
-rw-r--r-- | dhcpv4/dhcpv4.go | 32 | ||||
-rw-r--r-- | dhcpv4/dhcpv4_test.go | 10 | ||||
-rw-r--r-- | dhcpv4/modifiers.go | 2 | ||||
-rw-r--r-- | dhcpv4/modifiers_test.go | 4 | ||||
-rw-r--r-- | dhcpv4/server_test.go | 2 | ||||
-rw-r--r-- | dhcpv4/types.go | 6 |
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 |