github.com/cilium/cilium@v1.16.2/pkg/hubble/parser/seven/dns.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright Authors of Hubble 3 4 package seven 5 6 import ( 7 "fmt" 8 "strings" 9 10 "github.com/google/gopacket/layers" 11 12 flowpb "github.com/cilium/cilium/api/v1/flow" 13 "github.com/cilium/cilium/pkg/proxy/accesslog" 14 ) 15 16 func decodeDNS(flowType accesslog.FlowType, dns *accesslog.LogRecordDNS) *flowpb.Layer7_Dns { 17 qtypes := make([]string, 0, len(dns.QTypes)) 18 for _, qtype := range dns.QTypes { 19 qtypes = append(qtypes, layers.DNSType(qtype).String()) 20 } 21 if flowType == accesslog.TypeRequest { 22 // Set only fields that are relevant for requests. 23 return &flowpb.Layer7_Dns{ 24 Dns: &flowpb.DNS{ 25 Query: dns.Query, 26 ObservationSource: string(dns.ObservationSource), 27 Qtypes: qtypes, 28 }, 29 } 30 } 31 ips := make([]string, 0, len(dns.IPs)) 32 for _, ip := range dns.IPs { 33 ips = append(ips, ip.String()) 34 } 35 rtypes := make([]string, 0, len(dns.AnswerTypes)) 36 for _, rtype := range dns.AnswerTypes { 37 rtypes = append(rtypes, layers.DNSType(rtype).String()) 38 } 39 return &flowpb.Layer7_Dns{ 40 Dns: &flowpb.DNS{ 41 Query: dns.Query, 42 Ips: ips, 43 Ttl: dns.TTL, 44 Cnames: dns.CNAMEs, 45 ObservationSource: string(dns.ObservationSource), 46 Rcode: uint32(dns.RCode), 47 Qtypes: qtypes, 48 Rrtypes: rtypes, 49 }, 50 } 51 } 52 53 func dnsSummary(flowType accesslog.FlowType, dns *accesslog.LogRecordDNS) string { 54 types := []string{} 55 for _, t := range dns.QTypes { 56 types = append(types, layers.DNSType(t).String()) 57 } 58 qTypeStr := strings.Join(types, ",") 59 60 switch flowType { 61 case accesslog.TypeRequest: 62 return fmt.Sprintf("DNS Query %s %s", dns.Query, qTypeStr) 63 case accesslog.TypeResponse: 64 rcode := layers.DNSResponseCode(dns.RCode) 65 66 var answer string 67 if rcode != layers.DNSResponseCodeNoErr { 68 answer = fmt.Sprintf("RCode: %s", rcode) 69 } else { 70 parts := make([]string, 0) 71 72 if len(dns.IPs) > 0 { 73 ips := make([]string, 0, len(dns.IPs)) 74 for _, ip := range dns.IPs { 75 ips = append(ips, ip.String()) 76 } 77 parts = append(parts, fmt.Sprintf("%q", strings.Join(ips, ","))) 78 } 79 80 if len(dns.CNAMEs) > 0 { 81 parts = append(parts, fmt.Sprintf("CNAMEs: %q", strings.Join(dns.CNAMEs, ","))) 82 } 83 84 answer = strings.Join(parts, " ") 85 } 86 87 sourceType := "Query" 88 switch dns.ObservationSource { 89 case accesslog.DNSSourceProxy: 90 sourceType = "Proxy" 91 } 92 93 return fmt.Sprintf("DNS Answer %s TTL: %d (%s %s %s)", answer, dns.TTL, sourceType, dns.Query, qTypeStr) 94 } 95 96 return "" 97 }