github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/pkg/tcpip/header/igmp_test.go (about) 1 // Copyright 2020 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package header_test 16 17 import ( 18 "testing" 19 "time" 20 21 "github.com/SagerNet/gvisor/pkg/tcpip/header" 22 "github.com/SagerNet/gvisor/pkg/tcpip/testutil" 23 ) 24 25 // TestIGMPHeader tests the functions within header.igmp 26 func TestIGMPHeader(t *testing.T) { 27 const maxRespTimeTenthSec = 0xF0 28 b := []byte{ 29 0x11, // IGMP Type, Membership Query 30 maxRespTimeTenthSec, // Maximum Response Time 31 0xC0, 0xC0, // Checksum 32 0x01, 0x02, 0x03, 0x04, // Group Address 33 } 34 35 igmpHeader := header.IGMP(b) 36 37 if got, want := igmpHeader.Type(), header.IGMPMembershipQuery; got != want { 38 t.Errorf("got igmpHeader.Type() = %x, want = %x", got, want) 39 } 40 41 if got, want := igmpHeader.MaxRespTime(), header.DecisecondToDuration(maxRespTimeTenthSec); got != want { 42 t.Errorf("got igmpHeader.MaxRespTime() = %s, want = %s", got, want) 43 } 44 45 if got, want := igmpHeader.Checksum(), uint16(0xC0C0); got != want { 46 t.Errorf("got igmpHeader.Checksum() = %x, want = %x", got, want) 47 } 48 49 if got, want := igmpHeader.GroupAddress(), testutil.MustParse4("1.2.3.4"); got != want { 50 t.Errorf("got igmpHeader.GroupAddress() = %s, want = %s", got, want) 51 } 52 53 igmpType := header.IGMPv2MembershipReport 54 igmpHeader.SetType(igmpType) 55 if got := igmpHeader.Type(); got != igmpType { 56 t.Errorf("got igmpHeader.Type() = %x, want = %x", got, igmpType) 57 } 58 if got := header.IGMPType(b[0]); got != igmpType { 59 t.Errorf("got IGMPtype in backing buffer = %x, want %x", got, igmpType) 60 } 61 62 respTime := byte(0x02) 63 igmpHeader.SetMaxRespTime(respTime) 64 if got, want := igmpHeader.MaxRespTime(), header.DecisecondToDuration(respTime); got != want { 65 t.Errorf("got igmpHeader.MaxRespTime() = %s, want = %s", got, want) 66 } 67 68 checksum := uint16(0x0102) 69 igmpHeader.SetChecksum(checksum) 70 if got := igmpHeader.Checksum(); got != checksum { 71 t.Errorf("got igmpHeader.Checksum() = %x, want = %x", got, checksum) 72 } 73 74 groupAddress := testutil.MustParse4("4.3.2.1") 75 igmpHeader.SetGroupAddress(groupAddress) 76 if got := igmpHeader.GroupAddress(); got != groupAddress { 77 t.Errorf("got igmpHeader.GroupAddress() = %s, want = %s", got, groupAddress) 78 } 79 } 80 81 // TestIGMPChecksum ensures that the checksum calculator produces the expected 82 // checksum. 83 func TestIGMPChecksum(t *testing.T) { 84 b := []byte{ 85 0x11, // IGMP Type, Membership Query 86 0xF0, // Maximum Response Time 87 0xC0, 0xC0, // Checksum 88 0x01, 0x02, 0x03, 0x04, // Group Address 89 } 90 91 igmpHeader := header.IGMP(b) 92 93 // Calculate the initial checksum after setting the checksum temporarily to 0 94 // to avoid checksumming the checksum. 95 initialChecksum := igmpHeader.Checksum() 96 igmpHeader.SetChecksum(0) 97 checksum := ^header.Checksum(b, 0) 98 igmpHeader.SetChecksum(initialChecksum) 99 100 if got := header.IGMPCalculateChecksum(igmpHeader); got != checksum { 101 t.Errorf("got IGMPCalculateChecksum = %x, want %x", got, checksum) 102 } 103 } 104 105 func TestDecisecondToDuration(t *testing.T) { 106 const valueInDeciseconds = 5 107 if got, want := header.DecisecondToDuration(valueInDeciseconds), valueInDeciseconds*time.Second/10; got != want { 108 t.Fatalf("got header.DecisecondToDuration(%d) = %s, want = %s", valueInDeciseconds, got, want) 109 } 110 }