📄 snarkbsd.c
字号:
}}#if INSTALL_ATTACHE_SOCKETSstatic void (*deferred_io_handler)(void);static void (*deferred_io_first)(void);void glue_set_deferred_io_handler (void (*first)(void), void (*handler)(void)){ deferred_io_first = first; deferred_io_handler = handler;}#endifvoid *io_runner(void *arg){ struct bsdif *bif; fd_set ifds, ofds; int nfds, selret = 0; struct timeval tv; bits32_t when; (void)pipe(hack_pipe);#if INSTALL_ATTACHE_SOCKETS if (deferred_io_first) { (*deferred_io_first)(); deferred_io_first = NULL; }#endif ATTACHE_LOCK(); for (;;) { FD_ZERO(&ifds); FD_ZERO(&ofds); nfds = 1; FD_SET(0, &ifds); if (hack_pipe[0]>=nfds) nfds=hack_pipe[0]+1; FD_SET(hack_pipe[0], &ifds); for (bif = bsdif_list; bif; bif = bif->next) { if (bif->fd < 0 || !bif->handler) continue; if ((bif->flags & BSDIF_READ) != 0) FD_SET(bif->fd, &ifds); if ((bif->flags & BSDIF_WRITE) != 0) FD_SET(bif->fd, &ofds); if (bif->fd >= nfds) nfds = bif->fd + 1; } when = glue_callin_when - glue_now(); if (((sbits32_t) when) <= 0) { tv.tv_sec = tv.tv_usec = 0; } else { tv.tv_sec = when / 1000; tv.tv_usec = (when % 1000) * 1000; } ATTACHE_UNLOCK(); if (nfds > 0) selret = select(nfds, &ifds, &ofds, 0, &tv);#if INSTALL_ATTACHE_SOCKETS BUG_ASSERT(deferred_io_first == 0);#endif ATTACHE_LOCK(); if (snark_exit_flag) goto bye; when = glue_callin_when - glue_now(); if (glue_callin_who && ((sbits32_t) when) <= 0) { void (*who)(void) = glue_callin_who; glue_callin_who = 0; who(); } if ((nfds > 0) && (selret > 0)) { if (FD_ISSET(hack_pipe[0], &ifds)) { char c; read(hack_pipe[0], &c, 1); } if (FD_ISSET(0, &ifds)) { kbd_rcv(); } for (bif = bsdif_list; bif; bif = bif->next) { unsigned flags = 0; int fd = bif->fd; if (fd < 0 || !bif->handler) continue; if (FD_ISSET(fd, &ifds)) flags |= BSDIF_READ; if (FD_ISSET(fd, &ofds)) flags |= BSDIF_WRITE; if (flags) bif->handler(fd, bif->net, flags); } if (snark_exit_flag) goto bye;#if INSTALL_ATTACHE_SOCKETS if (deferred_io_handler) { ATTACHE_UNLOCK(); BUG_ASSERT(deferred_io_first == 0); (*deferred_io_handler)(); ATTACHE_LOCK(); }#endif } } bye: ATTACHE_UNLOCK(); task_kick(); return NULL;}/* * Run tasks. This is the main body of the task dispatcher; it does not return. */int tasks_run(){ struct task *task; ETC_THD_CREATE (&io_runner_thd, io_runner, NULL); ATTACHE_LOCK(); while (!snark_exit_flag) { while (!snark_exit_flag && ((task = task_deq()) != 0) && task->func != 0) task->func(task, task->cookie); ETC_COND_WAIT(&task_queue, &attache_lock); } snark_shutdown(); return snark_exit_value;}#else /* !INSTALL_ATTACHE_THREADS *//* * Run tasks. This is the main body of the task dispatcher; it does not return. */int tasks_run(){ struct bsdif *bif; fd_set ifds, ofds; struct timeval tv; struct task *task; bits32_t when; int nfds, selret = 0; for (;;) { FD_ZERO(&ifds); FD_ZERO(&ofds); nfds = 0; if (!kbd_eof && kbd_handler) { FD_SET(0, &ifds); nfds = 1; } for (bif = bsdif_list; bif; bif = bif->next) { if (bif->fd < 0 || !bif->handler) continue; if ((bif->flags & BSDIF_READ) != 0) FD_SET(bif->fd, &ifds); if ((bif->flags & BSDIF_WRITE) != 0) FD_SET(bif->fd, &ofds); if (bif->fd >= nfds) nfds = bif->fd + 1; } when = glue_callin_when - glue_now(); if (!task_idle() || ((sbits32_t) when) <= 0) { tv.tv_sec = tv.tv_usec = 0; } else { tv.tv_sec = when / 1000; tv.tv_usec = (when % 1000) * 1000; } if (nfds > 0) selret = select(nfds, &ifds, &ofds, 0, &tv); if ((nfds > 0) && (selret > 0)) { if (FD_ISSET(0, &ifds)) kbd_rcv(); if (snark_exit_flag) goto bye; for (bif = bsdif_list; bif; bif = bif->next) { unsigned flags = 0; int fd = bif->fd; if (fd < 0 || !bif->handler) continue; if (FD_ISSET(fd, &ifds)) flags |= BSDIF_READ; if (FD_ISSET(fd, &ofds)) flags |= BSDIF_WRITE; if (flags) bif->handler(fd, bif->net, flags); if (snark_exit_flag) goto bye; } } if ((task = task_deq()) != 0 && task->func != 0) task->func(task, task->cookie); if (snark_exit_flag) goto bye; if (glue_callin_who && ((sbits32_t) (glue_callin_when - glue_now())) <= 0) { void (*who)(void) = glue_callin_who; glue_callin_who = 0; who(); if (snark_exit_flag) goto bye; } } bye: snark_shutdown(); return snark_exit_value;}#endif /* INSTALL_ATTACHE_THREADS *//* This is the function we use to provide GLUE_CALLIN(). */void glue_callin(bits32_t when, void (*who)(void)){ glue_callin_when = when + glue_now(); glue_callin_who = who;#if INSTALL_ATTACHE_THREADS task_kick(); io_kick();#endif}#if INSTALL_ATTACHE/* * This function processes a system time received from SNTP. Because we * are in a simulator, we don't want to set the real system time. The * time is represented as seconds (secs) and fractions of a second * (fracs) since 00:00:00 1/1/1900. This is the standard NTP time * representation described in RFC 2030 and others. * * This function is handed the entire SNTP packet, because it is * likely that a real SNTP client would want to enforce some sort * of policy regarding what time sources to believe. */void glue_set_time(packet *p, bits32_t secs, bits32_t fracs){ /* adjust NTP time representation to Unix time representation. This * method is good enough for most purposes, but not perfect. */ secs -= (bits32_t)2208988800UL; printf("\nThe time is: %s\n", ctime((time_t *)&secs));}#endif/* * Let others have access to the basic file descriptor * select() loop in the task dispatcher. */struct fdprocs { struct bsdif bif; fdproc_t readproc, writeproc;};static voidfdproc_dispatch(int fd, void *net, unsigned flags){ struct fdprocs *fdp; fdp = (struct fdprocs *) net; if ((flags & BSDIF_READ) && fdp->readproc) fdp->readproc(fd, fdp->bif.private); if ((flags & BSDIF_WRITE) && fdp->writeproc) fdp->writeproc(fd, fdp->bif.private);}struct bsdif **fdprocs_search(int fd){ struct bsdif **p; for (p = &bsdif_list; *p && ((*p)->fd != fd || (*p)->handler != fdproc_dispatch); p = &(*p)->next) ; return p;}static struct fdprocs *fdprocs_find(int fd){ struct bsdif **p; struct fdprocs *fdp; p = fdprocs_search(fd); if (*p) { fdp = (struct fdprocs *) (*p)->net; } else { fdp = (struct fdprocs *) GLUE_ALLOC(sizeof(struct fdprocs)); if (fdp == 0) return 0; fdp->bif.fd = fd; fdp->bif.handler = fdproc_dispatch; fdp->bif.net = fdp; fdp->bif.private = 0; fdp->bif.flags = 0; fdp->readproc = 0; fdp->writeproc = 0; fdp->bif.next = bsdif_list; bsdif_list = &fdp->bif; } return fdp;}intsnark_set_fdprocs(int fd, void *cookie, fdproc_t readproc, fdproc_t writeproc){ unsigned flags = 0; struct fdprocs *fdp; if (readproc) flags |= BSDIF_READ; if (writeproc) flags |= BSDIF_WRITE; fdp = fdprocs_find(fd); if (fdp == 0) return -1; fdp->bif.private = cookie; fdp->bif.flags = flags; fdp->readproc = readproc; fdp->writeproc = writeproc; return 0;}intsnark_reset_read_fdproc(int fd, fdproc_t readproc){ struct fdprocs *fdp; fdp = fdprocs_find(fd); if (fdp == 0) return -1; if (readproc) fdp->bif.flags |= BSDIF_READ; else fdp->bif.flags &= ~BSDIF_READ; fdp->readproc = readproc; return 0;}intsnark_reset_write_fdproc(int fd, fdproc_t writeproc){ struct fdprocs *fdp; fdp = fdprocs_find(fd); if (fdp == 0) return -1; if (writeproc) fdp->bif.flags |= BSDIF_WRITE; else fdp->bif.flags &= ~BSDIF_WRITE; fdp->writeproc = writeproc; return 0;}#if INSTALL_ATTACHE/* * Network configuration. */static void netconfig_find_one (char *if_name, struct driver *driver, int instance, bits16_t flags, unsigned mtu, bits32_t speed){ static char anonymous[] = ""; struct net *net; struct bsdif *bif; char *drv_name = driver->prefix; size_t len, media_len;#if SNARK_GRATUITOUS_ARP ipaddr_t tmp_ip;#endif if (!drv_name) drv_name = anonymous; if (!if_name) if_name = anonymous; switch (driver->type) {#if INSTALL_SNARK_BSD_PPP case IF_PPP: media_len = sizeof(struct pppctl); break;#endif default: media_len = 0; break; } len = sizeof(*net) + sizeof(*bif) + media_len + STRLEN(drv_name) + STRLEN(if_name) + 1; if ((net = GLUE_ALLOC(len)) == 0) return; MEMSET(net, 0, len); bif = (struct bsdif *) (net + 1); net->s_name = (char *) (bif + 1); if (media_len > 0) { net->media_cookie = net->s_name; net->s_name += media_len; } net->specific = bif; bif->net = net; net->instance = instance; net->driver = driver; net->flags = flags | NF_DOWN; net->mtu = mtu; net->speed = speed; STRCPY(net->s_name, drv_name); STRCPY(net->s_name + STRLEN(net->s_name), if_name); if (netconfig_if(net)) { bif->next = bsdif_list; bsdif_list = bif; if_attach(net); if_up(net);#if SNARK_GRATUITOUS_ARP if (net->ip_addr != 0L) { SET_IPADDR_TYPE(&tmp_ip, IPV4); MEMCPY(PTR_IPADDR_BITS(&tmp_ip), &net->ip_addr, IPV4_ADDR_LEN); snark_gratuitous_arp(net, &tmp_ip); }#endif } else { GLUE_FREE(net); }}void netconfig_find(){#if INSTALL_SNARK_BSD_BPF bpf_driver_find(netconfig_find_one);#endif#if INSTALL_SNARK_BSD_NIT nit_driver_find(netconfig_find_one);#endif#if INSTALL_SNARK_DLPI dlpi_driver_find(netconfig_find_one);#endif#if INSTALL_SNARK_BSD_SNOOP snoop_driver_find(netconfig_find_one);#endif#if INSTALL_SNARK_BSD_SLIP slip_driver_find(netconfig_find_one);#endif#if INSTALL_SNARK_BSD_PPP ppp_driver_find(netconfig_find_one);#endif#if INSTALL_SNARK_BSD_VAPORNET vp_driver_find(netconfig_find_one);#endif#if INSTALL_SNARK_BSD_TUN tun_driver_find(netconfig_find_one);#endif}#endif /* INSTALL_ATTACHE *//* * Initialization and shutdown. * There's probably stuff I've forgotten, add as needed. */#ifndef SNARK_ATTACHE_MAXLNH#define SNARK_ATTACHE_MAXLNH 0#endif#ifndef SNARK_ATTACHE_MAXLNT#define SNARK_ATTACHE_MAXLNT 0#endifvoid snark_init(){#if INSTALL_ATTACHE_THREADS task_kick_init();#endif tasks_init();#if INSTALL_ATTACHE MaxLnh = SNARK_ATTACHE_MAXLNH; MaxLnt = SNARK_ATTACHE_MAXLNT; ATTACHE_LOCK(); attache_init(); ATTACHE_UNLOCK();#endif#if INSTALL_ENVOY envoy_init();#endif setlinebuf(stdout); sty_init(); keyboard_init();#if INSTALL_LIAISON rmon_init(); rmon_enable();#endif#if INSTALL_ATTACHE netconfig();#endif#if INSTALL_SNARK_BUG_CONF bug_config();#endif}void snark_shutdown(){ keyboard_shutdown();#if INSTALL_ATTACHE && INSTALL_ATTACHE_SHUTDOWN attache_shutdown();#if INSTALL_ATTACHE_THREADS ATTACHE_UNLOCK(); io_kick(); ETC_THD_YIELD();#endif#endif}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -