snoop_slp.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 1998,2000 by Sun Microsystems, Inc.
* All rights reserved.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iconv.h>
#include "snoop.h"
#include "slp.h"
#define MAXSUMLEN 30
/* define VERIFYSLP to enable full message checking in summary mode */
#define VERIFYSLP
/* Globals -- ugly, yes, but fast and easy in macros */
static int msglength;
static int retlength;
static char *msgend; /* the end of the summary message buffer */
static char *p; /* current position in the packet */
static char *msgbuf; /* message buffer for summary mode */
static int v1_charset = 0; /* character set; only in V1 */
/* Entry points for parsing the protocol */
static int interpret_slp_v1(int, struct slpv1_hdr *, int);
static int interpret_slp_v2(int, struct slpv2_hdr *, int);
/* header parsing */
/* V2 auth blocks */
static int slpv2_authblock(int);
/* From snoop_rport: */
extern int add_transient(int, int (*)());
/*
* Functions for parsing each protocol message
* Each function takes the interpreter's flags argument as its input
* parameter, and returns 1 on success, or 0 on message corruption.
* retlength is set as a side-effect in summary mode.
*/
static int v2_srv_rqst(int);
static int v2_srv_rply(int);
static int v2_srv_reg(int);
static int v2_srv_dereg(int);
static int v2_srv_ack(int);
static int v2_attr_rqst(int);
static int v2_attr_rply(int);
static int v2_daadvert(int);
static int v2_srv_type_rqst(int);
static int v2_srv_type_rply(int);
static int v2_saadvert(int);
static int v1_srv_rqst(int);
static int v1_srv_rply(int);
static int v1_srv_reg(int);
static int v1_srv_dereg(int);
static int v1_srv_ack(int);
static int v1_attr_rqst(int);
static int v1_attr_rply(int);
static int v1_daadvert(int);
static int v1_srv_type_rqst(int);
static int v1_srv_type_rply(int);
/*
* The dispatch tables for handling individual messages, keyed by
* function number.
*/
typedef int function_handler();
#define V2_MAX_FUNCTION 11
(function_handler *) NULL,
(function_handler *) v2_saadvert };
#define V1_MAX_FUNCTION 10
(function_handler *) NULL,
(function_handler *) v1_srv_type_rply };
/* TCP continuation handling */
#define MAX_TCPCONT 16
static struct tcp_cont {
int dst_port;
char *msg;
int totallen;
int curr_offset;
} *tcp_cont[MAX_TCPCONT];
static int current_tcp_cont;
static void reg_tcp_cont(char *, int, int, int);
static int add_tcp_cont(struct tcp_cont *, char *, int);
static struct tcp_cont *find_tcp_cont(int);
static void remove_tcp_cont(int);
/* Conversions from numbers to strings */
static char *slpv2_func(int, boolean_t);
static char *slpv2_error(unsigned short);
static char *slpv1_func(int, boolean_t);
static char *slpv1_error(unsigned short);
static char *slpv1_charset(unsigned short);
/*
* The only external entry point to the SLP interpreter. This function
* simply dispatches the packet based on the version.
*/
extern int dst_port, curr_proto;
retlength = 0;
p = slp;
/* check if this is a TCP continuation */
if (tce) {
}
}
}
else
}
/*
* Primitives. These are implemented as much as possible as macros for
* speed.
*/
#define FIELD_DEFAULT 0
#define FIELD_PREVRESP 1
#define FIELD_TYPENA 2
static long long netval = 0; /* need signed 64 bit quantity */
/* gets two bytes from p and leaves the result in netval */
#define nbtohs() \
/* gets four bytes from p and leaves the result in netval */
#define nbtohl() \
#define get_byte() \
if (msglength >= 1) { \
netval = *p; \
p++; \
msglength--; \
} else \
netval = -1
#define GETBYTE(x) \
get_byte(); \
return (0); \
x = netval
#define SKIPBYTE \
get_byte(); \
return (0); \
/*
* gets two bytes from p, leaves the result in netval, and updates
* msglength and p.
*/
#define get_short() \
if (msglength >= sizeof (unsigned short)) { \
nbtohs(); \
p += sizeof (unsigned short); \
msglength -= sizeof (unsigned short); \
} else \
netval = -1
#define GETSHORT(x) \
get_short(); \
return (0); \
x = netval
#define SKIPSHORT \
get_short(); \
return (0)
static void slp_prevresp(char *p) {
char *p2;
/* cycle through all entries */
*p2++ = '\0';
/* print entry at p */
}
}
static int skip_field(int type) {
unsigned short stringlen;
get_short();
if (netval < 0) {
return (-1);
}
/* special case for NA field in SrvTypeRqst */
stringlen = 0;
}
return (-1);
}
p += stringlen;
return (stringlen);
}
return (0)
#define GETFIELD \
get_short(); \
return (0); \
p += retlength; \
/*
* Determines from the first five bytes of a potential SLP header
* if the following message is really an SLP message. Returns 1 if
* it is a real SLP message, 0 if not.
*/
/* a valid version will be 1 or 2 */
switch (*slphdr) {
case 1:
/* valid function? */
return (0);
}
/* valid length heuristic */
return (0);
}
return (1);
case 2:
/* valid function? */
return (0);
}
/* valid length heuristic */
return (0);
}
return (1);
default:
return (0);
}
}
/*
* Converts a V1 char encoding to UTF8. If this fails, returns 0,
* otherwise, 1. This function is the union of iconv UTF-8
* modules and character sets registered with IANA.
*/
switch (v1_charset) {
case 4:
case 1004:
break;
case 5:
break;
case 6:
break;
case 7:
break;
case 8:
break;
case 9:
break;
case 10:
break;
case 11:
break;
case 12:
break;
case 13:
break;
case 37:
break;
case 104:
break;
case 1000:
break;
case 1001:
break;
default:
/*
* charset not set, or reserved, or not supported, so
* just copy it and hope for the best.
*/
return (1);
}
return (0);
}
== (size_t)-1) {
return (0);
}
return (1);
}
int length;
get_short();
if (netval < 0) {
return (-1);
}
/* special case for NA field in SrvTypeRqst */
return (0);
}
/* framing error: message is not long enough to contain data */
" [Framing error: remaining pkt length = %u]",
return (-1);
}
if (length > 0) {
if (v1_charset) {
}
} else {
}
switch (type) {
case FIELD_PREVRESP:
break;
default:
break;
}
}
p += length;
}
/* return ok */
return (0);
}
/* reserved */
get_byte();
if (netval < 0)
return (-1);
/* lifetime */
get_short();
return (-1);
/* length */
get_short();
return (-1);
/* time */
if (cnt == -1)
"URL: length = %u, lifetime = %d (%24.24s)",
else
/* number the URLs to make it easier to parse them */
"URL %d: length = %u, lifetime = %d (%24.24s)",
if (!tcp_continuation)
/* framing error: message is not long enough to contain data */
" [Framing error: remaining pkt length = %u]",
return (-1);
}
if (length > 0) {
}
}
p += length;
get_byte();
if ((n = netval) < 0)
return (-1);
if (n > 0) {
int i;
for (i = 0; i < n; i++)
if ((length = slpv2_authblock(i)) < 0)
return (-1);
}
return (0);
}
return (0)
#define V2_DOURL(x) \
if (slpv2_url(x) < 0) \
return (0)
#define V2_DOERRCODE \
if (msglength < sizeof (unsigned short)) \
return (0); \
nbtohs(); \
p += sizeof (unsigned short); \
msglength -= sizeof (unsigned short); \
msglength = 0; /* skip rest of message */ \
return (0)
if (slpv2_authblock(cnt) < 0) \
return (0)
#define V2_DOTIMESTAMP \
if (msglength < 4) \
return (0); \
nbtohl(); \
p += 4; \
msglength -= 4
/* some V1 macros */
return (0)
#define DOERRCODE \
if (msglength < sizeof (unsigned short)) \
return (0); \
nbtohs(); \
slpv1_error(errcode)); \
p += sizeof (unsigned short); \
msglength -= sizeof (unsigned short); \
return (0)
#define DOURL \
return (0)
if (auth && slpv1_authblock() < 0) \
return (0)
/*
* TCP Continuation handling
* We keep track of continuations in a fixed size cache, so as to prevent
* memory leaks if some continuations are never finished. The continuations
* are indexed by their destination ports.
*/
/* always overwrite the entry at current_tcp_cont */
if (tcp_cont[current_tcp_cont]) {
}
if (current_tcp_cont == MAX_TCPCONT)
current_tcp_cont = 0;
}
/* returns 0 if there is a mismatch error, 1 on success */
return (0);
return (1);
}
int i;
for (i = current_tcp_cont; i >= 0; i--)
return (tcp_cont[i]);
return (tcp_cont[i]);
return (NULL);
}
static void remove_tcp_cont(int dst_port) {
int i;
for (i = current_tcp_cont; i >= 0; i--)
return;
}
return;
}
}
/*
* V2 interpreter
*/
char msgbuf_real[256];
int totallen = 0;
/*
* Somewhat of a hack to decode traffic from a server that does
* not send udp replies from its SLP src port.
*/
if (curr_proto == IPPROTO_UDP &&
dst_port == 427 &&
src_port != 427) {
}
/* parse the header */
/* Parse the message body */
/* finish any remaining tasks */
}
}
}
/* summary error check */
if (retlength < 0) {
if (curr_proto == IPPROTO_TCP)
"%s [partial TCP message]", msgbuf);
else if (overflow)
else
}
#ifdef VERIFYSLP
else if (msglength > 0)
#endif
else
/* detailed error check */
if (msglength > 0) {
if (tcp_continuation) {
"[TCP Continuation, %d bytes remaining]",
} else
"[%d extra bytes at end of SLP message]", msglength);
}
show_trailer();
if (tcp_continuation && msglength == 0)
}
return (0);
}
int *totallen,
int fraglen) {
extern int curr_proto, dst_port;
/* summary mode header parsing */
/* make sure we have at least a header */
return (0);
}
/* skip to end of header */
p += sizeof (*slp);
/* skip language tag */
char *lang;
int len;
/* detailed mode header parsing */
show_space();
return (0);
}
/* check for TCP continuation */
if (curr_proto == IPPROTO_TCP &&
!tcp_continuation) {
}
" (Stated and on-the-wire lengths differ)");
}
/* flags */
"overflow", "no overflow"));
"fresh registration", "no fresh registration"));
"request multicast / broadcast", "unicast"));
/* check reserved flags that must be zero */
" .... .xxx = %d (reserved flags nonzero)",
}
/* end of flags */
/* language tag */
"Language Tag Length = %u [CORRUPT MESSAGE]",
len);
return (0);
}
/* set msglength to remaining length of SLP message */
p += len;
}
return (1);
}
unsigned int firstop;
return (1);
/* check for options */
if (firstop) {
unsigned short op_id;
unsigned short nextop;
char *op_class;
for (;;) {
unsigned short real_oplen;
if (msglength < 4) {
"Option expected but not present");
return (0);
}
nbtohs();
p += sizeof (unsigned short);
msglength -= sizeof (unsigned short);
nbtohs();
p += sizeof (unsigned short);
msglength -= sizeof (unsigned short);
/* known options */
switch (op_id) {
case 1:
"Option: Required Attribute Missing");
break;
default:
p += (real_oplen - 4);
break;
}
if (op_id < 0x3fff)
op_class = "Standardized, optional";
else if (op_id < 0x7fff)
op_class = "Standardized, mandatory";
else if (op_id < 0x8fff)
op_class = "Not standardized, private";
else if (op_id < 0xffff)
op_class = "Reserved";
if (nextop &&
!tcp_continuation) {
"[Framing error: remaining pkt length = %u]",
return (0);
}
if (!nextop)
break;
}
}
return (1);
}
#ifdef VERIFYSLP
static int skip_v2authblock() {
/* auth header */
if (msglength < 10)
return (-1);
/* block descriptor: 2 bytes */
p += sizeof (unsigned short);
/* length */
nbtohs();
p += sizeof (unsigned short);
/* timestamp */
p += 4;
/* SPI String length */
nbtohs();
p += sizeof (unsigned short);
msglength -= 10;
return (-1);
p += slen;
/* structured auth block */
return (0);
}
#endif
static char *display_bsd(unsigned short bsd) {
switch (bsd) {
case 1: return ("MD5 with RSA");
case 2: return ("DSA with SHA-1");
case 3: return ("Keyed HMAC with MD5");
default: return ("Unknown BSD");
}
}
static char *slpv2_func(int t, boolean_t s) {
static char buf[128];
switch (t) {
case V2_SRVDEREG:
return (s ? "SrvDereg" : "Service Deregistration");
case V2_SRVTYPERQST:
return (s ? "SrvTypeRqst" : "Service Type Request");
case V2_SRVTYPERPLY:
return (s ? "SrvTypeRply" : "Service Type Reply");
}
return (s ? buf : "unknown function");
}
static char *slpv2_error(unsigned short code) {
static char buf[128];
switch (code) {
case OK: return "ok";
case LANG_NOT_SUPPORTED: return "language not supported";
case PROTOCOL_PARSE_ERR: return "protocol parse error";
case INVALID_REGISTRATION: return "invalid registration";
case SCOPE_NOT_SUPPORTED: return "scope not supported";
case AUTHENTICATION_UNKNOWN: return "authentication unknown";
case V2_AUTHENTICATION_ABSENT: return "authentication absent";
case V2_AUTHENTICATION_FAILED: return "authentication failed";
case V2_VER_NOT_SUPPORTED: return "version not supported";
case V2_INTERNAL_ERROR: return "internal error";
case V2_DA_BUSY_NOW: return "DA busy";
case V2_OPTION_NOT_UNDERSTOOD: return "option not understood";
case V2_INVALID_UPDATE: return "invalid update";
case V2_RQST_NOT_SUPPORTED: return "request not supported";
case INVALID_LIFETIME: return "invalid lifetime";
}
return (buf);
}
static char *convert_ts(unsigned int timestamp) {
/* timestamp is in UNIX time */
static char buff[128];
return (buff);
}
static int slpv2_authblock(int cnt) {
unsigned int timestamp;
if (msglength < 10) {
" [no room for auth block header: remaining msg length = %u]",
return (-1);
}
/* bsd */
nbtohs();
p += sizeof (unsigned short);
/* length */
nbtohs();
p += sizeof (unsigned short);
/* timestamp */
nbtohl();
p += 4;
/* SPI String length */
nbtohs();
p += sizeof (unsigned short);
msglength -= 10;
" [no room for auth block scopes: remaining msg length = %u]",
return (-1);
}
if (!tcp_continuation)
/* framing error: message is not long enough to contain data */
" [Framing error: remaining pkt length = %u]",
return (-1);
}
scopes = p;
p += slen;
"Auth block %d: timestamp = %s", cnt,
return (0);
}
static int v2_srv_rqst(int flags) {
GETFIELD; /* service type */
GETFIELD; /* predicate */
}
return (1);
}
static int v2_srv_rply(int flags) {
int n;
int i, auth_cnt;
msglength = 0; /* skip rest of message */
return (0);
} else {
#ifdef VERIFYSLP
for (n = 0; n < itemcnt; n++) {
SKIPBYTE; /* reserved */
SKIPSHORT; /* lifetime */
if (skip_v2authblock() < 0)
return (0);
}
#endif
}
for (n = 0; n < itemcnt; n++) {
V2_DOURL(n);
}
}
return (1);
}
static int v2_srv_reg(int flags) {
int i, auth_cnt;
SKIPBYTE; /* reserved */
SKIPSHORT; /* lifetime */
GETFIELD; /* URL */
#ifdef VERIFYSLP
for (i = 0; i < auth_cnt; i++)
if (skip_v2authblock() < 0)
return (0);
for (i = 0; i < auth_cnt; i++)
if (skip_v2authblock() < 0)
return (0);
#endif
V2_DOURL(-1);
/* auth */
for (i = 0; i < auth_cnt; i++)
V2_DOAUTH(i);
}
return (1);
}
static int v2_srv_dereg(int flags) {
int i, auth_cnt;
SKIPBYTE; /* reserved */
SKIPSHORT; /* lifetime */
GETFIELD; /* URL */
#ifdef VERIFYSLP
for (i = 0; i < auth_cnt; i++)
if (skip_v2authblock() < 0)
return (0);
#endif
V2_DOURL(-1);
}
return (1);
}
static int v2_srv_ack(int flags) {
unsigned short errcode;
}
return (1);
}
static int v2_attr_rqst(int flags) {
GETFIELD; /* URL */
GETFIELD; /* attrs */
#ifdef VERIFYSLP
#endif
}
return (1);
}
static int v2_attr_rply(int flags) {
int auth_cnt, i;
unsigned short errcode;
msglength = 0; /* skip rest of message */
return (0);
} else {
GETFIELD; /* attr list */
#ifdef VERIFYSLP
for (i = 0; i < auth_cnt; i++)
if (skip_v2authblock() < 0)
return (0);
#endif
}
/* auth */
for (i = 0; i < auth_cnt; i++)
V2_DOAUTH(i);
}
return (1);
}
static int v2_daadvert(int flags) {
int auth_cnt, i;
unsigned short errcode;
unsigned int timestamp;
SKIPSHORT; /* error code */
GETFIELD; /* URL */
#ifdef VERIFYSLP
for (i = 0; i < auth_cnt; i++)
if (skip_v2authblock() < 0)
return (0);
#endif
/* auth */
for (i = 0; i < auth_cnt; i++)
V2_DOAUTH(i);
}
return (1);
}
static int v2_srv_type_rqst(int flags) {
GETFIELD; /* scope */
}
return (1);
}
static int v2_srv_type_rply(int flags) {
unsigned short errcode;
else
}
return (1);
}
static int v2_saadvert(int flags) {
int auth_cnt, i;
GETFIELD; /* URL */
#ifdef VERIFYSLP
for (i = 0; i < auth_cnt; i++)
if (skip_v2authblock() < 0)
return (0);
#endif
/* auth */
for (i = 0; i < auth_cnt; i++)
V2_DOAUTH(i);
}
return (1);
}
/*
* V1 Interpreter
*/
char msgbuf_real[256];
}
/*
* Somewhat of a hack to decode traffic from a server that does
* not send udp replies from its SLP src port.
*/
if (curr_proto == IPPROTO_UDP &&
dst_port == 427 &&
src_port != 427)
/* parse the header */
/* Parse the message body */
}
}
/* summary error check */
if (retlength < 0) {
if (curr_proto == IPPROTO_TCP)
"%s [partial TCP message]",
msgbuf);
else if (overflow)
else
}
#ifdef VERIFYSLP
else if (msglength > 0)
#endif
else
/* detail error check */
if (msglength > 0) {
"[%d extra bytes at end of SLP message]", msglength);
}
show_trailer();
}
v1_charset = 0;
return (0);
}
int fraglen) {
char portflag = ' ';
return (0);
}
if (curr_proto == IPPROTO_TCP)
else
return (0);
}
portflag = '-';
p += sizeof (*slp);
show_space();
return (0);
}
if (curr_proto == IPPROTO_TCP)
else
return (0);
}
/* flags */
"overflow", "no overflow"));
"monolingual", "not monolingual"));
"url authentication", "no url authentication"));
"attribute authentication", "no attribute authentication"));
"fresh registration", "no fresh registration"));
/* check reserved flags that must be zero */
" .... .xxx = %d (reserved flags nonzero)",
}
/* end of flags */
/* set msglength to remaining length of SLP message */
p += sizeof (*slp);
}
return (1);
}
static char *slpv1_func(int t, boolean_t s) {
static char buf[128];
switch (t) {
case V1_SRVDEREG: return s?
"SrvDereg" : "Service Deregistration";
}
return (s ? buf : "unknown function");
}
static char *slpv1_error(unsigned short code) {
static char buf[128];
switch (code) {
case OK: return "ok";
case LANG_NOT_SUPPORTED: return "language not supported";
case PROTOCOL_PARSE_ERR: return "protocol parse error";
case INVALID_REGISTRATION: return "invalid registration";
case SCOPE_NOT_SUPPORTED: return "scope not supported";
case CHARSET_NOT_UNDERSTOOD:return "character set not understood";
case AUTHENTICATION_INVALID:return "invalid authentication";
case NOT_SUPPORTED_YET: return "not yet supported";
case REQUEST_TIMED_OUT: return "request timed out";
return ("could not initialize net resources");
return ("could not allocate memory");
case PARAMETER_BAD: return "bad parameter";
case INTERNAL_NET_ERROR: return "internal network error";
case INTERNAL_SYSTEM_ERROR: return "internal system error";
}
return (buf);
}
/*
* Character set info from
*
* Assigned MIB enum Numbers
* -------------------------
* 0 Reserved
* 1 Reserved
* 3-106 Set By Standards Organizations
* 1000-1010 Unicode / 10646
* 2000-2087 Vendor
* 2250-2258 Vendor
*
* MIBenum: 3
* Alias: US-ASCII (preferred MIME name)
* Source: ECMA registry [RFC1345]
*
* MIBenum: 106
* Name: UTF-8
* Source: RFC 2044
*/
static char *slpv1_charset(unsigned short code) {
if (code <= 1)
return ("Reserved");
if (code == 3)
return ("US-ASCII");
if (code == 4)
return ("latin1");
if (code == 106)
return ("UTF-8");
return ("set by standards organization");
return ("Unicode variant");
return ("Vendor assigned");
return ("unknown");
}
#ifdef VERIFYSLP
static int skip_v1authblock() {
unsigned short length;
/* auth header: 12 bytes total */
if (msglength < 12)
return (-1);
/* timestamp: 8 bytes */
p += 8; /* timestamp: 8 bytes */
p += sizeof (short); /* block descriptor: 2 bytes */
nbtohs();
p += sizeof (short);
msglength -= 12;
/* framing error: message is not long enough to contain data */
return (-1);
}
p += length;
return (0);
}
#endif
static int slpv1_authblock() {
char msgbuf[128];
int n;
if (msglength < 12) {
" [no room for auth block: remaining msg length = %u]",
return (-1);
}
/* timestamp: 8 bytes */
*msgbuf = '\0';
for (n = 0; n < 8; n++, p += 1) {
char tmp[16];
}
nbtohs();
p += sizeof (short);
nbtohs();
p += sizeof (short);
msglength -= 12;
" Auth block: timestamp = %s",
msgbuf);
" block desc = 0x%04x, length = %u",
/* framing error: message is not long enough to contain data */
" [Framing error: remaining pkt length = %u]", msglength);
return (-1);
}
p += length;
return (0);
}
get_short();
return (-1);
get_short();
return (-1);
/* framing error: message is not long enough to contain data */
" [Framing error: remaining pkt length = %u]", msglength);
return (-1);
}
if (length > 0) {
}
}
}
p += length;
if (auth_present)
return (slpv1_authblock());
return (0);
}
static int v1_srv_rqst(int flags) {
GETFIELD; /* predicate */
}
return (1);
}
static int v1_srv_rply(int flags) {
int n;
} else {
#ifdef VERIFYSLP
for (n = 0; n < itemcnt; n++) {
SKIPSHORT; /* lifetime */
}
#endif
}
for (n = 0; n < itemcnt; n++) {
}
}
return (1);
}
static int v1_srv_reg(int flags) {
SKIPSHORT; /* lifetime */
GETFIELD; /* URL */
#ifdef VERIFYSLP
#endif
}
return (1);
}
static int v1_srv_ack(int flags) {
unsigned short errcode;
}
}
return (1);
}
static int v1_srv_dereg(int flags) {
GETFIELD; /* URL */
#ifdef VERIFYSLP
#endif
}
return (1);
}
static int v1_attr_rqst(int flags) {
GETFIELD; /* URL */
#ifdef VERIFYSLP
#endif
}
return (1);
}
static int v1_attr_rply(int flags) {
unsigned short errcode;
} else {
GETFIELD; /* attr list */
#ifdef VERIFYSLP
#endif
}
}
return (1);
}
static int v1_daadvert(int flags) {
unsigned short errcode;
} else {
GETFIELD; /* URL */
#ifdef VERIFYSLP
#endif
}
}
return (1);
}
static int v1_srv_type_rqst(int flags) {
GETFIELD; /* scope */
}
return (1);
}
static int v1_srv_type_rply(int flags) {
int n;
} else {
#ifdef VERIFYSLP
for (n = 0; n < itemcnt; n++) {
}
#endif
}
for (n = 0; n < itemcnt; n++) {
}
}
return (1);
}