阅读:1848回复:1
贴一个 SCO OpenServer 5.0.5a 下面的 DLPI passthru stream module 源码。
完整的远码上传了等着审查呢:)
/*============================================================================== 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. ------------------------------------------------------------------------------*/ |
|
沙发#
发布于:2003-12-02 10:40
支持ing
|
|
|