⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ip_strm_mod.c

📁 7号信令功能代码,为开源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*************************************************************************									**                   Gcom DLPI <-> Linux SKBUF Driver		        **									***************************************************************************									**                  Copyright (C) 1995,1996,1997 Gcom, Inc		**									**									**	Author: Among others Mikel L. Matthews Gcom, Inc.		**									** Copyright (C) 1997-1999  Mikel Matthews, Gcom, Inc <mikel@gcom.com>	**                          Dave Grothe, Gcom, Inc <dave@gcom.com>	**									*************************************************************************//* * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. *  * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Library General Public License for more details. *  * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Cambridge, * MA 02139, USA. *  * This is a pushable streams module that bridges a DLPI stream to * an IP masquerading as a network driver. * * The way you use it is as follows: * * Open your DLPI stream file. * * Push this module. * * Do DLPI attach and bind. * * Send SIOCSIFNAME ioctl with the desired interface name. * * The ioctl causes the module to register itself with IP as a network * interface driver. * * Do the appropriate ifconfig and route commands. * * You can tear down the IP side by doing ifconfig <name> off.  You can * tear down the whole thing by closing the streams file. *//*************************************************************************                              SCCS ID                                  ***************************************************************************									** The following strings identify this module as to version info.	**									*************************************************************************/#ident "@(#) LiS ip_strm_mod.c 2.21 10/09/02 22:08:57 "#include <linux/config.h>#include <linux/version.h>#ifdef CONFIG_MODVERSIONS#include <linux/modversions.h>#endif#include <linux/module.h>#include <linux/kernel.h>#include <linux/string.h>#include <linux/errno.h>#include <linux/ioport.h>#include <linux/slab.h>#include <linux/interrupt.h>#include <linux/timer.h>#include <linux/pci.h>#include <linux/spinlock.h>#include <linux/init.h>#include <linux/delay.h>#include <linux/ioctl.h>#include <asm/bitops.h>#include <asm/io.h>#include <asm/uaccess.h>#include <linux/net.h>#include <linux/in.h>#include <linux/netdevice.h>#include <linux/etherdevice.h>#include <linux/skbuff.h>#include <linux/ethtool.h>#include <linux/delay.h>#include <linux/types.h>#include <linux/if_arp.h>/* * UNIX includes */#include <sys/stream.h>#include <sys/cmn_err.h>#include <sys/dlpi.h>#include <sys/mkdev.h>#include <sys/ddi.h>#include <sys/cred.h>#include <sys/LiS/mod.h>#include "ip_strm_mod.h"#include <sys/osif.h>/*************************************************************************                        Function Prototypes                            *************************************************************************//* * Functions in this file */extern int	ip_strm_init(struct ism_dev *dev) ;/*************************************************************************                    Streams Entry Point Routines                       ***************************************************************************									** The following section of code contains the entry point routines for	** the streams driver.  These are the open, close, put and service	** routines pointed to by the qinit structures above.			**									*************************************************************************/extern  int		ip_to_streams_open(queue_t *,dev_t *,int ,int, cred_t *);extern  int		ip_to_streams_close(queue_t *, int, cred_t *);extern  int		ip_to_streams_wput(queue_t *,mblk_t *);extern  int		ip_to_streams_wsrv(queue_t *);extern  int		ip_to_streams_rput(queue_t *,mblk_t *);extern  int	        ip_to_streams_rsrv(queue_t *);extern  int		ip_to_streams_conn_req(ip_to_streams_minor_t *minor_ptr,				      mblk_t *mp, int retry) ;extern int		ip_to_streams_proto(ip_to_streams_minor_t *, mblk_t *,					int );#ifdef GCOMextern  void		netman_hex_mp (mblk_t *, char *);extern  void    	Rsys_print_traced_token (char *bufp) ;extern	void		Rsys_hex_print(char *, unsigned char *, int);#endif/*************************************************************************                    Linkage to Streams System                          *************************************************************************/struct module_info ip_to_streams_minfo =	{ 0		/* mi_idnum  */	, "ip_to_streams"	/* mi_idname */	, 0		/* mi_minpsz */	, INFPSZ	/* mi_maxpsz */	, 20000		/* mi_hiwat  */	, 2000		/* mi_lowat  */	};struct qinit ip_to_streams_rinit =	{ ip_to_streams_rput	, ip_to_streams_rsrv	/* qi_srvp  */	, ip_to_streams_open	/* qi_open  */	, ip_to_streams_close	/* qi_close */	, NULL			/* qi_admin */	, &ip_to_streams_minfo	/* qi_minfo */	, NULL		/* qi_mstat */	};struct qinit ip_to_streams_winit =	{ ip_to_streams_wput	/* qi_putp  */	, ip_to_streams_wsrv	/* qi_srvp  */	, NULL		/* qi_open  */	, NULL		/* qi_close */	, NULL		/* qi_admin */	, &ip_to_streams_minfo	/* qi_minfo */	, NULL		/* qi_mstat */	};struct streamtab ip_to_streams_info =	{ &ip_to_streams_rinit	   /* read queue definition */	, &ip_to_streams_winit	   /* write queue definition */	, NULL			   /* mux read queue  */	, NULL			   /* mux write queue */	};int	ip_to_streamsdevflag = 0;/*************************************************************************                       Storage Declarations                            *************************************************************************/unsigned long		 ip_to_streams_debug_mask = 0;#define IP_STRM_MTU (1500)/*************************************************************************                           ip_to_streams_open                          ***************************************************************************									** The streams open routine. Called when this is pushed on to the stack	**									*************************************************************************/intip_to_streams_open( queue_t *rdq,	   dev_t   *devp,	   int      flag,	   int      sflag,	   cred_t  *credp){    ip_to_streams_minor_t	*minor_ptr ;    if ( ip_to_streams_debug_mask & (DBG_OPEN) )	cmn_err(CE_CONT, "\nip_to_streams_open: q=%x sflag=%d", sflag) ;    minor_ptr = (ip_to_streams_minor_p) ALLOC(sizeof(ip_to_streams_minor_t)) ;    if (minor_ptr == NULL)	return(-ENOMEM) ;    memset(minor_ptr, 0, sizeof(*minor_ptr)) ;	/* clear to zero */    minor_ptr->dl_magic = DL_MAGIC ;    rdq->q_ptr = (caddr_t) minor_ptr ;    WR(rdq)->q_ptr = (caddr_t) minor_ptr ;    minor_ptr->dl_rdq = rdq ;    minor_ptr->dl_wrq = WR(rdq) ;    minor_ptr->dl_q   = rdq;    minor_ptr->dl_err_prim = -1 ;		/* ensure no retry */    strcpy(minor_ptr->myname, "is") ;		/* initial name Ip/Streams */#if defined(KERNEL_2_3)    strcpy(minor_ptr->mydev.name, "is") ;	/* initial name Ip/Streams */#else    minor_ptr->mydev.name = minor_ptr->myname ;#endif    minor_ptr->mydev.init = ip_strm_init ;    minor_ptr->mydev.priv = minor_ptr ;    if ( ip_to_streams_debug_mask & (DBG_OPEN) )	cmn_err(CE_CONT, "\nip_to_streams_open succeeded") ;    return (0);			/* success */} /* ip_to_streams_open *//*************************************************************************                          ip_to_streams_close                          ***************************************************************************									** Called when closing the stream					**									*************************************************************************/int ip_to_streams_close(queue_t *q, int dummy, cred_t *credp){    ip_to_streams_minor_t	*minor_ptr ;    if ( ip_to_streams_debug_mask & (DBG_OPEN) )	cmn_err(CE_CONT, "\nip_to_streams_close: q=%x ", q) ;    minor_ptr = (ip_to_streams_minor_t *) q->q_ptr ;    if (   minor_ptr != (ip_to_streams_minor_t *) NULL	&& minor_ptr->dl_magic == DL_MAGIC       )    {	if ( ip_to_streams_debug_mask & (DBG_OPEN) )	    cmn_err(CE_CONT, "ip_to_streams_close: %s\n", minor_ptr->myname) ;	if (minor_ptr->dev_registered != 0)	/* still open to IP */	    unregister_netdev(&minor_ptr->mydev) ;	minor_ptr->dl_magic = ~DL_MAGIC ;	FREE(minor_ptr) ;    }    else    if ( ip_to_streams_debug_mask & (DBG_OPEN) )	cmn_err(CE_CONT, "ip_to_streams_close: invalid minor ptr q_ptr=%x\n",			q->q_ptr) ;    q->q_ptr = NULL ;				/* zot the q ptrs */    WR(q)->q_ptr = NULL ;			/* zot the q ptrs */    return(0) ;} /* ip_to_streams_close *//*************************************************************************                          ip_to_streams_ioctl                          ***************************************************************************									** Have a look at an ioctl received from the user.  Return 1 if the	** ioctl is to be forwarded downstream.  Return 0 if we handled it here.	**									*************************************************************************/int ip_to_streams_ioctl(queue_t *q, mblk_t  *mp){    struct iocblk		*iocp;    ip_to_streams_minor_t	*minor_ptr ;    mblk_t			*xmp = mp->b_cont ;    int				 result = 0 ;    iocp = (struct iocblk *) mp -> b_rptr;      /* the request header */    if ((mp -> b_wptr - mp -> b_rptr) < sizeof (struct iocblk *))   /* small */	return(1) ;			/* let driver deal with it */    minor_ptr = (ip_to_streams_minor_t *) q->q_ptr ;    switch (iocp -> ioc_cmd)    {    case SIOCSIFNAME:		/* set interface name */        /*         * This ioctl is sent by the streams user.  It is the last step         * in making this stream available to IP.  Once we know the         * name we register the device with IP as an interface.         *         * As an added feature, the streams user can set the name         * to the empty string and we will unregister from IP.  When         * we unregister we leave the streams side alone so that a         * simple "set if-name" ioctl will make the interface appear         * under IP again.         */	if (xmp != NULL && *xmp->b_rptr != 0)		/* name specified */	{	    strncpy(minor_ptr->myname, xmp->b_rptr, sizeof(minor_ptr->myname)) ;#if defined(KERNEL_2_3)	    strcpy(minor_ptr->mydev.name, minor_ptr->myname) ;#else	    minor_ptr->mydev.name = minor_ptr->myname ;#endif	    if ((result = register_netdev(&minor_ptr->mydev)) != 0)		printk("ip_to_streams_ioctl: "		       "register_netdev(%s) failed: %d\n",		       minor_ptr->myname, result);	    else		printk("ip_to_streams_ioctl: SIOCSIFNAME: %s\n",			minor_ptr->myname) ;	    minor_ptr->dev_registered = result == 0 ;	}	else				/* nullify name, unregister */	{	    unregister_netdev(&minor_ptr->mydev) ;	    strcpy(minor_ptr->myname, "is") ;	    minor_ptr->contype = 0;	/* not connected */	    minor_ptr->ip_open = 0 ;	/* not open to IP now */	}	if (xmp != NULL)	{	    freemsg(xmp) ;		/* don't return any data */	    mp->b_cont = NULL ;	}	break ;    default:	printk("ip_to_streams_ioctl: undefined ioctl: 0x%x\n", iocp->ioc_cmd) ;	result = -EINVAL ;	break ;    }    /*     * If you exit the switch then we are going to reply to the     * ioctl and not forward it downstream.     */    if (result)						/* error */    {	mp -> b_datap -> db_type = M_IOCNAK;	iocp -> ioc_count = 0;                          /* no data */    }    else                                                /* success */    {	mp -> b_datap -> db_type = M_IOCACK;	if ((xmp = mp -> b_cont) == NULL)               /* no chained buf */	    iocp -> ioc_count = 0;                      /* no data */	else                                            /* a response */	    iocp -> ioc_count = xmp -> b_wptr - xmp -> b_rptr;    }    iocp -> ioc_error = result;    qreply(q, mp);    return(0) ;				/* do not forward */} /* ip_to_streams_ioctl *//*************************************************************************                           ip_to_streams_wput                          ***************************************************************************									** Write side put routine						**									*************************************************************************/int ip_to_streams_wput(queue_t *q, mblk_t  *mp){    ip_to_streams_minor_t	*minor_ptr ;    if ( ip_to_streams_debug_mask & DBG_PUT )	cmn_err(CE_CONT, "\nip_to_streams_wput: q=%x mp=%x\n", q, mp) ;    minor_ptr = (ip_to_streams_minor_t *) q->q_ptr ;    /* make sure the data structure is valid */    if (   minor_ptr == (ip_to_streams_minor_t *) NULL	|| minor_ptr->dl_magic != DL_MAGIC       )    {	if (ip_to_streams_debug_mask & DBG_SQUAWK)	    cmn_err(CE_NOTE, "ip_to_streams_wput: bad minor") ;	freemsg(mp) ;	return(0) ;    }    switch(mp->b_datap->db_type)    {    case M_DATA:	if ( canputnext(q) )		/* data uses flow control */	    putnext(q, mp);	else	    putq(q, mp);	break;    case M_PROTO:    case M_PCPROTO:    {	int err;	union DL_primitives *dlp;	err = 0;	dlp = (union DL_primitives *)mp->b_rptr;	switch(dlp->dl_primitive)	{	    case DL_UNITDATA_REQ:	    {		if ( ip_to_streams_debug_mask & DBG_WPUT)		    printk("ip_to_streams_wput: DL_UNITDATA_REQ:\n");		if ( canputnext(q) )		/* data uses flow control */		    putnext(q, mp);		else		    putq(q, mp);		return(0) ;	    }	    case DL_INFO_REQ:	    {		if ( ip_to_streams_debug_mask & DBG_WPUT)		    printk("ip_to_streams_wput: DL_INFO_REQ:\n");		putnext(q, mp);		break;	    }	    case DL_BIND_REQ:	    {		dl_bind_req_t	     *dlp;		if ( ip_to_streams_debug_mask & DBG_WPUT)		    printk("ip_to_streams_wput:DL_BIND_REQ:\n");		minor_ptr->dlstate = DL_BIND_PENDING;		dlp = (dl_bind_req_t *) mp->b_rptr ;		minor_ptr->dl_sap = dlp->dl_sap ;	/* save SAP */		putnext(q, mp);		break;	    }	    case DL_UNBIND_REQ:	    {		if ( ip_to_streams_debug_mask & DBG_WPUT)		    printk("DL_UNBIND_REQ:\n");		minor_ptr->dlstate = DL_UNBIND_PENDING;		minor_ptr->dl_sap = 0 ;		putnext(q, mp);		break;	    }	    case DL_ATTACH_REQ:	    {		if ( ip_to_streams_debug_mask & DBG_WPUT)		    printk("DL_ATTACH_REQ:\n");		minor_ptr->dlstate = DL_ATTACH_PENDING;		putnext(q, mp);		break;	    }	    case DL_DETACH_REQ:	    {		if ( ip_to_streams_debug_mask & DBG_WPUT)		    printk("DL_DETACH_REQ:\n");		minor_ptr->dlstate = DL_DETACH_PENDING ;		putnext(q, mp);		break;	    }	    break;	}	break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -