1 // Copyright 2012 Google, Inc. All rights reserved.
3 // Use of this source code is governed by a BSD-style license
4 // that can be found in the LICENSE file in the root of the source
7 // This file tests some of the functionality provided in the ip4.go
17 "github.com/google/gopacket"
20 // Test the function getIPv4OptionSize when the ipv4 has no options
21 func TestGetIPOptLengthNoOpt(t *testing.T) {
23 length := ip.getIPv4OptionSize()
25 t.Fatalf("Empty option list should have 0 length. Actual %d", length)
29 // Test the function getIPv4OptionSize when the ipv4 has end of list option
30 func TestGetIPOptLengthEndOfList(t *testing.T) {
32 ip.Options = append(ip.Options, IPv4Option{OptionType: 0, OptionLength: 1})
33 length := ip.getIPv4OptionSize()
35 t.Fatalf("After padding, the list should have 4 length. Actual %d", length)
39 // Test the function getIPv4OptionSize when the ipv4 has padding and end of list option
40 func TestGetIPOptLengthPaddingEndOfList(t *testing.T) {
42 ip.Options = append(ip.Options, IPv4Option{OptionType: 1, OptionLength: 1})
43 ip.Options = append(ip.Options, IPv4Option{OptionType: 0, OptionLength: 1})
44 length := ip.getIPv4OptionSize()
46 t.Fatalf("After padding, the list should have 4 length. Actual %d", length)
50 // Test the function getIPv4OptionSize when the ipv4 has some non-trivial option and end of list option
51 func TestGetIPOptLengthOptionEndOfList(t *testing.T) {
53 someByte := make([]byte, 8)
54 ip.Options = append(ip.Options, IPv4Option{OptionType: 2, OptionLength: 10, OptionData: someByte})
55 ip.Options = append(ip.Options, IPv4Option{OptionType: 0, OptionLength: 1})
56 length := ip.getIPv4OptionSize()
58 t.Fatalf("The list should have 12 length. Actual %d", length)
62 // Tests that the Options slice is properly reset before parsing new data
63 func TestIPOptResetDuringDecoding(t *testing.T) {
65 Options: []IPv4Option{{OptionType: 42, OptionLength: 4, OptionData: make([]byte, 2)}},
68 ipWithoutOptions := &IPv4{
69 SrcIP: net.IPv4(192, 168, 1, 1),
70 DstIP: net.IPv4(192, 168, 1, 1),
71 Protocol: IPProtocolTCP,
74 ipBytes, err := serialize(ipWithoutOptions)
77 t.Fatalf("Failed to serialize ip layer: %v", err)
80 err = ip.DecodeFromBytes(ipBytes, gopacket.NilDecodeFeedback)
83 t.Fatalf("Failed to deserialize ip layer: %v", err)
86 if len(ip.Options) > 0 {
87 t.Fatalf("Options slice has stale data from previous packet")
92 func serialize(ip *IPv4) ([]byte, error) {
93 buffer := gopacket.NewSerializeBuffer()
94 err := ip.SerializeTo(buffer, gopacket.SerializeOptions{
96 ComputeChecksums: true,
98 return buffer.Bytes(), err
101 // Test the function checksum
102 func TestChecksum(t *testing.T) {
103 testData := []struct {
108 name: "sum has two carries",
109 header: "4540005800000000ff11ffff0aeb1d070aed8877",
112 name: "wikipedia case",
113 header: "45000073000040004011b861c0a80001c0a800c7",
117 for _, test := range testData {
118 bytes, err := hex.DecodeString(test.header)
120 t.Fatalf("Failed to Decode header: %v", err)
122 wantBytes, err := hex.DecodeString(test.want)
124 t.Fatalf("Failed to decode want checksum: %v", err)
127 if got, want := checksum(bytes), binary.BigEndian.Uint16(wantBytes); got != want {
128 t.Errorf("In test %q, got incorrect checksum: got(%x), want(%x)", test.name, got, want)