Skip to content

Commit

Permalink
Merge 1066289 into f5ba31a
Browse files Browse the repository at this point in the history
  • Loading branch information
nikofil committed Nov 15, 2017
2 parents f5ba31a + 1066289 commit a15b2ff
Show file tree
Hide file tree
Showing 27 changed files with 72 additions and 73 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ The `Initialize` method initializes all the selected modules in the library, by
Then, you need a flow that contains the packet. You can get the flow a packet belongs to with the following call:

```go
flow, isNew := godpi.GetPacketFlow(&packet)
flow, isNew := godpi.GetPacketFlow(packet)
```

That call returns the flow, as well as whether that flow is a new one (this packet is the first in the flow) or an existing one.
Expand Down Expand Up @@ -69,7 +69,7 @@ func main() {
fmt.Println(err)
} else {
for packet := range packets {
flow, _ := godpi.GetPacketFlow(&packet)
flow, _ := godpi.GetPacketFlow(packet)
result := godpi.ClassifyFlow(flow)
if result.Protocol != types.Unknown {
fmt.Println(result.Source, "detected protocol", result.Protocol)
Expand Down
8 changes: 4 additions & 4 deletions glide.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion glide.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package: github.com/mushorg/go-dpi
import:
- package: github.com/google/gopacket
version: ^1.1.12
version: ^1.1.14
- package: github.com/pkg/errors
version: ^0.8.0
- package: github.com/patrickmn/go-cache
Expand Down
2 changes: 1 addition & 1 deletion godpi.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ func SetCacheExpiration(expiration time.Duration) {
// will be created with only this packet.
// The function also returns whether the returned Flow is a new one, and not
// one that already existed.
func GetPacketFlow(packet *gopacket.Packet) (*types.Flow, bool) {
func GetPacketFlow(packet gopacket.Packet) (*types.Flow, bool) {
return types.GetFlowForPacket(packet)
}

Expand Down
2 changes: 1 addition & 1 deletion godpi_example/example_app.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ func main() {
count = 0
for packet := range packetChannel {
fmt.Printf("Packet #%d: ", count+1)
flow, isNew := godpi.GetPacketFlow(&packet)
flow, isNew := godpi.GetPacketFlow(packet)
result := godpi.ClassifyFlow(flow)
if result.Protocol != types.Unknown {
fmt.Print(result)
Expand Down
6 changes: 3 additions & 3 deletions godpi_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,13 +102,13 @@ func TestGetPacketFlow(t *testing.T) {
t.Fatal(err)
}
packet := <-dumpPackets
flowFirst, isNew := GetPacketFlow(&packet)
flowFirst, isNew := GetPacketFlow(packet)
if !isNew {
t.Error("Not new flow for first packet")
}
for i := 0; i < 3; i++ {
packet := <-dumpPackets
flowNext, isNew := GetPacketFlow(&packet)
flowNext, isNew := GetPacketFlow(packet)
if isNew {
t.Error("New flow returned for packet in existing flow")
}
Expand Down Expand Up @@ -142,7 +142,7 @@ func BenchmarkClassifyFlow(b *testing.B) {
b.Error(err)
}
for p := range dumpPackets {
flow, _ := GetPacketFlow(&p)
flow, _ := GetPacketFlow(p)
if flow.GetClassificationResult().Protocol == types.Unknown {
ClassifyFlow(flow)
}
Expand Down
8 changes: 4 additions & 4 deletions modules/classifiers/classifiers.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ func (module *ClassifierModule) ConfigureModule(config ClassifierModuleConfig) {
func checkFlowLayer(flow *types.Flow, layerType gopacket.LayerType,
checkFunc func(layer gopacket.Layer) bool) bool {
for _, packet := range flow.GetPackets() {
if layer := (*packet).Layer(layerType); layer != nil {
if layer := packet.Layer(layerType); layer != nil {
if checkFunc(layer) {
return true
}
Expand All @@ -118,10 +118,10 @@ func checkFlowLayer(flow *types.Flow, layerType gopacket.LayerType,
// checkFirstPayload applies the check function to the payload of the first
// packet that has the specified layer. It returns the result of that function
// on that first packet, or false if no such packet exists.
func checkFirstPayload(packets []*gopacket.Packet, layerType gopacket.LayerType,
checkFunc func(payload []byte, packetsRest []*gopacket.Packet) bool) bool {
func checkFirstPayload(packets []gopacket.Packet, layerType gopacket.LayerType,
checkFunc func(payload []byte, packetsRest []gopacket.Packet) bool) bool {
for i, packet := range packets {
if layer := (*packet).Layer(layerType); layer != nil {
if layer := packet.Layer(layerType); layer != nil {
if payload := layer.LayerPayload(); payload != nil && len(payload) > 0 {
return checkFunc(payload, packets[i+1:])
}
Expand Down
12 changes: 6 additions & 6 deletions modules/classifiers/classifiers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ func TestClassifyFlow(t *testing.T) {
<-dumpPackets
}
packet := <-dumpPackets
flow := types.CreateFlowFromPacket(&packet)
flow := types.CreateFlowFromPacket(packet)
result := module.ClassifyFlow(flow)
flowCls := flow.GetClassificationResult()
if result.Protocol != types.HTTP || flowCls.Protocol != types.HTTP {
Expand Down Expand Up @@ -55,7 +55,7 @@ func TestCheckFlowLayer(t *testing.T) {
flow := types.NewFlow()
for packet := range dumpPackets {
packetCopy := packet
flow.AddPacket(&packetCopy)
flow.AddPacket(packetCopy)
}
noDetections := checkFlowLayer(flow, layers.LayerTypeTCP, func(layer gopacket.Layer) bool {
_, ok := layer.(*layers.TCP)
Expand Down Expand Up @@ -86,12 +86,12 @@ func TestCheckFirstPayload(t *testing.T) {
flow := types.NewFlow()
for packet := range dumpPackets {
packetCopy := packet
flow.AddPacket(&packetCopy)
flow.AddPacket(packetCopy)
}

called := false
noDetections := checkFirstPayload(flow.GetPackets(), layers.LayerTypeTCP,
func(payload []byte, packetsRest []*gopacket.Packet) bool {
func(payload []byte, packetsRest []gopacket.Packet) bool {
called = true
if payload == nil || len(payload) == 0 {
t.Error("No payload passed to callback")
Expand Down Expand Up @@ -120,7 +120,7 @@ func getPcapDumpProtoMap(filename string) (result map[types.Protocol]int) {
return
}
for packet := range packets {
flow, _ := types.GetFlowForPacket(&packet)
flow, _ := types.GetFlowForPacket(packet)
if flow.GetClassificationResult().Protocol == types.Unknown {
res := module.ClassifyFlow(flow)
result[res.Protocol]++
Expand Down Expand Up @@ -175,7 +175,7 @@ func TestConfigureModule(t *testing.T) {
<-dumpPackets
}
packet := <-dumpPackets
flow := types.CreateFlowFromPacket(&packet)
flow := types.CreateFlowFromPacket(packet)
result := module.ClassifyFlow(flow)
if result.Protocol != types.HTTP {
t.Error("Wrong protocol detected:", result.Protocol)
Expand Down
4 changes: 2 additions & 2 deletions modules/classifiers/ftp.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ type FTPClassifier struct{}
// HeuristicClassify for FTPClassifier
func (classifier FTPClassifier) HeuristicClassify(flow *types.Flow) bool {
return checkFirstPayload(flow.GetPackets(), layers.LayerTypeTCP,
func(payload []byte, packetsRest []*gopacket.Packet) bool {
func(payload []byte, packetsRest []gopacket.Packet) bool {
payloadStr := string(payload)
for _, line := range strings.Split(payloadStr, "\n") {
if len(line) > 0 && !strings.HasPrefix(line, "220") {
return false
}
}
return checkFirstPayload(packetsRest, layers.LayerTypeTCP,
func(payload []byte, _ []*gopacket.Packet) bool {
func(payload []byte, _ []gopacket.Packet) bool {
payloadStr := string(payload)
return strings.HasPrefix(payloadStr, "USER ") &&
strings.HasSuffix(payloadStr, "\n")
Expand Down
2 changes: 1 addition & 1 deletion modules/classifiers/jabber.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ type JABBERClassifier struct{}
// HeuristicClassify for JABBERClassifier
func (classifier JABBERClassifier) HeuristicClassify(flow *types.Flow) bool {
return checkFirstPayload(flow.GetPackets(), layers.LayerTypeTCP,
func(payload []byte, packetsRest []*gopacket.Packet) bool {
func(payload []byte, packetsRest []gopacket.Packet) bool {
payloadStr := string(payload)
result, _ := regexp.MatchString("<?xml\\sversion='\\d+.\\d+'?.*", payloadStr)
return result
Expand Down
2 changes: 1 addition & 1 deletion modules/classifiers/mqtt.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ type MQTTClassifier struct{}
// HeuristicClassify for MQTTClassifier
func (classifier MQTTClassifier) HeuristicClassify(flow *types.Flow) bool {
return checkFirstPayload(flow.GetPackets(), layers.LayerTypeTCP,
func(payload []byte, packetsRest []*gopacket.Packet) bool {
func(payload []byte, packetsRest []gopacket.Packet) bool {
//check Control packet (connect)
isValidPacket := payload[0] == 0x10
//check message lenght
Expand Down
8 changes: 4 additions & 4 deletions modules/classifiers/netbios.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
// NetBIOSClassifier struct
type NetBIOSClassifier struct{}

func checkTCPNetBIOS(payload []byte, packetsRest []*gopacket.Packet) bool {
func checkTCPNetBIOS(payload []byte, packetsRest []gopacket.Packet) bool {
if len(payload) < 8 {
return false
}
Expand All @@ -24,8 +24,8 @@ func checkTCPNetBIOS(payload []byte, packetsRest []*gopacket.Packet) bool {
return nbLen+4 == len(payload) && isSessRequest && namesHavePadding
}

func checkUDPNetBIOSWrapper(isFirstPktBroadcast *bool) func([]byte, []*gopacket.Packet) bool {
return func(payload []byte, packetsRest []*gopacket.Packet) bool {
func checkUDPNetBIOSWrapper(isFirstPktBroadcast *bool) func([]byte, []gopacket.Packet) bool {
return func(payload []byte, packetsRest []gopacket.Packet) bool {
// try to detect a name query
if len(payload) != 50 {
return false
Expand All @@ -45,7 +45,7 @@ func (classifier NetBIOSClassifier) HeuristicClassify(flow *types.Flow) bool {
var isFirstPktBroadcast bool
packets := flow.GetPackets()
if len(packets) > 0 {
if layer := (*packets[0]).Layer(layers.LayerTypeIPv4); layer != nil {
if layer := packets[0].Layer(layers.LayerTypeIPv4); layer != nil {
ipLayer := layer.(*layers.IPv4)
isFirstPktBroadcast = ipLayer.DstIP[3] == 0xFF
}
Expand Down
2 changes: 1 addition & 1 deletion modules/classifiers/rdp.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ type RDPClassifier struct{}
// HeuristicClassify for RDPClassifier
func (classifier RDPClassifier) HeuristicClassify(flow *types.Flow) bool {
return checkFirstPayload(flow.GetPackets(), layers.LayerTypeTCP,
func(payload []byte, packetsRest []*gopacket.Packet) bool {
func(payload []byte, packetsRest []gopacket.Packet) bool {
if len(payload) < 20 {
return false
}
Expand Down
2 changes: 1 addition & 1 deletion modules/classifiers/rpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ type RPCClassifier struct{}
// HeuristicClassify for RPCClassifier
func (classifier RPCClassifier) HeuristicClassify(flow *types.Flow) bool {
return checkFirstPayload(flow.GetPackets(), layers.LayerTypeTCP,
func(payload []byte, packetsRest []*gopacket.Packet) bool {
func(payload []byte, packetsRest []gopacket.Packet) bool {
if len(payload) < 24 {
return false
}
Expand Down
2 changes: 1 addition & 1 deletion modules/classifiers/smb.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ type SMBClassifier struct{}
// HeuristicClassify for SMBClassifier
func (classifier SMBClassifier) HeuristicClassify(flow *types.Flow) bool {
return checkFirstPayload(flow.GetPackets(), layers.LayerTypeTCP,
func(payload []byte, packetsRest []*gopacket.Packet) bool {
func(payload []byte, packetsRest []gopacket.Packet) bool {
// skip netbios layer if it exists
if len(payload) > 4 && payload[0] == 0 {
netbiosLen := binary.BigEndian.Uint32(payload[:4])
Expand Down
4 changes: 2 additions & 2 deletions modules/classifiers/smtp.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ type SMTPClassifier struct{}
// HeuristicClassify for SMTPClassifier
func (classifier SMTPClassifier) HeuristicClassify(flow *types.Flow) bool {
return checkFirstPayload(flow.GetPackets(), layers.LayerTypeTCP,
func(payload []byte, packetsRest []*gopacket.Packet) bool {
func(payload []byte, packetsRest []gopacket.Packet) bool {
payloadStr := string(payload)
for _, line := range strings.Split(payloadStr, "\n") {
if len(line) > 0 && !strings.HasPrefix(line, "220") {
return false
}
}
return checkFirstPayload(packetsRest, layers.LayerTypeTCP,
func(payload []byte, _ []*gopacket.Packet) bool {
func(payload []byte, _ []gopacket.Packet) bool {
payloadStr := string(payload)
return (strings.HasPrefix(payloadStr, "EHLO ") ||
strings.HasPrefix(payloadStr, "HELO ")) &&
Expand Down
2 changes: 1 addition & 1 deletion modules/classifiers/ssh.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ type SSHClassifier struct{}
// HeuristicClassify for SSHClassifier
func (classifier SSHClassifier) HeuristicClassify(flow *types.Flow) bool {
return checkFirstPayload(flow.GetPackets(), layers.LayerTypeTCP,
func(payload []byte, _ []*gopacket.Packet) bool {
func(payload []byte, _ []gopacket.Packet) bool {
payloadStr := string(payload)
hasSuffix := strings.HasSuffix(payloadStr, "\n")
hasSSHStr := strings.HasPrefix(payloadStr, "SSH") || strings.Contains(payloadStr, "OpenSSH")
Expand Down
2 changes: 1 addition & 1 deletion modules/classifiers/ssl.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ type SSLClassifier struct{}
// HeuristicClassify for SSLClassifier
func (classifier SSLClassifier) HeuristicClassify(flow *types.Flow) bool {
return checkFirstPayload(flow.GetPackets(), layers.LayerTypeTCP,
func(payload []byte, _ []*gopacket.Packet) (detected bool) {
func(payload []byte, _ []gopacket.Packet) (detected bool) {
if len(payload) >= 9 {
packetLen := int(binary.BigEndian.Uint16(payload[3:5]))
clientHelloLenBytes := append([]byte{0}, payload[6:9]...)
Expand Down
6 changes: 3 additions & 3 deletions modules/ml/linearsvc.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,14 +110,14 @@ func (module *LinearSVCModule) Destroy() error {

func getFirstClientPayload(flow *types.Flow) (classifyPayload []byte, isTCP bool) {
packets := flow.GetPackets()
firstTransport := (*packets[0]).TransportLayer()
firstTransport := packets[0].TransportLayer()
switch transport := firstTransport.(type) {
case *layers.TCP:
isTCP = true
if transport.SYN && !transport.ACK && len(packets) >= 4 {
clientPort := transport.SrcPort
for _, pkt := range packets[3:] {
if pktTCP := (*pkt).Layer(layers.LayerTypeTCP).(*layers.TCP); pktTCP != nil && pktTCP.SrcPort == clientPort {
if pktTCP := pkt.Layer(layers.LayerTypeTCP).(*layers.TCP); pktTCP != nil && pktTCP.SrcPort == clientPort {
if pktPayload := pktTCP.LayerPayload(); pktPayload != nil && len(pktPayload) > 0 {
classifyPayload = pktPayload
break
Expand All @@ -128,7 +128,7 @@ func getFirstClientPayload(flow *types.Flow) (classifyPayload []byte, isTCP bool
case *layers.UDP:
isTCP = false
for _, pkt := range packets {
if pktUDP := (*pkt).Layer(layers.LayerTypeUDP).(*layers.UDP); pktUDP != nil {
if pktUDP := pkt.Layer(layers.LayerTypeUDP).(*layers.UDP); pktUDP != nil {
if pktPayload := pktUDP.LayerPayload(); pktPayload != nil && len(pktPayload) > 0 {
classifyPayload = pktPayload
break
Expand Down
4 changes: 2 additions & 2 deletions modules/ml/linearsvc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func TestClassifyFlow(t *testing.T) {
httpFlow := types.NewFlow()
for i := 0; i < 4; i++ {
packet := <-packetChan
httpFlow.AddPacket(&packet)
httpFlow.AddPacket(packet)
}

res := module.ClassifyFlow(httpFlow)
Expand All @@ -72,7 +72,7 @@ func TestClassifyFlow(t *testing.T) {
}
dnsFlow := types.NewFlow()
dnsPacket := <-packetChan
dnsFlow.AddPacket(&dnsPacket)
dnsFlow.AddPacket(dnsPacket)

res = module.ClassifyFlow(dnsFlow)
if res.Protocol != types.DNS {
Expand Down
2 changes: 1 addition & 1 deletion modules/wrappers/LPI_wrapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func (wrapper *LPIWrapper) ClassifyFlow(flow *types.Flow) (types.Protocol, error
lpiFlow := C.lpiCreateFlow()
defer C.lpiFreeFlow(lpiFlow)
for _, packet := range flow.GetPackets() {
pktData := (*packet).Data()
pktData := packet.Data()
dataPtr := unsafe.Pointer(&pktData[0])
C.lpiAddPacketToFlow(lpiFlow, dataPtr, C.ushort(len(pktData)))
}
Expand Down
4 changes: 2 additions & 2 deletions modules/wrappers/LPI_wrapper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ func TestLPIWrapperClassifyFlow(t *testing.T) {
flow := types.NewFlow()
for i := 0; i < 3; i++ {
packet := <-packetChan
flow.AddPacket(&packet)
flow.AddPacket(packet)
}

// first three packets should not be enough to classify the flow
Expand All @@ -27,7 +27,7 @@ func TestLPIWrapperClassifyFlow(t *testing.T) {

flow = types.NewFlow()
packet := <-packetChan
flow.AddPacket(&packet)
flow.AddPacket(packet)

// fourth packet should be HTTP
if result, _ := wrapper.ClassifyFlow(flow); result != types.HTTP {
Expand Down

0 comments on commit a15b2ff

Please sign in to comment.