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

📄 device.c

📁 cipe 编程
💻 C
📖 第 1 页 / 共 2 页
字号:
    if (copy_to_user((void*)ifr->ifr_data, (void*)&parm,                \                     sizeof(parm)))                                     \        e=-EFAULT;                                                      \    goto out;                                                           \  }#else    if (!suser())	return -EPERM;#define doioctl(nam,fun,str) {                                              \    struct str parm;                                                        \    dprintk(DEB_CALL, (KERN_INFO "%s: " nam "\n", dev->name));              \    if ((e=verify_area(VERIFY_READ, ifr->ifr_data, sizeof(parm)))<0)        \        goto out;                                                           \    memcpy_fromfs((void*)&parm, (void*)ifr->ifr_data, sizeof(parm));        \    if (parm.magic!=VERSION_MAGIC) {                                        \        printk(KERN_WARNING "%s: ciped version mismatch\n", dev->name);     \        e=-EINVAL; goto out; }                                              \    if ((e=fun(dev, &parm))<0)                                              \        goto out;                                                           \    if ((e=verify_area(VERIFY_WRITE, ifr->ifr_data, sizeof(parm)))<0)       \        goto out;                                                           \    memcpy_tofs((void*)ifr->ifr_data, (void*)&parm, sizeof(parm));          \    goto out;                                                               \  }#endif    /*cipe_use_module();*/    switch (cmd) {#ifdef SIOCGIFCIPPAR    case SIOCGIFCIPPAR:	doioctl("getpar", cipe_getpar, siocgifcippar);#endif    case SIOCSIFCIPPAR:	doioctl("setpar", cipe_setpar, siocsifcippar);    case SIOCSIFCIPKEY:	doioctl("setkey", cipe_setkey, siocsifcipkey);    case SIOCSIFCIPATT:	doioctl("attach", cipe_attach, siocsifcipatt);    case SIOCSIFCIPALL:	doioctl("alloc", cipe_alloc, siocsifcipall);    case SIOCSIFCIPUNA:	doioctl("unalloc", cipe_unalloc, siocsifcipall);    /* default: e=-EINVAL; */    } out:    /*cipe_unuse_module();*/    return e;#undef doioctl}int cipe_dev_open(struct NET_DEVICE *dev){    DEVTOCIPE(dev,c,-ENODEV);    if (!c->sock)	return -ENXIO;    dprintk(DEB_CALL, (KERN_INFO "%s: opened\n", dev->name));    return 0;}void cipe_close(struct cipe *c){    dprintk(DEB_CALL, (KERN_INFO "%s: closed\n", c->dev->name));    cipe_zero_c(c);    cipe_unuse_module();}int cipe_dev_close(struct NET_DEVICE *dev){    struct cipe *c = (struct cipe*)(dev->priv);    if ((!c) || (c->magic!=CIPE_MAGIC)) {	printk(KERN_WARNING "%s: cipe_dev_close: no valid struct\n",               dev->name);	return 0;    }    if (c->sock) {	dprintk(DEB_CALL, (KERN_INFO "%s: closing\n", c->dev->name));	/* Tell the attached socket we're going down */	SOCK(c)->sk_shutdown=SHUTDOWN_MASK;	SOCK(c)->sk_zapped=1;	SOCK(c)->sk_err=ENXIO;	SOCK(c)->sk_error_report(SOCK(c));#ifdef LINUX_21	if (!cipe_owner(c)) {	    /* SHOULD NOT HAPPEN. Socket is probably left orphaned.	       This is really only an emergency path to allow closing	       the device after an Oops. */	    printk(KERN_ERR "cipe_dev_close: not owned??\n");	    cipe_close(c);	}#endif    } else {	cipe_close(c);    }    return 0;}struct DEV_STATS *cipe_get_stats(struct NET_DEVICE *dev){    DEVTOCIPE(dev,c,NULL);    return &(c->stat);}int cipe_set_mac(struct NET_DEVICE *dev, void *p){    struct sockaddr *addr=p;    memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);    return 0;}/*** Initialization and finalization stuff ***/#ifndef LINUX_21static inline void dev_init_buffers(struct NET_DEVICE *dev){    int i;    for (i = 0; i < DEV_NUMBUFFS; i++)  {        skb_queue_head_init(&dev->buffs[i]);    }}#endifstatic int cipe_init_dev(struct NET_DEVICE *dev){    struct cipe *c = (struct cipe*)(dev->priv);    if (!c)	return -ENODEV;    memset(c, 0, sizeof(struct cipe)); /* zero the device struct along */    c->magic       = CIPE_MAGIC;    c->dev         = dev;    cipe_zero_c(c);    /* Device parameters. */#ifdef VER_ETH    ether_setup(dev); /* sets hard_header etc. */#endif    /* Procedural */    dev->open                   = cipe_dev_open;    dev->stop                   = cipe_dev_close;    dev->hard_start_xmit        = cipe_xmit;    dev->set_mac_address	= cipe_set_mac;    dev->do_ioctl               = cipe_dev_ioctl;    dev->get_stats              = cipe_get_stats;    /* "Hardware" */#ifndef VER_ETH    dev->type		        = ARPHRD_TUNNEL;    dev->hard_header_len        = 0; /* we copy anyway to expand */    dev->tx_queue_len	        = 100; /* matches ethernet */#endif    dev->mtu		        = ETH_DATA_LEN                                     -sizeof(struct sockshdr)                                     -cipehdrlen                                     -cipefootlen                                     -MAXIVSIZE;    /* cannot use c->cipher->ivsize here because not initialized */#ifdef LINUX_21    dev->iflink         = -1;#else    dev->family		= AF_INET;    dev->pa_alen	= 4;    dev->metric         = 1;#endif#ifndef LINUX_25    dev_init_buffers(dev);#endif    /* New-style flags */#ifndef VER_ETH    dev->flags		= IFF_POINTOPOINT|IFF_NOARP;#endif    return 0;}#ifndef LINUX_21struct semaphore cipe_alloc_sem=MUTEX;#endifstatic int cipe_alloc_dev(int n){    int e=0;    struct cipe_ctrl *cc;    struct NET_DEVICE *d;    dprintk(DEB_CALL, (KERN_INFO DEVNAME ": cipe_alloc_dev %d\n", n));    if (!(cc=kmalloc(sizeof(struct cipe_ctrl), GFP_KERNEL))) {        cipe_ctrls[n]=NULL;	printk(KERN_ERR DEVNAME ": failed to allocate device %d\n", n);        return -ENOMEM;    }    memset((void *)cc, 0, sizeof(*cc));/* If this doesn't compile, define or undefine HAVE_DEVNAME_ARRAY   in cipe.h accordingly. */#ifdef HAVE_DEVNAME_ARRAY    sprintf(cc->dev.name, DEVNAME "%d", n);#else    sprintf(cc->name, DEVNAME "%d", n);    cc->dev.name      = cc->name;#endif    cc->dev.base_addr = n; /* dummy */    cc->dev.priv      = (void*)cc;    cc->dev.next      = NULL;    cc->dev.init      = cipe_init_dev; /* called by register_netdevice */#if 1    /* Generate a dummy MAC address. This code seems to be in accordance       to the address assignments as of RFC1700, pp.172f.       We use 00-00-5E-vv-nn-zz with       vv=1pppccc0, p=protocol, c=crypto,       nn=device number, zz=from MAC of first eth device.    */    cc->dev.dev_addr[2]=0x5E;    cc->dev.dev_addr[3]=0x80+(ProtocolVersion<<4)+(CRNUM<<1);    cc->dev.dev_addr[4]=n;    for (d=dev_base; d; d=d->next)	if (d->type==ARPHRD_ETHER) {	    cc->dev.dev_addr[5]=d->dev_addr[5];	    break;	}#else    /* MAC address will be generated from IP as with PLIP. FC-FC-ip-ip-ip-ip */    cc->dev.dev_addr[1]=cc->dev.dev_addr[0]=0xFC;#endif    memset(cc->dev.broadcast, 0xFF, ETH_ALEN);    cc->dev.addr_len=ETH_ALEN;    e=register_netdevice(&(cc->dev));    if (e<0) {	kfree(cc);	printk(KERN_ERR	       "%s: register_netdevice() failed\n", cc->dev.name);        cc=NULL;    } else {        cc->cipe.owner=current->pid;    }    cipe_ctrls[n]=cc;    return e;}static void cipe_unalloc_dev(int n){    struct cipe_ctrl *cc=cipe_ctrls[n];    if (!cc)	return;    dprintk(DEB_CALL, (KERN_INFO DEVNAME ": cipe_unalloc_dev %d\n", n));    if (cc->cipe.magic!=CIPE_MAGIC) {        printk(KERN_WARNING DEVNAME ": Ouch: cipe_unalloc_dev() wrong struct\n");        return;    }    unregister_netdevice(&(cc->dev));    cipe_ctrls[n]=NULL;#ifndef LINUX_21    kfree(cc);#endif}/* For Linux 2.2 and later, the struct cipe_ctrl is freed   via a notifier. */#ifdef LINUX_21static int cipe_netdev_event(struct notifier_block *this, unsigned long event, void *ptr){    struct NET_DEVICE *dev = ptr;    if (event == NETDEV_UNREGISTER) {        struct cipe_ctrl *cc = (struct cipe_ctrl *)dev->priv;        if (cc->cipe.magic!=CIPE_MAGIC) {            printk(KERN_WARNING DEVNAME ": Ouch: cipe_netdev_event() wrong struct\n");        } else {            printk(KERN_DEBUG DEVNAME ": freeing %s\n", cc->dev.name);            kfree(cc);        }    }    return NOTIFY_DONE;}static struct notifier_block netdev_notifier = {        .notifier_call  = cipe_netdev_event,};#endifint init_module(void){    int e=cipe_check_kernel();    if (e<0)	return e;    /* sanity check on insmod-provided data */    if (cipe_maxdev<1)  cipe_maxdev=1;#ifdef NO_DYNDEV    if (cipe_maxdev>100) cipe_maxdev=100;#else    if (cipe_maxdev>10000) cipe_maxdev=10000;#endif#ifdef DEBUG    printk(KERN_INFO	   DEVNAME ": CIPE driver vers %s (c) Olaf Titz 1996-2003, %d channels, debug=%d\n",	   driver_version, cipe_maxdev, cipe_debug);#else    printk(KERN_INFO	   DEVNAME ": CIPE driver vers %s (c) Olaf Titz 1996-2003, %d channels\n",	   driver_version, cipe_maxdev);#endif    prnseed=(~jiffies)^CURRENT_TIME_SEC;    cipe_ctrls = (struct cipe_ctrl **) kmalloc(sizeof(void*)*cipe_maxdev,					       GFP_KERNEL);    if (!cipe_ctrls) {	printk(KERN_ERR	       DEVNAME ": failed to allocate master control structure\n");	return -ENOMEM;    }    memset(cipe_ctrls, 0, sizeof(void*)*cipe_maxdev);#ifdef LINUX_21    register_netdevice_notifier(&netdev_notifier);#endif#ifdef NO_DYNDEV    {        int i;	rtnl_LOCK();        for (i=0; i<cipe_maxdev; ++i)            if ((e=cipe_alloc_dev(i))) {		rtnl_UNLOCK();                return e;	    }	rtnl_UNLOCK();        return 0;    }#else    rtnl_LOCK();    e=cipe_alloc_dev(0);    rtnl_UNLOCK();    return e;#endif}void cleanup_module(void){    int i;    rtnl_LOCK();    for (i=0; i<cipe_maxdev; ++i)	cipe_unalloc_dev(i);    rtnl_UNLOCK();#ifdef LINUX_21    unregister_netdevice_notifier(&netdev_notifier);#endif    kfree(cipe_ctrls);}

⌨️ 快捷键说明

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