// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org)
package org.xbill.DNS;
import java.net.*;
import java.io.*;
import java.util.*;
/**
* Well Known Services - Lists services offered by this host.
*
* @author Brian Wellington
*/
public class WKSRecord extends Record {
private static final long serialVersionUID = -9104259763909119805L;
public static class Protocol {
/**
* IP protocol identifiers. This is basically copied out of RFC 1010.
*/
private Protocol() {}
/** Internet Control Message */
public static final int ICMP = 1;
/** Internet Group Management */
public static final int IGMP = 2;
/** Gateway-to-Gateway */
public static final int GGP = 3;
/** Stream */
public static final int ST = 5;
/** Transmission Control */
public static final int TCP = 6;
/** UCL */
public static final int UCL = 7;
/** Exterior Gateway Protocol */
public static final int EGP = 8;
/** any private interior gateway */
public static final int IGP = 9;
/** BBN RCC Monitoring */
public static final int BBN_RCC_MON = 10;
/** Network Voice Protocol */
public static final int NVP_II = 11;
/** PUP */
public static final int PUP = 12;
/** ARGUS */
public static final int ARGUS = 13;
/** EMCON */
public static final int EMCON = 14;
/** Cross Net Debugger */
public static final int XNET = 15;
/** Chaos */
public static final int CHAOS = 16;
/** User Datagram */
public static final int UDP = 17;
/** Multiplexing */
public static final int MUX = 18;
/** DCN Measurement Subsystems */
public static final int DCN_MEAS = 19;
/** Host Monitoring */
public static final int HMP = 20;
/** Packet Radio Measurement */
public static final int PRM = 21;
/** XEROX NS IDP */
public static final int XNS_IDP = 22;
/** Trunk-1 */
public static final int TRUNK_1 = 23;
/** Trunk-2 */
public static final int TRUNK_2 = 24;
/** Leaf-1 */
public static final int LEAF_1 = 25;
/** Leaf-2 */
public static final int LEAF_2 = 26;
/** Reliable Data Protocol */
public static final int RDP = 27;
/** Internet Reliable Transaction */
public static final int IRTP = 28;
/** ISO Transport Protocol Class 4 */
public static final int ISO_TP4 = 29;
/** Bulk Data Transfer Protocol */
public static final int NETBLT = 30;
/** MFE Network Services Protocol */
public static final int MFE_NSP = 31;
/** MERIT Internodal Protocol */
public static final int MERIT_INP = 32;
/** Sequential Exchange Protocol */
public static final int SEP = 33;
/** CFTP */
public static final int CFTP = 62;
/** SATNET and Backroom EXPAK */
public static final int SAT_EXPAK = 64;
/** MIT Subnet Support */
public static final int MIT_SUBNET = 65;
/** MIT Remote Virtual Disk Protocol */
public static final int RVD = 66;
/** Internet Pluribus Packet Core */
public static final int IPPC = 67;
/** SATNET Monitoring */
public static final int SAT_MON = 69;
/** Internet Packet Core Utility */
public static final int IPCV = 71;
/** Backroom SATNET Monitoring */
public static final int BR_SAT_MON = 76;
/** WIDEBAND Monitoring */
public static final int WB_MON = 78;
/** WIDEBAND EXPAK */
public static final int WB_EXPAK = 79;
private static Mnemonic protocols = new Mnemonic("IP protocol",
Mnemonic.CASE_LOWER);
static {
protocols.setMaximum(0xFF);
protocols.setNumericAllowed(true);
protocols.add(ICMP, "icmp");
protocols.add(IGMP, "igmp");
protocols.add(GGP, "ggp");
protocols.add(ST, "st");
protocols.add(TCP, "tcp");
protocols.add(UCL, "ucl");
protocols.add(EGP, "egp");
protocols.add(IGP, "igp");
protocols.add(BBN_RCC_MON, "bbn-rcc-mon");
protocols.add(NVP_II, "nvp-ii");
protocols.add(PUP, "pup");
protocols.add(ARGUS, "argus");
protocols.add(EMCON, "emcon");
protocols.add(XNET, "xnet");
protocols.add(CHAOS, "chaos");
protocols.add(UDP, "udp");
protocols.add(MUX, "mux");
protocols.add(DCN_MEAS, "dcn-meas");
protocols.add(HMP, "hmp");
protocols.add(PRM, "prm");
protocols.add(XNS_IDP, "xns-idp");
protocols.add(TRUNK_1, "trunk-1");
protocols.add(TRUNK_2, "trunk-2");
protocols.add(LEAF_1, "leaf-1");
protocols.add(LEAF_2, "leaf-2");
protocols.add(RDP, "rdp");
protocols.add(IRTP, "irtp");
protocols.add(ISO_TP4, "iso-tp4");
protocols.add(NETBLT, "netblt");
protocols.add(MFE_NSP, "mfe-nsp");
protocols.add(MERIT_INP, "merit-inp");
protocols.add(SEP, "sep");
protocols.add(CFTP, "cftp");
protocols.add(SAT_EXPAK, "sat-expak");
protocols.add(MIT_SUBNET, "mit-subnet");
protocols.add(RVD, "rvd");
protocols.add(IPPC, "ippc");
protocols.add(SAT_MON, "sat-mon");
protocols.add(IPCV, "ipcv");
protocols.add(BR_SAT_MON, "br-sat-mon");
protocols.add(WB_MON, "wb-mon");
protocols.add(WB_EXPAK, "wb-expak");
}
/**
* Converts an IP protocol value into its textual representation
*/
public static String
string(int type) {
return protocols.getText(type);
}
/**
* Converts a textual representation of an IP protocol into its
* numeric code. Integers in the range 0..255 are also accepted.
* @param s The textual representation of the protocol
* @return The protocol code, or -1 on error.
*/
public static int
value(String s) {
return protocols.getValue(s);
}
}
public static class Service {
/**
* TCP/UDP services. This is basically copied out of RFC 1010,
* with MIT-ML-DEV removed, as it is not unique, and the description
* of SWIFT-RVF fixed.
*/
private Service() {}
/** Remote Job Entry */
public static final int RJE = 5;
/** Echo */
public static final int ECHO = 7;
/** Discard */
public static final int DISCARD = 9;
/** Active Users */
public static final int USERS = 11;
/** Daytime */
public static final int DAYTIME = 13;
/** Quote of the Day */
public static final int QUOTE = 17;
/** Character Generator */
public static final int CHARGEN = 19;
/** File Transfer [Default Data] */
public static final int FTP_DATA = 20;
/** File Transfer [Control] */
public static final int FTP = 21;
/** Telnet */
public static final int TELNET = 23;
/** Simple Mail Transfer */
public static final int SMTP = 25;
/** NSW User System FE */
public static final int NSW_FE = 27;
/** MSG ICP */
public static final int MSG_ICP = 29;
/** MSG Authentication */
public static final int MSG_AUTH = 31;
/** Display Support Protocol */
public static final int DSP = 33;
/** Time */
public static final int TIME = 37;
/** Resource Location Protocol */
public static final int RLP = 39;
/** Graphics */
public static final int GRAPHICS = 41;
/** Host Name Server */
public static final int NAMESERVER = 42;
/** Who Is */
public static final int NICNAME = 43;
/** MPM FLAGS Protocol */
public static final int MPM_FLAGS = 44;
/** Message Processing Module [recv] */
public static final int MPM = 45;
/** MPM [default send] */
public static final int MPM_SND = 46;
/** NI FTP */
public static final int NI_FTP = 47;
/** Login Host Protocol */
public static final int LOGIN = 49;
/** IMP Logical Address Maintenance */
public static final int LA_MAINT = 51;
/** Domain Name Server */
public static final int DOMAIN = 53;
/** ISI Graphics Language */
public static final int ISI_GL = 55;
/** NI MAIL */
public static final int NI_MAIL = 61;
/** VIA Systems - FTP */
public static final int VIA_FTP = 63;
/** TACACS-Database Service */
public static final int TACACS_DS = 65;
/** Bootstrap Protocol Server */
public static final int BOOTPS = 67;
/** Bootstrap Protocol Client */
public static final int BOOTPC = 68;
/** Trivial File Transfer */
public static final int TFTP = 69;
/** Remote Job Service */
public static final int NETRJS_1 = 71;
/** Remote Job Service */
public static final int NETRJS_2 = 72;
/** Remote Job Service */
public static final int NETRJS_3 = 73;
/** Remote Job Service */
public static final int NETRJS_4 = 74;
/** Finger */
public static final int FINGER = 79;
/** HOSTS2 Name Server */
public static final int HOSTS2_NS = 81;
/** SU/MIT Telnet Gateway */
public static final int SU_MIT_TG = 89;
/** MIT Dover Spooler */
public static final int MIT_DOV = 91;
/** Device Control Protocol */
public static final int DCP = 93;
/** SUPDUP */
public static final int SUPDUP = 95;
/** Swift Remote Virtual File Protocol */
public static final int SWIFT_RVF = 97;
/** TAC News */
public static final int TACNEWS = 98;
/** Metagram Relay */
public static final int METAGRAM = 99;
/** NIC Host Name Server */
public static final int HOSTNAME = 101;
/** ISO-TSAP */
public static final int ISO_TSAP = 102;
/** X400 */
public static final int X400 = 103;
/** X400-SND */
public static final int X400_SND = 104;
/** Mailbox Name Nameserver */
public static final int CSNET_NS = 105;
/** Remote Telnet Service */
public static final int RTELNET = 107;
/** Post Office Protocol - Version 2 */
public static final int POP_2 = 109;
/** SUN Remote Procedure Call */
public static final int SUNRPC = 111;
/** Authentication Service */
public static final int AUTH = 113;
/** Simple File Transfer Protocol */
public static final int SFTP = 115;
/** UUCP Path Service */
public static final int UUCP_PATH = 117;
/** Network News Transfer Protocol */
public static final int NNTP = 119;
/** HYDRA Expedited Remote Procedure */
public static final int ERPC = 121;
/** Network Time Protocol */
public static final int NTP = 123;
/** Locus PC-Interface Net Map Server */
public static final int LOCUS_MAP = 125;
/** Locus PC-Interface Conn Server */
public static final int LOCUS_CON = 127;
/** Password Generator Protocol */
public static final int PWDGEN = 129;
/** CISCO FNATIVE */
public static final int CISCO_FNA = 130;
/** CISCO TNATIVE */
public static final int CISCO_TNA = 131;
/** CISCO SYSMAINT */
public static final int CISCO_SYS = 132;
/** Statistics Service */
public static final int STATSRV = 133;
/** INGRES-NET Service */
public static final int INGRES_NET = 134;
/** Location Service */
public static final int LOC_SRV = 135;
/** PROFILE Naming System */
public static final int PROFILE = 136;
/** NETBIOS Name Service */
public static final int NETBIOS_NS = 137;
/** NETBIOS Datagram Service */
public static final int NETBIOS_DGM = 138;
/** NETBIOS Session Service */
public static final int NETBIOS_SSN = 139;
/** EMFIS Data Service */
public static final int EMFIS_DATA = 140;
/** EMFIS Control Service */
public static final int EMFIS_CNTL = 141;
/** Britton-Lee IDM */
public static final int BL_IDM = 142;
/** Survey Measurement */
public static final int SUR_MEAS = 243;
/** LINK */
public static final int LINK = 245;
private static Mnemonic services = new Mnemonic("TCP/UDP service",
Mnemonic.CASE_LOWER);
static {
services.setMaximum(0xFFFF);
services.setNumericAllowed(true);
services.add(RJE, "rje");
services.add(ECHO, "echo");
services.add(DISCARD, "discard");
services.add(USERS, "users");
services.add(DAYTIME, "daytime");
services.add(QUOTE, "quote");
services.add(CHARGEN, "chargen");
services.add(FTP_DATA, "ftp-data");
services.add(FTP, "ftp");
services.add(TELNET, "telnet");
services.add(SMTP, "smtp");
services.add(NSW_FE, "nsw-fe");
services.add(MSG_ICP, "msg-icp");
services.add(MSG_AUTH, "msg-auth");
services.add(DSP, "dsp");
services.add(TIME, "time");
services.add(RLP, "rlp");
services.add(GRAPHICS, "graphics");
services.add(NAMESERVER, "nameserver");
services.add(NICNAME, "nicname");
services.add(MPM_FLAGS, "mpm-flags");
services.add(MPM, "mpm");
services.add(MPM_SND, "mpm-snd");
services.add(NI_FTP, "ni-ftp");
services.add(LOGIN, "login");
services.add(LA_MAINT, "la-maint");
services.add(DOMAIN, "domain");
services.add(ISI_GL, "isi-gl");
services.add(NI_MAIL, "ni-mail");
services.add(VIA_FTP, "via-ftp");
services.add(TACACS_DS, "tacacs-ds");
services.add(BOOTPS, "bootps");
services.add(BOOTPC, "bootpc");
services.add(TFTP, "tftp");
services.add(NETRJS_1, "netrjs-1");
services.add(NETRJS_2, "netrjs-2");
services.add(NETRJS_3, "netrjs-3");
services.add(NETRJS_4, "netrjs-4");
services.add(FINGER, "finger");
services.add(HOSTS2_NS, "hosts2-ns");
services.add(SU_MIT_TG, "su-mit-tg");
services.add(MIT_DOV, "mit-dov");
services.add(DCP, "dcp");
services.add(SUPDUP, "supdup");
services.add(SWIFT_RVF, "swift-rvf");
services.add(TACNEWS, "tacnews");
services.add(METAGRAM, "metagram");
services.add(HOSTNAME, "hostname");
services.add(ISO_TSAP, "iso-tsap");
services.add(X400, "x400");
services.add(X400_SND, "x400-snd");
services.add(CSNET_NS, "csnet-ns");
services.add(RTELNET, "rtelnet");
services.add(POP_2, "pop-2");
services.add(SUNRPC, "sunrpc");
services.add(AUTH, "auth");
services.add(SFTP, "sftp");
services.add(UUCP_PATH, "uucp-path");
services.add(NNTP, "nntp");
services.add(ERPC, "erpc");
services.add(NTP, "ntp");
services.add(LOCUS_MAP, "locus-map");
services.add(LOCUS_CON, "locus-con");
services.add(PWDGEN, "pwdgen");
services.add(CISCO_FNA, "cisco-fna");
services.add(CISCO_TNA, "cisco-tna");
services.add(CISCO_SYS, "cisco-sys");
services.add(STATSRV, "statsrv");
services.add(INGRES_NET, "ingres-net");
services.add(LOC_SRV, "loc-srv");
services.add(PROFILE, "profile");
services.add(NETBIOS_NS, "netbios-ns");
services.add(NETBIOS_DGM, "netbios-dgm");
services.add(NETBIOS_SSN, "netbios-ssn");
services.add(EMFIS_DATA, "emfis-data");
services.add(EMFIS_CNTL, "emfis-cntl");
services.add(BL_IDM, "bl-idm");
services.add(SUR_MEAS, "sur-meas");
services.add(LINK, "link");
}
/**
* Converts a TCP/UDP service port number into its textual
* representation.
*/
public static String
string(int type) {
return services.getText(type);
}
/**
* Converts a textual representation of a TCP/UDP service into its
* port number. Integers in the range 0..65535 are also accepted.
* @param s The textual representation of the service.
* @return The port number, or -1 on error.
*/
public static int
value(String s) {
return services.getValue(s);
}
}
private byte [] address;
private int protocol;
private int [] services;
WKSRecord() {}
Record
getObject() {
return new WKSRecord();
}
/**
* Creates a WKS Record from the given data
* @param address The IP address
* @param protocol The IP protocol number
* @param services An array of supported services, represented by port number.
*/
public
WKSRecord(Name name, int dclass, long ttl, InetAddress address, int protocol,
int [] services)
{
super(name, Type.WKS, dclass, ttl);
if (Address.familyOf(address) != Address.IPv4)
throw new IllegalArgumentException("invalid IPv4 address");
this.address = address.getAddress();
this.protocol = checkU8("protocol", protocol);
for (int i = 0; i < services.length; i++) {
checkU16("service", services[i]);
}
this.services = new int[services.length];
System.arraycopy(services, 0, this.services, 0, services.length);
Arrays.sort(this.services);
}
void
rrFromWire(DNSInput in) throws IOException {
address = in.readByteArray(4);
protocol = in.readU8();
byte [] array = in.readByteArray();
List list = new ArrayList();
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < 8; j++) {
int octet = array[i] & 0xFF;
if ((octet & (1 << (7 - j))) != 0) {
list.add(new Integer(i * 8 + j));
}
}
}
services = new int[list.size()];
for (int i = 0; i < list.size(); i++) {
services[i] = ((Integer) list.get(i)).intValue();
}
}
void
rdataFromString(Tokenizer st, Name origin) throws IOException {
String s = st.getString();
address = Address.toByteArray(s, Address.IPv4);
if (address == null)
throw st.exception("invalid address");
s = st.getString();
protocol = Protocol.value(s);
if (protocol < 0) {
throw st.exception("Invalid IP protocol: " + s);
}
List list = new ArrayList();
while (true) {
Tokenizer.Token t = st.get();
if (!t.isString())
break;
int service = Service.value(t.value);
if (service < 0) {
throw st.exception("Invalid TCP/UDP service: " +
t.value);
}
list.add(new Integer(service));
}
st.unget();
services = new int[list.size()];
for (int i = 0; i < list.size(); i++) {
services[i] = ((Integer) list.get(i)).intValue();
}
}
/**
* Converts rdata to a String
*/
String
rrToString() {
StringBuffer sb = new StringBuffer();
sb.append(Address.toDottedQuad(address));
sb.append(" ");
sb.append(protocol);
for (int i = 0; i < services.length; i++) {
sb.append(" " + services[i]);
}
return sb.toString();
}
/**
* Returns the IP address.
*/
public InetAddress
getAddress() {
try {
return InetAddress.getByAddress(address);
} catch (UnknownHostException e) {
return null;
}
}
/**
* Returns the IP protocol.
*/
public int
getProtocol() {
return protocol;
}
/**
* Returns the services provided by the host on the specified address.
*/
public int []
getServices() {
return services;
}
void
rrToWire(DNSOutput out, Compression c, boolean canonical) {
out.writeByteArray(address);
out.writeU8(protocol);
int highestPort = services[services.length - 1];
byte [] array = new byte[highestPort / 8 + 1];
for (int i = 0; i < services.length; i++) {
int port = services[i];
array[port / 8] |= (1 << (7 - port % 8));
}
out.writeByteArray(array);
}
}