Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions packet/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ const (
// IANAProtoICMP is IANA Internet Control Message number
IANAProtoICMP = 1

// IANAProtoIPIP is IANA User Datagram number
IANAProtoIPIP = 4

// IANAProtoTCP is IANA Transmission Control number
IANAProtoTCP = 6

Expand Down Expand Up @@ -123,6 +126,15 @@ func (p *Packet) decodeNextLayer() error {

p.L4 = udp
len = 8

case IANAProtoIPIP:
ipip, err := decodeIPIP(p.data)
if err != nil {
return err
}

p.L4 = ipip
len = 40
default:
return errUnknownTransportLayer
}
Expand Down
61 changes: 58 additions & 3 deletions packet/transport.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@

package packet

import "errors"
import (
"errors"
"net"
)

// TCPHeader represents TCP header
type TCPHeader struct {
Expand All @@ -39,9 +42,30 @@ type UDPHeader struct {
DstPort int
}

// IPIPHeader represents IPIP header
type IPIPHeader struct {
InnerVersion int
InnerTOS int
InnerTotalLen int
InnerID int
InnerFlags int
InnerFragOff int
InnerTTL int
InnerProtocol int
InnerChecksum int
InnerSrc string
InnerDst string
SrcPort int
DstPort int
DataOffset int
Reserved int
Flags int
}

var (
errShortTCPHeaderLength = errors.New("short TCP header length")
errShortUDPHeaderLength = errors.New("short UDP header length")
errShortTCPHeaderLength = errors.New("short TCP header length")
errShortUDPHeaderLength = errors.New("short UDP header length")
errShortIPIPHeaderLength = errors.New("short IPIP header length")
)

func decodeTCP(b []byte) (TCPHeader, error) {
Expand All @@ -68,3 +92,34 @@ func decodeUDP(b []byte) (UDPHeader, error) {
DstPort: int(b[2])<<8 | int(b[3]),
}, nil
}

func decodeIPIP(b []byte) (IPIPHeader, error) {
if len(b) < 40 {
return IPIPHeader{}, errShortIPIPHeaderLength
}

var (
src net.IP = b[12:16]
dst net.IP = b[16:20]
)

ipipHeader := IPIPHeader{
InnerVersion: int(b[0] & 0xf0 >> 4),
InnerTOS: int(b[1]),
InnerTotalLen: int(b[2])<<8 | int(b[3]),
InnerID: int(b[4])<<8 | int(b[5]),
InnerFlags: int(b[6] & 0x07),
InnerTTL: int(b[8]),
InnerProtocol: int(b[9]),
InnerChecksum: int(b[10])<<8 | int(b[11]),
InnerSrc: src.String(),
InnerDst: dst.String(),
SrcPort: int(b[20])<<8 | int(b[21]),
DstPort: int(b[22])<<8 | int(b[23]),
DataOffset: int(b[32]) >> 4,
Reserved: 0,
Flags: ((int(b[32])<<8 | int(b[33])) & 0x01ff),
}

return ipipHeader, nil
}