summaryrefslogtreecommitdiffstats
path: root/usr.sbin/ppp/server.c
diff options
context:
space:
mode:
authorbrian <brian@FreeBSD.org>1998-05-21 21:49:08 +0000
committerbrian <brian@FreeBSD.org>1998-05-21 21:49:08 +0000
commit56df88b778aee0e60678672b107a48a8ea05cb48 (patch)
tree13b88ca17b38e787c84b0cd242677b3c3c0b93c3 /usr.sbin/ppp/server.c
parente077fa331b8a428923ded3a95d0b8d47084cf670 (diff)
downloadFreeBSD-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.c228
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;
}
OpenPOWER on IntegriCloud