1 # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
3 # Permission to use, copy, modify, and distribute this software and its
4 # documentation for any purpose with or without fee is hereby granted,
5 # provided that the above copyright notice and this permission notice
6 # appear in all copies.
8 # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
9 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
11 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
14 # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 _proto_tcp
= socket
.getprotobyname('tcp')
23 _proto_udp
= socket
.getprotobyname('udp')
25 class WKS(dns
.rdata
.Rdata
):
28 @ivar address: the address
30 @ivar protocol: the protocol
32 @ivar bitmap: the bitmap
36 __slots__
= ['address', 'protocol', 'bitmap']
38 def __init__(self
, rdclass
, rdtype
, address
, protocol
, bitmap
):
39 super(WKS
, self
).__init
__(rdclass
, rdtype
)
40 self
.address
= address
41 self
.protocol
= protocol
44 def to_text(self
, origin
=None, relativize
=True, **kw
):
46 for i
in xrange(0, len(self
.bitmap
)):
47 byte
= ord(self
.bitmap
[i
])
48 for j
in xrange(0, 8):
49 if byte
& (0x80 >> j
):
50 bits
.append(str(i
* 8 + j
))
52 return '%s %d %s' % (self
.address
, self
.protocol
, text
)
54 def from_text(cls
, rdclass
, rdtype
, tok
, origin
= None, relativize
= True):
55 address
= tok
.get_string()
56 protocol
= tok
.get_string()
57 if protocol
.isdigit():
58 protocol
= int(protocol
)
60 protocol
= socket
.getprotobyname(protocol
)
63 token
= tok
.get().unescape()
64 if token
.is_eol_or_eof():
66 if token
.value
.isdigit():
67 serv
= int(token
.value
)
69 if protocol
!= _proto_udp
and protocol
!= _proto_tcp
:
70 raise NotImplementedError("protocol must be TCP or UDP")
71 if protocol
== _proto_udp
:
75 serv
= socket
.getservbyname(token
.value
, protocol_text
)
79 for j
in xrange(l
, i
+ 1):
81 bitmap
[i
] = chr(ord(bitmap
[i
]) |
(0x80 >> (serv
% 8)))
82 bitmap
= dns
.rdata
._truncate
_bitmap
(bitmap
)
83 return cls(rdclass
, rdtype
, address
, protocol
, bitmap
)
85 from_text
= classmethod(from_text
)
87 def to_wire(self
, file, compress
= None, origin
= None):
88 file.write(dns
.ipv4
.inet_aton(self
.address
))
89 protocol
= struct
.pack('!B', self
.protocol
)
91 file.write(self
.bitmap
)
93 def from_wire(cls
, rdclass
, rdtype
, wire
, current
, rdlen
, origin
= None):
94 address
= dns
.ipv4
.inet_ntoa(wire
[current
: current
+ 4])
95 protocol
, = struct
.unpack('!B', wire
[current
+ 4 : current
+ 5])
98 bitmap
= wire
[current
: current
+ rdlen
].unwrap()
99 return cls(rdclass
, rdtype
, address
, protocol
, bitmap
)
101 from_wire
= classmethod(from_wire
)
103 def _cmp(self
, other
):
104 sa
= dns
.ipv4
.inet_aton(self
.address
)
105 oa
= dns
.ipv4
.inet_aton(other
.address
)
108 sp
= struct
.pack('!B', self
.protocol
)
109 op
= struct
.pack('!B', other
.protocol
)
112 v
= cmp(self
.bitmap
, other
.bitmap
)