from __future__ import print_function
from __future__ import division
+import math
import socket
import struct
import dns
"""" Determines whether this instance is using the draft option code """
return self.option == DRAFT_OPTION_CODE
- def to_wire(self, file):
+ def to_wire(self, file=None):
"""Create EDNS packet as defined in draft-vandergaast-edns-client-subnet-01."""
ip = self.calculate_ip()
format = "!HBB%ds" % (mask_bits // 8)
data = struct.pack(format, self.family, self.mask, self.scope, test)
- file.write(data)
+ if file:
+ file.write(data)
+ else:
+ return data
def from_wire(cls, otype, wire, current, olen):
"""Read EDNS packet as defined in draft-vandergaast-edns-client-subnet-01.
from_wire = classmethod(from_wire)
+ # needed in 2.0.0..
+ @classmethod
+ def from_wire_parser(cls, otype, parser):
+ family, src, scope = parser.get_struct('!HBB')
+ addrlen = int(math.ceil(src / 8.0))
+ prefix = parser.get_bytes(addrlen)
+ if family == 1:
+ pad = 4 - addrlen
+ addr = dns.ipv4.inet_ntoa(prefix + b'\x00' * pad)
+ elif family == 2:
+ pad = 16 - addrlen
+ addr = dns.ipv6.inet_ntoa(prefix + b'\x00' * pad)
+ else:
+ raise ValueError('unsupported family')
+
+ return cls(addr, src, scope, otype)
+
def __repr__(self):
if self.family == FAMILY_IPV4:
ip = socket.inet_ntop(socket.AF_INET, struct.pack('!L', self.ip))
self.client = client
self.server = server
- def to_wire(self, file):
+ def to_wire(self, file=None):
"""Create EDNS packet as defined in draft-ietf-dnsop-cookies-09."""
- file.write(self.client)
if self.server and len(self.server) > 0:
- file.write(self.server)
+ data = self.client + self.server
+ else:
+ data = self.client
+
+ if file:
+ file.write(data)
+ else:
+ return data
def from_wire(cls, otype, wire, current, olen):
"""Read EDNS packet as defined in draft-ietf-dnsop-cookies-09.
from_wire = classmethod(from_wire)
+ # needed in 2.0.0
+ @classmethod
+ def from_wire_parser(cls, otype, parser):
+ data = parser.get_remaining()
+
+ if len(data) != 8 and (len(data) < 16 or len(data) > 40):
+ raise Exception('Invalid EDNS Cookies option')
+
+ client = data[:8]
+ if len(data) > 8:
+ server = data[8:]
+ else:
+ server = None
+
+ return cls(client, server)
+
def __repr__(self):
return '%s(%s, %s)' % (
self.__class__.__name__,
dns.edns._type_to_class[0x000A] = CookiesOption
-