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

📄 vnet.c

📁 嵌入式系统的网络仿真
💻 C
📖 第 1 页 / 共 4 页
字号:
   if (gif->pollPtr) {      *gif->pollPtr |= gif->pollMask;      if (skb_queue_len(&gif->packetQueue) >= gif->clusterCount) {         Atomic_Or(gif->actPtr, gif->actMask);      }   }   */ //chy: ???? /*#ifndef KERNEL_2_1   end_bh_atomic();#endif*/   wake_up(&gif->waitQueue);    return;    drop_packet:   dev_kfree_skb(skb);   }//int vnet_guestif_read(struct vnet_guestif *gif,struct file  *filp, char *buf, size_t count)int vnet_guestif_read(struct vnet_bolt *bolt,struct file  *filp, char *buf, size_t count){      struct vnet_guestif *gif=(struct vnet_guestif *)bolt->nut.private;   struct sk_buff *skb;   int ret;      DECLARE_WAITQUEUE(wait, current);   //struct wait_queue wait = {current, NULL, }       DBG(KERN_INFO "vnet: vnet_guestif_read begin\n");      add_wait_queue(&gif->waitQueue, &wait);   for (;;) {      current->state = TASK_INTERRUPTIBLE;      mb();      skb = skb_peek(&gif->packetQueue);      if (skb && (skb->len > count)) {         skb = NULL;         ret = -EMSGSIZE;         break;      }      ret = -EAGAIN;      skb = skb_dequeue(&gif->packetQueue);      //chy:????      /*      if (gif->pollPtr && skb_queue_empty(&gif->packetQueue)) {         *gif->pollPtr &= ~gif->pollMask;      }       */            if (skb != NULL || filp->f_flags & O_NONBLOCK) {         break;      }            ret = -EINTR;      if (signal_pending(current)) {         break;      }      schedule();   }   current->state = TASK_RUNNING;   remove_wait_queue(&gif->waitQueue, &wait);   if (! skb) {      return ret;   }        gif->stats.read++;   count = (count < skb->len) ? count : skb->len;   copy_to_user(buf, skb->data, count);   dev_kfree_skb(skb);      DBG(KERN_INFO "vnet: vnet_guestif_read end\n");   return count;}//int vnet_guestif_write(struct vnet_guestif *gif,struct file  *filp, const char *buf, size_t count)int vnet_guestif_write(struct vnet_bolt *bolt,struct file  *filp, const char *buf, size_t count){   struct vnet_guestif *gif=(struct vnet_guestif *)bolt->nut.private;   struct sk_buff *skb;   //struct vnet_hub *hub;   struct vnet_nut *peer;      DBG(KERN_INFO "vnet: vnet_guestif_write begin\n");   /*    * Check size    */      if (count < sizeof (struct ethhdr)) {      return -EINVAL;   }      /*    * Allocate an sk_buff.    */      skb = dev_alloc_skb(count + 7);   if (skb == NULL) {      // XXX obey O_NONBLOCK?      return -ENOBUFS;   }	//chy: ?????   /*#ifndef KERNEL_2_1   skb->free = 1;#endif   */      skb_reserve(skb, 2);      /*    * Copy the data and send it.    */      gif->stats.written++;   if (copy_from_user(skb_put(skb, count), buf, count)) {      return -EFAULT;   }      peer=gif->bolt.nut.peer;   if(!peer||!peer->rcv){   	printk("vnet: vnet_guestif_write gif->bolt.nut.peer or peer->rcv is NULL!!!\n");   	return -EFAULT;   }   /*   hub=(struct hub *)peer->private;   if(!hub){   	printk("vnet: vnet_guestif_write peer->private is NULL!!!\n");   	return -EFAULT;   }   */      peer->rcv(peer, skb);   DBG(KERN_INFO "vnet: vnet_guestif_write end\n");      return count;}void vnet_nut_recv(struct vnet_nut *nut, struct sk_buff *skb){  if (nut && nut->rcv &&nut->peer) {      nut->rcv(nut->peer, skb);   } else {      dev_kfree_skb(skb);   }}//int vnet_guestif_ioctl(struct vnet_guestif *gif,int vnet_guestif_ioctl(struct vnet_bolt *bolt,                struct file    *filp,                unsigned int    iocmd,                unsigned long   ioarg){	printk(KERN_INFO "vnet_guestif_ioctl isn't realized yet!!!\n");	return -EFAULT; }//int vnet_guestif_poll(struct vnet_guestif *gif,int vnet_guestif_poll(struct vnet_bolt *bolt,               		  struct file  *filp,	                  poll_table   *wait){   struct vnet_guestif *gif=(struct vnet_guestif *)bolt->nut.private;   poll_wait(filp, &gif->waitQueue, wait);   if (!skb_queue_empty(&gif->packetQueue)) {      return POLLIN;   }   return 0;}int vnet_guestif_procread(char    *page,   // IN/OUT: buffer to write into                   char   **start,  // OUT: 0 if file < 4k, else offset into page                   off_t    off,    // IN: offset of read into the file                   int      count,  // IN: maximum number of bytes to read                   int     *eof,    // OUT: TRUE if there is nothing more to read                   void    *data)   // IN: client data - not used{   struct vnet_guestif *gif = (struct vnet_guestif *)data;    int len = 0;   //chy: ???   /*   if (!gif|| !VNetGrabJacks(&gif->bolt.nut)) {      return len;   }   */   if(!gif){   	 printk("vnet: vnet_guestif_procread gif is NULL!!!\n");   	 return 0;   }      len += vnet_bolt_print(&gif->bolt, page+len);   //chy: ???   //VNetReleaseJacks(&gif->bolt.nut);      len += sprintf(page+len, "read %u written %u queued %u ",                  gif->stats.read,                  gif->stats.written,                  gif->stats.queued);      len += sprintf(page+len, "dropped.down %u dropped.mismatch %u dropped.overflow %u ",                  gif->stats.droppedDown,                  gif->stats.droppedMismatch,                  gif->stats.droppedOverflow);   len += sprintf(page+len, "\n");      *start = 0;   *eof   = 1;   return len;}int vnet_guestif_create(struct vnet_bolt **ret){   struct vnet_guestif *gif = NULL;   static unsigned id = 0;   int retval;      DBG(KERN_INFO "vnet: vnet_guestif_create begin\n");   gif = (struct vnet_guestif *)kmalloc(sizeof(struct vnet_guestif), GFP_KERNEL);   if (!gif) {      return -ENOMEM;   }   /*    * Initialize fields.    */   gif->bolt.nut.type=VNET_GUESTIF_NUT;   gif->bolt.id = id++;   gif->bolt.nut.peer = NULL;   gif->bolt.nut.numbolts = 1;   sprintf(gif->bolt.nut.name, "gif%d", gif->bolt.id);   gif->bolt.nut.private = gif;   gif->bolt.nut.refCount = 0;   gif->bolt.nut.connected = FALSE;   gif->bolt.nut.index = 0;   gif->bolt.nut.procEntry = NULL;   gif->bolt.nut.free = vnet_gusetif_free;   init_waitqueue_head(&gif->bolt.nut.waitQueue);   gif->bolt.nut.rcv = vnet_guestif_recv;   gif->bolt.nut.cycleDetect = NULL;   gif->bolt.nut.boltsChanged = NULL;   gif->bolt.nut.isBridged = NULL;   gif->pollPtr = NULL;   gif->clusterCount = 0;   gif->pollMask = 0;   /*    * Make proc entry for this nut.    */     retval = vnet_procfs_makeentry(NULL, gif->bolt.nut.name, S_IFREG,                               &gif->bolt.nut.procEntry);   if (retval) {         kfree(gif);         return retval;   } else {         gif->bolt.nut.procEntry->read_proc = vnet_guestif_procread;      	 gif->bolt.nut.procEntry->data = gif;   }   /*    * Rest of fields.    */      gif->bolt.flags = IFF_RUNNING;   //chy: the padr is not allocated now   memset(gif->bolt.paddr, 0, sizeof gif->bolt.paddr);   memset(gif->bolt.ladrf, 0, sizeof gif->bolt.ladrf);   gif->bolt.fileOpRead = vnet_guestif_read;   gif->bolt.fileOpWrite = vnet_guestif_write;   gif->bolt.fileOpIoctl = vnet_guestif_ioctl;   gif->bolt.fileOpSelect = vnet_guestif_poll;      skb_queue_head_init(&(gif->packetQueue));   init_waitqueue_head(&gif->waitQueue);   memset(&gif->stats, 0, sizeof(struct vnet_guestif_stats));      *ret = (struct vnet_bolt*)gif;   DBG(KERN_INFO "vnet: vnet_guestif_create end\n");   return 0;}/* *---------------------------------------------------------------------- * * VNetgifFree -- * *      Free the user interface port. * * Results:  *      None. * * Side effects: *      None. * *---------------------------------------------------------------------- */void vnet_guestif_free(struct vnet_guestif *gif){   struct sk_buff *skb;      DBG(KERN_INFO "vnet: vnet_guestif_free begin\n");   for (;;) {      skb = skb_dequeue(&gif->packetQueue);      if (skb == NULL) {	 break;      }      dev_kfree_skb(skb);   }//chy: do it in future/*      if (gif->pollPtr) {      VNetgifUnmapPollPtr(gif);      gif->clusterCount = 0;   }*/   if (gif->bolt.nut.procEntry) {      vnet_procfs_removeentry(gif->bolt.nut.procEntry, NULL);   }   kfree(gif);   DBG(KERN_INFO "vnet: vnet_guestif_free end\n");}static void vnet_nut_release(struct vnet_nut *nut){   spin_lock_bh(&vnet_nutLock);      nut->refCount--;         nut->peer->refCount--;   if (nut->refCount == 0) {     wake_up(&nut->waitQueue);   }   if (nut->peer->refCount == 0) {     wake_up(&nut->peer->waitQueue);   }   spin_unlock_bh(&vnet_nutLock);}static void vnet_bolt_addtolist(struct vnet_bolt *bolt){   spin_lock(&vnet_boltLock);      bolt->next = vnet_bolthead;   vnet_bolthead = bolt;      spin_unlock(&vnet_boltLock);}static  void vnet_bolt_removefromlist(struct vnet_bolt *bolt){  struct vnet_bolt **p;   spin_lock(&vnet_boltLock);      for (p = &vnet_bolthead; *p; p = &(*p)->next) {      if (*p == bolt) {         *p = bolt->next;         break;      }   }   spin_unlock(&vnet_boltLock);}static inline void vnet_bolt_free(struct vnet_bolt *this){  DBG(KERN_INFO "vnet: vnet_bolt_free begin, no use\n");	  /*  if(!this){  	kfree(this);  }  */}int vnet_nut_print(struct vnet_nut *nut, char * buf){   int len = 0;      if (!nut->peer) {      len += sprintf(buf+len, "connected not ");   } else {      len += sprintf(buf+len, "connected %s ", nut->peer->name);   }   return len;}static int vnet_bolt_print(struct vnet_bolt *bolt, char * buf){   int len = 0;   len += vnet_nut_print(&bolt->nut, buf+len);   //chy:maybe do in future   //len += VNetPrintPIDs(bolt, buf+len);   len += sprintf(buf+len, "mac %02x:%02x:%02x:%02x:%02x:%02x ",                  bolt->paddr[0], bolt->paddr[1], bolt->paddr[2],                   bolt->paddr[3], bolt->paddr[4], bolt->paddr[5]);   len += sprintf(buf+len, "ladrf %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x ",                  bolt->ladrf[0], bolt->ladrf[1], bolt->ladrf[2],                  bolt->ladrf[3], bolt->ladrf[4], bolt->ladrf[5],                  bolt->ladrf[6], bolt->ladrf[7]);   len += sprintf(buf+len, "flags IFF_RUNNING");      if (bolt->flags & IFF_UP) {      len += sprintf(buf+len, ",IFF_UP");         }   if (bolt->flags & IFF_BROADCAST) {      len += sprintf(buf+len, ",IFF_BROADCAST");         }   if (bolt->flags & IFF_DEBUG) {      len += sprintf(buf+len, ",IFF_DEBUG");         }   if (bolt->flags & IFF_PROMISC) {      len += sprintf(buf+len, ",IFF_PROMISC");         }   if (bolt->flags & IFF_MULTICAST) {      len += sprintf(buf+len, ",IFF_MULTICAST");         }   if (bolt->flags & IFF_ALLMULTI) {      len += sprintf(buf+len, ",IFF_ALLMULTI");         }   len += sprintf(buf+len, " ");      return len;}              

⌨️ 快捷键说明

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