Files
Arquivotheca.Solaris-2.5/uts/common/io/dedump.c
seta75D 7c4988eac0 Init
2021-10-11 19:38:01 -03:00

315 lines
5.8 KiB
C
Executable File

#ident "@(#)dedump.c 1.14 94/03/31 SMI" /* SVr3.2H */
/*
* Dump streams module. Could be used anywhere on the stream to
* print all message headers and data on to the console or logged
* by using the log(7) driver.
*/
#include <sys/types.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/signal.h>
#include <sys/user.h>
#include <sys/stream.h>
#include <sys/stropts.h>
#include <sys/conf.h>
#include <sys/errno.h>
#include <sys/dedump.h>
#include <sys/cmn_err.h>
#include <sys/ddi.h>
/*
* This is the loadable module wrapper.
*/
#include <sys/modctl.h>
extern struct streamtab dedumpinfo;
static struct fmodsw fsw = {
"dedump",
&dedumpinfo,
D_NEW
};
/*
* Module linkage information for the kernel.
*/
extern struct mod_ops mod_strmodops;
static struct modlstrmod modlstrmod = {
&mod_strmodops, "dump streams module", &fsw
};
static struct modlinkage modlinkage = {
MODREV_1, (void *)&modlstrmod, NULL
};
int
_init(void)
{
return (mod_install(&modlinkage));
}
int
_fini(void)
{
return (mod_remove(&modlinkage));
}
int
_info(struct modinfo *modinfop)
{
return (mod_info(&modlinkage, modinfop));
}
char contents[64];
unsigned char
message_code[MESSAGE_NUM] = {
M_DATA, M_PROTO, M_BREAK, M_PASSFP,
M_SIG, M_DELAY, M_CTL, M_IOCTL,
M_SETOPTS, M_RSE, M_IOCACK, M_IOCNAK,
M_PCPROTO, M_PCSIG, M_READ, M_FLUSH,
M_STOP, M_START, M_HANGUP, M_ERROR,
M_COPYIN, M_COPYOUT, M_IOCDATA, M_PCRSE,
M_STARTI, M_STOPI, M_UNHANGUP
};
char *
message_name[MESSAGE_NUM] = {
"M_DATA", "M_PROTO", "M_BREAK", "M_PASSFP",
"M_SIG", "M_DELAY", "M_CTL", "M_IOCTL",
"M_SETOPTS", "M_RSE", "M_IOCACK", "M_IOCNAK",
"M_PCPROTO", "M_PCSIG", "M_READ", "M_FLUSH",
"M_STOP", "M_START", "M_HANGUP", "M_ERROR",
"M_COPYIN", "M_COPYOUT", "M_IOCDATA", "M_PCRSE",
"M_STARTI", "M_STOPI", "M_UNHANGUP"
};
int
message_size[MESSAGE_NUM] = {
NULL, NULL, NULL, NULL,
CHAR, INT, NULL, IOC_SIZE,
OPT_SIZE, NULL, IOC_SIZE, IOC_SIZE,
NULL, CHAR, LONG, CHAR,
NULL, NULL, NULL, CHAR,
REQ_SIZE, REQ_SIZE, REP_SIZE, NULL,
NULL, NULL, NULL
};
static int dedumpopen(queue_t *q, dev_t *devp, int oflag, int sflag,
cred_t *crp);
static int dedumpput(queue_t *q, mblk_t *mp);
static int dedumpclose(queue_t *q, int flag, cred_t *crp);
static void prt_message(queue_t *q, mblk_t *mp);
struct module_info dedumpmiinfo = {
0xaaa,
"dedump",
0,
INFPSZ,
(unsigned long)INFPSZ,
(unsigned long)INFPSZ
};
struct module_info dedumpmoinfo = {
0xaaa,
"dedump",
0,
INFPSZ,
(unsigned long)INFPSZ,
(unsigned long)INFPSZ
};
struct qinit dedumprinit = {
dedumpput,
NULL,
dedumpopen,
dedumpclose,
NULL,
&dedumpmiinfo,
NULL
};
struct qinit dedumpwinit = {
dedumpput,
NULL,
NULL,
NULL,
NULL,
&dedumpmoinfo,
NULL
};
struct streamtab dedumpinfo = {
&dedumprinit,
&dedumpwinit,
NULL,
NULL,
};
int ddbg;
#define d1printf if (ddbg >= 1) printf
#define d2printf if (ddbg >= 2) printf
#define d3printf if (ddbg >= 3) printf
extern struct dmp *dump;
extern int dump_cnt;
/*
* /dev/dump open
*/
/*ARGSUSED1*/
static int
dedumpopen(queue_t *q, dev_t *devp, int oflag, int sflag,
cred_t *crp)
{
struct dmp *dp;
short i;
d3printf("open routine called\n");
printf("dump: in dumpopen routine\n");
if (!sflag) {
printf("Non module open");
return (ENXIO);
}
if (q->q_ptr) {
return (0); /* already attached */
}
for (dp = dump, i = 0; dp->dump_flags & DUMP_IN_USE; dp++, i++)
if (dp >= &dump[dump_cnt-1]) {
printf("dump: No dump structures\n");
ttolwp(curthread)->lwp_error = ENOSPC;
return (ENOSPC);
}
dp->dump_flags = DUMP_IN_USE;
dp->dump_no = i;
dp->dump_wq = WR(q);
dp->dump_flags = PRT_TO_CONSOLE; /* default is print to console */
q->q_ptr = (caddr_t) dp;
WR(q)->q_ptr = (caddr_t) dp;
return (0);
}
/*ARGSUSED1*/
static int
dedumpclose(queue_t *q, int flag, cred_t *crp)
{
struct dmp *dp;
d3printf("close routine called\n");
dp = (struct dmp *)q->q_ptr;
dp->dump_flags = dp->dump_no = 0;
dp->dump_wq = NULL;
q->q_ptr = WR(q)->q_ptr = NULL;
return (0);
}
/*
* dump put procedure.
* Common for upstream and downstream
*/
static int
dedumpput(queue_t *q, mblk_t *mp)
{
struct dmp *dp;
struct iocblk *iocp;
d3printf("put routine called\n");
dp = (struct dmp *)q->q_ptr;
switch (mp->b_datap->db_type) {
case M_IOCTL:
iocp = (struct iocblk *)mp->b_rptr;
switch (iocp->ioc_cmd) {
case SET_OPTIONS:
dp->dump_flags =
*(short *)mp->b_cont->b_rptr;
d3printf("wput: flags %o\n",
dp->dump_flags);
mp->b_datap->db_type = M_IOCACK;
qreply(q, mp);
return (0);
default:
prt_message(q, mp);
putnext(q, mp);
return (0);
}
default:
prt_message(q, mp);
putnext(q, mp);
return (0);
}
}
static void
prt_message(queue_t *q, mblk_t *mp)
{
struct dmp *dp;
short index, i;
unsigned char type, direction, mod, div;
dp = (struct dmp *)q->q_ptr;
type = mp->b_datap->db_type;
direction = (q->q_flag & QREADR)? READ : WRITE;
/* find the index into message code array */
for (index = 0; index < MESSAGE_NUM; index++) {
if (type == message_code[index]) {
if (message_size[index] != NULL)
bcopy((caddr_t)mp->b_rptr, contents,
(uint)message_size[index]);
if (dp->dump_flags & PRT_TO_CONSOLE) {
printf("MID 0x%x SID %d %s %s",
q->q_qinfo->qi_minfo->mi_idnum,
dp->dump_no, message_name[index],
(direction) ? "DOWN ":"UP ");
if (message_size[index] != NULL) {
for (i = 0; i < message_size[index];
i++) {
if (contents[i] == 0)
printf("00");
else {
mod = contents[i] / 16;
div = contents[i] -
16 * mod;
printf("%x%x", mod,
div);
}
}
}
printf("\n");
}
#ifdef notneeded
if (dp->dump_flags & PRT_TO_LOG)
(void) strlog(q->q_qinfo->qi_minfo->mi_idnum,
dp->dump_no, 1, SL_TRACE,
"D %d %d %s\n", type, direction,
contents);
#endif
return;
}
}
}