|
@@ -1688,6 +1688,10 @@ PKT *ClonePacket(PKT *p, bool copy_data)
|
|
|
ret->L7.IkeHeader = MallocFast(sizeof(IKE_HEADER));
|
|
|
Copy(ret->L7.IkeHeader, p->L7.IkeHeader, sizeof(IKE_HEADER));
|
|
|
break;
|
|
|
+
|
|
|
+ case L7_DNS:
|
|
|
+ StrCpy(ret->DnsQueryHost, sizeof(ret->DnsQueryHost), p->DnsQueryHost);
|
|
|
+ break;
|
|
|
}
|
|
|
|
|
|
// Address data
|
|
@@ -1845,12 +1849,13 @@ PKT *ParsePacketEx4(UCHAR *buf, UINT size, bool no_l3, UINT vlan_type_id, bool b
|
|
|
USHORT port_raw = Endian16(80);
|
|
|
USHORT port_raw2 = Endian16(8080);
|
|
|
USHORT port_raw3 = Endian16(443);
|
|
|
+ USHORT port_raw4 = Endian16(3128);
|
|
|
|
|
|
// Analyze if the packet is a part of HTTP
|
|
|
if ((p->TypeL3 == L3_IPV4 || p->TypeL3 == L3_IPV6) && p->TypeL4 == L4_TCP)
|
|
|
{
|
|
|
TCP_HEADER *tcp = p->L4.TCPHeader;
|
|
|
- if (tcp != NULL && (tcp->DstPort == port_raw || tcp->DstPort == port_raw2) &&
|
|
|
+ if (tcp != NULL && (tcp->DstPort == port_raw || tcp->DstPort == port_raw2 || tcp->DstPort == port_raw4) &&
|
|
|
(!((tcp->Flag & TCP_SYN) || (tcp->Flag & TCP_RST) || (tcp->Flag & TCP_FIN))))
|
|
|
{
|
|
|
if (p->PayloadSize >= 1)
|
|
@@ -3010,6 +3015,148 @@ bool ParseTCP(PKT *p, UCHAR *buf, UINT size)
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
+// Get the next byte
|
|
|
+UCHAR GetNextByte(BUF *b)
|
|
|
+{
|
|
|
+ UCHAR c = 0;
|
|
|
+ // Validate arguments
|
|
|
+ if (b == NULL)
|
|
|
+ {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (ReadBuf(b, &c, 1) != 1)
|
|
|
+ {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ return c;
|
|
|
+}
|
|
|
+
|
|
|
+// Interpret the DNS query
|
|
|
+bool ParseDnsQuery(char *name, UINT name_size, void *data, UINT data_size)
|
|
|
+{
|
|
|
+ BUF *b;
|
|
|
+ char tmp[257];
|
|
|
+ bool ok = true;
|
|
|
+ USHORT val;
|
|
|
+ // Validate arguments
|
|
|
+ if (name == NULL || data == NULL || data_size == 0)
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ StrCpy(name, name_size, "");
|
|
|
+
|
|
|
+ b = NewBuf();
|
|
|
+ WriteBuf(b, data, data_size);
|
|
|
+ SeekBuf(b, 0, 0);
|
|
|
+
|
|
|
+ while (true)
|
|
|
+ {
|
|
|
+ UINT next_len = (UINT)GetNextByte(b);
|
|
|
+ if (next_len > 0)
|
|
|
+ {
|
|
|
+ // Read only the specified length
|
|
|
+ Zero(tmp, sizeof(tmp));
|
|
|
+ if (ReadBuf(b, tmp, next_len) != next_len)
|
|
|
+ {
|
|
|
+ ok = false;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ // Append
|
|
|
+ if (StrLen(name) != 0)
|
|
|
+ {
|
|
|
+ StrCat(name, name_size, ".");
|
|
|
+ }
|
|
|
+ StrCat(name, name_size, tmp);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // Read all
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (ReadBuf(b, &val, sizeof(val)) != sizeof(val))
|
|
|
+ {
|
|
|
+ ok = false;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (Endian16(val) != 0x01 && Endian16(val) != 0x0c)
|
|
|
+ {
|
|
|
+ ok = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (ReadBuf(b, &val, sizeof(val)) != sizeof(val))
|
|
|
+ {
|
|
|
+ ok = false;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (Endian16(val) != 0x01)
|
|
|
+ {
|
|
|
+ ok = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ FreeBuf(b);
|
|
|
+
|
|
|
+ if (ok == false || StrLen(name) == 0)
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// DNS parsing
|
|
|
+void ParseDNS(PKT *p, UCHAR *buf, UINT size)
|
|
|
+{
|
|
|
+ UCHAR *query_data;
|
|
|
+ UINT query_data_size;
|
|
|
+ DNSV4_HEADER *dns;
|
|
|
+ char hostname[MAX_SIZE];
|
|
|
+ if (p == NULL|| buf == NULL)
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (size < sizeof(DNSV4_HEADER))
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ dns = (DNSV4_HEADER *)buf;
|
|
|
+
|
|
|
+ if ((dns->Flag1 & 78) != 0 || (dns->Flag1 & 0x80) != 0)
|
|
|
+ {
|
|
|
+ // Illegal opcode
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (Endian16(dns->NumQuery) != 1)
|
|
|
+ {
|
|
|
+ // Number of queries is invalid
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ query_data = ((UCHAR *)dns) + sizeof(DNSV4_HEADER);
|
|
|
+ query_data_size = size - sizeof(DNSV4_HEADER);
|
|
|
+
|
|
|
+ // Interpret the query
|
|
|
+ if (ParseDnsQuery(hostname, sizeof(hostname), query_data, query_data_size) == false)
|
|
|
+ {
|
|
|
+ // Interpretation fails
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ StrCpy(p->DnsQueryHost, sizeof(p->DnsQueryHost), hostname);
|
|
|
+ p->TypeL7 = L7_DNS;
|
|
|
+}
|
|
|
+
|
|
|
// UDP parsing
|
|
|
bool ParseUDP(PKT *p, UCHAR *buf, UINT size)
|
|
|
{
|
|
@@ -3053,6 +3200,12 @@ bool ParseUDP(PKT *p, UCHAR *buf, UINT size)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ if (dst_port == 53)
|
|
|
+ {
|
|
|
+ ParseDNS(p, buf, size);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
if (src_port == 500 || dst_port == 500 || src_port == 4500 || dst_port == 4500)
|
|
|
{
|
|
|
if (p->PayloadSize >= sizeof(IKE_HEADER))
|