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

📄 vapornet.c

📁 wm PNE 3.3 source code, running at more than vxworks6.x version.
💻 C
📖 第 1 页 / 共 2 页
字号:
	  ctl->remote_exists = 1;      }    }    closedir(dd);    ctl->bcast_mtime = st.st_mtime;    ctl->nbcasts = n;  } else {    n = ctl->nbcasts;  }  for (i = 0; i < n; i++)    idx[i] = i;  if (n) {    while (n > 0) {      i = random() % n;      vp_unicast(ctl, p, ctl->bcasts[idx[i]]);      idx[i] = idx[--n];    }  }  else {    /* We might have an unnumbered link to send to */    if (ctl->remote_exists)      vp_link_send(ctl, p);  }}/* * Process an outgoing Attache IP packet.  Since we just drop packets * that we can't send right away, we may as well do this directly * from the driver rather than maintaining an output queue. * * Except that sometimes it's weirder when we're simulating a bad link. */static void vp_ip_send_handler(struct timer *tm, void *cookie){  packet *p = cookie, **pp;  struct net *net = p->pkt_n;  struct bsdif *bif = net->specific;  struct vp_ctl *ctl = bif->private;  struct vp_lnh *lh = (struct vp_lnh *) (p->pkt_buffer);  inaddr_t host = lh->host;  int drop = 0;  if (ctl) {    /*     * Packet dropping to simulate bad networks.     * Yes, thank you, I am making this up as I go along.     */    ctl->drop_count++;    switch (ctl->drop_p1) {     case 1:      /*       * Drop nth packet.  p2 specifies n, p2 specifies whether       * we're dropping every-nth or just first-nth.       */      if (ctl->drop_count % ctl->drop_p2 == 0) {	drop = 1;	if (!ctl->drop_p3)	  ctl->drop_p1 = 0;      }      break;     case 2:      /*       * Drop p2/p3 of the packets, pseudo-randomly.       */      if (random() % ctl->drop_p3 < ctl->drop_p2)	drop = 1;      break;    }    /*     * Send the packet in the right way, unless we're dropping it.     */    if (!drop) {      if (ctl->pktlog)	vp_log_packet(ctl->pktlog, p);      if ((p->pkt_flags & (PF_TX_BROADCAST | PF_TX_MULTICAST)) != 0)	vp_broadcast(ctl, p);      else if (ctl->remote_exists && ctl->local_exists) 	vp_link_send(ctl, p);      else	vp_unicast(ctl, p, host);    }#if 0    else {      printf("[Dropping packet #%lu (%s)]\n", ctl->drop_count, net->s_name);    }#endif    /*     * Unlink packet from the gc chain.     */    for (pp = &ctl->opkts; *pp; pp = &(*pp)->pkt_link) {      if (*pp == p) {	*pp = p->pkt_link;	break;      }    }  }  /*   * Free the packet no matter what else we do.   */  pkt_free(p);}static void vp_ip_send(struct net *net, packet *p, inaddr_t host){  struct bsdif *bif = net->specific;  struct vp_ctl *ctl = bif->private;  struct vp_lnh *lh = (struct vp_lnh *) (p->pkt_buffer);  if (!ctl) {    pkt_free(p);    return;  }  etc_tm_init(&lh->tm);  lh->tm.handler = vp_ip_send_handler;  lh->tm.cookie = p;  lh->host = host;  p->pkt_n = net;  p->pkt_link = ctl->opkts;  ctl->opkts = p;  if (ctl->jitter)    etc_tm_set(&lh->tm, ctl->delay + random() % ctl->jitter);  else if (ctl->delay)    etc_tm_set(&lh->tm, ctl->delay);  else    lh->tm.handler(&lh->tm, lh->tm.cookie);}/* * The parameters set in this function all degrade the virtual network * simulated by this code in various ways that may be useful when * testing/debugging.  Leaving all of these parameters in their default * (zero) state yields the best network we can simulate (no delays, * packets dropped only when the underlying IPC decides to drop them). */static void vp_ip_send_config  (struct vp_ctl *ctl, struct ini_handle *ini_handle){  char *s, varname[20];  /*   * Delay each outbound packet by a fixed number of milliseconds.   * This and "jitter" are additive.   */  sprintf(varname, "%s-delay", ctl->net->s_name);  if ((s = ini_lookup(ini_handle, attache_section, varname)) != 0)    sscanf(s, "%lu", &ctl->delay);  /*   * Delay each outbound packet by a pseudorandom number of milliseconds   * in the range from zero to (n - 1).  This and "delay" are additive.   */  sprintf(varname, "%s-jitter", ctl->net->s_name);  if ((s = ini_lookup(ini_handle, attache_section, varname)) != 0)    sscanf(s, "%lu", &ctl->jitter);  /*   * Drop packets according to one of the algorithms in vp_ip_send_handler().   * See that function for details.   */  sprintf(varname, "%s-drop", ctl->net->s_name);  if ((s = ini_lookup(ini_handle, attache_section, varname)) != 0)    sscanf(s, "%lu %lu %lu", &ctl->drop_p1, &ctl->drop_p2, &ctl->drop_p3);}static void vp_link_config(struct vp_ctl *ctl, struct ini_handle *ini_handle){  char *s;  char *av[20];  int ac, i = 0;  for (s = ini_iter_start(ini_handle, attache_section, "unnumbered-link"); s;       s = ini_iter_next(ini_handle)) {    ac = parse_line(s, av, sizeof(av)/sizeof(*av));    if (ac < 3)      continue;    if (STRCMP(av[i++], ctl->net->s_name) != 0)      continue;    if (STRLEN(av[i]) > VP_MAX_TAG)      av[i][VP_MAX_TAG+1] = '\0';    STRCPY(ctl->local_tag, av[i++]);    if (STRLEN(av[i]) > VP_MAX_TAG)      av[i][VP_MAX_TAG+1] = '\0';    STRCPY(ctl->remote_tag, av[i]);    printf("  -- Configuring %s with local tag %s, remote link to tag %s\n",	   ctl->net->s_name, ctl->local_tag, ctl->remote_tag);    return;  }}  			   /* * Process whatever incoming packets we can without blocking. * Passes zero or more Attache packets to ip_rcv(). */static void vp_rcv(struct net *net){  struct bsdif *bif = net->specific;  struct vp_ctl *ctl = bif->private;  packet *p = ctl->ipkt;  size_t len = net->driver->maxlen + MaxLnh;  int n;  for (;;) {    if (p == 0) {      if ((p = pkt_alloc(len)) == 0)	break;      p->pkt_data += MaxLnh;      p->pkt_datalen -= MaxLnh;    }    do {      n = recv(bif->fd, p->pkt_data, p->pkt_datalen, 0);    } while (n < 0 && errno == EINTR);    if (n <= 0) {      if (errno != EWOULDBLOCK)	bif->flags &= ~BSDIF_READ;      break;    }    p->pkt_datalen = n;    p->pkt_n = net;    ip_rcv(p);    p = 0;  }  ctl->ipkt = p;}/* * Handle events detected by generic BSD I/O loop. * This particular driver should never get anything but read events. */static void vp_handler(int fd, void *net, unsigned flags){  assert((flags & ~BSDIF_READ) == 0);  vp_rcv(net);}/* * Media control routine.  In this particular driver, this takes * the place of the driver init and close routines as well, since * there's no real need to separate out those functions. */static int vp_media_ctl(struct net *net, int code, void *cookie){  char sockname[sizeof(vp_socket_dir) + 16];  struct bsdif *bif = net->specific;  struct sockaddr_un sa;  struct vp_ctl *ctl;  sprintf(sa.sun_path, "%s/i%d-%s",	  vp_socket_dir, (int) getpid(), net->s_name);  sa.sun_family = AF_UNIX;  switch (code) {       case MEDIA_CTL_INIT:    net->flags |= NF_DRIVER_DOWN;    if ((bif->private = ctl = GLUE_ALLOC(sizeof(*ctl))) == 0) {      fprintf(stderr, "couldn't allocate vp control structure\n");      return MEDIA_CTL_ERROR;    }    MEMSET(ctl, 0, sizeof(*ctl));    etc_tm_init(&ctl->pktlog_sync);    ctl->net = net;    if ((bif->fd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) {      perror("couldn't create vp socket");    } else if (mkdir(vp_socket_dir, 0777) < 0 && errno != EEXIST) {      perror("couldn't create vp socket inode directory");    } else if (unlink(sa.sun_path) < 0 && errno != ENOENT) {      perror("couldn't unlink old vp socket inode");    } else if (bind(bif->fd, (struct sockaddr *) &sa, 		    (sizeof(sa) - sizeof(sa.sun_path) +		     STRLEN(sa.sun_path))) < 0) {      perror("couldn't bind vp socket address");    } else if (fcntl(bif->fd, F_SETFL, FNDELAY) < 0) {      perror("couldn't set vp socket non-blocking");    } else {      struct ini_handle *ini_handle = ini_open(256);      vp_open_log(ctl, ini_handle);      vp_ip_send_config(ctl, ini_handle);      /* This is where we configure point-to-point names */      vp_link_config(ctl, ini_handle);      ini_close(ini_handle);      bif->handler = vp_handler;      bif->flags |= BSDIF_READ;      net->flags &= ~NF_DRIVER_DOWN;      return MEDIA_CTL_GOOD;    }    /* aieeeee.... */       case MEDIA_CTL_CLOSE:    ctl = bif->private;    net->flags |= NF_DRIVER_DOWN;    bif->flags &= ~(BSDIF_READ | BSDIF_WRITE);    unlink(sa.sun_path);    if (bif->fd >= 0) {      close(bif->fd);      bif->fd = -1;    }    if (ctl) {      if (ctl->ipkt)	pkt_free(ctl->ipkt);      while (ctl->opkts) {	packet *p = ctl->opkts;	struct vp_lnh *lh = (struct vp_lnh *) (p->pkt_buffer);	etc_tm_cancel(&lh->tm);	ctl->opkts = p->pkt_link;	pkt_free(p);      }      if (ctl->pktlog)	vp_close_log(ctl);      GLUE_FREE(ctl);      bif->private = 0;    }    return code == MEDIA_CTL_CLOSE ? MEDIA_CTL_GOOD : MEDIA_CTL_ERROR;   case MEDIA_CTL_IP_UP:    ctl = bif->private;    net->flags &= ~NF_DOWN;    net->status_tstamp = GLUE_NOW();#if INSTALL_ATTACHE_MIB    net->ifLastChange = centiseconds_since_attache_boot();#endif    if (!route_address_count(net, 0) && (ctl->local_tag[0])) {      sprintf(sockname, "%s/%s", vp_socket_dir, ctl->local_tag);      if (unlink(sockname) < 0 && errno != ENOENT)	perror("couldn't unlink vp unnumbered link");      else if (link(sa.sun_path, sockname) < 0)	perror("couldn't link vp unnumbered link");      else {	ctl->local_exists = 1;	ip_advise_if_up(net);	return MEDIA_CTL_GOOD;      }      return MEDIA_CTL_ERROR;    }    ip_advise_if_up(net);    return MEDIA_CTL_GOOD;   case MEDIA_CTL_IP_DOWN:    ctl = bif->private;    net->flags |= NF_DOWN;    net->status_tstamp = GLUE_NOW();#if INSTALL_ATTACHE_MIB    net->ifLastChange = centiseconds_since_attache_boot();#endif    ip_advise_if_down(net);    if (STRLEN(ctl->local_tag)) {      sprintf(sockname, "%s/%s", vp_socket_dir, ctl->local_tag);      unlink(sockname);      ctl->local_exists = 0;    }    return MEDIA_CTL_GOOD;   case MEDIA_CTL_ADD_ADDRESS:    ctl = bif->private;    sprintf(sockname, "%s/%s", vp_socket_dir, inettoa(* (inaddr_t *) cookie));    if (unlink(sockname) < 0 && errno != ENOENT)      perror("couldn't unlink vp IP address");    else if (link(sa.sun_path, sockname) < 0)      perror("couldn't link secondary vp IP address");    else {      if (ctl->local_exists) {	sprintf(sockname, "%s/%s", vp_socket_dir, ctl->local_tag);	unlink(sockname);	ctl->local_exists = 0;      }      return MEDIA_CTL_GOOD;    }    return MEDIA_CTL_ERROR;   case MEDIA_CTL_DELETE_ADDRESS:    sprintf(sockname, "%s/%s", vp_socket_dir, inettoa(* (inaddr_t *) cookie));    unlink(sockname);    return MEDIA_CTL_ERROR;       default:    return MEDIA_CTL_UNKNOWN_CODE;  }}static struct driver vp_driver = {  0,				/* Init routine */  0,				/* Raw send routine */  vp_ip_send,			/* IP packet send routine */  0,				/* ARP routine */  0,				/* Device control routine */  0,				/* Close routine */  "vp",				/* Driver name prefix */  "BSD Socket VaporNet",	/* Driver name */  sizeof(struct vp_lnh),	/* Net header length */  0,				/* Net trailer length */  VP_MTU,			/* Max packet size */  IF_ETHER_3MB,			/* MIB interface type (fake broadcast) */  0,				/* ARP hardware type (none) */  vp_media_ctl			/* Media layer control routine */};static struct driver ws_driver = {  0,				/* Init routine */  0,				/* Raw send routine */  vp_ip_send,			/* IP packet send routine */  0,				/* ARP routine */  0,				/* Device control routine */  0,				/* Close routine */  "ws",				/* Driver name prefix */  "BSD Socket WetStringNet",	/* Driver name */  sizeof(struct vp_lnh),	/* Net header length */  0,				/* Net trailer length */  VP_MTU,			/* Max packet size */  IF_PROP_SERIAL,		/* MIB interface type (fake point-to-point) */  0,				/* ARP hardware type (none) */  vp_media_ctl,			/* Media layer control routine */  0,				/* IPv6 send */  0				/* IPv4 send */};/* * Standard snark interface find routine. * Since there's no real device in back of a vapornet interface, * we just generate a specified number of interface names, then exit. */void vp_driver_find  (void (*config)(char *, struct driver *, int, bits16_t, unsigned, bits32_t)){  char name[10];  int instance;  for (instance = 0; instance < VP_MAX_INTERFACES; instance++) {    sprintf(name, "%d", instance);    config(name, &vp_driver, instance, 0,	   vp_driver.maxlen - vp_driver.lnh - vp_driver.lnt, VP_SPEED);  }  for (instance = 0; instance < WS_MAX_INTERFACES; instance++) {    sprintf(name, "%d", instance);    config(name, &ws_driver, instance, 0,	   ws_driver.maxlen - ws_driver.lnh - ws_driver.lnt, WS_SPEED);  }}#endif /* INSTALL_SNARK_BSD_VAPORNET */

⌨️ 快捷键说明

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