17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 77c478bd9Sstevel@tonic-gate * with the License. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 127c478bd9Sstevel@tonic-gate * and limitations under the License. 137c478bd9Sstevel@tonic-gate * 147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 197c478bd9Sstevel@tonic-gate * 207c478bd9Sstevel@tonic-gate * CDDL HEADER END 217c478bd9Sstevel@tonic-gate */ 227c478bd9Sstevel@tonic-gate /* 237c478bd9Sstevel@tonic-gate * Copyright (c) 1998,2000 by Sun Microsystems, Inc. 247c478bd9Sstevel@tonic-gate * All rights reserved. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate #include <stdio.h> 287c478bd9Sstevel@tonic-gate #include <arpa/inet.h> 297c478bd9Sstevel@tonic-gate #include <stdlib.h> 307c478bd9Sstevel@tonic-gate #include <string.h> 317c478bd9Sstevel@tonic-gate #include <sys/time.h> 327c478bd9Sstevel@tonic-gate #include <iconv.h> 337c478bd9Sstevel@tonic-gate #include "snoop.h" 347c478bd9Sstevel@tonic-gate #include "slp.h" 357c478bd9Sstevel@tonic-gate 367c478bd9Sstevel@tonic-gate #define MAXSUMLEN 30 377c478bd9Sstevel@tonic-gate 387c478bd9Sstevel@tonic-gate /* define VERIFYSLP to enable full message checking in summary mode */ 397c478bd9Sstevel@tonic-gate #define VERIFYSLP 407c478bd9Sstevel@tonic-gate 417c478bd9Sstevel@tonic-gate /* Globals -- ugly, yes, but fast and easy in macros */ 427c478bd9Sstevel@tonic-gate static int msglength; 437c478bd9Sstevel@tonic-gate static int retlength; 447c478bd9Sstevel@tonic-gate static char *msgend; /* the end of the summary message buffer */ 457c478bd9Sstevel@tonic-gate static char *p; /* current position in the packet */ 467c478bd9Sstevel@tonic-gate static char *msgbuf; /* message buffer for summary mode */ 477c478bd9Sstevel@tonic-gate static boolean_t url_auth = B_FALSE; 487c478bd9Sstevel@tonic-gate static boolean_t attr_auth = B_FALSE; 497c478bd9Sstevel@tonic-gate static boolean_t fresh = B_FALSE; 507c478bd9Sstevel@tonic-gate static boolean_t overflow = B_FALSE; 517c478bd9Sstevel@tonic-gate static int v1_charset = 0; /* character set; only in V1 */ 527c478bd9Sstevel@tonic-gate 537c478bd9Sstevel@tonic-gate /* Entry points for parsing the protocol */ 547c478bd9Sstevel@tonic-gate static int interpret_slp_v1(int, struct slpv1_hdr *, int); 557c478bd9Sstevel@tonic-gate static int interpret_slp_v2(int, struct slpv2_hdr *, int); 567c478bd9Sstevel@tonic-gate 577c478bd9Sstevel@tonic-gate /* header parsing */ 587c478bd9Sstevel@tonic-gate static int v1_header(int, struct slpv1_hdr *, int); 597c478bd9Sstevel@tonic-gate static int v2_header(int, struct slpv2_hdr *, int *, int); 607c478bd9Sstevel@tonic-gate static int v2_finish(struct slpv2_hdr *, int); 617c478bd9Sstevel@tonic-gate 627c478bd9Sstevel@tonic-gate /* V2 auth blocks */ 637c478bd9Sstevel@tonic-gate static int slpv2_authblock(int); 647c478bd9Sstevel@tonic-gate 657c478bd9Sstevel@tonic-gate /* 667c478bd9Sstevel@tonic-gate * Functions for parsing each protocol message 677c478bd9Sstevel@tonic-gate * Each function takes the interpreter's flags argument as its input 687c478bd9Sstevel@tonic-gate * parameter, and returns 1 on success, or 0 on message corruption. 697c478bd9Sstevel@tonic-gate * retlength is set as a side-effect in summary mode. 707c478bd9Sstevel@tonic-gate */ 717c478bd9Sstevel@tonic-gate static int v2_srv_rqst(int); 727c478bd9Sstevel@tonic-gate static int v2_srv_rply(int); 737c478bd9Sstevel@tonic-gate static int v2_srv_reg(int); 747c478bd9Sstevel@tonic-gate static int v2_srv_dereg(int); 757c478bd9Sstevel@tonic-gate static int v2_srv_ack(int); 767c478bd9Sstevel@tonic-gate static int v2_attr_rqst(int); 777c478bd9Sstevel@tonic-gate static int v2_attr_rply(int); 787c478bd9Sstevel@tonic-gate static int v2_daadvert(int); 797c478bd9Sstevel@tonic-gate static int v2_srv_type_rqst(int); 807c478bd9Sstevel@tonic-gate static int v2_srv_type_rply(int); 817c478bd9Sstevel@tonic-gate static int v2_saadvert(int); 827c478bd9Sstevel@tonic-gate 837c478bd9Sstevel@tonic-gate static int v1_srv_rqst(int); 847c478bd9Sstevel@tonic-gate static int v1_srv_rply(int); 857c478bd9Sstevel@tonic-gate static int v1_srv_reg(int); 867c478bd9Sstevel@tonic-gate static int v1_srv_dereg(int); 877c478bd9Sstevel@tonic-gate static int v1_srv_ack(int); 887c478bd9Sstevel@tonic-gate static int v1_attr_rqst(int); 897c478bd9Sstevel@tonic-gate static int v1_attr_rply(int); 907c478bd9Sstevel@tonic-gate static int v1_daadvert(int); 917c478bd9Sstevel@tonic-gate static int v1_srv_type_rqst(int); 927c478bd9Sstevel@tonic-gate static int v1_srv_type_rply(int); 937c478bd9Sstevel@tonic-gate 947c478bd9Sstevel@tonic-gate /* 957c478bd9Sstevel@tonic-gate * The dispatch tables for handling individual messages, keyed by 967c478bd9Sstevel@tonic-gate * function number. 977c478bd9Sstevel@tonic-gate */ 987c478bd9Sstevel@tonic-gate typedef int function_handler(); 997c478bd9Sstevel@tonic-gate 1007c478bd9Sstevel@tonic-gate #define V2_MAX_FUNCTION 11 1017c478bd9Sstevel@tonic-gate 1027c478bd9Sstevel@tonic-gate static function_handler *v2_functions[V2_MAX_FUNCTION + 1] = { 1037c478bd9Sstevel@tonic-gate (function_handler *) NULL, 1047c478bd9Sstevel@tonic-gate (function_handler *) v2_srv_rqst, 1057c478bd9Sstevel@tonic-gate (function_handler *) v2_srv_rply, 1067c478bd9Sstevel@tonic-gate (function_handler *) v2_srv_reg, 1077c478bd9Sstevel@tonic-gate (function_handler *) v2_srv_dereg, 1087c478bd9Sstevel@tonic-gate (function_handler *) v2_srv_ack, 1097c478bd9Sstevel@tonic-gate (function_handler *) v2_attr_rqst, 1107c478bd9Sstevel@tonic-gate (function_handler *) v2_attr_rply, 1117c478bd9Sstevel@tonic-gate (function_handler *) v2_daadvert, 1127c478bd9Sstevel@tonic-gate (function_handler *) v2_srv_type_rqst, 1137c478bd9Sstevel@tonic-gate (function_handler *) v2_srv_type_rply, 1147c478bd9Sstevel@tonic-gate (function_handler *) v2_saadvert }; 1157c478bd9Sstevel@tonic-gate 1167c478bd9Sstevel@tonic-gate #define V1_MAX_FUNCTION 10 1177c478bd9Sstevel@tonic-gate 1187c478bd9Sstevel@tonic-gate static function_handler *v1_functions[V1_MAX_FUNCTION + 1] = { 1197c478bd9Sstevel@tonic-gate (function_handler *) NULL, 1207c478bd9Sstevel@tonic-gate (function_handler *) v1_srv_rqst, 1217c478bd9Sstevel@tonic-gate (function_handler *) v1_srv_rply, 1227c478bd9Sstevel@tonic-gate (function_handler *) v1_srv_reg, 1237c478bd9Sstevel@tonic-gate (function_handler *) v1_srv_dereg, 1247c478bd9Sstevel@tonic-gate (function_handler *) v1_srv_ack, 1257c478bd9Sstevel@tonic-gate (function_handler *) v1_attr_rqst, 1267c478bd9Sstevel@tonic-gate (function_handler *) v1_attr_rply, 1277c478bd9Sstevel@tonic-gate (function_handler *) v1_daadvert, 1287c478bd9Sstevel@tonic-gate (function_handler *) v1_srv_type_rqst, 1297c478bd9Sstevel@tonic-gate (function_handler *) v1_srv_type_rply }; 1307c478bd9Sstevel@tonic-gate 1317c478bd9Sstevel@tonic-gate /* TCP continuation handling */ 1327c478bd9Sstevel@tonic-gate static boolean_t tcp_continuation = B_FALSE; 1337c478bd9Sstevel@tonic-gate 1347c478bd9Sstevel@tonic-gate #define MAX_TCPCONT 16 1357c478bd9Sstevel@tonic-gate 1367c478bd9Sstevel@tonic-gate static struct tcp_cont { 1377c478bd9Sstevel@tonic-gate int dst_port; 1387c478bd9Sstevel@tonic-gate char *msg; 1397c478bd9Sstevel@tonic-gate int totallen; 1407c478bd9Sstevel@tonic-gate int curr_offset; 1417c478bd9Sstevel@tonic-gate } *tcp_cont[MAX_TCPCONT]; 1427c478bd9Sstevel@tonic-gate 1437c478bd9Sstevel@tonic-gate static int current_tcp_cont; 1447c478bd9Sstevel@tonic-gate 1457c478bd9Sstevel@tonic-gate static void reg_tcp_cont(char *, int, int, int); 1467c478bd9Sstevel@tonic-gate static int add_tcp_cont(struct tcp_cont *, char *, int); 1477c478bd9Sstevel@tonic-gate static struct tcp_cont *find_tcp_cont(int); 1487c478bd9Sstevel@tonic-gate static void remove_tcp_cont(int); 1497c478bd9Sstevel@tonic-gate 1507c478bd9Sstevel@tonic-gate /* Conversions from numbers to strings */ 1517c478bd9Sstevel@tonic-gate static char *slpv2_func(int, boolean_t); 1527c478bd9Sstevel@tonic-gate static char *slpv2_error(unsigned short); 1537c478bd9Sstevel@tonic-gate static char *slpv1_func(int, boolean_t); 1547c478bd9Sstevel@tonic-gate static char *slpv1_error(unsigned short); 1557c478bd9Sstevel@tonic-gate static char *slpv1_charset(unsigned short); 1567c478bd9Sstevel@tonic-gate 1577c478bd9Sstevel@tonic-gate /* 1587c478bd9Sstevel@tonic-gate * The only external entry point to the SLP interpreter. This function 1597c478bd9Sstevel@tonic-gate * simply dispatches the packet based on the version. 1607c478bd9Sstevel@tonic-gate */ 161*5b8f338eSToomas Soome void interpret_slp(int flags, void *slp, int fraglen) { 1627c478bd9Sstevel@tonic-gate extern int dst_port, curr_proto; 1637c478bd9Sstevel@tonic-gate struct tcp_cont *tce = NULL; 164*5b8f338eSToomas Soome char *s; 1657c478bd9Sstevel@tonic-gate 1667c478bd9Sstevel@tonic-gate msglength = fraglen; 1677c478bd9Sstevel@tonic-gate retlength = 0; 1687c478bd9Sstevel@tonic-gate p = slp; 1697c478bd9Sstevel@tonic-gate 1707c478bd9Sstevel@tonic-gate /* check if this is a TCP continuation */ 1717c478bd9Sstevel@tonic-gate if (flags & F_DTAIL && curr_proto == IPPROTO_TCP) { 1727c478bd9Sstevel@tonic-gate tce = find_tcp_cont(dst_port); 1737c478bd9Sstevel@tonic-gate if (tce) { 1747c478bd9Sstevel@tonic-gate if (add_tcp_cont(tce, slp, fraglen)) { 1757c478bd9Sstevel@tonic-gate slp = tce->msg; 1767c478bd9Sstevel@tonic-gate fraglen = tce->curr_offset; 1777c478bd9Sstevel@tonic-gate tcp_continuation = B_TRUE; 1787c478bd9Sstevel@tonic-gate } 1797c478bd9Sstevel@tonic-gate } 1807c478bd9Sstevel@tonic-gate } 181*5b8f338eSToomas Soome if (*(char *)slp == 2 || tce) 182*5b8f338eSToomas Soome interpret_slp_v2(flags, slp, fraglen); 1837c478bd9Sstevel@tonic-gate else 184*5b8f338eSToomas Soome interpret_slp_v1(flags, slp, fraglen); 1857c478bd9Sstevel@tonic-gate 1867c478bd9Sstevel@tonic-gate tcp_continuation = B_FALSE; 1877c478bd9Sstevel@tonic-gate } 1887c478bd9Sstevel@tonic-gate 1897c478bd9Sstevel@tonic-gate /* 1907c478bd9Sstevel@tonic-gate * Primitives. These are implemented as much as possible as macros for 1917c478bd9Sstevel@tonic-gate * speed. 1927c478bd9Sstevel@tonic-gate */ 1937c478bd9Sstevel@tonic-gate 1947c478bd9Sstevel@tonic-gate #define FIELD_DEFAULT 0 1957c478bd9Sstevel@tonic-gate #define FIELD_PREVRESP 1 1967c478bd9Sstevel@tonic-gate #define FIELD_TYPENA 2 1977c478bd9Sstevel@tonic-gate 1987c478bd9Sstevel@tonic-gate static long long netval = 0; /* need signed 64 bit quantity */ 1997c478bd9Sstevel@tonic-gate 2007c478bd9Sstevel@tonic-gate /* gets two bytes from p and leaves the result in netval */ 2017c478bd9Sstevel@tonic-gate #define nbtohs() \ 2027c478bd9Sstevel@tonic-gate netval = ((int)(p[0] & 0xff)) << 8; \ 2037c478bd9Sstevel@tonic-gate netval += ((int)(p[1] & 0xff)) 2047c478bd9Sstevel@tonic-gate 2057c478bd9Sstevel@tonic-gate /* gets four bytes from p and leaves the result in netval */ 2067c478bd9Sstevel@tonic-gate #define nbtohl() \ 2077c478bd9Sstevel@tonic-gate netval = ((int)(p[0] & 0xff)) << 24; \ 2087c478bd9Sstevel@tonic-gate netval += ((int)(p[1] & 0xff)) << 16; \ 2097c478bd9Sstevel@tonic-gate netval += ((int)(p[2] & 0xff)) << 8; \ 2107c478bd9Sstevel@tonic-gate netval += ((int)(p[3] & 0xff)) 2117c478bd9Sstevel@tonic-gate 2127c478bd9Sstevel@tonic-gate #define get_byte() \ 2137c478bd9Sstevel@tonic-gate if (msglength >= 1) { \ 2147c478bd9Sstevel@tonic-gate netval = *p; \ 2157c478bd9Sstevel@tonic-gate p++; \ 2167c478bd9Sstevel@tonic-gate msglength--; \ 2177c478bd9Sstevel@tonic-gate } else \ 2187c478bd9Sstevel@tonic-gate netval = -1 2197c478bd9Sstevel@tonic-gate 2207c478bd9Sstevel@tonic-gate #define GETBYTE(x) \ 2217c478bd9Sstevel@tonic-gate get_byte(); \ 2227c478bd9Sstevel@tonic-gate if ((retlength = netval) < 0) \ 2237c478bd9Sstevel@tonic-gate return (0); \ 2247c478bd9Sstevel@tonic-gate x = netval 2257c478bd9Sstevel@tonic-gate 2267c478bd9Sstevel@tonic-gate #define SKIPBYTE \ 2277c478bd9Sstevel@tonic-gate get_byte(); \ 2287c478bd9Sstevel@tonic-gate if ((retlength = netval) < 0) \ 2297c478bd9Sstevel@tonic-gate return (0); \ 2307c478bd9Sstevel@tonic-gate 2317c478bd9Sstevel@tonic-gate /* 2327c478bd9Sstevel@tonic-gate * gets two bytes from p, leaves the result in netval, and updates 2337c478bd9Sstevel@tonic-gate * msglength and p. 2347c478bd9Sstevel@tonic-gate */ 2357c478bd9Sstevel@tonic-gate #define get_short() \ 2367c478bd9Sstevel@tonic-gate if (msglength >= sizeof (unsigned short)) { \ 2377c478bd9Sstevel@tonic-gate nbtohs(); \ 2387c478bd9Sstevel@tonic-gate p += sizeof (unsigned short); \ 2397c478bd9Sstevel@tonic-gate msglength -= sizeof (unsigned short); \ 2407c478bd9Sstevel@tonic-gate } else \ 2417c478bd9Sstevel@tonic-gate netval = -1 2427c478bd9Sstevel@tonic-gate 2437c478bd9Sstevel@tonic-gate #define GETSHORT(x) \ 2447c478bd9Sstevel@tonic-gate get_short(); \ 2457c478bd9Sstevel@tonic-gate if ((retlength = netval) < 0) \ 2467c478bd9Sstevel@tonic-gate return (0); \ 2477c478bd9Sstevel@tonic-gate x = netval 2487c478bd9Sstevel@tonic-gate 2497c478bd9Sstevel@tonic-gate #define SKIPSHORT \ 2507c478bd9Sstevel@tonic-gate get_short(); \ 2517c478bd9Sstevel@tonic-gate if ((retlength = netval) < 0) \ 2527c478bd9Sstevel@tonic-gate return (0) 2537c478bd9Sstevel@tonic-gate 2547c478bd9Sstevel@tonic-gate #define get_int24(pp) \ 2557c478bd9Sstevel@tonic-gate netval = ((int)((pp)[0] & 0xff)) << 16; \ 2567c478bd9Sstevel@tonic-gate netval += ((int)((pp)[1] & 0xff)) << 8; \ 2577c478bd9Sstevel@tonic-gate netval += ((int)((pp)[2] & 0xff)) 2587c478bd9Sstevel@tonic-gate 2597c478bd9Sstevel@tonic-gate static void slp_prevresp(char *p) { 2607c478bd9Sstevel@tonic-gate char *p2; 2617c478bd9Sstevel@tonic-gate 2627c478bd9Sstevel@tonic-gate /* cycle through all entries */ 2637c478bd9Sstevel@tonic-gate for (; p != NULL; p = p2) { 2647c478bd9Sstevel@tonic-gate p2 = strchr(p, ','); 2657c478bd9Sstevel@tonic-gate if (p2 != NULL) 2667c478bd9Sstevel@tonic-gate *p2++ = '\0'; 2677c478bd9Sstevel@tonic-gate 2687c478bd9Sstevel@tonic-gate /* print entry at p */ 2697c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), " \"%s\"", p); 2707c478bd9Sstevel@tonic-gate } 2717c478bd9Sstevel@tonic-gate } 2727c478bd9Sstevel@tonic-gate 2737c478bd9Sstevel@tonic-gate static int skip_field(int type) { 2747c478bd9Sstevel@tonic-gate unsigned short stringlen; 2757c478bd9Sstevel@tonic-gate 2767c478bd9Sstevel@tonic-gate get_short(); 2777c478bd9Sstevel@tonic-gate if (netval < 0) { 2787c478bd9Sstevel@tonic-gate return (-1); 2797c478bd9Sstevel@tonic-gate } 2807c478bd9Sstevel@tonic-gate stringlen = netval; 2817c478bd9Sstevel@tonic-gate 2827c478bd9Sstevel@tonic-gate /* special case for NA field in SrvTypeRqst */ 2837c478bd9Sstevel@tonic-gate if (type == FIELD_TYPENA && stringlen == 0xffff) { 2847c478bd9Sstevel@tonic-gate stringlen = 0; 2857c478bd9Sstevel@tonic-gate } 2867c478bd9Sstevel@tonic-gate 2877c478bd9Sstevel@tonic-gate if (stringlen > msglength) { 2887c478bd9Sstevel@tonic-gate return (-1); 2897c478bd9Sstevel@tonic-gate } 2907c478bd9Sstevel@tonic-gate 2917c478bd9Sstevel@tonic-gate msglength -= stringlen; 2927c478bd9Sstevel@tonic-gate p += stringlen; 2937c478bd9Sstevel@tonic-gate 2947c478bd9Sstevel@tonic-gate return (stringlen); 2957c478bd9Sstevel@tonic-gate } 2967c478bd9Sstevel@tonic-gate 2977c478bd9Sstevel@tonic-gate #define SKIPFIELD(type) \ 2987c478bd9Sstevel@tonic-gate if ((retlength = skip_field(type)) < 0) \ 2997c478bd9Sstevel@tonic-gate return (0) 3007c478bd9Sstevel@tonic-gate 3017c478bd9Sstevel@tonic-gate #define GETFIELD \ 3027c478bd9Sstevel@tonic-gate get_short(); \ 3037c478bd9Sstevel@tonic-gate if ((retlength = netval) < 0) \ 3047c478bd9Sstevel@tonic-gate return (0); \ 3057c478bd9Sstevel@tonic-gate strncat(msgbuf, p, (retlength > MAXSUMLEN ? MAXSUMLEN : retlength)); \ 3067c478bd9Sstevel@tonic-gate p += retlength; \ 3077c478bd9Sstevel@tonic-gate msglength -= retlength 3087c478bd9Sstevel@tonic-gate 3097c478bd9Sstevel@tonic-gate /* 3107c478bd9Sstevel@tonic-gate * Determines from the first five bytes of a potential SLP header 3117c478bd9Sstevel@tonic-gate * if the following message is really an SLP message. Returns 1 if 3127c478bd9Sstevel@tonic-gate * it is a real SLP message, 0 if not. 3137c478bd9Sstevel@tonic-gate */ 3147c478bd9Sstevel@tonic-gate int valid_slp(unsigned char *slphdr, int len) { 3157c478bd9Sstevel@tonic-gate struct slpv1_hdr slp1; 3167c478bd9Sstevel@tonic-gate struct slpv2_hdr slp2; 3177c478bd9Sstevel@tonic-gate 3187c478bd9Sstevel@tonic-gate len -= (8 /* udp */ + 20 /* IP */ + 14 /* ether */); 3197c478bd9Sstevel@tonic-gate /* a valid version will be 1 or 2 */ 3207c478bd9Sstevel@tonic-gate switch (*slphdr) { 3217c478bd9Sstevel@tonic-gate case 1: 3227c478bd9Sstevel@tonic-gate memcpy(&slp1, slphdr, 5); 3237c478bd9Sstevel@tonic-gate /* valid function? */ 3247c478bd9Sstevel@tonic-gate if (slp1.function > V1_MAX_FUNCTION) { 3257c478bd9Sstevel@tonic-gate return (0); 3267c478bd9Sstevel@tonic-gate } 3277c478bd9Sstevel@tonic-gate /* valid length heuristic */ 3287c478bd9Sstevel@tonic-gate if (slp1.length > len) { 3297c478bd9Sstevel@tonic-gate return (0); 3307c478bd9Sstevel@tonic-gate } 3317c478bd9Sstevel@tonic-gate return (1); 3327c478bd9Sstevel@tonic-gate case 2: 3337c478bd9Sstevel@tonic-gate memcpy(&slp2, slphdr, 5); 3347c478bd9Sstevel@tonic-gate /* valid function? */ 3357c478bd9Sstevel@tonic-gate if (slp2.function > V2_MAX_FUNCTION) { 3367c478bd9Sstevel@tonic-gate return (0); 3377c478bd9Sstevel@tonic-gate } 3387c478bd9Sstevel@tonic-gate /* valid length heuristic */ 3397c478bd9Sstevel@tonic-gate get_int24(&(slp2.l1)); 3407c478bd9Sstevel@tonic-gate if (netval > len) { 3417c478bd9Sstevel@tonic-gate return (0); 3427c478bd9Sstevel@tonic-gate } 3437c478bd9Sstevel@tonic-gate return (1); 3447c478bd9Sstevel@tonic-gate default: 3457c478bd9Sstevel@tonic-gate return (0); 3467c478bd9Sstevel@tonic-gate } 3477c478bd9Sstevel@tonic-gate } 3487c478bd9Sstevel@tonic-gate 3497c478bd9Sstevel@tonic-gate /* 3507c478bd9Sstevel@tonic-gate * Converts a V1 char encoding to UTF8. If this fails, returns 0, 3517c478bd9Sstevel@tonic-gate * otherwise, 1. This function is the union of iconv UTF-8 3527c478bd9Sstevel@tonic-gate * modules and character sets registered with IANA. 3537c478bd9Sstevel@tonic-gate */ 3547c478bd9Sstevel@tonic-gate static int make_utf8(char *outbuf, size_t outlen, 3557c478bd9Sstevel@tonic-gate const char *inbuf, size_t inlen) { 3567c478bd9Sstevel@tonic-gate iconv_t cd; 3577c478bd9Sstevel@tonic-gate size_t converted; 3587c478bd9Sstevel@tonic-gate 3597c478bd9Sstevel@tonic-gate switch (v1_charset) { 3607c478bd9Sstevel@tonic-gate case 4: 3617c478bd9Sstevel@tonic-gate case 1004: 3627c478bd9Sstevel@tonic-gate cd = iconv_open("UTF-8", "8859-1"); 3637c478bd9Sstevel@tonic-gate break; 3647c478bd9Sstevel@tonic-gate case 5: 3657c478bd9Sstevel@tonic-gate cd = iconv_open("UTF-8", "8859-2"); 3667c478bd9Sstevel@tonic-gate break; 3677c478bd9Sstevel@tonic-gate case 6: 3687c478bd9Sstevel@tonic-gate cd = iconv_open("UTF-8", "8859-3"); 3697c478bd9Sstevel@tonic-gate break; 3707c478bd9Sstevel@tonic-gate case 7: 3717c478bd9Sstevel@tonic-gate cd = iconv_open("UTF-8", "8859-4"); 3727c478bd9Sstevel@tonic-gate break; 3737c478bd9Sstevel@tonic-gate case 8: 3747c478bd9Sstevel@tonic-gate cd = iconv_open("UTF-8", "8859-5"); 3757c478bd9Sstevel@tonic-gate break; 3767c478bd9Sstevel@tonic-gate case 9: 3777c478bd9Sstevel@tonic-gate cd = iconv_open("UTF-8", "8859-6"); 3787c478bd9Sstevel@tonic-gate break; 3797c478bd9Sstevel@tonic-gate case 10: 3807c478bd9Sstevel@tonic-gate cd = iconv_open("UTF-8", "8859-7"); 3817c478bd9Sstevel@tonic-gate break; 3827c478bd9Sstevel@tonic-gate case 11: 3837c478bd9Sstevel@tonic-gate cd = iconv_open("UTF-8", "8859-8"); 3847c478bd9Sstevel@tonic-gate break; 3857c478bd9Sstevel@tonic-gate case 12: 3867c478bd9Sstevel@tonic-gate cd = iconv_open("UTF-8", "8859-9"); 3877c478bd9Sstevel@tonic-gate break; 3887c478bd9Sstevel@tonic-gate case 13: 3897c478bd9Sstevel@tonic-gate cd = iconv_open("UTF-8", "8859-10"); 3907c478bd9Sstevel@tonic-gate break; 3917c478bd9Sstevel@tonic-gate case 37: 3927c478bd9Sstevel@tonic-gate cd = iconv_open("UTF-8", "ko_KR-iso2022-7"); 3937c478bd9Sstevel@tonic-gate break; 3947c478bd9Sstevel@tonic-gate case 104: 3957c478bd9Sstevel@tonic-gate cd = iconv_open("UTF-8", "iso2022"); 3967c478bd9Sstevel@tonic-gate break; 3977c478bd9Sstevel@tonic-gate case 1000: 3987c478bd9Sstevel@tonic-gate cd = iconv_open("UTF-8", "UCS-2"); 3997c478bd9Sstevel@tonic-gate break; 4007c478bd9Sstevel@tonic-gate case 1001: 4017c478bd9Sstevel@tonic-gate cd = iconv_open("UTF-8", "UCS-4"); 4027c478bd9Sstevel@tonic-gate break; 4037c478bd9Sstevel@tonic-gate default: 4047c478bd9Sstevel@tonic-gate /* 4057c478bd9Sstevel@tonic-gate * charset not set, or reserved, or not supported, so 4067c478bd9Sstevel@tonic-gate * just copy it and hope for the best. 4077c478bd9Sstevel@tonic-gate */ 4087c478bd9Sstevel@tonic-gate converted = outlen < inlen ? outlen : inlen; 4097c478bd9Sstevel@tonic-gate memcpy(outbuf, inbuf, converted); 4107c478bd9Sstevel@tonic-gate outbuf[converted] = 0; 4117c478bd9Sstevel@tonic-gate return (1); 4127c478bd9Sstevel@tonic-gate } 4137c478bd9Sstevel@tonic-gate 4147c478bd9Sstevel@tonic-gate if (cd == (iconv_t)-1) { 4157c478bd9Sstevel@tonic-gate return (0); 4167c478bd9Sstevel@tonic-gate } 4177c478bd9Sstevel@tonic-gate 4187c478bd9Sstevel@tonic-gate if ((converted = iconv(cd, &inbuf, &inlen, &outbuf, &outlen)) 4197c478bd9Sstevel@tonic-gate == (size_t)-1) { 4207c478bd9Sstevel@tonic-gate return (0); 4217c478bd9Sstevel@tonic-gate } 4227c478bd9Sstevel@tonic-gate 4237c478bd9Sstevel@tonic-gate outbuf[converted] = 0; 4247c478bd9Sstevel@tonic-gate iconv_close(cd); 4257c478bd9Sstevel@tonic-gate 4267c478bd9Sstevel@tonic-gate return (1); 4277c478bd9Sstevel@tonic-gate } 4287c478bd9Sstevel@tonic-gate 4297c478bd9Sstevel@tonic-gate static int slp_field(char *tag, int type) { 4307c478bd9Sstevel@tonic-gate int length; 4317c478bd9Sstevel@tonic-gate 4327c478bd9Sstevel@tonic-gate get_short(); 4337c478bd9Sstevel@tonic-gate if (netval < 0) { 4347c478bd9Sstevel@tonic-gate return (-1); 4357c478bd9Sstevel@tonic-gate } 4367c478bd9Sstevel@tonic-gate length = netval; 4377c478bd9Sstevel@tonic-gate 4387c478bd9Sstevel@tonic-gate /* special case for NA field in SrvTypeRqst */ 4397c478bd9Sstevel@tonic-gate if (type == FIELD_TYPENA && length == 0xffff) { 4407c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "%s: length = -1: Use all NAs", tag); 4417c478bd9Sstevel@tonic-gate return (0); 4427c478bd9Sstevel@tonic-gate } 4437c478bd9Sstevel@tonic-gate 4447c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "%s: length = %d", tag, length); 4457c478bd9Sstevel@tonic-gate if (length > msglength) { 4467c478bd9Sstevel@tonic-gate /* framing error: message is not long enough to contain data */ 4477c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), 4487c478bd9Sstevel@tonic-gate " [Framing error: remaining pkt length = %u]", 4497c478bd9Sstevel@tonic-gate msglength); 4507c478bd9Sstevel@tonic-gate return (-1); 4517c478bd9Sstevel@tonic-gate } 4527c478bd9Sstevel@tonic-gate 4537c478bd9Sstevel@tonic-gate if (length > 0) { 4547c478bd9Sstevel@tonic-gate char *buf = malloc(length + 1); 4557c478bd9Sstevel@tonic-gate if (buf != NULL) { 4567c478bd9Sstevel@tonic-gate if (v1_charset) { 4577c478bd9Sstevel@tonic-gate if (!make_utf8(buf, length, p, length)) { 4587c478bd9Sstevel@tonic-gate strcpy(buf, "[Invalid Character Encoding]"); 4597c478bd9Sstevel@tonic-gate } 4607c478bd9Sstevel@tonic-gate } else { 4617c478bd9Sstevel@tonic-gate memcpy(buf, p, length); 4627c478bd9Sstevel@tonic-gate buf[length] = '\0'; /* ensure null-terminated */ 4637c478bd9Sstevel@tonic-gate } 4647c478bd9Sstevel@tonic-gate 4657c478bd9Sstevel@tonic-gate switch (type) { 4667c478bd9Sstevel@tonic-gate case FIELD_PREVRESP: 4677c478bd9Sstevel@tonic-gate slp_prevresp(buf); 4687c478bd9Sstevel@tonic-gate break; 4697c478bd9Sstevel@tonic-gate 4707c478bd9Sstevel@tonic-gate default: 4717c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), " \"%s\"", buf); 4727c478bd9Sstevel@tonic-gate break; 4737c478bd9Sstevel@tonic-gate } 4747c478bd9Sstevel@tonic-gate free(buf); 4757c478bd9Sstevel@tonic-gate } 4767c478bd9Sstevel@tonic-gate 4777c478bd9Sstevel@tonic-gate p += length; 4787c478bd9Sstevel@tonic-gate msglength -= length; 4797c478bd9Sstevel@tonic-gate } 4807c478bd9Sstevel@tonic-gate 4817c478bd9Sstevel@tonic-gate /* return ok */ 4827c478bd9Sstevel@tonic-gate return (0); 4837c478bd9Sstevel@tonic-gate } 4847c478bd9Sstevel@tonic-gate 4857c478bd9Sstevel@tonic-gate static int slpv2_url(int cnt) { 4867c478bd9Sstevel@tonic-gate time_t exp; 4877c478bd9Sstevel@tonic-gate int lifetime, length, n; 4887c478bd9Sstevel@tonic-gate 4897c478bd9Sstevel@tonic-gate /* reserved */ 4907c478bd9Sstevel@tonic-gate get_byte(); 4917c478bd9Sstevel@tonic-gate if (netval < 0) 4927c478bd9Sstevel@tonic-gate return (-1); 4937c478bd9Sstevel@tonic-gate 4947c478bd9Sstevel@tonic-gate /* lifetime */ 4957c478bd9Sstevel@tonic-gate get_short(); 4967c478bd9Sstevel@tonic-gate if ((lifetime = netval) < 0) 4977c478bd9Sstevel@tonic-gate return (-1); 4987c478bd9Sstevel@tonic-gate 4997c478bd9Sstevel@tonic-gate /* length */ 5007c478bd9Sstevel@tonic-gate get_short(); 5017c478bd9Sstevel@tonic-gate if ((length = netval) < 0) 5027c478bd9Sstevel@tonic-gate return (-1); 5037c478bd9Sstevel@tonic-gate 5047c478bd9Sstevel@tonic-gate /* time */ 5057c478bd9Sstevel@tonic-gate exp = time(0) + lifetime; 5067c478bd9Sstevel@tonic-gate if (cnt == -1) 5077c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), 5087c478bd9Sstevel@tonic-gate "URL: length = %u, lifetime = %d (%24.24s)", 5097c478bd9Sstevel@tonic-gate length, lifetime, ctime(&exp)); 5107c478bd9Sstevel@tonic-gate else 5117c478bd9Sstevel@tonic-gate /* number the URLs to make it easier to parse them */ 5127c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), 5137c478bd9Sstevel@tonic-gate "URL %d: length = %u, lifetime = %d (%24.24s)", 5147c478bd9Sstevel@tonic-gate cnt, length, lifetime, ctime(&exp)); 5157c478bd9Sstevel@tonic-gate 5167c478bd9Sstevel@tonic-gate if (length > msglength) { 5177c478bd9Sstevel@tonic-gate if (!tcp_continuation) 5187c478bd9Sstevel@tonic-gate /* framing error: message is not long enough to contain data */ 5197c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), 5207c478bd9Sstevel@tonic-gate " [Framing error: remaining pkt length = %u]", 5217c478bd9Sstevel@tonic-gate msglength); 5227c478bd9Sstevel@tonic-gate return (-1); 5237c478bd9Sstevel@tonic-gate } 5247c478bd9Sstevel@tonic-gate 5257c478bd9Sstevel@tonic-gate if (length > 0) { 5267c478bd9Sstevel@tonic-gate char *buf = malloc(length + 1); 5277c478bd9Sstevel@tonic-gate if (buf != NULL) { 5287c478bd9Sstevel@tonic-gate memcpy(buf, p, length); 5297c478bd9Sstevel@tonic-gate buf[length] = '\0'; /* ensure null-terminated */ 5307c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), " \"%s\"", buf); 5317c478bd9Sstevel@tonic-gate free(buf); 5327c478bd9Sstevel@tonic-gate } 5337c478bd9Sstevel@tonic-gate } 5347c478bd9Sstevel@tonic-gate msglength -= length; 5357c478bd9Sstevel@tonic-gate p += length; 5367c478bd9Sstevel@tonic-gate 5377c478bd9Sstevel@tonic-gate get_byte(); 5387c478bd9Sstevel@tonic-gate if ((n = netval) < 0) 5397c478bd9Sstevel@tonic-gate return (-1); 5407c478bd9Sstevel@tonic-gate 5417c478bd9Sstevel@tonic-gate if (n > 0) { 5427c478bd9Sstevel@tonic-gate int i; 5437c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "%d Authentication Blocks", n); 5447c478bd9Sstevel@tonic-gate for (i = 0; i < n; i++) 5457c478bd9Sstevel@tonic-gate if ((length = slpv2_authblock(i)) < 0) 5467c478bd9Sstevel@tonic-gate return (-1); 5477c478bd9Sstevel@tonic-gate } 5487c478bd9Sstevel@tonic-gate return (0); 5497c478bd9Sstevel@tonic-gate } 5507c478bd9Sstevel@tonic-gate 5517c478bd9Sstevel@tonic-gate #define DOFIELD(tag, type) \ 5527c478bd9Sstevel@tonic-gate if (slp_field(tag, type) < 0) \ 5537c478bd9Sstevel@tonic-gate return (0) 5547c478bd9Sstevel@tonic-gate 5557c478bd9Sstevel@tonic-gate #define V2_DOURL(x) \ 5567c478bd9Sstevel@tonic-gate if (slpv2_url(x) < 0) \ 5577c478bd9Sstevel@tonic-gate return (0) 5587c478bd9Sstevel@tonic-gate 5597c478bd9Sstevel@tonic-gate #define V2_DOERRCODE \ 5607c478bd9Sstevel@tonic-gate if (msglength < sizeof (unsigned short)) \ 5617c478bd9Sstevel@tonic-gate return (0); \ 5627c478bd9Sstevel@tonic-gate nbtohs(); \ 5637c478bd9Sstevel@tonic-gate errcode = netval; \ 5647c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "Error code = %d, %s", \ 5657c478bd9Sstevel@tonic-gate errcode, slpv2_error(errcode)); \ 5667c478bd9Sstevel@tonic-gate p += sizeof (unsigned short); \ 5677c478bd9Sstevel@tonic-gate msglength -= sizeof (unsigned short); \ 5687c478bd9Sstevel@tonic-gate if (errcode != OK) \ 5697c478bd9Sstevel@tonic-gate msglength = 0; /* skip rest of message */ \ 5707c478bd9Sstevel@tonic-gate if (errcode != OK) \ 5717c478bd9Sstevel@tonic-gate return (0) 5727c478bd9Sstevel@tonic-gate 5737c478bd9Sstevel@tonic-gate #define V2_DOAUTH(cnt) \ 5747c478bd9Sstevel@tonic-gate if (slpv2_authblock(cnt) < 0) \ 5757c478bd9Sstevel@tonic-gate return (0) 5767c478bd9Sstevel@tonic-gate 5777c478bd9Sstevel@tonic-gate #define V2_DOTIMESTAMP \ 5787c478bd9Sstevel@tonic-gate if (msglength < 4) \ 5797c478bd9Sstevel@tonic-gate return (0); \ 5807c478bd9Sstevel@tonic-gate nbtohl(); \ 5817c478bd9Sstevel@tonic-gate timestamp = netval; \ 5827c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "Timestamp = %u, %s", \ 5837c478bd9Sstevel@tonic-gate timestamp, (timestamp ? convert_ts(timestamp) : "0")); \ 5847c478bd9Sstevel@tonic-gate p += 4; \ 5857c478bd9Sstevel@tonic-gate msglength -= 4 5867c478bd9Sstevel@tonic-gate 5877c478bd9Sstevel@tonic-gate /* some V1 macros */ 5887c478bd9Sstevel@tonic-gate #define SKIPAUTH(auth) \ 5897c478bd9Sstevel@tonic-gate if (auth && ((retlength = skip_v1authblock()) < 0)) \ 5907c478bd9Sstevel@tonic-gate return (0) 5917c478bd9Sstevel@tonic-gate 5927c478bd9Sstevel@tonic-gate #define DOERRCODE \ 5937c478bd9Sstevel@tonic-gate if (msglength < sizeof (unsigned short)) \ 5947c478bd9Sstevel@tonic-gate return (0); \ 5957c478bd9Sstevel@tonic-gate nbtohs(); \ 5967c478bd9Sstevel@tonic-gate errcode = netval; \ 5977c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "Error code = %d, %s", errcode, \ 5987c478bd9Sstevel@tonic-gate slpv1_error(errcode)); \ 5997c478bd9Sstevel@tonic-gate p += sizeof (unsigned short); \ 6007c478bd9Sstevel@tonic-gate msglength -= sizeof (unsigned short); \ 6017c478bd9Sstevel@tonic-gate if (errcode != OK) \ 6027c478bd9Sstevel@tonic-gate return (0) 6037c478bd9Sstevel@tonic-gate 6047c478bd9Sstevel@tonic-gate #define DOURL \ 6057c478bd9Sstevel@tonic-gate if (slpv1_url(url_auth) < 0) \ 6067c478bd9Sstevel@tonic-gate return (0) 6077c478bd9Sstevel@tonic-gate 6087c478bd9Sstevel@tonic-gate #define DOAUTH(auth) \ 6097c478bd9Sstevel@tonic-gate if (auth && slpv1_authblock() < 0) \ 6107c478bd9Sstevel@tonic-gate return (0) 6117c478bd9Sstevel@tonic-gate 6127c478bd9Sstevel@tonic-gate /* 6137c478bd9Sstevel@tonic-gate * TCP Continuation handling 6147c478bd9Sstevel@tonic-gate * We keep track of continuations in a fixed size cache, so as to prevent 6157c478bd9Sstevel@tonic-gate * memory leaks if some continuations are never finished. The continuations 6167c478bd9Sstevel@tonic-gate * are indexed by their destination ports. 6177c478bd9Sstevel@tonic-gate */ 6187c478bd9Sstevel@tonic-gate static void reg_tcp_cont(char *msg, int totallen, 6197c478bd9Sstevel@tonic-gate int fraglen, int dst_port) { 6207c478bd9Sstevel@tonic-gate struct tcp_cont *tce = malloc(sizeof (*tce)); 6217c478bd9Sstevel@tonic-gate 6227c478bd9Sstevel@tonic-gate /* always overwrite the entry at current_tcp_cont */ 6237c478bd9Sstevel@tonic-gate if (tcp_cont[current_tcp_cont]) { 6247c478bd9Sstevel@tonic-gate free(tcp_cont[current_tcp_cont]->msg); 6257c478bd9Sstevel@tonic-gate free(tcp_cont[current_tcp_cont]); 6267c478bd9Sstevel@tonic-gate } 6277c478bd9Sstevel@tonic-gate 6287c478bd9Sstevel@tonic-gate tce->dst_port = dst_port; 6297c478bd9Sstevel@tonic-gate tce->msg = malloc(totallen); 6307c478bd9Sstevel@tonic-gate memcpy(tce->msg, msg, fraglen); 6317c478bd9Sstevel@tonic-gate tce->totallen = totallen; 6327c478bd9Sstevel@tonic-gate tce->curr_offset = fraglen; 6337c478bd9Sstevel@tonic-gate 6347c478bd9Sstevel@tonic-gate tcp_cont[current_tcp_cont++] = tce; 6357c478bd9Sstevel@tonic-gate if (current_tcp_cont == MAX_TCPCONT) 6367c478bd9Sstevel@tonic-gate current_tcp_cont = 0; 6377c478bd9Sstevel@tonic-gate } 6387c478bd9Sstevel@tonic-gate 6397c478bd9Sstevel@tonic-gate /* returns 0 if there is a mismatch error, 1 on success */ 6407c478bd9Sstevel@tonic-gate static int add_tcp_cont(struct tcp_cont *tce, char *msg, int fraglen) { 6417c478bd9Sstevel@tonic-gate if ((fraglen + tce->curr_offset) > tce->totallen) 6427c478bd9Sstevel@tonic-gate return (0); 6437c478bd9Sstevel@tonic-gate 6447c478bd9Sstevel@tonic-gate memcpy(tce->msg + tce->curr_offset, msg, fraglen); 6457c478bd9Sstevel@tonic-gate tce->curr_offset += fraglen; 6467c478bd9Sstevel@tonic-gate return (1); 6477c478bd9Sstevel@tonic-gate } 6487c478bd9Sstevel@tonic-gate 6497c478bd9Sstevel@tonic-gate static struct tcp_cont *find_tcp_cont(int dst_port) { 6507c478bd9Sstevel@tonic-gate int i; 6517c478bd9Sstevel@tonic-gate for (i = current_tcp_cont; i >= 0; i--) 6527c478bd9Sstevel@tonic-gate if (tcp_cont[i] && tcp_cont[i]->dst_port == dst_port) 6537c478bd9Sstevel@tonic-gate return (tcp_cont[i]); 6547c478bd9Sstevel@tonic-gate 6557c478bd9Sstevel@tonic-gate for (i = MAX_TCPCONT -1; i > current_tcp_cont; i--) 6567c478bd9Sstevel@tonic-gate if (tcp_cont[i] && tcp_cont[i]->dst_port == dst_port) 6577c478bd9Sstevel@tonic-gate return (tcp_cont[i]); 6587c478bd9Sstevel@tonic-gate 6597c478bd9Sstevel@tonic-gate return (NULL); 6607c478bd9Sstevel@tonic-gate } 6617c478bd9Sstevel@tonic-gate 6627c478bd9Sstevel@tonic-gate static void remove_tcp_cont(int dst_port) { 6637c478bd9Sstevel@tonic-gate int i; 6647c478bd9Sstevel@tonic-gate for (i = current_tcp_cont; i >= 0; i--) 6657c478bd9Sstevel@tonic-gate if (tcp_cont[i] && tcp_cont[i]->dst_port == dst_port) { 6667c478bd9Sstevel@tonic-gate free(tcp_cont[i]->msg); 6677c478bd9Sstevel@tonic-gate free(tcp_cont[i]); 6687c478bd9Sstevel@tonic-gate tcp_cont[i] = NULL; 6697c478bd9Sstevel@tonic-gate return; 6707c478bd9Sstevel@tonic-gate } 6717c478bd9Sstevel@tonic-gate 6727c478bd9Sstevel@tonic-gate for (i = MAX_TCPCONT -1; i > current_tcp_cont; i--) 6737c478bd9Sstevel@tonic-gate if (tcp_cont[i] && tcp_cont[i]->dst_port == dst_port) { 6747c478bd9Sstevel@tonic-gate free(tcp_cont[i]->msg); 6757c478bd9Sstevel@tonic-gate free(tcp_cont[i]); 6767c478bd9Sstevel@tonic-gate tcp_cont[i] = NULL; 6777c478bd9Sstevel@tonic-gate return; 6787c478bd9Sstevel@tonic-gate } 6797c478bd9Sstevel@tonic-gate } 6807c478bd9Sstevel@tonic-gate 6817c478bd9Sstevel@tonic-gate /* 6827c478bd9Sstevel@tonic-gate * V2 interpreter 6837c478bd9Sstevel@tonic-gate */ 6847c478bd9Sstevel@tonic-gate 6857c478bd9Sstevel@tonic-gate static int interpret_slp_v2(int flags, struct slpv2_hdr *slp, int fraglen) { 6867c478bd9Sstevel@tonic-gate extern int src_port, dst_port, curr_proto; 6877c478bd9Sstevel@tonic-gate char msgbuf_real[256]; 6887c478bd9Sstevel@tonic-gate int totallen = 0; 6897c478bd9Sstevel@tonic-gate 6907c478bd9Sstevel@tonic-gate msgbuf = msgbuf_real; 6917c478bd9Sstevel@tonic-gate 6927c478bd9Sstevel@tonic-gate /* 6937c478bd9Sstevel@tonic-gate * Somewhat of a hack to decode traffic from a server that does 6947c478bd9Sstevel@tonic-gate * not send udp replies from its SLP src port. 6957c478bd9Sstevel@tonic-gate */ 6967c478bd9Sstevel@tonic-gate 6977c478bd9Sstevel@tonic-gate if (curr_proto == IPPROTO_UDP && 6987c478bd9Sstevel@tonic-gate dst_port == 427 && 6997c478bd9Sstevel@tonic-gate src_port != 427) { 7007c478bd9Sstevel@tonic-gate add_transient(src_port, (int (*)())interpret_slp); 7017c478bd9Sstevel@tonic-gate } 7027c478bd9Sstevel@tonic-gate 7037c478bd9Sstevel@tonic-gate /* parse the header */ 7047c478bd9Sstevel@tonic-gate if (v2_header(flags, slp, &totallen, fraglen)) { 7057c478bd9Sstevel@tonic-gate 7067c478bd9Sstevel@tonic-gate if (slp->function <= V2_MAX_FUNCTION && slp->function > 0) { 7077c478bd9Sstevel@tonic-gate 7087c478bd9Sstevel@tonic-gate /* Parse the message body */ 7097c478bd9Sstevel@tonic-gate if ((v2_functions[slp->function])(flags)) { 7107c478bd9Sstevel@tonic-gate 7117c478bd9Sstevel@tonic-gate /* finish any remaining tasks */ 7127c478bd9Sstevel@tonic-gate v2_finish(slp, flags); 7137c478bd9Sstevel@tonic-gate 7147c478bd9Sstevel@tonic-gate } 7157c478bd9Sstevel@tonic-gate 7167c478bd9Sstevel@tonic-gate } 7177c478bd9Sstevel@tonic-gate 7187c478bd9Sstevel@tonic-gate } 7197c478bd9Sstevel@tonic-gate 7207c478bd9Sstevel@tonic-gate /* summary error check */ 7217c478bd9Sstevel@tonic-gate if (flags & F_SUM) { 7227c478bd9Sstevel@tonic-gate if (retlength < 0) { 7237c478bd9Sstevel@tonic-gate if (curr_proto == IPPROTO_TCP) 7247c478bd9Sstevel@tonic-gate sprintf(get_sum_line(), 7257c478bd9Sstevel@tonic-gate "%s [partial TCP message]", msgbuf); 7267c478bd9Sstevel@tonic-gate else if (overflow) 7277c478bd9Sstevel@tonic-gate sprintf(get_sum_line(), "%s [OVERFLOW]", msgbuf); 7287c478bd9Sstevel@tonic-gate else 7297c478bd9Sstevel@tonic-gate sprintf(get_sum_line(), "%s [CORRUPTED MESSAGE]", msgbuf); 7307c478bd9Sstevel@tonic-gate } 7317c478bd9Sstevel@tonic-gate #ifdef VERIFYSLP 7327c478bd9Sstevel@tonic-gate else if (msglength > 0) 7337c478bd9Sstevel@tonic-gate sprintf(get_sum_line(), "%s +%d", msgbuf, msglength); 7347c478bd9Sstevel@tonic-gate #endif 7357c478bd9Sstevel@tonic-gate else 7367c478bd9Sstevel@tonic-gate sprintf(get_sum_line(), "%s", msgbuf); 7377c478bd9Sstevel@tonic-gate } else if (flags & F_DTAIL) { 7387c478bd9Sstevel@tonic-gate /* detailed error check */ 7397c478bd9Sstevel@tonic-gate if (msglength > 0) { 7407c478bd9Sstevel@tonic-gate if (tcp_continuation) { 7417c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), 7427c478bd9Sstevel@tonic-gate "[TCP Continuation, %d bytes remaining]", 7437c478bd9Sstevel@tonic-gate totallen - fraglen); 7447c478bd9Sstevel@tonic-gate } else 7457c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), 7467c478bd9Sstevel@tonic-gate "[%d extra bytes at end of SLP message]", msglength); 7477c478bd9Sstevel@tonic-gate } 7487c478bd9Sstevel@tonic-gate 7497c478bd9Sstevel@tonic-gate show_trailer(); 7507c478bd9Sstevel@tonic-gate 7517c478bd9Sstevel@tonic-gate if (tcp_continuation && msglength == 0) 7527c478bd9Sstevel@tonic-gate remove_tcp_cont(dst_port); 7537c478bd9Sstevel@tonic-gate } 7547c478bd9Sstevel@tonic-gate 7557c478bd9Sstevel@tonic-gate return (0); 7567c478bd9Sstevel@tonic-gate } 7577c478bd9Sstevel@tonic-gate 7587c478bd9Sstevel@tonic-gate static int v2_header(int flags, 7597c478bd9Sstevel@tonic-gate struct slpv2_hdr *slp, 7607c478bd9Sstevel@tonic-gate int *totallen, 7617c478bd9Sstevel@tonic-gate int fraglen) { 7627c478bd9Sstevel@tonic-gate extern int curr_proto, dst_port; 7637c478bd9Sstevel@tonic-gate char *prototag = (curr_proto == IPPROTO_TCP ? "/tcp" : ""); 7647c478bd9Sstevel@tonic-gate 7657c478bd9Sstevel@tonic-gate if ((slp->flags & V2_OVERFLOW) == V2_OVERFLOW) 7667c478bd9Sstevel@tonic-gate overflow = B_TRUE; 7677c478bd9Sstevel@tonic-gate 7687c478bd9Sstevel@tonic-gate /* summary mode header parsing */ 7697c478bd9Sstevel@tonic-gate if (flags & F_SUM) { 7707c478bd9Sstevel@tonic-gate 7717c478bd9Sstevel@tonic-gate /* make sure we have at least a header */ 7727c478bd9Sstevel@tonic-gate if (msglength < sizeof (*slp)) { 7737c478bd9Sstevel@tonic-gate sprintf(get_sum_line(), "SLP V2 [Incomplete Header]"); 7747c478bd9Sstevel@tonic-gate return (0); 7757c478bd9Sstevel@tonic-gate } 7767c478bd9Sstevel@tonic-gate 7777c478bd9Sstevel@tonic-gate sprintf(msgbuf, "SLP V2 %s [%d%s] ", 7787c478bd9Sstevel@tonic-gate slpv2_func(slp->function, B_TRUE), 7797c478bd9Sstevel@tonic-gate ntohs(slp->xid), prototag); 7807c478bd9Sstevel@tonic-gate 7817c478bd9Sstevel@tonic-gate /* skip to end of header */ 7827c478bd9Sstevel@tonic-gate msgend = msgbuf + strlen(msgbuf); 7837c478bd9Sstevel@tonic-gate msglength -= sizeof (*slp); 7847c478bd9Sstevel@tonic-gate p += sizeof (*slp); 7857c478bd9Sstevel@tonic-gate 7867c478bd9Sstevel@tonic-gate /* skip language tag */ 7877c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_DEFAULT); 7887c478bd9Sstevel@tonic-gate } else if (flags & F_DTAIL) { 7897c478bd9Sstevel@tonic-gate char *lang; 7907c478bd9Sstevel@tonic-gate int len; 7917c478bd9Sstevel@tonic-gate 7927c478bd9Sstevel@tonic-gate /* detailed mode header parsing */ 7937c478bd9Sstevel@tonic-gate show_header("SLP: ", "Service Location Protocol (v2)", fraglen); 7947c478bd9Sstevel@tonic-gate show_space(); 7957c478bd9Sstevel@tonic-gate 7967c478bd9Sstevel@tonic-gate if (msglength < sizeof (*slp)) { 7977c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "==> Incomplete SLP header"); 7987c478bd9Sstevel@tonic-gate return (0); 7997c478bd9Sstevel@tonic-gate } 8007c478bd9Sstevel@tonic-gate 8017c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "Version = %d", slp->vers); 8027c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "Function = %d, %s", 8037c478bd9Sstevel@tonic-gate slp->function, slpv2_func(slp->function, B_FALSE)); 8047c478bd9Sstevel@tonic-gate get_int24(&(slp->l1)); 8057c478bd9Sstevel@tonic-gate *totallen = netval; 8067c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "Message length = %u", *totallen); 8077c478bd9Sstevel@tonic-gate /* check for TCP continuation */ 8087c478bd9Sstevel@tonic-gate if (curr_proto == IPPROTO_TCP && 8097c478bd9Sstevel@tonic-gate *totallen > msglength && 8107c478bd9Sstevel@tonic-gate !tcp_continuation) { 8117c478bd9Sstevel@tonic-gate tcp_continuation = B_TRUE; 8127c478bd9Sstevel@tonic-gate reg_tcp_cont((char *)slp, *totallen, msglength, dst_port); 8137c478bd9Sstevel@tonic-gate } 8147c478bd9Sstevel@tonic-gate 8157c478bd9Sstevel@tonic-gate if (!tcp_continuation && *totallen != msglength) { 8167c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), 8177c478bd9Sstevel@tonic-gate " (Stated and on-the-wire lengths differ)"); 8187c478bd9Sstevel@tonic-gate } 8197c478bd9Sstevel@tonic-gate /* flags */ 8207c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "Flags = 0x%02x", slp->flags); 8217c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), " %s", 8227c478bd9Sstevel@tonic-gate getflag(slp->flags, V2_OVERFLOW, 8237c478bd9Sstevel@tonic-gate "overflow", "no overflow")); 8247c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), " %s", 8257c478bd9Sstevel@tonic-gate getflag(slp->flags, V2_FRESH, 8267c478bd9Sstevel@tonic-gate "fresh registration", "no fresh registration")); 8277c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), " %s", 8287c478bd9Sstevel@tonic-gate getflag(slp->flags, V2_MCAST, 8297c478bd9Sstevel@tonic-gate "request multicast / broadcast", "unicast")); 8307c478bd9Sstevel@tonic-gate /* check reserved flags that must be zero */ 8317c478bd9Sstevel@tonic-gate if ((slp->flags & 7) != 0) { 8327c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), 8337c478bd9Sstevel@tonic-gate " .... .xxx = %d (reserved flags nonzero)", 8347c478bd9Sstevel@tonic-gate slp->flags & 7); 8357c478bd9Sstevel@tonic-gate } 8367c478bd9Sstevel@tonic-gate /* end of flags */ 8377c478bd9Sstevel@tonic-gate 8387c478bd9Sstevel@tonic-gate /* language tag */ 8397c478bd9Sstevel@tonic-gate p = (char *)slp + sizeof (*slp); 8407c478bd9Sstevel@tonic-gate msglength -= sizeof (*slp); 8417c478bd9Sstevel@tonic-gate GETSHORT(len); 8427c478bd9Sstevel@tonic-gate if (len > msglength) { 8437c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), 8447c478bd9Sstevel@tonic-gate "Language Tag Length = %u [CORRUPT MESSAGE]", 8457c478bd9Sstevel@tonic-gate len); 8467c478bd9Sstevel@tonic-gate return (0); 8477c478bd9Sstevel@tonic-gate } 8487c478bd9Sstevel@tonic-gate 8497c478bd9Sstevel@tonic-gate lang = get_line(0, 0); 8507c478bd9Sstevel@tonic-gate strcpy(lang, "Language Tag = "); 8517c478bd9Sstevel@tonic-gate strncat(lang, p, len); 8527c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "XID = %u", ntohs(slp->xid)); 8537c478bd9Sstevel@tonic-gate 8547c478bd9Sstevel@tonic-gate /* set msglength to remaining length of SLP message */ 8557c478bd9Sstevel@tonic-gate p += len; 8567c478bd9Sstevel@tonic-gate msglength -= len; 8577c478bd9Sstevel@tonic-gate } 8587c478bd9Sstevel@tonic-gate 8597c478bd9Sstevel@tonic-gate return (1); 8607c478bd9Sstevel@tonic-gate } 8617c478bd9Sstevel@tonic-gate 8627c478bd9Sstevel@tonic-gate static int v2_finish(struct slpv2_hdr *slp, int flags) { 8637c478bd9Sstevel@tonic-gate unsigned int firstop; 8647c478bd9Sstevel@tonic-gate 8657c478bd9Sstevel@tonic-gate if (!(flags & F_DTAIL)) 8667c478bd9Sstevel@tonic-gate return (1); 8677c478bd9Sstevel@tonic-gate 8687c478bd9Sstevel@tonic-gate /* check for options */ 8697c478bd9Sstevel@tonic-gate get_int24(&(slp->o1)); 8707c478bd9Sstevel@tonic-gate firstop = netval; 8717c478bd9Sstevel@tonic-gate 8727c478bd9Sstevel@tonic-gate if (firstop) { 8737c478bd9Sstevel@tonic-gate unsigned short op_id; 8747c478bd9Sstevel@tonic-gate unsigned short nextop; 8757c478bd9Sstevel@tonic-gate char *op_class; 8767c478bd9Sstevel@tonic-gate 8777c478bd9Sstevel@tonic-gate for (;;) { 8787c478bd9Sstevel@tonic-gate unsigned short real_oplen; 8797c478bd9Sstevel@tonic-gate 8807c478bd9Sstevel@tonic-gate if (msglength < 4) { 8817c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), 8827c478bd9Sstevel@tonic-gate "Option expected but not present"); 8837c478bd9Sstevel@tonic-gate return (0); 8847c478bd9Sstevel@tonic-gate } 8857c478bd9Sstevel@tonic-gate 8867c478bd9Sstevel@tonic-gate nbtohs(); 8877c478bd9Sstevel@tonic-gate op_id = netval; 8887c478bd9Sstevel@tonic-gate p += sizeof (unsigned short); 8897c478bd9Sstevel@tonic-gate msglength -= sizeof (unsigned short); 8907c478bd9Sstevel@tonic-gate nbtohs(); 8917c478bd9Sstevel@tonic-gate nextop = netval; 8927c478bd9Sstevel@tonic-gate p += sizeof (unsigned short); 8937c478bd9Sstevel@tonic-gate msglength -= sizeof (unsigned short); 8947c478bd9Sstevel@tonic-gate 8957c478bd9Sstevel@tonic-gate real_oplen = nextop ? nextop : msglength; 8967c478bd9Sstevel@tonic-gate 8977c478bd9Sstevel@tonic-gate /* known options */ 8987c478bd9Sstevel@tonic-gate switch (op_id) { 8997c478bd9Sstevel@tonic-gate case 1: 9007c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), 9017c478bd9Sstevel@tonic-gate "Option: Required Attribute Missing"); 9027c478bd9Sstevel@tonic-gate DOFIELD("Template IDVer", FIELD_DEFAULT); 9037c478bd9Sstevel@tonic-gate DOFIELD("Required Attrs", FIELD_DEFAULT); 9047c478bd9Sstevel@tonic-gate break; 9057c478bd9Sstevel@tonic-gate default: 9067c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "Option: Unknown"); 9077c478bd9Sstevel@tonic-gate p += (real_oplen - 4); 9087c478bd9Sstevel@tonic-gate msglength -= (real_oplen - 4); 9097c478bd9Sstevel@tonic-gate break; 9107c478bd9Sstevel@tonic-gate } 9117c478bd9Sstevel@tonic-gate 9127c478bd9Sstevel@tonic-gate if (op_id < 0x3fff) 9137c478bd9Sstevel@tonic-gate op_class = "Standardized, optional"; 9147c478bd9Sstevel@tonic-gate else if (op_id < 0x7fff) 9157c478bd9Sstevel@tonic-gate op_class = "Standardized, mandatory"; 9167c478bd9Sstevel@tonic-gate else if (op_id < 0x8fff) 9177c478bd9Sstevel@tonic-gate op_class = "Not standardized, private"; 9187c478bd9Sstevel@tonic-gate else if (op_id < 0xffff) 9197c478bd9Sstevel@tonic-gate op_class = "Reserved"; 9207c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "Option ID = 0x%04x, %s", 9217c478bd9Sstevel@tonic-gate op_id, op_class); 9227c478bd9Sstevel@tonic-gate if (nextop && 9237c478bd9Sstevel@tonic-gate ((nextop - 4) > msglength) && 9247c478bd9Sstevel@tonic-gate !tcp_continuation) { 9257c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), 9267c478bd9Sstevel@tonic-gate "[Framing error: remaining pkt length = %u]", 9277c478bd9Sstevel@tonic-gate msglength); 9287c478bd9Sstevel@tonic-gate return (0); 9297c478bd9Sstevel@tonic-gate } 9307c478bd9Sstevel@tonic-gate 9317c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "Option Length = %u", real_oplen); 9327c478bd9Sstevel@tonic-gate 9337c478bd9Sstevel@tonic-gate if (!nextop) 9347c478bd9Sstevel@tonic-gate break; 9357c478bd9Sstevel@tonic-gate } 9367c478bd9Sstevel@tonic-gate } 9377c478bd9Sstevel@tonic-gate 9387c478bd9Sstevel@tonic-gate return (1); 9397c478bd9Sstevel@tonic-gate } 9407c478bd9Sstevel@tonic-gate 9417c478bd9Sstevel@tonic-gate #ifdef VERIFYSLP 9427c478bd9Sstevel@tonic-gate static int skip_v2authblock() { 9437c478bd9Sstevel@tonic-gate unsigned short length, slen; 9447c478bd9Sstevel@tonic-gate 9457c478bd9Sstevel@tonic-gate /* auth header */ 9467c478bd9Sstevel@tonic-gate if (msglength < 10) 9477c478bd9Sstevel@tonic-gate return (-1); 9487c478bd9Sstevel@tonic-gate 9497c478bd9Sstevel@tonic-gate /* block descriptor: 2 bytes */ 9507c478bd9Sstevel@tonic-gate p += sizeof (unsigned short); 9517c478bd9Sstevel@tonic-gate /* length */ 9527c478bd9Sstevel@tonic-gate nbtohs(); 9537c478bd9Sstevel@tonic-gate length = netval; 9547c478bd9Sstevel@tonic-gate p += sizeof (unsigned short); 9557c478bd9Sstevel@tonic-gate /* timestamp */ 9567c478bd9Sstevel@tonic-gate p += 4; 9577c478bd9Sstevel@tonic-gate /* SPI String length */ 9587c478bd9Sstevel@tonic-gate nbtohs(); 9597c478bd9Sstevel@tonic-gate slen = netval; 9607c478bd9Sstevel@tonic-gate p += sizeof (unsigned short); 9617c478bd9Sstevel@tonic-gate 9627c478bd9Sstevel@tonic-gate msglength -= 10; 9637c478bd9Sstevel@tonic-gate if (slen > msglength || length > (msglength + 10)) 9647c478bd9Sstevel@tonic-gate return (-1); 9657c478bd9Sstevel@tonic-gate 9667c478bd9Sstevel@tonic-gate p += slen; 9677c478bd9Sstevel@tonic-gate msglength -= slen; 9687c478bd9Sstevel@tonic-gate 9697c478bd9Sstevel@tonic-gate /* structured auth block */ 9707c478bd9Sstevel@tonic-gate p += (length - 10 - slen); 9717c478bd9Sstevel@tonic-gate msglength -= (length - 10 - slen); 9727c478bd9Sstevel@tonic-gate return (0); 9737c478bd9Sstevel@tonic-gate } 9747c478bd9Sstevel@tonic-gate #endif 9757c478bd9Sstevel@tonic-gate 9767c478bd9Sstevel@tonic-gate static char *display_bsd(unsigned short bsd) { 9777c478bd9Sstevel@tonic-gate switch (bsd) { 9787c478bd9Sstevel@tonic-gate case 1: return ("MD5 with RSA"); 9797c478bd9Sstevel@tonic-gate case 2: return ("DSA with SHA-1"); 9807c478bd9Sstevel@tonic-gate case 3: return ("Keyed HMAC with MD5"); 9817c478bd9Sstevel@tonic-gate default: return ("Unknown BSD"); 9827c478bd9Sstevel@tonic-gate } 9837c478bd9Sstevel@tonic-gate } 9847c478bd9Sstevel@tonic-gate 9857c478bd9Sstevel@tonic-gate static char *slpv2_func(int t, boolean_t s) { 9867c478bd9Sstevel@tonic-gate static char buf[128]; 9877c478bd9Sstevel@tonic-gate 9887c478bd9Sstevel@tonic-gate switch (t) { 9897c478bd9Sstevel@tonic-gate case V2_SRVRQST: return s? "SrvRqst" : "Service Request"; 9907c478bd9Sstevel@tonic-gate case V2_SRVRPLY: return s? "SrvRply" : "Service Reply"; 9917c478bd9Sstevel@tonic-gate case V2_SRVREG: return s? "SrvReg" : "Service Registration"; 9927c478bd9Sstevel@tonic-gate case V2_SRVDEREG: 9937c478bd9Sstevel@tonic-gate return (s ? "SrvDereg" : "Service Deregistration"); 9947c478bd9Sstevel@tonic-gate case V2_SRVACK: return s? "SrvAck" : "Service Acknowledge"; 9957c478bd9Sstevel@tonic-gate case V2_ATTRRQST: return s? "AttrRqst" : "Attribute Request"; 9967c478bd9Sstevel@tonic-gate case V2_ATTRRPLY: return s? "AttrRply" : "Attribute Reply"; 9977c478bd9Sstevel@tonic-gate case V2_DAADVERT: return s? "DAAdvert" : "DA advertisement"; 9987c478bd9Sstevel@tonic-gate case V2_SRVTYPERQST: 9997c478bd9Sstevel@tonic-gate return (s ? "SrvTypeRqst" : "Service Type Request"); 10007c478bd9Sstevel@tonic-gate case V2_SRVTYPERPLY: 10017c478bd9Sstevel@tonic-gate return (s ? "SrvTypeRply" : "Service Type Reply"); 10027c478bd9Sstevel@tonic-gate case V2_SAADVERT: return s? "SAAdvert" : "SA advertisement"; 10037c478bd9Sstevel@tonic-gate } 10047c478bd9Sstevel@tonic-gate sprintf(buf, "(func %d)", t); 10057c478bd9Sstevel@tonic-gate return (s ? buf : "unknown function"); 10067c478bd9Sstevel@tonic-gate } 10077c478bd9Sstevel@tonic-gate 10087c478bd9Sstevel@tonic-gate static char *slpv2_error(unsigned short code) { 10097c478bd9Sstevel@tonic-gate static char buf[128]; 10107c478bd9Sstevel@tonic-gate 10117c478bd9Sstevel@tonic-gate switch (code) { 10127c478bd9Sstevel@tonic-gate case OK: return "ok"; 10137c478bd9Sstevel@tonic-gate case LANG_NOT_SUPPORTED: return "language not supported"; 10147c478bd9Sstevel@tonic-gate case PROTOCOL_PARSE_ERR: return "protocol parse error"; 10157c478bd9Sstevel@tonic-gate case INVALID_REGISTRATION: return "invalid registration"; 10167c478bd9Sstevel@tonic-gate case SCOPE_NOT_SUPPORTED: return "scope not supported"; 10177c478bd9Sstevel@tonic-gate case AUTHENTICATION_UNKNOWN: return "authentication unknown"; 10187c478bd9Sstevel@tonic-gate case V2_AUTHENTICATION_ABSENT: return "authentication absent"; 10197c478bd9Sstevel@tonic-gate case V2_AUTHENTICATION_FAILED: return "authentication failed"; 10207c478bd9Sstevel@tonic-gate case V2_VER_NOT_SUPPORTED: return "version not supported"; 10217c478bd9Sstevel@tonic-gate case V2_INTERNAL_ERROR: return "internal error"; 10227c478bd9Sstevel@tonic-gate case V2_DA_BUSY_NOW: return "DA busy"; 10237c478bd9Sstevel@tonic-gate case V2_OPTION_NOT_UNDERSTOOD: return "option not understood"; 10247c478bd9Sstevel@tonic-gate case V2_INVALID_UPDATE: return "invalid update"; 10257c478bd9Sstevel@tonic-gate case V2_RQST_NOT_SUPPORTED: return "request not supported"; 10267c478bd9Sstevel@tonic-gate case INVALID_LIFETIME: return "invalid lifetime"; 10277c478bd9Sstevel@tonic-gate } 10287c478bd9Sstevel@tonic-gate sprintf(buf, "error %d", code); 10297c478bd9Sstevel@tonic-gate return (buf); 10307c478bd9Sstevel@tonic-gate } 10317c478bd9Sstevel@tonic-gate 10327c478bd9Sstevel@tonic-gate static char *convert_ts(unsigned int timestamp) { 10337c478bd9Sstevel@tonic-gate /* timestamp is in UNIX time */ 10347c478bd9Sstevel@tonic-gate static char buff[128]; 10357c478bd9Sstevel@tonic-gate 10367c478bd9Sstevel@tonic-gate strcpy(buff, ctime((time_t *)×tamp)); 10377c478bd9Sstevel@tonic-gate buff[strlen(buff) - 1] = '\0'; 10387c478bd9Sstevel@tonic-gate return (buff); 10397c478bd9Sstevel@tonic-gate } 10407c478bd9Sstevel@tonic-gate 10417c478bd9Sstevel@tonic-gate static int slpv2_authblock(int cnt) { 10427c478bd9Sstevel@tonic-gate unsigned short bsd, length, slen; 10437c478bd9Sstevel@tonic-gate char *pp, *scopes; 10447c478bd9Sstevel@tonic-gate unsigned int timestamp; 10457c478bd9Sstevel@tonic-gate 10467c478bd9Sstevel@tonic-gate if (msglength < 10) { 10477c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), 10487c478bd9Sstevel@tonic-gate " [no room for auth block header: remaining msg length = %u]", 10497c478bd9Sstevel@tonic-gate msglength); 10507c478bd9Sstevel@tonic-gate return (-1); 10517c478bd9Sstevel@tonic-gate } 10527c478bd9Sstevel@tonic-gate 10537c478bd9Sstevel@tonic-gate /* bsd */ 10547c478bd9Sstevel@tonic-gate nbtohs(); 10557c478bd9Sstevel@tonic-gate bsd = netval; 10567c478bd9Sstevel@tonic-gate p += sizeof (unsigned short); 10577c478bd9Sstevel@tonic-gate 10587c478bd9Sstevel@tonic-gate /* length */ 10597c478bd9Sstevel@tonic-gate nbtohs(); 10607c478bd9Sstevel@tonic-gate length = netval; 10617c478bd9Sstevel@tonic-gate p += sizeof (unsigned short); 10627c478bd9Sstevel@tonic-gate 10637c478bd9Sstevel@tonic-gate /* timestamp */ 10647c478bd9Sstevel@tonic-gate nbtohl(); 10657c478bd9Sstevel@tonic-gate timestamp = netval; 10667c478bd9Sstevel@tonic-gate p += 4; 10677c478bd9Sstevel@tonic-gate 10687c478bd9Sstevel@tonic-gate /* SPI String length */ 10697c478bd9Sstevel@tonic-gate nbtohs(); 10707c478bd9Sstevel@tonic-gate slen = netval; 10717c478bd9Sstevel@tonic-gate p += sizeof (unsigned short); 10727c478bd9Sstevel@tonic-gate 10737c478bd9Sstevel@tonic-gate msglength -= 10; 10747c478bd9Sstevel@tonic-gate if (slen > msglength) { 10757c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), 10767c478bd9Sstevel@tonic-gate " [no room for auth block scopes: remaining msg length = %u]", 10777c478bd9Sstevel@tonic-gate msglength); 10787c478bd9Sstevel@tonic-gate return (-1); 10797c478bd9Sstevel@tonic-gate } 10807c478bd9Sstevel@tonic-gate 10817c478bd9Sstevel@tonic-gate if (length > (msglength + 10)) { 10827c478bd9Sstevel@tonic-gate if (!tcp_continuation) 10837c478bd9Sstevel@tonic-gate /* framing error: message is not long enough to contain data */ 10847c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), 10857c478bd9Sstevel@tonic-gate " [Framing error: remaining pkt length = %u]", 10867c478bd9Sstevel@tonic-gate msglength); 10877c478bd9Sstevel@tonic-gate return (-1); 10887c478bd9Sstevel@tonic-gate } 10897c478bd9Sstevel@tonic-gate 10907c478bd9Sstevel@tonic-gate scopes = p; 10917c478bd9Sstevel@tonic-gate p += slen; 10927c478bd9Sstevel@tonic-gate msglength -= slen; 10937c478bd9Sstevel@tonic-gate 10947c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), 10957c478bd9Sstevel@tonic-gate "Auth block %d: timestamp = %s", cnt, 10967c478bd9Sstevel@tonic-gate (timestamp) ? convert_ts(timestamp) : "0"); 10977c478bd9Sstevel@tonic-gate 10987c478bd9Sstevel@tonic-gate pp = get_line(0, 0); 10997c478bd9Sstevel@tonic-gate strcpy(pp, " SPI = "); 11007c478bd9Sstevel@tonic-gate strncat(pp, scopes, slen); 11017c478bd9Sstevel@tonic-gate 11027c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), 11037c478bd9Sstevel@tonic-gate " block desc = 0x%04x: %s", bsd, display_bsd(bsd)); 11047c478bd9Sstevel@tonic-gate 11057c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), " length = %u", length); 11067c478bd9Sstevel@tonic-gate 11077c478bd9Sstevel@tonic-gate p += (length - 10 - slen); 11087c478bd9Sstevel@tonic-gate msglength -= (length - 10 - slen); 11097c478bd9Sstevel@tonic-gate return (0); 11107c478bd9Sstevel@tonic-gate } 11117c478bd9Sstevel@tonic-gate 11127c478bd9Sstevel@tonic-gate static int v2_srv_rqst(int flags) { 11137c478bd9Sstevel@tonic-gate if (flags & F_SUM) { 11147c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_DEFAULT); /* PR list */ 11157c478bd9Sstevel@tonic-gate GETFIELD; /* service type */ 11167c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_DEFAULT); /* scopes */ 11177c478bd9Sstevel@tonic-gate strcat(msgend, " ["); 11187c478bd9Sstevel@tonic-gate GETFIELD; /* predicate */ 11197c478bd9Sstevel@tonic-gate strcat(msgend, "]"); 11207c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_DEFAULT); /* SPI */ 11217c478bd9Sstevel@tonic-gate } else if (flags & F_DTAIL) { 11227c478bd9Sstevel@tonic-gate DOFIELD("Previous responders", FIELD_DEFAULT); 11237c478bd9Sstevel@tonic-gate DOFIELD("Service type", FIELD_DEFAULT); 11247c478bd9Sstevel@tonic-gate DOFIELD("Scopes", FIELD_DEFAULT); 11257c478bd9Sstevel@tonic-gate DOFIELD("Predicate string", FIELD_DEFAULT); 11267c478bd9Sstevel@tonic-gate DOFIELD("Requested SPI", FIELD_DEFAULT); 11277c478bd9Sstevel@tonic-gate } 11287c478bd9Sstevel@tonic-gate 11297c478bd9Sstevel@tonic-gate return (1); 11307c478bd9Sstevel@tonic-gate } 11317c478bd9Sstevel@tonic-gate 11327c478bd9Sstevel@tonic-gate static int v2_srv_rply(int flags) { 11337c478bd9Sstevel@tonic-gate unsigned short itemcnt, errcode; 11347c478bd9Sstevel@tonic-gate int n; 11357c478bd9Sstevel@tonic-gate 11367c478bd9Sstevel@tonic-gate if (flags & F_SUM) { 11377c478bd9Sstevel@tonic-gate int i, auth_cnt; 11387c478bd9Sstevel@tonic-gate 11397c478bd9Sstevel@tonic-gate GETSHORT(errcode); 11407c478bd9Sstevel@tonic-gate if (errcode != OK) { 11417c478bd9Sstevel@tonic-gate strcat(msgbuf, slpv2_error(errcode)); 11427c478bd9Sstevel@tonic-gate msglength = 0; /* skip rest of message */ 11437c478bd9Sstevel@tonic-gate return (0); 11447c478bd9Sstevel@tonic-gate } else { 11457c478bd9Sstevel@tonic-gate GETSHORT(itemcnt); 11467c478bd9Sstevel@tonic-gate sprintf(msgend, "%d URL entries", itemcnt); 11477c478bd9Sstevel@tonic-gate #ifdef VERIFYSLP 11487c478bd9Sstevel@tonic-gate for (n = 0; n < itemcnt; n++) { 11497c478bd9Sstevel@tonic-gate SKIPBYTE; /* reserved */ 11507c478bd9Sstevel@tonic-gate SKIPSHORT; /* lifetime */ 11517c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_DEFAULT); /* URL */ 11527c478bd9Sstevel@tonic-gate GETBYTE(auth_cnt); 11537c478bd9Sstevel@tonic-gate for (i = 0; i < auth_cnt; auth_cnt++) 11547c478bd9Sstevel@tonic-gate if (skip_v2authblock() < 0) 11557c478bd9Sstevel@tonic-gate return (0); 11567c478bd9Sstevel@tonic-gate } 11577c478bd9Sstevel@tonic-gate #endif 11587c478bd9Sstevel@tonic-gate } 11597c478bd9Sstevel@tonic-gate } else if (flags & F_DTAIL) { 11607c478bd9Sstevel@tonic-gate V2_DOERRCODE; 11617c478bd9Sstevel@tonic-gate GETSHORT(itemcnt); 11627c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "URL entry count = %d", itemcnt); 11637c478bd9Sstevel@tonic-gate for (n = 0; n < itemcnt; n++) { 11647c478bd9Sstevel@tonic-gate V2_DOURL(n); 11657c478bd9Sstevel@tonic-gate } 11667c478bd9Sstevel@tonic-gate } 11677c478bd9Sstevel@tonic-gate 11687c478bd9Sstevel@tonic-gate return (1); 11697c478bd9Sstevel@tonic-gate } 11707c478bd9Sstevel@tonic-gate 11717c478bd9Sstevel@tonic-gate static int v2_srv_reg(int flags) { 11727c478bd9Sstevel@tonic-gate int i, auth_cnt; 11737c478bd9Sstevel@tonic-gate 11747c478bd9Sstevel@tonic-gate if (flags & F_SUM) { 11757c478bd9Sstevel@tonic-gate SKIPBYTE; /* reserved */ 11767c478bd9Sstevel@tonic-gate SKIPSHORT; /* lifetime */ 11777c478bd9Sstevel@tonic-gate GETFIELD; /* URL */ 11787c478bd9Sstevel@tonic-gate #ifdef VERIFYSLP 11797c478bd9Sstevel@tonic-gate GETBYTE(auth_cnt); 11807c478bd9Sstevel@tonic-gate for (i = 0; i < auth_cnt; i++) 11817c478bd9Sstevel@tonic-gate if (skip_v2authblock() < 0) 11827c478bd9Sstevel@tonic-gate return (0); 11837c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_DEFAULT); /* type */ 11847c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_DEFAULT); /* scopes */ 11857c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_DEFAULT); /* attrs */ 11867c478bd9Sstevel@tonic-gate GETBYTE(auth_cnt); 11877c478bd9Sstevel@tonic-gate for (i = 0; i < auth_cnt; i++) 11887c478bd9Sstevel@tonic-gate if (skip_v2authblock() < 0) 11897c478bd9Sstevel@tonic-gate return (0); 11907c478bd9Sstevel@tonic-gate #endif 11917c478bd9Sstevel@tonic-gate } if (flags & F_DTAIL) { 11927c478bd9Sstevel@tonic-gate V2_DOURL(-1); 11937c478bd9Sstevel@tonic-gate DOFIELD("Service type", FIELD_DEFAULT); 11947c478bd9Sstevel@tonic-gate DOFIELD("Scopes", FIELD_DEFAULT); 11957c478bd9Sstevel@tonic-gate DOFIELD("Attribute list", FIELD_DEFAULT); 11967c478bd9Sstevel@tonic-gate /* auth */ 11977c478bd9Sstevel@tonic-gate GETBYTE(auth_cnt); 11987c478bd9Sstevel@tonic-gate for (i = 0; i < auth_cnt; i++) 11997c478bd9Sstevel@tonic-gate V2_DOAUTH(i); 12007c478bd9Sstevel@tonic-gate } 12017c478bd9Sstevel@tonic-gate 12027c478bd9Sstevel@tonic-gate return (1); 12037c478bd9Sstevel@tonic-gate } 12047c478bd9Sstevel@tonic-gate 12057c478bd9Sstevel@tonic-gate static int v2_srv_dereg(int flags) { 12067c478bd9Sstevel@tonic-gate if (flags & F_SUM) { 12077c478bd9Sstevel@tonic-gate int i, auth_cnt; 12087c478bd9Sstevel@tonic-gate 12097c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_DEFAULT); /* scopes */ 12107c478bd9Sstevel@tonic-gate SKIPBYTE; /* reserved */ 12117c478bd9Sstevel@tonic-gate SKIPSHORT; /* lifetime */ 12127c478bd9Sstevel@tonic-gate GETFIELD; /* URL */ 12137c478bd9Sstevel@tonic-gate 12147c478bd9Sstevel@tonic-gate #ifdef VERIFYSLP 12157c478bd9Sstevel@tonic-gate GETBYTE(auth_cnt); 12167c478bd9Sstevel@tonic-gate for (i = 0; i < auth_cnt; i++) 12177c478bd9Sstevel@tonic-gate if (skip_v2authblock() < 0) 12187c478bd9Sstevel@tonic-gate return (0); 12197c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_DEFAULT); /* attrs */ 12207c478bd9Sstevel@tonic-gate #endif 12217c478bd9Sstevel@tonic-gate } else if (flags & F_DTAIL) { 12227c478bd9Sstevel@tonic-gate DOFIELD("Scopes", FIELD_DEFAULT); 12237c478bd9Sstevel@tonic-gate V2_DOURL(-1); 12247c478bd9Sstevel@tonic-gate DOFIELD("Tag list", FIELD_DEFAULT); 12257c478bd9Sstevel@tonic-gate } 12267c478bd9Sstevel@tonic-gate 12277c478bd9Sstevel@tonic-gate return (1); 12287c478bd9Sstevel@tonic-gate } 12297c478bd9Sstevel@tonic-gate 12307c478bd9Sstevel@tonic-gate static int v2_srv_ack(int flags) { 12317c478bd9Sstevel@tonic-gate unsigned short errcode; 12327c478bd9Sstevel@tonic-gate if (flags & F_SUM) { 12337c478bd9Sstevel@tonic-gate GETSHORT(errcode); 12347c478bd9Sstevel@tonic-gate strcat(msgbuf, slpv2_error(errcode)); 12357c478bd9Sstevel@tonic-gate } else if (flags & F_DTAIL) { 12367c478bd9Sstevel@tonic-gate V2_DOERRCODE; 12377c478bd9Sstevel@tonic-gate } 12387c478bd9Sstevel@tonic-gate 12397c478bd9Sstevel@tonic-gate return (1); 12407c478bd9Sstevel@tonic-gate } 12417c478bd9Sstevel@tonic-gate 12427c478bd9Sstevel@tonic-gate static int v2_attr_rqst(int flags) { 12437c478bd9Sstevel@tonic-gate if (flags & F_SUM) { 12447c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_DEFAULT); /* PR list */ 12457c478bd9Sstevel@tonic-gate GETFIELD; /* URL */ 12467c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_DEFAULT); /* scopes */ 12477c478bd9Sstevel@tonic-gate strcat(msgend, " ["); 12487c478bd9Sstevel@tonic-gate GETFIELD; /* attrs */ 12497c478bd9Sstevel@tonic-gate strcat(msgend, "]"); 12507c478bd9Sstevel@tonic-gate 12517c478bd9Sstevel@tonic-gate #ifdef VERIFYSLP 12527c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_DEFAULT); /* SPI */ 12537c478bd9Sstevel@tonic-gate #endif 12547c478bd9Sstevel@tonic-gate } else if (flags & F_DTAIL) { 12557c478bd9Sstevel@tonic-gate DOFIELD("Previous responders", FIELD_DEFAULT); 12567c478bd9Sstevel@tonic-gate DOFIELD("URL", FIELD_DEFAULT); 12577c478bd9Sstevel@tonic-gate DOFIELD("Scopes", FIELD_DEFAULT); 12587c478bd9Sstevel@tonic-gate DOFIELD("Tag list", FIELD_DEFAULT); 12597c478bd9Sstevel@tonic-gate DOFIELD("Requested SPI", FIELD_DEFAULT); 12607c478bd9Sstevel@tonic-gate } 12617c478bd9Sstevel@tonic-gate 12627c478bd9Sstevel@tonic-gate return (1); 12637c478bd9Sstevel@tonic-gate } 12647c478bd9Sstevel@tonic-gate 12657c478bd9Sstevel@tonic-gate static int v2_attr_rply(int flags) { 12667c478bd9Sstevel@tonic-gate int auth_cnt, i; 12677c478bd9Sstevel@tonic-gate unsigned short errcode; 12687c478bd9Sstevel@tonic-gate 12697c478bd9Sstevel@tonic-gate if (flags & F_SUM) { 12707c478bd9Sstevel@tonic-gate GETSHORT(errcode); 12717c478bd9Sstevel@tonic-gate if (errcode != OK) { 12727c478bd9Sstevel@tonic-gate strcat(msgbuf, slpv2_error(errcode)); 12737c478bd9Sstevel@tonic-gate msglength = 0; /* skip rest of message */ 12747c478bd9Sstevel@tonic-gate return (0); 12757c478bd9Sstevel@tonic-gate } else { 12767c478bd9Sstevel@tonic-gate GETFIELD; /* attr list */ 12777c478bd9Sstevel@tonic-gate 12787c478bd9Sstevel@tonic-gate #ifdef VERIFYSLP 12797c478bd9Sstevel@tonic-gate GETBYTE(auth_cnt); 12807c478bd9Sstevel@tonic-gate for (i = 0; i < auth_cnt; i++) 12817c478bd9Sstevel@tonic-gate if (skip_v2authblock() < 0) 12827c478bd9Sstevel@tonic-gate return (0); 12837c478bd9Sstevel@tonic-gate #endif 12847c478bd9Sstevel@tonic-gate } 12857c478bd9Sstevel@tonic-gate } else if (flags & F_DTAIL) { 12867c478bd9Sstevel@tonic-gate V2_DOERRCODE; 12877c478bd9Sstevel@tonic-gate DOFIELD("Attribute list", FIELD_DEFAULT); 12887c478bd9Sstevel@tonic-gate /* auth */ 12897c478bd9Sstevel@tonic-gate GETBYTE(auth_cnt); 12907c478bd9Sstevel@tonic-gate for (i = 0; i < auth_cnt; i++) 12917c478bd9Sstevel@tonic-gate V2_DOAUTH(i); 12927c478bd9Sstevel@tonic-gate } 12937c478bd9Sstevel@tonic-gate 12947c478bd9Sstevel@tonic-gate return (1); 12957c478bd9Sstevel@tonic-gate } 12967c478bd9Sstevel@tonic-gate 12977c478bd9Sstevel@tonic-gate static int v2_daadvert(int flags) { 12987c478bd9Sstevel@tonic-gate int auth_cnt, i; 12997c478bd9Sstevel@tonic-gate unsigned short errcode; 13007c478bd9Sstevel@tonic-gate unsigned int timestamp; 13017c478bd9Sstevel@tonic-gate 13027c478bd9Sstevel@tonic-gate if (flags & F_SUM) { 13037c478bd9Sstevel@tonic-gate SKIPSHORT; /* error code */ 13047c478bd9Sstevel@tonic-gate SKIPSHORT; SKIPSHORT; /* timestamp */ 13057c478bd9Sstevel@tonic-gate GETFIELD; /* URL */ 13067c478bd9Sstevel@tonic-gate 13077c478bd9Sstevel@tonic-gate #ifdef VERIFYSLP 13087c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_DEFAULT); /* scopes */ 13097c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_DEFAULT); /* attrs */ 13107c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_DEFAULT); /* SPIs */ 13117c478bd9Sstevel@tonic-gate 13127c478bd9Sstevel@tonic-gate GETBYTE(auth_cnt); 13137c478bd9Sstevel@tonic-gate for (i = 0; i < auth_cnt; i++) 13147c478bd9Sstevel@tonic-gate if (skip_v2authblock() < 0) 13157c478bd9Sstevel@tonic-gate return (0); 13167c478bd9Sstevel@tonic-gate #endif 13177c478bd9Sstevel@tonic-gate } else if (flags & F_DTAIL) { 13187c478bd9Sstevel@tonic-gate V2_DOERRCODE; 13197c478bd9Sstevel@tonic-gate V2_DOTIMESTAMP; 13207c478bd9Sstevel@tonic-gate DOFIELD("URL", FIELD_DEFAULT); 13217c478bd9Sstevel@tonic-gate DOFIELD("Scope list", FIELD_DEFAULT); 13227c478bd9Sstevel@tonic-gate DOFIELD("Attribute list", FIELD_DEFAULT); 13237c478bd9Sstevel@tonic-gate DOFIELD("Configured SPIs", FIELD_DEFAULT); 13247c478bd9Sstevel@tonic-gate /* auth */ 13257c478bd9Sstevel@tonic-gate GETBYTE(auth_cnt); 13267c478bd9Sstevel@tonic-gate for (i = 0; i < auth_cnt; i++) 13277c478bd9Sstevel@tonic-gate V2_DOAUTH(i); 13287c478bd9Sstevel@tonic-gate } 13297c478bd9Sstevel@tonic-gate 13307c478bd9Sstevel@tonic-gate return (1); 13317c478bd9Sstevel@tonic-gate } 13327c478bd9Sstevel@tonic-gate 13337c478bd9Sstevel@tonic-gate static int v2_srv_type_rqst(int flags) { 13347c478bd9Sstevel@tonic-gate if (flags & F_SUM) { 13357c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_DEFAULT); /* prev responders */ 13367c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_TYPENA); /* naming authority */ 13377c478bd9Sstevel@tonic-gate GETFIELD; /* scope */ 13387c478bd9Sstevel@tonic-gate } else if (flags & F_DTAIL) { 13397c478bd9Sstevel@tonic-gate DOFIELD("Previous responders", FIELD_DEFAULT); 13407c478bd9Sstevel@tonic-gate DOFIELD("Naming authority", FIELD_TYPENA); 13417c478bd9Sstevel@tonic-gate DOFIELD("Scopes", FIELD_DEFAULT); 13427c478bd9Sstevel@tonic-gate } 13437c478bd9Sstevel@tonic-gate 13447c478bd9Sstevel@tonic-gate return (1); 13457c478bd9Sstevel@tonic-gate } 13467c478bd9Sstevel@tonic-gate 13477c478bd9Sstevel@tonic-gate static int v2_srv_type_rply(int flags) { 13487c478bd9Sstevel@tonic-gate unsigned short errcode; 13497c478bd9Sstevel@tonic-gate 13507c478bd9Sstevel@tonic-gate if (flags & F_SUM) { 13517c478bd9Sstevel@tonic-gate GETSHORT(errcode); 13527c478bd9Sstevel@tonic-gate if (errcode != OK) 13537c478bd9Sstevel@tonic-gate strcat(msgbuf, slpv2_error(errcode)); 13547c478bd9Sstevel@tonic-gate else 13557c478bd9Sstevel@tonic-gate GETFIELD; 13567c478bd9Sstevel@tonic-gate } else if (flags & F_DTAIL) { 13577c478bd9Sstevel@tonic-gate V2_DOERRCODE; 13587c478bd9Sstevel@tonic-gate DOFIELD("Service types", FIELD_DEFAULT); 13597c478bd9Sstevel@tonic-gate } 13607c478bd9Sstevel@tonic-gate 13617c478bd9Sstevel@tonic-gate return (1); 13627c478bd9Sstevel@tonic-gate } 13637c478bd9Sstevel@tonic-gate 13647c478bd9Sstevel@tonic-gate static int v2_saadvert(int flags) { 13657c478bd9Sstevel@tonic-gate int auth_cnt, i; 13667c478bd9Sstevel@tonic-gate 13677c478bd9Sstevel@tonic-gate if (flags & F_SUM) { 13687c478bd9Sstevel@tonic-gate GETFIELD; /* URL */ 13697c478bd9Sstevel@tonic-gate 13707c478bd9Sstevel@tonic-gate #ifdef VERIFYSLP 13717c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_DEFAULT); /* scopes */ 13727c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_DEFAULT); /* attrs */ 13737c478bd9Sstevel@tonic-gate 13747c478bd9Sstevel@tonic-gate GETBYTE(auth_cnt); 13757c478bd9Sstevel@tonic-gate for (i = 0; i < auth_cnt; i++) 13767c478bd9Sstevel@tonic-gate if (skip_v2authblock() < 0) 13777c478bd9Sstevel@tonic-gate return (0); 13787c478bd9Sstevel@tonic-gate #endif 13797c478bd9Sstevel@tonic-gate } else if (flags & F_DTAIL) { 13807c478bd9Sstevel@tonic-gate DOFIELD("URL", FIELD_DEFAULT); 13817c478bd9Sstevel@tonic-gate DOFIELD("Scopes", FIELD_DEFAULT); 13827c478bd9Sstevel@tonic-gate DOFIELD("Attribute list", FIELD_DEFAULT); 13837c478bd9Sstevel@tonic-gate /* auth */ 13847c478bd9Sstevel@tonic-gate GETBYTE(auth_cnt); 13857c478bd9Sstevel@tonic-gate for (i = 0; i < auth_cnt; i++) 13867c478bd9Sstevel@tonic-gate V2_DOAUTH(i); 13877c478bd9Sstevel@tonic-gate } 13887c478bd9Sstevel@tonic-gate 13897c478bd9Sstevel@tonic-gate return (1); 13907c478bd9Sstevel@tonic-gate } 13917c478bd9Sstevel@tonic-gate 13927c478bd9Sstevel@tonic-gate /* 13937c478bd9Sstevel@tonic-gate * V1 Interpreter 13947c478bd9Sstevel@tonic-gate */ 13957c478bd9Sstevel@tonic-gate 13967c478bd9Sstevel@tonic-gate static int interpret_slp_v1(int flags, struct slpv1_hdr *slp, int fraglen) { 13977c478bd9Sstevel@tonic-gate char msgbuf_real[256]; 13987c478bd9Sstevel@tonic-gate extern int src_port, dst_port, curr_proto; 13997c478bd9Sstevel@tonic-gate boolean_t overflow = B_FALSE; 14007c478bd9Sstevel@tonic-gate 14017c478bd9Sstevel@tonic-gate msgbuf = msgbuf_real; 14027c478bd9Sstevel@tonic-gate 14037c478bd9Sstevel@tonic-gate if (msglength >= sizeof (*slp)) { 14047c478bd9Sstevel@tonic-gate if ((slp->flags & V1_URL_AUTH) == V1_URL_AUTH) 14057c478bd9Sstevel@tonic-gate url_auth = B_TRUE; 14067c478bd9Sstevel@tonic-gate if ((slp->flags & V1_ATTR_AUTH) == V1_ATTR_AUTH) 14077c478bd9Sstevel@tonic-gate attr_auth = B_TRUE; 14087c478bd9Sstevel@tonic-gate if ((slp->flags & V1_FRESH_REG) == V1_FRESH_REG) 14097c478bd9Sstevel@tonic-gate fresh = B_TRUE; 14107c478bd9Sstevel@tonic-gate if ((slp->flags & V1_OVERFLOW) == V1_OVERFLOW) 14117c478bd9Sstevel@tonic-gate overflow = B_TRUE; 14127c478bd9Sstevel@tonic-gate } 14137c478bd9Sstevel@tonic-gate 14147c478bd9Sstevel@tonic-gate /* 14157c478bd9Sstevel@tonic-gate * Somewhat of a hack to decode traffic from a server that does 14167c478bd9Sstevel@tonic-gate * not send udp replies from its SLP src port. 14177c478bd9Sstevel@tonic-gate */ 14187c478bd9Sstevel@tonic-gate if (curr_proto == IPPROTO_UDP && 14197c478bd9Sstevel@tonic-gate dst_port == 427 && 14207c478bd9Sstevel@tonic-gate src_port != 427) 14217c478bd9Sstevel@tonic-gate add_transient(src_port, (int (*)())interpret_slp); 14227c478bd9Sstevel@tonic-gate 14237c478bd9Sstevel@tonic-gate /* parse the header */ 14247c478bd9Sstevel@tonic-gate if (v1_header(flags, slp, fraglen)) { 14257c478bd9Sstevel@tonic-gate 14267c478bd9Sstevel@tonic-gate if (slp->function <= V1_MAX_FUNCTION && slp->function > 0) { 14277c478bd9Sstevel@tonic-gate 14287c478bd9Sstevel@tonic-gate /* Parse the message body */ 14297c478bd9Sstevel@tonic-gate (v1_functions[slp->function])(flags); 14307c478bd9Sstevel@tonic-gate 14317c478bd9Sstevel@tonic-gate } 14327c478bd9Sstevel@tonic-gate 14337c478bd9Sstevel@tonic-gate } 14347c478bd9Sstevel@tonic-gate 14357c478bd9Sstevel@tonic-gate /* summary error check */ 14367c478bd9Sstevel@tonic-gate if (flags & F_SUM) { 14377c478bd9Sstevel@tonic-gate if (retlength < 0) { 14387c478bd9Sstevel@tonic-gate if (curr_proto == IPPROTO_TCP) 14397c478bd9Sstevel@tonic-gate sprintf(get_sum_line(), 14407c478bd9Sstevel@tonic-gate "%s [partial TCP message]", 14417c478bd9Sstevel@tonic-gate msgbuf); 14427c478bd9Sstevel@tonic-gate else if (overflow) 14437c478bd9Sstevel@tonic-gate sprintf(get_sum_line(), "%s [OVERFLOW]", msgbuf); 14447c478bd9Sstevel@tonic-gate else 14457c478bd9Sstevel@tonic-gate sprintf(get_sum_line(), "%s [CORRUPTED MESSAGE]", msgbuf); 14467c478bd9Sstevel@tonic-gate } 14477c478bd9Sstevel@tonic-gate #ifdef VERIFYSLP 14487c478bd9Sstevel@tonic-gate else if (msglength > 0) 14497c478bd9Sstevel@tonic-gate sprintf(get_sum_line(), "%s +%d", msgbuf, msglength); 14507c478bd9Sstevel@tonic-gate #endif 14517c478bd9Sstevel@tonic-gate else 14527c478bd9Sstevel@tonic-gate sprintf(get_sum_line(), "%s", msgbuf); 14537c478bd9Sstevel@tonic-gate } else if (flags & F_DTAIL) { 14547c478bd9Sstevel@tonic-gate /* detail error check */ 14557c478bd9Sstevel@tonic-gate if (msglength > 0) { 14567c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), 14577c478bd9Sstevel@tonic-gate "[%d extra bytes at end of SLP message]", msglength); 14587c478bd9Sstevel@tonic-gate } 14597c478bd9Sstevel@tonic-gate 14607c478bd9Sstevel@tonic-gate show_trailer(); 14617c478bd9Sstevel@tonic-gate 14627c478bd9Sstevel@tonic-gate } 14637c478bd9Sstevel@tonic-gate 14647c478bd9Sstevel@tonic-gate v1_charset = 0; 14657c478bd9Sstevel@tonic-gate 14667c478bd9Sstevel@tonic-gate return (0); 14677c478bd9Sstevel@tonic-gate } 14687c478bd9Sstevel@tonic-gate 14697c478bd9Sstevel@tonic-gate static int v1_header(int flags, 14707c478bd9Sstevel@tonic-gate struct slpv1_hdr *slp, 14717c478bd9Sstevel@tonic-gate int fraglen) { 14727c478bd9Sstevel@tonic-gate extern int src_port, dst_port, curr_proto; 14737c478bd9Sstevel@tonic-gate char *prototag = (curr_proto == IPPROTO_TCP? "/tcp" : ""); 14747c478bd9Sstevel@tonic-gate 14757c478bd9Sstevel@tonic-gate if (flags & F_SUM) { 14767c478bd9Sstevel@tonic-gate char portflag = ' '; 14777c478bd9Sstevel@tonic-gate 14787c478bd9Sstevel@tonic-gate if (msglength < sizeof (*slp)) { 14797c478bd9Sstevel@tonic-gate sprintf(msgbuf, "SLP V1 [incomplete header]"); 14807c478bd9Sstevel@tonic-gate return (0); 14817c478bd9Sstevel@tonic-gate } 14827c478bd9Sstevel@tonic-gate 14837c478bd9Sstevel@tonic-gate if (slp->vers != 1) { 14847c478bd9Sstevel@tonic-gate if (curr_proto == IPPROTO_TCP) 14857c478bd9Sstevel@tonic-gate sprintf(msgbuf, "SLP [TCP Continuation]"); 14867c478bd9Sstevel@tonic-gate else 14877c478bd9Sstevel@tonic-gate sprintf(msgbuf, "SLP [unknown version %d]", slp->vers); 14887c478bd9Sstevel@tonic-gate return (0); 14897c478bd9Sstevel@tonic-gate } 14907c478bd9Sstevel@tonic-gate 14917c478bd9Sstevel@tonic-gate if (src_port != 427 && dst_port != 427) 14927c478bd9Sstevel@tonic-gate portflag = '-'; 14937c478bd9Sstevel@tonic-gate 14947c478bd9Sstevel@tonic-gate sprintf(msgbuf, "SLP V1%c%s [%d%s] ", portflag, 14957c478bd9Sstevel@tonic-gate slpv1_func(slp->function, B_TRUE), 14967c478bd9Sstevel@tonic-gate ntohs(slp->xid), prototag); 14977c478bd9Sstevel@tonic-gate msgend = msgbuf + strlen(msgbuf); 14987c478bd9Sstevel@tonic-gate msglength -= sizeof (*slp); 14997c478bd9Sstevel@tonic-gate p += sizeof (*slp); 15007c478bd9Sstevel@tonic-gate } else if (flags & F_DTAIL) { 15017c478bd9Sstevel@tonic-gate show_header("SLP: ", "Service Location Protocol (v1)", fraglen); 15027c478bd9Sstevel@tonic-gate show_space(); 15037c478bd9Sstevel@tonic-gate 15047c478bd9Sstevel@tonic-gate if (msglength < sizeof (*slp)) { 15057c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "==> Incomplete SLP header"); 15067c478bd9Sstevel@tonic-gate return (0); 15077c478bd9Sstevel@tonic-gate } 15087c478bd9Sstevel@tonic-gate 15097c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "Version = %d", slp->vers); 15107c478bd9Sstevel@tonic-gate if (slp->vers != 1) { 15117c478bd9Sstevel@tonic-gate if (curr_proto == IPPROTO_TCP) 15127c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "==> TCP continuation"); 15137c478bd9Sstevel@tonic-gate else 15147c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "==> Unexpected version number"); 15157c478bd9Sstevel@tonic-gate return (0); 15167c478bd9Sstevel@tonic-gate } 15177c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "Function = %d, %s", 15187c478bd9Sstevel@tonic-gate slp->function, slpv1_func(slp->function, B_FALSE)); 15197c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "Message length = %u", ntohs(slp->length)); 15207c478bd9Sstevel@tonic-gate 15217c478bd9Sstevel@tonic-gate /* flags */ 15227c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "Flags = 0x%02x", slp->flags); 15237c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), " %s", 15247c478bd9Sstevel@tonic-gate getflag(slp->flags, V1_OVERFLOW, 15257c478bd9Sstevel@tonic-gate "overflow", "no overflow")); 15267c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), " %s", 15277c478bd9Sstevel@tonic-gate getflag(slp->flags, V1_MONOLINGUAL, 15287c478bd9Sstevel@tonic-gate "monolingual", "not monolingual")); 15297c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), " %s", 15307c478bd9Sstevel@tonic-gate getflag(slp->flags, V1_URL_AUTH, 15317c478bd9Sstevel@tonic-gate "url authentication", "no url authentication")); 15327c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), " %s", 15337c478bd9Sstevel@tonic-gate getflag(slp->flags, V1_ATTR_AUTH, 15347c478bd9Sstevel@tonic-gate "attribute authentication", "no attribute authentication")); 15357c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), " %s", 15367c478bd9Sstevel@tonic-gate getflag(slp->flags, V1_FRESH_REG, 15377c478bd9Sstevel@tonic-gate "fresh registration", "no fresh registration")); 15387c478bd9Sstevel@tonic-gate /* check reserved flags that must be zero */ 15397c478bd9Sstevel@tonic-gate if ((slp->flags & 7) != 0) { 15407c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), 15417c478bd9Sstevel@tonic-gate " .... .xxx = %d (reserved flags nonzero)", 15427c478bd9Sstevel@tonic-gate slp->flags & 7); 15437c478bd9Sstevel@tonic-gate } 15447c478bd9Sstevel@tonic-gate /* end of flags */ 15457c478bd9Sstevel@tonic-gate 15467c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "Dialect = %u", slp->dialect); 15477c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "Language = 0x%02x%02x, %c%c", 15487c478bd9Sstevel@tonic-gate slp->language[0], slp->language[1], 15497c478bd9Sstevel@tonic-gate slp->language[0], slp->language[1]); 15507c478bd9Sstevel@tonic-gate v1_charset = ntohs(slp->charset); 15517c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "Character encoding = %u, %s", 15527c478bd9Sstevel@tonic-gate v1_charset, 15537c478bd9Sstevel@tonic-gate slpv1_charset(v1_charset)); 15547c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "XID = %u", ntohs(slp->xid)); 15557c478bd9Sstevel@tonic-gate 15567c478bd9Sstevel@tonic-gate /* set msglength to remaining length of SLP message */ 15577c478bd9Sstevel@tonic-gate msglength -= sizeof (*slp); 15587c478bd9Sstevel@tonic-gate p += sizeof (*slp); 15597c478bd9Sstevel@tonic-gate } 15607c478bd9Sstevel@tonic-gate 15617c478bd9Sstevel@tonic-gate return (1); 15627c478bd9Sstevel@tonic-gate } 15637c478bd9Sstevel@tonic-gate 15647c478bd9Sstevel@tonic-gate static char *slpv1_func(int t, boolean_t s) { 15657c478bd9Sstevel@tonic-gate static char buf[128]; 15667c478bd9Sstevel@tonic-gate switch (t) { 15677c478bd9Sstevel@tonic-gate case V1_SRVREQ: return s? "SrvRqst" : "Service Request"; 15687c478bd9Sstevel@tonic-gate case V1_SRVRPLY: return s? "SrvRply" : "Service Reply"; 15697c478bd9Sstevel@tonic-gate case V1_SRVREG: return s? "SrvReg" : "Service Registration"; 15707c478bd9Sstevel@tonic-gate case V1_SRVDEREG: return s? 15717c478bd9Sstevel@tonic-gate "SrvDereg" : "Service Deregistration"; 15727c478bd9Sstevel@tonic-gate case V1_SRVACK: return s? "SrvAck" : "Service Acknowledge"; 15737c478bd9Sstevel@tonic-gate case V1_ATTRRQST: return s? "AttrRqst" : "Attribute Request"; 15747c478bd9Sstevel@tonic-gate case V1_ATTRRPLY: return s? "AttrRply" : "Attribute Reply"; 15757c478bd9Sstevel@tonic-gate case V1_DAADVERT: return s? "DAAdvert" : "DA advertisement"; 15767c478bd9Sstevel@tonic-gate case V1_SRVTYPERQST:return s? "SrvTypeRqst" : "Service Type Request"; 15777c478bd9Sstevel@tonic-gate case V1_SRVTYPERPLY:return s? "SrvTypeRply" : "Service Type Reply"; 15787c478bd9Sstevel@tonic-gate } 15797c478bd9Sstevel@tonic-gate sprintf(buf, "(func %d)", t); 15807c478bd9Sstevel@tonic-gate return (s ? buf : "unknown function"); 15817c478bd9Sstevel@tonic-gate } 15827c478bd9Sstevel@tonic-gate 15837c478bd9Sstevel@tonic-gate static char *slpv1_error(unsigned short code) { 15847c478bd9Sstevel@tonic-gate static char buf[128]; 15857c478bd9Sstevel@tonic-gate 15867c478bd9Sstevel@tonic-gate switch (code) { 15877c478bd9Sstevel@tonic-gate case OK: return "ok"; 15887c478bd9Sstevel@tonic-gate case LANG_NOT_SUPPORTED: return "language not supported"; 15897c478bd9Sstevel@tonic-gate case PROTOCOL_PARSE_ERR: return "protocol parse error"; 15907c478bd9Sstevel@tonic-gate case INVALID_REGISTRATION: return "invalid registration"; 15917c478bd9Sstevel@tonic-gate case SCOPE_NOT_SUPPORTED: return "scope not supported"; 15927c478bd9Sstevel@tonic-gate case CHARSET_NOT_UNDERSTOOD:return "character set not understood"; 15937c478bd9Sstevel@tonic-gate case AUTHENTICATION_INVALID:return "invalid authentication"; 15947c478bd9Sstevel@tonic-gate case NOT_SUPPORTED_YET: return "not yet supported"; 15957c478bd9Sstevel@tonic-gate case REQUEST_TIMED_OUT: return "request timed out"; 15967c478bd9Sstevel@tonic-gate case COULD_NOT_INIT_NET_RESOURCES: 15977c478bd9Sstevel@tonic-gate return ("could not initialize net resources"); 15987c478bd9Sstevel@tonic-gate case COULD_NOT_ALLOCATE_MEMORY: 15997c478bd9Sstevel@tonic-gate return ("could not allocate memory"); 16007c478bd9Sstevel@tonic-gate case PARAMETER_BAD: return "bad parameter"; 16017c478bd9Sstevel@tonic-gate case INTERNAL_NET_ERROR: return "internal network error"; 16027c478bd9Sstevel@tonic-gate case INTERNAL_SYSTEM_ERROR: return "internal system error"; 16037c478bd9Sstevel@tonic-gate } 16047c478bd9Sstevel@tonic-gate sprintf(buf, "error %d", code); 16057c478bd9Sstevel@tonic-gate return (buf); 16067c478bd9Sstevel@tonic-gate } 16077c478bd9Sstevel@tonic-gate 16087c478bd9Sstevel@tonic-gate /* 16097c478bd9Sstevel@tonic-gate * Character set info from 16107c478bd9Sstevel@tonic-gate * www.isi.edu/in-notes/iana/assignments/character-sets 16117c478bd9Sstevel@tonic-gate * 16127c478bd9Sstevel@tonic-gate * Assigned MIB enum Numbers 16137c478bd9Sstevel@tonic-gate * ------------------------- 16147c478bd9Sstevel@tonic-gate * 0 Reserved 16157c478bd9Sstevel@tonic-gate * 1 Reserved 16167c478bd9Sstevel@tonic-gate * 3-106 Set By Standards Organizations 16177c478bd9Sstevel@tonic-gate * 1000-1010 Unicode / 10646 16187c478bd9Sstevel@tonic-gate * 2000-2087 Vendor 16197c478bd9Sstevel@tonic-gate * 2250-2258 Vendor 16207c478bd9Sstevel@tonic-gate * 16217c478bd9Sstevel@tonic-gate * MIBenum: 3 16227c478bd9Sstevel@tonic-gate * Alias: US-ASCII (preferred MIME name) 16237c478bd9Sstevel@tonic-gate * Source: ECMA registry [RFC1345] 16247c478bd9Sstevel@tonic-gate * 16257c478bd9Sstevel@tonic-gate * MIBenum: 106 16267c478bd9Sstevel@tonic-gate * Name: UTF-8 16277c478bd9Sstevel@tonic-gate * Source: RFC 2044 16287c478bd9Sstevel@tonic-gate */ 16297c478bd9Sstevel@tonic-gate 16307c478bd9Sstevel@tonic-gate static char *slpv1_charset(unsigned short code) { 16317c478bd9Sstevel@tonic-gate if (code <= 1) 16327c478bd9Sstevel@tonic-gate return ("Reserved"); 16337c478bd9Sstevel@tonic-gate if (code == 3) 16347c478bd9Sstevel@tonic-gate return ("US-ASCII"); 16357c478bd9Sstevel@tonic-gate if (code == 4) 16367c478bd9Sstevel@tonic-gate return ("latin1"); 16377c478bd9Sstevel@tonic-gate if (code == 106) 16387c478bd9Sstevel@tonic-gate return ("UTF-8"); 16397c478bd9Sstevel@tonic-gate if (code >= 3 && code <= 106) 16407c478bd9Sstevel@tonic-gate return ("set by standards organization"); 16417c478bd9Sstevel@tonic-gate if (code >= 1000 && code <= 1010) 16427c478bd9Sstevel@tonic-gate return ("Unicode variant"); 16437c478bd9Sstevel@tonic-gate if ((code >= 2000 && code <= 2087) || 16447c478bd9Sstevel@tonic-gate (code >= 2250 && code <= 2258)) 16457c478bd9Sstevel@tonic-gate return ("Vendor assigned"); 16467c478bd9Sstevel@tonic-gate 16477c478bd9Sstevel@tonic-gate return ("unknown"); 16487c478bd9Sstevel@tonic-gate } 16497c478bd9Sstevel@tonic-gate 16507c478bd9Sstevel@tonic-gate #ifdef VERIFYSLP 16517c478bd9Sstevel@tonic-gate static int skip_v1authblock() { 16527c478bd9Sstevel@tonic-gate unsigned short length; 16537c478bd9Sstevel@tonic-gate 16547c478bd9Sstevel@tonic-gate /* auth header: 12 bytes total */ 16557c478bd9Sstevel@tonic-gate if (msglength < 12) 16567c478bd9Sstevel@tonic-gate return (-1); 16577c478bd9Sstevel@tonic-gate 16587c478bd9Sstevel@tonic-gate /* timestamp: 8 bytes */ 16597c478bd9Sstevel@tonic-gate p += 8; /* timestamp: 8 bytes */ 16607c478bd9Sstevel@tonic-gate p += sizeof (short); /* block descriptor: 2 bytes */ 16617c478bd9Sstevel@tonic-gate nbtohs(); 16627c478bd9Sstevel@tonic-gate length = netval; 16637c478bd9Sstevel@tonic-gate p += sizeof (short); 16647c478bd9Sstevel@tonic-gate msglength -= 12; 16657c478bd9Sstevel@tonic-gate 16667c478bd9Sstevel@tonic-gate if (length > msglength) { 16677c478bd9Sstevel@tonic-gate /* framing error: message is not long enough to contain data */ 16687c478bd9Sstevel@tonic-gate return (-1); 16697c478bd9Sstevel@tonic-gate } 16707c478bd9Sstevel@tonic-gate 16717c478bd9Sstevel@tonic-gate p += length; 16727c478bd9Sstevel@tonic-gate msglength -= length; 16737c478bd9Sstevel@tonic-gate return (0); 16747c478bd9Sstevel@tonic-gate } 16757c478bd9Sstevel@tonic-gate #endif 16767c478bd9Sstevel@tonic-gate 16777c478bd9Sstevel@tonic-gate static int slpv1_authblock() { 16787c478bd9Sstevel@tonic-gate unsigned short bsd, length; 16797c478bd9Sstevel@tonic-gate char msgbuf[128]; 16807c478bd9Sstevel@tonic-gate int n; 16817c478bd9Sstevel@tonic-gate 16827c478bd9Sstevel@tonic-gate if (msglength < 12) { 16837c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), 16847c478bd9Sstevel@tonic-gate " [no room for auth block: remaining msg length = %u]", 16857c478bd9Sstevel@tonic-gate msglength); 16867c478bd9Sstevel@tonic-gate return (-1); 16877c478bd9Sstevel@tonic-gate } 16887c478bd9Sstevel@tonic-gate 16897c478bd9Sstevel@tonic-gate /* timestamp: 8 bytes */ 16907c478bd9Sstevel@tonic-gate *msgbuf = '\0'; 16917c478bd9Sstevel@tonic-gate for (n = 0; n < 8; n++, p += 1) { 16927c478bd9Sstevel@tonic-gate char tmp[16]; 16937c478bd9Sstevel@tonic-gate sprintf(tmp, "%02x", (unsigned char)(*p)); 16947c478bd9Sstevel@tonic-gate strcat(msgbuf, tmp); 16957c478bd9Sstevel@tonic-gate } 16967c478bd9Sstevel@tonic-gate 16977c478bd9Sstevel@tonic-gate nbtohs(); 16987c478bd9Sstevel@tonic-gate bsd = netval; 16997c478bd9Sstevel@tonic-gate p += sizeof (short); 17007c478bd9Sstevel@tonic-gate nbtohs(); 17017c478bd9Sstevel@tonic-gate length = netval; 17027c478bd9Sstevel@tonic-gate p += sizeof (short); 17037c478bd9Sstevel@tonic-gate msglength -= 12; 17047c478bd9Sstevel@tonic-gate 17057c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), 17067c478bd9Sstevel@tonic-gate " Auth block: timestamp = %s", 17077c478bd9Sstevel@tonic-gate msgbuf); 17087c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), 17097c478bd9Sstevel@tonic-gate " block desc = 0x%04x, length = %u", 17107c478bd9Sstevel@tonic-gate bsd, length); 17117c478bd9Sstevel@tonic-gate if (length > msglength) { 17127c478bd9Sstevel@tonic-gate /* framing error: message is not long enough to contain data */ 17137c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), 17147c478bd9Sstevel@tonic-gate " [Framing error: remaining pkt length = %u]", msglength); 17157c478bd9Sstevel@tonic-gate return (-1); 17167c478bd9Sstevel@tonic-gate } 17177c478bd9Sstevel@tonic-gate 17187c478bd9Sstevel@tonic-gate p += length; 17197c478bd9Sstevel@tonic-gate msglength -= length; 17207c478bd9Sstevel@tonic-gate return (0); 17217c478bd9Sstevel@tonic-gate } 17227c478bd9Sstevel@tonic-gate 17237c478bd9Sstevel@tonic-gate static int slpv1_url(boolean_t auth_present) { 17247c478bd9Sstevel@tonic-gate time_t exp; 17257c478bd9Sstevel@tonic-gate int lifetime, length; 17267c478bd9Sstevel@tonic-gate 17277c478bd9Sstevel@tonic-gate get_short(); 17287c478bd9Sstevel@tonic-gate if ((lifetime = netval) < 0) 17297c478bd9Sstevel@tonic-gate return (-1); 17307c478bd9Sstevel@tonic-gate get_short(); 17317c478bd9Sstevel@tonic-gate if ((length = netval) < 0) 17327c478bd9Sstevel@tonic-gate return (-1); 17337c478bd9Sstevel@tonic-gate 17347c478bd9Sstevel@tonic-gate exp = time(0) + lifetime; 17357c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "URL: length = %u, lifetime = %d (%24.24s)", 17367c478bd9Sstevel@tonic-gate length, lifetime, ctime(&exp)); 17377c478bd9Sstevel@tonic-gate if (length > msglength) { 17387c478bd9Sstevel@tonic-gate /* framing error: message is not long enough to contain data */ 17397c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), 17407c478bd9Sstevel@tonic-gate " [Framing error: remaining pkt length = %u]", msglength); 17417c478bd9Sstevel@tonic-gate return (-1); 17427c478bd9Sstevel@tonic-gate } 17437c478bd9Sstevel@tonic-gate 17447c478bd9Sstevel@tonic-gate if (length > 0) { 17457c478bd9Sstevel@tonic-gate char *buf = malloc(length + 1); 17467c478bd9Sstevel@tonic-gate if (buf != NULL) { 17477c478bd9Sstevel@tonic-gate if (!make_utf8(buf, length, p, length)) { 17487c478bd9Sstevel@tonic-gate strcpy(buf, "[Invalid Character Encoding]"); 17497c478bd9Sstevel@tonic-gate } 17507c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), " \"%s\"", buf); 17517c478bd9Sstevel@tonic-gate free(buf); 17527c478bd9Sstevel@tonic-gate } 17537c478bd9Sstevel@tonic-gate } 17547c478bd9Sstevel@tonic-gate msglength -= length; 17557c478bd9Sstevel@tonic-gate p += length; 17567c478bd9Sstevel@tonic-gate 17577c478bd9Sstevel@tonic-gate if (auth_present) 17587c478bd9Sstevel@tonic-gate return (slpv1_authblock()); 17597c478bd9Sstevel@tonic-gate 17607c478bd9Sstevel@tonic-gate return (0); 17617c478bd9Sstevel@tonic-gate } 17627c478bd9Sstevel@tonic-gate 17637c478bd9Sstevel@tonic-gate static int v1_srv_rqst(int flags) { 17647c478bd9Sstevel@tonic-gate if (flags & F_SUM) { 17657c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_PREVRESP); /* prev responders */ 17667c478bd9Sstevel@tonic-gate GETFIELD; /* predicate */ 17677c478bd9Sstevel@tonic-gate } else if (flags & F_DTAIL) { 17687c478bd9Sstevel@tonic-gate DOFIELD("Previous responders", FIELD_PREVRESP); 17697c478bd9Sstevel@tonic-gate DOFIELD("predicate string", FIELD_DEFAULT); 17707c478bd9Sstevel@tonic-gate } 17717c478bd9Sstevel@tonic-gate 17727c478bd9Sstevel@tonic-gate return (1); 17737c478bd9Sstevel@tonic-gate } 17747c478bd9Sstevel@tonic-gate 17757c478bd9Sstevel@tonic-gate static int v1_srv_rply(int flags) { 17767c478bd9Sstevel@tonic-gate unsigned short errcode, itemcnt; 17777c478bd9Sstevel@tonic-gate int n; 17787c478bd9Sstevel@tonic-gate 17797c478bd9Sstevel@tonic-gate if (flags & F_SUM) { 17807c478bd9Sstevel@tonic-gate GETSHORT(errcode); 17817c478bd9Sstevel@tonic-gate if (errcode != OK) { 17827c478bd9Sstevel@tonic-gate strcat(msgbuf, slpv1_error(errcode)); 17837c478bd9Sstevel@tonic-gate } else { 17847c478bd9Sstevel@tonic-gate GETSHORT(itemcnt); 17857c478bd9Sstevel@tonic-gate sprintf(msgend, "%d URL entries", itemcnt); 17867c478bd9Sstevel@tonic-gate #ifdef VERIFYSLP 17877c478bd9Sstevel@tonic-gate for (n = 0; n < itemcnt; n++) { 17887c478bd9Sstevel@tonic-gate SKIPSHORT; /* lifetime */ 17897c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_DEFAULT); /* URL */ 17907c478bd9Sstevel@tonic-gate SKIPAUTH(url_auth); /* URL auth */ 17917c478bd9Sstevel@tonic-gate } 17927c478bd9Sstevel@tonic-gate #endif 17937c478bd9Sstevel@tonic-gate } 17947c478bd9Sstevel@tonic-gate } else if (flags & F_DTAIL) { 17957c478bd9Sstevel@tonic-gate DOERRCODE; 17967c478bd9Sstevel@tonic-gate GETSHORT(itemcnt); 17977c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "URL entry count = %d", itemcnt); 17987c478bd9Sstevel@tonic-gate for (n = 0; n < itemcnt; n++) { 17997c478bd9Sstevel@tonic-gate DOURL; 18007c478bd9Sstevel@tonic-gate } 18017c478bd9Sstevel@tonic-gate } 18027c478bd9Sstevel@tonic-gate 18037c478bd9Sstevel@tonic-gate return (1); 18047c478bd9Sstevel@tonic-gate } 18057c478bd9Sstevel@tonic-gate 18067c478bd9Sstevel@tonic-gate static int v1_srv_reg(int flags) { 18077c478bd9Sstevel@tonic-gate if (flags & F_SUM) { 18087c478bd9Sstevel@tonic-gate SKIPSHORT; /* lifetime */ 18097c478bd9Sstevel@tonic-gate GETFIELD; /* URL */ 18107c478bd9Sstevel@tonic-gate #ifdef VERIFYSLP 18117c478bd9Sstevel@tonic-gate SKIPAUTH(url_auth); /* URL auth */ 18127c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_DEFAULT); /* attribute list */ 18137c478bd9Sstevel@tonic-gate SKIPAUTH(attr_auth); /* attr auth */ 18147c478bd9Sstevel@tonic-gate #endif 18157c478bd9Sstevel@tonic-gate } else if (flags & F_DTAIL) { 18167c478bd9Sstevel@tonic-gate DOURL; 18177c478bd9Sstevel@tonic-gate DOFIELD("Attribute list", FIELD_DEFAULT); 18187c478bd9Sstevel@tonic-gate DOAUTH(attr_auth); 18197c478bd9Sstevel@tonic-gate } 18207c478bd9Sstevel@tonic-gate 18217c478bd9Sstevel@tonic-gate return (1); 18227c478bd9Sstevel@tonic-gate } 18237c478bd9Sstevel@tonic-gate 18247c478bd9Sstevel@tonic-gate static int v1_srv_ack(int flags) { 18257c478bd9Sstevel@tonic-gate unsigned short errcode; 18267c478bd9Sstevel@tonic-gate 18277c478bd9Sstevel@tonic-gate if (flags & F_SUM) { 18287c478bd9Sstevel@tonic-gate GETSHORT(errcode); 18297c478bd9Sstevel@tonic-gate strcat(msgbuf, slpv1_error(errcode)); 18307c478bd9Sstevel@tonic-gate if (errcode == OK && fresh) { 18317c478bd9Sstevel@tonic-gate strcat(msgbuf, " [Fresh]"); 18327c478bd9Sstevel@tonic-gate } 18337c478bd9Sstevel@tonic-gate } else if (flags & F_DTAIL) { 18347c478bd9Sstevel@tonic-gate DOERRCODE; 18357c478bd9Sstevel@tonic-gate } 18367c478bd9Sstevel@tonic-gate 18377c478bd9Sstevel@tonic-gate return (1); 18387c478bd9Sstevel@tonic-gate } 18397c478bd9Sstevel@tonic-gate 18407c478bd9Sstevel@tonic-gate static int v1_srv_dereg(int flags) { 18417c478bd9Sstevel@tonic-gate if (flags & F_SUM) { 18427c478bd9Sstevel@tonic-gate GETFIELD; /* URL */ 18437c478bd9Sstevel@tonic-gate #ifdef VERIFYSLP 18447c478bd9Sstevel@tonic-gate SKIPAUTH(url_auth); 18457c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_DEFAULT); /* tag spec */ 18467c478bd9Sstevel@tonic-gate #endif 18477c478bd9Sstevel@tonic-gate } else if (flags & F_DTAIL) { 18487c478bd9Sstevel@tonic-gate DOFIELD("URL", FIELD_DEFAULT); 18497c478bd9Sstevel@tonic-gate DOAUTH(url_auth); 18507c478bd9Sstevel@tonic-gate DOFIELD("Tag spec", FIELD_DEFAULT); 18517c478bd9Sstevel@tonic-gate } 18527c478bd9Sstevel@tonic-gate 18537c478bd9Sstevel@tonic-gate return (1); 18547c478bd9Sstevel@tonic-gate } 18557c478bd9Sstevel@tonic-gate 18567c478bd9Sstevel@tonic-gate static int v1_attr_rqst(int flags) { 18577c478bd9Sstevel@tonic-gate if (flags & F_SUM) { 18587c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_PREVRESP); /* prev responders */ 18597c478bd9Sstevel@tonic-gate GETFIELD; /* URL */ 18607c478bd9Sstevel@tonic-gate #ifdef VERIFYSLP 18617c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_DEFAULT); /* scope */ 18627c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_DEFAULT); /* select list */ 18637c478bd9Sstevel@tonic-gate #endif 18647c478bd9Sstevel@tonic-gate } else if (flags & F_DTAIL) { 18657c478bd9Sstevel@tonic-gate DOFIELD("Previous responders", FIELD_PREVRESP); 18667c478bd9Sstevel@tonic-gate DOFIELD("URL", FIELD_DEFAULT); 18677c478bd9Sstevel@tonic-gate DOFIELD("Scope", FIELD_DEFAULT); 18687c478bd9Sstevel@tonic-gate DOFIELD("Select list", FIELD_DEFAULT); 18697c478bd9Sstevel@tonic-gate } 18707c478bd9Sstevel@tonic-gate 18717c478bd9Sstevel@tonic-gate return (1); 18727c478bd9Sstevel@tonic-gate } 18737c478bd9Sstevel@tonic-gate 18747c478bd9Sstevel@tonic-gate static int v1_attr_rply(int flags) { 18757c478bd9Sstevel@tonic-gate unsigned short errcode; 18767c478bd9Sstevel@tonic-gate 18777c478bd9Sstevel@tonic-gate if (flags & F_SUM) { 18787c478bd9Sstevel@tonic-gate GETSHORT(errcode); 18797c478bd9Sstevel@tonic-gate if (errcode != OK) { 18807c478bd9Sstevel@tonic-gate strcat(msgbuf, slpv1_error(errcode)); 18817c478bd9Sstevel@tonic-gate } else { 18827c478bd9Sstevel@tonic-gate GETFIELD; /* attr list */ 18837c478bd9Sstevel@tonic-gate #ifdef VERIFYSLP 18847c478bd9Sstevel@tonic-gate SKIPAUTH(attr_auth); 18857c478bd9Sstevel@tonic-gate #endif 18867c478bd9Sstevel@tonic-gate } 18877c478bd9Sstevel@tonic-gate } else if (flags & F_DTAIL) { 18887c478bd9Sstevel@tonic-gate DOERRCODE; 18897c478bd9Sstevel@tonic-gate DOFIELD("Attribute list", FIELD_DEFAULT); 18907c478bd9Sstevel@tonic-gate DOAUTH(attr_auth); 18917c478bd9Sstevel@tonic-gate } 18927c478bd9Sstevel@tonic-gate 18937c478bd9Sstevel@tonic-gate return (1); 18947c478bd9Sstevel@tonic-gate } 18957c478bd9Sstevel@tonic-gate 18967c478bd9Sstevel@tonic-gate static int v1_daadvert(int flags) { 18977c478bd9Sstevel@tonic-gate unsigned short errcode; 18987c478bd9Sstevel@tonic-gate 18997c478bd9Sstevel@tonic-gate if (flags & F_SUM) { 19007c478bd9Sstevel@tonic-gate GETSHORT(errcode); 19017c478bd9Sstevel@tonic-gate if (errcode != OK) { 19027c478bd9Sstevel@tonic-gate strcat(msgbuf, slpv1_error(errcode)); 19037c478bd9Sstevel@tonic-gate } else { 19047c478bd9Sstevel@tonic-gate GETFIELD; /* URL */ 19057c478bd9Sstevel@tonic-gate #ifdef VERIFYSLP 19067c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_DEFAULT); /* scope list */ 19077c478bd9Sstevel@tonic-gate #endif 19087c478bd9Sstevel@tonic-gate } 19097c478bd9Sstevel@tonic-gate } else if (flags & F_DTAIL) { 19107c478bd9Sstevel@tonic-gate DOERRCODE; 19117c478bd9Sstevel@tonic-gate DOFIELD("URL", FIELD_DEFAULT); 19127c478bd9Sstevel@tonic-gate DOFIELD("Scope list", FIELD_DEFAULT); 19137c478bd9Sstevel@tonic-gate } 19147c478bd9Sstevel@tonic-gate 19157c478bd9Sstevel@tonic-gate return (1); 19167c478bd9Sstevel@tonic-gate } 19177c478bd9Sstevel@tonic-gate 19187c478bd9Sstevel@tonic-gate static int v1_srv_type_rqst(int flags) { 19197c478bd9Sstevel@tonic-gate if (flags & F_SUM) { 19207c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_PREVRESP); /* prev responders */ 19217c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_TYPENA); /* naming authority */ 19227c478bd9Sstevel@tonic-gate GETFIELD; /* scope */ 19237c478bd9Sstevel@tonic-gate } else if (flags & F_DTAIL) { 19247c478bd9Sstevel@tonic-gate DOFIELD("Previous responders", FIELD_PREVRESP); 19257c478bd9Sstevel@tonic-gate DOFIELD("Naming authority", FIELD_TYPENA); 19267c478bd9Sstevel@tonic-gate DOFIELD("Scope string", FIELD_DEFAULT); 19277c478bd9Sstevel@tonic-gate } 19287c478bd9Sstevel@tonic-gate 19297c478bd9Sstevel@tonic-gate return (1); 19307c478bd9Sstevel@tonic-gate } 19317c478bd9Sstevel@tonic-gate 19327c478bd9Sstevel@tonic-gate static int v1_srv_type_rply(int flags) { 19337c478bd9Sstevel@tonic-gate unsigned short errcode, itemcnt; 19347c478bd9Sstevel@tonic-gate int n; 19357c478bd9Sstevel@tonic-gate 19367c478bd9Sstevel@tonic-gate if (flags & F_SUM) { 19377c478bd9Sstevel@tonic-gate GETSHORT(errcode); 19387c478bd9Sstevel@tonic-gate if (errcode != OK) { 19397c478bd9Sstevel@tonic-gate strcat(msgbuf, slpv1_error(errcode)); 19407c478bd9Sstevel@tonic-gate } else { 19417c478bd9Sstevel@tonic-gate GETSHORT(itemcnt); 19427c478bd9Sstevel@tonic-gate sprintf(msgend, "%d type entries", itemcnt); 19437c478bd9Sstevel@tonic-gate #ifdef VERIFYSLP 19447c478bd9Sstevel@tonic-gate for (n = 0; n < itemcnt; n++) { 19457c478bd9Sstevel@tonic-gate SKIPFIELD(FIELD_DEFAULT); /* Service type item */ 19467c478bd9Sstevel@tonic-gate } 19477c478bd9Sstevel@tonic-gate #endif 19487c478bd9Sstevel@tonic-gate } 19497c478bd9Sstevel@tonic-gate } else if (flags & F_DTAIL) { 19507c478bd9Sstevel@tonic-gate DOERRCODE; 19517c478bd9Sstevel@tonic-gate GETSHORT(itemcnt); 19527c478bd9Sstevel@tonic-gate sprintf(get_line(0, 0), "Service type count = %d", itemcnt); 19537c478bd9Sstevel@tonic-gate for (n = 0; n < itemcnt; n++) { 19547c478bd9Sstevel@tonic-gate DOFIELD(" Service type item", FIELD_DEFAULT); 19557c478bd9Sstevel@tonic-gate } 19567c478bd9Sstevel@tonic-gate } 19577c478bd9Sstevel@tonic-gate 19587c478bd9Sstevel@tonic-gate return (1); 19597c478bd9Sstevel@tonic-gate } 1960