diff options
-rw-r--r-- | dhcpv6/option_temporaryaddress.go | 4 | ||||
-rw-r--r-- | dhcpv6/option_temporaryaddress_test.go | 197 |
2 files changed, 129 insertions, 72 deletions
diff --git a/dhcpv6/option_temporaryaddress.go b/dhcpv6/option_temporaryaddress.go index 8ccbe7b..cc102a4 100644 --- a/dhcpv6/option_temporaryaddress.go +++ b/dhcpv6/option_temporaryaddress.go @@ -9,8 +9,8 @@ import ( // OptIATA implements the identity association for non-temporary addresses // option. // -// This module defines the OptIATA structure. -// https://www.ietf.org/rfc/rfc8415.txt +// This module defines the OptIATA structure, as defined by RFC 8415 Section +// 21.5. type OptIATA struct { IaId [4]byte Options IdentityOptions diff --git a/dhcpv6/option_temporaryaddress_test.go b/dhcpv6/option_temporaryaddress_test.go index 6d94f8f..673172a 100644 --- a/dhcpv6/option_temporaryaddress_test.go +++ b/dhcpv6/option_temporaryaddress_test.go @@ -1,71 +1,142 @@ package dhcpv6 import ( + "errors" + "fmt" "net" "reflect" "testing" "time" + "github.com/google/go-cmp/cmp" "github.com/stretchr/testify/require" + "github.com/u-root/uio/uio" ) -func TestParseMessageWithIATA(t *testing.T) { - data := []byte{ - 0, 4, // IATA option code - 0, 32, // length - 1, 0, 0, 0, // IAID - // IATA Options - 0, 5, 0, 0x18, 0x24, 1, 0xdb, 0, 0x30, 0x10, 0xc0, 0x8f, 0xfa, 0xce, 0, 0, 0, 0x44, 0, 0, // IP - 0, 0, 0, 2, // PreferredLifetime - 0, 0, 0, 4, // ValidLifetime - } - var got MessageOptions - if err := got.FromBytes(data); err != nil { - t.Errorf("FromBytes = %v", err) - } - - want := &OptIATA{ - IaId: [4]byte{1, 0, 0, 0}, - Options: IdentityOptions{Options: Options{&OptIAAddress{ - IPv6Addr: net.IP{0x24, 1, 0xdb, 0, 0x30, 0x10, 0xc0, 0x8f, 0xfa, 0xce, 0, 0, 0, 0x44, 0, 0}, - PreferredLifetime: 2 * time.Second, - ValidLifetime: 4 * time.Second, - Options: AddressOptions{Options: Options{}}, - }}}, - } - if gotIATA := got.OneIATA(); !reflect.DeepEqual(gotIATA, want) { - t.Errorf("OneIATA = %v, want %v", gotIATA, want) - } -} - -func TestOptIATAParseOptIATA(t *testing.T) { - data := []byte{ - 1, 0, 0, 0, // IAID - 0, 5, 0, 0x18, 0x24, 1, 0xdb, 0, 0x30, 0x10, 0xc0, 0x8f, 0xfa, 0xce, 0, 0, 0, 0x44, 0, 0, 0, 0, 0xb2, 0x7a, 0, 0, 0xc0, 0x8a, // options +func TestIATAParseAndGetter(t *testing.T) { + for i, tt := range []struct { + buf []byte + err error + want []*OptIATA + }{ + { + buf: []byte{ + 0, 4, // IATA option code + 0, 32, // length + 1, 0, 0, 0, // IAID + 0, 5, 0, 0x18, 0x24, 1, 0xdb, 0, 0x30, 0x10, 0xc0, 0x8f, 0xfa, 0xce, 0, 0, 0, 0x44, 0, 0, // IPv6 + 0, 0, 0, 2, // PreferredLifetime + 0, 0, 0, 4, // ValidLifetime + }, + want: []*OptIATA{ + &OptIATA{ + IaId: [4]byte{1, 0, 0, 0}, + Options: IdentityOptions{Options: Options{&OptIAAddress{ + IPv6Addr: net.IP{0x24, 1, 0xdb, 0, 0x30, 0x10, 0xc0, 0x8f, 0xfa, 0xce, 0, 0, 0, 0x44, 0, 0}, + PreferredLifetime: 2 * time.Second, + ValidLifetime: 4 * time.Second, + Options: AddressOptions{Options: Options{}}, + }}}, + }, + }, + }, + { + buf: []byte{ + 0, 4, // IATA option code + 0, 32, // length + 1, 0, 0, 0, // IAID + 0, 5, 0, 0x18, 0x24, 1, 0xdb, 0, 0x30, 0x10, 0xc0, 0x8f, 0xfa, 0xce, 0, 0, 0, 0x44, 0, 0, // IPv6 + 0, 0, 0, 2, // PreferredLifetime + 0, 0, 0, 4, // ValidLifetime + + 0, 4, // IATA option code + 0, 32, // length + 1, 2, 3, 4, // IAID + 0, 5, 0, 0x18, 0x24, 1, 0xdb, 0, 0x30, 0x10, 0xc0, 0x8f, 0xfa, 0xce, 0, 0, 0, 0x44, 0, 0, // IPv6 + 0, 0, 0, 2, // PreferredLifetime + 0, 0, 0, 4, // ValidLifetime + }, + want: []*OptIATA{ + &OptIATA{ + IaId: [4]byte{1, 0, 0, 0}, + Options: IdentityOptions{Options: Options{&OptIAAddress{ + IPv6Addr: net.IP{0x24, 1, 0xdb, 0, 0x30, 0x10, 0xc0, 0x8f, 0xfa, 0xce, 0, 0, 0, 0x44, 0, 0}, + PreferredLifetime: 2 * time.Second, + ValidLifetime: 4 * time.Second, + Options: AddressOptions{Options: Options{}}, + }}}, + }, + &OptIATA{ + IaId: [4]byte{1, 2, 3, 4}, + Options: IdentityOptions{Options: Options{&OptIAAddress{ + IPv6Addr: net.IP{0x24, 1, 0xdb, 0, 0x30, 0x10, 0xc0, 0x8f, 0xfa, 0xce, 0, 0, 0, 0x44, 0, 0}, + PreferredLifetime: 2 * time.Second, + ValidLifetime: 4 * time.Second, + Options: AddressOptions{Options: Options{}}, + }}}, + }, + }, + }, + + { + buf: nil, + want: nil, + }, + { + buf: []byte{0, 4, 0, 1, 0}, + want: nil, + err: uio.ErrBufferTooShort, + }, + { + buf: []byte{ + 0, 4, // IATA option code + 0, 3, // length + 1, 0, 0, // IAID too short + }, + want: nil, + err: uio.ErrBufferTooShort, + }, + { + buf: []byte{ + 0, 4, // IATA option code + 0, 28, // length + 1, 0, 0, 0, // IAID + 0, 5, 0, 0x18, 0x24, 1, 0xdb, 0, 0x30, 0x10, 0xc0, 0x8f, 0xfa, 0xce, 0, 0, 0, 0x44, 0, 0, // IPv6 + 0, 0, 0xb2, 0x7a, // PreferredLifetime + // Missing ValidLifetime + }, + want: nil, + err: uio.ErrBufferTooShort, + }, + } { + t.Run(fmt.Sprintf("%d", i), func(t *testing.T) { + var mo MessageOptions + if err := mo.FromBytes(tt.buf); !errors.Is(err, tt.err) { + t.Errorf("FromBytes = %v, want %v", err, tt.err) + } + if got := mo.IATA(); !reflect.DeepEqual(got, tt.want) { + t.Errorf("IATA = %v, want %v", got, tt.want) + } + var wantOne *OptIATA + if len(tt.want) >= 1 { + wantOne = tt.want[0] + } + if got := mo.OneIATA(); !reflect.DeepEqual(got, wantOne) { + t.Errorf("OneIATA = %v, want %v", got, wantOne) + } + + if len(tt.want) >= 1 { + var b MessageOptions + for _, iata := range tt.want { + b.Add(iata) + } + got := b.ToBytes() + if diff := cmp.Diff(tt.buf, got); diff != "" { + t.Errorf("ToBytes mismatch (-want, +got): %s", diff) + } + } + }) } - var opt OptIATA - err := opt.FromBytes(data) - require.NoError(t, err) - require.Equal(t, OptionIATA, opt.Code()) -} - -func TestOptIATAParseOptIATAInvalidLength(t *testing.T) { - data := []byte{ - 1, 0, 0, // truncated IAID - } - var opt OptIATA - err := opt.FromBytes(data) - require.Error(t, err) -} - -func TestOptIATAParseOptIATAInvalidOptions(t *testing.T) { - data := []byte{ - 1, 0, 0, 0, // IAID - 0, 5, 0, 0x18, 0x24, 1, 0xdb, 0, 0x30, 0x10, 0xc0, 0x8f, 0xfa, 0xce, 0, 0, 0, 0x44, 0, 0, 0, 0, 0xb2, 0x7a, // truncated options - } - var opt OptIATA - err := opt.FromBytes(data) - require.Error(t, err) } func TestOptIATAGetOneOption(t *testing.T) { @@ -120,20 +191,6 @@ func TestOptIATADelOption(t *testing.T) { require.Equal(t, iana2.Options.Options, Options{&optsc}) } -func TestOptIATAToBytes(t *testing.T) { - opt := OptIATA{ - IaId: [4]byte{1, 2, 3, 4}, - Options: IdentityOptions{[]Option{ - OptElapsedTime(10 * time.Millisecond), - }}, - } - expected := []byte{ - 1, 2, 3, 4, // IA ID - 0, 8, 0, 2, 0x00, 0x01, - } - require.Equal(t, expected, opt.ToBytes()) -} - func TestOptIATAString(t *testing.T) { data := []byte{ 1, 0, 0, 0, // IAID |