Home | History | Annotate | Download | only in DNS
      1 // Copyright (c) 1999-2004 Brian Wellington (bwelling (at) xbill.org)
      2 
      3 package org.xbill.DNS;
      4 
      5 import java.net.*;
      6 import java.io.*;
      7 import java.util.*;
      8 
      9 /**
     10  * Well Known Services - Lists services offered by this host.
     11  *
     12  * @author Brian Wellington
     13  */
     14 
     15 public class WKSRecord extends Record {
     16 
     17 private static final long serialVersionUID = -9104259763909119805L;
     18 
     19 public 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 
    223 public 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 }
    577 private byte [] address;
    578 private int protocol;
    579 private int [] services;
    580 
    581 WKSRecord() {}
    582 
    583 Record
    584 getObject() {
    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  */
    594 public
    595 WKSRecord(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 
    611 void
    612 rrFromWire(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 
    631 void
    632 rdataFromString(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  */
    666 String
    667 rrToString() {
    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  */
    681 public InetAddress
    682 getAddress() {
    683 	try {
    684 		return InetAddress.getByAddress(address);
    685 	} catch (UnknownHostException e) {
    686 		return null;
    687 	}
    688 }
    689 
    690 /**
    691  * Returns the IP protocol.
    692  */
    693 public int
    694 getProtocol() {
    695 	return protocol;
    696 }
    697 
    698 /**
    699  * Returns the services provided by the host on the specified address.
    700  */
    701 public int []
    702 getServices() {
    703 	return services;
    704 }
    705 
    706 void
    707 rrToWire(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