17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*9a70fc3bSMark J. Nelson * Common Development and Distribution License (the "License"). 6*9a70fc3bSMark J. Nelson * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 227c478bd9Sstevel@tonic-gate * Copyright 2001-2002 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate * 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate // SrvLocHeader.java: Abstract superclass for SLP Headers 287c478bd9Sstevel@tonic-gate // Author: James Kempf 297c478bd9Sstevel@tonic-gate // Created On: Mon Sep 14 12:47:20 1998 307c478bd9Sstevel@tonic-gate // Last Modified By: James Kempf 317c478bd9Sstevel@tonic-gate // Last Modified On: Mon Nov 23 14:32:50 1998 327c478bd9Sstevel@tonic-gate // Update Count: 55 337c478bd9Sstevel@tonic-gate // 347c478bd9Sstevel@tonic-gate 357c478bd9Sstevel@tonic-gate package com.sun.slp; 367c478bd9Sstevel@tonic-gate 377c478bd9Sstevel@tonic-gate import java.util.*; 387c478bd9Sstevel@tonic-gate import java.net.*; 397c478bd9Sstevel@tonic-gate import java.io.*; 407c478bd9Sstevel@tonic-gate 417c478bd9Sstevel@tonic-gate /** 427c478bd9Sstevel@tonic-gate * SrvLocHeader handles different versions of the SLP header. Clients 437c478bd9Sstevel@tonic-gate * call the instance methods returned by newInstance(). If no version 447c478bd9Sstevel@tonic-gate * specific subclass exists for the version number, null is returned 457c478bd9Sstevel@tonic-gate * from newInstance. Parsing of the header and message bodies, and 467c478bd9Sstevel@tonic-gate * creation of error replies are handled by the version specific 477c478bd9Sstevel@tonic-gate * subclasses. We also let the SrvLocHeader serve as a SrvLocMsg object 487c478bd9Sstevel@tonic-gate * to handle the SrvAck, which only has an error code. 497c478bd9Sstevel@tonic-gate * 507c478bd9Sstevel@tonic-gate * @author James Kempf 517c478bd9Sstevel@tonic-gate */ 527c478bd9Sstevel@tonic-gate 537c478bd9Sstevel@tonic-gate abstract class SrvLocHeader extends Object implements SrvLocMsg, Cloneable { 547c478bd9Sstevel@tonic-gate 557c478bd9Sstevel@tonic-gate // Table of header classes. Keys are the version number. 567c478bd9Sstevel@tonic-gate 577c478bd9Sstevel@tonic-gate private static final Hashtable classTable = new Hashtable(); 587c478bd9Sstevel@tonic-gate 597c478bd9Sstevel@tonic-gate // Offset to XID. 607c478bd9Sstevel@tonic-gate 617c478bd9Sstevel@tonic-gate static final int XID_OFFSET = 10; 627c478bd9Sstevel@tonic-gate 637c478bd9Sstevel@tonic-gate // Common constants and instance variables. 647c478bd9Sstevel@tonic-gate 657c478bd9Sstevel@tonic-gate // Number of bytes in the version and function fields. 667c478bd9Sstevel@tonic-gate 677c478bd9Sstevel@tonic-gate static int VERSION_FUNCTION_BYTES = 2; 687c478bd9Sstevel@tonic-gate 697c478bd9Sstevel@tonic-gate // SLP function codes. Even though SAAdvert isn't in all versions, 707c478bd9Sstevel@tonic-gate // we include it here. 717c478bd9Sstevel@tonic-gate 727c478bd9Sstevel@tonic-gate static final int SrvReq = 1; 737c478bd9Sstevel@tonic-gate static final int SrvRply = 2; 747c478bd9Sstevel@tonic-gate static final int SrvReg = 3; 757c478bd9Sstevel@tonic-gate static final int SrvDereg = 4; 767c478bd9Sstevel@tonic-gate static final int SrvAck = 5; 777c478bd9Sstevel@tonic-gate static final int AttrRqst = 6; 787c478bd9Sstevel@tonic-gate static final int AttrRply = 7; 797c478bd9Sstevel@tonic-gate static final int DAAdvert = 8; 807c478bd9Sstevel@tonic-gate static final int SrvTypeRqst = 9; 817c478bd9Sstevel@tonic-gate static final int SrvTypeRply = 10; 827c478bd9Sstevel@tonic-gate static final int SAAdvert = 11; 837c478bd9Sstevel@tonic-gate 847c478bd9Sstevel@tonic-gate static final String[] functionCodeAbbr = { 857c478bd9Sstevel@tonic-gate "0", 867c478bd9Sstevel@tonic-gate "SrvReq", 877c478bd9Sstevel@tonic-gate "SrvRply", 887c478bd9Sstevel@tonic-gate "SrvReg", 897c478bd9Sstevel@tonic-gate "SrvDereg", 907c478bd9Sstevel@tonic-gate "SrvAck", 917c478bd9Sstevel@tonic-gate "AttrRqst", 927c478bd9Sstevel@tonic-gate "AttrRply", 937c478bd9Sstevel@tonic-gate "DAAdvert", 947c478bd9Sstevel@tonic-gate "SrvTypeRqst", 957c478bd9Sstevel@tonic-gate "SrvTypeRply", 967c478bd9Sstevel@tonic-gate "SAAdvert", 977c478bd9Sstevel@tonic-gate }; 987c478bd9Sstevel@tonic-gate 997c478bd9Sstevel@tonic-gate // Sizes of data items. 1007c478bd9Sstevel@tonic-gate 1017c478bd9Sstevel@tonic-gate protected static final int BYTE_SIZE = 1; 1027c478bd9Sstevel@tonic-gate protected static final int SHORT_SIZE = 2; 1037c478bd9Sstevel@tonic-gate protected static final int INT24_SIZE = 3; 1047c478bd9Sstevel@tonic-gate 1057c478bd9Sstevel@tonic-gate // 1067c478bd9Sstevel@tonic-gate // Header instance variables. 1077c478bd9Sstevel@tonic-gate // 1087c478bd9Sstevel@tonic-gate 1097c478bd9Sstevel@tonic-gate // Unprotected for less code. 1107c478bd9Sstevel@tonic-gate 1117c478bd9Sstevel@tonic-gate int version = 0; // version number 1127c478bd9Sstevel@tonic-gate int functionCode = 0; // function code 1137c478bd9Sstevel@tonic-gate int length = 0; // packet length 1147c478bd9Sstevel@tonic-gate short xid = 0; // transaction id 1157c478bd9Sstevel@tonic-gate short errCode = 1167c478bd9Sstevel@tonic-gate ServiceLocationException.OK; // not applicable to start 1177c478bd9Sstevel@tonic-gate Locale locale = Defaults.locale; // language locale 1187c478bd9Sstevel@tonic-gate Vector previousResponders = null; // list of previous responders 1197c478bd9Sstevel@tonic-gate Vector scopes = null; // list of scopes 1207c478bd9Sstevel@tonic-gate boolean overflow = false; // Overflow flag 1217c478bd9Sstevel@tonic-gate boolean fresh = false; // Fresh flag 1227c478bd9Sstevel@tonic-gate boolean mcast = false; // Mulitcast flag. 1237c478bd9Sstevel@tonic-gate byte[] payload = new byte[0]; // bytes of outgoing payload, 1247c478bd9Sstevel@tonic-gate int nbytes = 0; // number of bytes processed 1257c478bd9Sstevel@tonic-gate int packetLength = 0; // length of packet. 1267c478bd9Sstevel@tonic-gate int iNumReplies = 0; // number of replies. 1277c478bd9Sstevel@tonic-gate 1287c478bd9Sstevel@tonic-gate 1297c478bd9Sstevel@tonic-gate protected static short uniqueXID = 0; // outgoing transaction id. 1307c478bd9Sstevel@tonic-gate 1317c478bd9Sstevel@tonic-gate // Message description. 1327c478bd9Sstevel@tonic-gate 1337c478bd9Sstevel@tonic-gate private String msgType; 1347c478bd9Sstevel@tonic-gate private String msgDescription; 1357c478bd9Sstevel@tonic-gate 1367c478bd9Sstevel@tonic-gate SrvLocHeader()1377c478bd9Sstevel@tonic-gate SrvLocHeader() { 1387c478bd9Sstevel@tonic-gate 1397c478bd9Sstevel@tonic-gate packetLength = SLPConfig.getSLPConfig().getMTU(); 1407c478bd9Sstevel@tonic-gate 1417c478bd9Sstevel@tonic-gate } 1427c478bd9Sstevel@tonic-gate 1437c478bd9Sstevel@tonic-gate // 1447c478bd9Sstevel@tonic-gate // SrvLocMsg Implementation. 1457c478bd9Sstevel@tonic-gate // 1467c478bd9Sstevel@tonic-gate getHeader()1477c478bd9Sstevel@tonic-gate public SrvLocHeader getHeader() { 1487c478bd9Sstevel@tonic-gate return this; 1497c478bd9Sstevel@tonic-gate 1507c478bd9Sstevel@tonic-gate } 1517c478bd9Sstevel@tonic-gate getErrorCode()1527c478bd9Sstevel@tonic-gate public short getErrorCode() { 1537c478bd9Sstevel@tonic-gate return errCode; 1547c478bd9Sstevel@tonic-gate 1557c478bd9Sstevel@tonic-gate } 1567c478bd9Sstevel@tonic-gate 1577c478bd9Sstevel@tonic-gate // Return number of replies to this message. 1587c478bd9Sstevel@tonic-gate getNumReplies()1597c478bd9Sstevel@tonic-gate public int getNumReplies() { 1607c478bd9Sstevel@tonic-gate return iNumReplies; 1617c478bd9Sstevel@tonic-gate 1627c478bd9Sstevel@tonic-gate } 1637c478bd9Sstevel@tonic-gate 1647c478bd9Sstevel@tonic-gate // 1657c478bd9Sstevel@tonic-gate // SrvLocHeader Interface. 1667c478bd9Sstevel@tonic-gate // 1677c478bd9Sstevel@tonic-gate 1687c478bd9Sstevel@tonic-gate // Register a new header class for version. Serious error, causing 1697c478bd9Sstevel@tonic-gate // program termination, if we can't find it. 1707c478bd9Sstevel@tonic-gate addHeaderClass(String className, int version)1717c478bd9Sstevel@tonic-gate static void addHeaderClass(String className, int version) { 1727c478bd9Sstevel@tonic-gate 1737c478bd9Sstevel@tonic-gate try { 1747c478bd9Sstevel@tonic-gate 1757c478bd9Sstevel@tonic-gate Class headerClass = Class.forName(className); 1767c478bd9Sstevel@tonic-gate 1777c478bd9Sstevel@tonic-gate classTable.put(new Integer(version), headerClass); 1787c478bd9Sstevel@tonic-gate 1797c478bd9Sstevel@tonic-gate } catch (ClassNotFoundException ex) { 1807c478bd9Sstevel@tonic-gate 1817c478bd9Sstevel@tonic-gate Assert.slpassert(false, 1827c478bd9Sstevel@tonic-gate "no_class", 1837c478bd9Sstevel@tonic-gate new Object[] {className}); 1847c478bd9Sstevel@tonic-gate 1857c478bd9Sstevel@tonic-gate } 1867c478bd9Sstevel@tonic-gate } 1877c478bd9Sstevel@tonic-gate 1887c478bd9Sstevel@tonic-gate // Create a version specific instance. We use a naming convention 1897c478bd9Sstevel@tonic-gate // to identify the version specific classes used to create the 1907c478bd9Sstevel@tonic-gate // instance. 1917c478bd9Sstevel@tonic-gate newInstance(int version)1927c478bd9Sstevel@tonic-gate static SrvLocHeader newInstance(int version) { 1937c478bd9Sstevel@tonic-gate 1947c478bd9Sstevel@tonic-gate try { 1957c478bd9Sstevel@tonic-gate 1967c478bd9Sstevel@tonic-gate // Get header class. 1977c478bd9Sstevel@tonic-gate 1987c478bd9Sstevel@tonic-gate Class hdrClass = (Class)classTable.get(new Integer(version)); 1997c478bd9Sstevel@tonic-gate 2007c478bd9Sstevel@tonic-gate if (hdrClass == null) { 2017c478bd9Sstevel@tonic-gate return null; 2027c478bd9Sstevel@tonic-gate 2037c478bd9Sstevel@tonic-gate } 2047c478bd9Sstevel@tonic-gate 2057c478bd9Sstevel@tonic-gate SrvLocHeader hdr = (SrvLocHeader)hdrClass.newInstance(); 2067c478bd9Sstevel@tonic-gate 2077c478bd9Sstevel@tonic-gate return hdr; 2087c478bd9Sstevel@tonic-gate 2097c478bd9Sstevel@tonic-gate } catch (Exception ex) { 2107c478bd9Sstevel@tonic-gate 2117c478bd9Sstevel@tonic-gate SLPConfig.getSLPConfig().writeLog("slh_creation_exception", 2127c478bd9Sstevel@tonic-gate new Object[] { 2137c478bd9Sstevel@tonic-gate new Integer(version), 2147c478bd9Sstevel@tonic-gate ex, 2157c478bd9Sstevel@tonic-gate ex.getMessage()}); 2167c478bd9Sstevel@tonic-gate return null; 2177c478bd9Sstevel@tonic-gate 2187c478bd9Sstevel@tonic-gate } 2197c478bd9Sstevel@tonic-gate 2207c478bd9Sstevel@tonic-gate } 2217c478bd9Sstevel@tonic-gate 2227c478bd9Sstevel@tonic-gate // Parse the incoming stream to obtain the header. 2237c478bd9Sstevel@tonic-gate parseHeader(int functionCode, DataInputStream dis)2247c478bd9Sstevel@tonic-gate abstract void parseHeader(int functionCode, DataInputStream dis) 2257c478bd9Sstevel@tonic-gate throws ServiceLocationException, IOException, IllegalArgumentException; 2267c478bd9Sstevel@tonic-gate 2277c478bd9Sstevel@tonic-gate // Parse the incoming stream to obtain the message. 2287c478bd9Sstevel@tonic-gate parseMsg(DataInputStream dis)2297c478bd9Sstevel@tonic-gate abstract SrvLocMsg parseMsg(DataInputStream dis) 2307c478bd9Sstevel@tonic-gate throws ServiceLocationException, IOException, IllegalArgumentException; 2317c478bd9Sstevel@tonic-gate 2327c478bd9Sstevel@tonic-gate // Externalize the message. 2337c478bd9Sstevel@tonic-gate 2347c478bd9Sstevel@tonic-gate abstract void externalize(ByteArrayOutputStream baos, boolean multicast, boolean isTCP)2357c478bd9Sstevel@tonic-gate externalize(ByteArrayOutputStream baos, 2367c478bd9Sstevel@tonic-gate boolean multicast, 2377c478bd9Sstevel@tonic-gate boolean isTCP) 2387c478bd9Sstevel@tonic-gate throws ServiceLocationException; 2397c478bd9Sstevel@tonic-gate 2407c478bd9Sstevel@tonic-gate // Return the appropriately versioned DAAdvert. 2417c478bd9Sstevel@tonic-gate 2427c478bd9Sstevel@tonic-gate abstract SDAAdvert getDAAdvert(short xid, long timestamp, ServiceURL url, Vector scopes, Vector attrs)2437c478bd9Sstevel@tonic-gate getDAAdvert(short xid, 2447c478bd9Sstevel@tonic-gate long timestamp, 2457c478bd9Sstevel@tonic-gate ServiceURL url, 2467c478bd9Sstevel@tonic-gate Vector scopes, 2477c478bd9Sstevel@tonic-gate Vector attrs) 2487c478bd9Sstevel@tonic-gate throws ServiceLocationException; 2497c478bd9Sstevel@tonic-gate 2507c478bd9Sstevel@tonic-gate // 2517c478bd9Sstevel@tonic-gate // Methods that some subclasses may reimplement. 2527c478bd9Sstevel@tonic-gate // 2537c478bd9Sstevel@tonic-gate 2547c478bd9Sstevel@tonic-gate // Parse any options. 2557c478bd9Sstevel@tonic-gate parseOptions(DataInputStream dis)2567c478bd9Sstevel@tonic-gate void parseOptions(DataInputStream dis) 2577c478bd9Sstevel@tonic-gate throws ServiceLocationException, 2587c478bd9Sstevel@tonic-gate IOException, 2597c478bd9Sstevel@tonic-gate IllegalArgumentException { 2607c478bd9Sstevel@tonic-gate 2617c478bd9Sstevel@tonic-gate } 2627c478bd9Sstevel@tonic-gate 2637c478bd9Sstevel@tonic-gate // Create an error reply for this message. This reply will be appropriate 2647c478bd9Sstevel@tonic-gate // for the server to send back to the client. Default is to do nothing, 2657c478bd9Sstevel@tonic-gate // which is the code for the client. 2667c478bd9Sstevel@tonic-gate makeErrorReply(Exception ex)2677c478bd9Sstevel@tonic-gate SrvLocMsg makeErrorReply(Exception ex) { 2687c478bd9Sstevel@tonic-gate return null; 2697c478bd9Sstevel@tonic-gate 2707c478bd9Sstevel@tonic-gate } 2717c478bd9Sstevel@tonic-gate 2727c478bd9Sstevel@tonic-gate // 2737c478bd9Sstevel@tonic-gate // Common utilities for all versions. 2747c478bd9Sstevel@tonic-gate // 2757c478bd9Sstevel@tonic-gate 2767c478bd9Sstevel@tonic-gate // Set the packet length to the incoming value. 2777c478bd9Sstevel@tonic-gate setPacketLength(int newLength)2787c478bd9Sstevel@tonic-gate void setPacketLength(int newLength) { 2797c478bd9Sstevel@tonic-gate 2807c478bd9Sstevel@tonic-gate if (newLength > 0) { 2817c478bd9Sstevel@tonic-gate packetLength = newLength; 2827c478bd9Sstevel@tonic-gate 2837c478bd9Sstevel@tonic-gate } 2847c478bd9Sstevel@tonic-gate } 2857c478bd9Sstevel@tonic-gate 2867c478bd9Sstevel@tonic-gate // Add an Internet address to the previous responders list. 2877c478bd9Sstevel@tonic-gate addPreviousResponder(InetAddress addr)2887c478bd9Sstevel@tonic-gate void addPreviousResponder(InetAddress addr) { 2897c478bd9Sstevel@tonic-gate 2907c478bd9Sstevel@tonic-gate String hostAddr = addr.getHostAddress(); 2917c478bd9Sstevel@tonic-gate 2927c478bd9Sstevel@tonic-gate Assert.slpassert((previousResponders != null), 2937c478bd9Sstevel@tonic-gate "prev_resp_reply", 2947c478bd9Sstevel@tonic-gate new Object[0]); 2957c478bd9Sstevel@tonic-gate 2967c478bd9Sstevel@tonic-gate if (!previousResponders.contains(hostAddr)) { 2977c478bd9Sstevel@tonic-gate previousResponders.addElement(hostAddr); 2987c478bd9Sstevel@tonic-gate 2997c478bd9Sstevel@tonic-gate } 3007c478bd9Sstevel@tonic-gate } 3017c478bd9Sstevel@tonic-gate 3027c478bd9Sstevel@tonic-gate // Get a unique transaction id. 3037c478bd9Sstevel@tonic-gate getUniqueXID()3047c478bd9Sstevel@tonic-gate synchronized static short getUniqueXID() { 3057c478bd9Sstevel@tonic-gate if (uniqueXID == 0) { 3067c478bd9Sstevel@tonic-gate Random r = new Random(); 3077c478bd9Sstevel@tonic-gate uniqueXID = (short)(r.nextInt() &0xFFFF); 3087c478bd9Sstevel@tonic-gate } 3097c478bd9Sstevel@tonic-gate uniqueXID++; 3107c478bd9Sstevel@tonic-gate return (short)(uniqueXID & 0xFFFF); 3117c478bd9Sstevel@tonic-gate } 3127c478bd9Sstevel@tonic-gate 3137c478bd9Sstevel@tonic-gate // Parse 2-byte integer, bump byte count. 3147c478bd9Sstevel@tonic-gate getInt(DataInputStream dis)3157c478bd9Sstevel@tonic-gate int getInt(DataInputStream dis) 3167c478bd9Sstevel@tonic-gate throws ServiceLocationException, IOException { 3177c478bd9Sstevel@tonic-gate 3187c478bd9Sstevel@tonic-gate int ret = getInteger(dis); 3197c478bd9Sstevel@tonic-gate 3207c478bd9Sstevel@tonic-gate nbytes += SHORT_SIZE; 3217c478bd9Sstevel@tonic-gate 3227c478bd9Sstevel@tonic-gate return ret; 3237c478bd9Sstevel@tonic-gate } 3247c478bd9Sstevel@tonic-gate 3257c478bd9Sstevel@tonic-gate 3267c478bd9Sstevel@tonic-gate // Parse a 2-byte integer from the input stream. 3277c478bd9Sstevel@tonic-gate getInteger(DataInputStream dis)3287c478bd9Sstevel@tonic-gate static int getInteger(DataInputStream dis) 3297c478bd9Sstevel@tonic-gate throws ServiceLocationException, IOException { 3307c478bd9Sstevel@tonic-gate 3317c478bd9Sstevel@tonic-gate byte[] b = new byte[2]; 3327c478bd9Sstevel@tonic-gate 3337c478bd9Sstevel@tonic-gate dis.readFully(b, 0, 2); 3347c478bd9Sstevel@tonic-gate 3357c478bd9Sstevel@tonic-gate int x = (int)((char)b[0] & 0xFF); 3367c478bd9Sstevel@tonic-gate int y = (int)((char)b[1] & 0xFF); 3377c478bd9Sstevel@tonic-gate int z = x << 8; 3387c478bd9Sstevel@tonic-gate z += y; 3397c478bd9Sstevel@tonic-gate return z; 3407c478bd9Sstevel@tonic-gate } 3417c478bd9Sstevel@tonic-gate 3427c478bd9Sstevel@tonic-gate // Parse 2-byte integer, bump byte count. 3437c478bd9Sstevel@tonic-gate putInt(int z, ByteArrayOutputStream baos)3447c478bd9Sstevel@tonic-gate void putInt(int z, ByteArrayOutputStream baos) { 3457c478bd9Sstevel@tonic-gate 3467c478bd9Sstevel@tonic-gate putInteger(z, baos); 3477c478bd9Sstevel@tonic-gate 3487c478bd9Sstevel@tonic-gate nbytes += SHORT_SIZE; 3497c478bd9Sstevel@tonic-gate 3507c478bd9Sstevel@tonic-gate } 3517c478bd9Sstevel@tonic-gate 3527c478bd9Sstevel@tonic-gate // Parse a 2-byte integer to the output stream. 3537c478bd9Sstevel@tonic-gate putInteger(int z, ByteArrayOutputStream baos)3547c478bd9Sstevel@tonic-gate static void putInteger(int z, ByteArrayOutputStream baos) { 3557c478bd9Sstevel@tonic-gate baos.write((byte) ((0xFF00 & z)>>8)); 3567c478bd9Sstevel@tonic-gate baos.write((byte) (0xFF & z)); 3577c478bd9Sstevel@tonic-gate } 3587c478bd9Sstevel@tonic-gate 3597c478bd9Sstevel@tonic-gate 3607c478bd9Sstevel@tonic-gate // Parse a 3-byte integer from the byte input stream. 3617c478bd9Sstevel@tonic-gate getInt24(DataInputStream dis)3627c478bd9Sstevel@tonic-gate protected int getInt24(DataInputStream dis) 3637c478bd9Sstevel@tonic-gate throws ServiceLocationException, IOException { 3647c478bd9Sstevel@tonic-gate 3657c478bd9Sstevel@tonic-gate byte[] b = new byte[3]; 3667c478bd9Sstevel@tonic-gate 3677c478bd9Sstevel@tonic-gate dis.readFully(b, 0, 3); 3687c478bd9Sstevel@tonic-gate 3697c478bd9Sstevel@tonic-gate int w = (int)((char)b[0] & 0xFF); 3707c478bd9Sstevel@tonic-gate int x = (int)((char)b[1] & 0xFF); 3717c478bd9Sstevel@tonic-gate int y = (int)((char)b[2] & 0xFF); 3727c478bd9Sstevel@tonic-gate int z = w << 16; 3737c478bd9Sstevel@tonic-gate z += x << 8; 3747c478bd9Sstevel@tonic-gate z += y; 3757c478bd9Sstevel@tonic-gate nbytes += 3; 3767c478bd9Sstevel@tonic-gate return z; 3777c478bd9Sstevel@tonic-gate } 3787c478bd9Sstevel@tonic-gate 3797c478bd9Sstevel@tonic-gate // Parse a 3-byte integer to the output stream. 3807c478bd9Sstevel@tonic-gate putInt24(int z, ByteArrayOutputStream baos)3817c478bd9Sstevel@tonic-gate protected void putInt24(int z, ByteArrayOutputStream baos) { 3827c478bd9Sstevel@tonic-gate baos.write((byte) ((0xFF0000 & z) >> 16)); 3837c478bd9Sstevel@tonic-gate baos.write((byte) ((0xFF00 & z)>>8)); 3847c478bd9Sstevel@tonic-gate baos.write((byte) (0xFF & z)); 3857c478bd9Sstevel@tonic-gate 3867c478bd9Sstevel@tonic-gate nbytes += 3; 3877c478bd9Sstevel@tonic-gate } 3887c478bd9Sstevel@tonic-gate 3897c478bd9Sstevel@tonic-gate 3907c478bd9Sstevel@tonic-gate // Parse string, bump byte count. Use UTF8 encoding. 3917c478bd9Sstevel@tonic-gate getString(StringBuffer buf, DataInputStream dis)3927c478bd9Sstevel@tonic-gate byte[] getString(StringBuffer buf, DataInputStream dis) 3937c478bd9Sstevel@tonic-gate throws ServiceLocationException, IOException { 3947c478bd9Sstevel@tonic-gate 3957c478bd9Sstevel@tonic-gate byte[] ret = getStringField(buf, dis, Defaults.UTF8); 3967c478bd9Sstevel@tonic-gate 3977c478bd9Sstevel@tonic-gate nbytes += ret.length + SHORT_SIZE; 3987c478bd9Sstevel@tonic-gate 3997c478bd9Sstevel@tonic-gate return ret; 4007c478bd9Sstevel@tonic-gate } 4017c478bd9Sstevel@tonic-gate 4027c478bd9Sstevel@tonic-gate // Parse a string with an initial length from the input stream. 4037c478bd9Sstevel@tonic-gate // Convert it to the proper encoding. Return the raw bytes for 4047c478bd9Sstevel@tonic-gate // auth block creation. 4057c478bd9Sstevel@tonic-gate 4067c478bd9Sstevel@tonic-gate static byte[] getStringField(StringBuffer buf, DataInputStream dis, String encoding)4077c478bd9Sstevel@tonic-gate getStringField(StringBuffer buf, DataInputStream dis, String encoding) 4087c478bd9Sstevel@tonic-gate throws ServiceLocationException, IOException { 4097c478bd9Sstevel@tonic-gate 4107c478bd9Sstevel@tonic-gate // Clear out buffer first. 4117c478bd9Sstevel@tonic-gate 4127c478bd9Sstevel@tonic-gate buf.setLength(0); 4137c478bd9Sstevel@tonic-gate 4147c478bd9Sstevel@tonic-gate // First get the length. 4157c478bd9Sstevel@tonic-gate 4167c478bd9Sstevel@tonic-gate int i, n = 0; 4177c478bd9Sstevel@tonic-gate 4187c478bd9Sstevel@tonic-gate n = getInteger(dis); 4197c478bd9Sstevel@tonic-gate 4207c478bd9Sstevel@tonic-gate // Now get the bytes. 4217c478bd9Sstevel@tonic-gate 4227c478bd9Sstevel@tonic-gate byte[] bytes = new byte[n]; 4237c478bd9Sstevel@tonic-gate 4247c478bd9Sstevel@tonic-gate dis.readFully(bytes, 0, n); 4257c478bd9Sstevel@tonic-gate 4267c478bd9Sstevel@tonic-gate // Convert to string and return. 4277c478bd9Sstevel@tonic-gate 4287c478bd9Sstevel@tonic-gate buf.append(getBytesString(bytes, encoding)); 4297c478bd9Sstevel@tonic-gate 4307c478bd9Sstevel@tonic-gate return bytes; 4317c478bd9Sstevel@tonic-gate 4327c478bd9Sstevel@tonic-gate } 4337c478bd9Sstevel@tonic-gate 4347c478bd9Sstevel@tonic-gate // Parse out string, bump byte count. Use UTF8 encoding. 4357c478bd9Sstevel@tonic-gate putString(String string, ByteArrayOutputStream baos)4367c478bd9Sstevel@tonic-gate byte[] putString(String string, ByteArrayOutputStream baos) { 4377c478bd9Sstevel@tonic-gate 4387c478bd9Sstevel@tonic-gate byte[] bytes = putStringField(string, baos, Defaults.UTF8); 4397c478bd9Sstevel@tonic-gate 4407c478bd9Sstevel@tonic-gate nbytes += bytes.length + SHORT_SIZE; 4417c478bd9Sstevel@tonic-gate 4427c478bd9Sstevel@tonic-gate return bytes; 4437c478bd9Sstevel@tonic-gate 4447c478bd9Sstevel@tonic-gate } 4457c478bd9Sstevel@tonic-gate 4467c478bd9Sstevel@tonic-gate // Put a string with an initial length into the byte stream, converting 4477c478bd9Sstevel@tonic-gate // into the proper encoding. 4487c478bd9Sstevel@tonic-gate 4497c478bd9Sstevel@tonic-gate static byte[] putStringField(String string, ByteArrayOutputStream baos, String encoding)4507c478bd9Sstevel@tonic-gate putStringField(String string, 4517c478bd9Sstevel@tonic-gate ByteArrayOutputStream baos, 4527c478bd9Sstevel@tonic-gate String encoding) { 4537c478bd9Sstevel@tonic-gate 4547c478bd9Sstevel@tonic-gate byte[] bytes = getStringBytes(string, encoding); 4557c478bd9Sstevel@tonic-gate 4567c478bd9Sstevel@tonic-gate // Put out the string's length in the encoding. 4577c478bd9Sstevel@tonic-gate 4587c478bd9Sstevel@tonic-gate putInteger(bytes.length, baos); 4597c478bd9Sstevel@tonic-gate 4607c478bd9Sstevel@tonic-gate // Now really write out the bytes. 4617c478bd9Sstevel@tonic-gate 4627c478bd9Sstevel@tonic-gate baos.write(bytes, 0, bytes.length); 4637c478bd9Sstevel@tonic-gate 4647c478bd9Sstevel@tonic-gate return bytes; 4657c478bd9Sstevel@tonic-gate 4667c478bd9Sstevel@tonic-gate } 4677c478bd9Sstevel@tonic-gate 4687c478bd9Sstevel@tonic-gate // Convert a Unicode string into encoded bytes. 4697c478bd9Sstevel@tonic-gate getStringBytes(String string, String encoding)4707c478bd9Sstevel@tonic-gate static byte[] getStringBytes(String string, String encoding) { 4717c478bd9Sstevel@tonic-gate 4727c478bd9Sstevel@tonic-gate try { 4737c478bd9Sstevel@tonic-gate return string.getBytes(encoding); 4747c478bd9Sstevel@tonic-gate 4757c478bd9Sstevel@tonic-gate } catch (UnsupportedEncodingException ex) { 4767c478bd9Sstevel@tonic-gate return new byte[0]; // won't happen, hopefully... 4777c478bd9Sstevel@tonic-gate 4787c478bd9Sstevel@tonic-gate } 4797c478bd9Sstevel@tonic-gate } 4807c478bd9Sstevel@tonic-gate 4817c478bd9Sstevel@tonic-gate // Convert bytes into a Unicode string. 4827c478bd9Sstevel@tonic-gate getBytesString(byte[] bytes, String encoding)4837c478bd9Sstevel@tonic-gate static String getBytesString(byte[] bytes, String encoding) { 4847c478bd9Sstevel@tonic-gate 4857c478bd9Sstevel@tonic-gate try { 4867c478bd9Sstevel@tonic-gate return new String(bytes, encoding); 4877c478bd9Sstevel@tonic-gate 4887c478bd9Sstevel@tonic-gate } catch (UnsupportedEncodingException ex) { 4897c478bd9Sstevel@tonic-gate return ""; // won't happen, hopefully ... 4907c478bd9Sstevel@tonic-gate 4917c478bd9Sstevel@tonic-gate } 4927c478bd9Sstevel@tonic-gate 4937c478bd9Sstevel@tonic-gate } 4947c478bd9Sstevel@tonic-gate 4957c478bd9Sstevel@tonic-gate // Parse a comma separated list of strings from the vector into the 4967c478bd9Sstevel@tonic-gate // output stream. 4977c478bd9Sstevel@tonic-gate 4987c478bd9Sstevel@tonic-gate protected byte[] parseCommaSeparatedListOut(Vector v, ByteArrayOutputStream baos)4997c478bd9Sstevel@tonic-gate parseCommaSeparatedListOut(Vector v, 5007c478bd9Sstevel@tonic-gate ByteArrayOutputStream baos) { 5017c478bd9Sstevel@tonic-gate 5027c478bd9Sstevel@tonic-gate return putString(vectorToCommaSeparatedList(v), baos); 5037c478bd9Sstevel@tonic-gate 5047c478bd9Sstevel@tonic-gate } 5057c478bd9Sstevel@tonic-gate 5067c478bd9Sstevel@tonic-gate /** 5077c478bd9Sstevel@tonic-gate * Create a comma separated list of strings out of the vector. 5087c478bd9Sstevel@tonic-gate * 5097c478bd9Sstevel@tonic-gate * @param v A Vector of strings. 5107c478bd9Sstevel@tonic-gate */ 5117c478bd9Sstevel@tonic-gate 5127c478bd9Sstevel@tonic-gate static String vectorToCommaSeparatedList(Vector v)5137c478bd9Sstevel@tonic-gate vectorToCommaSeparatedList(Vector v) { 5147c478bd9Sstevel@tonic-gate 5157c478bd9Sstevel@tonic-gate // Construct in a string buffer first. 5167c478bd9Sstevel@tonic-gate 5177c478bd9Sstevel@tonic-gate int i, n = v.size(); 5187c478bd9Sstevel@tonic-gate StringBuffer buf = new StringBuffer(); 5197c478bd9Sstevel@tonic-gate 5207c478bd9Sstevel@tonic-gate 5217c478bd9Sstevel@tonic-gate for (i = 0; i < n; i++) { 5227c478bd9Sstevel@tonic-gate String string = (String)v.elementAt(i); 5237c478bd9Sstevel@tonic-gate 5247c478bd9Sstevel@tonic-gate // Add comma for previous one if we need it. 5257c478bd9Sstevel@tonic-gate 5267c478bd9Sstevel@tonic-gate if (i != 0) { 5277c478bd9Sstevel@tonic-gate buf.append(','); 5287c478bd9Sstevel@tonic-gate } 5297c478bd9Sstevel@tonic-gate 5307c478bd9Sstevel@tonic-gate buf.append(string); 5317c478bd9Sstevel@tonic-gate 5327c478bd9Sstevel@tonic-gate } 5337c478bd9Sstevel@tonic-gate 5347c478bd9Sstevel@tonic-gate // Return the bytes. 5357c478bd9Sstevel@tonic-gate 5367c478bd9Sstevel@tonic-gate return buf.toString(); 5377c478bd9Sstevel@tonic-gate } 5387c478bd9Sstevel@tonic-gate 5397c478bd9Sstevel@tonic-gate /** 5407c478bd9Sstevel@tonic-gate * @parameter The string has the format = STRING *("," STRING) 5417c478bd9Sstevel@tonic-gate * @parameter A boolean indicating whether parens should be ignored or 5427c478bd9Sstevel@tonic-gate * used for grouping. 5437c478bd9Sstevel@tonic-gate * @return A vector (of Strings) based upon the (comma delimited) string. 5447c478bd9Sstevel@tonic-gate */ parseCommaSeparatedListIn(String s, boolean ignoreParens)5457c478bd9Sstevel@tonic-gate static Vector parseCommaSeparatedListIn(String s, boolean ignoreParens) 5467c478bd9Sstevel@tonic-gate throws ServiceLocationException { 5477c478bd9Sstevel@tonic-gate 5487c478bd9Sstevel@tonic-gate if (s == null) 5497c478bd9Sstevel@tonic-gate return new Vector(); 5507c478bd9Sstevel@tonic-gate if (s.length() == 0) 5517c478bd9Sstevel@tonic-gate return new Vector(); 5527c478bd9Sstevel@tonic-gate StringTokenizer st = new StringTokenizer(s, ",()", true); 5537c478bd9Sstevel@tonic-gate try { 5547c478bd9Sstevel@tonic-gate int level = 0; 5557c478bd9Sstevel@tonic-gate String el = ""; 5567c478bd9Sstevel@tonic-gate Vector v = new Vector(); 5577c478bd9Sstevel@tonic-gate 5587c478bd9Sstevel@tonic-gate while (st.hasMoreElements()) { 5597c478bd9Sstevel@tonic-gate String tok = st.nextToken(); 5607c478bd9Sstevel@tonic-gate 5617c478bd9Sstevel@tonic-gate // It's an open paren, so begin collecting. 5627c478bd9Sstevel@tonic-gate 5637c478bd9Sstevel@tonic-gate if (tok.equals("(")) { 5647c478bd9Sstevel@tonic-gate 5657c478bd9Sstevel@tonic-gate // Increment the level if not ignoring parens, add to token 5667c478bd9Sstevel@tonic-gate 5677c478bd9Sstevel@tonic-gate if (!ignoreParens) { 5687c478bd9Sstevel@tonic-gate level++; 5697c478bd9Sstevel@tonic-gate 5707c478bd9Sstevel@tonic-gate } 5717c478bd9Sstevel@tonic-gate 5727c478bd9Sstevel@tonic-gate el += tok; 5737c478bd9Sstevel@tonic-gate 5747c478bd9Sstevel@tonic-gate } else if (tok.equals(")")) { 5757c478bd9Sstevel@tonic-gate 5767c478bd9Sstevel@tonic-gate // Decrement level if not ignoring parens. 5777c478bd9Sstevel@tonic-gate 5787c478bd9Sstevel@tonic-gate if (!ignoreParens) { 5797c478bd9Sstevel@tonic-gate level--; 5807c478bd9Sstevel@tonic-gate 5817c478bd9Sstevel@tonic-gate } 5827c478bd9Sstevel@tonic-gate 5837c478bd9Sstevel@tonic-gate el += tok; 5847c478bd9Sstevel@tonic-gate 5857c478bd9Sstevel@tonic-gate } else if (tok.equals(",")) { 5867c478bd9Sstevel@tonic-gate 5877c478bd9Sstevel@tonic-gate // Add if collecting. 5887c478bd9Sstevel@tonic-gate 5897c478bd9Sstevel@tonic-gate if (level != 0) { 5907c478bd9Sstevel@tonic-gate el += tok; 5917c478bd9Sstevel@tonic-gate 5927c478bd9Sstevel@tonic-gate } else { 5937c478bd9Sstevel@tonic-gate 5947c478bd9Sstevel@tonic-gate // Check for empty token. 5957c478bd9Sstevel@tonic-gate 5967c478bd9Sstevel@tonic-gate if (el.length() <= 0) { 5977c478bd9Sstevel@tonic-gate throw 5987c478bd9Sstevel@tonic-gate new ServiceLocationException( 5997c478bd9Sstevel@tonic-gate ServiceLocationException.PARSE_ERROR, 6007c478bd9Sstevel@tonic-gate "csl_syntax_error", 6017c478bd9Sstevel@tonic-gate new Object[] {s}); 6027c478bd9Sstevel@tonic-gate } 6037c478bd9Sstevel@tonic-gate 6047c478bd9Sstevel@tonic-gate // If not collecting, then close off the element. 6057c478bd9Sstevel@tonic-gate 6067c478bd9Sstevel@tonic-gate v.addElement(el); 6077c478bd9Sstevel@tonic-gate el = ""; 6087c478bd9Sstevel@tonic-gate 6097c478bd9Sstevel@tonic-gate } 6107c478bd9Sstevel@tonic-gate } else { 6117c478bd9Sstevel@tonic-gate el += tok; 6127c478bd9Sstevel@tonic-gate 6137c478bd9Sstevel@tonic-gate } 6147c478bd9Sstevel@tonic-gate } 6157c478bd9Sstevel@tonic-gate 6167c478bd9Sstevel@tonic-gate // Add last token, but check first for empty token. 6177c478bd9Sstevel@tonic-gate 6187c478bd9Sstevel@tonic-gate if (el.length() <= 0) { 6197c478bd9Sstevel@tonic-gate throw 6207c478bd9Sstevel@tonic-gate new ServiceLocationException( 6217c478bd9Sstevel@tonic-gate ServiceLocationException.PARSE_ERROR, 6227c478bd9Sstevel@tonic-gate "csl_syntax_error", 6237c478bd9Sstevel@tonic-gate new Object[] {s}); 6247c478bd9Sstevel@tonic-gate } 6257c478bd9Sstevel@tonic-gate 6267c478bd9Sstevel@tonic-gate v.addElement(el); 6277c478bd9Sstevel@tonic-gate 6287c478bd9Sstevel@tonic-gate // If we're still collecting on close, then there's a syntax error. 6297c478bd9Sstevel@tonic-gate 6307c478bd9Sstevel@tonic-gate if (level != 0) { 6317c478bd9Sstevel@tonic-gate throw 6327c478bd9Sstevel@tonic-gate new ServiceLocationException( 6337c478bd9Sstevel@tonic-gate ServiceLocationException.PARSE_ERROR, 6347c478bd9Sstevel@tonic-gate "csl_syntax_error", 6357c478bd9Sstevel@tonic-gate new Object[] {s}); 6367c478bd9Sstevel@tonic-gate } 6377c478bd9Sstevel@tonic-gate 6387c478bd9Sstevel@tonic-gate return v; 6397c478bd9Sstevel@tonic-gate } catch (NoSuchElementException nsee) { 6407c478bd9Sstevel@tonic-gate throw 6417c478bd9Sstevel@tonic-gate new ServiceLocationException( 6427c478bd9Sstevel@tonic-gate ServiceLocationException.PARSE_ERROR, 6437c478bd9Sstevel@tonic-gate "csl_syntax_error", 6447c478bd9Sstevel@tonic-gate new Object[] {s}); 6457c478bd9Sstevel@tonic-gate 6467c478bd9Sstevel@tonic-gate } 6477c478bd9Sstevel@tonic-gate } 6487c478bd9Sstevel@tonic-gate 6497c478bd9Sstevel@tonic-gate // Allow clients to clone the header. 6507c478bd9Sstevel@tonic-gate clone()6517c478bd9Sstevel@tonic-gate public Object clone() 6527c478bd9Sstevel@tonic-gate throws CloneNotSupportedException { 6537c478bd9Sstevel@tonic-gate SrvLocHeader hdr = (SrvLocHeader)super.clone(); 6547c478bd9Sstevel@tonic-gate 6557c478bd9Sstevel@tonic-gate // Reinitialize some stuff. Subclasses must reimplement nbytes 6567c478bd9Sstevel@tonic-gate // header size calculation. 6577c478bd9Sstevel@tonic-gate 6587c478bd9Sstevel@tonic-gate hdr.length = 0; 6597c478bd9Sstevel@tonic-gate hdr.payload = new byte[0]; 6607c478bd9Sstevel@tonic-gate hdr.iNumReplies = 0; 6617c478bd9Sstevel@tonic-gate // packetlength stays the same, we may be using the same transport. 6627c478bd9Sstevel@tonic-gate 6637c478bd9Sstevel@tonic-gate return hdr; 6647c478bd9Sstevel@tonic-gate 6657c478bd9Sstevel@tonic-gate } 6667c478bd9Sstevel@tonic-gate 6677c478bd9Sstevel@tonic-gate // Construct a description of the header. Messages add individual 6687c478bd9Sstevel@tonic-gate // descriptions to this. 6697c478bd9Sstevel@tonic-gate constructDescription(String msgType, String msgDescription)6707c478bd9Sstevel@tonic-gate protected void constructDescription(String msgType, 6717c478bd9Sstevel@tonic-gate String msgDescription) { 6727c478bd9Sstevel@tonic-gate this.msgType = msgType; 6737c478bd9Sstevel@tonic-gate this.msgDescription = msgDescription; 6747c478bd9Sstevel@tonic-gate } 6757c478bd9Sstevel@tonic-gate getMsgType()6767c478bd9Sstevel@tonic-gate public String getMsgType() { 6777c478bd9Sstevel@tonic-gate if (msgType == null) { 6787c478bd9Sstevel@tonic-gate if (functionCode > 0 && functionCode < functionCodeAbbr.length) { 6797c478bd9Sstevel@tonic-gate return functionCodeAbbr[functionCode]; 6807c478bd9Sstevel@tonic-gate } else { 6817c478bd9Sstevel@tonic-gate return String.valueOf(functionCode); 6827c478bd9Sstevel@tonic-gate } 6837c478bd9Sstevel@tonic-gate } else { 6847c478bd9Sstevel@tonic-gate return msgType; 6857c478bd9Sstevel@tonic-gate } 6867c478bd9Sstevel@tonic-gate } 6877c478bd9Sstevel@tonic-gate getMsgDescription()6887c478bd9Sstevel@tonic-gate public String getMsgDescription() { 6897c478bd9Sstevel@tonic-gate return (msgDescription == null) ? "" : msgDescription; 6907c478bd9Sstevel@tonic-gate } 6917c478bd9Sstevel@tonic-gate } 692