ODPM 266: Go-libmemif + 2 examples.
[govpp.git] / vendor / github.com / google / gopacket / layers / ip4_test.go
1 // Copyright 2012 Google, Inc. All rights reserved.
2 //
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
5 // tree.
6
7 // This file tests some of the functionality provided in the ip4.go
8
9 package layers
10
11 import (
12         "encoding/binary"
13         "encoding/hex"
14         "net"
15         "testing"
16
17         "github.com/google/gopacket"
18 )
19
20 // Test the function getIPv4OptionSize when the ipv4 has no options
21 func TestGetIPOptLengthNoOpt(t *testing.T) {
22         ip := IPv4{}
23         length := ip.getIPv4OptionSize()
24         if length != 0 {
25                 t.Fatalf("Empty option list should have 0 length.  Actual %d", length)
26         }
27 }
28
29 // Test the function getIPv4OptionSize when the ipv4 has end of list option
30 func TestGetIPOptLengthEndOfList(t *testing.T) {
31         ip := IPv4{}
32         ip.Options = append(ip.Options, IPv4Option{OptionType: 0, OptionLength: 1})
33         length := ip.getIPv4OptionSize()
34         if length != 4 {
35                 t.Fatalf("After padding, the list should have 4 length.  Actual %d", length)
36         }
37 }
38
39 // Test the function getIPv4OptionSize when the ipv4 has padding and end of list option
40 func TestGetIPOptLengthPaddingEndOfList(t *testing.T) {
41         ip := IPv4{}
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()
45         if length != 4 {
46                 t.Fatalf("After padding, the list should have 4 length.  Actual %d", length)
47         }
48 }
49
50 // Test the function getIPv4OptionSize when the ipv4 has some non-trivial option and end of list option
51 func TestGetIPOptLengthOptionEndOfList(t *testing.T) {
52         ip := IPv4{}
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()
57         if length != 12 {
58                 t.Fatalf("The list should have 12 length.  Actual %d", length)
59         }
60 }
61
62 // Tests that the Options slice is properly reset before parsing new data
63 func TestIPOptResetDuringDecoding(t *testing.T) {
64         ip := &IPv4{
65                 Options: []IPv4Option{{OptionType: 42, OptionLength: 4, OptionData: make([]byte, 2)}},
66         }
67
68         ipWithoutOptions := &IPv4{
69                 SrcIP:    net.IPv4(192, 168, 1, 1),
70                 DstIP:    net.IPv4(192, 168, 1, 1),
71                 Protocol: IPProtocolTCP,
72         }
73
74         ipBytes, err := serialize(ipWithoutOptions)
75
76         if err != nil {
77                 t.Fatalf("Failed to serialize ip layer: %v", err)
78         }
79
80         err = ip.DecodeFromBytes(ipBytes, gopacket.NilDecodeFeedback)
81
82         if err != nil {
83                 t.Fatalf("Failed to deserialize ip layer: %v", err)
84         }
85
86         if len(ip.Options) > 0 {
87                 t.Fatalf("Options slice has stale data from previous packet")
88         }
89
90 }
91
92 func serialize(ip *IPv4) ([]byte, error) {
93         buffer := gopacket.NewSerializeBuffer()
94         err := ip.SerializeTo(buffer, gopacket.SerializeOptions{
95                 FixLengths:       true,
96                 ComputeChecksums: true,
97         })
98         return buffer.Bytes(), err
99 }
100
101 // Test the function checksum
102 func TestChecksum(t *testing.T) {
103         testData := []struct {
104                 name   string
105                 header string
106                 want   string
107         }{{
108                 name:   "sum has two carries",
109                 header: "4540005800000000ff11ffff0aeb1d070aed8877",
110                 want:   "fffe",
111         }, {
112                 name:   "wikipedia case",
113                 header: "45000073000040004011b861c0a80001c0a800c7",
114                 want:   "b861",
115         }}
116
117         for _, test := range testData {
118                 bytes, err := hex.DecodeString(test.header)
119                 if err != nil {
120                         t.Fatalf("Failed to Decode header: %v", err)
121                 }
122                 wantBytes, err := hex.DecodeString(test.want)
123                 if err != nil {
124                         t.Fatalf("Failed to decode want checksum: %v", err)
125                 }
126
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)
129                 }
130         }
131 }