1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright (c) 1998,2000 by Sun Microsystems, Inc. 24*7c478bd9Sstevel@tonic-gate * All rights reserved. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate #include <stdio.h> 30*7c478bd9Sstevel@tonic-gate #include <arpa/inet.h> 31*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 32*7c478bd9Sstevel@tonic-gate #include <string.h> 33*7c478bd9Sstevel@tonic-gate #include <sys/time.h> 34*7c478bd9Sstevel@tonic-gate #include <iconv.h> 35*7c478bd9Sstevel@tonic-gate #include "snoop.h" 36*7c478bd9Sstevel@tonic-gate #include "slp.h" 37*7c478bd9Sstevel@tonic-gate 38*7c478bd9Sstevel@tonic-gate #define MAXSUMLEN 30 39*7c478bd9Sstevel@tonic-gate 40*7c478bd9Sstevel@tonic-gate /* define VERIFYSLP to enable full message checking in summary mode */ 41*7c478bd9Sstevel@tonic-gate #define VERIFYSLP 42*7c478bd9Sstevel@tonic-gate 43*7c478bd9Sstevel@tonic-gate /* Globals -- ugly, yes, but fast and easy in macros */ 44*7c478bd9Sstevel@tonic-gate static int msglength; 45*7c478bd9Sstevel@tonic-gate static int retlength; 46*7c478bd9Sstevel@tonic-gate static char *msgend; /* the end of the summary message buffer */ 47*7c478bd9Sstevel@tonic-gate static char *p; /* current position in the packet */ 48*7c478bd9Sstevel@tonic-gate static char *msgbuf; /* message buffer for summary mode */ 49*7c478bd9Sstevel@tonic-gate static boolean_t url_auth = B_FALSE; 50*7c478bd9Sstevel@tonic-gate static boolean_t attr_auth = B_FALSE; 51*7c478bd9Sstevel@tonic-gate static boolean_t fresh = B_FALSE; 52*7c478bd9Sstevel@tonic-gate static boolean_t overflow = B_FALSE; 53*7c478bd9Sstevel@tonic-gate static int v1_charset = 0; /* character set; only in V1 */ 54*7c478bd9Sstevel@tonic-gate 55*7c478bd9Sstevel@tonic-gate /* Entry points for parsing the protocol */ 56*7c478bd9Sstevel@tonic-gate static int interpret_slp_v1(int, struct slpv1_hdr *, int); 57*7c478bd9Sstevel@tonic-gate static int interpret_slp_v2(int, struct slpv2_hdr *, int); 58*7c478bd9Sstevel@tonic-gate 59*7c478bd9Sstevel@tonic-gate /* header parsing */ 60*7c478bd9Sstevel@tonic-gate static int v1_header(int, struct slpv1_hdr *, int); 61*7c478bd9Sstevel@tonic-gate static int v2_header(int, struct slpv2_hdr *, int *, int); 62*7c478bd9Sstevel@tonic-gate static int v2_finish(struct slpv2_hdr *, int); 63*7c478bd9Sstevel@tonic-gate 64*7c478bd9Sstevel@tonic-gate /* V2 auth blocks */ 65*7c478bd9Sstevel@tonic-gate static int slpv2_authblock(int); 66*7c478bd9Sstevel@tonic-gate 67*7c478bd9Sstevel@tonic-gate /* From snoop_rport: */ 68*7c478bd9Sstevel@tonic-gate extern int add_transient(int, int (*)()); 69*7c478bd9Sstevel@tonic-gate 70*7c478bd9Sstevel@tonic-gate /* 71*7c478bd9Sstevel@tonic-gate * Functions for parsing each protocol message 72*7c478bd9Sstevel@tonic-gate * Each function takes the interpreter's flags argument as its input 73*7c478bd9Sstevel@tonic-gate * parameter, and returns 1 on success, or 0 on message corruption. 74*7c478bd9Sstevel@tonic-gate * retlength is set as a side-effect in summary mode. 75*7c478bd9Sstevel@tonic-gate */ 76*7c478bd9Sstevel@tonic-gate static int v2_srv_rqst(int); 77*7c478bd9Sstevel@tonic-gate static int v2_srv_rply(int); 78*7c478bd9Sstevel@tonic-gate static int v2_srv_reg(int); 79*7c478bd9Sstevel@tonic-gate static int v2_srv_dereg(int); 80*7c478bd9Sstevel@tonic-gate static int v2_srv_ack(int); 81*7c478bd9Sstevel@tonic-gate static int v2_attr_rqst(int); 82*7c478bd9Sstevel@tonic-gate static int v2_attr_rply(int); 83*7c478bd9Sstevel@tonic-gate static int v2_daadvert(int); 84*7c478bd9Sstevel@tonic-gate static int v2_srv_type_rqst(int); 85*7c478bd9Sstevel@tonic-gate static int v2_srv_type_rply(int); 86*7c478bd9Sstevel@tonic-gate static int v2_saadvert(int); 87*7c478bd9Sstevel@tonic-gate 88*7c478bd9Sstevel@tonic-gate static int v1_srv_rqst(int); 89*7c478bd9Sstevel@tonic-gate static int v1_srv_rply(int); 90*7c478bd9Sstevel@tonic-gate static int v1_srv_reg(int); 91*7c478bd9Sstevel@tonic-gate static int v1_srv_dereg(int); 92*7c478bd9Sstevel@tonic-gate static int v1_srv_ack(int); 93*7c478bd9Sstevel@tonic-gate static int v1_attr_rqst(int); 94*7c478bd9Sstevel@tonic-gate static int v1_attr_rply(int); 95*7c478bd9Sstevel@tonic-gate static int v1_daadvert(int); 96*7c478bd9Sstevel@tonic-gate static int v1_srv_type_rqst(int); 97*7c478bd9Sstevel@tonic-gate static int v1_srv_type_rply(int); 98*7c478bd9Sstevel@tonic-gate 99*7c478bd9Sstevel@tonic-gate /* 100*7c478bd9Sstevel@tonic-gate * The dispatch tables for handling individual messages, keyed by 101*7c478bd9Sstevel@tonic-gate * function number. 102*7c478bd9Sstevel@tonic-gate */ 103*7c478bd9Sstevel@tonic-gate typedef int function_handler(); 104*7c478bd9Sstevel@tonic-gate 105*7c478bd9Sstevel@tonic-gate #define V2_MAX_FUNCTION 11 106*7c478bd9Sstevel@tonic-gate 107*7c478bd9Sstevel@tonic-gate static function_handler *v2_functions[V2_MAX_FUNCTION + 1] = { 108*7c478bd9Sstevel@tonic-gate (function_handler *) NULL, 109*7c478bd9Sstevel@tonic-gate (function_handler *) v2_srv_rqst, 110*7c478bd9Sstevel@tonic-gate (function_handler *) v2_srv_rply, 111*7c478bd9Sstevel@tonic-gate (function_handler *) v2_srv_reg, 112*7c478bd9Sstevel@tonic-gate (function_handler *) v2_srv_dereg, 113*7c478bd9Sstevel@tonic-gate (function_handler *) v2_srv_ack, 114*7c478bd9Sstevel@tonic-gate (function_handler *) v2_attr_rqst, 115*7c478bd9Sstevel@tonic-gate (function_handler *) v2_attr_rply, 116*7c478bd9Sstevel@tonic-gate (function_handler *) v2_daadvert, 117*7c478bd9Sstevel@tonic-gate (function_handler *) v2_srv_type_rqst, 118*7c478bd9Sstevel@tonic-gate (function_handler *) v2_srv_type_rply, 119*7c478bd9Sstevel@tonic-gate (function_handler *) v2_saadvert }; 120*7c478bd9Sstevel@tonic-gate 121*7c478bd9Sstevel@tonic-gate #define V1_MAX_FUNCTION 10 122*7c478bd9Sstevel@tonic-gate 123*7c478bd9Sstevel@tonic-gate static function_handler *v1_functions[V1_MAX_FUNCTION + 1] = { 124*7c478bd9Sstevel@tonic-gate (function_handler *) NULL, 125*7c478bd9Sstevel@tonic-gate (function_handler *) v1_srv_rqst, 126*7c478bd9Sstevel@tonic-gate (function_handler *) v1_srv_rply, 127*7c478bd9Sstevel@tonic-gate (function_handler *) v1_srv_reg, 128*7c478bd9Sstevel@tonic-gate (function_handler *) v1_srv_dereg, 129*7c478bd9Sstevel@tonic-gate (function_handler *) v1_srv_ack, 130*7c478bd9Sstevel@tonic-gate (function_handler *) v1_attr_rqst, 131*7c478bd9Sstevel@tonic-gate (function_handler *) v1_attr_rply, 132*7c478bd9Sstevel@tonic-gate (function_handler *) v1_daadvert, 133*7c478bd9Sstevel@tonic-gate (function_handler *) v1_srv_type_rqst, 134*7c478bd9Sstevel@tonic-gate (function_handler *) v1_srv_type_rply }; 135*7c478bd9Sstevel@tonic-gate 136*7c478bd9Sstevel@tonic-gate /* TCP continuation handling */ 137*7c478bd9Sstevel@tonic-gate static boolean_t tcp_continuation = B_FALSE; 138*7c478bd9Sstevel@tonic-gate 139*7c478bd9Sstevel@tonic-gate #define MAX_TCPCONT 16 140*7c478bd9Sstevel@tonic-gate 141*7c478bd9Sstevel@tonic-gate static struct tcp_cont { 142*7c478bd9Sstevel@tonic-gate int dst_port; 143*7c478bd9Sstevel@tonic-gate char *msg; 144*7c478bd9Sstevel@tonic-gate int totallen; 145*7c478bd9Sstevel@tonic-gate int curr_offset; 146*7c478bd9Sstevel@tonic-gate } *tcp_cont[MAX_TCPCONT]; 147*7c478bd9Sstevel@tonic-gate 148*7c478bd9Sstevel@tonic-gate static int current_tcp_cont; 149*7c478bd9Sstevel@tonic-gate 150*7c478bd9Sstevel@tonic-gate static void reg_tcp_cont(char *, int, int, int); 151*7c478bd9Sstevel@tonic-gate static int add_tcp_cont(struct tcp_cont *, char *, int); 152*7c478bd9Sstevel@tonic-gate static struct tcp_cont *find_tcp_cont(int); 153*7c478bd9Sstevel@tonic-gate static void remove_tcp_cont(int); 154*7c478bd9Sstevel@tonic-gate 155*7c478bd9Sstevel@tonic-gate /* Conversions from numbers to strings */ 156*7c478bd9Sstevel@tonic-gate static char *slpv2_func(int, boolean_t); 157*7c478bd9Sstevel@tonic-gate static char *slpv2_error(unsigned short); 158*7c478bd9Sstevel@tonic-gate static char *slpv1_func(int, boolean_t); 159*7c478bd9Sstevel@tonic-gate static char *slpv1_error(unsigned short); 160*7c478bd9Sstevel@tonic-gate static char *slpv1_charset(unsigned short); 161*7c478bd9Sstevel@tonic-gate 162*7c478bd9Sstevel@tonic-gate /* 163*7c478bd9Sstevel@tonic-gate * The only external entry point to the SLP interpreter. This function 164*7c478bd9Sstevel@tonic-gate * simply dispatches the packet based on the version. 165*7c478bd9Sstevel@tonic-gate */ 166*7c478bd9Sstevel@tonic-gate void interpret_slp(int flags, char *slp, int fraglen) { 167*7c478bd9Sstevel@tonic-gate extern int dst_port, curr_proto; 168*7c478bd9Sstevel@tonic-gate struct tcp_cont *tce = NULL; 169*7c478bd9Sstevel@tonic-gate 170*7c478bd9Sstevel@tonic-gate msglength = fraglen; 171*7c478bd9Sstevel@tonic-gate retlength = 0; 172*7c478bd9Sstevel@tonic-gate p = slp; 173*7c478bd9Sstevel@tonic-gate 174*7c478bd9Sstevel@tonic-gate /* check if this is a TCP continuation */ 175*7c478bd9Sstevel@tonic-gate if (flags & F_DTAIL && curr_proto == IPPROTO_TCP) { 176*7c478bd9Sstevel@tonic-gate tce = find_tcp_cont(dst_port); 177*7c478bd9Sstevel@tonic-gate if (tce) { 178*7c478bd9Sstevel@tonic-gate if (add_tcp_cont(tce, slp, fraglen)) { 179*7c478bd9Sstevel@tonic-gate slp = tce->msg; 180*7c478bd9Sstevel@tonic-gate fraglen = tce->curr_offset; 181*7c478bd9Sstevel@tonic-gate tcp_continuation = B_TRUE; 182*7c478bd9Sstevel@tonic-gate } 183*7c478bd9Sstevel@tonic-gate } 184*7c478bd9Sstevel@tonic-gate } 185*7c478bd9Sstevel@tonic-gate if (*slp == 2 || tce) 186*7c478bd9Sstevel@tonic-gate interpret_slp_v2(flags, (void *)slp, fraglen); 187*7c478bd9Sstevel@tonic-gate else 188*7c478bd9Sstevel@tonic-gate interpret_slp_v1(flags, (void *)slp, fraglen); 189*7c478bd9Sstevel@tonic-gate 190*7c478bd9Sstevel@tonic-gate tcp_continuation = B_FALSE; 191*7c478bd9Sstevel@tonic-gate } 192*7c478bd9Sstevel@tonic-gate 193*7c478bd9Sstevel@tonic-gate /* 194*7c478bd9Sstevel@tonic-gate * Primitives. These are implemented as much as possible as macros for 195*7c478bd9Sstevel@tonic-gate * speed. 196*7c478bd9Sstevel@tonic-gate */ 197*7c478bd9Sstevel@tonic-gate 198*7c478bd9Sstevel@tonic-gate #define FIELD_DEFAULT 0 199*7c478bd9Sstevel@tonic-gate #define FIELD_PREVRESP 1 200*7c478bd9Sstevel@tonic-gate #define FIELD_TYPENA 2 201*7c478bd9Sstevel@tonic-gate 202*7c478bd9Sstevel@tonic-gate static long long netval = 0; /* need signed 64 bit quantity */ 203*7c478bd9Sstevel@tonic-gate 204*7c478bd9Sstevel@tonic-gate /* gets two bytes from p and leaves the result in netval */ 205*7c478bd9Sstevel@tonic-gate #define nbtohs() \ 206*7c478bd9Sstevel@tonic-gate netval = ((int)(p[0] & 0xff)) << 8; \ 207*7c478bd9Sstevel@tonic-gate netval += ((int)(p[1] & 0xff)) 208*7c478bd9Sstevel@tonic-gate 209*7c478bd9Sstevel@tonic-gate /* gets four bytes from p and leaves the result in netval */ 210*7c478bd9Sstevel@tonic-gate #define nbtohl() \ 211*7c478bd9Sstevel@tonic-gate netval = ((int)(p[0] & 0xff)) << 24; \ 212*7c478bd9Sstevel@tonic-gate netval += ((int)(p[1] & 0xff)) << 16; \ 213*7c478bd9Sstevel@tonic-gate netval += ((int)(p[2] & 0xff)) << 8; \ 214*7c478bd9Sstevel@tonic-gate netval += ((int)(p[3] & 0xff)) 215*7c478bd9Sstevel@tonic-gate 216*7c478bd9Sstevel@tonic-gate #define get_byte() \ 217*7c478bd9Sstevel@tonic-gate if (msglength >= 1) { \ 218*7c478bd9Sstevel@tonic-gate netval = *p; \ 219*7c478bd9Sstevel@tonic-gate p++; \ 220*7c478bd9Sstevel@tonic-gate msglength--; \ 221*7c478bd9Sstevel@tonic-gate } else \ 222*7c478bd9Sstevel@tonic-gate netval = -1 223*7c478bd9Sstevel@tonic-gate 224*7c478bd9Sstevel@tonic-gate #define GETBYTE(x) \ 225*7c478bd9Sstevel@tonic-gate get_byte(); \ 226*7c478bd9Sstevel@tonic-gate if ((retlength = netval) < 0) \ 227*7c478bd9Sstevel@tonic-gate return (0); \ 228*7c478bd9Sstevel@tonic-gate x = netval 229*7c478bd9Sstevel@tonic-gate 230*7c478bd9Sstevel@tonic-gate #define SKIPBYTE \ 231*7c478bd9Sstevel@tonic-gate get_byte(); \ 232*7c478bd9Sstevel@tonic-gate if ((retlength = netval) < 0) \ 233*7c478bd9Sstevel@tonic-gate return (0); \ 234*7c478bd9Sstevel@tonic-gate 235*7c478bd9Sstevel@tonic-gate /* 236*7c478bd9Sstevel@tonic-gate * gets two bytes from p, leaves the result in netval, and updates 237*7c478bd9Sstevel@tonic-gate * msglength and p. 238*7c478bd9Sstevel@tonic-gate */ 239*7c478bd9Sstevel@tonic-gate #define get_short() \ 240*7c478bd9Sstevel@tonic-gate if (msglength >= sizeof (unsigned short)) { \ 241*7c478bd9Sstevel@tonic-gate nbtohs(); \ 242*7c478bd9Sstevel@tonic-gate p += sizeof (unsigned short); \ 243*7c478bd9Sstevel@tonic-gate msglength -= sizeof (unsigned short); \ 244*7c478bd9Sstevel@tonic-gate } else \ 245*7c478bd9Sstevel@tonic-gate netval = -1 246*7c478bd9Sstevel@tonic-gate 247*7c478bd9Sstevel@tonic-gate #define GETSHORT(x) \ 248*7c478bd9Sstevel@tonic-gate get_short(); \ 249*7c478bd9Sstevel@tonic-gate if ((retlength = netval) < 0) \ 250*7c478bd9Sstevel@tonic-gate return (0); \ 251*7c478bd9Sstevel@tonic-gate x = netval 252*7c478bd9Sstevel@tonic-gate 253*7c478bd9Sstevel@tonic-gate #define SKIPSHORT \ 254*7c478bd9Sstevel@tonic-gate get_short(); \ 255*7c478bd9Sstevel@tonic-gate if ((retlength = netval) < 0) \ 256*7c478bd9Sstevel@tonic-gate return (0) 257*7c478bd9Sstevel@tonic-gate 258*7c478bd9Sstevel@tonic-gate #define get_int24(pp) \ 259*7c478bd9Sstevel@tonic-gate netval = ((int)((pp)[0] & 0xff)) << 16; \ 260*7c478bd9Sstevel@tonic-gate netval += ((int)((pp)[1] & 0xff)) << 8; \ 261*7c478bd9Sstevel@tonic-gate netval += ((int)((pp)[2] & 0xff)) 262*7c478bd9Sstevel@tonic-gate 263*7c478bd9Sstevel@tonic-gate static void slp_prevresp(char *p) { 264*7c478bd9Sstevel@tonic-gate char *p2; 265*7c478bd9Sstevel@tonic-gate 266*7c478bd9Sstevel@tonic-gate /* cycle through all entries */ 267*7c478bd9Sstevel@tonic-gate for (; p != NULL; p = p2) { 268*7c478bd9Sstevel@tonic-gate p2 = strchr(p, ','); 269*7c478bd9Sstevel@tonic-gate if (p2 != NULL) 270*7c478bd9Sstevel@tonic-gate *p2++ = '\0'; 271*7c478bd9Sstevel@tonic-gate 272*7c478bd9Sstevel@tonic-gate /* print entry at p */ 273*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), " \"%s\"", p); 274*7c478bd9Sstevel@tonic-gate } 275*7c478bd9Sstevel@tonic-gate } 276*7c478bd9Sstevel@tonic-gate 277*7c478bd9Sstevel@tonic-gate static int skip_field(int type) { 278*7c478bd9Sstevel@tonic-gate unsigned short stringlen; 279*7c478bd9Sstevel@tonic-gate 280*7c478bd9Sstevel@tonic-gate get_short(); 281*7c478bd9Sstevel@tonic-gate if (netval < 0) { 282*7c478bd9Sstevel@tonic-gate return (-1); 283*7c478bd9Sstevel@tonic-gate } 284*7c478bd9Sstevel@tonic-gate stringlen = netval; 285*7c478bd9Sstevel@tonic-gate 286*7c478bd9Sstevel@tonic-gate /* special case for NA field in SrvTypeRqst */ 287*7c478bd9Sstevel@tonic-gate if (type == FIELD_TYPENA && stringlen == 0xffff) { 288*7c478bd9Sstevel@tonic-gate stringlen = 0; 289*7c478bd9Sstevel@tonic-gate } 290*7c478bd9Sstevel@tonic-gate 291*7c478bd9Sstevel@tonic-gate if (stringlen > msglength) { 292*7c478bd9Sstevel@tonic-gate return (-1); 293*7c478bd9Sstevel@tonic-gate } 294*7c478bd9Sstevel@tonic-gate 295*7c478bd9Sstevel@tonic-gate msglength -= stringlen; 296*7c478bd9Sstevel@tonic-gate p += stringlen; 297*7c478bd9Sstevel@tonic-gate 298*7c478bd9Sstevel@tonic-gate return (stringlen); 299*7c478bd9Sstevel@tonic-gate } 300*7c478bd9Sstevel@tonic-gate 301*7c478bd9Sstevel@tonic-gate #define SKIPFIELD(type) \ 302*7c478bd9Sstevel@tonic-gate if ((retlength = skip_field(type)) < 0) \ 303*7c478bd9Sstevel@tonic-gate return (0) 304*7c478bd9Sstevel@tonic-gate 305*7c478bd9Sstevel@tonic-gate #define GETFIELD \ 306*7c478bd9Sstevel@tonic-gate get_short(); \ 307*7c478bd9Sstevel@tonic-gate if ((retlength = netval) < 0) \ 308*7c478bd9Sstevel@tonic-gate return (0); \ 309*7c478bd9Sstevel@tonic-gate strncat(msgbuf, p, (retlength > MAXSUMLEN ? MAXSUMLEN : retlength)); \ 310*7c478bd9Sstevel@tonic-gate p += retlength; \ 311*7c478bd9Sstevel@tonic-gate msglength -= retlength 312*7c478bd9Sstevel@tonic-gate 313*7c478bd9Sstevel@tonic-gate /* 314*7c478bd9Sstevel@tonic-gate * Determines from the first five bytes of a potential SLP header 315*7c478bd9Sstevel@tonic-gate * if the following message is really an SLP message. Returns 1 if 316*7c478bd9Sstevel@tonic-gate * it is a real SLP message, 0 if not. 317*7c478bd9Sstevel@tonic-gate */ 318*7c478bd9Sstevel@tonic-gate int valid_slp(unsigned char *slphdr, int len) { 319*7c478bd9Sstevel@tonic-gate struct slpv1_hdr slp1; 320*7c478bd9Sstevel@tonic-gate struct slpv2_hdr slp2; 321*7c478bd9Sstevel@tonic-gate 322*7c478bd9Sstevel@tonic-gate len -= (8 /* udp */ + 20 /* IP */ + 14 /* ether */); 323*7c478bd9Sstevel@tonic-gate /* a valid version will be 1 or 2 */ 324*7c478bd9Sstevel@tonic-gate switch (*slphdr) { 325*7c478bd9Sstevel@tonic-gate case 1: 326*7c478bd9Sstevel@tonic-gate memcpy(&slp1, slphdr, 5); 327*7c478bd9Sstevel@tonic-gate /* valid function? */ 328*7c478bd9Sstevel@tonic-gate if (slp1.function > V1_MAX_FUNCTION) { 329*7c478bd9Sstevel@tonic-gate return (0); 330*7c478bd9Sstevel@tonic-gate } 331*7c478bd9Sstevel@tonic-gate /* valid length heuristic */ 332*7c478bd9Sstevel@tonic-gate if (slp1.length > len) { 333*7c478bd9Sstevel@tonic-gate return (0); 334*7c478bd9Sstevel@tonic-gate } 335*7c478bd9Sstevel@tonic-gate return (1); 336*7c478bd9Sstevel@tonic-gate case 2: 337*7c478bd9Sstevel@tonic-gate memcpy(&slp2, slphdr, 5); 338*7c478bd9Sstevel@tonic-gate /* valid function? */ 339*7c478bd9Sstevel@tonic-gate if (slp2.function > V2_MAX_FUNCTION) { 340*7c478bd9Sstevel@tonic-gate return (0); 341*7c478bd9Sstevel@tonic-gate } 342*7c478bd9Sstevel@tonic-gate /* valid length heuristic */ 343*7c478bd9Sstevel@tonic-gate get_int24(&(slp2.l1)); 344*7c478bd9Sstevel@tonic-gate if (netval > len) { 345*7c478bd9Sstevel@tonic-gate return (0); 346*7c478bd9Sstevel@tonic-gate } 347*7c478bd9Sstevel@tonic-gate return (1); 348*7c478bd9Sstevel@tonic-gate default: 349*7c478bd9Sstevel@tonic-gate return (0); 350*7c478bd9Sstevel@tonic-gate } 351*7c478bd9Sstevel@tonic-gate } 352*7c478bd9Sstevel@tonic-gate 353*7c478bd9Sstevel@tonic-gate /* 354*7c478bd9Sstevel@tonic-gate * Converts a V1 char encoding to UTF8. If this fails, returns 0, 355*7c478bd9Sstevel@tonic-gate * otherwise, 1. This function is the union of iconv UTF-8 356*7c478bd9Sstevel@tonic-gate * modules and character sets registered with IANA. 357*7c478bd9Sstevel@tonic-gate */ 358*7c478bd9Sstevel@tonic-gate static int make_utf8(char *outbuf, size_t outlen, 359*7c478bd9Sstevel@tonic-gate const char *inbuf, size_t inlen) { 360*7c478bd9Sstevel@tonic-gate iconv_t cd; 361*7c478bd9Sstevel@tonic-gate size_t converted; 362*7c478bd9Sstevel@tonic-gate 363*7c478bd9Sstevel@tonic-gate switch (v1_charset) { 364*7c478bd9Sstevel@tonic-gate case 4: 365*7c478bd9Sstevel@tonic-gate case 1004: 366*7c478bd9Sstevel@tonic-gate cd = iconv_open("UTF-8", "8859-1"); 367*7c478bd9Sstevel@tonic-gate break; 368*7c478bd9Sstevel@tonic-gate case 5: 369*7c478bd9Sstevel@tonic-gate cd = iconv_open("UTF-8", "8859-2"); 370*7c478bd9Sstevel@tonic-gate break; 371*7c478bd9Sstevel@tonic-gate case 6: 372*7c478bd9Sstevel@tonic-gate cd = iconv_open("UTF-8", "8859-3"); 373*7c478bd9Sstevel@tonic-gate break; 374*7c478bd9Sstevel@tonic-gate case 7: 375*7c478bd9Sstevel@tonic-gate cd = iconv_open("UTF-8", "8859-4"); 376*7c478bd9Sstevel@tonic-gate break; 377*7c478bd9Sstevel@tonic-gate case 8: 378*7c478bd9Sstevel@tonic-gate cd = iconv_open("UTF-8", "8859-5"); 379*7c478bd9Sstevel@tonic-gate break; 380*7c478bd9Sstevel@tonic-gate case 9: 381*7c478bd9Sstevel@tonic-gate cd = iconv_open("UTF-8", "8859-6"); 382*7c478bd9Sstevel@tonic-gate break; 383*7c478bd9Sstevel@tonic-gate case 10: 384*7c478bd9Sstevel@tonic-gate cd = iconv_open("UTF-8", "8859-7"); 385*7c478bd9Sstevel@tonic-gate break; 386*7c478bd9Sstevel@tonic-gate case 11: 387*7c478bd9Sstevel@tonic-gate cd = iconv_open("UTF-8", "8859-8"); 388*7c478bd9Sstevel@tonic-gate break; 389*7c478bd9Sstevel@tonic-gate case 12: 390*7c478bd9Sstevel@tonic-gate cd = iconv_open("UTF-8", "8859-9"); 391*7c478bd9Sstevel@tonic-gate break; 392*7c478bd9Sstevel@tonic-gate case 13: 393*7c478bd9Sstevel@tonic-gate cd = iconv_open("UTF-8", "8859-10"); 394*7c478bd9Sstevel@tonic-gate break; 395*7c478bd9Sstevel@tonic-gate case 37: 396*7c478bd9Sstevel@tonic-gate cd = iconv_open("UTF-8", "ko_KR-iso2022-7"); 397*7c478bd9Sstevel@tonic-gate break; 398*7c478bd9Sstevel@tonic-gate case 104: 399*7c478bd9Sstevel@tonic-gate cd = iconv_open("UTF-8", "iso2022"); 400*7c478bd9Sstevel@tonic-gate break; 401*7c478bd9Sstevel@tonic-gate case 1000: 402*7c478bd9Sstevel@tonic-gate cd = iconv_open("UTF-8", "UCS-2"); 403*7c478bd9Sstevel@tonic-gate break; 404*7c478bd9Sstevel@tonic-gate case 1001: 405*7c478bd9Sstevel@tonic-gate cd = iconv_open("UTF-8", "UCS-4"); 406*7c478bd9Sstevel@tonic-gate break; 407*7c478bd9Sstevel@tonic-gate default: 408*7c478bd9Sstevel@tonic-gate /* 409*7c478bd9Sstevel@tonic-gate * charset not set, or reserved, or not supported, so 410*7c478bd9Sstevel@tonic-gate * just copy it and hope for the best. 411*7c478bd9Sstevel@tonic-gate */ 412*7c478bd9Sstevel@tonic-gate converted = outlen < inlen ? outlen : inlen; 413*7c478bd9Sstevel@tonic-gate memcpy(outbuf, inbuf, converted); 414*7c478bd9Sstevel@tonic-gate outbuf[converted] = 0; 415*7c478bd9Sstevel@tonic-gate return (1); 416*7c478bd9Sstevel@tonic-gate } 417*7c478bd9Sstevel@tonic-gate 418*7c478bd9Sstevel@tonic-gate if (cd == (iconv_t)-1) { 419*7c478bd9Sstevel@tonic-gate return (0); 420*7c478bd9Sstevel@tonic-gate } 421*7c478bd9Sstevel@tonic-gate 422*7c478bd9Sstevel@tonic-gate if ((converted = iconv(cd, &inbuf, &inlen, &outbuf, &outlen)) 423*7c478bd9Sstevel@tonic-gate == (size_t)-1) { 424*7c478bd9Sstevel@tonic-gate return (0); 425*7c478bd9Sstevel@tonic-gate } 426*7c478bd9Sstevel@tonic-gate 427*7c478bd9Sstevel@tonic-gate outbuf[converted] = 0; 428*7c478bd9Sstevel@tonic-gate iconv_close(cd); 429*7c478bd9Sstevel@tonic-gate 430*7c478bd9Sstevel@tonic-gate return (1); 431*7c478bd9Sstevel@tonic-gate } 432*7c478bd9Sstevel@tonic-gate 433*7c478bd9Sstevel@tonic-gate static int slp_field(char *tag, int type) { 434*7c478bd9Sstevel@tonic-gate int length; 435*7c478bd9Sstevel@tonic-gate 436*7c478bd9Sstevel@tonic-gate get_short(); 437*7c478bd9Sstevel@tonic-gate if (netval < 0) { 438*7c478bd9Sstevel@tonic-gate return (-1); 439*7c478bd9Sstevel@tonic-gate } 440*7c478bd9Sstevel@tonic-gate length = netval; 441*7c478bd9Sstevel@tonic-gate 442*7c478bd9Sstevel@tonic-gate /* special case for NA field in SrvTypeRqst */ 443*7c478bd9Sstevel@tonic-gate if (type == FIELD_TYPENA && length == 0xffff) { 444*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "%s: length = -1: Use all NAs", tag); 445*7c478bd9Sstevel@tonic-gate return (0); 446*7c478bd9Sstevel@tonic-gate } 447*7c478bd9Sstevel@tonic-gate 448*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "%s: length = %d", tag, length); 449*7c478bd9Sstevel@tonic-gate if (length > msglength) { 450*7c478bd9Sstevel@tonic-gate /* framing error: message is not long enough to contain data */ 451*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), 452*7c478bd9Sstevel@tonic-gate " [Framing error: remaining pkt length = %u]", 453*7c478bd9Sstevel@tonic-gate msglength); 454*7c478bd9Sstevel@tonic-gate return (-1); 455*7c478bd9Sstevel@tonic-gate } 456*7c478bd9Sstevel@tonic-gate 457*7c478bd9Sstevel@tonic-gate if (length > 0) { 458*7c478bd9Sstevel@tonic-gate char *buf = malloc(length + 1); 459*7c478bd9Sstevel@tonic-gate if (buf != NULL) { 460*7c478bd9Sstevel@tonic-gate if (v1_charset) { 461*7c478bd9Sstevel@tonic-gate if (!make_utf8(buf, length, p, length)) { 462*7c478bd9Sstevel@tonic-gate strcpy(buf, "[Invalid Character Encoding]"); 463*7c478bd9Sstevel@tonic-gate } 464*7c478bd9Sstevel@tonic-gate } else { 465*7c478bd9Sstevel@tonic-gate memcpy(buf, p, length); 466*7c478bd9Sstevel@tonic-gate buf[length] = '\0'; /* ensure null-terminated */ 467*7c478bd9Sstevel@tonic-gate } 468*7c478bd9Sstevel@tonic-gate 469*7c478bd9Sstevel@tonic-gate switch (type) { 470*7c478bd9Sstevel@tonic-gate case FIELD_PREVRESP: 471*7c478bd9Sstevel@tonic-gate slp_prevresp(buf); 472*7c478bd9Sstevel@tonic-gate break; 473*7c478bd9Sstevel@tonic-gate 474*7c478bd9Sstevel@tonic-gate default: 475*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), " \"%s\"", buf); 476*7c478bd9Sstevel@tonic-gate break; 477*7c478bd9Sstevel@tonic-gate } 478*7c478bd9Sstevel@tonic-gate free(buf); 479*7c478bd9Sstevel@tonic-gate } 480*7c478bd9Sstevel@tonic-gate 481*7c478bd9Sstevel@tonic-gate p += length; 482*7c478bd9Sstevel@tonic-gate msglength -= length; 483*7c478bd9Sstevel@tonic-gate } 484*7c478bd9Sstevel@tonic-gate 485*7c478bd9Sstevel@tonic-gate /* return ok */ 486*7c478bd9Sstevel@tonic-gate return (0); 487*7c478bd9Sstevel@tonic-gate } 488*7c478bd9Sstevel@tonic-gate 489*7c478bd9Sstevel@tonic-gate static int slpv2_url(int cnt) { 490*7c478bd9Sstevel@tonic-gate time_t exp; 491*7c478bd9Sstevel@tonic-gate int lifetime, length, n; 492*7c478bd9Sstevel@tonic-gate 493*7c478bd9Sstevel@tonic-gate /* reserved */ 494*7c478bd9Sstevel@tonic-gate get_byte(); 495*7c478bd9Sstevel@tonic-gate if (netval < 0) 496*7c478bd9Sstevel@tonic-gate return (-1); 497*7c478bd9Sstevel@tonic-gate 498*7c478bd9Sstevel@tonic-gate /* lifetime */ 499*7c478bd9Sstevel@tonic-gate get_short(); 500*7c478bd9Sstevel@tonic-gate if ((lifetime = netval) < 0) 501*7c478bd9Sstevel@tonic-gate return (-1); 502*7c478bd9Sstevel@tonic-gate 503*7c478bd9Sstevel@tonic-gate /* length */ 504*7c478bd9Sstevel@tonic-gate get_short(); 505*7c478bd9Sstevel@tonic-gate if ((length = netval) < 0) 506*7c478bd9Sstevel@tonic-gate return (-1); 507*7c478bd9Sstevel@tonic-gate 508*7c478bd9Sstevel@tonic-gate /* time */ 509*7c478bd9Sstevel@tonic-gate exp = time(0) + lifetime; 510*7c478bd9Sstevel@tonic-gate if (cnt == -1) 511*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), 512*7c478bd9Sstevel@tonic-gate "URL: length = %u, lifetime = %d (%24.24s)", 513*7c478bd9Sstevel@tonic-gate length, lifetime, ctime(&exp)); 514*7c478bd9Sstevel@tonic-gate else 515*7c478bd9Sstevel@tonic-gate /* number the URLs to make it easier to parse them */ 516*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), 517*7c478bd9Sstevel@tonic-gate "URL %d: length = %u, lifetime = %d (%24.24s)", 518*7c478bd9Sstevel@tonic-gate cnt, length, lifetime, ctime(&exp)); 519*7c478bd9Sstevel@tonic-gate 520*7c478bd9Sstevel@tonic-gate if (length > msglength) { 521*7c478bd9Sstevel@tonic-gate if (!tcp_continuation) 522*7c478bd9Sstevel@tonic-gate /* framing error: message is not long enough to contain data */ 523*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), 524*7c478bd9Sstevel@tonic-gate " [Framing error: remaining pkt length = %u]", 525*7c478bd9Sstevel@tonic-gate msglength); 526*7c478bd9Sstevel@tonic-gate return (-1); 527*7c478bd9Sstevel@tonic-gate } 528*7c478bd9Sstevel@tonic-gate 529*7c478bd9Sstevel@tonic-gate if (length > 0) { 530*7c478bd9Sstevel@tonic-gate char *buf = malloc(length + 1); 531*7c478bd9Sstevel@tonic-gate if (buf != NULL) { 532*7c478bd9Sstevel@tonic-gate memcpy(buf, p, length); 533*7c478bd9Sstevel@tonic-gate buf[length] = '\0'; /* ensure null-terminated */ 534*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), " \"%s\"", buf); 535*7c478bd9Sstevel@tonic-gate free(buf); 536*7c478bd9Sstevel@tonic-gate } 537*7c478bd9Sstevel@tonic-gate } 538*7c478bd9Sstevel@tonic-gate msglength -= length; 539*7c478bd9Sstevel@tonic-gate p += length; 540*7c478bd9Sstevel@tonic-gate 541*7c478bd9Sstevel@tonic-gate get_byte(); 542*7c478bd9Sstevel@tonic-gate if ((n = netval) < 0) 543*7c478bd9Sstevel@tonic-gate return (-1); 544*7c478bd9Sstevel@tonic-gate 545*7c478bd9Sstevel@tonic-gate if (n > 0) { 546*7c478bd9Sstevel@tonic-gate int i; 547*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "%d Authentication Blocks", n); 548*7c478bd9Sstevel@tonic-gate for (i = 0; i < n; i++) 549*7c478bd9Sstevel@tonic-gate if ((length = slpv2_authblock(i)) < 0) 550*7c478bd9Sstevel@tonic-gate return (-1); 551*7c478bd9Sstevel@tonic-gate } 552*7c478bd9Sstevel@tonic-gate return (0); 553*7c478bd9Sstevel@tonic-gate } 554*7c478bd9Sstevel@tonic-gate 555*7c478bd9Sstevel@tonic-gate #define DOFIELD(tag, type) \ 556*7c478bd9Sstevel@tonic-gate if (slp_field(tag, type) < 0) \ 557*7c478bd9Sstevel@tonic-gate return (0) 558*7c478bd9Sstevel@tonic-gate 559*7c478bd9Sstevel@tonic-gate #define V2_DOURL(x) \ 560*7c478bd9Sstevel@tonic-gate if (slpv2_url(x) < 0) \ 561*7c478bd9Sstevel@tonic-gate return (0) 562*7c478bd9Sstevel@tonic-gate 563*7c478bd9Sstevel@tonic-gate #define V2_DOERRCODE \ 564*7c478bd9Sstevel@tonic-gate if (msglength < sizeof (unsigned short)) \ 565*7c478bd9Sstevel@tonic-gate return (0); \ 566*7c478bd9Sstevel@tonic-gate nbtohs(); \ 567*7c478bd9Sstevel@tonic-gate errcode = netval; \ 568*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "Error code = %d, %s", \ 569*7c478bd9Sstevel@tonic-gate errcode, slpv2_error(errcode)); \ 570*7c478bd9Sstevel@tonic-gate p += sizeof (unsigned short); \ 571*7c478bd9Sstevel@tonic-gate msglength -= sizeof (unsigned short); \ 572*7c478bd9Sstevel@tonic-gate if (errcode != OK) \ 573*7c478bd9Sstevel@tonic-gate msglength = 0; /* skip rest of message */ \ 574*7c478bd9Sstevel@tonic-gate if (errcode != OK) \ 575*7c478bd9Sstevel@tonic-gate return (0) 576*7c478bd9Sstevel@tonic-gate 577*7c478bd9Sstevel@tonic-gate #define V2_DOAUTH(cnt) \ 578*7c478bd9Sstevel@tonic-gate if (slpv2_authblock(cnt) < 0) \ 579*7c478bd9Sstevel@tonic-gate return (0) 580*7c478bd9Sstevel@tonic-gate 581*7c478bd9Sstevel@tonic-gate #define V2_DOTIMESTAMP \ 582*7c478bd9Sstevel@tonic-gate if (msglength < 4) \ 583*7c478bd9Sstevel@tonic-gate return (0); \ 584*7c478bd9Sstevel@tonic-gate nbtohl(); \ 585*7c478bd9Sstevel@tonic-gate timestamp = netval; \ 586*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "Timestamp = %u, %s", \ 587*7c478bd9Sstevel@tonic-gate timestamp, (timestamp ? convert_ts(timestamp) : "0")); \ 588*7c478bd9Sstevel@tonic-gate p += 4; \ 589*7c478bd9Sstevel@tonic-gate msglength -= 4 590*7c478bd9Sstevel@tonic-gate 591*7c478bd9Sstevel@tonic-gate /* some V1 macros */ 592*7c478bd9Sstevel@tonic-gate #define SKIPAUTH(auth) \ 593*7c478bd9Sstevel@tonic-gate if (auth && ((retlength = skip_v1authblock()) < 0)) \ 594*7c478bd9Sstevel@tonic-gate return (0) 595*7c478bd9Sstevel@tonic-gate 596*7c478bd9Sstevel@tonic-gate #define DOERRCODE \ 597*7c478bd9Sstevel@tonic-gate if (msglength < sizeof (unsigned short)) \ 598*7c478bd9Sstevel@tonic-gate return (0); \ 599*7c478bd9Sstevel@tonic-gate nbtohs(); \ 600*7c478bd9Sstevel@tonic-gate errcode = netval; \ 601*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "Error code = %d, %s", errcode, \ 602*7c478bd9Sstevel@tonic-gate slpv1_error(errcode)); \ 603*7c478bd9Sstevel@tonic-gate p += sizeof (unsigned short); \ 604*7c478bd9Sstevel@tonic-gate msglength -= sizeof (unsigned short); \ 605*7c478bd9Sstevel@tonic-gate if (errcode != OK) \ 606*7c478bd9Sstevel@tonic-gate return (0) 607*7c478bd9Sstevel@tonic-gate 608*7c478bd9Sstevel@tonic-gate #define DOURL \ 609*7c478bd9Sstevel@tonic-gate if (slpv1_url(url_auth) < 0) \ 610*7c478bd9Sstevel@tonic-gate return (0) 611*7c478bd9Sstevel@tonic-gate 612*7c478bd9Sstevel@tonic-gate #define DOAUTH(auth) \ 613*7c478bd9Sstevel@tonic-gate if (auth && slpv1_authblock() < 0) \ 614*7c478bd9Sstevel@tonic-gate return (0) 615*7c478bd9Sstevel@tonic-gate 616*7c478bd9Sstevel@tonic-gate /* 617*7c478bd9Sstevel@tonic-gate * TCP Continuation handling 618*7c478bd9Sstevel@tonic-gate * We keep track of continuations in a fixed size cache, so as to prevent 619*7c478bd9Sstevel@tonic-gate * memory leaks if some continuations are never finished. The continuations 620*7c478bd9Sstevel@tonic-gate * are indexed by their destination ports. 621*7c478bd9Sstevel@tonic-gate */ 622*7c478bd9Sstevel@tonic-gate static void reg_tcp_cont(char *msg, int totallen, 623*7c478bd9Sstevel@tonic-gate int fraglen, int dst_port) { 624*7c478bd9Sstevel@tonic-gate struct tcp_cont *tce = malloc(sizeof (*tce)); 625*7c478bd9Sstevel@tonic-gate 626*7c478bd9Sstevel@tonic-gate /* always overwrite the entry at current_tcp_cont */ 627*7c478bd9Sstevel@tonic-gate if (tcp_cont[current_tcp_cont]) { 628*7c478bd9Sstevel@tonic-gate free(tcp_cont[current_tcp_cont]->msg); 629*7c478bd9Sstevel@tonic-gate free(tcp_cont[current_tcp_cont]); 630*7c478bd9Sstevel@tonic-gate } 631*7c478bd9Sstevel@tonic-gate 632*7c478bd9Sstevel@tonic-gate tce->dst_port = dst_port; 633*7c478bd9Sstevel@tonic-gate tce->msg = malloc(totallen); 634*7c478bd9Sstevel@tonic-gate memcpy(tce->msg, msg, fraglen); 635*7c478bd9Sstevel@tonic-gate tce->totallen = totallen; 636*7c478bd9Sstevel@tonic-gate tce->curr_offset = fraglen; 637*7c478bd9Sstevel@tonic-gate 638*7c478bd9Sstevel@tonic-gate tcp_cont[current_tcp_cont++] = tce; 639*7c478bd9Sstevel@tonic-gate if (current_tcp_cont == MAX_TCPCONT) 640*7c478bd9Sstevel@tonic-gate current_tcp_cont = 0; 641*7c478bd9Sstevel@tonic-gate } 642*7c478bd9Sstevel@tonic-gate 643*7c478bd9Sstevel@tonic-gate /* returns 0 if there is a mismatch error, 1 on success */ 644*7c478bd9Sstevel@tonic-gate static int add_tcp_cont(struct tcp_cont *tce, char *msg, int fraglen) { 645*7c478bd9Sstevel@tonic-gate if ((fraglen + tce->curr_offset) > tce->totallen) 646*7c478bd9Sstevel@tonic-gate return (0); 647*7c478bd9Sstevel@tonic-gate 648*7c478bd9Sstevel@tonic-gate memcpy(tce->msg + tce->curr_offset, msg, fraglen); 649*7c478bd9Sstevel@tonic-gate tce->curr_offset += fraglen; 650*7c478bd9Sstevel@tonic-gate return (1); 651*7c478bd9Sstevel@tonic-gate } 652*7c478bd9Sstevel@tonic-gate 653*7c478bd9Sstevel@tonic-gate static struct tcp_cont *find_tcp_cont(int dst_port) { 654*7c478bd9Sstevel@tonic-gate int i; 655*7c478bd9Sstevel@tonic-gate for (i = current_tcp_cont; i >= 0; i--) 656*7c478bd9Sstevel@tonic-gate if (tcp_cont[i] && tcp_cont[i]->dst_port == dst_port) 657*7c478bd9Sstevel@tonic-gate return (tcp_cont[i]); 658*7c478bd9Sstevel@tonic-gate 659*7c478bd9Sstevel@tonic-gate for (i = MAX_TCPCONT -1; i > current_tcp_cont; i--) 660*7c478bd9Sstevel@tonic-gate if (tcp_cont[i] && tcp_cont[i]->dst_port == dst_port) 661*7c478bd9Sstevel@tonic-gate return (tcp_cont[i]); 662*7c478bd9Sstevel@tonic-gate 663*7c478bd9Sstevel@tonic-gate return (NULL); 664*7c478bd9Sstevel@tonic-gate } 665*7c478bd9Sstevel@tonic-gate 666*7c478bd9Sstevel@tonic-gate static void remove_tcp_cont(int dst_port) { 667*7c478bd9Sstevel@tonic-gate int i; 668*7c478bd9Sstevel@tonic-gate for (i = current_tcp_cont; i >= 0; i--) 669*7c478bd9Sstevel@tonic-gate if (tcp_cont[i] && tcp_cont[i]->dst_port == dst_port) { 670*7c478bd9Sstevel@tonic-gate free(tcp_cont[i]->msg); 671*7c478bd9Sstevel@tonic-gate free(tcp_cont[i]); 672*7c478bd9Sstevel@tonic-gate tcp_cont[i] = NULL; 673*7c478bd9Sstevel@tonic-gate return; 674*7c478bd9Sstevel@tonic-gate } 675*7c478bd9Sstevel@tonic-gate 676*7c478bd9Sstevel@tonic-gate for (i = MAX_TCPCONT -1; i > current_tcp_cont; i--) 677*7c478bd9Sstevel@tonic-gate if (tcp_cont[i] && tcp_cont[i]->dst_port == dst_port) { 678*7c478bd9Sstevel@tonic-gate free(tcp_cont[i]->msg); 679*7c478bd9Sstevel@tonic-gate free(tcp_cont[i]); 680*7c478bd9Sstevel@tonic-gate tcp_cont[i] = NULL; 681*7c478bd9Sstevel@tonic-gate return; 682*7c478bd9Sstevel@tonic-gate } 683*7c478bd9Sstevel@tonic-gate } 684*7c478bd9Sstevel@tonic-gate 685*7c478bd9Sstevel@tonic-gate /* 686*7c478bd9Sstevel@tonic-gate * V2 interpreter 687*7c478bd9Sstevel@tonic-gate */ 688*7c478bd9Sstevel@tonic-gate 689*7c478bd9Sstevel@tonic-gate static int interpret_slp_v2(int flags, struct slpv2_hdr *slp, int fraglen) { 690*7c478bd9Sstevel@tonic-gate extern int src_port, dst_port, curr_proto; 691*7c478bd9Sstevel@tonic-gate char msgbuf_real[256]; 692*7c478bd9Sstevel@tonic-gate int totallen = 0; 693*7c478bd9Sstevel@tonic-gate 694*7c478bd9Sstevel@tonic-gate msgbuf = msgbuf_real; 695*7c478bd9Sstevel@tonic-gate 696*7c478bd9Sstevel@tonic-gate /* 697*7c478bd9Sstevel@tonic-gate * Somewhat of a hack to decode traffic from a server that does 698*7c478bd9Sstevel@tonic-gate * not send udp replies from its SLP src port. 699*7c478bd9Sstevel@tonic-gate */ 700*7c478bd9Sstevel@tonic-gate 701*7c478bd9Sstevel@tonic-gate if (curr_proto == IPPROTO_UDP && 702*7c478bd9Sstevel@tonic-gate dst_port == 427 && 703*7c478bd9Sstevel@tonic-gate src_port != 427) { 704*7c478bd9Sstevel@tonic-gate add_transient(src_port, (int (*)())interpret_slp); 705*7c478bd9Sstevel@tonic-gate } 706*7c478bd9Sstevel@tonic-gate 707*7c478bd9Sstevel@tonic-gate /* parse the header */ 708*7c478bd9Sstevel@tonic-gate if (v2_header(flags, slp, &totallen, fraglen)) { 709*7c478bd9Sstevel@tonic-gate 710*7c478bd9Sstevel@tonic-gate if (slp->function <= V2_MAX_FUNCTION && slp->function > 0) { 711*7c478bd9Sstevel@tonic-gate 712*7c478bd9Sstevel@tonic-gate /* Parse the message body */ 713*7c478bd9Sstevel@tonic-gate if ((v2_functions[slp->function])(flags)) { 714*7c478bd9Sstevel@tonic-gate 715*7c478bd9Sstevel@tonic-gate /* finish any remaining tasks */ 716*7c478bd9Sstevel@tonic-gate v2_finish(slp, flags); 717*7c478bd9Sstevel@tonic-gate 718*7c478bd9Sstevel@tonic-gate } 719*7c478bd9Sstevel@tonic-gate 720*7c478bd9Sstevel@tonic-gate } 721*7c478bd9Sstevel@tonic-gate 722*7c478bd9Sstevel@tonic-gate } 723*7c478bd9Sstevel@tonic-gate 724*7c478bd9Sstevel@tonic-gate /* summary error check */ 725*7c478bd9Sstevel@tonic-gate if (flags & F_SUM) { 726*7c478bd9Sstevel@tonic-gate if (retlength < 0) { 727*7c478bd9Sstevel@tonic-gate if (curr_proto == IPPROTO_TCP) 728*7c478bd9Sstevel@tonic-gate sprintf(get_sum_line(), 729*7c478bd9Sstevel@tonic-gate "%s [partial TCP message]", msgbuf); 730*7c478bd9Sstevel@tonic-gate else if (overflow) 731*7c478bd9Sstevel@tonic-gate sprintf(get_sum_line(), "%s [OVERFLOW]", msgbuf); 732*7c478bd9Sstevel@tonic-gate else 733*7c478bd9Sstevel@tonic-gate sprintf(get_sum_line(), "%s [CORRUPTED MESSAGE]", msgbuf); 734*7c478bd9Sstevel@tonic-gate } 735*7c478bd9Sstevel@tonic-gate #ifdef VERIFYSLP 736*7c478bd9Sstevel@tonic-gate else if (msglength > 0) 737*7c478bd9Sstevel@tonic-gate sprintf(get_sum_line(), "%s +%d", msgbuf, msglength); 738*7c478bd9Sstevel@tonic-gate #endif 739*7c478bd9Sstevel@tonic-gate else 740*7c478bd9Sstevel@tonic-gate sprintf(get_sum_line(), "%s", msgbuf); 741*7c478bd9Sstevel@tonic-gate } else if (flags & F_DTAIL) { 742*7c478bd9Sstevel@tonic-gate /* detailed error check */ 743*7c478bd9Sstevel@tonic-gate if (msglength > 0) { 744*7c478bd9Sstevel@tonic-gate if (tcp_continuation) { 745*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), 746*7c478bd9Sstevel@tonic-gate "[TCP Continuation, %d bytes remaining]", 747*7c478bd9Sstevel@tonic-gate totallen - fraglen); 748*7c478bd9Sstevel@tonic-gate } else 749*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), 750*7c478bd9Sstevel@tonic-gate "[%d extra bytes at end of SLP message]", msglength); 751*7c478bd9Sstevel@tonic-gate } 752*7c478bd9Sstevel@tonic-gate 753*7c478bd9Sstevel@tonic-gate show_trailer(); 754*7c478bd9Sstevel@tonic-gate 755*7c478bd9Sstevel@tonic-gate if (tcp_continuation && msglength == 0) 756*7c478bd9Sstevel@tonic-gate remove_tcp_cont(dst_port); 757*7c478bd9Sstevel@tonic-gate } 758*7c478bd9Sstevel@tonic-gate 759*7c478bd9Sstevel@tonic-gate return (0); 760*7c478bd9Sstevel@tonic-gate } 761*7c478bd9Sstevel@tonic-gate 762*7c478bd9Sstevel@tonic-gate static int v2_header(int flags, 763*7c478bd9Sstevel@tonic-gate struct slpv2_hdr *slp, 764*7c478bd9Sstevel@tonic-gate int *totallen, 765*7c478bd9Sstevel@tonic-gate int fraglen) { 766*7c478bd9Sstevel@tonic-gate extern int curr_proto, dst_port; 767*7c478bd9Sstevel@tonic-gate char *prototag = (curr_proto == IPPROTO_TCP ? "/tcp" : ""); 768*7c478bd9Sstevel@tonic-gate 769*7c478bd9Sstevel@tonic-gate if ((slp->flags & V2_OVERFLOW) == V2_OVERFLOW) 770*7c478bd9Sstevel@tonic-gate overflow = B_TRUE; 771*7c478bd9Sstevel@tonic-gate 772*7c478bd9Sstevel@tonic-gate /* summary mode header parsing */ 773*7c478bd9Sstevel@tonic-gate if (flags & F_SUM) { 774*7c478bd9Sstevel@tonic-gate 775*7c478bd9Sstevel@tonic-gate /* make sure we have at least a header */ 776*7c478bd9Sstevel@tonic-gate if (msglength < sizeof (*slp)) { 777*7c478bd9Sstevel@tonic-gate sprintf(get_sum_line(), "SLP V2 [Incomplete Header]"); 778*7c478bd9Sstevel@tonic-gate return (0); 779*7c478bd9Sstevel@tonic-gate } 780*7c478bd9Sstevel@tonic-gate 781*7c478bd9Sstevel@tonic-gate sprintf(msgbuf, "SLP V2 %s [%d%s] ", 782*7c478bd9Sstevel@tonic-gate slpv2_func(slp->function, B_TRUE), 783*7c478bd9Sstevel@tonic-gate ntohs(slp->xid), prototag); 784*7c478bd9Sstevel@tonic-gate 785*7c478bd9Sstevel@tonic-gate /* skip to end of header */ 786*7c478bd9Sstevel@tonic-gate msgend = msgbuf + strlen(msgbuf); 787*7c478bd9Sstevel@tonic-gate msglength -= sizeof (*slp); 788*7c478bd9Sstevel@tonic-gate p += sizeof (*slp); 789*7c478bd9Sstevel@tonic-gate 790*7c478bd9Sstevel@tonic-gate /* skip language tag */ 791*7c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_DEFAULT); 792*7c478bd9Sstevel@tonic-gate } else if (flags & F_DTAIL) { 793*7c478bd9Sstevel@tonic-gate char *lang; 794*7c478bd9Sstevel@tonic-gate int len; 795*7c478bd9Sstevel@tonic-gate 796*7c478bd9Sstevel@tonic-gate /* detailed mode header parsing */ 797*7c478bd9Sstevel@tonic-gate show_header("SLP: ", "Service Location Protocol (v2)", fraglen); 798*7c478bd9Sstevel@tonic-gate show_space(); 799*7c478bd9Sstevel@tonic-gate 800*7c478bd9Sstevel@tonic-gate if (msglength < sizeof (*slp)) { 801*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "==> Incomplete SLP header"); 802*7c478bd9Sstevel@tonic-gate return (0); 803*7c478bd9Sstevel@tonic-gate } 804*7c478bd9Sstevel@tonic-gate 805*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "Version = %d", slp->vers); 806*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "Function = %d, %s", 807*7c478bd9Sstevel@tonic-gate slp->function, slpv2_func(slp->function, B_FALSE)); 808*7c478bd9Sstevel@tonic-gate get_int24(&(slp->l1)); 809*7c478bd9Sstevel@tonic-gate *totallen = netval; 810*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "Message length = %u", *totallen); 811*7c478bd9Sstevel@tonic-gate /* check for TCP continuation */ 812*7c478bd9Sstevel@tonic-gate if (curr_proto == IPPROTO_TCP && 813*7c478bd9Sstevel@tonic-gate *totallen > msglength && 814*7c478bd9Sstevel@tonic-gate !tcp_continuation) { 815*7c478bd9Sstevel@tonic-gate tcp_continuation = B_TRUE; 816*7c478bd9Sstevel@tonic-gate reg_tcp_cont((char *)slp, *totallen, msglength, dst_port); 817*7c478bd9Sstevel@tonic-gate } 818*7c478bd9Sstevel@tonic-gate 819*7c478bd9Sstevel@tonic-gate if (!tcp_continuation && *totallen != msglength) { 820*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), 821*7c478bd9Sstevel@tonic-gate " (Stated and on-the-wire lengths differ)"); 822*7c478bd9Sstevel@tonic-gate } 823*7c478bd9Sstevel@tonic-gate /* flags */ 824*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "Flags = 0x%02x", slp->flags); 825*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), " %s", 826*7c478bd9Sstevel@tonic-gate getflag(slp->flags, V2_OVERFLOW, 827*7c478bd9Sstevel@tonic-gate "overflow", "no overflow")); 828*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), " %s", 829*7c478bd9Sstevel@tonic-gate getflag(slp->flags, V2_FRESH, 830*7c478bd9Sstevel@tonic-gate "fresh registration", "no fresh registration")); 831*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), " %s", 832*7c478bd9Sstevel@tonic-gate getflag(slp->flags, V2_MCAST, 833*7c478bd9Sstevel@tonic-gate "request multicast / broadcast", "unicast")); 834*7c478bd9Sstevel@tonic-gate /* check reserved flags that must be zero */ 835*7c478bd9Sstevel@tonic-gate if ((slp->flags & 7) != 0) { 836*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), 837*7c478bd9Sstevel@tonic-gate " .... .xxx = %d (reserved flags nonzero)", 838*7c478bd9Sstevel@tonic-gate slp->flags & 7); 839*7c478bd9Sstevel@tonic-gate } 840*7c478bd9Sstevel@tonic-gate /* end of flags */ 841*7c478bd9Sstevel@tonic-gate 842*7c478bd9Sstevel@tonic-gate /* language tag */ 843*7c478bd9Sstevel@tonic-gate p = (char *)slp + sizeof (*slp); 844*7c478bd9Sstevel@tonic-gate msglength -= sizeof (*slp); 845*7c478bd9Sstevel@tonic-gate GETSHORT(len); 846*7c478bd9Sstevel@tonic-gate if (len > msglength) { 847*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), 848*7c478bd9Sstevel@tonic-gate "Language Tag Length = %u [CORRUPT MESSAGE]", 849*7c478bd9Sstevel@tonic-gate len); 850*7c478bd9Sstevel@tonic-gate return (0); 851*7c478bd9Sstevel@tonic-gate } 852*7c478bd9Sstevel@tonic-gate 853*7c478bd9Sstevel@tonic-gate lang = get_line(0, 0); 854*7c478bd9Sstevel@tonic-gate strcpy(lang, "Language Tag = "); 855*7c478bd9Sstevel@tonic-gate strncat(lang, p, len); 856*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "XID = %u", ntohs(slp->xid)); 857*7c478bd9Sstevel@tonic-gate 858*7c478bd9Sstevel@tonic-gate /* set msglength to remaining length of SLP message */ 859*7c478bd9Sstevel@tonic-gate p += len; 860*7c478bd9Sstevel@tonic-gate msglength -= len; 861*7c478bd9Sstevel@tonic-gate } 862*7c478bd9Sstevel@tonic-gate 863*7c478bd9Sstevel@tonic-gate return (1); 864*7c478bd9Sstevel@tonic-gate } 865*7c478bd9Sstevel@tonic-gate 866*7c478bd9Sstevel@tonic-gate static int v2_finish(struct slpv2_hdr *slp, int flags) { 867*7c478bd9Sstevel@tonic-gate unsigned int firstop; 868*7c478bd9Sstevel@tonic-gate 869*7c478bd9Sstevel@tonic-gate if (!(flags & F_DTAIL)) 870*7c478bd9Sstevel@tonic-gate return (1); 871*7c478bd9Sstevel@tonic-gate 872*7c478bd9Sstevel@tonic-gate /* check for options */ 873*7c478bd9Sstevel@tonic-gate get_int24(&(slp->o1)); 874*7c478bd9Sstevel@tonic-gate firstop = netval; 875*7c478bd9Sstevel@tonic-gate 876*7c478bd9Sstevel@tonic-gate if (firstop) { 877*7c478bd9Sstevel@tonic-gate unsigned short op_id; 878*7c478bd9Sstevel@tonic-gate unsigned short nextop; 879*7c478bd9Sstevel@tonic-gate char *op_class; 880*7c478bd9Sstevel@tonic-gate 881*7c478bd9Sstevel@tonic-gate for (;;) { 882*7c478bd9Sstevel@tonic-gate unsigned short real_oplen; 883*7c478bd9Sstevel@tonic-gate 884*7c478bd9Sstevel@tonic-gate if (msglength < 4) { 885*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), 886*7c478bd9Sstevel@tonic-gate "Option expected but not present"); 887*7c478bd9Sstevel@tonic-gate return (0); 888*7c478bd9Sstevel@tonic-gate } 889*7c478bd9Sstevel@tonic-gate 890*7c478bd9Sstevel@tonic-gate nbtohs(); 891*7c478bd9Sstevel@tonic-gate op_id = netval; 892*7c478bd9Sstevel@tonic-gate p += sizeof (unsigned short); 893*7c478bd9Sstevel@tonic-gate msglength -= sizeof (unsigned short); 894*7c478bd9Sstevel@tonic-gate nbtohs(); 895*7c478bd9Sstevel@tonic-gate nextop = netval; 896*7c478bd9Sstevel@tonic-gate p += sizeof (unsigned short); 897*7c478bd9Sstevel@tonic-gate msglength -= sizeof (unsigned short); 898*7c478bd9Sstevel@tonic-gate 899*7c478bd9Sstevel@tonic-gate real_oplen = nextop ? nextop : msglength; 900*7c478bd9Sstevel@tonic-gate 901*7c478bd9Sstevel@tonic-gate /* known options */ 902*7c478bd9Sstevel@tonic-gate switch (op_id) { 903*7c478bd9Sstevel@tonic-gate case 1: 904*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), 905*7c478bd9Sstevel@tonic-gate "Option: Required Attribute Missing"); 906*7c478bd9Sstevel@tonic-gate DOFIELD("Template IDVer", FIELD_DEFAULT); 907*7c478bd9Sstevel@tonic-gate DOFIELD("Required Attrs", FIELD_DEFAULT); 908*7c478bd9Sstevel@tonic-gate break; 909*7c478bd9Sstevel@tonic-gate default: 910*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "Option: Unknown"); 911*7c478bd9Sstevel@tonic-gate p += (real_oplen - 4); 912*7c478bd9Sstevel@tonic-gate msglength -= (real_oplen - 4); 913*7c478bd9Sstevel@tonic-gate break; 914*7c478bd9Sstevel@tonic-gate } 915*7c478bd9Sstevel@tonic-gate 916*7c478bd9Sstevel@tonic-gate if (op_id < 0x3fff) 917*7c478bd9Sstevel@tonic-gate op_class = "Standardized, optional"; 918*7c478bd9Sstevel@tonic-gate else if (op_id < 0x7fff) 919*7c478bd9Sstevel@tonic-gate op_class = "Standardized, mandatory"; 920*7c478bd9Sstevel@tonic-gate else if (op_id < 0x8fff) 921*7c478bd9Sstevel@tonic-gate op_class = "Not standardized, private"; 922*7c478bd9Sstevel@tonic-gate else if (op_id < 0xffff) 923*7c478bd9Sstevel@tonic-gate op_class = "Reserved"; 924*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "Option ID = 0x%04x, %s", 925*7c478bd9Sstevel@tonic-gate op_id, op_class); 926*7c478bd9Sstevel@tonic-gate if (nextop && 927*7c478bd9Sstevel@tonic-gate ((nextop - 4) > msglength) && 928*7c478bd9Sstevel@tonic-gate !tcp_continuation) { 929*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), 930*7c478bd9Sstevel@tonic-gate "[Framing error: remaining pkt length = %u]", 931*7c478bd9Sstevel@tonic-gate msglength); 932*7c478bd9Sstevel@tonic-gate return (0); 933*7c478bd9Sstevel@tonic-gate } 934*7c478bd9Sstevel@tonic-gate 935*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "Option Length = %u", real_oplen); 936*7c478bd9Sstevel@tonic-gate 937*7c478bd9Sstevel@tonic-gate if (!nextop) 938*7c478bd9Sstevel@tonic-gate break; 939*7c478bd9Sstevel@tonic-gate } 940*7c478bd9Sstevel@tonic-gate } 941*7c478bd9Sstevel@tonic-gate 942*7c478bd9Sstevel@tonic-gate return (1); 943*7c478bd9Sstevel@tonic-gate } 944*7c478bd9Sstevel@tonic-gate 945*7c478bd9Sstevel@tonic-gate #ifdef VERIFYSLP 946*7c478bd9Sstevel@tonic-gate static int skip_v2authblock() { 947*7c478bd9Sstevel@tonic-gate unsigned short length, slen; 948*7c478bd9Sstevel@tonic-gate 949*7c478bd9Sstevel@tonic-gate /* auth header */ 950*7c478bd9Sstevel@tonic-gate if (msglength < 10) 951*7c478bd9Sstevel@tonic-gate return (-1); 952*7c478bd9Sstevel@tonic-gate 953*7c478bd9Sstevel@tonic-gate /* block descriptor: 2 bytes */ 954*7c478bd9Sstevel@tonic-gate p += sizeof (unsigned short); 955*7c478bd9Sstevel@tonic-gate /* length */ 956*7c478bd9Sstevel@tonic-gate nbtohs(); 957*7c478bd9Sstevel@tonic-gate length = netval; 958*7c478bd9Sstevel@tonic-gate p += sizeof (unsigned short); 959*7c478bd9Sstevel@tonic-gate /* timestamp */ 960*7c478bd9Sstevel@tonic-gate p += 4; 961*7c478bd9Sstevel@tonic-gate /* SPI String length */ 962*7c478bd9Sstevel@tonic-gate nbtohs(); 963*7c478bd9Sstevel@tonic-gate slen = netval; 964*7c478bd9Sstevel@tonic-gate p += sizeof (unsigned short); 965*7c478bd9Sstevel@tonic-gate 966*7c478bd9Sstevel@tonic-gate msglength -= 10; 967*7c478bd9Sstevel@tonic-gate if (slen > msglength || length > (msglength + 10)) 968*7c478bd9Sstevel@tonic-gate return (-1); 969*7c478bd9Sstevel@tonic-gate 970*7c478bd9Sstevel@tonic-gate p += slen; 971*7c478bd9Sstevel@tonic-gate msglength -= slen; 972*7c478bd9Sstevel@tonic-gate 973*7c478bd9Sstevel@tonic-gate /* structured auth block */ 974*7c478bd9Sstevel@tonic-gate p += (length - 10 - slen); 975*7c478bd9Sstevel@tonic-gate msglength -= (length - 10 - slen); 976*7c478bd9Sstevel@tonic-gate return (0); 977*7c478bd9Sstevel@tonic-gate } 978*7c478bd9Sstevel@tonic-gate #endif 979*7c478bd9Sstevel@tonic-gate 980*7c478bd9Sstevel@tonic-gate static char *display_bsd(unsigned short bsd) { 981*7c478bd9Sstevel@tonic-gate switch (bsd) { 982*7c478bd9Sstevel@tonic-gate case 1: return ("MD5 with RSA"); 983*7c478bd9Sstevel@tonic-gate case 2: return ("DSA with SHA-1"); 984*7c478bd9Sstevel@tonic-gate case 3: return ("Keyed HMAC with MD5"); 985*7c478bd9Sstevel@tonic-gate default: return ("Unknown BSD"); 986*7c478bd9Sstevel@tonic-gate } 987*7c478bd9Sstevel@tonic-gate } 988*7c478bd9Sstevel@tonic-gate 989*7c478bd9Sstevel@tonic-gate static char *slpv2_func(int t, boolean_t s) { 990*7c478bd9Sstevel@tonic-gate static char buf[128]; 991*7c478bd9Sstevel@tonic-gate 992*7c478bd9Sstevel@tonic-gate switch (t) { 993*7c478bd9Sstevel@tonic-gate case V2_SRVRQST: return s? "SrvRqst" : "Service Request"; 994*7c478bd9Sstevel@tonic-gate case V2_SRVRPLY: return s? "SrvRply" : "Service Reply"; 995*7c478bd9Sstevel@tonic-gate case V2_SRVREG: return s? "SrvReg" : "Service Registration"; 996*7c478bd9Sstevel@tonic-gate case V2_SRVDEREG: 997*7c478bd9Sstevel@tonic-gate return (s ? "SrvDereg" : "Service Deregistration"); 998*7c478bd9Sstevel@tonic-gate case V2_SRVACK: return s? "SrvAck" : "Service Acknowledge"; 999*7c478bd9Sstevel@tonic-gate case V2_ATTRRQST: return s? "AttrRqst" : "Attribute Request"; 1000*7c478bd9Sstevel@tonic-gate case V2_ATTRRPLY: return s? "AttrRply" : "Attribute Reply"; 1001*7c478bd9Sstevel@tonic-gate case V2_DAADVERT: return s? "DAAdvert" : "DA advertisement"; 1002*7c478bd9Sstevel@tonic-gate case V2_SRVTYPERQST: 1003*7c478bd9Sstevel@tonic-gate return (s ? "SrvTypeRqst" : "Service Type Request"); 1004*7c478bd9Sstevel@tonic-gate case V2_SRVTYPERPLY: 1005*7c478bd9Sstevel@tonic-gate return (s ? "SrvTypeRply" : "Service Type Reply"); 1006*7c478bd9Sstevel@tonic-gate case V2_SAADVERT: return s? "SAAdvert" : "SA advertisement"; 1007*7c478bd9Sstevel@tonic-gate } 1008*7c478bd9Sstevel@tonic-gate sprintf(buf, "(func %d)", t); 1009*7c478bd9Sstevel@tonic-gate return (s ? buf : "unknown function"); 1010*7c478bd9Sstevel@tonic-gate } 1011*7c478bd9Sstevel@tonic-gate 1012*7c478bd9Sstevel@tonic-gate static char *slpv2_error(unsigned short code) { 1013*7c478bd9Sstevel@tonic-gate static char buf[128]; 1014*7c478bd9Sstevel@tonic-gate 1015*7c478bd9Sstevel@tonic-gate switch (code) { 1016*7c478bd9Sstevel@tonic-gate case OK: return "ok"; 1017*7c478bd9Sstevel@tonic-gate case LANG_NOT_SUPPORTED: return "language not supported"; 1018*7c478bd9Sstevel@tonic-gate case PROTOCOL_PARSE_ERR: return "protocol parse error"; 1019*7c478bd9Sstevel@tonic-gate case INVALID_REGISTRATION: return "invalid registration"; 1020*7c478bd9Sstevel@tonic-gate case SCOPE_NOT_SUPPORTED: return "scope not supported"; 1021*7c478bd9Sstevel@tonic-gate case AUTHENTICATION_UNKNOWN: return "authentication unknown"; 1022*7c478bd9Sstevel@tonic-gate case V2_AUTHENTICATION_ABSENT: return "authentication absent"; 1023*7c478bd9Sstevel@tonic-gate case V2_AUTHENTICATION_FAILED: return "authentication failed"; 1024*7c478bd9Sstevel@tonic-gate case V2_VER_NOT_SUPPORTED: return "version not supported"; 1025*7c478bd9Sstevel@tonic-gate case V2_INTERNAL_ERROR: return "internal error"; 1026*7c478bd9Sstevel@tonic-gate case V2_DA_BUSY_NOW: return "DA busy"; 1027*7c478bd9Sstevel@tonic-gate case V2_OPTION_NOT_UNDERSTOOD: return "option not understood"; 1028*7c478bd9Sstevel@tonic-gate case V2_INVALID_UPDATE: return "invalid update"; 1029*7c478bd9Sstevel@tonic-gate case V2_RQST_NOT_SUPPORTED: return "request not supported"; 1030*7c478bd9Sstevel@tonic-gate case INVALID_LIFETIME: return "invalid lifetime"; 1031*7c478bd9Sstevel@tonic-gate } 1032*7c478bd9Sstevel@tonic-gate sprintf(buf, "error %d", code); 1033*7c478bd9Sstevel@tonic-gate return (buf); 1034*7c478bd9Sstevel@tonic-gate } 1035*7c478bd9Sstevel@tonic-gate 1036*7c478bd9Sstevel@tonic-gate static char *convert_ts(unsigned int timestamp) { 1037*7c478bd9Sstevel@tonic-gate /* timestamp is in UNIX time */ 1038*7c478bd9Sstevel@tonic-gate static char buff[128]; 1039*7c478bd9Sstevel@tonic-gate 1040*7c478bd9Sstevel@tonic-gate strcpy(buff, ctime((time_t *)×tamp)); 1041*7c478bd9Sstevel@tonic-gate buff[strlen(buff) - 1] = '\0'; 1042*7c478bd9Sstevel@tonic-gate return (buff); 1043*7c478bd9Sstevel@tonic-gate } 1044*7c478bd9Sstevel@tonic-gate 1045*7c478bd9Sstevel@tonic-gate static int slpv2_authblock(int cnt) { 1046*7c478bd9Sstevel@tonic-gate unsigned short bsd, length, slen; 1047*7c478bd9Sstevel@tonic-gate char *pp, *scopes; 1048*7c478bd9Sstevel@tonic-gate unsigned int timestamp; 1049*7c478bd9Sstevel@tonic-gate 1050*7c478bd9Sstevel@tonic-gate if (msglength < 10) { 1051*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), 1052*7c478bd9Sstevel@tonic-gate " [no room for auth block header: remaining msg length = %u]", 1053*7c478bd9Sstevel@tonic-gate msglength); 1054*7c478bd9Sstevel@tonic-gate return (-1); 1055*7c478bd9Sstevel@tonic-gate } 1056*7c478bd9Sstevel@tonic-gate 1057*7c478bd9Sstevel@tonic-gate /* bsd */ 1058*7c478bd9Sstevel@tonic-gate nbtohs(); 1059*7c478bd9Sstevel@tonic-gate bsd = netval; 1060*7c478bd9Sstevel@tonic-gate p += sizeof (unsigned short); 1061*7c478bd9Sstevel@tonic-gate 1062*7c478bd9Sstevel@tonic-gate /* length */ 1063*7c478bd9Sstevel@tonic-gate nbtohs(); 1064*7c478bd9Sstevel@tonic-gate length = netval; 1065*7c478bd9Sstevel@tonic-gate p += sizeof (unsigned short); 1066*7c478bd9Sstevel@tonic-gate 1067*7c478bd9Sstevel@tonic-gate /* timestamp */ 1068*7c478bd9Sstevel@tonic-gate nbtohl(); 1069*7c478bd9Sstevel@tonic-gate timestamp = netval; 1070*7c478bd9Sstevel@tonic-gate p += 4; 1071*7c478bd9Sstevel@tonic-gate 1072*7c478bd9Sstevel@tonic-gate /* SPI String length */ 1073*7c478bd9Sstevel@tonic-gate nbtohs(); 1074*7c478bd9Sstevel@tonic-gate slen = netval; 1075*7c478bd9Sstevel@tonic-gate p += sizeof (unsigned short); 1076*7c478bd9Sstevel@tonic-gate 1077*7c478bd9Sstevel@tonic-gate msglength -= 10; 1078*7c478bd9Sstevel@tonic-gate if (slen > msglength) { 1079*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), 1080*7c478bd9Sstevel@tonic-gate " [no room for auth block scopes: remaining msg length = %u]", 1081*7c478bd9Sstevel@tonic-gate msglength); 1082*7c478bd9Sstevel@tonic-gate return (-1); 1083*7c478bd9Sstevel@tonic-gate } 1084*7c478bd9Sstevel@tonic-gate 1085*7c478bd9Sstevel@tonic-gate if (length > (msglength + 10)) { 1086*7c478bd9Sstevel@tonic-gate if (!tcp_continuation) 1087*7c478bd9Sstevel@tonic-gate /* framing error: message is not long enough to contain data */ 1088*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), 1089*7c478bd9Sstevel@tonic-gate " [Framing error: remaining pkt length = %u]", 1090*7c478bd9Sstevel@tonic-gate msglength); 1091*7c478bd9Sstevel@tonic-gate return (-1); 1092*7c478bd9Sstevel@tonic-gate } 1093*7c478bd9Sstevel@tonic-gate 1094*7c478bd9Sstevel@tonic-gate scopes = p; 1095*7c478bd9Sstevel@tonic-gate p += slen; 1096*7c478bd9Sstevel@tonic-gate msglength -= slen; 1097*7c478bd9Sstevel@tonic-gate 1098*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), 1099*7c478bd9Sstevel@tonic-gate "Auth block %d: timestamp = %s", cnt, 1100*7c478bd9Sstevel@tonic-gate (timestamp) ? convert_ts(timestamp) : "0"); 1101*7c478bd9Sstevel@tonic-gate 1102*7c478bd9Sstevel@tonic-gate pp = get_line(0, 0); 1103*7c478bd9Sstevel@tonic-gate strcpy(pp, " SPI = "); 1104*7c478bd9Sstevel@tonic-gate strncat(pp, scopes, slen); 1105*7c478bd9Sstevel@tonic-gate 1106*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), 1107*7c478bd9Sstevel@tonic-gate " block desc = 0x%04x: %s", bsd, display_bsd(bsd)); 1108*7c478bd9Sstevel@tonic-gate 1109*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), " length = %u", length); 1110*7c478bd9Sstevel@tonic-gate 1111*7c478bd9Sstevel@tonic-gate p += (length - 10 - slen); 1112*7c478bd9Sstevel@tonic-gate msglength -= (length - 10 - slen); 1113*7c478bd9Sstevel@tonic-gate return (0); 1114*7c478bd9Sstevel@tonic-gate } 1115*7c478bd9Sstevel@tonic-gate 1116*7c478bd9Sstevel@tonic-gate static int v2_srv_rqst(int flags) { 1117*7c478bd9Sstevel@tonic-gate if (flags & F_SUM) { 1118*7c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_DEFAULT); /* PR list */ 1119*7c478bd9Sstevel@tonic-gate GETFIELD; /* service type */ 1120*7c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_DEFAULT); /* scopes */ 1121*7c478bd9Sstevel@tonic-gate strcat(msgend, " ["); 1122*7c478bd9Sstevel@tonic-gate GETFIELD; /* predicate */ 1123*7c478bd9Sstevel@tonic-gate strcat(msgend, "]"); 1124*7c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_DEFAULT); /* SPI */ 1125*7c478bd9Sstevel@tonic-gate } else if (flags & F_DTAIL) { 1126*7c478bd9Sstevel@tonic-gate DOFIELD("Previous responders", FIELD_DEFAULT); 1127*7c478bd9Sstevel@tonic-gate DOFIELD("Service type", FIELD_DEFAULT); 1128*7c478bd9Sstevel@tonic-gate DOFIELD("Scopes", FIELD_DEFAULT); 1129*7c478bd9Sstevel@tonic-gate DOFIELD("Predicate string", FIELD_DEFAULT); 1130*7c478bd9Sstevel@tonic-gate DOFIELD("Requested SPI", FIELD_DEFAULT); 1131*7c478bd9Sstevel@tonic-gate } 1132*7c478bd9Sstevel@tonic-gate 1133*7c478bd9Sstevel@tonic-gate return (1); 1134*7c478bd9Sstevel@tonic-gate } 1135*7c478bd9Sstevel@tonic-gate 1136*7c478bd9Sstevel@tonic-gate static int v2_srv_rply(int flags) { 1137*7c478bd9Sstevel@tonic-gate unsigned short itemcnt, errcode; 1138*7c478bd9Sstevel@tonic-gate int n; 1139*7c478bd9Sstevel@tonic-gate 1140*7c478bd9Sstevel@tonic-gate if (flags & F_SUM) { 1141*7c478bd9Sstevel@tonic-gate int i, auth_cnt; 1142*7c478bd9Sstevel@tonic-gate 1143*7c478bd9Sstevel@tonic-gate GETSHORT(errcode); 1144*7c478bd9Sstevel@tonic-gate if (errcode != OK) { 1145*7c478bd9Sstevel@tonic-gate strcat(msgbuf, slpv2_error(errcode)); 1146*7c478bd9Sstevel@tonic-gate msglength = 0; /* skip rest of message */ 1147*7c478bd9Sstevel@tonic-gate return (0); 1148*7c478bd9Sstevel@tonic-gate } else { 1149*7c478bd9Sstevel@tonic-gate GETSHORT(itemcnt); 1150*7c478bd9Sstevel@tonic-gate sprintf(msgend, "%d URL entries", itemcnt); 1151*7c478bd9Sstevel@tonic-gate #ifdef VERIFYSLP 1152*7c478bd9Sstevel@tonic-gate for (n = 0; n < itemcnt; n++) { 1153*7c478bd9Sstevel@tonic-gate SKIPBYTE; /* reserved */ 1154*7c478bd9Sstevel@tonic-gate SKIPSHORT; /* lifetime */ 1155*7c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_DEFAULT); /* URL */ 1156*7c478bd9Sstevel@tonic-gate GETBYTE(auth_cnt); 1157*7c478bd9Sstevel@tonic-gate for (i = 0; i < auth_cnt; auth_cnt++) 1158*7c478bd9Sstevel@tonic-gate if (skip_v2authblock() < 0) 1159*7c478bd9Sstevel@tonic-gate return (0); 1160*7c478bd9Sstevel@tonic-gate } 1161*7c478bd9Sstevel@tonic-gate #endif 1162*7c478bd9Sstevel@tonic-gate } 1163*7c478bd9Sstevel@tonic-gate } else if (flags & F_DTAIL) { 1164*7c478bd9Sstevel@tonic-gate V2_DOERRCODE; 1165*7c478bd9Sstevel@tonic-gate GETSHORT(itemcnt); 1166*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "URL entry count = %d", itemcnt); 1167*7c478bd9Sstevel@tonic-gate for (n = 0; n < itemcnt; n++) { 1168*7c478bd9Sstevel@tonic-gate V2_DOURL(n); 1169*7c478bd9Sstevel@tonic-gate } 1170*7c478bd9Sstevel@tonic-gate } 1171*7c478bd9Sstevel@tonic-gate 1172*7c478bd9Sstevel@tonic-gate return (1); 1173*7c478bd9Sstevel@tonic-gate } 1174*7c478bd9Sstevel@tonic-gate 1175*7c478bd9Sstevel@tonic-gate static int v2_srv_reg(int flags) { 1176*7c478bd9Sstevel@tonic-gate int i, auth_cnt; 1177*7c478bd9Sstevel@tonic-gate 1178*7c478bd9Sstevel@tonic-gate if (flags & F_SUM) { 1179*7c478bd9Sstevel@tonic-gate SKIPBYTE; /* reserved */ 1180*7c478bd9Sstevel@tonic-gate SKIPSHORT; /* lifetime */ 1181*7c478bd9Sstevel@tonic-gate GETFIELD; /* URL */ 1182*7c478bd9Sstevel@tonic-gate #ifdef VERIFYSLP 1183*7c478bd9Sstevel@tonic-gate GETBYTE(auth_cnt); 1184*7c478bd9Sstevel@tonic-gate for (i = 0; i < auth_cnt; i++) 1185*7c478bd9Sstevel@tonic-gate if (skip_v2authblock() < 0) 1186*7c478bd9Sstevel@tonic-gate return (0); 1187*7c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_DEFAULT); /* type */ 1188*7c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_DEFAULT); /* scopes */ 1189*7c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_DEFAULT); /* attrs */ 1190*7c478bd9Sstevel@tonic-gate GETBYTE(auth_cnt); 1191*7c478bd9Sstevel@tonic-gate for (i = 0; i < auth_cnt; i++) 1192*7c478bd9Sstevel@tonic-gate if (skip_v2authblock() < 0) 1193*7c478bd9Sstevel@tonic-gate return (0); 1194*7c478bd9Sstevel@tonic-gate #endif 1195*7c478bd9Sstevel@tonic-gate } if (flags & F_DTAIL) { 1196*7c478bd9Sstevel@tonic-gate V2_DOURL(-1); 1197*7c478bd9Sstevel@tonic-gate DOFIELD("Service type", FIELD_DEFAULT); 1198*7c478bd9Sstevel@tonic-gate DOFIELD("Scopes", FIELD_DEFAULT); 1199*7c478bd9Sstevel@tonic-gate DOFIELD("Attribute list", FIELD_DEFAULT); 1200*7c478bd9Sstevel@tonic-gate /* auth */ 1201*7c478bd9Sstevel@tonic-gate GETBYTE(auth_cnt); 1202*7c478bd9Sstevel@tonic-gate for (i = 0; i < auth_cnt; i++) 1203*7c478bd9Sstevel@tonic-gate V2_DOAUTH(i); 1204*7c478bd9Sstevel@tonic-gate } 1205*7c478bd9Sstevel@tonic-gate 1206*7c478bd9Sstevel@tonic-gate return (1); 1207*7c478bd9Sstevel@tonic-gate } 1208*7c478bd9Sstevel@tonic-gate 1209*7c478bd9Sstevel@tonic-gate static int v2_srv_dereg(int flags) { 1210*7c478bd9Sstevel@tonic-gate if (flags & F_SUM) { 1211*7c478bd9Sstevel@tonic-gate int i, auth_cnt; 1212*7c478bd9Sstevel@tonic-gate 1213*7c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_DEFAULT); /* scopes */ 1214*7c478bd9Sstevel@tonic-gate SKIPBYTE; /* reserved */ 1215*7c478bd9Sstevel@tonic-gate SKIPSHORT; /* lifetime */ 1216*7c478bd9Sstevel@tonic-gate GETFIELD; /* URL */ 1217*7c478bd9Sstevel@tonic-gate 1218*7c478bd9Sstevel@tonic-gate #ifdef VERIFYSLP 1219*7c478bd9Sstevel@tonic-gate GETBYTE(auth_cnt); 1220*7c478bd9Sstevel@tonic-gate for (i = 0; i < auth_cnt; i++) 1221*7c478bd9Sstevel@tonic-gate if (skip_v2authblock() < 0) 1222*7c478bd9Sstevel@tonic-gate return (0); 1223*7c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_DEFAULT); /* attrs */ 1224*7c478bd9Sstevel@tonic-gate #endif 1225*7c478bd9Sstevel@tonic-gate } else if (flags & F_DTAIL) { 1226*7c478bd9Sstevel@tonic-gate DOFIELD("Scopes", FIELD_DEFAULT); 1227*7c478bd9Sstevel@tonic-gate V2_DOURL(-1); 1228*7c478bd9Sstevel@tonic-gate DOFIELD("Tag list", FIELD_DEFAULT); 1229*7c478bd9Sstevel@tonic-gate } 1230*7c478bd9Sstevel@tonic-gate 1231*7c478bd9Sstevel@tonic-gate return (1); 1232*7c478bd9Sstevel@tonic-gate } 1233*7c478bd9Sstevel@tonic-gate 1234*7c478bd9Sstevel@tonic-gate static int v2_srv_ack(int flags) { 1235*7c478bd9Sstevel@tonic-gate unsigned short errcode; 1236*7c478bd9Sstevel@tonic-gate if (flags & F_SUM) { 1237*7c478bd9Sstevel@tonic-gate GETSHORT(errcode); 1238*7c478bd9Sstevel@tonic-gate strcat(msgbuf, slpv2_error(errcode)); 1239*7c478bd9Sstevel@tonic-gate } else if (flags & F_DTAIL) { 1240*7c478bd9Sstevel@tonic-gate V2_DOERRCODE; 1241*7c478bd9Sstevel@tonic-gate } 1242*7c478bd9Sstevel@tonic-gate 1243*7c478bd9Sstevel@tonic-gate return (1); 1244*7c478bd9Sstevel@tonic-gate } 1245*7c478bd9Sstevel@tonic-gate 1246*7c478bd9Sstevel@tonic-gate static int v2_attr_rqst(int flags) { 1247*7c478bd9Sstevel@tonic-gate if (flags & F_SUM) { 1248*7c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_DEFAULT); /* PR list */ 1249*7c478bd9Sstevel@tonic-gate GETFIELD; /* URL */ 1250*7c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_DEFAULT); /* scopes */ 1251*7c478bd9Sstevel@tonic-gate strcat(msgend, " ["); 1252*7c478bd9Sstevel@tonic-gate GETFIELD; /* attrs */ 1253*7c478bd9Sstevel@tonic-gate strcat(msgend, "]"); 1254*7c478bd9Sstevel@tonic-gate 1255*7c478bd9Sstevel@tonic-gate #ifdef VERIFYSLP 1256*7c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_DEFAULT); /* SPI */ 1257*7c478bd9Sstevel@tonic-gate #endif 1258*7c478bd9Sstevel@tonic-gate } else if (flags & F_DTAIL) { 1259*7c478bd9Sstevel@tonic-gate DOFIELD("Previous responders", FIELD_DEFAULT); 1260*7c478bd9Sstevel@tonic-gate DOFIELD("URL", FIELD_DEFAULT); 1261*7c478bd9Sstevel@tonic-gate DOFIELD("Scopes", FIELD_DEFAULT); 1262*7c478bd9Sstevel@tonic-gate DOFIELD("Tag list", FIELD_DEFAULT); 1263*7c478bd9Sstevel@tonic-gate DOFIELD("Requested SPI", FIELD_DEFAULT); 1264*7c478bd9Sstevel@tonic-gate } 1265*7c478bd9Sstevel@tonic-gate 1266*7c478bd9Sstevel@tonic-gate return (1); 1267*7c478bd9Sstevel@tonic-gate } 1268*7c478bd9Sstevel@tonic-gate 1269*7c478bd9Sstevel@tonic-gate static int v2_attr_rply(int flags) { 1270*7c478bd9Sstevel@tonic-gate int auth_cnt, i; 1271*7c478bd9Sstevel@tonic-gate unsigned short errcode; 1272*7c478bd9Sstevel@tonic-gate 1273*7c478bd9Sstevel@tonic-gate if (flags & F_SUM) { 1274*7c478bd9Sstevel@tonic-gate GETSHORT(errcode); 1275*7c478bd9Sstevel@tonic-gate if (errcode != OK) { 1276*7c478bd9Sstevel@tonic-gate strcat(msgbuf, slpv2_error(errcode)); 1277*7c478bd9Sstevel@tonic-gate msglength = 0; /* skip rest of message */ 1278*7c478bd9Sstevel@tonic-gate return (0); 1279*7c478bd9Sstevel@tonic-gate } else { 1280*7c478bd9Sstevel@tonic-gate GETFIELD; /* attr list */ 1281*7c478bd9Sstevel@tonic-gate 1282*7c478bd9Sstevel@tonic-gate #ifdef VERIFYSLP 1283*7c478bd9Sstevel@tonic-gate GETBYTE(auth_cnt); 1284*7c478bd9Sstevel@tonic-gate for (i = 0; i < auth_cnt; i++) 1285*7c478bd9Sstevel@tonic-gate if (skip_v2authblock() < 0) 1286*7c478bd9Sstevel@tonic-gate return (0); 1287*7c478bd9Sstevel@tonic-gate #endif 1288*7c478bd9Sstevel@tonic-gate } 1289*7c478bd9Sstevel@tonic-gate } else if (flags & F_DTAIL) { 1290*7c478bd9Sstevel@tonic-gate V2_DOERRCODE; 1291*7c478bd9Sstevel@tonic-gate DOFIELD("Attribute list", FIELD_DEFAULT); 1292*7c478bd9Sstevel@tonic-gate /* auth */ 1293*7c478bd9Sstevel@tonic-gate GETBYTE(auth_cnt); 1294*7c478bd9Sstevel@tonic-gate for (i = 0; i < auth_cnt; i++) 1295*7c478bd9Sstevel@tonic-gate V2_DOAUTH(i); 1296*7c478bd9Sstevel@tonic-gate } 1297*7c478bd9Sstevel@tonic-gate 1298*7c478bd9Sstevel@tonic-gate return (1); 1299*7c478bd9Sstevel@tonic-gate } 1300*7c478bd9Sstevel@tonic-gate 1301*7c478bd9Sstevel@tonic-gate static int v2_daadvert(int flags) { 1302*7c478bd9Sstevel@tonic-gate int auth_cnt, i; 1303*7c478bd9Sstevel@tonic-gate unsigned short errcode; 1304*7c478bd9Sstevel@tonic-gate unsigned int timestamp; 1305*7c478bd9Sstevel@tonic-gate 1306*7c478bd9Sstevel@tonic-gate if (flags & F_SUM) { 1307*7c478bd9Sstevel@tonic-gate SKIPSHORT; /* error code */ 1308*7c478bd9Sstevel@tonic-gate SKIPSHORT; SKIPSHORT; /* timestamp */ 1309*7c478bd9Sstevel@tonic-gate GETFIELD; /* URL */ 1310*7c478bd9Sstevel@tonic-gate 1311*7c478bd9Sstevel@tonic-gate #ifdef VERIFYSLP 1312*7c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_DEFAULT); /* scopes */ 1313*7c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_DEFAULT); /* attrs */ 1314*7c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_DEFAULT); /* SPIs */ 1315*7c478bd9Sstevel@tonic-gate 1316*7c478bd9Sstevel@tonic-gate GETBYTE(auth_cnt); 1317*7c478bd9Sstevel@tonic-gate for (i = 0; i < auth_cnt; i++) 1318*7c478bd9Sstevel@tonic-gate if (skip_v2authblock() < 0) 1319*7c478bd9Sstevel@tonic-gate return (0); 1320*7c478bd9Sstevel@tonic-gate #endif 1321*7c478bd9Sstevel@tonic-gate } else if (flags & F_DTAIL) { 1322*7c478bd9Sstevel@tonic-gate V2_DOERRCODE; 1323*7c478bd9Sstevel@tonic-gate V2_DOTIMESTAMP; 1324*7c478bd9Sstevel@tonic-gate DOFIELD("URL", FIELD_DEFAULT); 1325*7c478bd9Sstevel@tonic-gate DOFIELD("Scope list", FIELD_DEFAULT); 1326*7c478bd9Sstevel@tonic-gate DOFIELD("Attribute list", FIELD_DEFAULT); 1327*7c478bd9Sstevel@tonic-gate DOFIELD("Configured SPIs", FIELD_DEFAULT); 1328*7c478bd9Sstevel@tonic-gate /* auth */ 1329*7c478bd9Sstevel@tonic-gate GETBYTE(auth_cnt); 1330*7c478bd9Sstevel@tonic-gate for (i = 0; i < auth_cnt; i++) 1331*7c478bd9Sstevel@tonic-gate V2_DOAUTH(i); 1332*7c478bd9Sstevel@tonic-gate } 1333*7c478bd9Sstevel@tonic-gate 1334*7c478bd9Sstevel@tonic-gate return (1); 1335*7c478bd9Sstevel@tonic-gate } 1336*7c478bd9Sstevel@tonic-gate 1337*7c478bd9Sstevel@tonic-gate static int v2_srv_type_rqst(int flags) { 1338*7c478bd9Sstevel@tonic-gate if (flags & F_SUM) { 1339*7c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_DEFAULT); /* prev responders */ 1340*7c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_TYPENA); /* naming authority */ 1341*7c478bd9Sstevel@tonic-gate GETFIELD; /* scope */ 1342*7c478bd9Sstevel@tonic-gate } else if (flags & F_DTAIL) { 1343*7c478bd9Sstevel@tonic-gate DOFIELD("Previous responders", FIELD_DEFAULT); 1344*7c478bd9Sstevel@tonic-gate DOFIELD("Naming authority", FIELD_TYPENA); 1345*7c478bd9Sstevel@tonic-gate DOFIELD("Scopes", FIELD_DEFAULT); 1346*7c478bd9Sstevel@tonic-gate } 1347*7c478bd9Sstevel@tonic-gate 1348*7c478bd9Sstevel@tonic-gate return (1); 1349*7c478bd9Sstevel@tonic-gate } 1350*7c478bd9Sstevel@tonic-gate 1351*7c478bd9Sstevel@tonic-gate static int v2_srv_type_rply(int flags) { 1352*7c478bd9Sstevel@tonic-gate unsigned short errcode; 1353*7c478bd9Sstevel@tonic-gate 1354*7c478bd9Sstevel@tonic-gate if (flags & F_SUM) { 1355*7c478bd9Sstevel@tonic-gate GETSHORT(errcode); 1356*7c478bd9Sstevel@tonic-gate if (errcode != OK) 1357*7c478bd9Sstevel@tonic-gate strcat(msgbuf, slpv2_error(errcode)); 1358*7c478bd9Sstevel@tonic-gate else 1359*7c478bd9Sstevel@tonic-gate GETFIELD; 1360*7c478bd9Sstevel@tonic-gate } else if (flags & F_DTAIL) { 1361*7c478bd9Sstevel@tonic-gate V2_DOERRCODE; 1362*7c478bd9Sstevel@tonic-gate DOFIELD("Service types", FIELD_DEFAULT); 1363*7c478bd9Sstevel@tonic-gate } 1364*7c478bd9Sstevel@tonic-gate 1365*7c478bd9Sstevel@tonic-gate return (1); 1366*7c478bd9Sstevel@tonic-gate } 1367*7c478bd9Sstevel@tonic-gate 1368*7c478bd9Sstevel@tonic-gate static int v2_saadvert(int flags) { 1369*7c478bd9Sstevel@tonic-gate int auth_cnt, i; 1370*7c478bd9Sstevel@tonic-gate 1371*7c478bd9Sstevel@tonic-gate if (flags & F_SUM) { 1372*7c478bd9Sstevel@tonic-gate GETFIELD; /* URL */ 1373*7c478bd9Sstevel@tonic-gate 1374*7c478bd9Sstevel@tonic-gate #ifdef VERIFYSLP 1375*7c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_DEFAULT); /* scopes */ 1376*7c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_DEFAULT); /* attrs */ 1377*7c478bd9Sstevel@tonic-gate 1378*7c478bd9Sstevel@tonic-gate GETBYTE(auth_cnt); 1379*7c478bd9Sstevel@tonic-gate for (i = 0; i < auth_cnt; i++) 1380*7c478bd9Sstevel@tonic-gate if (skip_v2authblock() < 0) 1381*7c478bd9Sstevel@tonic-gate return (0); 1382*7c478bd9Sstevel@tonic-gate #endif 1383*7c478bd9Sstevel@tonic-gate } else if (flags & F_DTAIL) { 1384*7c478bd9Sstevel@tonic-gate DOFIELD("URL", FIELD_DEFAULT); 1385*7c478bd9Sstevel@tonic-gate DOFIELD("Scopes", FIELD_DEFAULT); 1386*7c478bd9Sstevel@tonic-gate DOFIELD("Attribute list", FIELD_DEFAULT); 1387*7c478bd9Sstevel@tonic-gate /* auth */ 1388*7c478bd9Sstevel@tonic-gate GETBYTE(auth_cnt); 1389*7c478bd9Sstevel@tonic-gate for (i = 0; i < auth_cnt; i++) 1390*7c478bd9Sstevel@tonic-gate V2_DOAUTH(i); 1391*7c478bd9Sstevel@tonic-gate } 1392*7c478bd9Sstevel@tonic-gate 1393*7c478bd9Sstevel@tonic-gate return (1); 1394*7c478bd9Sstevel@tonic-gate } 1395*7c478bd9Sstevel@tonic-gate 1396*7c478bd9Sstevel@tonic-gate /* 1397*7c478bd9Sstevel@tonic-gate * V1 Interpreter 1398*7c478bd9Sstevel@tonic-gate */ 1399*7c478bd9Sstevel@tonic-gate 1400*7c478bd9Sstevel@tonic-gate static int interpret_slp_v1(int flags, struct slpv1_hdr *slp, int fraglen) { 1401*7c478bd9Sstevel@tonic-gate char msgbuf_real[256]; 1402*7c478bd9Sstevel@tonic-gate extern int src_port, dst_port, curr_proto; 1403*7c478bd9Sstevel@tonic-gate boolean_t overflow = B_FALSE; 1404*7c478bd9Sstevel@tonic-gate 1405*7c478bd9Sstevel@tonic-gate msgbuf = msgbuf_real; 1406*7c478bd9Sstevel@tonic-gate 1407*7c478bd9Sstevel@tonic-gate if (msglength >= sizeof (*slp)) { 1408*7c478bd9Sstevel@tonic-gate if ((slp->flags & V1_URL_AUTH) == V1_URL_AUTH) 1409*7c478bd9Sstevel@tonic-gate url_auth = B_TRUE; 1410*7c478bd9Sstevel@tonic-gate if ((slp->flags & V1_ATTR_AUTH) == V1_ATTR_AUTH) 1411*7c478bd9Sstevel@tonic-gate attr_auth = B_TRUE; 1412*7c478bd9Sstevel@tonic-gate if ((slp->flags & V1_FRESH_REG) == V1_FRESH_REG) 1413*7c478bd9Sstevel@tonic-gate fresh = B_TRUE; 1414*7c478bd9Sstevel@tonic-gate if ((slp->flags & V1_OVERFLOW) == V1_OVERFLOW) 1415*7c478bd9Sstevel@tonic-gate overflow = B_TRUE; 1416*7c478bd9Sstevel@tonic-gate } 1417*7c478bd9Sstevel@tonic-gate 1418*7c478bd9Sstevel@tonic-gate /* 1419*7c478bd9Sstevel@tonic-gate * Somewhat of a hack to decode traffic from a server that does 1420*7c478bd9Sstevel@tonic-gate * not send udp replies from its SLP src port. 1421*7c478bd9Sstevel@tonic-gate */ 1422*7c478bd9Sstevel@tonic-gate if (curr_proto == IPPROTO_UDP && 1423*7c478bd9Sstevel@tonic-gate dst_port == 427 && 1424*7c478bd9Sstevel@tonic-gate src_port != 427) 1425*7c478bd9Sstevel@tonic-gate add_transient(src_port, (int (*)())interpret_slp); 1426*7c478bd9Sstevel@tonic-gate 1427*7c478bd9Sstevel@tonic-gate /* parse the header */ 1428*7c478bd9Sstevel@tonic-gate if (v1_header(flags, slp, fraglen)) { 1429*7c478bd9Sstevel@tonic-gate 1430*7c478bd9Sstevel@tonic-gate if (slp->function <= V1_MAX_FUNCTION && slp->function > 0) { 1431*7c478bd9Sstevel@tonic-gate 1432*7c478bd9Sstevel@tonic-gate /* Parse the message body */ 1433*7c478bd9Sstevel@tonic-gate (v1_functions[slp->function])(flags); 1434*7c478bd9Sstevel@tonic-gate 1435*7c478bd9Sstevel@tonic-gate } 1436*7c478bd9Sstevel@tonic-gate 1437*7c478bd9Sstevel@tonic-gate } 1438*7c478bd9Sstevel@tonic-gate 1439*7c478bd9Sstevel@tonic-gate /* summary error check */ 1440*7c478bd9Sstevel@tonic-gate if (flags & F_SUM) { 1441*7c478bd9Sstevel@tonic-gate if (retlength < 0) { 1442*7c478bd9Sstevel@tonic-gate if (curr_proto == IPPROTO_TCP) 1443*7c478bd9Sstevel@tonic-gate sprintf(get_sum_line(), 1444*7c478bd9Sstevel@tonic-gate "%s [partial TCP message]", 1445*7c478bd9Sstevel@tonic-gate msgbuf); 1446*7c478bd9Sstevel@tonic-gate else if (overflow) 1447*7c478bd9Sstevel@tonic-gate sprintf(get_sum_line(), "%s [OVERFLOW]", msgbuf); 1448*7c478bd9Sstevel@tonic-gate else 1449*7c478bd9Sstevel@tonic-gate sprintf(get_sum_line(), "%s [CORRUPTED MESSAGE]", msgbuf); 1450*7c478bd9Sstevel@tonic-gate } 1451*7c478bd9Sstevel@tonic-gate #ifdef VERIFYSLP 1452*7c478bd9Sstevel@tonic-gate else if (msglength > 0) 1453*7c478bd9Sstevel@tonic-gate sprintf(get_sum_line(), "%s +%d", msgbuf, msglength); 1454*7c478bd9Sstevel@tonic-gate #endif 1455*7c478bd9Sstevel@tonic-gate else 1456*7c478bd9Sstevel@tonic-gate sprintf(get_sum_line(), "%s", msgbuf); 1457*7c478bd9Sstevel@tonic-gate } else if (flags & F_DTAIL) { 1458*7c478bd9Sstevel@tonic-gate /* detail error check */ 1459*7c478bd9Sstevel@tonic-gate if (msglength > 0) { 1460*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), 1461*7c478bd9Sstevel@tonic-gate "[%d extra bytes at end of SLP message]", msglength); 1462*7c478bd9Sstevel@tonic-gate } 1463*7c478bd9Sstevel@tonic-gate 1464*7c478bd9Sstevel@tonic-gate show_trailer(); 1465*7c478bd9Sstevel@tonic-gate 1466*7c478bd9Sstevel@tonic-gate } 1467*7c478bd9Sstevel@tonic-gate 1468*7c478bd9Sstevel@tonic-gate v1_charset = 0; 1469*7c478bd9Sstevel@tonic-gate 1470*7c478bd9Sstevel@tonic-gate return (0); 1471*7c478bd9Sstevel@tonic-gate } 1472*7c478bd9Sstevel@tonic-gate 1473*7c478bd9Sstevel@tonic-gate static int v1_header(int flags, 1474*7c478bd9Sstevel@tonic-gate struct slpv1_hdr *slp, 1475*7c478bd9Sstevel@tonic-gate int fraglen) { 1476*7c478bd9Sstevel@tonic-gate extern int src_port, dst_port, curr_proto; 1477*7c478bd9Sstevel@tonic-gate char *prototag = (curr_proto == IPPROTO_TCP? "/tcp" : ""); 1478*7c478bd9Sstevel@tonic-gate 1479*7c478bd9Sstevel@tonic-gate if (flags & F_SUM) { 1480*7c478bd9Sstevel@tonic-gate char portflag = ' '; 1481*7c478bd9Sstevel@tonic-gate 1482*7c478bd9Sstevel@tonic-gate if (msglength < sizeof (*slp)) { 1483*7c478bd9Sstevel@tonic-gate sprintf(msgbuf, "SLP V1 [incomplete header]"); 1484*7c478bd9Sstevel@tonic-gate return (0); 1485*7c478bd9Sstevel@tonic-gate } 1486*7c478bd9Sstevel@tonic-gate 1487*7c478bd9Sstevel@tonic-gate if (slp->vers != 1) { 1488*7c478bd9Sstevel@tonic-gate if (curr_proto == IPPROTO_TCP) 1489*7c478bd9Sstevel@tonic-gate sprintf(msgbuf, "SLP [TCP Continuation]"); 1490*7c478bd9Sstevel@tonic-gate else 1491*7c478bd9Sstevel@tonic-gate sprintf(msgbuf, "SLP [unknown version %d]", slp->vers); 1492*7c478bd9Sstevel@tonic-gate return (0); 1493*7c478bd9Sstevel@tonic-gate } 1494*7c478bd9Sstevel@tonic-gate 1495*7c478bd9Sstevel@tonic-gate if (src_port != 427 && dst_port != 427) 1496*7c478bd9Sstevel@tonic-gate portflag = '-'; 1497*7c478bd9Sstevel@tonic-gate 1498*7c478bd9Sstevel@tonic-gate sprintf(msgbuf, "SLP V1%c%s [%d%s] ", portflag, 1499*7c478bd9Sstevel@tonic-gate slpv1_func(slp->function, B_TRUE), 1500*7c478bd9Sstevel@tonic-gate ntohs(slp->xid), prototag); 1501*7c478bd9Sstevel@tonic-gate msgend = msgbuf + strlen(msgbuf); 1502*7c478bd9Sstevel@tonic-gate msglength -= sizeof (*slp); 1503*7c478bd9Sstevel@tonic-gate p += sizeof (*slp); 1504*7c478bd9Sstevel@tonic-gate } else if (flags & F_DTAIL) { 1505*7c478bd9Sstevel@tonic-gate show_header("SLP: ", "Service Location Protocol (v1)", fraglen); 1506*7c478bd9Sstevel@tonic-gate show_space(); 1507*7c478bd9Sstevel@tonic-gate 1508*7c478bd9Sstevel@tonic-gate if (msglength < sizeof (*slp)) { 1509*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "==> Incomplete SLP header"); 1510*7c478bd9Sstevel@tonic-gate return (0); 1511*7c478bd9Sstevel@tonic-gate } 1512*7c478bd9Sstevel@tonic-gate 1513*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "Version = %d", slp->vers); 1514*7c478bd9Sstevel@tonic-gate if (slp->vers != 1) { 1515*7c478bd9Sstevel@tonic-gate if (curr_proto == IPPROTO_TCP) 1516*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "==> TCP continuation"); 1517*7c478bd9Sstevel@tonic-gate else 1518*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "==> Unexpected version number"); 1519*7c478bd9Sstevel@tonic-gate return (0); 1520*7c478bd9Sstevel@tonic-gate } 1521*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "Function = %d, %s", 1522*7c478bd9Sstevel@tonic-gate slp->function, slpv1_func(slp->function, B_FALSE)); 1523*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "Message length = %u", ntohs(slp->length)); 1524*7c478bd9Sstevel@tonic-gate 1525*7c478bd9Sstevel@tonic-gate /* flags */ 1526*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "Flags = 0x%02x", slp->flags); 1527*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), " %s", 1528*7c478bd9Sstevel@tonic-gate getflag(slp->flags, V1_OVERFLOW, 1529*7c478bd9Sstevel@tonic-gate "overflow", "no overflow")); 1530*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), " %s", 1531*7c478bd9Sstevel@tonic-gate getflag(slp->flags, V1_MONOLINGUAL, 1532*7c478bd9Sstevel@tonic-gate "monolingual", "not monolingual")); 1533*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), " %s", 1534*7c478bd9Sstevel@tonic-gate getflag(slp->flags, V1_URL_AUTH, 1535*7c478bd9Sstevel@tonic-gate "url authentication", "no url authentication")); 1536*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), " %s", 1537*7c478bd9Sstevel@tonic-gate getflag(slp->flags, V1_ATTR_AUTH, 1538*7c478bd9Sstevel@tonic-gate "attribute authentication", "no attribute authentication")); 1539*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), " %s", 1540*7c478bd9Sstevel@tonic-gate getflag(slp->flags, V1_FRESH_REG, 1541*7c478bd9Sstevel@tonic-gate "fresh registration", "no fresh registration")); 1542*7c478bd9Sstevel@tonic-gate /* check reserved flags that must be zero */ 1543*7c478bd9Sstevel@tonic-gate if ((slp->flags & 7) != 0) { 1544*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), 1545*7c478bd9Sstevel@tonic-gate " .... .xxx = %d (reserved flags nonzero)", 1546*7c478bd9Sstevel@tonic-gate slp->flags & 7); 1547*7c478bd9Sstevel@tonic-gate } 1548*7c478bd9Sstevel@tonic-gate /* end of flags */ 1549*7c478bd9Sstevel@tonic-gate 1550*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "Dialect = %u", slp->dialect); 1551*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "Language = 0x%02x%02x, %c%c", 1552*7c478bd9Sstevel@tonic-gate slp->language[0], slp->language[1], 1553*7c478bd9Sstevel@tonic-gate slp->language[0], slp->language[1]); 1554*7c478bd9Sstevel@tonic-gate v1_charset = ntohs(slp->charset); 1555*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "Character encoding = %u, %s", 1556*7c478bd9Sstevel@tonic-gate v1_charset, 1557*7c478bd9Sstevel@tonic-gate slpv1_charset(v1_charset)); 1558*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "XID = %u", ntohs(slp->xid)); 1559*7c478bd9Sstevel@tonic-gate 1560*7c478bd9Sstevel@tonic-gate /* set msglength to remaining length of SLP message */ 1561*7c478bd9Sstevel@tonic-gate msglength -= sizeof (*slp); 1562*7c478bd9Sstevel@tonic-gate p += sizeof (*slp); 1563*7c478bd9Sstevel@tonic-gate } 1564*7c478bd9Sstevel@tonic-gate 1565*7c478bd9Sstevel@tonic-gate return (1); 1566*7c478bd9Sstevel@tonic-gate } 1567*7c478bd9Sstevel@tonic-gate 1568*7c478bd9Sstevel@tonic-gate static char *slpv1_func(int t, boolean_t s) { 1569*7c478bd9Sstevel@tonic-gate static char buf[128]; 1570*7c478bd9Sstevel@tonic-gate switch (t) { 1571*7c478bd9Sstevel@tonic-gate case V1_SRVREQ: return s? "SrvRqst" : "Service Request"; 1572*7c478bd9Sstevel@tonic-gate case V1_SRVRPLY: return s? "SrvRply" : "Service Reply"; 1573*7c478bd9Sstevel@tonic-gate case V1_SRVREG: return s? "SrvReg" : "Service Registration"; 1574*7c478bd9Sstevel@tonic-gate case V1_SRVDEREG: return s? 1575*7c478bd9Sstevel@tonic-gate "SrvDereg" : "Service Deregistration"; 1576*7c478bd9Sstevel@tonic-gate case V1_SRVACK: return s? "SrvAck" : "Service Acknowledge"; 1577*7c478bd9Sstevel@tonic-gate case V1_ATTRRQST: return s? "AttrRqst" : "Attribute Request"; 1578*7c478bd9Sstevel@tonic-gate case V1_ATTRRPLY: return s? "AttrRply" : "Attribute Reply"; 1579*7c478bd9Sstevel@tonic-gate case V1_DAADVERT: return s? "DAAdvert" : "DA advertisement"; 1580*7c478bd9Sstevel@tonic-gate case V1_SRVTYPERQST:return s? "SrvTypeRqst" : "Service Type Request"; 1581*7c478bd9Sstevel@tonic-gate case V1_SRVTYPERPLY:return s? "SrvTypeRply" : "Service Type Reply"; 1582*7c478bd9Sstevel@tonic-gate } 1583*7c478bd9Sstevel@tonic-gate sprintf(buf, "(func %d)", t); 1584*7c478bd9Sstevel@tonic-gate return (s ? buf : "unknown function"); 1585*7c478bd9Sstevel@tonic-gate } 1586*7c478bd9Sstevel@tonic-gate 1587*7c478bd9Sstevel@tonic-gate static char *slpv1_error(unsigned short code) { 1588*7c478bd9Sstevel@tonic-gate static char buf[128]; 1589*7c478bd9Sstevel@tonic-gate 1590*7c478bd9Sstevel@tonic-gate switch (code) { 1591*7c478bd9Sstevel@tonic-gate case OK: return "ok"; 1592*7c478bd9Sstevel@tonic-gate case LANG_NOT_SUPPORTED: return "language not supported"; 1593*7c478bd9Sstevel@tonic-gate case PROTOCOL_PARSE_ERR: return "protocol parse error"; 1594*7c478bd9Sstevel@tonic-gate case INVALID_REGISTRATION: return "invalid registration"; 1595*7c478bd9Sstevel@tonic-gate case SCOPE_NOT_SUPPORTED: return "scope not supported"; 1596*7c478bd9Sstevel@tonic-gate case CHARSET_NOT_UNDERSTOOD:return "character set not understood"; 1597*7c478bd9Sstevel@tonic-gate case AUTHENTICATION_INVALID:return "invalid authentication"; 1598*7c478bd9Sstevel@tonic-gate case NOT_SUPPORTED_YET: return "not yet supported"; 1599*7c478bd9Sstevel@tonic-gate case REQUEST_TIMED_OUT: return "request timed out"; 1600*7c478bd9Sstevel@tonic-gate case COULD_NOT_INIT_NET_RESOURCES: 1601*7c478bd9Sstevel@tonic-gate return ("could not initialize net resources"); 1602*7c478bd9Sstevel@tonic-gate case COULD_NOT_ALLOCATE_MEMORY: 1603*7c478bd9Sstevel@tonic-gate return ("could not allocate memory"); 1604*7c478bd9Sstevel@tonic-gate case PARAMETER_BAD: return "bad parameter"; 1605*7c478bd9Sstevel@tonic-gate case INTERNAL_NET_ERROR: return "internal network error"; 1606*7c478bd9Sstevel@tonic-gate case INTERNAL_SYSTEM_ERROR: return "internal system error"; 1607*7c478bd9Sstevel@tonic-gate } 1608*7c478bd9Sstevel@tonic-gate sprintf(buf, "error %d", code); 1609*7c478bd9Sstevel@tonic-gate return (buf); 1610*7c478bd9Sstevel@tonic-gate } 1611*7c478bd9Sstevel@tonic-gate 1612*7c478bd9Sstevel@tonic-gate /* 1613*7c478bd9Sstevel@tonic-gate * Character set info from 1614*7c478bd9Sstevel@tonic-gate * www.isi.edu/in-notes/iana/assignments/character-sets 1615*7c478bd9Sstevel@tonic-gate * 1616*7c478bd9Sstevel@tonic-gate * Assigned MIB enum Numbers 1617*7c478bd9Sstevel@tonic-gate * ------------------------- 1618*7c478bd9Sstevel@tonic-gate * 0 Reserved 1619*7c478bd9Sstevel@tonic-gate * 1 Reserved 1620*7c478bd9Sstevel@tonic-gate * 3-106 Set By Standards Organizations 1621*7c478bd9Sstevel@tonic-gate * 1000-1010 Unicode / 10646 1622*7c478bd9Sstevel@tonic-gate * 2000-2087 Vendor 1623*7c478bd9Sstevel@tonic-gate * 2250-2258 Vendor 1624*7c478bd9Sstevel@tonic-gate * 1625*7c478bd9Sstevel@tonic-gate * MIBenum: 3 1626*7c478bd9Sstevel@tonic-gate * Alias: US-ASCII (preferred MIME name) 1627*7c478bd9Sstevel@tonic-gate * Source: ECMA registry [RFC1345] 1628*7c478bd9Sstevel@tonic-gate * 1629*7c478bd9Sstevel@tonic-gate * MIBenum: 106 1630*7c478bd9Sstevel@tonic-gate * Name: UTF-8 1631*7c478bd9Sstevel@tonic-gate * Source: RFC 2044 1632*7c478bd9Sstevel@tonic-gate */ 1633*7c478bd9Sstevel@tonic-gate 1634*7c478bd9Sstevel@tonic-gate static char *slpv1_charset(unsigned short code) { 1635*7c478bd9Sstevel@tonic-gate if (code <= 1) 1636*7c478bd9Sstevel@tonic-gate return ("Reserved"); 1637*7c478bd9Sstevel@tonic-gate if (code == 3) 1638*7c478bd9Sstevel@tonic-gate return ("US-ASCII"); 1639*7c478bd9Sstevel@tonic-gate if (code == 4) 1640*7c478bd9Sstevel@tonic-gate return ("latin1"); 1641*7c478bd9Sstevel@tonic-gate if (code == 106) 1642*7c478bd9Sstevel@tonic-gate return ("UTF-8"); 1643*7c478bd9Sstevel@tonic-gate if (code >= 3 && code <= 106) 1644*7c478bd9Sstevel@tonic-gate return ("set by standards organization"); 1645*7c478bd9Sstevel@tonic-gate if (code >= 1000 && code <= 1010) 1646*7c478bd9Sstevel@tonic-gate return ("Unicode variant"); 1647*7c478bd9Sstevel@tonic-gate if ((code >= 2000 && code <= 2087) || 1648*7c478bd9Sstevel@tonic-gate (code >= 2250 && code <= 2258)) 1649*7c478bd9Sstevel@tonic-gate return ("Vendor assigned"); 1650*7c478bd9Sstevel@tonic-gate 1651*7c478bd9Sstevel@tonic-gate return ("unknown"); 1652*7c478bd9Sstevel@tonic-gate } 1653*7c478bd9Sstevel@tonic-gate 1654*7c478bd9Sstevel@tonic-gate #ifdef VERIFYSLP 1655*7c478bd9Sstevel@tonic-gate static int skip_v1authblock() { 1656*7c478bd9Sstevel@tonic-gate unsigned short length; 1657*7c478bd9Sstevel@tonic-gate 1658*7c478bd9Sstevel@tonic-gate /* auth header: 12 bytes total */ 1659*7c478bd9Sstevel@tonic-gate if (msglength < 12) 1660*7c478bd9Sstevel@tonic-gate return (-1); 1661*7c478bd9Sstevel@tonic-gate 1662*7c478bd9Sstevel@tonic-gate /* timestamp: 8 bytes */ 1663*7c478bd9Sstevel@tonic-gate p += 8; /* timestamp: 8 bytes */ 1664*7c478bd9Sstevel@tonic-gate p += sizeof (short); /* block descriptor: 2 bytes */ 1665*7c478bd9Sstevel@tonic-gate nbtohs(); 1666*7c478bd9Sstevel@tonic-gate length = netval; 1667*7c478bd9Sstevel@tonic-gate p += sizeof (short); 1668*7c478bd9Sstevel@tonic-gate msglength -= 12; 1669*7c478bd9Sstevel@tonic-gate 1670*7c478bd9Sstevel@tonic-gate if (length > msglength) { 1671*7c478bd9Sstevel@tonic-gate /* framing error: message is not long enough to contain data */ 1672*7c478bd9Sstevel@tonic-gate return (-1); 1673*7c478bd9Sstevel@tonic-gate } 1674*7c478bd9Sstevel@tonic-gate 1675*7c478bd9Sstevel@tonic-gate p += length; 1676*7c478bd9Sstevel@tonic-gate msglength -= length; 1677*7c478bd9Sstevel@tonic-gate return (0); 1678*7c478bd9Sstevel@tonic-gate } 1679*7c478bd9Sstevel@tonic-gate #endif 1680*7c478bd9Sstevel@tonic-gate 1681*7c478bd9Sstevel@tonic-gate static int slpv1_authblock() { 1682*7c478bd9Sstevel@tonic-gate unsigned short bsd, length; 1683*7c478bd9Sstevel@tonic-gate char msgbuf[128]; 1684*7c478bd9Sstevel@tonic-gate int n; 1685*7c478bd9Sstevel@tonic-gate 1686*7c478bd9Sstevel@tonic-gate if (msglength < 12) { 1687*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), 1688*7c478bd9Sstevel@tonic-gate " [no room for auth block: remaining msg length = %u]", 1689*7c478bd9Sstevel@tonic-gate msglength); 1690*7c478bd9Sstevel@tonic-gate return (-1); 1691*7c478bd9Sstevel@tonic-gate } 1692*7c478bd9Sstevel@tonic-gate 1693*7c478bd9Sstevel@tonic-gate /* timestamp: 8 bytes */ 1694*7c478bd9Sstevel@tonic-gate *msgbuf = '\0'; 1695*7c478bd9Sstevel@tonic-gate for (n = 0; n < 8; n++, p += 1) { 1696*7c478bd9Sstevel@tonic-gate char tmp[16]; 1697*7c478bd9Sstevel@tonic-gate sprintf(tmp, "%02x", (unsigned char)(*p)); 1698*7c478bd9Sstevel@tonic-gate strcat(msgbuf, tmp); 1699*7c478bd9Sstevel@tonic-gate } 1700*7c478bd9Sstevel@tonic-gate 1701*7c478bd9Sstevel@tonic-gate nbtohs(); 1702*7c478bd9Sstevel@tonic-gate bsd = netval; 1703*7c478bd9Sstevel@tonic-gate p += sizeof (short); 1704*7c478bd9Sstevel@tonic-gate nbtohs(); 1705*7c478bd9Sstevel@tonic-gate length = netval; 1706*7c478bd9Sstevel@tonic-gate p += sizeof (short); 1707*7c478bd9Sstevel@tonic-gate msglength -= 12; 1708*7c478bd9Sstevel@tonic-gate 1709*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), 1710*7c478bd9Sstevel@tonic-gate " Auth block: timestamp = %s", 1711*7c478bd9Sstevel@tonic-gate msgbuf); 1712*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), 1713*7c478bd9Sstevel@tonic-gate " block desc = 0x%04x, length = %u", 1714*7c478bd9Sstevel@tonic-gate bsd, length); 1715*7c478bd9Sstevel@tonic-gate if (length > msglength) { 1716*7c478bd9Sstevel@tonic-gate /* framing error: message is not long enough to contain data */ 1717*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), 1718*7c478bd9Sstevel@tonic-gate " [Framing error: remaining pkt length = %u]", msglength); 1719*7c478bd9Sstevel@tonic-gate return (-1); 1720*7c478bd9Sstevel@tonic-gate } 1721*7c478bd9Sstevel@tonic-gate 1722*7c478bd9Sstevel@tonic-gate p += length; 1723*7c478bd9Sstevel@tonic-gate msglength -= length; 1724*7c478bd9Sstevel@tonic-gate return (0); 1725*7c478bd9Sstevel@tonic-gate } 1726*7c478bd9Sstevel@tonic-gate 1727*7c478bd9Sstevel@tonic-gate static int slpv1_url(boolean_t auth_present) { 1728*7c478bd9Sstevel@tonic-gate time_t exp; 1729*7c478bd9Sstevel@tonic-gate int lifetime, length; 1730*7c478bd9Sstevel@tonic-gate 1731*7c478bd9Sstevel@tonic-gate get_short(); 1732*7c478bd9Sstevel@tonic-gate if ((lifetime = netval) < 0) 1733*7c478bd9Sstevel@tonic-gate return (-1); 1734*7c478bd9Sstevel@tonic-gate get_short(); 1735*7c478bd9Sstevel@tonic-gate if ((length = netval) < 0) 1736*7c478bd9Sstevel@tonic-gate return (-1); 1737*7c478bd9Sstevel@tonic-gate 1738*7c478bd9Sstevel@tonic-gate exp = time(0) + lifetime; 1739*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "URL: length = %u, lifetime = %d (%24.24s)", 1740*7c478bd9Sstevel@tonic-gate length, lifetime, ctime(&exp)); 1741*7c478bd9Sstevel@tonic-gate if (length > msglength) { 1742*7c478bd9Sstevel@tonic-gate /* framing error: message is not long enough to contain data */ 1743*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), 1744*7c478bd9Sstevel@tonic-gate " [Framing error: remaining pkt length = %u]", msglength); 1745*7c478bd9Sstevel@tonic-gate return (-1); 1746*7c478bd9Sstevel@tonic-gate } 1747*7c478bd9Sstevel@tonic-gate 1748*7c478bd9Sstevel@tonic-gate if (length > 0) { 1749*7c478bd9Sstevel@tonic-gate char *buf = malloc(length + 1); 1750*7c478bd9Sstevel@tonic-gate if (buf != NULL) { 1751*7c478bd9Sstevel@tonic-gate if (!make_utf8(buf, length, p, length)) { 1752*7c478bd9Sstevel@tonic-gate strcpy(buf, "[Invalid Character Encoding]"); 1753*7c478bd9Sstevel@tonic-gate } 1754*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), " \"%s\"", buf); 1755*7c478bd9Sstevel@tonic-gate free(buf); 1756*7c478bd9Sstevel@tonic-gate } 1757*7c478bd9Sstevel@tonic-gate } 1758*7c478bd9Sstevel@tonic-gate msglength -= length; 1759*7c478bd9Sstevel@tonic-gate p += length; 1760*7c478bd9Sstevel@tonic-gate 1761*7c478bd9Sstevel@tonic-gate if (auth_present) 1762*7c478bd9Sstevel@tonic-gate return (slpv1_authblock()); 1763*7c478bd9Sstevel@tonic-gate 1764*7c478bd9Sstevel@tonic-gate return (0); 1765*7c478bd9Sstevel@tonic-gate } 1766*7c478bd9Sstevel@tonic-gate 1767*7c478bd9Sstevel@tonic-gate static int v1_srv_rqst(int flags) { 1768*7c478bd9Sstevel@tonic-gate if (flags & F_SUM) { 1769*7c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_PREVRESP); /* prev responders */ 1770*7c478bd9Sstevel@tonic-gate GETFIELD; /* predicate */ 1771*7c478bd9Sstevel@tonic-gate } else if (flags & F_DTAIL) { 1772*7c478bd9Sstevel@tonic-gate DOFIELD("Previous responders", FIELD_PREVRESP); 1773*7c478bd9Sstevel@tonic-gate DOFIELD("predicate string", FIELD_DEFAULT); 1774*7c478bd9Sstevel@tonic-gate } 1775*7c478bd9Sstevel@tonic-gate 1776*7c478bd9Sstevel@tonic-gate return (1); 1777*7c478bd9Sstevel@tonic-gate } 1778*7c478bd9Sstevel@tonic-gate 1779*7c478bd9Sstevel@tonic-gate static int v1_srv_rply(int flags) { 1780*7c478bd9Sstevel@tonic-gate unsigned short errcode, itemcnt; 1781*7c478bd9Sstevel@tonic-gate int n; 1782*7c478bd9Sstevel@tonic-gate 1783*7c478bd9Sstevel@tonic-gate if (flags & F_SUM) { 1784*7c478bd9Sstevel@tonic-gate GETSHORT(errcode); 1785*7c478bd9Sstevel@tonic-gate if (errcode != OK) { 1786*7c478bd9Sstevel@tonic-gate strcat(msgbuf, slpv1_error(errcode)); 1787*7c478bd9Sstevel@tonic-gate } else { 1788*7c478bd9Sstevel@tonic-gate GETSHORT(itemcnt); 1789*7c478bd9Sstevel@tonic-gate sprintf(msgend, "%d URL entries", itemcnt); 1790*7c478bd9Sstevel@tonic-gate #ifdef VERIFYSLP 1791*7c478bd9Sstevel@tonic-gate for (n = 0; n < itemcnt; n++) { 1792*7c478bd9Sstevel@tonic-gate SKIPSHORT; /* lifetime */ 1793*7c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_DEFAULT); /* URL */ 1794*7c478bd9Sstevel@tonic-gate SKIPAUTH(url_auth); /* URL auth */ 1795*7c478bd9Sstevel@tonic-gate } 1796*7c478bd9Sstevel@tonic-gate #endif 1797*7c478bd9Sstevel@tonic-gate } 1798*7c478bd9Sstevel@tonic-gate } else if (flags & F_DTAIL) { 1799*7c478bd9Sstevel@tonic-gate DOERRCODE; 1800*7c478bd9Sstevel@tonic-gate GETSHORT(itemcnt); 1801*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "URL entry count = %d", itemcnt); 1802*7c478bd9Sstevel@tonic-gate for (n = 0; n < itemcnt; n++) { 1803*7c478bd9Sstevel@tonic-gate DOURL; 1804*7c478bd9Sstevel@tonic-gate } 1805*7c478bd9Sstevel@tonic-gate } 1806*7c478bd9Sstevel@tonic-gate 1807*7c478bd9Sstevel@tonic-gate return (1); 1808*7c478bd9Sstevel@tonic-gate } 1809*7c478bd9Sstevel@tonic-gate 1810*7c478bd9Sstevel@tonic-gate static int v1_srv_reg(int flags) { 1811*7c478bd9Sstevel@tonic-gate if (flags & F_SUM) { 1812*7c478bd9Sstevel@tonic-gate SKIPSHORT; /* lifetime */ 1813*7c478bd9Sstevel@tonic-gate GETFIELD; /* URL */ 1814*7c478bd9Sstevel@tonic-gate #ifdef VERIFYSLP 1815*7c478bd9Sstevel@tonic-gate SKIPAUTH(url_auth); /* URL auth */ 1816*7c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_DEFAULT); /* attribute list */ 1817*7c478bd9Sstevel@tonic-gate SKIPAUTH(attr_auth); /* attr auth */ 1818*7c478bd9Sstevel@tonic-gate #endif 1819*7c478bd9Sstevel@tonic-gate } else if (flags & F_DTAIL) { 1820*7c478bd9Sstevel@tonic-gate DOURL; 1821*7c478bd9Sstevel@tonic-gate DOFIELD("Attribute list", FIELD_DEFAULT); 1822*7c478bd9Sstevel@tonic-gate DOAUTH(attr_auth); 1823*7c478bd9Sstevel@tonic-gate } 1824*7c478bd9Sstevel@tonic-gate 1825*7c478bd9Sstevel@tonic-gate return (1); 1826*7c478bd9Sstevel@tonic-gate } 1827*7c478bd9Sstevel@tonic-gate 1828*7c478bd9Sstevel@tonic-gate static int v1_srv_ack(int flags) { 1829*7c478bd9Sstevel@tonic-gate unsigned short errcode; 1830*7c478bd9Sstevel@tonic-gate 1831*7c478bd9Sstevel@tonic-gate if (flags & F_SUM) { 1832*7c478bd9Sstevel@tonic-gate GETSHORT(errcode); 1833*7c478bd9Sstevel@tonic-gate strcat(msgbuf, slpv1_error(errcode)); 1834*7c478bd9Sstevel@tonic-gate if (errcode == OK && fresh) { 1835*7c478bd9Sstevel@tonic-gate strcat(msgbuf, " [Fresh]"); 1836*7c478bd9Sstevel@tonic-gate } 1837*7c478bd9Sstevel@tonic-gate } else if (flags & F_DTAIL) { 1838*7c478bd9Sstevel@tonic-gate DOERRCODE; 1839*7c478bd9Sstevel@tonic-gate } 1840*7c478bd9Sstevel@tonic-gate 1841*7c478bd9Sstevel@tonic-gate return (1); 1842*7c478bd9Sstevel@tonic-gate } 1843*7c478bd9Sstevel@tonic-gate 1844*7c478bd9Sstevel@tonic-gate static int v1_srv_dereg(int flags) { 1845*7c478bd9Sstevel@tonic-gate if (flags & F_SUM) { 1846*7c478bd9Sstevel@tonic-gate GETFIELD; /* URL */ 1847*7c478bd9Sstevel@tonic-gate #ifdef VERIFYSLP 1848*7c478bd9Sstevel@tonic-gate SKIPAUTH(url_auth); 1849*7c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_DEFAULT); /* tag spec */ 1850*7c478bd9Sstevel@tonic-gate #endif 1851*7c478bd9Sstevel@tonic-gate } else if (flags & F_DTAIL) { 1852*7c478bd9Sstevel@tonic-gate DOFIELD("URL", FIELD_DEFAULT); 1853*7c478bd9Sstevel@tonic-gate DOAUTH(url_auth); 1854*7c478bd9Sstevel@tonic-gate DOFIELD("Tag spec", FIELD_DEFAULT); 1855*7c478bd9Sstevel@tonic-gate } 1856*7c478bd9Sstevel@tonic-gate 1857*7c478bd9Sstevel@tonic-gate return (1); 1858*7c478bd9Sstevel@tonic-gate } 1859*7c478bd9Sstevel@tonic-gate 1860*7c478bd9Sstevel@tonic-gate static int v1_attr_rqst(int flags) { 1861*7c478bd9Sstevel@tonic-gate if (flags & F_SUM) { 1862*7c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_PREVRESP); /* prev responders */ 1863*7c478bd9Sstevel@tonic-gate GETFIELD; /* URL */ 1864*7c478bd9Sstevel@tonic-gate #ifdef VERIFYSLP 1865*7c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_DEFAULT); /* scope */ 1866*7c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_DEFAULT); /* select list */ 1867*7c478bd9Sstevel@tonic-gate #endif 1868*7c478bd9Sstevel@tonic-gate } else if (flags & F_DTAIL) { 1869*7c478bd9Sstevel@tonic-gate DOFIELD("Previous responders", FIELD_PREVRESP); 1870*7c478bd9Sstevel@tonic-gate DOFIELD("URL", FIELD_DEFAULT); 1871*7c478bd9Sstevel@tonic-gate DOFIELD("Scope", FIELD_DEFAULT); 1872*7c478bd9Sstevel@tonic-gate DOFIELD("Select list", FIELD_DEFAULT); 1873*7c478bd9Sstevel@tonic-gate } 1874*7c478bd9Sstevel@tonic-gate 1875*7c478bd9Sstevel@tonic-gate return (1); 1876*7c478bd9Sstevel@tonic-gate } 1877*7c478bd9Sstevel@tonic-gate 1878*7c478bd9Sstevel@tonic-gate static int v1_attr_rply(int flags) { 1879*7c478bd9Sstevel@tonic-gate unsigned short errcode; 1880*7c478bd9Sstevel@tonic-gate 1881*7c478bd9Sstevel@tonic-gate if (flags & F_SUM) { 1882*7c478bd9Sstevel@tonic-gate GETSHORT(errcode); 1883*7c478bd9Sstevel@tonic-gate if (errcode != OK) { 1884*7c478bd9Sstevel@tonic-gate strcat(msgbuf, slpv1_error(errcode)); 1885*7c478bd9Sstevel@tonic-gate } else { 1886*7c478bd9Sstevel@tonic-gate GETFIELD; /* attr list */ 1887*7c478bd9Sstevel@tonic-gate #ifdef VERIFYSLP 1888*7c478bd9Sstevel@tonic-gate SKIPAUTH(attr_auth); 1889*7c478bd9Sstevel@tonic-gate #endif 1890*7c478bd9Sstevel@tonic-gate } 1891*7c478bd9Sstevel@tonic-gate } else if (flags & F_DTAIL) { 1892*7c478bd9Sstevel@tonic-gate DOERRCODE; 1893*7c478bd9Sstevel@tonic-gate DOFIELD("Attribute list", FIELD_DEFAULT); 1894*7c478bd9Sstevel@tonic-gate DOAUTH(attr_auth); 1895*7c478bd9Sstevel@tonic-gate } 1896*7c478bd9Sstevel@tonic-gate 1897*7c478bd9Sstevel@tonic-gate return (1); 1898*7c478bd9Sstevel@tonic-gate } 1899*7c478bd9Sstevel@tonic-gate 1900*7c478bd9Sstevel@tonic-gate static int v1_daadvert(int flags) { 1901*7c478bd9Sstevel@tonic-gate unsigned short errcode; 1902*7c478bd9Sstevel@tonic-gate 1903*7c478bd9Sstevel@tonic-gate if (flags & F_SUM) { 1904*7c478bd9Sstevel@tonic-gate GETSHORT(errcode); 1905*7c478bd9Sstevel@tonic-gate if (errcode != OK) { 1906*7c478bd9Sstevel@tonic-gate strcat(msgbuf, slpv1_error(errcode)); 1907*7c478bd9Sstevel@tonic-gate } else { 1908*7c478bd9Sstevel@tonic-gate GETFIELD; /* URL */ 1909*7c478bd9Sstevel@tonic-gate #ifdef VERIFYSLP 1910*7c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_DEFAULT); /* scope list */ 1911*7c478bd9Sstevel@tonic-gate #endif 1912*7c478bd9Sstevel@tonic-gate } 1913*7c478bd9Sstevel@tonic-gate } else if (flags & F_DTAIL) { 1914*7c478bd9Sstevel@tonic-gate DOERRCODE; 1915*7c478bd9Sstevel@tonic-gate DOFIELD("URL", FIELD_DEFAULT); 1916*7c478bd9Sstevel@tonic-gate DOFIELD("Scope list", FIELD_DEFAULT); 1917*7c478bd9Sstevel@tonic-gate } 1918*7c478bd9Sstevel@tonic-gate 1919*7c478bd9Sstevel@tonic-gate return (1); 1920*7c478bd9Sstevel@tonic-gate } 1921*7c478bd9Sstevel@tonic-gate 1922*7c478bd9Sstevel@tonic-gate static int v1_srv_type_rqst(int flags) { 1923*7c478bd9Sstevel@tonic-gate if (flags & F_SUM) { 1924*7c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_PREVRESP); /* prev responders */ 1925*7c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_TYPENA); /* naming authority */ 1926*7c478bd9Sstevel@tonic-gate GETFIELD; /* scope */ 1927*7c478bd9Sstevel@tonic-gate } else if (flags & F_DTAIL) { 1928*7c478bd9Sstevel@tonic-gate DOFIELD("Previous responders", FIELD_PREVRESP); 1929*7c478bd9Sstevel@tonic-gate DOFIELD("Naming authority", FIELD_TYPENA); 1930*7c478bd9Sstevel@tonic-gate DOFIELD("Scope string", FIELD_DEFAULT); 1931*7c478bd9Sstevel@tonic-gate } 1932*7c478bd9Sstevel@tonic-gate 1933*7c478bd9Sstevel@tonic-gate return (1); 1934*7c478bd9Sstevel@tonic-gate } 1935*7c478bd9Sstevel@tonic-gate 1936*7c478bd9Sstevel@tonic-gate static int v1_srv_type_rply(int flags) { 1937*7c478bd9Sstevel@tonic-gate unsigned short errcode, itemcnt; 1938*7c478bd9Sstevel@tonic-gate int n; 1939*7c478bd9Sstevel@tonic-gate 1940*7c478bd9Sstevel@tonic-gate if (flags & F_SUM) { 1941*7c478bd9Sstevel@tonic-gate GETSHORT(errcode); 1942*7c478bd9Sstevel@tonic-gate if (errcode != OK) { 1943*7c478bd9Sstevel@tonic-gate strcat(msgbuf, slpv1_error(errcode)); 1944*7c478bd9Sstevel@tonic-gate } else { 1945*7c478bd9Sstevel@tonic-gate GETSHORT(itemcnt); 1946*7c478bd9Sstevel@tonic-gate sprintf(msgend, "%d type entries", itemcnt); 1947*7c478bd9Sstevel@tonic-gate #ifdef VERIFYSLP 1948*7c478bd9Sstevel@tonic-gate for (n = 0; n < itemcnt; n++) { 1949*7c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_DEFAULT); /* Service type item */ 1950*7c478bd9Sstevel@tonic-gate } 1951*7c478bd9Sstevel@tonic-gate #endif 1952*7c478bd9Sstevel@tonic-gate } 1953*7c478bd9Sstevel@tonic-gate } else if (flags & F_DTAIL) { 1954*7c478bd9Sstevel@tonic-gate DOERRCODE; 1955*7c478bd9Sstevel@tonic-gate GETSHORT(itemcnt); 1956*7c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "Service type count = %d", itemcnt); 1957*7c478bd9Sstevel@tonic-gate for (n = 0; n < itemcnt; n++) { 1958*7c478bd9Sstevel@tonic-gate DOFIELD(" Service type item", FIELD_DEFAULT); 1959*7c478bd9Sstevel@tonic-gate } 1960*7c478bd9Sstevel@tonic-gate } 1961*7c478bd9Sstevel@tonic-gate 1962*7c478bd9Sstevel@tonic-gate return (1); 1963*7c478bd9Sstevel@tonic-gate } 1964