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

📄 ldl.c

📁 7号信令功能代码,为开源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	   skb->len) ;    if (alldata)	cnt = skb->tail - skb->head ;	/* dump everything in the buffer */    else	alldata = cnt = 64 ;		/* make alldata non-zero */    ldl_bfr_dump("Dump from skb->head", skb->head, cnt, alldata) ;#undef L}STATIC char *ldl_framing_type(unsigned long framing){    switch (framing & LDL_FRAME_MASK)    {    case LDL_FRAME_EII:		return("LDL_FRAME_EII");    case LDL_FRAME_802_2:	return("LDL_FRAME_802_2");    case LDL_FRAME_SNAP:	return("LDL_FRAME_SNAP");    case LDL_FRAME_802_3:	return("LDL_FRAME_802_3");    case LDL_FRAME_RAW_LLC:	return("LDL_FRAME_RAW_LLC");    }    return("LDL_FRAME_UNKNOWN");}STATIC char *ldl_pkt_type(unsigned saptype){    switch (saptype)    {#ifdef ETH_P_ECHO    case ETH_P_ECHO:	return("ETH_P_ECHO");#endif    case ETH_P_PUP:	return("ETH_P_PUP");    case ETH_P_IP:	return("ETH_P_IP");    case ETH_P_X25:	return("ETH_P_X25");    case ETH_P_ARP:	return("ETH_P_ARP");    case ETH_P_BPQ:	return("ETH_P_BPQ");    case ETH_P_DEC:	return("ETH_P_DEC");    case ETH_P_DNA_DL:	return("ETH_P_DNA_DL");    case ETH_P_DNA_RC:	return("ETH_P_DNA_RC");    case ETH_P_DNA_RT:	return("ETH_P_DNA_RT");    case ETH_P_LAT:	return("ETH_P_LAT");    case ETH_P_DIAG:	return("ETH_P_DIAG");    case ETH_P_CUST:	return("ETH_P_CUST");    case ETH_P_SCA:	return("ETH_P_SCA");    case ETH_P_RARP:	return("ETH_P_RARP");    case ETH_P_ATALK:	return("ETH_P_ATALK");    case ETH_P_AARP:	return("ETH_P_AARP");    case ETH_P_IPX:	return("ETH_P_IPX");    case ETH_P_IPV6:	return("ETH_P_IPV6");    case ETH_P_802_3:	return("ETH_P_802_3");    case ETH_P_AX25:	return("ETH_P_AX25");    case ETH_P_ALL:	return("ETH_P_ALL");    case ETH_P_802_2:	return("ETH_P_802_2");    case ETH_P_SNAP:	return("ETH_P_SNAP");    case ETH_P_DDCMP:	return("ETH_P_DDCMP");    case ETH_P_WAN_PPP:	return("ETH_P_WAN_PPP");    case ETH_P_PPP_MP:	return("ETH_P_PPP_MP");    case ETH_P_LOCALTALK:return("ETH_P_LOCALTALK");    case ETH_P_PPPTALK:	return("ETH_P_PPPTALK");    case ETH_P_TR_802_2:return("ETH_P_TR_802_2");    case ETH_P_MOBITEX:	return("ETH_P_MOBITEX");    case ETH_P_CONTROL:	return("ETH_P_CONTROL");    case ETH_P_IRDA:	return("ETH_P_IRDA");    case 0:		return("NULL(0)");    }    return("ETH_P_UNKNOWN");}void ldl_init(void){	if (initialized)		return;	printk("ldl: Linux streams datalink driver\n");	printk("ldl: Copyright (C) 1998 Ole Husgaard\n");	memset(dl_dl, 0, sizeof dl_dl);	first_pt = NULL;	first_ndev = NULL;	first_open = NULL;	n_hangup = 0;	lis_spin_lock_init(&first_pt_lock, "LiS DLPI packet type list lock");	lis_spin_lock_init(&first_open_lock, "LiS DLPI open driver list lock");	initialized = 1;}/****************************************************************************//*                                                                          *//*  Packet type and SAP handling.                                           *//*                                                                          *//****************************************************************************//* *  sap_create  - create and add another packet type (sap) to a device. * *  Returns 0 on success, -1 on failure. * *  Notice that sap_create is always called under SPLSTR() */STATIC int sap_create(struct dl *dl, sap_t dlsap, dl_ushort saptype){	struct pt *pt, *npt;	struct sap *sap;	ASSERT(dl != NULL);	ASSERT(dl->magic == DL_MAGIC);	ASSERT(dl->ndev != NULL);	saptype = htons(saptype);	if ((sap = ALLOC(sizeof *sap)) == NULL)		return -1;	++sap_n_alloc;	memset(sap, 0, sizeof *sap);	sap->magic = SAP_MAGIC;	sap->dl = dl;	sap->sap = dlsap;	if (dl->sap == NULL) {		/* This is a primary bind */		sap->next_sap = NULL;		dl->sap = sap;	} else {		/* This is a subsequent bind */		sap->next_sap = dl->subs;		dl->subs = sap;	}	/* Does Linux already pass us this packet type on this device? */	npt = NULL;	lis_spin_lock(&first_pt_lock);	do {		for (pt = first_pt; pt; pt = pt->next)			if (pt->pt.type == saptype &&			    pt->pt.dev == dl->ndev->dev)				break;		if (pt == NULL) {			if (npt == NULL) {				lis_spin_unlock(&first_pt_lock);				if ((npt = ALLOC(sizeof *pt)) == NULL) {					FREE(sap);					sap_n_alloc--;					return -1;				}				++pt_n_alloc;				memset(npt, 0, sizeof *npt);				lis_spin_lock(&first_pt_lock);			} else {				npt->next = first_pt;				first_pt = pt = npt;			}		} else if (npt != NULL) {			FREE(npt);			npt = NULL;			pt_n_alloc--;		}	} while (pt == NULL);	sap->pt = pt;	if (pt->listen == NULL) {		/* New, unused packet_type */		ASSERT(pt->magic == 0);		/* No need to synchronize with rcv_func() */ 		sap->next_listen = pt->listen;		pt->listen = sap;		lis_rw_lock_init(&pt->lock, "LiS SAP listening list");		pt->magic = PT_MAGIC;		pt->pt.type = saptype;		pt->pt.dev = dl->ndev->dev;		pt->pt.func = rcv_func;		pt->pt.data = NULL;		pt->pt.next = NULL;		lis_spin_unlock(&first_pt_lock);		dev_add_pack(&pt->pt);	} else {		/* Re-use of packet_type */		ASSERT(pt->magic == PT_MAGIC);		ASSERT(pt->pt.type == saptype);		ASSERT(pt->pt.func == rcv_func);		lis_rw_write_lock(&pt->lock);		sap->next_listen = pt->listen;		pt->listen = sap;		lis_rw_write_unlock(&pt->lock);		lis_spin_unlock(&first_pt_lock);	}	return 0;}/* *  sap_destroy  - remove and destroy a packet type (sap) from a device. * *  Returns 0 on success, -1 if not found. */STATIC int sap_destroy(struct dl *dl, struct sap *sap){	int psw;	struct pt *pt, *opt;	struct sap **sapp_dl, **sapp_pt;	ASSERT(dl != NULL);	ASSERT(dl->magic == DL_MAGIC);	ASSERT(sap != NULL);	ASSERT(sap->magic == SAP_MAGIC);	ASSERT(dl->subs != NULL || sap == dl->sap);	pt = sap->pt;	ASSERT(pt != NULL);	ASSERT(pt->magic == PT_MAGIC);	SPLSTR(psw);	lis_spin_lock(&first_pt_lock);	lis_rw_write_lock(&pt->lock);	if (pt->listen == sap && sap->next_listen == NULL) {		/* It is the last use of this packet_type */		lis_rw_write_unlock(&pt->lock);		if (pt == first_pt)			first_pt = pt->next;		else {			for (opt = first_pt; opt->next != NULL; opt = opt->next)				if (opt->next == pt) {					opt->next = pt->next;					break;				}		}		lis_spin_unlock(&first_pt_lock);		dev_remove_pack(&pt->pt);		pt->magic = 0;		FREE(pt);		--pt_n_alloc;	} else {		lis_spin_unlock(&first_pt_lock);		sapp_pt = &pt->listen;		for (;;) {			ASSERT(*sapp_pt != NULL);			if (*sapp_pt == NULL) {				/*				 * Not found, but it should be there:				 * Emergency brake				 */				lis_rw_write_unlock(&pt->lock);				SPLX(psw);				return -1;			}			if (*sapp_pt == sap)				break;			sapp_pt = &(*sapp_pt)->next_listen;		}		*sapp_pt = sap->next_listen;		lis_rw_write_unlock(&pt->lock);	}	if (dl->sap == sap) {		ASSERT(dl->subs == NULL);		dl->sap = NULL;	} else {		sapp_dl = &dl->subs;		for(;;) {			ASSERT(*sapp_dl != NULL);			if (*sapp_dl == NULL) {				/*				 * Not found, but it should be there:				 * Emergency brake				 */				SPLX(psw);				return -1;			}			ASSERT((*sapp_dl)->magic == SAP_MAGIC);			ASSERT((*sapp_dl)->dl == dl);			if (*sapp_dl == sap)				break;			sapp_dl = &(*sapp_dl)->next_sap;		}		*sapp_dl = sap->next_sap;	}	sap->dl = NULL;	sap->pt = NULL;	sap->magic = 0;	FREE(sap);	--sap_n_alloc;	SPLX(psw);	return 0;}/* *  sap_destroy_all  - remove and destroy all packet types (sap) from a device. */STATIC void sap_destroy_all(struct dl *dl){	int ret;	ASSERT(dl != NULL);	while (dl->subs) {		ASSERT(dl->subs->pt != NULL);		ret = sap_destroy(dl, dl->subs);		ASSERT(ret == 0);		if (ret != 0)			return; /* Emergency brake */	}	if (dl->sap) {		ASSERT(dl->sap->pt != NULL);		ret = sap_destroy(dl, dl->sap);		ASSERT(ret == 0);	}}/****************************************************************************//*                                                                          *//*  Hangup handling.                                                        *//*                                                                          *//****************************************************************************//* *  hangup_set  - set endpoint flag for hangup * *  Not reentrant. */STATIC INLINE void hangup_set(struct dl *dl){	if ((dl->flags & LDLFLAG_HANGUP) == 0) {		/*		 *  A hangup should never happen on an unattached device.		 */		ASSERT(dl->dlstate != DL_UNATTACHED);		/*		 *  The hangup has not already been done.		 */		ASSERT((dl->flags & LDLFLAG_HANGUP_DONE) != 0);		/*		 *  This endpoint should already have been disassociated		 *  from the netdevice.		 */		ASSERT(dl->ndev == NULL);		dl->flags |= LDLFLAG_HANGUP;	/* Set flag		*/		++n_hangup;			/* Update count		*/	}}/* *  hangup_do  - do the actual hangup on an endpoint */STATIC INLINE void hangup_do(struct dl *dl){	int psw;	SPLSTR(psw);	ASSERT((dl->flags & LDLFLAG_HANGUP) != 0);	/* Has the hangup been done already? */	if ((dl->flags & LDLFLAG_HANGUP_DONE) != 0) {		SPLX(psw);		return;	}	ASSERT(n_hangup > 0);	/*	 *  In the transient states a hangup cannot easily be done.         *  A check of the hangup flag retries the hangup when these states	 *  are left.	 */	if (dl->dlstate == DL_UNBIND_PENDING ||	    dl->dlstate == DL_SUBS_UNBIND_PND) {		SPLX(psw);		return;	}	/*	 *  Go into the DL_UNATTACHED state before hanging up.	 *  This ensures that all resources associated with the endpoint	 *  are released. In particular, no more unitdata indications	 *  should come from this endpoint.	 */	if (dl->dlstate == DL_IDLE) {		sap_destroy_all(dl);		dl->dlstate = DL_UNBOUND;	}	if (dl->dlstate == DL_UNBOUND) {		STATIC void ndev_release(struct dl *dl);		ndev_release(dl);		dl->addr_len = 0;		dl->ndev = NULL;		dl->dlstate = DL_UNATTACHED;	}	ASSERT(dl->dlstate == DL_UNATTACHED);	SPLX(psw);		if (putctl(dl->rq->q_next, M_HANGUP))	{		SPLSTR(psw);		if ((dl->flags & LDLFLAG_HANGUP_DONE) == 0) {			dl->flags |= LDLFLAG_HANGUP_DONE;			--n_hangup;		}		SPLX(psw);	} else		printk("ldl: cannot send M_HANGUP\n");}/****************************************************************************//*                                                                          *//*  Netdevice handling.                                                     *//*                                                                          *//****************************************************************************//* *  ndev_find  - find netdevice * *  Not reentrant, returns NULL if not found. */STATIC INLINE struct ndev *ndev_find(struct ldldev *dev){	struct ndev *ndev;	for (ndev = first_ndev; ndev; ndev = ndev->next)		if (ndev->dev == dev)			break;	return ndev;}/* *  ndev_get  - create or find netdevice * *  Not reentrant, returns NULL on failure. */STATIC struct ndev *ndev_get(dl_ulong ppa){	dl_ulong i;	struct ldldev *dev;	struct ndev *ndev;	/* Find the Linux netdevice to attach to */	for (dev = dev_base, i = 0; dev; dev = dev->next, ++i) 		if (ppa == i)			break;	if (dev == NULL)		return NULL;	ASSERT(ppa == i);	if ((ndev = ndev_find(dev)) == NULL) {		if ((ndev = ALLOC(sizeof *ndev)) == NULL)			return NULL;		++ndev_n_alloc;		memset(ndev, 0, sizeof *ndev);		ndev->magic = NDEV_MAGIC;		ndev->dev = dev;		ndev->wr_max = DEV_WR_MAX;		ndev->wr_min = DEV_WR_MIN;	}	return ndev;}/* *  ndev_attach  - attach endpoint to a netdevice * *  Not reentrant. */STATIC void ndev_attach(struct ndev *ndev, struct dl *dl){	ASSERT(ndev != NULL);	ASSERT(ndev->magic == NDEV_MAGIC);	ASSERT(dl != NULL);	ASSERT(dl->magic == DL_MAGIC);	ASSERT(dl->ndev == NULL);	dl->ndev = ndev;	dl->next_ndev = ndev->endpoints;	ndev->endpoints = dl;}/* *  ndev_free  - free netdevice * *  Not reentrant.

⌨️ 快捷键说明

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