MCPcopy Create free account
hub / github.com/SamNet-dev/snix / buildInjection

Function buildInjection

core/engine/packet.go:124–187  ·  view source on GitHub ↗

buildInjection constructs a fresh IPv4+TCP packet that mirrors the observed ACK closing the handshake but replaces the payload, sequence number, IP ident, and TCP flags per injectSpec. Returns a fully assembled packet. The IP checksum is always valid; the TCP checksum is valid unless spec.corruptCh

(ack pkt, spec injectSpec)

Source from the content-addressed store, hash-verified

122// is XOR'd with a fixed nonzero constant so the destination host drops the
123// packet while a checksum-agnostic DPI still parses it.
124func buildInjection(ack pkt, spec injectSpec) []byte {
125 seqNum := spec.seqNum
126 ipIDDelta := spec.ipIDDelta
127 setPSH := spec.setPSH
128 payload := spec.payload
129 // Minimal IPv4 (20 bytes) + minimal TCP (20 bytes) + payload. We
130 // deliberately drop TCP options from the injected packet — they are not
131 // required for DPI to parse the SNI and keep the packet small.
132 const ipHL, tcpHL = 20, 20
133 total := ipHL + tcpHL + len(payload)
134 out := make([]byte, total)
135
136 // IPv4 header.
137 out[0] = 0x45 // version 4, IHL 5
138 out[1] = 0x00 // DSCP/ECN
139 binary.BigEndian.PutUint16(out[2:4], uint16(total))
140 binary.BigEndian.PutUint16(out[4:6], ack.ident+ipIDDelta)
141 binary.BigEndian.PutUint16(out[6:8], 0x4000) // DF, no fragment
142 out[8] = 64 // TTL
143 out[9] = 6 // protocol TCP
144 // checksum at 10..12 left zero for now
145 copy(out[12:16], ack.srcIP[:])
146 copy(out[16:20], ack.dstIP[:])
147 ipCsum := checksum(out[0:ipHL])
148 binary.BigEndian.PutUint16(out[10:12], ipCsum)
149
150 // TCP header.
151 tcp := out[ipHL:]
152 binary.BigEndian.PutUint16(tcp[0:2], ack.srcPort)
153 binary.BigEndian.PutUint16(tcp[2:4], ack.dstPort)
154 binary.BigEndian.PutUint32(tcp[4:8], seqNum)
155 binary.BigEndian.PutUint32(tcp[8:12], ack.ackNum)
156 tcp[12] = (tcpHL / 4) << 4
157 flags := uint8(flagACK)
158 if setPSH {
159 flags |= flagPSH
160 }
161 tcp[13] = flags
162 binary.BigEndian.PutUint16(tcp[14:16], 0x0800) // window — matches common Linux default
163 // checksum placeholder at 16:18
164 // urgent pointer at 18:20 = 0
165 copy(tcp[tcpHL:], payload)
166
167 // TCP checksum: pseudo-header + TCP header + payload.
168 var psh [12]byte
169 copy(psh[0:4], ack.srcIP[:])
170 copy(psh[4:8], ack.dstIP[:])
171 psh[8] = 0
172 psh[9] = 6
173 binary.BigEndian.PutUint16(psh[10:12], uint16(tcpHL+len(payload)))
174
175 tcpCsum := checksumMany(psh[:], tcp[:tcpHL+len(payload)])
176 if spec.corruptChecksum {
177 // Flip several bits so recomputation by an aggressive middlebox can't
178 // accidentally match. 0xBEEF is distinctive in captures for debugging.
179 tcpCsum ^= 0xBEEF
180 if tcpCsum == 0 {
181 tcpCsum = 0x1234 // 0 means "no checksum"; avoid it.

Callers 2

scheduleInjectMethod · 0.85

Calls 2

checksumFunction · 0.85
checksumManyFunction · 0.85

Tested by 1