func rst(srcIP net.IP, dstIP net.IP, srcPort uint16, dstPort uint16, seq uint32, ack uint32, payloadLen uint32) *tcpPacket { iphdr := packet.NewIPv4() tcphdr := packet.NewTCP() iphdr.Version = 4 iphdr.DstIP = srcIP iphdr.SrcIP = dstIP iphdr.TTL = 64 iphdr.Protocol = packet.IPProtocolTCP tcphdr.DstPort = srcPort tcphdr.SrcPort = dstPort tcphdr.Window = uint16(MAX_RECV_WINDOW) tcphdr.RST = true tcphdr.ACK = true tcphdr.Seq = 0 // RFC 793: // "If the incoming segment has an ACK field, the reset takes its sequence // number from the ACK field of the segment, otherwise the reset has // sequence number zero and the ACK field is set to the sum of the sequence // number and segment length of the incoming segment. The connection remains // in the CLOSED state." tcphdr.Ack = seq + payloadLen if tcphdr.Ack == seq { tcphdr.Ack += 1 } if ack != 0 { tcphdr.Seq = ack } return packTCP(iphdr, tcphdr) }
func (tt *tcpConnTrack) synAck(syn *tcpPacket) { iphdr := packet.NewIPv4() tcphdr := packet.NewTCP() iphdr.Version = 4 iphdr.SrcIP = tt.remoteIP iphdr.DstIP = tt.localIP iphdr.TTL = 64 iphdr.Protocol = packet.IPProtocolTCP tcphdr.SrcPort = tt.remotePort tcphdr.DstPort = tt.localPort tcphdr.Window = uint16(atomic.LoadInt32(&tt.recvWindow)) tcphdr.SYN = true tcphdr.ACK = true tcphdr.Seq = tt.nxtSeq tcphdr.Ack = tt.rcvNxtSeq tcphdr.Options = []packet.TCPOption{{2, 4, []byte{0x5, 0xb4}}} synAck := packTCP(iphdr, tcphdr) tt.send(synAck) // SYN counts 1 seq tt.nxtSeq += 1 }
func (tt *tcpConnTrack) ack() { iphdr := packet.NewIPv4() tcphdr := packet.NewTCP() iphdr.Version = 4 iphdr.SrcIP = tt.remoteIP iphdr.DstIP = tt.localIP iphdr.TTL = 64 iphdr.Protocol = packet.IPProtocolTCP tcphdr.SrcPort = tt.remotePort tcphdr.DstPort = tt.localPort tcphdr.Window = uint16(atomic.LoadInt32(&tt.recvWindow)) tcphdr.ACK = true tcphdr.Seq = tt.nxtSeq tcphdr.Ack = tt.rcvNxtSeq ack := packTCP(iphdr, tcphdr) tt.send(ack) }
func (tt *tcpConnTrack) payload(data []byte) { iphdr := packet.NewIPv4() tcphdr := packet.NewTCP() iphdr.Version = 4 iphdr.SrcIP = tt.remoteIP iphdr.DstIP = tt.localIP iphdr.TTL = 64 iphdr.Protocol = packet.IPProtocolTCP tcphdr.SrcPort = tt.remotePort tcphdr.DstPort = tt.localPort tcphdr.Window = uint16(atomic.LoadInt32(&tt.recvWindow)) tcphdr.ACK = true tcphdr.PSH = true tcphdr.Seq = tt.nxtSeq tcphdr.Ack = tt.rcvNxtSeq tcphdr.Payload = data pkt := packTCP(iphdr, tcphdr) tt.send(pkt) // adjust seq tt.nxtSeq = tt.nxtSeq + uint32(len(data)) }
func copyTCPPacket(raw []byte, ip *packet.IPv4, tcp *packet.TCP) *tcpPacket { iphdr := packet.NewIPv4() tcphdr := packet.NewTCP() pkt := newTCPPacket() if len(tcp.Payload) == 0 { // shallow copy headers // for now, we don't need deep copy if no payload *iphdr = *ip *tcphdr = *tcp pkt.ip = iphdr pkt.tcp = tcphdr } else { // get a block of buffer, make a deep copy buf := newBuffer() n := copy(buf, raw) pkt.mtuBuf = buf pkt.wire = buf[:n] packet.ParseIPv4(pkt.wire, iphdr) packet.ParseTCP(iphdr.Payload, tcphdr) pkt.ip = iphdr pkt.tcp = tcphdr } return pkt }