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

📄 net_io.c

📁 思科路由器仿真器,用来仿7200系列得,可以在电脑上模拟路由器-Cisco router simulator, used to fake a 7200 series can be simulated
💻 C
📖 第 1 页 / 共 3 页
字号:
   }   strcpy(nged->dev_name,dev_name);   if (!(nged->pcap_dev = gen_eth_init(dev_name))) {      netio_free(nio,NULL);      return NULL;   }   nio->type     = NETIO_TYPE_GEN_ETH;   nio->send     = (void *)netio_geneth_send;   nio->recv     = (void *)netio_geneth_recv;   nio->save_cfg = netio_geneth_save_cfg;   nio->dptr     = &nio->u.nged;   if (netio_record(nio) == -1) {      netio_free(nio,NULL);      return NULL;   }   return nio;}#endif /* GEN_ETH *//* * ========================================================================= * FIFO Driver (intra-hypervisor communications) * ========================================================================= *//* Extract the first packet of the FIFO */static netio_fifo_pkt_t *netio_fifo_extract_pkt(netio_fifo_desc_t *nfd){    netio_fifo_pkt_t *p;         if (!(p = nfd->head))      return NULL;   nfd->pkt_count--;   nfd->head = p->next;   if (!nfd->head)      nfd->last = NULL;   return p;}/* Insert a packet into the FIFO (in tail) */static void netio_fifo_insert_pkt(netio_fifo_desc_t *nfd,netio_fifo_pkt_t *p){      pthread_mutex_lock(&nfd->lock);   nfd->pkt_count++;   p->next = NULL;   if (nfd->last) {      nfd->last->next = p;   } else {      nfd->head = p;   }   nfd->last = p;   pthread_mutex_unlock(&nfd->lock);}/* Free the packet list */static void netio_fifo_free_pkt_list(netio_fifo_desc_t *nfd){   netio_fifo_pkt_t *p,*next;      for(p=nfd->head;p;p=next) {      next = p->next;      free(p);   }   nfd->head = nfd->last = NULL;   nfd->pkt_count = 0;}/* Establish a cross-connect between two FIFO NetIO */int netio_fifo_crossconnect(netio_desc_t *a,netio_desc_t *b){   netio_fifo_desc_t *pa,*pb;   if ((a->type != NETIO_TYPE_FIFO) || (b->type != NETIO_TYPE_FIFO))      return(-1);   pa = &a->u.nfd;   pb = &b->u.nfd;   /* A => B */   pthread_mutex_lock(&pa->endpoint_lock);   pthread_mutex_lock(&pa->lock);   pa->endpoint = pb;   netio_fifo_free_pkt_list(pa);   pthread_mutex_unlock(&pa->lock);   pthread_mutex_unlock(&pa->endpoint_lock);   /* B => A */   pthread_mutex_lock(&pb->endpoint_lock);   pthread_mutex_lock(&pb->lock);   pb->endpoint = pa;   netio_fifo_free_pkt_list(pb);   pthread_mutex_unlock(&pb->lock);   pthread_mutex_unlock(&pb->endpoint_lock);   return(0);}/* Unbind an endpoint */static void netio_fifo_unbind_endpoint(netio_fifo_desc_t *nfd){   pthread_mutex_lock(&nfd->endpoint_lock);   nfd->endpoint = NULL;   pthread_mutex_unlock(&nfd->endpoint_lock);}/* Free a NetIO FIFO descriptor */static void netio_fifo_free(netio_fifo_desc_t *nfd){   if (nfd->endpoint)      netio_fifo_unbind_endpoint(nfd->endpoint);   netio_fifo_free_pkt_list(nfd);   pthread_mutex_destroy(&nfd->lock);   pthread_cond_destroy(&nfd->cond);}/* Send a packet (to the endpoint FIFO) */static ssize_t netio_fifo_send(netio_fifo_desc_t *nfd,void *pkt,size_t pkt_len){   netio_fifo_pkt_t *p;   size_t len;   pthread_mutex_lock(&nfd->endpoint_lock);   /* The cross-connect must have been established before */   if (!nfd->endpoint)      goto error;   /* Allocate a a new packet and insert it into the endpoint FIFO */   len = sizeof(netio_fifo_pkt_t) + pkt_len;   if (!(p = malloc(len)))      goto error;   memcpy(p->pkt,pkt,pkt_len);   p->pkt_len = pkt_len;   netio_fifo_insert_pkt(nfd->endpoint,p);   pthread_cond_signal(&nfd->endpoint->cond);   pthread_mutex_unlock(&nfd->endpoint_lock);   return(pkt_len); error:   pthread_mutex_unlock(&nfd->endpoint_lock);   return(-1);}/* Read a packet from the local FIFO queue */static ssize_t netio_fifo_recv(netio_fifo_desc_t *nfd,void *pkt,size_t max_len){   struct timespec ts;    m_tmcnt_t expire;   netio_fifo_pkt_t *p;   size_t len = -1;   /* Wait for the endpoint to signal a new arriving packet */   expire = m_gettime_usec() + 50000;   ts.tv_sec = expire / 1000000;   ts.tv_nsec = (expire % 1000000) * 1000;   pthread_mutex_lock(&nfd->lock);   pthread_cond_timedwait(&nfd->cond,&nfd->lock,&ts);   /* Extract a packet from the list */   p = netio_fifo_extract_pkt(nfd);   pthread_mutex_unlock(&nfd->lock);   if (p) {      len = m_min(p->pkt_len,max_len);      memcpy(pkt,p->pkt,len);      free(p);   }      return(len);}/* Create a new NetIO descriptor with FIFO method */netio_desc_t *netio_desc_create_fifo(char *nio_name){   netio_fifo_desc_t *nfd;   netio_desc_t *nio;      if (!(nio = netio_create(nio_name)))      return NULL;   nfd = &nio->u.nfd;   pthread_mutex_init(&nfd->lock,NULL);   pthread_mutex_init(&nfd->endpoint_lock,NULL);   pthread_cond_init(&nfd->cond,NULL);   nio->type = NETIO_TYPE_FIFO;   nio->send = (void *)netio_fifo_send;   nio->recv = (void *)netio_fifo_recv;   nio->dptr = nfd;   if (netio_record(nio) == -1) {      netio_free(nio,NULL);      return NULL;   }   return nio;}/* * ========================================================================= * NULL Driver (does nothing, used for debugging) * ========================================================================= */static ssize_t netio_null_send(void *null_ptr,void *pkt,size_t pkt_len){   return(pkt_len);}static ssize_t netio_null_recv(void *null_ptr,void *pkt,size_t max_len){   usleep(200000);   return(-1);}static void netio_null_save_cfg(netio_desc_t *nio,FILE *fd){   fprintf(fd,"nio create_null %s\n",nio->name);}/* Create a new NetIO descriptor with NULL method */netio_desc_t *netio_desc_create_null(char *nio_name){   netio_desc_t *nio;      if (!(nio = netio_create(nio_name)))      return NULL;   nio->type     = NETIO_TYPE_NULL;   nio->send     = (void *)netio_null_send;   nio->recv     = (void *)netio_null_recv;   nio->save_cfg = netio_null_save_cfg;   nio->dptr     = NULL;   if (netio_record(nio) == -1) {      netio_free(nio,NULL);      return NULL;   }   return nio;}/* Free a NetIO descriptor */static int netio_free(void *data,void *arg){   netio_desc_t *nio = data;   if (nio) {      netio_filter_unbind(nio,NETIO_FILTER_DIR_RX);      netio_filter_unbind(nio,NETIO_FILTER_DIR_TX);      switch(nio->type) {         case NETIO_TYPE_UNIX:            netio_unix_free(&nio->u.nud);            break;         case NETIO_TYPE_VDE:            netio_vde_free(&nio->u.nvd);            break;         case NETIO_TYPE_TAP:            netio_tap_free(&nio->u.ntd);            break;         case NETIO_TYPE_TCP_CLI:         case NETIO_TYPE_TCP_SER:            netio_tcp_free(&nio->u.nid);            break;         case NETIO_TYPE_UDP:            netio_udp_free(&nio->u.nid);            break;#ifdef LINUX_ETH         case NETIO_TYPE_LINUX_ETH:            netio_lnxeth_free(&nio->u.nled);            break;#endif#ifdef GEN_ETH         case NETIO_TYPE_GEN_ETH:            netio_geneth_free(&nio->u.nged);            break;#endif         case NETIO_TYPE_FIFO:            netio_fifo_free(&nio->u.nfd);            break;         case NETIO_TYPE_NULL:                       break;         default:            fprintf(stderr,"NETIO: unknown descriptor type %u\n",nio->type);      }      free(nio->name);      free(nio);   }   return(TRUE);}/* * ========================================================================= * RX Listeners * ========================================================================= *//* Find a RX listener */static inline struct netio_rx_listener *netio_rxl_find(netio_desc_t *nio){   struct netio_rx_listener *rxl;   for(rxl=netio_rxl_list;rxl;rxl=rxl->next)      if (rxl->nio == nio)         return rxl;   return NULL;}/* Remove a NIO from the listener list */static int netio_rxl_remove_internal(netio_desc_t *nio){   struct netio_rx_listener *rxl;   int res = -1;   if ((rxl = netio_rxl_find(nio))) {      /* we suppress this NIO only when the ref count hits 0 */      rxl->ref_count--;      if (!rxl->ref_count) {         /* remove this listener from the double linked list */         if (rxl->next)            rxl->next->prev = rxl->prev;               if (rxl->prev)            rxl->prev->next = rxl->next;         else            netio_rxl_list = rxl->next;         /* if this is non-FD NIO, wait for thread to terminate */         if (netio_get_fd(rxl->nio) == -1) {            rxl->running = FALSE;            pthread_join(rxl->spec_thread,NULL);         }                  free(rxl);      }      res = 0;   }      return(res);}/* Add a RXL listener to the listener list */static void netio_rxl_add_internal(struct netio_rx_listener *rxl){     struct netio_rx_listener *tmp;      if ((tmp = netio_rxl_find(rxl->nio))) {      tmp->ref_count++;      free(rxl);   } else {      rxl->prev = NULL;      rxl->next = netio_rxl_list;      if (rxl->next) rxl->next->prev = rxl;      netio_rxl_list = rxl;   }}/* RX Listener dedicated thread (for non-FD NIO) */static void *netio_rxl_spec_thread(void *arg){   struct netio_rx_listener *rxl = arg;   u_char pkt[NETIO_MAX_PKT_SIZE];   ssize_t pkt_len;   while(rxl->running) {      pkt_len = netio_recv(rxl->nio,pkt,sizeof(pkt));      if (pkt_len > 0)         rxl->rx_handler(rxl->nio,pkt,pkt_len,rxl->arg1,rxl->arg2);   }   return NULL;}/* RX Listener General Thread */void *netio_rxl_gen_thread(void *arg){    struct netio_rx_listener *rxl;   u_char pkt[NETIO_MAX_PKT_SIZE];   ssize_t pkt_len;   netio_desc_t *nio;   struct timeval tv;   int fd,fd_max,res;   fd_set rfds;   for(;;) {      NETIO_RXL_LOCK();      NETIO_RXQ_LOCK();      /* Add the new waiting NIO to the active list */      while(netio_rxl_add_list != NULL) {         rxl = netio_rxl_add_list;         netio_rxl_add_list = netio_rxl_add_list->next;         netio_rxl_add_internal(rxl);      }      /* Delete the NIO present in the remove list */      while(netio_rxl_remove_list != NULL) {         nio = netio_rxl_remove_list;         netio_rxl_remove_list = netio_rxl_remove_list->rxl_next;         netio_rxl_remove_internal(nio);      }      pthread_cond_broadcast(&netio_rxl_cond);      NETIO_RXQ_UNLOCK();      /* Build the FD set */      FD_ZERO(&rfds);      fd_max = -1;      for(rxl=netio_rxl_list;rxl;rxl=rxl->next) {         if ((fd = netio_get_fd(rxl->nio)) == -1)            continue;         if (fd > fd_max) fd_max = fd;         FD_SET(fd,&rfds);      }      NETIO_RXL_UNLOCK();      /* Wait for incoming packets */      tv.tv_sec = 0;      tv.tv_usec = 20 * 1000;  /* 200 ms */      res = select(fd_max+1,&rfds,NULL,NULL,&tv);      if (res == -1) {         if (errno != EINTR)            perror("netio_rxl_thread: select");         continue;      }      /* Examine active FDs and call user handlers */      NETIO_RXL_LOCK();      for(rxl=netio_rxl_list;rxl;rxl=rxl->next) {         if ((fd = netio_get_fd(rxl->nio)) == -1)            continue;         if (FD_ISSET(fd,&rfds)) {            pkt_len = netio_recv(rxl->nio,pkt,sizeof(pkt));            if (pkt_len > 0)               rxl->rx_handler(rxl->nio,pkt,pkt_len,rxl->arg1,rxl->arg2);         }      }      NETIO_RXL_UNLOCK();   }      return NULL;}/* Add a RX listener in the listener list */int netio_rxl_add(netio_desc_t *nio,netio_rx_handler_t rx_handler,                  void *arg1,void *arg2){   struct netio_rx_listener *rxl;   NETIO_RXQ_LOCK();   if (!(rxl = malloc(sizeof(*rxl)))) {      NETIO_RXQ_UNLOCK();      fprintf(stderr,"netio_rxl_add: unable to create structure.\n");      return(-1);   }   memset(rxl,0,sizeof(*rxl));   rxl->nio = nio;   rxl->ref_count = 1;   rxl->rx_handler = rx_handler;   rxl->arg1 = arg1;   rxl->arg2 = arg2;   rxl->running = TRUE;   if ((netio_get_fd(rxl->nio) == -1) &&       pthread_create(&rxl->spec_thread,NULL,netio_rxl_spec_thread,rxl))    {      NETIO_RXQ_UNLOCK();      fprintf(stderr,"netio_rxl_add: unable to create specific thread.\n");      free(rxl);      return(-1);   }   rxl->next = netio_rxl_add_list;   netio_rxl_add_list = rxl;   pthread_cond_wait(&netio_rxl_cond,&netio_rxq_mutex);   NETIO_RXQ_UNLOCK();   return(0);}/* Remove a NIO from the listener list */int netio_rxl_remove(netio_desc_t *nio){   NETIO_RXQ_LOCK();   nio->rxl_next = netio_rxl_remove_list;   netio_rxl_remove_list = nio;   pthread_cond_wait(&netio_rxl_cond,&netio_rxq_mutex);   NETIO_RXQ_UNLOCK();   return(0);}/* Initialize the RXL thread */int netio_rxl_init(void){   pthread_cond_init(&netio_rxl_cond,NULL);   if (pthread_create(&netio_rxl_thread,NULL,netio_rxl_gen_thread,NULL)) {      perror("netio_rxl_init: pthread_create");      return(-1);   }   return(0);}

⌨️ 快捷键说明

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