feat(10-02): add 28 new classification subtests to TestClassify
- Mail: IMAP 143/993, POP3 110/995, SMTPSub 587 (PROTO-01) - File Transfer: FTP 20/21, SMB 445, TFTP 69 (PROTO-02) - Remote Access: RDP 3389, Telnet 23, VNC 5900 (PROTO-03) - Database: MySQL 3306, PostgreSQL 5432, Redis 6379, MongoDB 27017 (PROTO-04) - Discovery: mDNS 5353, SSDP 1900, SNMP 161/162 (PROTO-05) - VoIP: SIP TCP+UDP 5060 (PROTO-06) - Web: QUIC UDP/443 distinct from HTTPS TCP/443 (PROTO-07) - Infrastructure: LDAP 389/636, Kerberos TCP+UDP 88, Syslog 514 (PROTO-08)
This commit is contained in:
@@ -226,6 +226,218 @@ func TestClassify(t *testing.T) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// --- Mail (PROTO-01) ---
|
||||||
|
t.Run("TestClassifyIMAP_port143", func(t *testing.T) {
|
||||||
|
pkt := buildTCPPacket(t, 143)
|
||||||
|
got := c.Classify(pkt)
|
||||||
|
if got.Class != classify.ClassIMAP {
|
||||||
|
t.Errorf("IMAP port 143: got class %q, want %q", got.Class, classify.ClassIMAP)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
t.Run("TestClassifyIMAP_port993", func(t *testing.T) {
|
||||||
|
pkt := buildTCPPacket(t, 993)
|
||||||
|
got := c.Classify(pkt)
|
||||||
|
if got.Class != classify.ClassIMAP {
|
||||||
|
t.Errorf("IMAPS port 993: got class %q, want %q", got.Class, classify.ClassIMAP)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
t.Run("TestClassifyPOP3_port110", func(t *testing.T) {
|
||||||
|
pkt := buildTCPPacket(t, 110)
|
||||||
|
got := c.Classify(pkt)
|
||||||
|
if got.Class != classify.ClassPOP3 {
|
||||||
|
t.Errorf("POP3 port 110: got class %q, want %q", got.Class, classify.ClassPOP3)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
t.Run("TestClassifyPOP3_port995", func(t *testing.T) {
|
||||||
|
pkt := buildTCPPacket(t, 995)
|
||||||
|
got := c.Classify(pkt)
|
||||||
|
if got.Class != classify.ClassPOP3 {
|
||||||
|
t.Errorf("POP3S port 995: got class %q, want %q", got.Class, classify.ClassPOP3)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
t.Run("TestClassifySMTPSub_port587", func(t *testing.T) {
|
||||||
|
pkt := buildTCPPacket(t, 587)
|
||||||
|
got := c.Classify(pkt)
|
||||||
|
if got.Class != classify.ClassSMTPSub {
|
||||||
|
t.Errorf("SMTP-sub port 587: got class %q, want %q", got.Class, classify.ClassSMTPSub)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// --- File Transfer (PROTO-02) ---
|
||||||
|
t.Run("TestClassifyFTP_port20", func(t *testing.T) {
|
||||||
|
pkt := buildTCPPacket(t, 20)
|
||||||
|
got := c.Classify(pkt)
|
||||||
|
if got.Class != classify.ClassFTP {
|
||||||
|
t.Errorf("FTP data port 20: got class %q, want %q", got.Class, classify.ClassFTP)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
t.Run("TestClassifyFTP_port21", func(t *testing.T) {
|
||||||
|
pkt := buildTCPPacket(t, 21)
|
||||||
|
got := c.Classify(pkt)
|
||||||
|
if got.Class != classify.ClassFTP {
|
||||||
|
t.Errorf("FTP control port 21: got class %q, want %q", got.Class, classify.ClassFTP)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
t.Run("TestClassifySMB_port445", func(t *testing.T) {
|
||||||
|
pkt := buildTCPPacket(t, 445)
|
||||||
|
got := c.Classify(pkt)
|
||||||
|
if got.Class != classify.ClassSMB {
|
||||||
|
t.Errorf("SMB port 445: got class %q, want %q", got.Class, classify.ClassSMB)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
t.Run("TestClassifyTFTP_port69", func(t *testing.T) {
|
||||||
|
pkt := buildUDPPacket(t, 69)
|
||||||
|
got := c.Classify(pkt)
|
||||||
|
if got.Class != classify.ClassTFTP {
|
||||||
|
t.Errorf("TFTP port 69: got class %q, want %q", got.Class, classify.ClassTFTP)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// --- Remote Access (PROTO-03) ---
|
||||||
|
t.Run("TestClassifyRDP_port3389", func(t *testing.T) {
|
||||||
|
pkt := buildTCPPacket(t, 3389)
|
||||||
|
got := c.Classify(pkt)
|
||||||
|
if got.Class != classify.ClassRDP {
|
||||||
|
t.Errorf("RDP port 3389: got class %q, want %q", got.Class, classify.ClassRDP)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
t.Run("TestClassifyTelnet_port23", func(t *testing.T) {
|
||||||
|
pkt := buildTCPPacket(t, 23)
|
||||||
|
got := c.Classify(pkt)
|
||||||
|
if got.Class != classify.ClassTelnet {
|
||||||
|
t.Errorf("Telnet port 23: got class %q, want %q", got.Class, classify.ClassTelnet)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
t.Run("TestClassifyVNC_port5900", func(t *testing.T) {
|
||||||
|
pkt := buildTCPPacket(t, 5900)
|
||||||
|
got := c.Classify(pkt)
|
||||||
|
if got.Class != classify.ClassVNC {
|
||||||
|
t.Errorf("VNC port 5900: got class %q, want %q", got.Class, classify.ClassVNC)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// --- Database (PROTO-04) ---
|
||||||
|
t.Run("TestClassifyMySQL_port3306", func(t *testing.T) {
|
||||||
|
pkt := buildTCPPacket(t, 3306)
|
||||||
|
got := c.Classify(pkt)
|
||||||
|
if got.Class != classify.ClassMySQL {
|
||||||
|
t.Errorf("MySQL port 3306: got class %q, want %q", got.Class, classify.ClassMySQL)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
t.Run("TestClassifyPostgreSQL_port5432", func(t *testing.T) {
|
||||||
|
pkt := buildTCPPacket(t, 5432)
|
||||||
|
got := c.Classify(pkt)
|
||||||
|
if got.Class != classify.ClassPostgreSQL {
|
||||||
|
t.Errorf("PostgreSQL port 5432: got class %q, want %q", got.Class, classify.ClassPostgreSQL)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
t.Run("TestClassifyRedis_port6379", func(t *testing.T) {
|
||||||
|
pkt := buildTCPPacket(t, 6379)
|
||||||
|
got := c.Classify(pkt)
|
||||||
|
if got.Class != classify.ClassRedis {
|
||||||
|
t.Errorf("Redis port 6379: got class %q, want %q", got.Class, classify.ClassRedis)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
t.Run("TestClassifyMongoDB_port27017", func(t *testing.T) {
|
||||||
|
pkt := buildTCPPacket(t, 27017)
|
||||||
|
got := c.Classify(pkt)
|
||||||
|
if got.Class != classify.ClassMongoDB {
|
||||||
|
t.Errorf("MongoDB port 27017: got class %q, want %q", got.Class, classify.ClassMongoDB)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// --- Discovery (PROTO-05) ---
|
||||||
|
t.Run("TestClassifyMDNS_port5353", func(t *testing.T) {
|
||||||
|
pkt := buildUDPPacket(t, 5353)
|
||||||
|
got := c.Classify(pkt)
|
||||||
|
if got.Class != classify.ClassMDNS {
|
||||||
|
t.Errorf("mDNS port 5353: got class %q, want %q", got.Class, classify.ClassMDNS)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
t.Run("TestClassifySDP_port1900", func(t *testing.T) {
|
||||||
|
pkt := buildUDPPacket(t, 1900)
|
||||||
|
got := c.Classify(pkt)
|
||||||
|
if got.Class != classify.ClassSSDP {
|
||||||
|
t.Errorf("SSDP port 1900: got class %q, want %q", got.Class, classify.ClassSSDP)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
t.Run("TestClassifySNMP_port161", func(t *testing.T) {
|
||||||
|
pkt := buildUDPPacket(t, 161)
|
||||||
|
got := c.Classify(pkt)
|
||||||
|
if got.Class != classify.ClassSNMP {
|
||||||
|
t.Errorf("SNMP port 161: got class %q, want %q", got.Class, classify.ClassSNMP)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
t.Run("TestClassifySNMP_port162", func(t *testing.T) {
|
||||||
|
pkt := buildUDPPacket(t, 162)
|
||||||
|
got := c.Classify(pkt)
|
||||||
|
if got.Class != classify.ClassSNMP {
|
||||||
|
t.Errorf("SNMP-trap port 162: got class %q, want %q", got.Class, classify.ClassSNMP)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// --- VoIP (PROTO-06) --- SIP runs on both TCP and UDP
|
||||||
|
t.Run("TestClassifySIP_TCP5060", func(t *testing.T) {
|
||||||
|
pkt := buildTCPPacket(t, 5060)
|
||||||
|
got := c.Classify(pkt)
|
||||||
|
if got.Class != classify.ClassSIP {
|
||||||
|
t.Errorf("SIP TCP 5060: got class %q, want %q", got.Class, classify.ClassSIP)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
t.Run("TestClassifySIP_UDP5060", func(t *testing.T) {
|
||||||
|
pkt := buildUDPPacket(t, 5060)
|
||||||
|
got := c.Classify(pkt)
|
||||||
|
if got.Class != classify.ClassSIP {
|
||||||
|
t.Errorf("SIP UDP 5060: got class %q, want %q", got.Class, classify.ClassSIP)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// --- Web extension (PROTO-07) --- QUIC is UDP 443, must NOT match HTTPS (TCP 443)
|
||||||
|
t.Run("TestClassifyQUIC_UDP443", func(t *testing.T) {
|
||||||
|
pkt := buildUDPPacket(t, 443)
|
||||||
|
got := c.Classify(pkt)
|
||||||
|
if got.Class != classify.ClassQUIC {
|
||||||
|
t.Errorf("QUIC UDP 443: got class %q, want %q", got.Class, classify.ClassQUIC)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// --- Infrastructure extension (PROTO-08) ---
|
||||||
|
t.Run("TestClassifyLDAP_port389", func(t *testing.T) {
|
||||||
|
pkt := buildTCPPacket(t, 389)
|
||||||
|
got := c.Classify(pkt)
|
||||||
|
if got.Class != classify.ClassLDAP {
|
||||||
|
t.Errorf("LDAP port 389: got class %q, want %q", got.Class, classify.ClassLDAP)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
t.Run("TestClassifyLDAP_port636", func(t *testing.T) {
|
||||||
|
pkt := buildTCPPacket(t, 636)
|
||||||
|
got := c.Classify(pkt)
|
||||||
|
if got.Class != classify.ClassLDAP {
|
||||||
|
t.Errorf("LDAPS port 636: got class %q, want %q", got.Class, classify.ClassLDAP)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
t.Run("TestClassifyKerberos_TCP88", func(t *testing.T) {
|
||||||
|
pkt := buildTCPPacket(t, 88)
|
||||||
|
got := c.Classify(pkt)
|
||||||
|
if got.Class != classify.ClassKerberos {
|
||||||
|
t.Errorf("Kerberos TCP 88: got class %q, want %q", got.Class, classify.ClassKerberos)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
t.Run("TestClassifyKerberos_UDP88", func(t *testing.T) {
|
||||||
|
pkt := buildUDPPacket(t, 88)
|
||||||
|
got := c.Classify(pkt)
|
||||||
|
if got.Class != classify.ClassKerberos {
|
||||||
|
t.Errorf("Kerberos UDP 88: got class %q, want %q", got.Class, classify.ClassKerberos)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
t.Run("TestClassifySyslog_port514", func(t *testing.T) {
|
||||||
|
pkt := buildUDPPacket(t, 514)
|
||||||
|
got := c.Classify(pkt)
|
||||||
|
if got.Class != classify.ClassSyslog {
|
||||||
|
t.Errorf("Syslog port 514: got class %q, want %q", got.Class, classify.ClassSyslog)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
t.Run("TestRulesAreOrderDependent", func(t *testing.T) {
|
t.Run("TestRulesAreOrderDependent", func(t *testing.T) {
|
||||||
// A rule list where TCP port 443 maps to ClassHTTP (wrong) placed first,
|
// A rule list where TCP port 443 maps to ClassHTTP (wrong) placed first,
|
||||||
// then ClassHTTPS. The first matching rule should win.
|
// then ClassHTTPS. The first matching rule should win.
|
||||||
|
|||||||
Reference in New Issue
Block a user