IDnsQueryLogger.cs 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. /*
  2. Technitium DNS Server
  3. Copyright (C) 2024 Shreyas Zare (shreyas@technitium.com)
  4. This program is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. using System;
  16. using System.Collections.Generic;
  17. using System.Net;
  18. using System.Threading.Tasks;
  19. using TechnitiumLibrary.Net.Dns;
  20. using TechnitiumLibrary.Net.Dns.ResourceRecords;
  21. namespace DnsServerCore.ApplicationCommon
  22. {
  23. public enum DnsServerResponseType : byte
  24. {
  25. Authoritative = 1,
  26. Recursive = 2,
  27. Cached = 3,
  28. Blocked = 4,
  29. UpstreamBlocked = 5,
  30. CacheBlocked = 6,
  31. Dropped = 7
  32. }
  33. /// <summary>
  34. /// Allows a DNS App to log incoming DNS requests and their corresponding responses.
  35. /// </summary>
  36. public interface IDnsQueryLogger
  37. {
  38. /// <summary>
  39. /// Allows a DNS App to log incoming DNS requests and responses. This method is called by the DNS Server after an incoming request is processed and a response is sent.
  40. /// </summary>
  41. /// <param name="timestamp">The time stamp of the log entry.</param>
  42. /// <param name="request">The incoming DNS request that was received.</param>
  43. /// <param name="remoteEP">The end point (IP address and port) of the client making the request.</param>
  44. /// <param name="protocol">The protocol using which the request was received.</param>
  45. /// <param name="response">The DNS response that was sent.</param>
  46. Task InsertLogAsync(DateTime timestamp, DnsDatagram request, IPEndPoint remoteEP, DnsTransportProtocol protocol, DnsDatagram response);
  47. /// <summary>
  48. /// Allows DNS Server HTTP API to query the logs recorded by the DNS App.
  49. /// </summary>
  50. /// <param name="pageNumber">The page number to be displayed to the user.</param>
  51. /// <param name="entriesPerPage">Total entries per page.</param>
  52. /// <param name="descendingOrder">Lists log entries in descending order.</param>
  53. /// <param name="start">Optional parameter to filter records by start date time.</param>
  54. /// <param name="end">Optional parameter to filter records by end date time.</param>
  55. /// <param name="clientIpAddress">Optional parameter to filter records by the client IP address.</param>
  56. /// <param name="protocol">Optional parameter to filter records by the DNS transport protocol.</param>
  57. /// <param name="responseType">Optional parameter to filter records by the type of response.</param>
  58. /// <param name="rcode">Optional parameter to filter records by the response code.</param>
  59. /// <param name="qname">Optional parameter to filter records by the request QNAME.</param>
  60. /// <param name="qtype">Optional parameter to filter records by the request QTYPE.</param>
  61. /// <param name="qclass">Optional parameter to filter records by the request QCLASS.</param>
  62. /// <returns>The <code>DnsLogPage</code> object that contains all the entries in the requested page number.</returns>
  63. Task<DnsLogPage> QueryLogsAsync(long pageNumber, int entriesPerPage, bool descendingOrder, DateTime? start, DateTime? end, IPAddress clientIpAddress, DnsTransportProtocol? protocol, DnsServerResponseType? responseType, DnsResponseCode? rcode, string qname, DnsResourceRecordType? qtype, DnsClass? qclass);
  64. }
  65. public class DnsLogPage
  66. {
  67. #region variables
  68. readonly long _pageNumber;
  69. readonly long _totalPages;
  70. readonly long _totalEntries;
  71. readonly IReadOnlyList<DnsLogEntry> _entries;
  72. #endregion
  73. #region constructor
  74. /// <summary>
  75. /// Creates a new object initialized with all the log page parameters.
  76. /// </summary>
  77. /// <param name="pageNumber">The actual page number of the selected data set.</param>
  78. /// <param name="totalPages">The total pages for the selected data set.</param>
  79. /// <param name="totalEntries">The total number of entries in the selected data set.</param>
  80. /// <param name="entries">The DNS log entries in this page.</param>
  81. public DnsLogPage(long pageNumber, long totalPages, long totalEntries, IReadOnlyList<DnsLogEntry> entries)
  82. {
  83. _pageNumber = pageNumber;
  84. _totalPages = totalPages;
  85. _totalEntries = totalEntries;
  86. _entries = entries;
  87. }
  88. #endregion
  89. #region properties
  90. /// <summary>
  91. /// The actual page number of the selected data set.
  92. /// </summary>
  93. public long PageNumber
  94. { get { return _pageNumber; } }
  95. /// <summary>
  96. /// The total pages for the selected data set.
  97. /// </summary>
  98. public long TotalPages
  99. { get { return _totalPages; } }
  100. /// <summary>
  101. /// The total number of entries in the selected data set.
  102. /// </summary>
  103. public long TotalEntries
  104. { get { return _totalEntries; } }
  105. /// <summary>
  106. /// The DNS log entries in this page.
  107. /// </summary>
  108. public IReadOnlyList<DnsLogEntry> Entries
  109. { get { return _entries; } }
  110. #endregion
  111. }
  112. public class DnsLogEntry
  113. {
  114. #region variables
  115. readonly long _rowNumber;
  116. readonly DateTime _timestamp;
  117. readonly IPAddress _clientIpAddress;
  118. readonly DnsTransportProtocol _protocol;
  119. readonly DnsServerResponseType _responseType;
  120. readonly DnsResponseCode _rcode;
  121. readonly DnsQuestionRecord _question;
  122. readonly string _answer;
  123. #endregion
  124. #region constructor
  125. /// <summary>
  126. /// Creates a new object initialized with all the log entry parameters.
  127. /// </summary>
  128. /// <param name="rowNumber">The row number of the entry in the selected data set.</param>
  129. /// <param name="timestamp">The time stamp of the log entry.</param>
  130. /// <param name="clientIpAddress">The client IP address of the request.</param>
  131. /// <param name="protocol">The DNS transport protocol of the request.</param>
  132. /// <param name="responseType">The type of response sent by the DNS server.</param>
  133. /// <param name="rcode">The response code sent by the DNS server.</param>
  134. /// <param name="question">The question section in the request.</param>
  135. /// <param name="answer">The answer in text format sent by the DNS server.</param>
  136. public DnsLogEntry(long rowNumber, DateTime timestamp, IPAddress clientIpAddress, DnsTransportProtocol protocol, DnsServerResponseType responseType, DnsResponseCode rcode, DnsQuestionRecord question, string answer)
  137. {
  138. _rowNumber = rowNumber;
  139. _timestamp = timestamp;
  140. _clientIpAddress = clientIpAddress;
  141. _protocol = protocol;
  142. _responseType = responseType;
  143. _rcode = rcode;
  144. _question = question;
  145. _answer = answer;
  146. switch (_timestamp.Kind)
  147. {
  148. case DateTimeKind.Local:
  149. _timestamp = _timestamp.ToUniversalTime();
  150. break;
  151. case DateTimeKind.Unspecified:
  152. _timestamp = DateTime.SpecifyKind(_timestamp, DateTimeKind.Utc);
  153. break;
  154. }
  155. }
  156. #endregion
  157. #region properties
  158. /// <summary>
  159. /// The row number of the entry in the selected data set.
  160. /// </summary>
  161. public long RowNumber
  162. { get { return _rowNumber; } }
  163. /// <summary>
  164. /// The time stamp of the log entry.
  165. /// </summary>
  166. public DateTime Timestamp
  167. { get { return _timestamp; } }
  168. /// <summary>
  169. /// The client IP address of the request.
  170. /// </summary>
  171. public IPAddress ClientIpAddress
  172. { get { return _clientIpAddress; } }
  173. /// <summary>
  174. /// The DNS transport protocol of the request.
  175. /// </summary>
  176. public DnsTransportProtocol Protocol
  177. { get { return _protocol; } }
  178. /// <summary>
  179. /// The type of response sent by the DNS server.
  180. /// </summary>
  181. public DnsServerResponseType ResponseType
  182. { get { return _responseType; } }
  183. /// <summary>
  184. /// The response code sent by the DNS server.
  185. /// </summary>
  186. public DnsResponseCode RCODE
  187. { get { return _rcode; } }
  188. /// <summary>
  189. /// The question section in the request.
  190. /// </summary>
  191. public DnsQuestionRecord Question
  192. { get { return _question; } }
  193. /// <summary>
  194. /// The answer in text format sent by the DNS server.
  195. /// </summary>
  196. public string Answer
  197. { get { return _answer; } }
  198. #endregion
  199. }
  200. }