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  }