]>
git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.util/src/org/argeo/util/naming/dns/DnsBrowser.java
376c51edc4b1fbc0b53cb1f109d7d8fdf25186fc
1 package org
.argeo
.util
.naming
.dns
;
3 import java
.io
.Closeable
;
4 import java
.io
.IOException
;
5 import java
.io
.PrintStream
;
6 import java
.util
.ArrayList
;
7 import java
.util
.Base64
;
8 import java
.util
.Collections
;
9 import java
.util
.Hashtable
;
10 import java
.util
.List
;
12 import java
.util
.Objects
;
13 import java
.util
.SortedSet
;
14 import java
.util
.StringJoiner
;
15 import java
.util
.TreeMap
;
16 import java
.util
.TreeSet
;
18 import javax
.naming
.Binding
;
19 import javax
.naming
.Context
;
20 import javax
.naming
.NameNotFoundException
;
21 import javax
.naming
.NamingEnumeration
;
22 import javax
.naming
.NamingException
;
23 import javax
.naming
.directory
.Attribute
;
24 import javax
.naming
.directory
.Attributes
;
25 import javax
.naming
.directory
.DirContext
;
26 import javax
.naming
.directory
.InitialDirContext
;
28 public class DnsBrowser
implements Closeable
{
29 private final DirContext initialCtx
;
31 public DnsBrowser() throws NamingException
{
32 this(new ArrayList
<>());
35 public DnsBrowser(List
<String
> dnsServerUrls
) throws NamingException
{
36 Objects
.requireNonNull(dnsServerUrls
);
37 Hashtable
<String
, Object
> env
= new Hashtable
<>();
38 env
.put(Context
.INITIAL_CONTEXT_FACTORY
, "com.sun.jndi.dns.DnsContextFactory");
39 if (!dnsServerUrls
.isEmpty()) {
40 boolean specified
= false;
41 StringJoiner providerUrl
= new StringJoiner(" ");
42 for (String dnsUrl
: dnsServerUrls
) {
44 providerUrl
.add(dnsUrl
);
49 env
.put(Context
.PROVIDER_URL
, providerUrl
.toString());
51 initialCtx
= new InitialDirContext(env
);
54 public Map
<String
, List
<String
>> getAllRecords(String name
) throws NamingException
{
55 Map
<String
, List
<String
>> res
= new TreeMap
<>();
56 Attributes attrs
= initialCtx
.getAttributes(name
);
57 NamingEnumeration
<String
> ids
= attrs
.getIDs();
58 while (ids
.hasMore()) {
59 String recordType
= ids
.next();
60 List
<String
> lst
= new ArrayList
<String
>();
61 res
.put(recordType
, lst
);
62 Attribute attr
= attrs
.get(recordType
);
65 return Collections
.unmodifiableMap(res
);
69 * Return a single record (typically A, AAAA, etc. or null if not available.
70 * Will fail if multiple records.
72 public String
getRecord(String name
, String recordType
) {
74 Attributes attrs
= initialCtx
.getAttributes(name
, new String
[] { recordType
});
75 if (attrs
.size() == 0)
77 Attribute attr
= attrs
.get(recordType
);
79 throw new IllegalArgumentException("Multiple record type " + recordType
);
80 assert attr
.size() != 0;
81 Object value
= attr
.get();
83 return value
.toString();
84 } catch (NameNotFoundException e
) {
86 } catch (NamingException e
) {
87 throw new IllegalStateException("Cannot get DNS entry " + recordType
+ " of " + name
, e
);
92 * Return records of a given type.
94 public List
<String
> getRecords(String name
, String recordType
) throws NamingException
{
95 List
<String
> res
= new ArrayList
<String
>();
96 Attributes attrs
= initialCtx
.getAttributes(name
, new String
[] { recordType
});
97 Attribute attr
= attrs
.get(recordType
);
102 /** Ordered, with preferred first. */
103 public List
<String
> getSrvRecordsAsHosts(String name
, boolean withPort
) throws NamingException
{
104 List
<String
> raw
= getRecords(name
, "SRV");
107 SortedSet
<SrvRecord
> res
= new TreeSet
<>();
108 for (int i
= 0; i
< raw
.size(); i
++) {
109 String record
= raw
.get(i
);
110 String
[] arr
= record
.split(" ");
111 Integer priority
= Integer
.parseInt(arr
[0]);
112 Integer weight
= Integer
.parseInt(arr
[1]);
113 Integer port
= Integer
.parseInt(arr
[2]);
114 String hostname
= arr
[3];
115 SrvRecord order
= new SrvRecord(priority
, weight
, port
, hostname
);
118 List
<String
> lst
= new ArrayList
<>();
119 for (SrvRecord order
: res
) {
120 lst
.add(order
.toHost(withPort
));
122 return Collections
.unmodifiableList(lst
);
125 private void addValues(Attribute attr
, List
<String
> lst
) throws NamingException
{
126 NamingEnumeration
<?
> values
= attr
.getAll();
127 while (values
.hasMore()) {
128 Object value
= values
.next();
130 if (value
instanceof byte[]) {
131 String str
= Base64
.getEncoder().encodeToString((byte[]) value
);
134 lst
.add(value
.toString());
140 public List
<String
> listEntries(String name
) throws NamingException
{
141 List
<String
> res
= new ArrayList
<String
>();
142 NamingEnumeration
<Binding
> ne
= initialCtx
.listBindings(name
);
143 while (ne
.hasMore()) {
144 Binding b
= ne
.next();
145 res
.add(b
.getName());
147 return Collections
.unmodifiableList(res
);
151 public void close() throws IOException
{
155 public void destroy() {
158 } catch (NamingException e
) {
163 public static void main(String
[] args
) {
164 if (args
.length
== 0) {
165 printUsage(System
.err
);
168 try (DnsBrowser dnsBrowser
= new DnsBrowser()) {
169 String hostname
= args
[0];
170 String recordType
= args
.length
> 1 ? args
[1] : "A";
171 if (recordType
.equals("*")) {
172 Map
<String
, List
<String
>> records
= dnsBrowser
.getAllRecords(hostname
);
173 for (String type
: records
.keySet()) {
174 for (String record
: records
.get(type
)) {
176 if ("44".equals(type
))
178 else if ("46".equals(type
))
180 else if ("48".equals(type
))
181 typeLabel
= "DNSKEY";
184 System
.out
.println(typeLabel
+ "\t" + record
);
188 System
.out
.println(dnsBrowser
.getRecord(hostname
, recordType
));
191 } catch (Exception e
) {
196 public static void printUsage(PrintStream out
) {
197 out
.println("java org.argeo.naming.DnsBrowser <hostname> [<record type> | *]");