mirror of
https://github.com/evilsocket/opensnitch.git
synced 2025-03-04 08:34:40 +01:00
IPv6 support
This commit is contained in:
parent
c10e7a30c8
commit
22c4aca5d0
4 changed files with 120 additions and 46 deletions
|
@ -30,51 +30,65 @@ type Connection struct {
|
|||
|
||||
func Parse(nfp netfilter.Packet) *Connection {
|
||||
ipLayer := nfp.Packet.Layer(layers.LayerTypeIPv4)
|
||||
if ipLayer == nil {
|
||||
ipLayer6 := nfp.Packet.Layer(layers.LayerTypeIPv6)
|
||||
if ipLayer == nil && ipLayer6 == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
ip, ok := ipLayer.(*layers.IPv4)
|
||||
if ok == false || ip == nil {
|
||||
return nil
|
||||
}
|
||||
if (ipLayer == nil) {
|
||||
ip, ok := ipLayer6.(*layers.IPv6)
|
||||
if ok == false || ip == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// we're not interested in connections
|
||||
// from/to the localhost interface
|
||||
if ip.SrcIP.IsLoopback() {
|
||||
return nil
|
||||
}
|
||||
// we're not interested in connections
|
||||
// from/to the localhost interface
|
||||
if ip.SrcIP.IsLoopback() {
|
||||
return nil
|
||||
}
|
||||
|
||||
// skip multicast stuff
|
||||
if ip.SrcIP.IsMulticast() || ip.DstIP.IsMulticast() {
|
||||
return nil
|
||||
}
|
||||
// skip multicast stuff
|
||||
if ip.SrcIP.IsMulticast() || ip.DstIP.IsMulticast() {
|
||||
return nil
|
||||
}
|
||||
|
||||
// skip broadcasted stuff
|
||||
// FIXME: this is ugly
|
||||
if ip.DstIP[3] == 0xff {
|
||||
return nil
|
||||
}
|
||||
con, err := NewConnection6(&nfp, ip)
|
||||
if err != nil {
|
||||
log.Debug("%s", err)
|
||||
return nil
|
||||
} else if con == nil {
|
||||
return nil
|
||||
}
|
||||
return con
|
||||
} else {
|
||||
ip, ok := ipLayer.(*layers.IPv4)
|
||||
if ok == false || ip == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
con, err := NewConnection(&nfp, ip)
|
||||
if err != nil {
|
||||
log.Debug("%s", err)
|
||||
return nil
|
||||
} else if con == nil {
|
||||
return nil
|
||||
}
|
||||
// we're not interested in connections
|
||||
// from/to the localhost interface
|
||||
if ip.SrcIP.IsLoopback() {
|
||||
return nil
|
||||
}
|
||||
|
||||
return con
|
||||
// skip multicast stuff
|
||||
if ip.SrcIP.IsMulticast() || ip.DstIP.IsMulticast() {
|
||||
return nil
|
||||
}
|
||||
|
||||
con, err := NewConnection(&nfp, ip)
|
||||
if err != nil {
|
||||
log.Debug("%s", err)
|
||||
return nil
|
||||
} else if con == nil {
|
||||
return nil
|
||||
}
|
||||
return con
|
||||
}
|
||||
}
|
||||
|
||||
func NewConnection(nfp *netfilter.Packet, ip *layers.IPv4) (c *Connection, err error) {
|
||||
c = &Connection{
|
||||
SrcIP: ip.SrcIP,
|
||||
DstIP: ip.DstIP,
|
||||
DstHost: dns.HostOr(ip.DstIP, ip.DstIP.String()),
|
||||
pkt: nfp,
|
||||
}
|
||||
|
||||
func newConnectionImpl(nfp *netfilter.Packet, c *Connection) (cr *Connection, err error) {
|
||||
// no errors but not enough info neither
|
||||
if c.parseDirection() == false {
|
||||
return nil, nil
|
||||
|
@ -94,28 +108,57 @@ func NewConnection(nfp *netfilter.Packet, ip *layers.IPv4) (c *Connection, err e
|
|||
return nil, fmt.Errorf("Could not find process by its pid %d for: %s", pid, c)
|
||||
}
|
||||
return c, nil
|
||||
|
||||
}
|
||||
|
||||
func NewConnection(nfp *netfilter.Packet, ip *layers.IPv4) (c *Connection, err error) {
|
||||
c = &Connection{
|
||||
SrcIP: ip.SrcIP,
|
||||
DstIP: ip.DstIP,
|
||||
DstHost: dns.HostOr(ip.DstIP, ip.DstIP.String()),
|
||||
pkt: nfp,
|
||||
}
|
||||
return newConnectionImpl(nfp, c)
|
||||
}
|
||||
|
||||
func NewConnection6(nfp *netfilter.Packet, ip *layers.IPv6) (c *Connection, err error) {
|
||||
c = &Connection{
|
||||
SrcIP: ip.SrcIP,
|
||||
DstIP: ip.DstIP,
|
||||
DstHost: dns.HostOr(ip.DstIP, ip.DstIP.String()),
|
||||
pkt: nfp,
|
||||
}
|
||||
return newConnectionImpl(nfp, c)
|
||||
}
|
||||
|
||||
func (c *Connection) parseDirection() bool {
|
||||
ret := false
|
||||
for _, layer := range c.pkt.Packet.Layers() {
|
||||
if layer.LayerType() == layers.LayerTypeTCP {
|
||||
if tcp, ok := layer.(*layers.TCP); ok == true && tcp != nil {
|
||||
c.Protocol = "tcp"
|
||||
c.DstPort = int(tcp.DstPort)
|
||||
c.SrcPort = int(tcp.SrcPort)
|
||||
return true
|
||||
ret = true
|
||||
}
|
||||
} else if layer.LayerType() == layers.LayerTypeUDP {
|
||||
if udp, ok := layer.(*layers.UDP); ok == true && udp != nil {
|
||||
c.Protocol = "udp"
|
||||
c.DstPort = int(udp.DstPort)
|
||||
c.SrcPort = int(udp.SrcPort)
|
||||
return true
|
||||
ret = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
for _, layer := range c.pkt.Packet.Layers() {
|
||||
if layer.LayerType() == layers.LayerTypeIPv6 {
|
||||
if tcp, ok := layer.(*layers.IPv6); ok == true && tcp != nil {
|
||||
c.Protocol += "6"
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (c *Connection) To() string {
|
||||
|
|
|
@ -27,6 +27,8 @@ func RunRule(enable bool, rule []string) (err error) {
|
|||
// fmt.Printf("iptables %s\n", rule)
|
||||
|
||||
_, err = core.Exec("iptables", rule)
|
||||
_, err = core.Exec("ip6tables", rule)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -33,8 +33,6 @@ const (
|
|||
|
||||
NF_DEFAULT_QUEUE_SIZE uint32 = 4096
|
||||
NF_DEFAULT_PACKET_SIZE uint32 = 4096
|
||||
|
||||
ipv4version = 0x40
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -167,7 +165,7 @@ func go_callback(queueId C.int, data *C.uchar, length C.int, mark C.uint, idx ui
|
|||
xdata := C.GoBytes(unsafe.Pointer(data), length)
|
||||
|
||||
var packet gopacket.Packet
|
||||
if xdata[0]&0xf0 == ipv4version {
|
||||
if (xdata[0] >> 4) == 4 { // first 4 bits is the version
|
||||
packet = gopacket.NewPacket(xdata, layers.LayerTypeIPv4, gopacketDecodeOptions)
|
||||
} else {
|
||||
packet = gopacket.NewPacket(xdata, layers.LayerTypeIPv6, gopacketDecodeOptions)
|
||||
|
|
|
@ -16,8 +16,8 @@ import (
|
|||
var (
|
||||
parser = regexp.MustCompile(`(?i)` +
|
||||
`\d+:\s+` + // sl
|
||||
`([a-f0-9]{8}):([a-f0-9]{4})\s+` + // local_address
|
||||
`([a-f0-9]{8}):([a-f0-9]{4})\s+` + // rem_address
|
||||
`([a-f0-9]{8,32}):([a-f0-9]{4})\s+` + // local_address
|
||||
`([a-f0-9]{8,32}):([a-f0-9]{4})\s+` + // rem_address
|
||||
`[a-f0-9]{2}\s+` + // st
|
||||
`[a-f0-9]{8}:[a-f0-9]{8}\s+` + // tx_queue rx_queue
|
||||
`[a-f0-9]{2}:[a-f0-9]{8}\s+` + // tr tm->when
|
||||
|
@ -44,10 +44,41 @@ func hexToInt(h string) int {
|
|||
return int(d)
|
||||
}
|
||||
|
||||
|
||||
func hexToInt2(h string) (int, int) {
|
||||
if len(h) > 16 {
|
||||
d, err := strconv.ParseInt(h[:16], 16, 64)
|
||||
if err != nil {
|
||||
log.Fatal("Error while parsing %s to int: %s", h[16:], err)
|
||||
}
|
||||
d2, err := strconv.ParseInt(h[16:], 16, 64)
|
||||
if err != nil {
|
||||
log.Fatal("Error while parsing %s to int: %s", h[16:], err)
|
||||
}
|
||||
return int(d), int(d2)
|
||||
} else {
|
||||
d, err := strconv.ParseInt(h, 16, 64)
|
||||
if err != nil {
|
||||
log.Fatal("Error while parsing %s to int: %s", h[16:], err)
|
||||
}
|
||||
return int(d), 0
|
||||
}
|
||||
}
|
||||
|
||||
func hexToIP(h string) net.IP {
|
||||
n := hexToInt(h)
|
||||
ip := make(net.IP, 4)
|
||||
binary.LittleEndian.PutUint32(ip, uint32(n))
|
||||
n, m := hexToInt2(h)
|
||||
var ip net.IP
|
||||
if m != 0 {
|
||||
ip = make(net.IP, 16)
|
||||
// TODO: Check if this depends on machine endianness?
|
||||
binary.LittleEndian.PutUint32(ip, uint32(n >> 32))
|
||||
binary.LittleEndian.PutUint32(ip[4:], uint32(n))
|
||||
binary.LittleEndian.PutUint32(ip[8:], uint32(m >> 32))
|
||||
binary.LittleEndian.PutUint32(ip[12:], uint32(m))
|
||||
} else {
|
||||
ip = make(net.IP, 4)
|
||||
binary.LittleEndian.PutUint32(ip, uint32(n))
|
||||
}
|
||||
return ip
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue