Simple library to encode/decode DNS wire-format packets
npx @tessl/cli install tessl/pypi-dnslib@0.9.00
# dnslib
1
2
A comprehensive Python library for DNS wire-format packet encoding and decoding. Provides support for converting DNS packets between wire format, Python objects, and Zone/DiG textual representations, along with a server framework for creating custom DNS resolvers and utility modules for testing and development.
3
4
## Package Information
5
6
- **Package Name**: dnslib
7
- **Language**: Python
8
- **Installation**: `pip install dnslib`
9
- **GitHub**: https://github.com/paulc/dnslib
10
- **Version**: 0.9.26 (maintenance mode)
11
12
## Core Imports
13
14
```python
15
import dnslib
16
```
17
18
Most common usage imports all DNS functionality:
19
20
```python
21
from dnslib import *
22
```
23
24
Module-specific imports:
25
26
```python
27
from dnslib.server import DNSServer, BaseResolver
28
from dnslib.client import DiG
29
from dnslib.proxy import ProxyResolver
30
```
31
32
## Basic Usage
33
34
```python
35
import binascii
36
from dnslib import *
37
38
# Parse a DNS packet from wire format
39
packet = binascii.unhexlify(b'd5ad818000010005000000000377777706676f6f676c6503636f6d0000010001c00c0005000100000005000803777777016cc010c02c0001000100000005000442f95b68c02c0001000100000005000442f95b63c02c0001000100000005000442f95b67c02c0001000100000005000442f95b93')
40
d = DNSRecord.parse(packet)
41
print(d) # Zone file format output
42
43
# Create a DNS query
44
q = DNSRecord.question("google.com")
45
print(q)
46
47
# Create a DNS query with specific record type
48
q = DNSRecord.question("google.com", "MX")
49
print(q)
50
51
# Create a DNS response
52
response = DNSRecord(
53
DNSHeader(qr=1, aa=1, ra=1),
54
q=DNSQuestion("example.com"),
55
a=RR("example.com", rdata=A("1.2.3.4"))
56
)
57
print(response)
58
59
# Create records from zone file format
60
rr = RR.fromZone("example.com IN A 1.2.3.4")
61
print(rr[0])
62
63
# Create a reply to a query
64
q = DNSRecord.question("example.com")
65
a = q.reply()
66
a.add_answer(*RR.fromZone("example.com 60 A 1.2.3.4"))
67
print(a)
68
```
69
70
## Architecture
71
72
dnslib follows the standard DNS packet structure with these key components:
73
74
- **DNSRecord**: Top-level container for complete DNS packets with header, questions, answers, authority, and additional sections
75
- **DNSHeader**: Packet header with ID, flags, and section counts
76
- **DNSQuestion**: Query section specifying name, type, and class
77
- **RR (Resource Record)**: Answer, authority, and additional sections containing name, type, class, TTL, and resource data
78
- **Resource Data Types**: Specific implementations for each DNS record type (A, AAAA, MX, CNAME, etc.)
79
- **DNSLabel**: DNS name representation with IDNA encoding support
80
81
The library provides three main representations:
82
- **Wire Format**: Binary DNS packet format for network transmission
83
- **Python Objects**: Structured classes for programmatic manipulation
84
- **Zone/DiG Format**: Human-readable textual representation
85
86
## Capabilities
87
88
### DNS Packet Handling
89
90
Core DNS packet encoding, decoding, and manipulation functionality supporting all standard DNS record types and DNSSEC extensions.
91
92
```python { .api }
93
class DNSRecord:
94
def __init__(self, header=None, q=None, a=None, auth=None, ar=None): ...
95
@classmethod
96
def parse(cls, packet): ...
97
@classmethod
98
def question(cls, qname, qtype="A", qclass="IN"): ...
99
def pack(self): ...
100
def reply(self, ra=1, aa=1): ...
101
def replyZone(self, zone): ...
102
def add_question(self, q): ...
103
def add_answer(self, *rr): ...
104
def add_auth(self, *rr): ...
105
def add_ar(self, *rr): ...
106
107
class DNSHeader:
108
def __init__(self, id=None, **kwargs): ...
109
def pack(self): ...
110
@classmethod
111
def parse(cls, buffer): ...
112
113
class DNSQuestion:
114
def __init__(self, qname, qtype="A", qclass="IN"): ...
115
def pack(self): ...
116
@classmethod
117
def parse(cls, buffer): ...
118
119
class RR:
120
def __init__(self, rname, rtype="A", rclass="IN", ttl=0, rdata=None): ...
121
def pack(self): ...
122
@classmethod
123
def parse(cls, buffer): ...
124
@classmethod
125
def fromZone(cls, zone): ...
126
```
127
128
[DNS Core Functionality](./dns-core.md)
129
130
### DNS Resource Records
131
132
Comprehensive support for DNS resource record types including address records, mail exchange, name servers, text records, and DNSSEC extensions.
133
134
```python { .api }
135
class A:
136
def __init__(self, data): ...
137
138
class AAAA:
139
def __init__(self, data): ...
140
141
class MX:
142
def __init__(self, preference, mx): ...
143
144
class CNAME:
145
def __init__(self, label): ...
146
147
class TXT:
148
def __init__(self, data): ...
149
150
class SOA:
151
def __init__(self, mname, rname, times): ...
152
```
153
154
[DNS Resource Records](./dns-records.md)
155
156
### DNS Server Framework
157
158
Framework for creating custom DNS resolvers with UDP/TCP server support, request handling, and logging capabilities.
159
160
```python { .api }
161
class DNSServer:
162
def __init__(self, resolver, port=53, address="", logger=None, **kwargs): ...
163
def start(self): ...
164
def start_thread(self): ...
165
166
class BaseResolver:
167
def resolve(self, request, handler): ...
168
169
class DNSLogger:
170
def __init__(self, log="request,reply,truncated,error", prefix=True, logf=None): ...
171
def log_recv(self, handler, data): ...
172
def log_send(self, handler, data): ...
173
```
174
175
[DNS Server Framework](./dns-server.md)
176
177
### DNS Client Utilities
178
179
DiG-like DNS client functionality for querying DNS servers, comparing responses, and debugging DNS configurations.
180
181
```python { .api }
182
class DiG:
183
def __init__(self, **kwargs): ...
184
def query(self, name, qtype="A", qclass="IN", **kwargs): ...
185
def compare(self, response1, response2): ...
186
```
187
188
[DNS Client Utilities](./dns-client.md)
189
190
### DNS Resolver Implementations
191
192
Ready-to-use resolver implementations including proxy resolvers, fixed response resolvers, zone file resolvers, and shell script resolvers.
193
194
```python { .api }
195
class ProxyResolver(BaseResolver):
196
def __init__(self, address, port, timeout=0): ...
197
def resolve(self, request, handler): ...
198
199
class FixedResolver(BaseResolver):
200
def __init__(self, zone): ...
201
def resolve(self, request, handler): ...
202
203
class ZoneResolver(BaseResolver):
204
def __init__(self, zone, glob=False): ...
205
def resolve(self, request, handler): ...
206
```
207
208
[DNS Resolvers](./dns-resolvers.md)
209
210
## Constants and Mappings
211
212
```python { .api }
213
# DNS record type mappings
214
QTYPE = Bimap(A=1, NS=2, CNAME=5, SOA=6, MX=15, TXT=16, AAAA=28, ...)
215
216
# DNS class mappings
217
CLASS = Bimap(IN=1, CS=2, CH=3, HS=4)
218
219
# Response code mappings
220
RCODE = Bimap(NOERROR=0, FORMERR=1, SERVFAIL=2, NXDOMAIN=3, ...)
221
222
# Operation code mappings
223
OPCODE = Bimap(QUERY=0, IQUERY=1, STATUS=2, NOTIFY=4, UPDATE=5)
224
225
# Query/Response flag
226
QR = Bimap(QUERY=0, RESPONSE=1)
227
```
228
229
## Exception Classes
230
231
```python { .api }
232
class DNSError(Exception): ...
233
class DNSLabelError(Exception): ...
234
class BufferError(Exception): ...
235
class BimapError(Exception): ...
236
```
237
238
## Command Line Interface
239
240
dnslib provides several command-line utilities accessible via Python module execution:
241
242
- **DNS Client**: `python -m dnslib.client --help`
243
- **DNS Proxy Server**: `python -m dnslib.proxy --help`
244
- **Intercepting Proxy**: `python -m dnslib.intercept --help`
245
- **Fixed Response Resolver**: `python -m dnslib.fixedresolver --help`
246
- **Zone File Resolver**: `python -m dnslib.zoneresolver --help`
247
- **Shell Script Resolver**: `python -m dnslib.shellresolver --help`