diff options
author | brian <brian@FreeBSD.org> | 1998-05-21 21:49:08 +0000 |
---|---|---|
committer | brian <brian@FreeBSD.org> | 1998-05-21 21:49:08 +0000 |
commit | 56df88b778aee0e60678672b107a48a8ea05cb48 (patch) | |
tree | 13b88ca17b38e787c84b0cd242677b3c3c0b93c3 /usr.sbin/ppp/server.c | |
parent | e077fa331b8a428923ded3a95d0b8d47084cf670 (diff) | |
download | FreeBSD-src-56df88b778aee0e60678672b107a48a8ea05cb48.zip FreeBSD-src-56df88b778aee0e60678672b107a48a8ea05cb48.tar.gz |
MFMP: Make ppp multilink capable.
See the file README.changes, and re-read the man page.
Diffstat (limited to 'usr.sbin/ppp/server.c')
-rw-r--r-- | usr.sbin/ppp/server.c | 228 |
1 files changed, 166 insertions, 62 deletions
diff --git a/usr.sbin/ppp/server.c b/usr.sbin/ppp/server.c index f0146aa..ae0ca6bb 100644 --- a/usr.sbin/ppp/server.c +++ b/usr.sbin/ppp/server.c @@ -23,113 +23,213 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: server.c,v 1.16 1998/01/21 02:15:27 brian Exp $ + * $Id: server.c,v 1.16.2.19 1998/05/10 22:20:20 brian Exp $ */ -#include <sys/param.h> +#include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netinet/in_systm.h> +#include <netinet/ip.h> +#include <sys/un.h> #include <errno.h> #include <stdio.h> #include <string.h> #include <sys/stat.h> -#include <sys/un.h> +#include <termios.h> #include <unistd.h> -#include "command.h" #include "mbuf.h" #include "log.h" -#include "loadalias.h" #include "defs.h" -#include "vars.h" +#include "descriptor.h" #include "server.h" #include "id.h" +#include "prompt.h" +#include "timer.h" +#include "lqr.h" +#include "hdlc.h" +#include "fsm.h" +#include "lcp.h" +#include "ccp.h" +#include "throughput.h" +#include "link.h" +#include "mp.h" +#include "iplist.h" +#include "slcompress.h" +#include "ipcp.h" +#include "filter.h" +#include "bundle.h" -int server = -1; +static int +server_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n) +{ + struct server *s = descriptor2server(d); -static struct sockaddr_un ifsun; -static char *rm; + if (r && s->fd >= 0) { + if (*n < s->fd + 1) + *n = s->fd + 1; + FD_SET(s->fd, r); + log_Printf(LogTIMER, "server: fdset(r) %d\n", s->fd); + return 1; + } + return 0; +} -int -ServerLocalOpen(const char *name, mode_t mask) +static int +server_IsSet(struct descriptor *d, const fd_set *fdset) { - int s; + struct server *s = descriptor2server(d); + return s->fd >= 0 && FD_ISSET(s->fd, fdset); +} - if (VarLocalAuth == LOCAL_DENY) { - LogPrintf(LogWARN, "Local: Can't open socket %s: No password " - "in ppp.secret\n", name); - return 1; +#define IN_SIZE sizeof(struct sockaddr_in) +#define UN_SIZE sizeof(struct sockaddr_in) +#define ADDRSZ (IN_SIZE > UN_SIZE ? IN_SIZE : UN_SIZE) + +static void +server_Read(struct descriptor *d, struct bundle *bundle, const fd_set *fdset) +{ + struct server *s = descriptor2server(d); + char hisaddr[ADDRSZ]; + struct sockaddr *sa = (struct sockaddr *)hisaddr; + struct sockaddr_in *in = (struct sockaddr_in *)hisaddr; + int ssize = ADDRSZ, wfd; + struct prompt *p; + + wfd = accept(s->fd, sa, &ssize); + if (wfd < 0) { + log_Printf(LogERROR, "server_Read: accept(): %s\n", strerror(errno)); + return; } - if (mode & MODE_INTER) { - LogPrintf(LogWARN, "Local: Can't open socket in interactive mode\n"); - return 1; + switch (sa->sa_family) { + case AF_LOCAL: + log_Printf(LogPHASE, "Connected to local client.\n"); + break; + + case AF_INET: + if (ntohs(in->sin_port) < 1024) { + log_Printf(LogALERT, "Rejected client connection from %s:%u" + "(invalid port number) !\n", + inet_ntoa(in->sin_addr), ntohs(in->sin_port)); + close(wfd); + return; + } + log_Printf(LogPHASE, "Connected to client from %s:%u\n", + inet_ntoa(in->sin_addr), in->sin_port); + break; + + default: + write(wfd, "Unrecognised access !\n", 22); + close(wfd); + return; } - memset(&ifsun, '\0', sizeof ifsun); - ifsun.sun_len = strlen(name); - if (ifsun.sun_len > sizeof ifsun.sun_path - 1) { - LogPrintf(LogERROR, "Local: %s: Path too long\n", name); + if ((p = prompt_Create(s, bundle, wfd)) == NULL) { + write(wfd, "Connection refused.\n", 20); + close(wfd); + } else { + switch (sa->sa_family) { + case AF_LOCAL: + p->src.type = "local"; + strncpy(p->src.from, s->rm, sizeof p->src.from - 1); + p->src.from[sizeof p->src.from - 1] = '\0'; + break; + case AF_INET: + p->src.type = "tcp"; + snprintf(p->src.from, sizeof p->src.from, "%s:%u", + inet_ntoa(in->sin_addr), in->sin_port); + break; + } + prompt_TtyCommandMode(p); + prompt_Required(p); + } +} + +static void +server_Write(struct descriptor *d, struct bundle *bundle, const fd_set *fdset) +{ + /* We never want to write here ! */ + log_Printf(LogERROR, "server_Write: Internal error: Bad call !\n"); +} + +struct server server = { + { + SERVER_DESCRIPTOR, + NULL, + server_UpdateSet, + server_IsSet, + server_Read, + server_Write + }, + -1 +}; + +int +server_LocalOpen(struct bundle *bundle, const char *name, mode_t mask) +{ + int s; + + if (server.rm && !strcmp(server.rm, name)) { + if (chmod(server.rm, mask)) + log_Printf(LogERROR, "Local: chmod: %s\n", strerror(errno)); + return 0; + } + + memset(&server.ifsun, '\0', sizeof server.ifsun); + server.ifsun.sun_len = strlen(name); + if (server.ifsun.sun_len > sizeof server.ifsun.sun_path - 1) { + log_Printf(LogERROR, "Local: %s: Path too long\n", name); return 2; } - ifsun.sun_family = AF_LOCAL; - strcpy(ifsun.sun_path, name); + server.ifsun.sun_family = AF_LOCAL; + strcpy(server.ifsun.sun_path, name); s = ID0socket(PF_LOCAL, SOCK_STREAM, 0); if (s < 0) { - LogPrintf(LogERROR, "Local: socket: %s\n", strerror(errno)); + log_Printf(LogERROR, "Local: socket: %s\n", strerror(errno)); return 3; } setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &s, sizeof s); if (mask != (mode_t)-1) mask = umask(mask); - if (bind(s, (struct sockaddr *)&ifsun, sizeof ifsun) < 0) { + if (bind(s, (struct sockaddr *)&server.ifsun, sizeof server.ifsun) < 0) { if (mask != (mode_t)-1) umask(mask); - LogPrintf(LogERROR, "Local: bind: %s\n", strerror(errno)); - if (errno == EADDRINUSE && VarTerm) - fprintf(VarTerm, "Wait for a while, then try again.\n"); + log_Printf(LogWARN, "Local: bind: %s\n", strerror(errno)); close(s); return 4; } if (mask != (mode_t)-1) umask(mask); if (listen(s, 5) != 0) { - LogPrintf(LogERROR, "Local: Unable to listen to socket - OS overload?\n"); + log_Printf(LogERROR, "Local: Unable to listen to socket - BUNDLE overload?\n"); close(s); ID0unlink(name); return 5; } - ServerClose(); - server = s; - rm = ifsun.sun_path; - LogPrintf(LogPHASE, "Listening at local socket %s.\n", name); + server_Close(bundle); + server.fd = s; + server.rm = server.ifsun.sun_path; + log_Printf(LogPHASE, "Listening at local socket %s.\n", name); return 0; } int -ServerTcpOpen(int port) +server_TcpOpen(struct bundle *bundle, int port) { struct sockaddr_in ifsin; int s; - if (VarLocalAuth == LOCAL_DENY) { - LogPrintf(LogWARN, "Tcp: Can't open socket %d: No password " - "in ppp.secret\n", port); - return 6; - } - - if (mode & MODE_INTER) { - LogPrintf(LogWARN, "Tcp: Can't open socket in interactive mode\n"); - return 6; - } + if (server.port == port) + return 0; s = ID0socket(PF_INET, SOCK_STREAM, 0); if (s < 0) { - LogPrintf(LogERROR, "Tcp: socket: %s\n", strerror(errno)); + log_Printf(LogERROR, "Tcp: socket: %s\n", strerror(errno)); return 7; } memset(&ifsin, '\0', sizeof ifsin); @@ -138,32 +238,36 @@ ServerTcpOpen(int port) ifsin.sin_port = htons(port); setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &s, sizeof s); if (bind(s, (struct sockaddr *)&ifsin, sizeof ifsin) < 0) { - LogPrintf(LogERROR, "Tcp: bind: %s\n", strerror(errno)); - if (errno == EADDRINUSE && VarTerm) - fprintf(VarTerm, "Wait for a while, then try again.\n"); + log_Printf(LogWARN, "Tcp: bind: %s\n", strerror(errno)); close(s); return 8; } if (listen(s, 5) != 0) { - LogPrintf(LogERROR, "Tcp: Unable to listen to socket - OS overload?\n"); + log_Printf(LogERROR, "Tcp: Unable to listen to socket - BUNDLE overload?\n"); close(s); return 9; } - ServerClose(); - server = s; - LogPrintf(LogPHASE, "Listening at port %d.\n", port); + server_Close(bundle); + server.fd = s; + server.port = port; + log_Printf(LogPHASE, "Listening at port %d.\n", port); return 0; } -void -ServerClose() +int +server_Close(struct bundle *bundle) { - if (server >= 0) { - close(server); - if (rm) { - ID0unlink(rm); - rm = 0; + if (server.fd >= 0) { + close(server.fd); + if (server.rm) { + ID0unlink(server.rm); + server.rm = NULL; } + server.fd = -1; + server.port = 0; + /* Drop associated prompts */ + bundle_DelPromptDescriptors(bundle, &server); + return 1; } - server = -1; + return 0; } |