1// Copyright 2017 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//****************************************************************************** 8 9package layers 10 11import ( 12 "github.com/google/gopacket" 13 "reflect" 14 "testing" 15) 16 17//****************************************************************************** 18 19// checkBFD() uses the bfd.go code to analyse the packet bytes as an BFD Control 20// packet and generate an BFD object. It then compares the generated BFD object 21// with the one provided and throws an error if there is any difference. 22// The desc argument is output with any failure message to identify the test. 23func checkBFD(desc string, t *testing.T, packetBytes []byte, pExpectedBFD *BFD) { 24 25 // Analyse the packet bytes, yielding a new packet object p. 26 p := gopacket.NewPacket(packetBytes, LinkTypeEthernet, gopacket.Default) 27 if p.ErrorLayer() != nil { 28 t.Errorf("Failed to decode packet %s: %v", desc, p.ErrorLayer().Error()) 29 } 30 31 // Ensure that the packet analysis yielded the correct set of layers: 32 // Link Layer = Ethernet. 33 // Network Layer = IPv4. 34 // Transport Layer = UDP. 35 // Application Layer = BFD. 36 checkLayers(p, []gopacket.LayerType{ 37 LayerTypeEthernet, 38 LayerTypeIPv4, 39 LayerTypeUDP, 40 LayerTypeBFD}, t) 41 42 // Select the Application (BFD) layer. 43 pResultBFD, ok := p.ApplicationLayer().(*BFD) 44 if !ok { 45 t.Error("No BFD layer type found in packet in " + desc + ".") 46 } 47 48 // Compare the generated BFD object with the expected BFD object. 49 if !reflect.DeepEqual(pResultBFD, pExpectedBFD) { 50 t.Errorf("BFD packet processing failed for packet "+desc+ 51 ":\ngot :\n%#v\n\nwant :\n%#v\n\n", pResultBFD, pExpectedBFD) 52 } 53 buf := gopacket.NewSerializeBuffer() 54 opts := gopacket.SerializeOptions{} 55 err := pResultBFD.SerializeTo(buf, opts) 56 if err != nil { 57 t.Error(err) 58 } 59 if !reflect.DeepEqual(pResultBFD.Contents, buf.Bytes()) { 60 t.Errorf("BFD packet serialization failed for packet "+desc+ 61 ":\ngot :\n%+v\n\nwant :\n%+v\n\n", buf.Bytes(), pResultBFD.Contents) 62 } 63 64} 65 66func TestBFDNoAuth(t *testing.T) { 67 // This test packet is based off of the first BFD packet in the BFD sample capture 68 // pcap file bfd-raw-auth-simple.pcap on the Wireshark sample captures page: 69 // 70 // https://wiki.wireshark.org/SampleCaptures 71 // https://wiki.wireshark.org/SampleCaptures?action=AttachFile&do=get&target=bfd-raw-auth-simple.pcap 72 // 73 // Changed to remove the authentication header, and adjust all of the lengths 74 var testPacketBFD = []byte{ 75 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x10, 0x94, 0x00, 0x00, 0x02, 0x08, 0x00, 0x45, 0x00, 76 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x11, 0x2f, 0x58, 0xc0, 0x55, 0x01, 0x02, 0xc0, 0x00, 77 0x00, 0x01, 0xc0, 0x00, 0x0e, 0xc8, 0x00, 0x20, 0x72, 0x31, 0x20, 0x40, 0x05, 0x18, 0x00, 0x00, 78 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x42, 0x40, 0x00, 0x0f, 0x42, 0x40, 0x00, 0x00, 79 0x00, 0x00, 0x01, 0x4e, 0x0a, 0x90, 0x40, 80 } 81 82 // Assemble the BFD object that we expect to emerge from this test. 83 pExpectedBFD := &BFD{ 84 BaseLayer: BaseLayer{ 85 Contents: []byte{ 86 0x20, 0x40, 0x05, 0x18, 0x00, 0x00, 0x00, 0x01, 87 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x42, 0x40, 88 0x00, 0x0f, 0x42, 0x40, 0x00, 0x00, 0x00, 0x00, 89 }, 90 Payload: nil, 91 }, 92 Version: 1, 93 Diagnostic: BFDDiagnosticNone, 94 State: BFDStateDown, 95 Poll: false, 96 Final: false, 97 ControlPlaneIndependent: false, 98 AuthPresent: false, 99 Demand: false, 100 Multipoint: false, 101 DetectMultiplier: 5, 102 MyDiscriminator: 1, 103 YourDiscriminator: 0, 104 DesiredMinTxInterval: 1000000, 105 RequiredMinRxInterval: 1000000, 106 RequiredMinEchoRxInterval: 0, 107 AuthHeader: nil, 108 } 109 110 checkBFD("testNoAuth", t, testPacketBFD, pExpectedBFD) 111} 112 113//****************************************************************************** 114 115func TestBFDAuthTypePassword(t *testing.T) { 116 117 // This test packet is the first BFD packet in the BFD sample capture 118 // pcap file bfd-raw-auth-simple.pcap on the Wireshark sample captures page: 119 // 120 // https://wiki.wireshark.org/SampleCaptures 121 // https://wiki.wireshark.org/SampleCaptures?action=AttachFile&do=get&target=bfd-raw-auth-simple.pcap 122 var testPacketBFD = []byte{ 123 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x10, 0x94, 0x00, 0x00, 0x02, 0x08, 0x00, 0x45, 0x00, 124 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x11, 0x2f, 0x58, 0xc0, 0x55, 0x01, 0x02, 0xc0, 0x00, 125 0x00, 0x01, 0xc0, 0x00, 0x0e, 0xc8, 0x00, 0x29, 0x72, 0x31, 0x20, 0x44, 0x05, 0x21, 0x00, 0x00, 126 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x42, 0x40, 0x00, 0x0f, 0x42, 0x40, 0x00, 0x00, 127 0x00, 0x00, 0x01, 0x09, 0x02, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x4e, 0x0a, 0x90, 0x40, 128 } 129 130 // Assemble the BFD object that we expect to emerge from this test. 131 pExpectedBFD := &BFD{ 132 BaseLayer: BaseLayer{ 133 Contents: []byte{ 134 0x20, 0x44, 0x05, 0x21, 0x00, 0x00, 0x00, 0x01, 135 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x42, 0x40, 136 0x00, 0x0f, 0x42, 0x40, 0x00, 0x00, 0x00, 0x00, 137 0x01, 0x09, 0x02, 0x73, 0x65, 0x63, 0x72, 0x65, 138 0x74, 139 }, 140 Payload: nil, 141 }, 142 Version: 1, 143 Diagnostic: BFDDiagnosticNone, 144 State: BFDStateDown, 145 Poll: false, 146 Final: false, 147 ControlPlaneIndependent: false, 148 AuthPresent: true, 149 Demand: false, 150 Multipoint: false, 151 DetectMultiplier: 5, 152 MyDiscriminator: 1, 153 YourDiscriminator: 0, 154 DesiredMinTxInterval: 1000000, 155 RequiredMinRxInterval: 1000000, 156 RequiredMinEchoRxInterval: 0, 157 AuthHeader: &BFDAuthHeader{ 158 AuthType: BFDAuthTypePassword, 159 KeyID: 2, 160 SequenceNumber: 0, 161 Data: []byte{'s', 'e', 'c', 'r', 'e', 't'}, 162 }, 163 } 164 165 checkBFD("testBFDAuthTypePassword", t, testPacketBFD, pExpectedBFD) 166} 167 168//****************************************************************************** 169 170func TestBFDAuthTypeKeyedMD5(t *testing.T) { 171 172 // This test packet is the first BFD packet in the BFD sample capture 173 // pcap file bfd-raw-auth-md5.pcap on the Wireshark sample captures page: 174 // 175 // https://wiki.wireshark.org/SampleCaptures 176 // https://wiki.wireshark.org/SampleCaptures?action=AttachFile&do=get&target=bfd-raw-auth-md5.pcap 177 var testPacketBFD = []byte{ 178 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x10, 0x94, 0x00, 0x00, 0x02, 0x08, 0x00, 0x45, 0x00, 179 0x00, 0x4c, 0x00, 0x01, 0x00, 0x00, 0x0a, 0x11, 0x2f, 0x48, 0xc0, 0x55, 0x01, 0x02, 0xc0, 0x00, 180 0x00, 0x01, 0x04, 0x00, 0x0e, 0xc8, 0x00, 0x38, 0x6a, 0xcc, 0x20, 0x44, 0x05, 0x30, 0x00, 0x00, 181 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x42, 0x40, 0x00, 0x0f, 0x42, 0x40, 0x00, 0x00, 182 0x00, 0x00, 0x02, 0x18, 0x02, 0x00, 0x00, 0x00, 0x00, 0x05, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 183 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x3c, 0xc3, 0xf8, 0x21, 184 } 185 186 // Assemble the BFD object that we expect to emerge from this test. 187 pExpectedBFD := &BFD{ 188 BaseLayer: BaseLayer{ 189 Contents: []byte{ 190 0x20, 0x44, 0x05, 0x30, 0x00, 0x00, 0x00, 0x01, 191 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x42, 0x40, 192 0x00, 0x0f, 0x42, 0x40, 0x00, 0x00, 0x00, 0x00, 193 0x02, 0x18, 0x02, 0x00, 0x00, 0x00, 0x00, 0x05, 194 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 195 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 196 }, 197 Payload: nil, 198 }, 199 Version: 1, 200 Diagnostic: BFDDiagnosticNone, 201 State: BFDStateDown, 202 Poll: false, 203 Final: false, 204 ControlPlaneIndependent: false, 205 AuthPresent: true, 206 Demand: false, 207 Multipoint: false, 208 DetectMultiplier: 5, 209 MyDiscriminator: 1, 210 YourDiscriminator: 0, 211 DesiredMinTxInterval: 1000000, 212 RequiredMinRxInterval: 1000000, 213 RequiredMinEchoRxInterval: 0, 214 AuthHeader: &BFDAuthHeader{ 215 AuthType: BFDAuthTypeKeyedMD5, 216 KeyID: 2, 217 SequenceNumber: 5, 218 Data: []byte{ 219 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 220 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 221 }, 222 }, 223 } 224 225 checkBFD("testBFDAuthTypeKeyedMD5", t, testPacketBFD, pExpectedBFD) 226} 227 228//****************************************************************************** 229 230func TestBFDAuthTypeMeticulousKeyedSHA1(t *testing.T) { 231 232 // This test packet is the first BFD packet in the BFD sample capture 233 // pcap file bfd-raw-auth-sha1.pcap on the Wireshark sample captures page: 234 // 235 // https://wiki.wireshark.org/SampleCaptures 236 // https://wiki.wireshark.org/SampleCaptures?action=AttachFile&do=get&target=bfd-raw-auth-sha1.pcap 237 var testPacketBFD = []byte{ 238 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x10, 0x94, 0x00, 0x00, 0x02, 0x08, 0x00, 0x45, 0x00, 239 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x11, 0x2f, 0x45, 0xc0, 0x55, 0x01, 0x02, 0xc0, 0x00, 240 0x00, 0x01, 0x04, 0x00, 0x0e, 0xc8, 0x00, 0x3c, 0x37, 0x8a, 0x20, 0x44, 0x05, 0x34, 0x00, 0x00, 241 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x42, 0x40, 0x00, 0x0f, 0x42, 0x40, 0x00, 0x00, 242 0x00, 0x00, 0x05, 0x1c, 0x02, 0x00, 0x00, 0x00, 0x00, 0x05, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 243 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0xea, 0x6d, 244 0x1f, 0x21, 245 } 246 247 // Assemble the BFD object that we expect to emerge from this test. 248 pExpectedBFD := &BFD{ 249 BaseLayer: BaseLayer{ 250 Contents: []byte{ 251 0x20, 0x44, 0x05, 0x34, 0x00, 0x00, 0x00, 0x01, 252 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x42, 0x40, 253 0x00, 0x0f, 0x42, 0x40, 0x00, 0x00, 0x00, 0x00, 254 0x05, 0x1c, 0x02, 0x00, 0x00, 0x00, 0x00, 0x05, 255 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 256 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 257 0x17, 0x18, 0x19, 0x1a, 258 }, 259 Payload: nil, 260 }, 261 Version: 1, 262 Diagnostic: BFDDiagnosticNone, 263 State: BFDStateDown, 264 Poll: false, 265 Final: false, 266 ControlPlaneIndependent: false, 267 AuthPresent: true, 268 Demand: false, 269 Multipoint: false, 270 DetectMultiplier: 5, 271 MyDiscriminator: 1, 272 YourDiscriminator: 0, 273 DesiredMinTxInterval: 1000000, 274 RequiredMinRxInterval: 1000000, 275 RequiredMinEchoRxInterval: 0, 276 AuthHeader: &BFDAuthHeader{ 277 AuthType: BFDAuthTypeMeticulousKeyedSHA1, 278 KeyID: 2, 279 SequenceNumber: 5, 280 Data: []byte{ 281 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 282 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 283 0x17, 0x18, 0x19, 0x1a, 284 }, 285 }, 286 } 287 288 checkBFD("TestBFDAuthTypeMeticulousKeyedSHA1", t, testPacketBFD, pExpectedBFD) 289} 290