#include <sys/types.h>
#include <sys/errno.h>
#include <setjmp.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <sys/tiuser.h>
#include <net/if.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <rpc/types.h>
#include <rpc/xdr.h>
#include <rpc/auth.h>
#include <rpc/clnt.h>
#include <rpc/rpc_msg.h>
#include <rpcsvc/yp_prot.h>
#include "snoop.h"
extern char *dlc_header;
extern jmp_buf xdr_err;
char *ypbind_error();
char *sum_ypxfrstat();
char *sum_ypmaplist();
void detail_ypmaplist();
static void niscall(int);
static void nisreply(int);
static int detail_ypstat(void);
static int sum_ypstat(char *);
#define YPBINDPROG ((ulong_t)100007)
#define YPBINDVERS ((ulong_t)2)
#define YPBINDVERS_ORIG ((ulong_t)1)
#define YPBINDPROC_NULL ((ulong_t)0)
#define YPBINDPROC_DOMAIN ((ulong_t)1)
#define YPBINDPROC_SETDOM ((ulong_t)2)
#define YPBIND_ERR_ERR 1
#define YPBIND_ERR_NOSERV 2
#define YPBIND_ERR_RESC 3
static char *procnames_bind_short[] = {
"NULL",
"DOMAIN",
"SETDOMAIN",
};
static char *procnames_bind_long[] = {
"Null procedure",
"Get domain name",
"Set domain name",
};
static char *procnames_short[] = {
"NULL",
"DOMAIN",
"DOMAIN_NONACK",
"MATCH",
"FIRST",
"NEXT",
"XFR",
"CLEAR",
"ALL",
"MASTER",
"ORDER",
"MAPLIST",
"NEWXFR",
};
#define MAXPROC_BIND 2
#define MAXPROC 12
static char *procnames_long[] = {
"Null procedure",
"Verify domain support",
"Verify domain support (broadcast)",
"Return value of a key",
"Return first key-value pair in map",
"Return next key-value pair in map",
"Request map update (old)",
"Close current map on server",
"Get all key-value pairs in map",
"Get master server",
"Get order",
"Return list of supported maps",
"Request map update",
};
void
interpret_nisbind(int flags, int type, int xid, int vers, int proc, char *data,
int len)
{
char *line;
char buff[YPMAXDOMAIN + 1];
unsigned int status;
if (proc < 0 || proc > MAXPROC_BIND)
return;
if (flags & F_SUM) {
if (setjmp(xdr_err)) {
return;
}
line = get_sum_line();
if (type == CALL) {
(void) sprintf(line, "NISBIND C %s",
procnames_bind_short[proc]);
line += strlen(line);
switch (proc) {
case YPBINDPROC_NULL:
break;
case YPBINDPROC_DOMAIN:
(void) sprintf(line, " %s",
getxdr_string(buff, YPMAXDOMAIN));
break;
case YPBINDPROC_SETDOM:
(void) sprintf(line, " %s",
getxdr_string(buff, YPMAXDOMAIN));
break;
default:
break;
}
check_retransmit(line, xid);
} else {
(void) sprintf(line, "NISBIND R %s ",
procnames_bind_short[proc]);
line += strlen(line);
switch (proc) {
case YPBINDPROC_NULL:
break;
case YPBINDPROC_DOMAIN:
status = getxdr_long();
if (status == 1) {
(void) strcat(line, "OK");
} else {
status = getxdr_long();
(void) sprintf(line, "ERROR=%s",
ypbind_error(status));
}
break;
case YPBINDPROC_SETDOM:
break;
default:
break;
}
}
}
if (flags & F_DTAIL) {
show_header("NISBIND:",
"Network Information Service Bind", len);
show_space();
if (setjmp(xdr_err)) {
return;
}
(void) sprintf(get_line(0, 0), "Proc = %d (%s)",
proc, procnames_bind_long[proc]);
if (type == CALL) {
switch (proc) {
case YPBINDPROC_NULL:
break;
case YPBINDPROC_DOMAIN:
(void) showxdr_string(YPMAXDOMAIN,
"Domain = %s");
break;
case YPBINDPROC_SETDOM:
(void) showxdr_string(YPMAXDOMAIN,
"Domain = %s");
(void) showxdr_hex(4, "Address=%s");
(void) showxdr_hex(2, "Port=%s");
(void) showxdr_u_long("Version=%lu");
break;
default:
break;
}
} else {
switch (proc) {
case YPBINDPROC_NULL:
break;
case YPBINDPROC_DOMAIN:
status = getxdr_u_long();
(void) sprintf(get_line(0, 0),
"Status = %lu (%s)",
status,
status == 1 ? "OK":"Fail");
if (status == 1) {
(void) showxdr_hex(4, "Address=%s");
(void) showxdr_hex(2, "Port=%s");
} else {
status = getxdr_u_long();
(void) sprintf(get_line(0, 0),
"Error = %lu (%s)", status,
ypbind_error(status));
}
break;
case YPBINDPROC_SETDOM:
break;
default:
break;
}
}
show_trailer();
}
}
void
interpret_nis(int flags, int type, int xid, int vers, int proc, char *data,
int len)
{
char *line;
char *dom, *map, *key;
int transid, status;
char buff1[YPMAXRECORD + 1], buff2[YPMAXRECORD + 1];
char buff3[YPMAXRECORD + 1];
if (flags & F_SUM) {
if (setjmp(xdr_err)) {
return;
}
line = get_sum_line();
if (type == CALL) {
if (proc > MAXPROC)
(void) sprintf(line, "NIS C %d", proc);
else
(void) sprintf(line, "NIS C %s",
procnames_short[proc]);
line += strlen(line);
switch (proc) {
case YPPROC_NULL:
break;
case YPPROC_DOMAIN:
case YPPROC_DOMAIN_NONACK:
case YPPROC_MAPLIST:
(void) sprintf(line, " %s",
getxdr_string(buff1, YPMAXDOMAIN));
break;
case YPPROC_FIRST:
dom = getxdr_string(buff1, YPMAXDOMAIN);
map = getxdr_string(buff2, YPMAXMAP);
(void) sprintf(line, " %s", map);
break;
case YPPROC_MATCH:
case YPPROC_NEXT:
dom = getxdr_string(buff1, YPMAXDOMAIN);
map = getxdr_string(buff2, YPMAXMAP);
key = getxdr_string(buff3, YPMAXRECORD);
(void) sprintf(line, " %s in %s", key, map);
break;
case YPPROC_NEWXFR:
case YPPROC_XFR:
dom = getxdr_string(buff1, YPMAXDOMAIN);
map = getxdr_string(buff2, YPMAXMAP);
(void) sprintf(line, " map %s in %s", map, dom);
break;
case YPPROC_CLEAR:
break;
case YPPROC_ALL:
case YPPROC_MASTER:
case YPPROC_ORDER:
dom = getxdr_string(buff1, YPMAXDOMAIN);
map = getxdr_string(buff2, YPMAXMAP);
(void) sprintf(line, " map %s in %s", map, dom);
break;
default:
break;
}
check_retransmit(line, xid);
} else {
if (proc > MAXPROC)
(void) sprintf(line, "NIS R %d ", proc);
else
(void) sprintf(line, "NIS R %s ",
procnames_short[proc]);
line += strlen(line);
switch (proc) {
case YPPROC_NULL:
break;
case YPPROC_DOMAIN:
case YPPROC_DOMAIN_NONACK:
(void) sprintf(line, "%s",
getxdr_long() ? "OK":"Fail");
break;
case YPPROC_MATCH:
(void) sum_ypstat(line);
break;
case YPPROC_FIRST:
case YPPROC_NEXT:
if (sum_ypstat(line) == YP_TRUE) {
line += strlen(line);
(void) getxdr_string(buff1,
YPMAXRECORD);
(void) sprintf(line, " key=%s",
getxdr_string(buff1,
YPMAXRECORD));
}
break;
case YPPROC_NEWXFR:
case YPPROC_XFR:
transid = getxdr_u_long();
status = getxdr_long();
(void) sprintf(line, "transid=%lu %s", transid,
sum_ypxfrstat(status));
break;
case YPPROC_CLEAR:
break;
case YPPROC_ALL:
if (getxdr_u_long()) {
(void) sum_ypstat(line);
line += strlen(line);
(void) sprintf(line, " key=%s",
getxdr_string(buff1, YPMAXRECORD));
} else {
(void) sprintf(line, "No more");
}
break;
case YPPROC_MASTER:
if (sum_ypstat(line) == YP_TRUE) {
line += strlen(line);
(void) sprintf(line, " peer=%s",
getxdr_string(buff1, YPMAXPEER));
}
break;
case YPPROC_ORDER:
if (sum_ypstat(line) == YP_TRUE) {
line += strlen(line);
(void) sprintf(line, " order=%lu",
getxdr_u_long());
}
break;
case YPPROC_MAPLIST:
if (sum_ypstat(line) == YP_TRUE) {
line += strlen(line);
(void) sprintf(line, " %s",
sum_ypmaplist());
}
break;
default:
break;
}
}
}
if (flags & F_DTAIL) {
show_header("NIS: ", "Network Information Service", len);
show_space();
if (setjmp(xdr_err)) {
return;
}
(void) sprintf(get_line(0, 0), "Proc = %d (%s)", proc,
proc > MAXPROC ? "unknown" : procnames_long[proc]);
if (type == CALL)
niscall(proc);
else
nisreply(proc);
show_trailer();
}
}
static void
niscall(int proc)
{
switch (proc) {
case YPPROC_NULL:
break;
case YPPROC_DOMAIN:
case YPPROC_DOMAIN_NONACK:
case YPPROC_MAPLIST:
(void) showxdr_string(YPMAXDOMAIN, "Domain = %s");
break;
case YPPROC_FIRST:
(void) showxdr_string(YPMAXDOMAIN, "Domain = %s");
(void) showxdr_string(YPMAXMAP, "Map = %s");
break;
case YPPROC_MATCH:
case YPPROC_NEXT:
(void) showxdr_string(YPMAXDOMAIN, "Domain = %s");
(void) showxdr_string(YPMAXMAP, "Map = %s");
(void) showxdr_string(YPMAXRECORD, "Key = %s");
break;
case YPPROC_NEWXFR:
(void) showxdr_string(YPMAXDOMAIN, "Domain = %s");
(void) showxdr_string(YPMAXMAP, "Map = %s");
(void) showxdr_u_long("Order = %lu");
(void) showxdr_string(YPMAXPEER, "Peer = %s");
(void) showxdr_u_long("Transid = %lu");
(void) showxdr_u_long("Prog = %lu");
(void) showxdr_string(YPMAXPEER, "Name = %s");
break;
case YPPROC_XFR:
(void) showxdr_string(YPMAXDOMAIN, "Domain = %s");
(void) showxdr_string(YPMAXMAP, "Map = %s");
(void) showxdr_u_long("Order = %lu");
(void) showxdr_string(YPMAXPEER, "Peer = %s");
(void) showxdr_u_long("Transid = %lu");
(void) showxdr_u_long("Prog = %lu");
(void) showxdr_u_long("Port = %lu");
break;
case YPPROC_CLEAR:
break;
case YPPROC_ALL:
case YPPROC_MASTER:
case YPPROC_ORDER:
(void) showxdr_string(YPMAXDOMAIN, "Domain = %s");
(void) showxdr_string(YPMAXMAP, "Map = %s");
break;
default:
break;
}
}
void
nisreply(int proc)
{
unsigned int xfrstat, more;
switch (proc) {
case YPPROC_NULL:
break;
case YPPROC_DOMAIN:
case YPPROC_DOMAIN_NONACK:
(void) sprintf(get_line(0, 0), "Result=%s",
getxdr_u_long() ? "OK":"Fail");
break;
case YPPROC_MATCH:
(void) detail_ypstat();
(void) showxdr_string(YPMAXRECORD, "Value = %s");
break;
case YPPROC_FIRST:
case YPPROC_NEXT:
(void) detail_ypstat();
(void) showxdr_string(YPMAXRECORD, "Value = %s");
(void) showxdr_string(YPMAXRECORD, "Key = %s");
break;
case YPPROC_NEWXFR:
case YPPROC_XFR:
(void) showxdr_u_long("Transid = %lu");
xfrstat = getxdr_u_long();
(void) sprintf(get_line(0, 0), "Transfer status = %lu (%s)",
xfrstat, sum_ypxfrstat(xfrstat));
break;
case YPPROC_CLEAR:
break;
case YPPROC_ALL:
more = getxdr_u_long();
(void) sprintf(get_line(0, 0), "More = %s",
more ? "true" : "false");
if (more) {
(void) detail_ypstat();
(void) showxdr_string(YPMAXRECORD, "Value = %s");
(void) showxdr_string(YPMAXRECORD, "Key = %s");
}
break;
case YPPROC_MASTER:
(void) detail_ypstat();
(void) showxdr_string(YPMAXPEER, "Peer = %s");
break;
case YPPROC_ORDER:
(void) detail_ypstat();
(void) showxdr_u_long("Order=%lu");
break;
case YPPROC_MAPLIST:
(void) detail_ypstat();
detail_ypmaplist();
break;
default:
break;
}
}
char *
sum_ypxfrstat(int status)
{
static char buff [16];
switch (status) {
case 1: return ("Success");
case 2: return ("Master's version not newer");
case -1: return ("Can't find server for map");
case -2: return ("No such domain");
case -3: return ("Resource allocation failure");
case -4: return ("RPC failure talking to server");
case -5: return ("Can't get master address");
case -6: return ("NIS server/map db error");
case -7: return ("Bad arguments");
case -8: return ("Local dbm operation failed");
case -9: return ("Local file I/O operation failed");
case -10: return ("Map version skew during transfer");
case -11: return ("Can't send clear req to local ypserv");
case -12: return ("No local order number in map");
case -13: return ("Transfer error");
case -14: return ("Transfer request refused");
default:
(void) sprintf(buff, "(%d)", status);
return (buff);
}
}
static int
sum_ypstat(char *line)
{
ulong_t status;
char *str;
char buff[16];
status = getxdr_u_long();
switch (status) {
case YP_TRUE: str = "OK"; break;
case YP_NOMORE: str = "No more entries"; break;
case YP_FALSE: str = "Fail"; break;
case YP_NOMAP: str = "No such map"; break;
case YP_NODOM: str = "No such domain"; break;
case YP_NOKEY: str = "No such key"; break;
case YP_BADOP: str = "Invalid operation"; break;
case YP_BADDB: str = "Bad database"; break;
case YP_YPERR: str = "Server error"; break;
case YP_BADARGS:str = "Bad args"; break;
case YP_VERS: str = "Version mismatch"; break;
default: (void) sprintf(buff, "(%lu)", status);
str = buff;
break;
}
(void) strcpy(line, str);
return ((int)status);
}
static int
detail_ypstat(void)
{
ulong_t status;
char buff[32];
status = sum_ypstat(buff);
(void) sprintf(get_line(0, 0), "Status = %d (%s)", status, buff);
return ((int)status);
}
char *
sum_ypmaplist(void)
{
static char buff[YPMAXMAP + 1];
int maps = 0;
if (setjmp(xdr_err)) {
(void) sprintf(buff, "%d+ maps", maps);
return (buff);
}
while (getxdr_long()) {
(void) getxdr_string(buff, YPMAXMAP);
maps++;
}
(void) sprintf(buff, "%d maps", maps);
return (buff);
}
void
detail_ypmaplist(void)
{
int maps = 0;
if (setjmp(xdr_err)) {
(void) sprintf(get_line(0, 0),
" %d+ maps. (Frame is incomplete)", maps);
return;
}
(void) sprintf(get_line(0, 0), "Map list");
while (getxdr_long()) {
(void) showxdr_string(YPMAXMAP, " %s");
maps++;
}
(void) sprintf(get_line(0, 0), "%d maps", maps);
}
char *
ypbind_error(int err)
{
static char buff[16];
switch (err) {
case YPBIND_ERR_ERR: return ("Internal error");
case YPBIND_ERR_NOSERV: return ("Internal error");
case YPBIND_ERR_RESC: return ("Resource allocation fail");
default:
(void) sprintf(buff, "(%d)", err);
return (buff);
}
}