Add windowskext integration, update related packages

This commit is contained in:
Daniel
2019-04-26 11:33:24 +02:00
parent a702cd4824
commit 78a0b3c1fb
33 changed files with 979 additions and 690 deletions

View File

@@ -154,7 +154,7 @@ func GetCommunicationByFirstPacket(pkt packet.Packet) (*Communication, error) {
// Incoming
if direction {
switch netutils.ClassifyIP(pkt.GetIPHeader().Src) {
switch netutils.ClassifyIP(pkt.Info().Src) {
case netutils.HostLocal:
domain = IncomingHost
case netutils.LinkLocal, netutils.SiteLocal, netutils.LocalMulticast:
@@ -186,7 +186,7 @@ func GetCommunicationByFirstPacket(pkt packet.Packet) (*Communication, error) {
if err != nil {
// if no domain could be found, it must be a direct connection (ie. no DNS)
switch netutils.ClassifyIP(pkt.GetIPHeader().Dst) {
switch netutils.ClassifyIP(pkt.Info().Dst) {
case netutils.HostLocal:
domain = PeerHost
case netutils.LinkLocal, netutils.SiteLocal, netutils.LocalMulticast:

View File

@@ -3,6 +3,7 @@
package packet
import (
"errors"
"fmt"
"net"
)
@@ -43,6 +44,10 @@ const (
STOP
)
var (
ErrFailedToLoadPayload = errors.New("could not load packet payload")
)
// Returns the byte size of the ip, IPv4 = 4 bytes, IPv6 = 16
func (v IPVersion) ByteSize() int {
switch v {
@@ -92,58 +97,59 @@ func (v Verdict) String() string {
return fmt.Sprintf("<unsupported verdict, %d>", uint8(v))
}
type IPHeader struct {
Version IPVersion
// PacketInfo holds IP and TCP/UDP header information
type PacketInfo struct {
Direction bool
InTunnel bool
Tos, TTL uint8
Protocol IPProtocol
Src, Dst net.IP
}
type TCPUDPHeader struct {
Version IPVersion
Src, Dst net.IP
Protocol IPProtocol
SrcPort, DstPort uint16
Checksum uint16 //not implemented
}
type PacketBase struct {
linkID string
Direction bool
InTunnel bool
Payload []byte
*IPHeader
*TCPUDPHeader
info PacketInfo
linkID string
Payload []byte
}
func (pkt *PacketBase) GetIPHeader() *IPHeader {
return pkt.IPHeader
func (pkt *PacketBase) Info() *PacketInfo {
return &pkt.info
}
func (pkt *PacketBase) GetTCPUDPHeader() *TCPUDPHeader {
return pkt.TCPUDPHeader
}
func (pkt *PacketBase) GetPayload() []byte {
return pkt.Payload
func (pkt *PacketBase) SetPacketInfo(packetInfo PacketInfo) {
pkt.info = packetInfo
}
func (pkt *PacketBase) SetInbound() {
pkt.Direction = true
pkt.info.Direction = true
}
func (pkt *PacketBase) SetOutbound() {
pkt.Direction = false
pkt.info.Direction = false
}
func (pkt *PacketBase) IsInbound() bool {
return pkt.Direction
return pkt.info.Direction
}
func (pkt *PacketBase) IsOutbound() bool {
return !pkt.Direction
return !pkt.info.Direction
}
func (pkt *PacketBase) IPVersion() IPVersion {
return pkt.Version
func (pkt *PacketBase) HasPorts() bool {
switch pkt.info.Protocol {
case TCP:
return true
case UDP:
return true
}
return false
}
func (pkt *PacketBase) GetPayload() ([]byte, error) {
return pkt.Payload, ErrFailedToLoadPayload
}
func (pkt *PacketBase) GetLinkID() string {
@@ -154,82 +160,63 @@ func (pkt *PacketBase) GetLinkID() string {
}
func (pkt *PacketBase) createLinkID() {
if pkt.IPHeader.Protocol == TCP || pkt.IPHeader.Protocol == UDP {
if pkt.Direction {
pkt.linkID = fmt.Sprintf("%d-%s-%d-%s-%d", pkt.Protocol, pkt.Dst, pkt.DstPort, pkt.Src, pkt.SrcPort)
if pkt.info.Protocol == TCP || pkt.info.Protocol == UDP {
if pkt.info.Direction {
pkt.linkID = fmt.Sprintf("%d-%s-%d-%s-%d", pkt.info.Protocol, pkt.info.Dst, pkt.info.DstPort, pkt.info.Src, pkt.info.SrcPort)
} else {
pkt.linkID = fmt.Sprintf("%d-%s-%d-%s-%d", pkt.Protocol, pkt.Src, pkt.SrcPort, pkt.Dst, pkt.DstPort)
pkt.linkID = fmt.Sprintf("%d-%s-%d-%s-%d", pkt.info.Protocol, pkt.info.Src, pkt.info.SrcPort, pkt.info.Dst, pkt.info.DstPort)
}
} else {
if pkt.Direction {
pkt.linkID = fmt.Sprintf("%d-%s-%s", pkt.Protocol, pkt.Dst, pkt.Src)
if pkt.info.Direction {
pkt.linkID = fmt.Sprintf("%d-%s-%s", pkt.info.Protocol, pkt.info.Dst, pkt.info.Src)
} else {
pkt.linkID = fmt.Sprintf("%d-%s-%s", pkt.Protocol, pkt.Src, pkt.Dst)
pkt.linkID = fmt.Sprintf("%d-%s-%s", pkt.info.Protocol, pkt.info.Src, pkt.info.Dst)
}
}
}
// Matches checks if a the packet matches a given endpoint (remote or local) in protocol, network and port.
//
// Comparison matrix:
// IN OUT
// Local Dst Src
// Remote Src Dst
//
func (pkt *PacketBase) MatchesAddress(endpoint bool, protocol IPProtocol, network *net.IPNet, port uint16) bool {
if pkt.Protocol != protocol {
func (pkt *PacketBase) MatchesAddress(remote bool, protocol IPProtocol, network *net.IPNet, port uint16) bool {
if pkt.info.Protocol != protocol {
return false
}
if pkt.Direction != endpoint {
if !network.Contains(pkt.Src) {
if pkt.info.Direction != remote {
if !network.Contains(pkt.info.Src) {
return false
}
if port != 0 && pkt.TCPUDPHeader != nil {
if pkt.SrcPort != port {
return false
}
if pkt.info.SrcPort != port {
return false
}
} else {
if !network.Contains(pkt.Dst) {
if !network.Contains(pkt.info.Dst) {
return false
}
if port != 0 && pkt.TCPUDPHeader != nil {
if pkt.DstPort != port {
return false
}
if pkt.info.DstPort != port {
return false
}
}
return true
}
func (pkt *PacketBase) MatchesIP(endpoint bool, network *net.IPNet) bool {
if pkt.Direction != endpoint {
if network.Contains(pkt.Src) {
if pkt.info.Direction != endpoint {
if network.Contains(pkt.info.Src) {
return true
}
} else {
if network.Contains(pkt.Dst) {
if network.Contains(pkt.info.Dst) {
return true
}
}
return false
}
// func (pkt *PacketBase) Accept() error {
// return nil
// }
//
// func (pkt *PacketBase) Drop() error {
// return nil
// }
//
// func (pkt *PacketBase) Block() error {
// return nil
// }
//
// func (pkt *PacketBase) Verdict(verdict Verdict) error {
// return nil
// }
// FORMATTING
func (pkt *PacketBase) String() string {
@@ -238,45 +225,45 @@ func (pkt *PacketBase) String() string {
// FmtPacket returns the most important information about the packet as a string
func (pkt *PacketBase) FmtPacket() string {
if pkt.IPHeader.Protocol == TCP || pkt.IPHeader.Protocol == UDP {
if pkt.Direction {
return fmt.Sprintf("IN %s %s:%d <-> %s:%d", pkt.Protocol, pkt.Dst, pkt.DstPort, pkt.Src, pkt.SrcPort)
if pkt.info.Protocol == TCP || pkt.info.Protocol == UDP {
if pkt.info.Direction {
return fmt.Sprintf("IN %s %s:%d <-> %s:%d", pkt.info.Protocol, pkt.info.Dst, pkt.info.DstPort, pkt.info.Src, pkt.info.SrcPort)
}
return fmt.Sprintf("OUT %s %s:%d <-> %s:%d", pkt.Protocol, pkt.Src, pkt.SrcPort, pkt.Dst, pkt.DstPort)
return fmt.Sprintf("OUT %s %s:%d <-> %s:%d", pkt.info.Protocol, pkt.info.Src, pkt.info.SrcPort, pkt.info.Dst, pkt.info.DstPort)
}
if pkt.Direction {
return fmt.Sprintf("IN %s %s <-> %s", pkt.Protocol, pkt.Dst, pkt.Src)
if pkt.info.Direction {
return fmt.Sprintf("IN %s %s <-> %s", pkt.info.Protocol, pkt.info.Dst, pkt.info.Src)
}
return fmt.Sprintf("OUT %s %s <-> %s", pkt.Protocol, pkt.Src, pkt.Dst)
return fmt.Sprintf("OUT %s %s <-> %s", pkt.info.Protocol, pkt.info.Src, pkt.info.Dst)
}
// FmtProtocol returns the protocol as a string
func (pkt *PacketBase) FmtProtocol() string {
return pkt.IPHeader.Protocol.String()
return pkt.info.Protocol.String()
}
// FmtRemoteIP returns the remote IP address as a string
func (pkt *PacketBase) FmtRemoteIP() string {
if pkt.Direction {
return pkt.IPHeader.Src.String()
if pkt.info.Direction {
return pkt.info.Src.String()
}
return pkt.IPHeader.Dst.String()
return pkt.info.Dst.String()
}
// FmtRemotePort returns the remote port as a string
func (pkt *PacketBase) FmtRemotePort() string {
if pkt.TCPUDPHeader != nil {
if pkt.Direction {
return fmt.Sprintf("%d", pkt.TCPUDPHeader.SrcPort)
if pkt.info.SrcPort != 0 {
if pkt.info.Direction {
return fmt.Sprintf("%d", pkt.info.SrcPort)
}
return fmt.Sprintf("%d", pkt.TCPUDPHeader.DstPort)
return fmt.Sprintf("%d", pkt.info.DstPort)
}
return "-"
}
// FmtRemoteAddress returns the full remote address (protocol, IP, port) as a string
func (pkt *PacketBase) FmtRemoteAddress() string {
return fmt.Sprintf("%s:%s:%s", pkt.IPHeader.Protocol.String(), pkt.FmtRemoteIP(), pkt.FmtRemotePort())
return fmt.Sprintf("%s:%s:%s", pkt.info.Protocol.String(), pkt.FmtRemoteIP(), pkt.FmtRemotePort())
}
// Packet is an interface to a network packet to provide object behaviour the same across all systems
@@ -292,15 +279,15 @@ type Packet interface {
RerouteToTunnel() error
// INFO
GetIPHeader() *IPHeader
GetTCPUDPHeader() *TCPUDPHeader
GetPayload() []byte
Info() *PacketInfo
SetPacketInfo(PacketInfo)
IsInbound() bool
IsOutbound() bool
SetInbound()
SetOutbound()
HasPorts() bool
GetPayload() ([]byte, error)
GetLinkID() string
IPVersion() IPVersion
// MATCHING
MatchesAddress(bool, IPProtocol, *net.IPNet, uint16) bool

91
network/packet/parse.go Normal file
View File

@@ -0,0 +1,91 @@
package packet
import (
"errors"
"fmt"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
)
// Parse parses an IP packet and saves the information in the given packet object.
func Parse(packetData []byte, packet *PacketBase) error {
var parsedPacket gopacket.Packet
if len(packetData) == 0 {
return errors.New("empty packet")
}
switch packetData[0] >> 4 {
case 4:
parsedPacket = gopacket.NewPacket(packetData, layers.LayerTypeIPv4, gopacket.DecodeOptions{Lazy: true, NoCopy: true})
if ipv4Layer := parsedPacket.Layer(layers.LayerTypeIPv4); ipv4Layer != nil {
ipv4, _ := ipv4Layer.(*layers.IPv4)
packet.info.Version = IPv4
packet.info.Protocol = IPProtocol(ipv4.Protocol)
packet.info.Src = ipv4.SrcIP
packet.info.Dst = ipv4.DstIP
} else {
var err error
if errLayer := parsedPacket.ErrorLayer(); errLayer != nil {
err = errLayer.Error()
}
return fmt.Errorf("failed to parse IPv4 packet: %s", err)
}
case 6:
parsedPacket = gopacket.NewPacket(packetData, layers.LayerTypeIPv6, gopacket.DecodeOptions{Lazy: true, NoCopy: true})
if ipv6Layer := parsedPacket.Layer(layers.LayerTypeIPv6); ipv6Layer != nil {
ipv6, _ := ipv6Layer.(*layers.IPv6)
packet.info.Version = IPv6
packet.info.Protocol = IPProtocol(ipv6.NextHeader)
packet.info.Src = ipv6.SrcIP
packet.info.Dst = ipv6.DstIP
} else {
var err error
if errLayer := parsedPacket.ErrorLayer(); errLayer != nil {
err = errLayer.Error()
}
return fmt.Errorf("failed to parse IPv6 packet: %s", err)
}
default:
return errors.New("unknown IP version")
}
switch packet.info.Protocol {
case TCP:
if tcpLayer := parsedPacket.Layer(layers.LayerTypeTCP); tcpLayer != nil {
tcp, _ := tcpLayer.(*layers.TCP)
packet.info.SrcPort = uint16(tcp.SrcPort)
packet.info.DstPort = uint16(tcp.DstPort)
} else {
var err error
if errLayer := parsedPacket.ErrorLayer(); errLayer != nil {
err = errLayer.Error()
}
return fmt.Errorf("could not parse TCP layer: %s", err)
}
case UDP:
if udpLayer := parsedPacket.Layer(layers.LayerTypeUDP); udpLayer != nil {
udp, _ := udpLayer.(*layers.UDP)
packet.info.SrcPort = uint16(udp.SrcPort)
packet.info.DstPort = uint16(udp.DstPort)
} else {
var err error
if errLayer := parsedPacket.ErrorLayer(); errLayer != nil {
err = errLayer.Error()
}
return fmt.Errorf("could not parse UDP layer: %s", err)
}
}
if appLayer := parsedPacket.ApplicationLayer(); appLayer != nil {
packet.Payload = appLayer.Payload()
}
if errLayer := parsedPacket.ErrorLayer(); errLayer != nil {
return errLayer.Error()
}
return nil
}

View File

@@ -3,7 +3,7 @@
package network
// Verdict describes the decision made about a connection or link.
type Verdict uint8
type Verdict int8
// List of values a Status can have
const (

View File

@@ -16,7 +16,7 @@ const (
// GetUnknownCommunication returns the connection to a packet of unknown owner.
func GetUnknownCommunication(pkt packet.Packet) (*Communication, error) {
if pkt.IsInbound() {
switch netutils.ClassifyIP(pkt.GetIPHeader().Src) {
switch netutils.ClassifyIP(pkt.Info().Src) {
case netutils.HostLocal:
return getOrCreateUnknownCommunication(pkt, IncomingHost)
case netutils.LinkLocal, netutils.SiteLocal, netutils.LocalMulticast:
@@ -28,7 +28,7 @@ func GetUnknownCommunication(pkt packet.Packet) (*Communication, error) {
}
}
switch netutils.ClassifyIP(pkt.GetIPHeader().Dst) {
switch netutils.ClassifyIP(pkt.Info().Dst) {
case netutils.HostLocal:
return getOrCreateUnknownCommunication(pkt, PeerHost)
case netutils.LinkLocal, netutils.SiteLocal, netutils.LocalMulticast: