TestBuildInjectionChecksums verifies both IP and TCP checksums are valid and the TCP mutation fields land in the right bytes.
(t *testing.T)
| 86 | // TestBuildInjectionChecksums verifies both IP and TCP checksums are valid |
| 87 | // and the TCP mutation fields land in the right bytes. |
| 88 | func TestBuildInjectionChecksums(t *testing.T) { |
| 89 | src := [4]byte{10, 0, 0, 1} |
| 90 | dst := [4]byte{1, 1, 1, 1} |
| 91 | ackRaw := synPacket(src, dst, 40000, 443, 0xABC) |
| 92 | // Promote it to an ACK for the test. |
| 93 | ackRaw[ackRaw[0]&0x0f*4+13] = flagACK |
| 94 | ack, err := parse(ackRaw) |
| 95 | if err != nil { |
| 96 | t.Fatal(err) |
| 97 | } |
| 98 | payload := []byte("HELLO-WORLD-FAKE-CLIENT-HELLO") |
| 99 | inj := buildInjection(ack, injectSpec{ |
| 100 | seqNum: 0x12345678, ipIDDelta: 1, setPSH: true, payload: payload, |
| 101 | }) |
| 102 | |
| 103 | // IP checksum must verify to zero. |
| 104 | if checksum(inj[:20]) != 0 { |
| 105 | t.Fatalf("IP checksum invalid: %#x", checksum(inj[:20])) |
| 106 | } |
| 107 | |
| 108 | // TCP checksum must verify over pseudo-header + TCP + payload. |
| 109 | var psh [12]byte |
| 110 | copy(psh[0:4], src[:]) |
| 111 | copy(psh[4:8], dst[:]) |
| 112 | psh[9] = 6 |
| 113 | binary.BigEndian.PutUint16(psh[10:12], uint16(20+len(payload))) |
| 114 | if checksumMany(psh[:], inj[20:]) != 0 { |
| 115 | t.Fatalf("TCP checksum invalid") |
| 116 | } |
| 117 | |
| 118 | // Verify mutated fields. |
| 119 | injp, err := parse(inj) |
| 120 | if err != nil { |
| 121 | t.Fatal(err) |
| 122 | } |
| 123 | if injp.seqNum != 0x12345678 { |
| 124 | t.Errorf("seq: %#x", injp.seqNum) |
| 125 | } |
| 126 | if injp.flags&flagPSH == 0 || injp.flags&flagACK == 0 { |
| 127 | t.Errorf("flags: %#x", injp.flags) |
| 128 | } |
| 129 | if injp.ident != 0x1234+1 { |
| 130 | t.Errorf("ident: %#x", injp.ident) |
| 131 | } |
| 132 | if string(injp.payload) != string(payload) { |
| 133 | t.Errorf("payload mismatch") |
| 134 | } |
| 135 | } |
nothing calls this directly
no test coverage detected