📄 pppbsd.c
字号:
hexdump("RX", p->pkt_data, p->pkt_datalen); ppp_rcv(p); } if (n == 0) /* out of packet buffers, try again later */ break; pdc->ibp += n; /* count what we consumed */ pdc->ilen -= n; }}/* * Process whatever outgoing Attache packets we can without blocking. * Generates zero or more writes of encoded PPP data. */static void ppp_driver_output(struct net *net){ struct bsdif *bif = net->specific; struct ppp_driver_ctl *pdc = bif->private; int n; for (;;) { if (pdc->olen == 0) { if ((n = ppp_driver_encode(net, pdc->obuf, sizeof(pdc->obuf))) == 0) break; pdc->olen = n; pdc->obp = pdc->obuf; } do { n = write(bif->fd, pdc->obp, pdc->olen); } while (n < 0 && errno == EINTR); if (n <= 0) break; pdc->obp += n; pdc->olen -= n; } if (n == 0 || (n < 0 && errno != EWOULDBLOCK)) bif->flags &= ~BSDIF_WRITE;}/* * Handle events detected by generic NetBSD I/O loop. * The flags tell us what kind of event happened, we call the * non-blocking I/O routines to do the real work. */static void ppp_driver_handler(int fd, void *net, unsigned flags){ if ((flags & BSDIF_WRITE) != 0) ppp_driver_output(net); if ((flags & BSDIF_READ) != 0) ppp_driver_input(net);}/* * Attache device driver routines. */static void ppp_driver_send(packet *p){ struct net *net = p->pkt_n; struct bsdif *bif = net->specific; struct ppp_driver_ctl *pdc = bif->private; hexdump("TX", p->pkt_data, p->pkt_datalen); p->pkt_flags |= PF_PPP_BOP; /* Flag that this is a new packet */ p->pkt_link = 0; /* Stuff this packet into the */ *pdc->opkt_tail = p; /* output queue */ pdc->opkt_tail = &p->pkt_link; bif->flags |= BSDIF_WRITE; /* Now interested in output events */ ppp_driver_output(net); /* Send what we can right away */}static void ppp_driver_close(struct net *net){ struct bsdif *bif = net->specific; net->flags |= NF_DRIVER_DOWN; bif->flags &= ~(BSDIF_READ | BSDIF_WRITE); if (bif->fd >= 0) { (void) close(bif->fd); /* Clean up our file if we had one */ bif->fd = -1; } if (bif->private) { GLUE_FREE(bif->private); /* Release our memory if we had any */ bif->private = 0; }}static void ppp_driver_init(struct net *net){ struct bsdif *bif = net->specific; struct ppp_driver_ctl *pdc; char name[64]; net->flags |= NF_DRIVER_DOWN; if (!net->speed) net->speed = 115200; if ((bif->private = pdc = GLUE_ALLOC(sizeof(*pdc))) == 0) { fprintf(stderr, "couldn't allocate ppp control structure\n"); return; } MEMSET(pdc, 0, sizeof(*pdc)); pdc->opkt_tail = &pdc->opkt_head; pdc->net = net;#if INSTALL_SNARK_BSD_PPP_OVER_PTY { int pty, tty; int subpid; char *pppd_path; struct termios t; int nsleep = 10; sprintf(name, "SNARKBSDPPP_PTY%d", net->instance); pppd_path = getenv(name); if (!pppd_path) return; if (openpty(&pty, &tty, name, NULL, NULL) < 0) { perror("can't open pty"); return; } tcgetattr(tty, &t); cfmakeraw(&t); tcsetattr(tty, TCSAFLUSH, &t); fflush(NULL); subpid = fork(); if (subpid < 0) { perror("fork"); return; /* !!! cleanup? */ } if (subpid == 0) { /* in the child; start pppd... */ dup2(tty, 0); dup2(tty, 1); close(pty); close(tty); fprintf(stderr, "execing %s in pid %d on %s in %d seconds...\n", pppd_path, getpid(), name, nsleep); sleep(nsleep); fprintf(stderr, "execing now\n"); execlp(pppd_path, "pppd", name, "file", "snark.ppprc", NULL); _exit(1); } /* now in the parent.. */ close(tty); bif->fd = pty; sleep(nsleep+1); }#elif !INSTALL_SNARK_BSD_PPP_OVER_TCP /* * Normal /dev/ttyxxx-based PPP. This code was written for FreeBSD 2.2.1, * it should be pretty easy to make it work on other Unix-like systems. */ { struct termios termios; sprintf(name, "/dev/%s", net->s_name + 3); if ((bif->fd = open(name, O_RDWR, 0660)) < 0) { /* |O_NONBLOCK */ perror("couldn't open ppp device"); goto lose; } if (tcgetattr(bif->fd, &termios) < 0) { perror("couldn't get ppp line state"); goto lose; } if (cfmakeraw(&termios), cfsetspeed(&termios, net->speed) < 0) { perror("couldn't fiddle ppp state"); goto lose; } if (tcsetattr(bif->fd, TCSANOW, &termios) < 0) { perror("couldn't set ppp line flags and speed"); goto lose; } }#elif 0 /* * PPP over TCP. This version does an active connect. In theory, * it should work nicely with IIJ-PPP in -direct mode running under * Juergen Nickelsen's "socket" program, but in practice the connection * keeps getting closed before LCP ever really gets going. Sigh. */ { struct sockaddr_in sin; char host[20]; unsigned short port; sprintf(name, "SNARKBSDPPP_%s", net->s_name + 3); if (sscanf(getenv(name), "%16[0-9.]:%hu", host, &port) != 2) { fprintf(stderr, "couldn't line information for PPP/TCP link\n"); goto lose; } MEMSET(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = htons(port); sin.sin_addr.s_addr = inet_addr(host); if ((bif->fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("couldn't get socket for PPP/TCP link"); goto lose; } if (connect(bif->fd, (struct sockaddr *) &sin, sizeof(sin)) < 0) { perror("couldn't connect PPP/TCP link"); goto lose; } }#else /* * PPP over TCP. This version does a passive listen, which, in theory, * should allow IIJ-PPP to connect to it directly. */ { struct sockaddr_in sin; unsigned short port; int s, n; sprintf(name, "SNARKBSDPPP_%s", net->s_name + 3); if (sscanf(getenv(name), "%hu", &port) != 1) { fprintf(stderr, "couldn't parse line information for PPP/TCP link %s: %s\n", name, getenv(name)); goto lose; } MEMSET(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = htons(port); if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("couldn't get socket for PPP/TCP listener"); goto lose; } if (bind(s, (struct sockaddr *) &sin, sizeof(sin)) < 0) { perror("couldn't bind socket for PPP/TCP listener"); goto lose; } if (listen(s, 1) < 0) { perror("couldn't listen for for PPP/TCP connection"); goto lose; } fprintf(stderr, "[Listening for PPP/TCP connection on port %u]\n", port); n = sizeof(sin); if ((bif->fd = accept(s, (struct sockaddr *) &sin, &n)) < 0) { perror("couldn't accept PPP/TCP connection"); goto lose; } close(s); fprintf(stderr, "[Got PPP/TCP connection from %s:%u]\n", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); }#endif if (fcntl(bif->fd, F_SETFL, FNDELAY) < 0) { perror("unable to set ppp line non-blocking"); goto lose; } bif->handler = ppp_driver_handler; bif->flags |= BSDIF_READ; net->flags &= ~NF_DRIVER_DOWN; return; /* success */lose: ppp_driver_close(net); /* failure */}static int ppp_driver_device_ctl(struct net *net, int code, ptr_t cookie){ struct bsdif *bif = net->specific; struct ppp_driver_ctl *pdc = bif->private; switch (code) { case DEVICE_CTL_SET_PPP_ASYNC_CTL_MAP: BUG_ASSERT(cookie && bif && pdc); pdc->snd_asynch_mask = *(bits32_t *)cookie; return DEVICE_CTL_GOOD; case DEVICE_CTL_GET_PPP_RCV_ASYNC_CTL_MAP: BUG_ASSERT(cookie); *(bits32_t *)cookie = PPP_DRIVER_RCV_ASYNCH_MASK; return DEVICE_CTL_GOOD; default: return DEVICE_CTL_UNKNOWN_CODE; }}static struct driver ppp_driver = { ppp_driver_init, /* Init routine */ ppp_driver_send, /* Raw send routine */ ppp_ip_send, /* IP packet send routine */ 0, /* ARP routine */ ppp_driver_device_ctl, /* Device control routine */ ppp_driver_close, /* Close routine */ "ppp", /* Driver name prefix */ "Point-to-Point Protocol", /* Driver name */ 4, /* Header length (adr, ctl, prot) */ 2, /* Trailer length (FCS) */ 1506, /* Max packet size */ IF_PPP, /* MIB interface type */ 0, /* ARP hardware type */ ppp_control, /* Media control routine */ 0, /* IPv6 send */ 0 /* IPv4 send */};void ppp_driver_find (void (*config)(char *, struct driver *, int, bits16_t, unsigned, bits32_t)){ char name[64]; int speed, instance; for (instance = 0; ; instance++) {#if INSTALL_SNARK_BSD_PPP_OVER_PTY sprintf(name, "SNARKBSDPPP_PTY%d", instance); if (!getenv(name)) return; speed = 115200;#elif INSTALL_SNARK_BSD_PPP_OVER_TCP sprintf(name, "SNARKBSDPPP_%s%d", BSDPPP_COMPORT_NAME, instance); if (!getenv(name)) return; speed = 115200;#else struct termios termios; int fd; sprintf(name, "/dev/%s%d", BSDPPP_COMPORT_NAME, instance); if ((fd = open(name, O_RDONLY | O_NONBLOCK)) < 0) { if (errno == ENOENT) return; continue; } speed = (tcgetattr(fd, &termios) < 0 ? 0 : cfgetispeed(&termios)); (void) close(fd); if (speed == 0) continue;#endif sprintf(name, "%s%d", BSDPPP_COMPORT_NAME, instance); config(name, &ppp_driver, instance, 0, ppp_driver.maxlen - ppp_driver.lnh - ppp_driver.lnt, speed); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -