397 lines
7.4 KiB
C
397 lines
7.4 KiB
C
|
|
/* Streams logging module */
|
|
|
|
#include "f_module.h"
|
|
#include "primitives.h"
|
|
#include <sys/time.h>
|
|
#include "f_signal.h"
|
|
#include "f_malloc.h"
|
|
#include <sys/sysmacros.h>
|
|
#include "stropts.h"
|
|
#ifdef DO_ADDUSER
|
|
#include "f_user.h"
|
|
#endif
|
|
#include <sys/errno.h>
|
|
#include "streams.h"
|
|
#include "streamlib.h"
|
|
|
|
#ifdef AUX
|
|
#include <sys/protosw.h>
|
|
#endif
|
|
#include <netinet/in.h>
|
|
#ifndef linux
|
|
#include <netinet/in_systm.h>
|
|
#include <netinet/ip.h>
|
|
#ifdef KERNEL
|
|
#include <linux/sched.h>
|
|
#endif
|
|
#endif
|
|
#include <netinet/tcp.h>
|
|
#include "kernel.h"
|
|
|
|
#define MAXB 100
|
|
|
|
static struct module_info log_minfo =
|
|
{
|
|
0, "strlog", 0, INFPSZ, 0, 0
|
|
};
|
|
static struct module_info xlog_minfo =
|
|
{
|
|
0, "xstrlog", 0, INFPSZ, 0, 0
|
|
};
|
|
|
|
static qf_open log_open;
|
|
static qf_close log_close;
|
|
static qf_put log_wput,log_rput;
|
|
static qf_put xlog_wput,xlog_rput;
|
|
|
|
static struct qinit log_rinit =
|
|
{ log_rput, NULL, log_open, log_close, NULL, &log_minfo, NULL };
|
|
static struct qinit log_winit =
|
|
{ log_wput, NULL, NULL, NULL, NULL, &log_minfo, NULL };
|
|
static struct qinit xlog_rinit =
|
|
{ xlog_rput, NULL, log_open, log_close, NULL, &xlog_minfo, NULL };
|
|
static struct qinit xlog_winit =
|
|
{ xlog_wput, NULL, NULL, NULL, NULL, &xlog_minfo, NULL };
|
|
|
|
struct streamtab strloginfo =
|
|
{&log_rinit, &log_winit, NULL, NULL};
|
|
struct streamtab xstrloginfo =
|
|
{&xlog_rinit, &xlog_winit, NULL, NULL};
|
|
|
|
#include "log.h"
|
|
#include "isdn_limits.h"
|
|
|
|
struct _log {
|
|
char flags;
|
|
char nr;
|
|
};
|
|
|
|
static int
|
|
log_open (queue_t * q, dev_t dev, int flag, int sflag ERR_DECL)
|
|
{
|
|
struct _log *log;
|
|
static int nr = 1;
|
|
|
|
if (q->q_ptr)
|
|
return 0;
|
|
|
|
log = malloc(sizeof(*log));
|
|
if(log == NULL)
|
|
ERR_RETURN(-ENOMEM);
|
|
memset(log,0,sizeof *log);
|
|
WR (q)->q_ptr = (char *) log;
|
|
q->q_ptr = (char *) log;
|
|
|
|
log->flags = LOG_INUSE | LOG_READ | LOG_WRITE;
|
|
log->nr = nr++;
|
|
if (1)
|
|
printf ("%sLog driver %d opened.\n", KERN_DEBUG,log->nr);
|
|
MORE_USE;
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
void
|
|
log_printmsg (void *xlog, const char *text, mblk_t * mp, const char *prefix)
|
|
{
|
|
struct _log *log = (struct _log *)xlog;
|
|
/* int ms = splstr (); */
|
|
static char pprefix[100];
|
|
|
|
if(prefix != NULL) {
|
|
strcpy(pprefix,prefix);
|
|
printf("%s",pprefix);
|
|
} else
|
|
*pprefix = '\0';
|
|
if (log != NULL)
|
|
printf ("Log %d: ", log->nr);
|
|
#if defined(linux) && defined(KERNEL)
|
|
printf("%ld ",jiffies);
|
|
#endif
|
|
if(text != NULL)
|
|
printf ("%s", text);
|
|
{
|
|
mblk_t *mp1;
|
|
char *name;
|
|
int nblocks = 0;
|
|
static mblk_t *blocks[MAXB];
|
|
char nam[20];
|
|
|
|
for (mp1 = mp; mp1 != NULL; mp1 = mp1->b_cont) {
|
|
blocks[nblocks++] = mp1;
|
|
switch (DATA_TYPE(mp1)) {
|
|
case M_DATA:
|
|
name = "DATA";
|
|
break;
|
|
case M_PROTO:
|
|
name = "PROTO";
|
|
break;
|
|
#ifdef M_SPROTO
|
|
case M_SPROTO:
|
|
name = "SPROTO";
|
|
break;
|
|
#endif
|
|
case M_BREAK:
|
|
name = "BREAK";
|
|
break;
|
|
case M_SIG:
|
|
name = "SIG";
|
|
break;
|
|
case M_DELAY:
|
|
name = "DELAY";
|
|
break;
|
|
case M_CTL:
|
|
name = "CTL";
|
|
break;
|
|
case M_IOCTL:
|
|
name = "IOCTL";
|
|
break;
|
|
case M_SETOPTS:
|
|
name = "SETOPTS";
|
|
break;
|
|
#ifdef M_ADMIN
|
|
case M_ADMIN:
|
|
name = "ADMIN";
|
|
break;
|
|
#endif
|
|
#ifdef M_EXPROTO
|
|
case M_EXPROTO:
|
|
name = "EXPROTO";
|
|
break;
|
|
#endif
|
|
#ifdef M_EXDATA
|
|
case M_EXDATA:
|
|
name = "EXDATA";
|
|
break;
|
|
#endif
|
|
#ifdef M_EXSPROTO
|
|
case M_EXSPROTO:
|
|
name = "EXSPROTO";
|
|
break;
|
|
#endif
|
|
#ifdef M_EXSIG
|
|
case M_EXSIG:
|
|
name = "EXSIG";
|
|
break;
|
|
#endif
|
|
#ifdef M_PCDATA
|
|
case M_PCDATA:
|
|
name = "PCDATA";
|
|
break;
|
|
#endif
|
|
#ifdef M_PCPROTO
|
|
case M_PCPROTO:
|
|
name = "PCPROTO";
|
|
break;
|
|
#endif
|
|
#ifdef M_PKT
|
|
case M_PKT:
|
|
name = "PKT";
|
|
break;
|
|
#endif
|
|
#ifdef M_PKTSTOP
|
|
case M_PKTSTOP:
|
|
name = "PKTSTOP";
|
|
break;
|
|
#endif
|
|
case M_IOCACK:
|
|
name = "IOCACK";
|
|
break;
|
|
case M_IOCNAK:
|
|
name = "IOCNAK";
|
|
break;
|
|
case M_PCSIG:
|
|
name = "PCSIG";
|
|
break;
|
|
case M_FLUSH:
|
|
name = "FLUSH";
|
|
break;
|
|
case M_STOP:
|
|
name = "STOP";
|
|
break;
|
|
case M_START:
|
|
name = "START";
|
|
break;
|
|
case M_HANGUP:
|
|
name = "HANGUP";
|
|
break;
|
|
case M_ERROR:
|
|
name = "ERROR";
|
|
break;
|
|
#ifdef _MSG_PROTO_OWN
|
|
#ifdef MSG_PROTO
|
|
case MSG_PROTO:
|
|
name = "MSGPROTO";
|
|
break;
|
|
#endif
|
|
#endif
|
|
default:
|
|
/* printf (":%d:", DATA_TYPE(mp1)); */
|
|
sprintf(nam,"unknown [0x%x]",DATA_TYPE(mp1));
|
|
name = nam;
|
|
break;
|
|
}
|
|
#if 0
|
|
printf ("; %s: %x.%x.%x.%d", name, mp1, DATA_BLOCK(mp1), mp1->b_rptr, mp1->b_wptr - mp1->b_rptr);
|
|
#else
|
|
printf ("; %s: %p.%d", name, mp1, mp1->b_wptr - mp1->b_rptr);
|
|
#endif
|
|
if (nblocks == MAXB) {
|
|
printf ("\n%s*** Block %p pointed to %p", KERN_CRIT, mp1, mp1->b_cont);
|
|
mp1->b_cont = NULL;
|
|
} else {
|
|
int j;
|
|
|
|
for (j = 0; j < nblocks; j++) {
|
|
if (mp1->b_cont == blocks[j]) {
|
|
printf ("\n%s*** Block %p circled to %p (%d)", KERN_CRIT, mp1, mp1->b_cont, j);
|
|
mp1->b_cont = NULL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
printf ("\n");
|
|
{
|
|
int j;
|
|
mblk_t *mp1;
|
|
const char ctab[]= "0123456789abcdef";
|
|
|
|
#define BLOCKSIZE 0x10
|
|
for (j = 0, mp1 = mp; mp1 != NULL; mp1 = mp1->b_cont, j++) {
|
|
int i;
|
|
uchar_t *dp;
|
|
|
|
for (i = 0, dp = (uchar_t *) mp1->b_rptr; dp < (uchar_t *) mp1->b_wptr; dp += BLOCKSIZE) {
|
|
int k;
|
|
int l = (uchar_t *) mp1->b_wptr - dp;
|
|
|
|
printf ("%s%03x ",pprefix,i);
|
|
#if 0
|
|
if(i >= 2*BLOCKSIZE && l > 3*BLOCKSIZE) { /* Skip the stuff in the middle */
|
|
l -= 2*BLOCKSIZE + (l % BLOCKSIZE);
|
|
printf("[... %d bytes (0x%x) skipped ...]\n",l,l);
|
|
dp += l; i += l;
|
|
continue;
|
|
}
|
|
#endif
|
|
for (k = 0; k < BLOCKSIZE && k < l; k++)
|
|
printf ("%c%c ", ctab[dp[k] >> 4], ctab[dp[k] & 0x0F]);
|
|
i += k;
|
|
for (; k < BLOCKSIZE; k++)
|
|
printf (" ");
|
|
printf (" : ");
|
|
for (k = 0; k < BLOCKSIZE && k < l; k++)
|
|
if (dp[k] > 31 && dp[k] < 127)
|
|
printf ("%c", dp[k]);
|
|
else
|
|
printf (".");
|
|
if (k < l)
|
|
printf (" +\n");
|
|
else if (mp1->b_cont != NULL) {
|
|
for (; k < BLOCKSIZE; k++)
|
|
printf (" ");
|
|
printf (" -\n");
|
|
} else
|
|
printf ("\n");
|
|
}
|
|
}
|
|
}
|
|
/* splx (ms); */
|
|
}
|
|
|
|
static void
|
|
log_wput (queue_t * q, mblk_t * mp)
|
|
{
|
|
register struct _log *log = (struct _log *) q->q_ptr;
|
|
|
|
log_printmsg (log, "write", mp, KERN_DEBUG);
|
|
putnext (q, mp);
|
|
return;
|
|
}
|
|
|
|
static void
|
|
log_rput (queue_t * q, mblk_t * mp)
|
|
{
|
|
register struct _log *log = (struct _log *) q->q_ptr;
|
|
|
|
log_printmsg (log, "read", mp, KERN_DEBUG);
|
|
putnext (q, mp);
|
|
return;
|
|
}
|
|
|
|
static void
|
|
xlog_rput (queue_t * q, mblk_t * mp)
|
|
{
|
|
register struct _log *log = (struct _log *) q->q_ptr;
|
|
|
|
switch (DATA_TYPE(mp)) {
|
|
default:
|
|
log_printmsg (log, "read", mp, KERN_DEBUG);
|
|
/* FALL THRU */
|
|
case CASE_DATA:
|
|
break;
|
|
}
|
|
putnext (q, mp);
|
|
return;
|
|
}
|
|
|
|
static void
|
|
xlog_wput (queue_t * q, mblk_t * mp)
|
|
{
|
|
register struct _log *log = (struct _log *) q->q_ptr;
|
|
|
|
switch (DATA_TYPE(mp)) {
|
|
default:
|
|
log_printmsg (log, "write", mp, KERN_DEBUG);
|
|
/* FALL THRU */
|
|
case CASE_DATA:
|
|
break;
|
|
}
|
|
putnext (q, mp);
|
|
return;
|
|
}
|
|
|
|
|
|
static void
|
|
log_close (queue_t * q, int dummy)
|
|
{
|
|
struct _log *log;
|
|
|
|
log = (struct _log *) q->q_ptr;
|
|
|
|
flushq (q, FLUSHALL);
|
|
flushq (WR (q), FLUSHALL);
|
|
if(1)
|
|
printf ("%sLog driver %d closed.\n", KERN_DEBUG,log->nr);
|
|
free(log);
|
|
LESS_USE;
|
|
return;
|
|
}
|
|
|
|
|
|
#ifdef MODULE
|
|
static int do_init_module(void)
|
|
{
|
|
int err;
|
|
|
|
err = register_strmod(&strloginfo);
|
|
if (err) return err;
|
|
err = register_strmod(&xstrloginfo);
|
|
if (err) {
|
|
unregister_strmod(&strloginfo);
|
|
return err ;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int do_exit_module(void)
|
|
{
|
|
int err1 = unregister_strmod(&strloginfo);
|
|
int err2 = unregister_strmod(&xstrloginfo);
|
|
return err1 || err2;
|
|
}
|
|
#endif
|