1// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org)
2
3package org.xbill.DNS;
4
5import java.net.*;
6import java.io.*;
7import java.util.*;
8
9/**
10 * Well Known Services - Lists services offered by this host.
11 *
12 * @author Brian Wellington
13 */
14
15public class WKSRecord extends Record {
16
17private static final long serialVersionUID = -9104259763909119805L;
18
19public static class Protocol {
20	/**
21	 * IP protocol identifiers.  This is basically copied out of RFC 1010.
22	 */
23
24	private Protocol() {}
25
26	/** Internet Control Message */
27	public static final int ICMP = 1;
28
29	/** Internet Group Management */
30	public static final int IGMP = 2;
31
32	/** Gateway-to-Gateway */
33	public static final int GGP = 3;
34
35	/** Stream */
36	public static final int ST = 5;
37
38	/** Transmission Control */
39	public static final int TCP = 6;
40
41	/** UCL */
42	public static final int UCL = 7;
43
44	/** Exterior Gateway Protocol */
45	public static final int EGP = 8;
46
47	/** any private interior gateway */
48	public static final int IGP = 9;
49
50	/** BBN RCC Monitoring */
51	public static final int BBN_RCC_MON = 10;
52
53	/** Network Voice Protocol */
54	public static final int NVP_II = 11;
55
56	/** PUP */
57	public static final int PUP = 12;
58
59	/** ARGUS */
60	public static final int ARGUS = 13;
61
62	/** EMCON */
63	public static final int EMCON = 14;
64
65	/** Cross Net Debugger */
66	public static final int XNET = 15;
67
68	/** Chaos */
69	public static final int CHAOS = 16;
70
71	/** User Datagram */
72	public static final int UDP = 17;
73
74	/** Multiplexing */
75	public static final int MUX = 18;
76
77	/** DCN Measurement Subsystems */
78	public static final int DCN_MEAS = 19;
79
80	/** Host Monitoring */
81	public static final int HMP = 20;
82
83	/** Packet Radio Measurement */
84	public static final int PRM = 21;
85
86	/** XEROX NS IDP */
87	public static final int XNS_IDP = 22;
88
89	/** Trunk-1 */
90	public static final int TRUNK_1 = 23;
91
92	/** Trunk-2 */
93	public static final int TRUNK_2 = 24;
94
95	/** Leaf-1 */
96	public static final int LEAF_1 = 25;
97
98	/** Leaf-2 */
99	public static final int LEAF_2 = 26;
100
101	/** Reliable Data Protocol */
102	public static final int RDP = 27;
103
104	/** Internet Reliable Transaction */
105	public static final int IRTP = 28;
106
107	/** ISO Transport Protocol Class 4 */
108	public static final int ISO_TP4 = 29;
109
110	/** Bulk Data Transfer Protocol */
111	public static final int NETBLT = 30;
112
113	/** MFE Network Services Protocol */
114	public static final int MFE_NSP = 31;
115
116	/** MERIT Internodal Protocol */
117	public static final int MERIT_INP = 32;
118
119	/** Sequential Exchange Protocol */
120	public static final int SEP = 33;
121
122	/** CFTP */
123	public static final int CFTP = 62;
124
125	/** SATNET and Backroom EXPAK */
126	public static final int SAT_EXPAK = 64;
127
128	/** MIT Subnet Support */
129	public static final int MIT_SUBNET = 65;
130
131	/** MIT Remote Virtual Disk Protocol */
132	public static final int RVD = 66;
133
134	/** Internet Pluribus Packet Core */
135	public static final int IPPC = 67;
136
137	/** SATNET Monitoring */
138	public static final int SAT_MON = 69;
139
140	/** Internet Packet Core Utility */
141	public static final int IPCV = 71;
142
143	/** Backroom SATNET Monitoring */
144	public static final int BR_SAT_MON = 76;
145
146	/** WIDEBAND Monitoring */
147	public static final int WB_MON = 78;
148
149	/** WIDEBAND EXPAK */
150	public static final int WB_EXPAK = 79;
151
152	private static Mnemonic protocols = new Mnemonic("IP protocol",
153							 Mnemonic.CASE_LOWER);
154
155	static {
156		protocols.setMaximum(0xFF);
157		protocols.setNumericAllowed(true);
158
159		protocols.add(ICMP, "icmp");
160		protocols.add(IGMP, "igmp");
161		protocols.add(GGP, "ggp");
162		protocols.add(ST, "st");
163		protocols.add(TCP, "tcp");
164		protocols.add(UCL, "ucl");
165		protocols.add(EGP, "egp");
166		protocols.add(IGP, "igp");
167		protocols.add(BBN_RCC_MON, "bbn-rcc-mon");
168		protocols.add(NVP_II, "nvp-ii");
169		protocols.add(PUP, "pup");
170		protocols.add(ARGUS, "argus");
171		protocols.add(EMCON, "emcon");
172		protocols.add(XNET, "xnet");
173		protocols.add(CHAOS, "chaos");
174		protocols.add(UDP, "udp");
175		protocols.add(MUX, "mux");
176		protocols.add(DCN_MEAS, "dcn-meas");
177		protocols.add(HMP, "hmp");
178		protocols.add(PRM, "prm");
179		protocols.add(XNS_IDP, "xns-idp");
180		protocols.add(TRUNK_1, "trunk-1");
181		protocols.add(TRUNK_2, "trunk-2");
182		protocols.add(LEAF_1, "leaf-1");
183		protocols.add(LEAF_2, "leaf-2");
184		protocols.add(RDP, "rdp");
185		protocols.add(IRTP, "irtp");
186		protocols.add(ISO_TP4, "iso-tp4");
187		protocols.add(NETBLT, "netblt");
188		protocols.add(MFE_NSP, "mfe-nsp");
189		protocols.add(MERIT_INP, "merit-inp");
190		protocols.add(SEP, "sep");
191		protocols.add(CFTP, "cftp");
192		protocols.add(SAT_EXPAK, "sat-expak");
193		protocols.add(MIT_SUBNET, "mit-subnet");
194		protocols.add(RVD, "rvd");
195		protocols.add(IPPC, "ippc");
196		protocols.add(SAT_MON, "sat-mon");
197		protocols.add(IPCV, "ipcv");
198		protocols.add(BR_SAT_MON, "br-sat-mon");
199		protocols.add(WB_MON, "wb-mon");
200		protocols.add(WB_EXPAK, "wb-expak");
201	}
202
203	/**
204	 * Converts an IP protocol value into its textual representation
205	 */
206	public static String
207	string(int type) {
208		return protocols.getText(type);
209	}
210
211	/**
212	 * Converts a textual representation of an IP protocol into its
213	 * numeric code.  Integers in the range 0..255 are also accepted.
214	 * @param s The textual representation of the protocol
215	 * @return The protocol code, or -1 on error.
216	 */
217	public static int
218	value(String s) {
219		return protocols.getValue(s);
220	}
221}
222
223public static class Service {
224	/**
225	 * TCP/UDP services.  This is basically copied out of RFC 1010,
226	 * with MIT-ML-DEV removed, as it is not unique, and the description
227	 * of SWIFT-RVF fixed.
228	 */
229
230	private Service() {}
231
232	/** Remote Job Entry */
233	public static final int RJE = 5;
234
235	/** Echo */
236	public static final int ECHO = 7;
237
238	/** Discard */
239	public static final int DISCARD = 9;
240
241	/** Active Users */
242	public static final int USERS = 11;
243
244	/** Daytime */
245	public static final int DAYTIME = 13;
246
247	/** Quote of the Day */
248	public static final int QUOTE = 17;
249
250	/** Character Generator */
251	public static final int CHARGEN = 19;
252
253	/** File Transfer [Default Data] */
254	public static final int FTP_DATA = 20;
255
256	/** File Transfer [Control] */
257	public static final int FTP = 21;
258
259	/** Telnet */
260	public static final int TELNET = 23;
261
262	/** Simple Mail Transfer */
263	public static final int SMTP = 25;
264
265	/** NSW User System FE */
266	public static final int NSW_FE = 27;
267
268	/** MSG ICP */
269	public static final int MSG_ICP = 29;
270
271	/** MSG Authentication */
272	public static final int MSG_AUTH = 31;
273
274	/** Display Support Protocol */
275	public static final int DSP = 33;
276
277	/** Time */
278	public static final int TIME = 37;
279
280	/** Resource Location Protocol */
281	public static final int RLP = 39;
282
283	/** Graphics */
284	public static final int GRAPHICS = 41;
285
286	/** Host Name Server */
287	public static final int NAMESERVER = 42;
288
289	/** Who Is */
290	public static final int NICNAME = 43;
291
292	/** MPM FLAGS Protocol */
293	public static final int MPM_FLAGS = 44;
294
295	/** Message Processing Module [recv] */
296	public static final int MPM = 45;
297
298	/** MPM [default send] */
299	public static final int MPM_SND = 46;
300
301	/** NI FTP */
302	public static final int NI_FTP = 47;
303
304	/** Login Host Protocol */
305	public static final int LOGIN = 49;
306
307	/** IMP Logical Address Maintenance */
308	public static final int LA_MAINT = 51;
309
310	/** Domain Name Server */
311	public static final int DOMAIN = 53;
312
313	/** ISI Graphics Language */
314	public static final int ISI_GL = 55;
315
316	/** NI MAIL */
317	public static final int NI_MAIL = 61;
318
319	/** VIA Systems - FTP */
320	public static final int VIA_FTP = 63;
321
322	/** TACACS-Database Service */
323	public static final int TACACS_DS = 65;
324
325	/** Bootstrap Protocol Server */
326	public static final int BOOTPS = 67;
327
328	/** Bootstrap Protocol Client */
329	public static final int BOOTPC = 68;
330
331	/** Trivial File Transfer */
332	public static final int TFTP = 69;
333
334	/** Remote Job Service */
335	public static final int NETRJS_1 = 71;
336
337	/** Remote Job Service */
338	public static final int NETRJS_2 = 72;
339
340	/** Remote Job Service */
341	public static final int NETRJS_3 = 73;
342
343	/** Remote Job Service */
344	public static final int NETRJS_4 = 74;
345
346	/** Finger */
347	public static final int FINGER = 79;
348
349	/** HOSTS2 Name Server */
350	public static final int HOSTS2_NS = 81;
351
352	/** SU/MIT Telnet Gateway */
353	public static final int SU_MIT_TG = 89;
354
355	/** MIT Dover Spooler */
356	public static final int MIT_DOV = 91;
357
358	/** Device Control Protocol */
359	public static final int DCP = 93;
360
361	/** SUPDUP */
362	public static final int SUPDUP = 95;
363
364	/** Swift Remote Virtual File Protocol */
365	public static final int SWIFT_RVF = 97;
366
367	/** TAC News */
368	public static final int TACNEWS = 98;
369
370	/** Metagram Relay */
371	public static final int METAGRAM = 99;
372
373	/** NIC Host Name Server */
374	public static final int HOSTNAME = 101;
375
376	/** ISO-TSAP */
377	public static final int ISO_TSAP = 102;
378
379	/** X400 */
380	public static final int X400 = 103;
381
382	/** X400-SND */
383	public static final int X400_SND = 104;
384
385	/** Mailbox Name Nameserver */
386	public static final int CSNET_NS = 105;
387
388	/** Remote Telnet Service */
389	public static final int RTELNET = 107;
390
391	/** Post Office Protocol - Version 2 */
392	public static final int POP_2 = 109;
393
394	/** SUN Remote Procedure Call */
395	public static final int SUNRPC = 111;
396
397	/** Authentication Service */
398	public static final int AUTH = 113;
399
400	/** Simple File Transfer Protocol */
401	public static final int SFTP = 115;
402
403	/** UUCP Path Service */
404	public static final int UUCP_PATH = 117;
405
406	/** Network News Transfer Protocol */
407	public static final int NNTP = 119;
408
409	/** HYDRA Expedited Remote Procedure */
410	public static final int ERPC = 121;
411
412	/** Network Time Protocol */
413	public static final int NTP = 123;
414
415	/** Locus PC-Interface Net Map Server */
416	public static final int LOCUS_MAP = 125;
417
418	/** Locus PC-Interface Conn Server */
419	public static final int LOCUS_CON = 127;
420
421	/** Password Generator Protocol */
422	public static final int PWDGEN = 129;
423
424	/** CISCO FNATIVE */
425	public static final int CISCO_FNA = 130;
426
427	/** CISCO TNATIVE */
428	public static final int CISCO_TNA = 131;
429
430	/** CISCO SYSMAINT */
431	public static final int CISCO_SYS = 132;
432
433	/** Statistics Service */
434	public static final int STATSRV = 133;
435
436	/** INGRES-NET Service */
437	public static final int INGRES_NET = 134;
438
439	/** Location Service */
440	public static final int LOC_SRV = 135;
441
442	/** PROFILE Naming System */
443	public static final int PROFILE = 136;
444
445	/** NETBIOS Name Service */
446	public static final int NETBIOS_NS = 137;
447
448	/** NETBIOS Datagram Service */
449	public static final int NETBIOS_DGM = 138;
450
451	/** NETBIOS Session Service */
452	public static final int NETBIOS_SSN = 139;
453
454	/** EMFIS Data Service */
455	public static final int EMFIS_DATA = 140;
456
457	/** EMFIS Control Service */
458	public static final int EMFIS_CNTL = 141;
459
460	/** Britton-Lee IDM */
461	public static final int BL_IDM = 142;
462
463	/** Survey Measurement */
464	public static final int SUR_MEAS = 243;
465
466	/** LINK */
467	public static final int LINK = 245;
468
469	private static Mnemonic services = new Mnemonic("TCP/UDP service",
470							Mnemonic.CASE_LOWER);
471
472	static {
473		services.setMaximum(0xFFFF);
474		services.setNumericAllowed(true);
475
476		services.add(RJE, "rje");
477		services.add(ECHO, "echo");
478		services.add(DISCARD, "discard");
479		services.add(USERS, "users");
480		services.add(DAYTIME, "daytime");
481		services.add(QUOTE, "quote");
482		services.add(CHARGEN, "chargen");
483		services.add(FTP_DATA, "ftp-data");
484		services.add(FTP, "ftp");
485		services.add(TELNET, "telnet");
486		services.add(SMTP, "smtp");
487		services.add(NSW_FE, "nsw-fe");
488		services.add(MSG_ICP, "msg-icp");
489		services.add(MSG_AUTH, "msg-auth");
490		services.add(DSP, "dsp");
491		services.add(TIME, "time");
492		services.add(RLP, "rlp");
493		services.add(GRAPHICS, "graphics");
494		services.add(NAMESERVER, "nameserver");
495		services.add(NICNAME, "nicname");
496		services.add(MPM_FLAGS, "mpm-flags");
497		services.add(MPM, "mpm");
498		services.add(MPM_SND, "mpm-snd");
499		services.add(NI_FTP, "ni-ftp");
500		services.add(LOGIN, "login");
501		services.add(LA_MAINT, "la-maint");
502		services.add(DOMAIN, "domain");
503		services.add(ISI_GL, "isi-gl");
504		services.add(NI_MAIL, "ni-mail");
505		services.add(VIA_FTP, "via-ftp");
506		services.add(TACACS_DS, "tacacs-ds");
507		services.add(BOOTPS, "bootps");
508		services.add(BOOTPC, "bootpc");
509		services.add(TFTP, "tftp");
510		services.add(NETRJS_1, "netrjs-1");
511		services.add(NETRJS_2, "netrjs-2");
512		services.add(NETRJS_3, "netrjs-3");
513		services.add(NETRJS_4, "netrjs-4");
514		services.add(FINGER, "finger");
515		services.add(HOSTS2_NS, "hosts2-ns");
516		services.add(SU_MIT_TG, "su-mit-tg");
517		services.add(MIT_DOV, "mit-dov");
518		services.add(DCP, "dcp");
519		services.add(SUPDUP, "supdup");
520		services.add(SWIFT_RVF, "swift-rvf");
521		services.add(TACNEWS, "tacnews");
522		services.add(METAGRAM, "metagram");
523		services.add(HOSTNAME, "hostname");
524		services.add(ISO_TSAP, "iso-tsap");
525		services.add(X400, "x400");
526		services.add(X400_SND, "x400-snd");
527		services.add(CSNET_NS, "csnet-ns");
528		services.add(RTELNET, "rtelnet");
529		services.add(POP_2, "pop-2");
530		services.add(SUNRPC, "sunrpc");
531		services.add(AUTH, "auth");
532		services.add(SFTP, "sftp");
533		services.add(UUCP_PATH, "uucp-path");
534		services.add(NNTP, "nntp");
535		services.add(ERPC, "erpc");
536		services.add(NTP, "ntp");
537		services.add(LOCUS_MAP, "locus-map");
538		services.add(LOCUS_CON, "locus-con");
539		services.add(PWDGEN, "pwdgen");
540		services.add(CISCO_FNA, "cisco-fna");
541		services.add(CISCO_TNA, "cisco-tna");
542		services.add(CISCO_SYS, "cisco-sys");
543		services.add(STATSRV, "statsrv");
544		services.add(INGRES_NET, "ingres-net");
545		services.add(LOC_SRV, "loc-srv");
546		services.add(PROFILE, "profile");
547		services.add(NETBIOS_NS, "netbios-ns");
548		services.add(NETBIOS_DGM, "netbios-dgm");
549		services.add(NETBIOS_SSN, "netbios-ssn");
550		services.add(EMFIS_DATA, "emfis-data");
551		services.add(EMFIS_CNTL, "emfis-cntl");
552		services.add(BL_IDM, "bl-idm");
553		services.add(SUR_MEAS, "sur-meas");
554		services.add(LINK, "link");
555	}
556
557	/**
558	 * Converts a TCP/UDP service port number into its textual
559	 * representation.
560	 */
561	public static String
562	string(int type) {
563		return services.getText(type);
564	}
565
566	/**
567	 * Converts a textual representation of a TCP/UDP service into its
568	 * port number.  Integers in the range 0..65535 are also accepted.
569	 * @param s The textual representation of the service.
570	 * @return The port number, or -1 on error.
571	 */
572	public static int
573	value(String s) {
574		return services.getValue(s);
575	}
576}
577private byte [] address;
578private int protocol;
579private int [] services;
580
581WKSRecord() {}
582
583Record
584getObject() {
585	return new WKSRecord();
586}
587
588/**
589 * Creates a WKS Record from the given data
590 * @param address The IP address
591 * @param protocol The IP protocol number
592 * @param services An array of supported services, represented by port number.
593 */
594public
595WKSRecord(Name name, int dclass, long ttl, InetAddress address, int protocol,
596	  int [] services)
597{
598	super(name, Type.WKS, dclass, ttl);
599	if (Address.familyOf(address) != Address.IPv4)
600		throw new IllegalArgumentException("invalid IPv4 address");
601	this.address = address.getAddress();
602	this.protocol = checkU8("protocol", protocol);
603	for (int i = 0; i < services.length; i++) {
604		checkU16("service", services[i]);
605	}
606	this.services = new int[services.length];
607	System.arraycopy(services, 0, this.services, 0, services.length);
608	Arrays.sort(this.services);
609}
610
611void
612rrFromWire(DNSInput in) throws IOException {
613	address = in.readByteArray(4);
614	protocol = in.readU8();
615	byte [] array = in.readByteArray();
616	List list = new ArrayList();
617	for (int i = 0; i < array.length; i++) {
618		for (int j = 0; j < 8; j++) {
619			int octet = array[i] & 0xFF;
620			if ((octet & (1 << (7 - j))) != 0) {
621				list.add(new Integer(i * 8 + j));
622			}
623		}
624	}
625	services = new int[list.size()];
626	for (int i = 0; i < list.size(); i++) {
627		services[i] = ((Integer) list.get(i)).intValue();
628	}
629}
630
631void
632rdataFromString(Tokenizer st, Name origin) throws IOException {
633	String s = st.getString();
634	address = Address.toByteArray(s, Address.IPv4);
635	if (address == null)
636		throw st.exception("invalid address");
637
638	s = st.getString();
639	protocol = Protocol.value(s);
640	if (protocol < 0) {
641		throw st.exception("Invalid IP protocol: " + s);
642	}
643
644	List list = new ArrayList();
645	while (true) {
646		Tokenizer.Token t = st.get();
647		if (!t.isString())
648			break;
649		int service = Service.value(t.value);
650		if (service < 0) {
651			throw st.exception("Invalid TCP/UDP service: " +
652					   t.value);
653		}
654		list.add(new Integer(service));
655	}
656	st.unget();
657	services = new int[list.size()];
658	for (int i = 0; i < list.size(); i++) {
659		services[i] = ((Integer) list.get(i)).intValue();
660	}
661}
662
663/**
664 * Converts rdata to a String
665 */
666String
667rrToString() {
668	StringBuffer sb = new StringBuffer();
669	sb.append(Address.toDottedQuad(address));
670	sb.append(" ");
671	sb.append(protocol);
672	for (int i = 0; i < services.length; i++) {
673		sb.append(" " + services[i]);
674	}
675	return sb.toString();
676}
677
678/**
679 * Returns the IP address.
680 */
681public InetAddress
682getAddress() {
683	try {
684		return InetAddress.getByAddress(address);
685	} catch (UnknownHostException e) {
686		return null;
687	}
688}
689
690/**
691 * Returns the IP protocol.
692 */
693public int
694getProtocol() {
695	return protocol;
696}
697
698/**
699 * Returns the services provided by the host on the specified address.
700 */
701public int []
702getServices() {
703	return services;
704}
705
706void
707rrToWire(DNSOutput out, Compression c, boolean canonical) {
708	out.writeByteArray(address);
709	out.writeU8(protocol);
710	int highestPort = services[services.length - 1];
711	byte [] array = new byte[highestPort / 8 + 1];
712	for (int i = 0; i < services.length; i++) {
713		int port = services[i];
714		array[port / 8] |= (1 << (7 - port % 8));
715	}
716	out.writeByteArray(array);
717}
718
719}
720