| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- /*
- * Copyright (c) 2013-2014 by Farsight Security, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package dnstap
- import (
- "bytes"
- "fmt"
- "net"
- "strconv"
- "time"
- "github.com/miekg/dns"
- )
- const quietTimeFormat = "15:04:05"
- func textConvertTime(s *bytes.Buffer, secs *uint64, nsecs *uint32) {
- if secs != nil {
- s.WriteString(time.Unix(int64(*secs), 0).Format(quietTimeFormat))
- } else {
- s.WriteString("??:??:??")
- }
- if nsecs != nil {
- s.WriteString(fmt.Sprintf(".%06d", *nsecs/1000))
- } else {
- s.WriteString(".??????")
- }
- }
- func textConvertIP(s *bytes.Buffer, ip []byte) {
- if ip != nil {
- s.WriteString(net.IP(ip).String())
- } else {
- s.WriteString("MISSING_ADDRESS")
- }
- }
- func textConvertMessage(m *Message, s *bytes.Buffer) {
- isQuery := false
- printQueryAddress := false
- switch *m.Type {
- case Message_CLIENT_QUERY,
- Message_RESOLVER_QUERY,
- Message_AUTH_QUERY,
- Message_FORWARDER_QUERY,
- Message_TOOL_QUERY,
- Message_UPDATE_QUERY:
- isQuery = true
- case Message_CLIENT_RESPONSE,
- Message_RESOLVER_RESPONSE,
- Message_AUTH_RESPONSE,
- Message_FORWARDER_RESPONSE,
- Message_TOOL_RESPONSE,
- Message_UPDATE_RESPONSE:
- isQuery = false
- default:
- s.WriteString("[unhandled Message.Type]\n")
- return
- }
- if isQuery {
- textConvertTime(s, m.QueryTimeSec, m.QueryTimeNsec)
- } else {
- textConvertTime(s, m.ResponseTimeSec, m.ResponseTimeNsec)
- }
- s.WriteString(" ")
- switch *m.Type {
- case Message_CLIENT_QUERY,
- Message_CLIENT_RESPONSE:
- {
- s.WriteString("C")
- }
- case Message_RESOLVER_QUERY,
- Message_RESOLVER_RESPONSE:
- {
- s.WriteString("R")
- }
- case Message_AUTH_QUERY,
- Message_AUTH_RESPONSE:
- {
- s.WriteString("A")
- }
- case Message_FORWARDER_QUERY,
- Message_FORWARDER_RESPONSE:
- {
- s.WriteString("F")
- }
- case Message_STUB_QUERY,
- Message_STUB_RESPONSE:
- {
- s.WriteString("S")
- }
- case Message_TOOL_QUERY,
- Message_TOOL_RESPONSE:
- {
- s.WriteString("T")
- }
- case Message_UPDATE_QUERY,
- Message_UPDATE_RESPONSE:
- {
- s.WriteString("U")
- }
- }
- if isQuery {
- s.WriteString("Q ")
- } else {
- s.WriteString("R ")
- }
- switch *m.Type {
- case Message_CLIENT_QUERY,
- Message_CLIENT_RESPONSE,
- Message_AUTH_QUERY,
- Message_AUTH_RESPONSE:
- printQueryAddress = true
- }
- if printQueryAddress {
- textConvertIP(s, m.QueryAddress)
- } else {
- textConvertIP(s, m.ResponseAddress)
- }
- s.WriteString(" ")
- if m.SocketProtocol != nil {
- s.WriteString(m.SocketProtocol.String())
- }
- s.WriteString(" ")
- var err error
- msg := new(dns.Msg)
- if isQuery {
- s.WriteString(strconv.Itoa(len(m.QueryMessage)))
- s.WriteString("b ")
- err = msg.Unpack(m.QueryMessage)
- } else {
- s.WriteString(strconv.Itoa(len(m.ResponseMessage)))
- s.WriteString("b ")
- err = msg.Unpack(m.ResponseMessage)
- }
- if err != nil || len(msg.Question) == 0 {
- s.WriteString("X ")
- } else {
- s.WriteString("\"" + msg.Question[0].Name + "\" ")
- s.WriteString(dns.Class(msg.Question[0].Qclass).String() + " ")
- s.WriteString(dns.Type(msg.Question[0].Qtype).String())
- }
- s.WriteString("\n")
- }
- // TextFormat renders a dnstap message in a compact human-readable text
- // form.
- func TextFormat(dt *Dnstap) (out []byte, ok bool) {
- var s bytes.Buffer
- if *dt.Type == Dnstap_MESSAGE {
- textConvertMessage(dt.Message, &s)
- return s.Bytes(), true
- }
- return nil, false
- }
|