Nemesis2k
驱动牛犊
驱动牛犊
  • 注册日期2002-03-29
  • 最后登录2004-10-27
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1774回复:1

贴一个 SCO OpenServer 5.0.5a 下面的 DLPI passthru stream module 源码。

楼主#
更多 发布于:2003-11-30 20:35
完整的远码上传了等着审查呢:)

/*==============================================================================
File: passthru.c
Desc: A network passthru stream module for SCO OpenServer 5.0.5a.

Revision history:
* 2003/2/26 Created by xh.

Comments:
1) Our passthru stream module will sit between IP driver and common DLPI module.
2) We will use \"push dev passthru\" directive in \"cenetb\" function to  filter
  all ethernet card. Since all boot_netX will call cenetb, we automatically
  inserted between all IP->DLPI stream.
3) But how to filter PPP? To be studied.  
4) Will will filter only ONE device at the same time. The use can use
  our user mode applet to set which device (net0, net1, ppp etc) we shall
  filter without rebuild kernel and reboot.
5) Then how can passthru know which DLPI data block shall be filtered?
  The solution is: When passthru find a DL_BIND_REQ, it will traverse
  down to the lowest device (namely netX) and save the (queue, netX)
  to a table. Afterwards each time a find a DLPI data block will
  use the queue paramter in passthruXput to find the device name
  and filter it or not.
6) The data between IP and DLPI contains only IP packet when the underlying
  device is ethernet device. PPP and 802.x device still unknow.

==============================================================================*/
#include <sys/types.h>
#include <sys/param.h>
#include <sys/conf.h>
#include <sys/sysmacros.h>
#include <sys/stropts.h>
#include <sys/stream.h>
#include <sys/debug.h>
#include <sys/cmn_err.h>
#include <sys/scodlpi.h>

/*------------------------------------------------------------------------------
Macro definitions.
------------------------------------------------------------------------------*/
#define KRNDUMP(p) cmn_err (CE_NOTE, \"^     %s : %u\", #p, p)
#define SCODLPI(p) {p, #p}

/*------------------------------------------------------------------------------
Constants definitions.
------------------------------------------------------------------------------*/
/* Ethernet headers and packet sizes */
#define C_PASSTHRU_HEADERSZ    14        /* ethernet header size */
#define C_PASSTHRU_MINPACK     60        /* minimum packet size including header */
#define C_PASSTHRU_MAXPACK     1518      /* max packet size including header & crc */
#define C_PASSTHRU_TXMAXSZ     (C_PASSTHRU_MAXPACK - 4)  /* subtract crc length */

/*------------------------------------------------------------------------------
Private function prototypes.
------------------------------------------------------------------------------*/
static int passthruopen (queue_t *q, int dev, int flag, int sflag);
static int passthruclose (queue_t *q);
static int passthrurput (queue_t *q, mblk_t *mp);
static int passthruwput (queue_t *q, mblk_t *mp);

static void dump_down_dlpi (queue_t *q, mblk_t *mp);
static void dump_up_dlpi (queue_t *q, mblk_t *mp);
static void decode_dlpi_msg_type (ulong primitive, int nUp);
static char * hexstr (unsigned char by);

/*------------------------------------------------------------------------------
Public function prototypes.
------------------------------------------------------------------------------*/
void viminit (void);

/*------------------------------------------------------------------------------
Private data.
------------------------------------------------------------------------------*/
static struct module_info rminfo = {0x6878, \"passthru\",0, 0xFFFFFFFF, 0, 0};
static struct module_info wminfo = {0x6878, \"passthru\",0, 0xFFFFFFFF, 0, 0};
            
static struct qinit rinit = {passthrurput, NULL, passthruopen, passthruclose, NULL,
                             &rminfo, NULL};            
static struct qinit winit = {passthruwput, NULL, NULL, NULL, NULL, &wminfo, NULL};

static int first_put = 1;

typedef struct _dlpi_primitive
{
ulong value;
char  * desc;
} dlpi_primitive_t;

static dlpi_primitive_t dlpi_primitives [] =
{
/* Primitives for Local Management Services */
{0x00, \"DL_INFO_REQ\"},
{0x03, \"DL_INFO_ACK\"},
{0x0b, \"DL_ATTACH_REQ\"},
{0x0c, \"DL_DETACH_REQ\"},
{0x01, \"DL_BIND_REQ\"},
{0x04, \"DL_BIND_ACK\"},
{0x02, \"DL_UNBIND_REQ\"},
{0x06, \"DL_OK_ACK\"},
{0x05, \"DL_ERROR_ACK\"},
{0x1b, \"DL_SUBS_BIND_REQ\"},
{0x1c, \"DL_SUBS_BIND_ACK\"},
{0x15, \"DL_SUBS_UNBIND_REQ\"},
{0x1d, \"DL_ENABMULTI_REQ\"},
{0x1e, \"DL_DISABMULTI_REQ\"},
{0x1f, \"DL_PROMISCON_REQ\"},
{0x20, \"DL_PROMISCOFF_REQ\"},

/* Primitives used for Connectionless Service */
{0x07, \"DL_UNITDATA_REQ\"},
{0x08, \"DL_UNITDATA_IND\"},
{0x09, \"DL_UDERROR_IND\"},
{0x0a, \"DL_UDQOS_REQ\"},

/* Primitives used for Connection-Oriented Service */
{0x0d, \"DL_CONNECT_REQ\"},
{0x0e, \"DL_CONNECT_IND\"},
{0x0f, \"DL_CONNECT_RES\"},
{0x10, \"DL_CONNECT_CON\"},
{0x11, \"DL_TOKEN_REQ\"},
{0x12, \"DL_TOKEN_ACK\"},
{0x13, \"DL_DISCONNECT_REQ\"},
{0x14, \"DL_DISCONNECT_IND\"},
{0x17, \"DL_RESET_REQ\"},
{0x18, \"DL_RESET_IND\"},
{0x19, \"DL_RESET_RES\"},
{0x1a, \"DL_RESET_CON\"},

/* Primitives used for Acknowledged Connectionless Service */
{0x21, \"DL_DATA_ACK_REQ\"},
{0x22, \"DL_DATA_ACK_IND\"},
{0x23, \"DL_DATA_ACK_STATUS_IND\"},
{0x24, \"DL_REPLY_REQ\"},
{0x25, \"DL_REPLY_IND\"},
{0x26, \"DL_REPLY_STATUS_IND\"},
{0x27, \"DL_REPLY_UPDATE_REQ\"},
{0x28, \"DL_REPLY_UPDATE_STATUS_IND\"},

/* Primitives used for XID and TEST operations */
{0x29, \"DL_XID_REQ\"},
{0x2a, \"DL_XIT_IND\"},
{0x2b, \"DL_XID_RES\"},
{0x2c, \"DL_XIT_CON\"},
{0x2d, \"DL_TEST_REQ\"},
{0x2e, \"DL_TEST_IND\"},
{0x2f, \"DL_TEST_RES\"},
{0x30, \"DL_TEST_CON\"},

/* Primitives to get and set the physical address, and to get Statistics*/
{0x31, \"DL_PHYS_ADDR_REQ\"},
{0x32, \"DL_PHYS_ADDR_ACK\"},
{0x33, \"DL_SET_PHYS_ADDR_REQ\"},
{0x34, \"DL_GET_STATISTICS_REQ\"},
{0x35, \"DL_GET_STATISTICS_ACK\"},

/* SCO specific DLPI */
SCODLPI (DL_CLR_STATISTICS_REQ),
SCODLPI (DL_SAP_STATISTICS_REQ),
SCODLPI (DL_SAP_STATISTICS_ACK),
SCODLPI (DL_SET_SRMODE_REQ),
SCODLPI (DL_SRTABLE_REQ),
SCODLPI (DL_SRTABLE_ACK),
SCODLPI (DL_SR_REQ),
SCODLPI (DL_SR_ACK),
SCODLPI (DL_SET_SR_REQ),
SCODLPI (DL_CLR_SR_REQ),
SCODLPI (DL_MCTABLE_REQ),
SCODLPI (DL_MCTABLE_ACK),

/* Unknown DLPI PRIMITIVE */
{0xFFFFFFFF, \"Unknown DLPI PRIMITIVE\"}
};
#define C_NUM_PRIMITIVES (sizeof (dlpi_primitives) / sizeof (dlpi_primitives [0]))

/*------------------------------------------------------------------------------
The only the one public extern data: streamtab.
------------------------------------------------------------------------------*/
struct streamtab viminfo = {&rinit, &winit, NULL, NULL};

/*------------------------------------------------------------------------------
Public functions.
------------------------------------------------------------------------------*/
void viminit (void)
{
printcfg (\"passthru\", 0, 0, -1, -1, \"%s\", \"Passthru Stream Module.\");
}

/*------------------------------------------------------------------------------
Private functions.
------------------------------------------------------------------------------*/
/*
 * passthruopen
 */
static int passthruopen (queue_t *q, int dev, int flag, int sflag)
{
/* Enter function. */
cmn_err (CE_NOTE, \"^ Enter passthruopen.\");

/* Leave function. */
cmn_err (CE_NOTE, \"^ Leave passthruopen\");
return 0;
}

/*
 * passthruclose
 */
static int passthruclose (queue_t *q)
{
/* Enter function. */
cmn_err (CE_NOTE, \"^ Enter passthruclose.\");

/* Leave function. */
cmn_err (CE_NOTE, \"^ Leave passthruclose\");
return 0;
}

/*
 * passthrurput
 */
static int passthrurput (queue_t *q, mblk_t *mp)
{
int nPacketSize;
mblk_t * pMsgBlk;

/* Enter function. */
/* cmn_err (CE_NOTE,\"^ Enter passthruput\"); */

// Dump the link.
if (1 == first_put)
{
queue_t * q2;
queue_t * p;
struct module_info * pModuleInfo;

/* Find the multiplexor. */
q2 = q;
while (NULL != q2->q_next)
{
q2 = q2->q_next;
}

/* Dump all moudles info */
cmn_err (CE_NOTE, \"^ Begin Dump Module Link\");
p = WR (q2);
do
{
if ((NULL != p->q_qinfo) && (NULL != p->q_qinfo->qi_minfo))
{
pModuleInfo = p->q_qinfo->qi_minfo;
cmn_err (CE_NOTE, \"^     0x%x\", pModuleInfo->mi_idnum);
if (NULL != pModuleInfo->mi_idname)
cmn_err (CE_NOTE, \"^     %s\", pModuleInfo->mi_idname);
else
cmn_err (CE_NOTE, \"^     N/A\");
}
cmn_err (CE_NOTE, \"^     %u\", p->q_minpsz);    
cmn_err (CE_NOTE, \"^     %u\", p->q_maxpsz);    
cmn_err (CE_NOTE, \"^     %u\", p->q_hiwat);    
cmn_err (CE_NOTE, \"^     %u\", p->q_lowat);    
cmn_err (CE_NOTE, \"^ \");
p = p->q_next;
} while (NULL != p);
cmn_err (CE_NOTE, \"^ End Dump Module Link\");
/* Run only once. */
first_put = 0;
}

/* Dump message info. */
switch (mp->b_datap->db_type)
{
case M_PROTO:
case M_PCPROTO:
dump_up_dlpi (q, mp);
break;

case M_DATA: /* We just try to understand the packet.*/
nPacketSize = 0;
pMsgBlk = mp;
while (NULL != pMsgBlk)
{
nPacketSize += pMsgBlk->b_wptr - pMsgBlk->b_rptr;
pMsgBlk = pMsgBlk->b_cont;
}
nPacketSize -= 14; /* Decease the ethernet header. */
cmn_err (CE_NOTE, \"^ passthruRput: M_DATA Data Size %n\", nPacketSize);
break;
default:
break;
}

/* Passthru this msg. */
putnext (q, mp);

/* Leave function. */
/* cmn_err (CE_NOTE,\"^ Leave passthruput\");*/
return 0;
}

/*
 * passthruwput
 */
static int passthruwput (queue_t *q, mblk_t *mp)
{
int nPacketSize;
mblk_t * pMsgBlk;

/* Enter function. */
/*cmn_err (CE_NOTE,\"^ Enter passthruput\");*/

// Dump the link.
if (1 == first_put)
{
queue_t * q2;
queue_t * p;
struct module_info * pModuleInfo;

/* Find the multiplexor. */
q2 = RD (q);
while (NULL != q2->q_next)
{
q2 = q2->q_next;
}

/* Dump all moudles info */
cmn_err (CE_NOTE, \"^ Begin Dump Module Link\");
p = WR (q2);
do
{
if ((NULL != p->q_qinfo) && (NULL != p->q_qinfo->qi_minfo))
{
pModuleInfo = p->q_qinfo->qi_minfo;
cmn_err (CE_NOTE, \"^     0x%x\", pModuleInfo->mi_idnum);
if (NULL != pModuleInfo->mi_idname)
cmn_err (CE_NOTE, \"^     %s\", pModuleInfo->mi_idname);
else
cmn_err (CE_NOTE, \"^     N/A\");
}
cmn_err (CE_NOTE, \"^     %u\", p->q_minpsz);    
cmn_err (CE_NOTE, \"^     %u\", p->q_maxpsz);    
cmn_err (CE_NOTE, \"^     %u\", p->q_hiwat);    
cmn_err (CE_NOTE, \"^     %u\", p->q_lowat);    
cmn_err (CE_NOTE, \"^ \");
p = p->q_next;
} while (NULL != p);
cmn_err (CE_NOTE, \"^ End Dump Module Link\");

/* Run only once. */
first_put = 0;
}

/* Dump message info. */
switch (mp->b_datap->db_type)
{
case M_PROTO:
case M_PCPROTO:
dump_down_dlpi (q, mp);
break;
case M_DATA: /* We just try to understand the packet.*/
nPacketSize = 0;
pMsgBlk = mp;
while (NULL != pMsgBlk)
{
nPacketSize += pMsgBlk->b_wptr - pMsgBlk->b_rptr;
pMsgBlk = pMsgBlk->b_cont;
}
nPacketSize -= 14; /* Decease the ethernet header. */
cmn_err (CE_NOTE, \"^ passthruWput: M_DATA Data Size %n\", nPacketSize);
break;
default:
break;
}

/* Passthru this msg. */
putnext (q, mp);

/* Leave function. */
/* cmn_err (CE_NOTE,\"^ Leave passthruput\");*/
return 0;
}

/*
 * dump_down_dlpi
 */
static void dump_down_dlpi (queue_t *q, mblk_t *mp)
{
static union DL_primitives * prim;
static dl_bind_req_t * dbr;
static dl_unitdata_req_t * dur;
static unsigned char * ctrl2;
static mblk_t * datamp;
static int datalen;
static int i;
static int bytes;
static int packets;
static int len;

prim = (union DL_primitives *) mp->b_rptr;
decode_dlpi_msg_type (prim->dl_primitive, 0);
switch (prim->dl_primitive)
{
case DL_BIND_REQ:
dbr = (dl_bind_req_t *) &prim->bind_req;
KRNDUMP (dbr->dl_sap);
KRNDUMP (dbr->dl_max_conind);
KRNDUMP (dbr->dl_service_mode);
KRNDUMP (dbr->dl_conn_mgmt);
KRNDUMP (dbr->dl_xidtest_flg);
cmn_err (CE_NOTE, \"^ \");
break;
case DL_UNITDATA_REQ:
dur = (dl_unitdata_req_t *) &prim->unitdata_req;
KRNDUMP (dur->dl_dest_addr_length);
KRNDUMP (dur->dl_dest_addr_offset);
KRNDUMP (dur->dl_priority);

cmn_err (CE_NOTE | CO_NONL, \"^ Dest Address: 0x\");
ctrl2 = mp->b_rptr + dur->dl_dest_addr_offset;
for (i = 0; i < dur->dl_dest_addr_length; i ++)
{
cmn_err (CE_CONT | CO_NONL, \"^%s\", hexstr(ctrl2 ));
}
cmn_err (CE_CONT, \"^ \\n\");

cmn_err (CE_NOTE | CO_NONL, \"^ First 14 Bytes Of Packet Data: \");
datamp = mp->b_cont;
if (NULL != datamp)
{
if (datamp->b_wptr - datamp->b_rptr < 14)
bytes = datamp->b_wptr - datamp->b_rptr;
else
bytes = 14;
ctrl2 = datamp->b_rptr;
for (i = 0; i < bytes; i ++)
{
cmn_err (CE_CONT | CO_NONL, \"^%s \", hexstr(ctrl2 ));
}
}
else
{
cmn_err (CE_CONT | CO_NONL, \"^ No Data!!!\");
}
cmn_err (CE_CONT, \"^ \\n\");

datalen = 0;
packets = 0;
datamp = mp->b_cont;
while (NULL != datamp)
{
len = datamp->b_wptr - datamp->b_rptr;
cmn_err (CE_NOTE, \"^ Data Block %u, Data Len: %u\", packets, len);
datalen += len;

datamp = datamp->b_cont;
packets ++;
}
cmn_err (CE_NOTE , \"^ Total data length: %u  Number Of Packets: %u\",
        datalen, packets);
       
break;
default:
break;
}
}

/*
 * dump_up_dlpi
 */
static void dump_up_dlpi (queue_t *q, mblk_t *mp)
{
static union DL_primitives * prim;
static dl_bind_ack_t * dba;
static dl_unitdata_ind_t * dui;
static unsigned char * ctrl2;
static mblk_t * datamp;
static int datalen;
static int i;
static int bytes;
static int packets;
static int len;

prim = (union DL_primitives *) mp->b_rptr;
decode_dlpi_msg_type (prim->dl_primitive, 1);
switch (prim->dl_primitive)
{
case DL_BIND_ACK:
dba = (dl_bind_ack_t *) &prim->bind_ack;
KRNDUMP (dba->dl_sap);
KRNDUMP (dba->dl_addr_length);
KRNDUMP (dba->dl_addr_offset);
KRNDUMP (dba->dl_max_conind);
KRNDUMP (dba->dl_xidtest_flg);

cmn_err (CE_NOTE | CO_NONL, \"^ Binded Address: 0x\");
ctrl2 = mp->b_rptr + dba->dl_addr_offset;
for (i = 0; i < dba->dl_addr_length; i ++)
{
cmn_err (CE_CONT | CO_NONL, \"^%s\", hexstr(ctrl2 ));
}
cmn_err (CE_CONT, \"^ \\n\");
break;
case DL_UNITDATA_IND:
dui = (dl_unitdata_ind_t *) &prim->unitdata_ind;
KRNDUMP (dui->dl_dest_addr_length);
KRNDUMP (dui->dl_dest_addr_offset);
KRNDUMP (dui->dl_src_addr_length);
KRNDUMP (dui->dl_src_addr_offset);

cmn_err (CE_NOTE | CO_NONL, \"^ Dest Address: 0x\");
ctrl2 = mp->b_rptr + dui->dl_dest_addr_offset;
for (i = 0; i < dui->dl_dest_addr_length; i ++)
{
cmn_err (CE_CONT | CO_NONL, \"^%s\", hexstr(ctrl2 ));
}
cmn_err (CE_CONT, \"^ \\n\");

cmn_err (CE_NOTE | CO_NONL, \"^ Src Address: 0x\");
ctrl2 = mp->b_rptr + dui->dl_src_addr_offset;
for (i = 0; i < dui->dl_src_addr_length; i ++)
{
cmn_err (CE_CONT | CO_NONL, \"^%s\", hexstr(ctrl2 ));
}
cmn_err (CE_CONT, \"^ \\n\");

cmn_err (CE_NOTE | CO_NONL, \"^ First 14 Bytes Of Packet Data: \");
datamp = mp->b_cont;
if (NULL != datamp)
{
if (datamp->b_wptr - datamp->b_rptr < 14)
bytes = datamp->b_wptr - datamp->b_rptr;
else
bytes = 14;
ctrl2 = datamp->b_rptr;
for (i = 0; i < bytes; i ++)
{
cmn_err (CE_CONT | CO_NONL, \"^%s \", hexstr(ctrl2 ));
}
}
else
{
cmn_err (CE_CONT | CO_NONL, \"^ No Data!!!\");
}
cmn_err (CE_CONT, \"^ \\n\");

datalen = 0;
packets = 0;
datamp = mp->b_cont;
while (NULL != datamp)
{
len = datamp->b_wptr - datamp->b_rptr;
cmn_err (CE_NOTE, \"^ Data Block %u, Data Len: %u\", packets, len);
datalen += len;

datamp = datamp->b_cont;
packets ++;
}
cmn_err (CE_NOTE , \"^ Total data length: %u  Number Of Packets: %u\",
        datalen, packets);
break;
default:
break;
}
}

/*
 * decode_dlpi_msg_type
 */
static void decode_dlpi_msg_type (ulong primitive, int nUp)
{
register int i;

for (i = 0; i < C_NUM_PRIMITIVES; i ++)
{
if (dlpi_primitives .value == primitive)
break;
}
if (1 == nUp)
{
cmn_err (CE_NOTE, \"^ %s  UP!!\", dlpi_primitives .desc);
}
else
{
cmn_err (CE_NOTE, \"^ %s  DOWN!!\", dlpi_primitives .desc);
}
}

/*
 * hexstr
 */
static char * hexstr (unsigned char by)
{
static char * hextbl = \"0123456789ABCDEF\";
static char buf [3];
static unsigned char low4;
static unsigned char high4;

high4 = by / 16;
low4 = by - high4 * 16;
buf [0] = hextbl [high4];
buf [1] = hextbl [low4];
buf [2] = 0;
return buf;
}

/*------------------------------------------------------------------------------
The end.
------------------------------------------------------------------------------*/
antspower
驱动中牛
驱动中牛
  • 注册日期2002-10-17
  • 最后登录2010-08-03
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值2点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2003-12-02 10:40
支持ing
放弃瘟草,现吃李草
游客

返回顶部