コード例 #1
0
ファイル: hdlc.c プロジェクト: chinnyannieb/empeg-hijack
static int hdlc_set_mode(hdlc_device *hdlc, int mode)
{
	int result=-1;		/* Default to soft modes */

	if(!capable(CAP_NET_ADMIN))
		return -EPERM;

	if(hdlc_to_dev(hdlc)->flags & IFF_UP)
		return -EBUSY;

	hdlc_to_dev(hdlc)->addr_len=0;
	hdlc->mode=MODE_NONE;
  
	if (!(mode & MODE_SOFT))
		switch(mode) {
		case MODE_HDLC:
			result = hdlc->set_mode ?
				hdlc->set_mode(hdlc, MODE_HDLC) : 0;
			break;

		case MODE_X25:	/* By card */
		case MODE_CISCO:
		case MODE_PPP:
		case MODE_FR_ANSI:
		case MODE_FR_CCITT:
		case MODE_FR_ANSI  | MODE_DCE:
		case MODE_FR_CCITT | MODE_DCE:
			result = hdlc->set_mode ?
				hdlc->set_mode(hdlc, mode) : -ENOSYS;
			break;
	
		default:
			return -EINVAL;
		}

	if (result) {
		mode |= MODE_SOFT; /* Try "host software" protocol */

		switch(mode & ~MODE_SOFT) {
		case MODE_CISCO:
		case MODE_PPP:
			break;

		case MODE_FR_ANSI:
		case MODE_FR_CCITT:
		case MODE_FR_ANSI  | MODE_DCE:
		case MODE_FR_CCITT | MODE_DCE:
			hdlc_to_dev(hdlc)->addr_len=2;
			*(u16*)hdlc_to_dev(hdlc)->dev_addr=htons(LMI_DLCI);
			dlci_to_q922(hdlc_to_dev(hdlc)->broadcast, LMI_DLCI);
			break;

		default:
			return -EINVAL;
		}

		result = hdlc->set_mode ?
			hdlc->set_mode(hdlc, MODE_HDLC) : 0;
	}

	if (result)
		return result;

	hdlc->mode=mode;
	if (mode_is(hdlc, MODE_PPP))
		hdlc_to_dev(hdlc)->type=ARPHRD_PPP;
	if (mode_is(hdlc, MODE_X25))
		hdlc_to_dev(hdlc)->type=ARPHRD_X25;
	else if (mode_is(hdlc, MODE_FR))
		hdlc_to_dev(hdlc)->type=ARPHRD_FRAD;
	else			/* Conflict - raw HDLC and Cisco */
		hdlc_to_dev(hdlc)->type=ARPHRD_HDLC;
  
	memset(&(hdlc->stats), 0, sizeof(struct net_device_stats));
	destroy_pvc_list(hdlc);
	return 0;
}
コード例 #2
0
ファイル: hdlc.c プロジェクト: chinnyannieb/empeg-hijack
static int hdlc_fr_pvc(hdlc_device *hdlc, int dlci)
{
	pvc_device **pvc_p=&hdlc->first_pvc;
	pvc_device *pvc;
	int result, create=1;	/* Create or delete PVC */

	if(!capable(CAP_NET_ADMIN))
		return -EPERM;

	if(dlci<0) {
		dlci=-dlci;
		create=0;
	}

	if(dlci<=0 || dlci>=1024)
		return -EINVAL;	/* Only 10 bits for DLCI, DLCI=0 is reserved */

	if(!mode_is(hdlc, MODE_FR))
		return -EINVAL;	/* Only meaningfull on FR */
    
	while(*pvc_p) {
		if (netdev_dlci(&(*pvc_p)->netdev)==dlci)
			break;
		pvc_p=&(*pvc_p)->next;
	}

	if (create) {		/* Create PVC */
		if (*pvc_p!=NULL)
			return -EEXIST;
    
		*pvc_p=kmalloc(sizeof(pvc_device), GFP_KERNEL);
		pvc=*pvc_p;
		memset(pvc, 0, sizeof(pvc_device));
    
		pvc->netdev.name=pvc->name;
		pvc->netdev.hard_start_xmit=pvc_xmit;
		pvc->netdev.get_stats=pvc_get_stats;
		pvc->netdev.open=pvc_open;
		pvc->netdev.stop=pvc_close;
		pvc->netdev.change_mtu=pvc_change_mtu;
		pvc->netdev.mtu=PVC_MAX_MTU;
  
		pvc->netdev.type=ARPHRD_DLCI;
		pvc->netdev.hard_header_len=16;
		pvc->netdev.hard_header=fr_hard_header;
		pvc->netdev.tx_queue_len=0;
		pvc->netdev.flags=IFF_POINTOPOINT;
  
		dev_init_buffers(&pvc->netdev);

		pvc->master=hdlc;
		*(u16*)pvc->netdev.dev_addr=htons(dlci);
		dlci_to_q922(pvc->netdev.broadcast, dlci);
		pvc->netdev.addr_len=2;	/* 16 bits is enough */
		pvc->netdev.irq=hdlc_to_dev(hdlc)->irq;

		result=dev_alloc_name(&pvc->netdev, "pvc%d");
		if (result<0) {
			kfree(pvc);
			*pvc_p=NULL;
			return result;
		}

		if (register_netdevice(&pvc->netdev)!=0) {
			kfree(pvc);
			*pvc_p=NULL;
			return -EIO;
		}

		if (!mode_is(hdlc, MODE_SOFT) && hdlc->create_pvc) {
			result=hdlc->create_pvc(pvc);
			if (result) {
				unregister_netdevice(&pvc->netdev);
				kfree(pvc);
				*pvc_p=NULL;
				return result;
			}
		}

		hdlc->lmi.state |= LINK_STATE_CHANGED;
		hdlc->pvc_count++;
		return 0;
	}

	if (*pvc_p==NULL)		/* Delete PVC */
		return -ENOENT;
  
	pvc=*pvc_p;
  
	if (pvc->netdev.flags & IFF_UP)
		return -EBUSY;		/* PVC in use */
  
	if (!mode_is(hdlc, MODE_SOFT) && hdlc->destroy_pvc)
		hdlc->destroy_pvc(pvc);

	hdlc->lmi.state |= LINK_STATE_CHANGED;
	hdlc->pvc_count--;
	*pvc_p=pvc->next;
	unregister_netdevice(&pvc->netdev);
	kfree(pvc);
	return 0;
}
コード例 #3
0
ファイル: hdlc.c プロジェクト: archith/camera_project
static int hdlc_set_mode(hdlc_device *hdlc, int mode)
{
	int result = -1;	/* Default to soft modes */
	struct net_device *dev = hdlc_to_dev(hdlc);

	if(!capable(CAP_NET_ADMIN))
		return -EPERM;

	if(dev->flags & IFF_UP)
		return -EBUSY;

	dev->addr_len = 0;
	dev->hard_header = NULL;
	hdlc->mode = MODE_NONE;

	if (!(mode & MODE_SOFT))
		switch(mode & MODE_MASK) {
		case MODE_HDLC:
			result = hdlc->set_mode ?
				hdlc->set_mode(hdlc, MODE_HDLC) : 0;
			break;

		case MODE_CISCO: /* By card */
#ifdef CONFIG_HDLC_PPP
		case MODE_PPP:
#endif
#ifdef CONFIG_HDLC_X25
		case MODE_X25:
#endif
		case MODE_FR:
			result = hdlc->set_mode ?
				hdlc->set_mode(hdlc, mode) : -ENOSYS;
			break;

		default:
			return -EINVAL;
		}

	if (result) {
		mode |= MODE_SOFT; /* Try "host software" protocol */

		switch(mode & MODE_MASK) {
		case MODE_CISCO:
			dev->hard_header = cisco_hard_header;
			break;

#ifdef CONFIG_HDLC_PPP
		case MODE_PPP:
			break;
#endif
#ifdef CONFIG_HDLC_X25
		case MODE_X25:
			break;
#endif

		case MODE_FR:
			dev->hard_header = fr_hard_header;
			dev->addr_len = 2;
			*(u16*)dev->dev_addr = htons(LMI_DLCI);
			dlci_to_q922(dev->broadcast, LMI_DLCI);
			break;

		default:
			return -EINVAL;
		}

		result = hdlc->set_mode ?
			hdlc->set_mode(hdlc, MODE_HDLC) : 0;
	}

	if (result)
		return result;

	hdlc->mode = mode;
	switch(mode & MODE_MASK) {
#ifdef CONFIG_HDLC_PPP
	case MODE_PPP:   dev->type = ARPHRD_PPP;   break;
#endif
#ifdef CONFIG_HDLC_X25
	case MODE_X25:   dev->type = ARPHRD_X25;   break;
#endif
	case MODE_FR:    dev->type = ARPHRD_FRAD;  break;
	case MODE_CISCO: dev->type = ARPHRD_CISCO; break;
	default:         dev->type = ARPHRD_RAWHDLC;
	}

	memset(&(hdlc->stats), 0, sizeof(struct net_device_stats));
	destroy_pvc_list(hdlc);
	return 0;
}